Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Svg based gemetries #1134

Merged
merged 4 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 11 additions & 11 deletions samples/ViewModelsSamples/Bars/Custom/MyGeometry.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
using System;
using LiveChartsCore.SkiaSharpView.Drawing;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using SkiaSharp;

namespace ViewModelsSamples.Bars.Custom;

public class MyGeometry : LiveChartsCore.SkiaSharpView.Drawing.Geometries.SVGPathGeometry
public class MyGeometry : SizedGeometry
{
public MyGeometry()
: base(() => SelectedPath ?? throw new NotImplementedException("Path not set yet!"))
public override void OnDraw(SkiaSharpDrawingContext context, SKPaint paint)
{
// we passed the "path source" to the base class
// it is a function that returns the path to draw
// this way we can change the path at runtime
var canvas = context.Canvas;
var y = Y;

// Note: LiveCharts geometries do not implement INotifyPropertyChanged
// so if you change the path at runtime you will need to call a chart update.
while (y < Y + Height)
{
canvas.DrawLine(X, y, X + Width, y, paint);
y += 10;
}
}

public static SKPath? SelectedPath { get; set; }
}
48 changes: 12 additions & 36 deletions samples/ViewModelsSamples/Bars/Custom/ViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,56 +1,32 @@
using System.Collections.Generic;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.ComponentModel;
using LiveChartsCore;
using LiveChartsCore.Drawing;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;

namespace ViewModelsSamples.Bars.Custom;

public partial class ViewModel : ObservableObject
{
public ViewModel()
{
Series = new ISeries[]
public ISeries[] Series { get; set; } =
{
new ColumnSeries<double>
{
Values = new List<double> { 4, 3, 2, 1 },
Fill = new SolidColorPaint(SKColors.CornflowerBlue)
Values = new double[] { 2, 1, 4, 2, 2, -5, -2 },
},

// use the second argument type to specify the geometry to draw for every point
// there are already many predefined geometries in the
// LiveChartsCore.SkiaSharpView.Drawing.Geometries namespace
new ColumnSeries<double, OvalGeometry>
// You can also use SVG paths to draw the geometry
// LiveCharts already provides some predefined paths in the SVGPoints class.
new ColumnSeries<double, SVGPathGeometry>
{
Values = new double[] { 4, 3, 2, 1 },
Fill = new SolidColorPaint(SKColors.DarkRed)
Values = new double[] { -2, 2, 1, 3, -1, 4, 3 },
GeometrySvg = SVGPoints.Gem
},

// you can also define your own SVG geometry
// MyGeometry class let us change the Path at runtime
// Click on the on any point to change the path.
// You can find the MyGeometry.cs file below
// you can declare your own gemetry and use the SkiaSharp api to draw it
new ColumnSeries<double, MyGeometry>
{
Values = new double[] { 4, 3, 2, 1 },
Fill = new SolidColorPaint(SKColors.Black)
}
Values = new double[] { 4, 5, 2, 4, 3, 2, 1 },
},
};

// We can change the MyGeometry path at runtime
// the SVGPoints class contains many predefined paths
// MyGeometry.SelectedPath = SVGPoints.Gem;

// You can also build your own path.
MyGeometry.SelectedPath = SKPath.ParseSvgPathData(
"M6 4C6 3.44772 6.44772 3 7 3H17C17.5523 3 18 3.44772 18 4V18C18 18.5523 17.5523 19 17 19H7C6.44772 " +
"19 6 18.5523 6 18V4ZM7 1C5.34315 1 4 2.34315 4 4V20C4 21.6569 5.34315 23 7 " +
"23H17C18.6569 23 20 21.6569 20 20V4C20 2.34315 18.6569 1 17 1H7ZM12 22C12.5523 22 13 21.5523 13 " +
"21C13 20.4477 12.5523 20 12 20C11.4477 20 11 20.4477 11 21C11 21.5523 11.4477 22 12 22Z");
}

public ISeries[] Series { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public LvcSize Measure(Chart<SkiaSharpDrawingContext> chart)
{
new SVGVisual
{
Path = SVGPoints.Star, // or define your own svg path: SKPath.ParseSvgPathData(...)
Path = SKPath.ParseSvgPathData(SVGPoints.Star),
Width = 25,
Height = 25,
Fill = new SolidColorPaint(theme.GetSeriesColor(series).AsSKColor()) {ZIndex = s_zIndex + 1 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public partial class ViewModel : ObservableObject
},
new SVGVisual
{
Path = SVGPoints.Star,
Path = SKPath.ParseSvgPathData(SVGPoints.Star),
X = 80,
Y = 80,
LocationUnit = MeasureUnit.Pixels,
Expand Down
19 changes: 8 additions & 11 deletions samples/ViewModelsSamples/Lines/Custom/MyGeometry.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
using System;
using LiveChartsCore.SkiaSharpView.Drawing;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using SkiaSharp;

namespace ViewModelsSamples.Lines.Custom;

public class MyGeometry : LiveChartsCore.SkiaSharpView.Drawing.Geometries.SVGPathGeometry
public class MyGeometry : SizedGeometry
{
public MyGeometry()
: base(() => SelectedPath ?? throw new NotImplementedException("Path not set yet!"))
public override void OnDraw(SkiaSharpDrawingContext context, SKPaint paint)
{
// we passed the "path source" to the base class
// it is a function that returns the path to draw
// this way we can change the path at runtime
var canvas = context.Canvas;

// Note: LiveCharts geometries do not implement INotifyPropertyChanged
// so if you change the path at runtime you will need to call a chart update.
canvas.DrawRect(X, Y, Width, Height, paint);
canvas.DrawLine(X, Y, X + Width, Y + Height, paint);
canvas.DrawLine(X + Width, Y, X, Y + Height, paint);
}

public static SKPath? SelectedPath { get; set; }
}
71 changes: 21 additions & 50 deletions samples/ViewModelsSamples/Lines/Custom/ViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,77 +1,48 @@
using CommunityToolkit.Mvvm.ComponentModel;
using LiveChartsCore;
using LiveChartsCore.Kernel;
using LiveChartsCore.Kernel.Sketches;
using LiveChartsCore.Drawing;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;

namespace ViewModelsSamples.Lines.Custom;

public partial class ViewModel : ObservableObject
{
public ViewModel()
{
Series = new ISeries[]
public ISeries[] Series { get; set; } =
{
new LineSeries<double>
{
Values = new double[] { 3, 1, 4, 3, 2, -5, -2 },
GeometrySize = 10,
Fill = null
Values = new double[] { 2, 1, 4, 2, 2, -5, -2 },
Fill = null,
GeometrySize = 20
},

// use the second argument type to specify the geometry to draw for every point
// use the second type parameter to specify the geometry to draw for every point
// there are already many predefined geometries in the
// LiveChartsCore.SkiaSharpView.Drawing.Geometries namespace
new LineSeries<double, RectangleGeometry>
{
Values = new double[] { 3, 3, -3, -2, -4, -3, -1 },
Fill = null
Fill = null,
GeometrySize = 20
},

// you can also define your own SVG geometry
// MyGeometry class let us change the Path at runtime
// Click on the on any point to change the path.
// You can find the MyGeometry.cs file below
new LineSeries<double, MyGeometry>
// You can also use SVG paths to draw the geometry
// LiveCharts already provides some predefined paths in the SVGPoints class.
new LineSeries<double, SVGPathGeometry>
{
Values = new double[] { -2, 2, 1, 3, -1, 4, 3 },

Stroke = new SolidColorPaint(SKColors.DarkOliveGreen, 3),
Fill = null,
GeometryStroke = new SolidColorPaint(SKColors.DarkOliveGreen, 3),
GeometryFill = new SolidColorPaint(SKColors.White),
GeometrySize = 35
}
};

// We can change the MyGeometry path at runtime
// the SVGPoints class contains many predefined paths
MyGeometry.SelectedPath = SVGPoints.Gem;

var variableGeometrySeries = (LineSeries<double, MyGeometry>)Series[2];
GeometrySvg = SVGPoints.Star,
GeometrySize = 20
},

// We toggle the geometry path on click
variableGeometrySeries.ChartPointPointerDown +=
(IChartView chart, ChartPoint<double, MyGeometry, LabelGeometry>? point) =>
// you can declare your own gemetry and use the SkiaSharp api to draw it
new LineSeries<double, MyGeometry>
{
MyGeometry.SelectedPath = MyGeometry.SelectedPath == SVGPoints.Gem
? SVGPoints.Star
: SVGPoints.Gem;

// call chart update to refresh the chart
chart.CoreChart.Update();
};

// You can also build your own path.
// MyGeometry.SelectedPath = SKPath.ParseSvgPathData(
// "M20.05 17.65C20.8054 17.0834 21.25 16.1943 21.25 15.25V4.25C21.25 " +
// "2.59315 19.9069 1.25 18.25 1.25H6.25C4.59315 1.25 3.25 2.59315 3.25 " +
// "4.25V15.25C3.25 16.1943 3.69458 17.0834 4.45 17.65L10.45 22.15C11.5167 " +
// "22.95 12.9833 22.95 14.05 22.15L20.05 17.65Z");
}

public ISeries[] Series { get; set; }
Values = new double[] { 4, 5, 2, 4, 3, 2, 1 },
Fill = null,
GeometrySize = 20
},
};
}
25 changes: 13 additions & 12 deletions samples/ViewModelsSamples/Scatter/Custom/MyGeometry.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using LiveChartsCore.SkiaSharpView.Drawing;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using SkiaSharp;

namespace ViewModelsSamples.Scatter.Custom;

public class MyGeometry : SVGPathGeometry
public class MyGeometry : SizedGeometry
{
// 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 override void OnDraw(SkiaSharpDrawingContext context, SKPaint paint)
{
var canvas = context.Canvas;
var y = Y;

public MyGeometry()
: base(svgPath)
{ }
while (y < Y + Height)
{
canvas.DrawLine(X, y, X + Width, y, paint);
y += 10;
}
}
}
19 changes: 14 additions & 5 deletions samples/ViewModelsSamples/Scatter/Custom/ViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.ComponentModel;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.Drawing;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using LiveChartsCore.SkiaSharpView.Painting;
Expand All @@ -17,16 +18,18 @@ public ViewModel()
var r = new Random();
var values1 = new ObservableCollection<ObservablePoint>();
var values2 = new ObservableCollection<ObservablePoint>();
var values3 = 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)));
values3.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
// use the second type parameter 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>
Expand All @@ -36,13 +39,19 @@ public ViewModel()
GeometrySize = 40,
},

// Or Define your own SVG geometry
new ScatterSeries<ObservablePoint, MyGeometry>
// You can also use SVG paths to draw the geometry
// LiveCharts already provides some predefined paths in the SVGPoints class.
new ScatterSeries<ObservablePoint, SVGPathGeometry>
{
Values = values2,
GeometrySvg = SVGPoints.Heart
},

// you can declare your own gemetry and use the SkiaSharp api to draw it
new ScatterSeries<ObservablePoint, MyGeometry>
{
Values = values3,
GeometrySize = 40,
Stroke = null,
Fill = new SolidColorPaint(SKColors.DarkOliveGreen)
}
};
}
Expand Down
33 changes: 1 addition & 32 deletions samples/ViewModelsSamples/StepLines/Custom/ViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using CommunityToolkit.Mvvm.ComponentModel;
using LiveChartsCore;
using LiveChartsCore.Kernel;
using LiveChartsCore.Kernel.Sketches;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using LiveChartsCore.SkiaSharpView.Painting;
Expand Down Expand Up @@ -31,11 +29,7 @@ public ViewModel()
Fill = null
},

// you can also define your own SVG geometry
// MyGeometry class let us change the Path at runtime
// Click on the on any point to change the path.
// You can find the MyGeometry.cs file below
new StepLineSeries<double, MyGeometry>
new StepLineSeries<double, SVGPathGeometry>
{
Values = new double[] { -2, 2, 1, 3, -1, 4, 3 },

Expand All @@ -46,31 +40,6 @@ public ViewModel()
GeometrySize = 35
}
};

// We can change the MyGeometry path at runtime
// the SVGPoints class contains many predefined paths
MyGeometry.SelectedPath = SVGPoints.Gem;

var variableGeometrySeries = (StepLineSeries<double, MyGeometry>)Series[2];

// We toggle the geometry path on click
variableGeometrySeries.ChartPointPointerDown +=
(IChartView chart, ChartPoint<double, MyGeometry, LabelGeometry>? point) =>
{
MyGeometry.SelectedPath = MyGeometry.SelectedPath == SVGPoints.Gem
? SVGPoints.Star
: SVGPoints.Gem;

// call chart update to refresh the chart
chart.CoreChart.Update();
};

// You can also build your own path.
// MyGeometry.SelectedPath = SKPath.ParseSvgPathData(
// "M20.05 17.65C20.8054 17.0834 21.25 16.1943 21.25 15.25V4.25C21.25 " +
// "2.59315 19.9069 1.25 18.25 1.25H6.25C4.59315 1.25 3.25 2.59315 3.25 " +
// "4.25V15.25C3.25 16.1943 3.69458 17.0834 4.45 17.65L10.45 22.15C11.5167 " +
// "22.95 12.9833 22.95 14.05 22.15L20.05 17.65Z");
}

public ISeries[] Series { get; set; }
Expand Down
4 changes: 1 addition & 3 deletions src/LiveChartsCore/BarSeries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,8 @@ public override Sketch<TDrawingContext> GetMiniaturesSketch()
if (Fill is not null) schedules.Add(BuildMiniatureSchedule(Fill, new TVisual()));
if (Stroke is not null) schedules.Add(BuildMiniatureSchedule(Stroke, new TVisual()));

return new Sketch<TDrawingContext>()
return new Sketch<TDrawingContext>(MiniatureShapeSize, MiniatureShapeSize, GeometrySvg)
{
Height = MiniatureShapeSize,
Width = MiniatureShapeSize,
PaintSchedules = schedules
};
}
Expand Down