Custom S V G Scatter Points
The [ObservableObject]
, [ObservableProperty]
and [ICommand]
attributes come from the
CommunityToolkit.Mvvm package, you can read more about it
here.
This web site wraps every sample using a UserControl
instance, but LiveCharts controls can be used inside any container.

View model
using System;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;
namespace ViewModelsSamples.Scatter.Custom;
public partial class ViewModel : ObservableObject
{
public ViewModel()
{
var r = new Random();
var values1 = new ObservableCollection<ObservablePoint>();
var values2 = new ObservableCollection<ObservablePoint>();
for (var i = 0; i < 20; i++)
{
values1.Add(new ObservablePoint(r.Next(0, 20), r.Next(0, 20)));
values2.Add(new ObservablePoint(r.Next(0, 20), r.Next(0, 20)));
}
Series = new ISeries[]
{
// use the second type argument to specify the geometry to draw for every point
// there are already many predefined geometries in the
// LiveChartsCore.SkiaSharpView.Drawing.Geometries namespace
new ScatterSeries<ObservablePoint, RoundedRectangleGeometry>
{
Values = values1,
Stroke = null,
GeometrySize = 40,
},
// Or Define your own SVG geometry
new ScatterSeries<ObservablePoint, MyGeometry>
{
Values = values2,
GeometrySize = 40,
Stroke = null,
Fill = new SolidColorPaint(SKColors.DarkOliveGreen)
}
};
}
public ISeries[] Series { get; set; }
}
MyGeometry.cs
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using SkiaSharp;
namespace ViewModelsSamples.Scatter.Custom;
public class MyGeometry : SVGPathGeometry
{
// the static field is important to prevent the svg path is parsed multiple times // mark
// Icon from Google Material Icons font.
// https://fonts.google.com/icons?selected=Material%20Icons%20Outlined%3Amy_location%3A
public static SKPath svgPath = SKPath.ParseSvgPathData(
"M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 " +
"11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 " +
"3.13 7 7-3.13 7-7 7z");
public MyGeometry()
: base(svgPath)
{ }
}
XAML
<UserControl x:Class="WPFSample.Scatter.Custom.View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
xmlns:vms="clr-namespace:ViewModelsSamples.Scatter.Custom;assembly=ViewModelsSamples">
<UserControl.DataContext>
<vms:ViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<lvc:CartesianChart Series="{Binding Series}"></lvc:CartesianChart>
</Grid>
</UserControl>