diff --git a/src/LiveChartsCore/CoreHeatLandSeries.cs b/src/LiveChartsCore/CoreHeatLandSeries.cs
index 6892307c3..ed34a1adb 100644
--- a/src/LiveChartsCore/CoreHeatLandSeries.cs
+++ b/src/LiveChartsCore/CoreHeatLandSeries.cs
@@ -102,7 +102,7 @@ public void Measure(MapContext context)
if (!_isHeatInCanvas)
{
- context.View.Canvas.AddDrawableTask(_heatPaint);
+ context.View.CoreCanvas.AddDrawableTask(_heatPaint);
_isHeatInCanvas = true;
}
@@ -124,7 +124,7 @@ public void Measure(MapContext context)
foreach (var land in Lands ?? [])
{
_ = Maps.BuildProjector(
- context.View.MapProjection, [context.View.Width, context.View.Height]);
+ context.View.MapProjection, [context.View.ControlSize.Width, context.View.ControlSize.Height]);
var heat = HeatFunctions.InterpolateColor((float)land.Value, bounds, HeatMap, heatStops);
@@ -156,8 +156,11 @@ public void Delete(MapContext context)
///
/// Initializes the series.
///
- protected void IntitializeSeries(Paint heatPaint) =>
+ protected void IntitializeSeries(Paint heatPaint)
+ {
+ heatPaint.PaintStyle = PaintStyle.Fill;
_heatPaint = heatPaint;
+ }
///
/// Called to invoke the property changed event.
diff --git a/src/LiveChartsCore/Geo/IGeoMapView.cs b/src/LiveChartsCore/Geo/IGeoMapView.cs
index 3b88e947f..5279e7a69 100644
--- a/src/LiveChartsCore/Geo/IGeoMapView.cs
+++ b/src/LiveChartsCore/Geo/IGeoMapView.cs
@@ -22,7 +22,7 @@
using System;
using System.Collections.Generic;
-using LiveChartsCore.Motion;
+using LiveChartsCore.Kernel.Sketches;
using LiveChartsCore.Painting;
namespace LiveChartsCore.Geo;
@@ -30,28 +30,13 @@ namespace LiveChartsCore.Geo;
///
/// Defines a geographic map.
///
-public interface IGeoMapView
+public interface IGeoMapView : IDrawnView
{
///
/// Gets or sets the active map.
///
DrawnMap ActiveMap { get; set; }
- ///
- /// Gets the motion canvas.
- ///
- CoreMotionCanvas Canvas { get; }
-
- ///
- /// Gets the control width.
- ///
- float Width { get; }
-
- ///
- /// Gets the control height.
- ///
- float Height { get; }
-
///
/// Gets or sets the stroke.
///
@@ -83,10 +68,10 @@ public interface IGeoMapView
///
object SyncContext { get; set; }
- ///
- /// Gets or sets the view command.
- ///
- object? ViewCommand { get; set; }
+ /////
+ ///// Gets or sets the view command.
+ /////
+ //object? ViewCommand { get; set; }
///
/// Invokes an action in the UI thread.
diff --git a/src/LiveChartsCore/GeoMapChart.cs b/src/LiveChartsCore/GeoMapChart.cs
index 5319976f5..e8675cc91 100644
--- a/src/LiveChartsCore/GeoMapChart.cs
+++ b/src/LiveChartsCore/GeoMapChart.cs
@@ -111,8 +111,8 @@ public virtual void Update(ChartUpdateParams? chartUpdateParams = null)
///
public void Unload()
{
- if (View.Stroke is not null) View.Canvas.RemovePaintTask(View.Stroke);
- if (View.Fill is not null) View.Canvas.RemovePaintTask(View.Fill);
+ if (View.Stroke is not null) View.CoreCanvas.RemovePaintTask(View.Stroke);
+ if (View.Fill is not null) View.CoreCanvas.RemovePaintTask(View.Fill);
_everMeasuredSeries.Clear();
_heatPaint = null!;
@@ -125,7 +125,7 @@ public void Unload()
_activeMap = null!;
_mapFactory = null!;
- View.Canvas.Dispose();
+ View.CoreCanvas.Dispose();
}
///
@@ -161,7 +161,7 @@ protected virtual Task UpdateThrottlerUnlocked()
{
View.InvokeOnUIThread(() =>
{
- lock (View.Canvas.Sync)
+ lock (View.CoreCanvas.Sync)
{
if (_isUnloaded) return;
Measure();
@@ -177,32 +177,32 @@ protected internal void Measure()
{
if (_activeMap is not null && _activeMap != View.ActiveMap)
{
- _previousStroke?.ClearGeometriesFromPaintTask(View.Canvas);
- _previousFill?.ClearGeometriesFromPaintTask(View.Canvas);
+ _previousStroke?.ClearGeometriesFromPaintTask(View.CoreCanvas);
+ _previousFill?.ClearGeometriesFromPaintTask(View.CoreCanvas);
_previousFill = null;
_previousStroke = null;
- View.Canvas.Clear();
+ View.CoreCanvas.Clear();
}
_activeMap = View.ActiveMap;
if (!_isHeatInCanvas)
{
- View.Canvas.AddDrawableTask(_heatPaint);
+ View.CoreCanvas.AddDrawableTask(_heatPaint);
_isHeatInCanvas = true;
}
if (_previousStroke != View.Stroke)
{
if (_previousStroke is not null)
- View.Canvas.RemovePaintTask(_previousStroke);
+ View.CoreCanvas.RemovePaintTask(_previousStroke);
if (View.Stroke is not null)
{
if (View.Stroke.ZIndex == 0) View.Stroke.ZIndex = PaintConstants.GeoMapStrokeZIndex;
View.Stroke.PaintStyle = PaintStyle.Stroke;
- View.Canvas.AddDrawableTask(View.Stroke);
+ View.CoreCanvas.AddDrawableTask(View.Stroke);
}
_previousStroke = View.Stroke;
@@ -211,12 +211,12 @@ protected internal void Measure()
if (_previousFill != View.Fill)
{
if (_previousFill is not null)
- View.Canvas.RemovePaintTask(_previousFill);
+ View.CoreCanvas.RemovePaintTask(_previousFill);
if (View.Fill is not null)
{
View.Fill.PaintStyle = PaintStyle.Fill;
- View.Canvas.AddDrawableTask(View.Fill);
+ View.CoreCanvas.AddDrawableTask(View.Fill);
}
_previousFill = View.Fill;
@@ -227,7 +227,7 @@ protected internal void Measure()
var context = new MapContext(
this, View, View.ActiveMap,
- Maps.BuildProjector(View.MapProjection, [View.Width, View.Height]));
+ Maps.BuildProjector(View.MapProjection, [View.ControlSize.Width, View.ControlSize.Height]));
_mapFactory.GenerateLands(context);
@@ -245,7 +245,7 @@ protected internal void Measure()
_ = _everMeasuredSeries.Remove(series);
}
- View.Canvas.Invalidate();
+ View.CoreCanvas.Invalidate();
}
private Task PanningThrottlerUnlocked()
@@ -253,7 +253,7 @@ private Task PanningThrottlerUnlocked()
return Task.Run(() =>
View.InvokeOnUIThread(() =>
{
- lock (View.Canvas.Sync)
+ lock (View.CoreCanvas.Sync)
{
Pan(
new LvcPoint(
diff --git a/src/LiveChartsCore/Kernel/Sketches/IChartView.cs b/src/LiveChartsCore/Kernel/Sketches/IChartView.cs
index 543743878..86185723c 100644
--- a/src/LiveChartsCore/Kernel/Sketches/IChartView.cs
+++ b/src/LiveChartsCore/Kernel/Sketches/IChartView.cs
@@ -25,7 +25,6 @@
using LiveChartsCore.Drawing;
using LiveChartsCore.Kernel.Events;
using LiveChartsCore.Measure;
-using LiveChartsCore.Motion;
using LiveChartsCore.Painting;
using LiveChartsCore.Themes;
using LiveChartsCore.VisualElements;
@@ -35,7 +34,7 @@ namespace LiveChartsCore.Kernel.Sketches;
///
/// Defines a chart view
///
-public interface IChartView
+public interface IChartView : IDrawnView
{
///
/// Gets or sets the series collection.
@@ -80,14 +79,6 @@ public interface IChartView
///
LvcColor BackColor { get; }
- ///
- /// Gets the size of the control.
- ///
- ///
- /// The size of the control.
- ///
- LvcSize ControlSize { get; }
-
///
/// Gets or sets the draw margin, if this property is null, the library will calculate a margin, this margin is the distance
/// between the view bounds and the drawable area.
@@ -176,14 +167,6 @@ public interface IChartView
///
bool AutoUpdateEnabled { get; set; }
- ///
- /// Gets the core canvas.
- ///
- ///
- /// The core canvas.
- ///
- CoreMotionCanvas CoreCanvas { get; }
-
///
/// Gets or sets the chart title.
///
diff --git a/src/LiveChartsCore/Kernel/Sketches/IDrawnView.cs b/src/LiveChartsCore/Kernel/Sketches/IDrawnView.cs
new file mode 100644
index 000000000..a9fb443fb
--- /dev/null
+++ b/src/LiveChartsCore/Kernel/Sketches/IDrawnView.cs
@@ -0,0 +1,45 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using LiveChartsCore.Drawing;
+using LiveChartsCore.Motion;
+
+namespace LiveChartsCore.Kernel.Sketches;
+
+///
+/// Defines a drawn view.
+///
+public interface IDrawnView
+{
+ ///
+ /// Gets the motion canvas.
+ ///
+ CoreMotionCanvas CoreCanvas { get; }
+
+ ///
+ /// Gets the size of the control.
+ ///
+ ///
+ /// The size of the control.
+ ///
+ LvcSize ControlSize { get; }
+}
diff --git a/src/skiasharp/LiveChartsCore.SkiaSharp.Avalonia/GeoMap.cs b/src/skiasharp/LiveChartsCore.SkiaSharp.Avalonia/GeoMap.cs
index 86ef8df91..2fea3fb14 100644
--- a/src/skiasharp/LiveChartsCore.SkiaSharp.Avalonia/GeoMap.cs
+++ b/src/skiasharp/LiveChartsCore.SkiaSharp.Avalonia/GeoMap.cs
@@ -20,255 +20,17 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-using System;
-using System.Collections.Generic;
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Input;
-using Avalonia.Markup.Xaml;
-using Avalonia.Media;
-using Avalonia.Threading;
-using LiveChartsCore.Drawing;
using LiveChartsCore.Geo;
-using LiveChartsCore.Kernel.Observers;
-using LiveChartsCore.Measure;
-using LiveChartsCore.Motion;
-using LiveChartsCore.Painting;
-using LiveChartsCore.SkiaSharpView.Painting;
-using SkiaSharp;
-namespace LiveChartsCore.SkiaSharpView.Avalonia;
-
-///
-public partial class GeoMap : UserControl, IGeoMapView
-{
- private readonly CollectionDeepObserver _seriesObserver;
- private readonly GeoMapChart _core;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public GeoMap()
- {
- Content = new MotionCanvas();
- _core = new GeoMapChart(this);
- _seriesObserver = new CollectionDeepObserver(() => _core?.Update());
-
- Background = new SolidColorBrush(new Color(0, 0, 0, 0));
-
- PointerWheelChanged += OnPointerWheelChanged;
- PointerPressed += OnPointerPressed;
- PointerMoved += OnPointerMoved;
- PointerExited += OnPointerLeave;
-
- //Shapes = Enumerable.Empty>();
- ActiveMap = Maps.GetWorldMap();
- SyncContext = new object();
-
- DetachedFromVisualTree += GeoMap_DetachedFromVisualTree;
- }
-
- #region dependency props
-
- ///
- /// The active map property.
- ///
- public static readonly AvaloniaProperty ActiveMapProperty =
- AvaloniaProperty.Register(nameof(ActiveMap), null, inherits: true);
-
- ///
- /// The active map property.
- ///
- public static readonly AvaloniaProperty
public abstract partial class ChartView : ContentView
{
- static ChartView()
- {
- if (!LiveChartsCoreMauiAppBuilderExtensions.AreHandlersRegistered)
- {
- throw new InvalidOperationException(
- "Since rc5 version, `.UseLiveCharts()` and `.UseSkiaSharp()` must be " +
- "chained to `.UseMauiApp()`, in the MauiProgram.cs file. For more info see:" +
- "https://livecharts.dev/docs/Maui/2.0.0-rc5/Overview.Installation");
- }
- }
-
internal virtual void OnPressed(object? sender, Native.Events.PressedEventArgs args) { }
internal virtual void OnMoved(object? sender, Native.Events.ScreenEventArgs args) { }
internal virtual void OnReleased(object? sender, Native.Events.PressedEventArgs args) { }
diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/GeoMap.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/GeoMap.cs
index d4de94268..9c995968a 100644
--- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/GeoMap.cs
+++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/GeoMap.cs
@@ -20,241 +20,17 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using LiveChartsCore.Drawing;
using LiveChartsCore.Geo;
-using LiveChartsCore.Kernel.Observers;
-using LiveChartsCore.Measure;
-using LiveChartsCore.Motion;
-using LiveChartsCore.Painting;
-using LiveChartsCore.SkiaSharpView.Painting;
-using Microsoft.Maui;
-using Microsoft.Maui.ApplicationModel;
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Controls.Xaml;
-using SkiaSharp;
-using Paint = LiveChartsCore.Painting.Paint;
-namespace LiveChartsCore.SkiaSharpView.Maui;
-
-///
-[XamlCompilation(XamlCompilationOptions.Compile)]
-public partial class GeoMap : ContentView, IGeoMapView
-{
- private readonly CollectionDeepObserver _seriesObserver;
- private readonly GeoMapChart _core;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public GeoMap()
- {
- Content = new MotionCanvas(false);
- _core = new GeoMapChart(this);
-
- SizeChanged += GeoMap_SizeChanged;
-
- _seriesObserver = new CollectionDeepObserver(() => _core.Update());
-
- SetValue(SeriesProperty, Enumerable.Empty());
- SetValue(ActiveMapProperty, Maps.GetWorldMap());
- SetValue(SyncContextProperty, new object());
- }
-
- #region dependency props
-
- ///
- /// The active map property
- ///
- public static readonly BindableProperty ActiveMapProperty =
- BindableProperty.Create(
- nameof(ActiveMap), typeof(DrawnMap), typeof(GeoMap), null, BindingMode.Default, null, OnBindablePropertyChanged);
-
- ///
- /// The sync context property
- ///
- public static readonly BindableProperty SyncContextProperty =
- BindableProperty.Create(
- nameof(SyncContext), typeof(object), typeof(GeoMap), null, BindingMode.Default, null, OnBindablePropertyChanged);
-
- ///
- /// The view command property
- ///
- public static readonly BindableProperty ViewCommandProperty =
- BindableProperty.Create(
- nameof(ViewCommand), typeof(object), typeof(GeoMap), null, BindingMode.Default, null,
- (BindableObject o, object oldValue, object newValue) =>
- {
- var chart = (GeoMap)o;
- chart._core.ViewTo(newValue);
- });
-
- ///
- /// The map projection property
- ///
- public static readonly BindableProperty MapProjectionProperty =
- BindableProperty.Create(
- nameof(MapProjection), typeof(MapProjection), typeof(GeoMap),
- MapProjection.Default, BindingMode.Default, null, OnBindablePropertyChanged);
-
- ///
- /// The stroke property
- ///
- public static readonly BindableProperty StrokeProperty =
- BindableProperty.Create(
- nameof(Stroke), typeof(Paint), typeof(GeoMap),
- new SolidColorPaint(new SKColor(255, 255, 255, 255)) { PaintStyle = PaintStyle.Stroke },
- BindingMode.Default, null, OnBindablePropertyChanged);
-
- ///
- /// The fill property
- ///
- public static readonly BindableProperty FillProperty =
- BindableProperty.Create(
- nameof(Fill), typeof(Paint), typeof(GeoMap),
- new SolidColorPaint(new SKColor(240, 240, 240, 255)) { PaintStyle = PaintStyle.Fill },
- BindingMode.Default, null, OnBindablePropertyChanged);
-
- ///
- /// The series property
- ///
- public static readonly BindableProperty SeriesProperty =
- BindableProperty.Create(
- nameof(Series), typeof(IEnumerable), typeof(GeoMap),
- Enumerable.Empty(),
- BindingMode.Default, null, (BindableObject o, object oldValue, object newValue) =>
- {
- var chart = (GeoMap)o;
- var seriesObserver = chart._seriesObserver;
- seriesObserver?.Dispose();
- seriesObserver?.Initialize((IEnumerable)newValue);
- chart._core.Update();
- });
-
- #endregion
-
- #region props
-
- ///
- public bool AutoUpdateEnabled { get; set; } = true;
-
- ///
- bool IGeoMapView.DesignerMode => false;
-
- ///
- public object SyncContext
- {
- get => GetValue(SyncContextProperty);
- set => SetValue(SyncContextProperty, value);
- }
+// ==============================================================================
+//
+// use the LiveChartsGeneratedCode.SourceGenMapChart class to add MAUI specific
+// code, this class is just to expose the GeoMap class in this namespace.
+//
+// ==============================================================================
- ///
- public object? ViewCommand
- {
- get => GetValue(ViewCommandProperty);
- set => SetValue(ViewCommandProperty, value);
- }
-
- ///
- public CoreMotionCanvas Canvas => ((MotionCanvas)Content).CanvasCore;
-
- ///
- public DrawnMap ActiveMap
- {
- get => (DrawnMap)GetValue(ActiveMapProperty);
- set => SetValue(ActiveMapProperty, value);
- }
-
- ///
- float IGeoMapView.Width => (float)Content.Width;
-
- ///
- float IGeoMapView.Height => (float)Content.Height;
-
- ///
- public MapProjection MapProjection
- {
- get => (MapProjection)GetValue(MapProjectionProperty);
- set => SetValue(MapProjectionProperty, value);
- }
-
- ///
- public Paint? Stroke
- {
- get => (Paint)GetValue(StrokeProperty);
- set
- {
- if (value is not null) value.PaintStyle = PaintStyle.Stroke;
- SetValue(StrokeProperty, value);
- }
- }
-
- ///
- public Paint? Fill
- {
- get => (Paint)GetValue(FillProperty);
- set
- {
- if (value is not null) value.PaintStyle = PaintStyle.Fill;
- SetValue(FillProperty, value);
- }
- }
-
- ///
- public IEnumerable Series
- {
- get => (IEnumerable)GetValue(SeriesProperty);
- set => SetValue(SeriesProperty, value);
- }
-
- #endregion
-
- ///
- protected override void OnParentSet()
- {
- base.OnParentSet();
-
- if (Parent == null)
- {
- _core.Unload();
- }
- }
-
- void IGeoMapView.InvokeOnUIThread(Action action) =>
- _ = MainThread.InvokeOnMainThreadAsync(action);
-
- private void GeoMap_SizeChanged(object? sender, EventArgs e) =>
- _core?.Update();
-
- private void PanGestureRecognizer_PanUpdated(object? sender, PanUpdatedEventArgs e)
- {
- if (_core is null) return;
- if (e.StatusType != GestureStatus.Running) return;
-
- var delta = new LvcPoint((float)e.TotalX, (float)e.TotalY);
- _core.Pan(delta);
- }
-
- private void PinchGestureRecognizer_PinchUpdated(object? sender, PinchGestureUpdatedEventArgs e)
- {
- if (e.Status != GestureStatus.Running || Math.Abs(e.Scale - 1) < 0.05 || _core is null) return;
-
- var p = e.ScaleOrigin;
- var w = ((IGeoMapView)this).Width;
- var h = ((IGeoMapView)this).Width;
-
- _core.ViewTo(
- new ZoomOnPointerView(
- new LvcPoint((float)(p.X * w), (float)(p.Y * h)),
- e.Scale > 1 ? ZoomDirection.ZoomIn : ZoomDirection.ZoomOut));
- }
+namespace LiveChartsCore.SkiaSharpView.Maui;
- private static void OnBindablePropertyChanged(BindableObject o, object oldValue, object newValue)
- {
- var chart = (GeoMap)o;
- if (chart._core is null) return;
- chart._core.Update();
- }
-}
+///
+public class GeoMap : LiveChartsGeneratedCode.SourceGenMapChart
+{ }
diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsGeneratedCode/SourceGenChart.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsGeneratedCode/SourceGenChart.cs
index d90f52f77..fa6b87690 100644
--- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsGeneratedCode/SourceGenChart.cs
+++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsGeneratedCode/SourceGenChart.cs
@@ -64,7 +64,7 @@ protected SourceGenChart()
private MotionCanvas CanvasView => (MotionCanvas)Content;
- ///
+ ///
public CoreMotionCanvas CoreCanvas => CanvasView.CanvasCore;
bool IChartView.DesignerMode => false;
@@ -79,7 +79,7 @@ LvcColor IChartView.BackColor
: CoreCanvas._virtualBackgroundColor;
}
}
- LvcSize IChartView.ControlSize => new() { Width = (float)Width, Height = (float)Height };
+ LvcSize IDrawnView.ControlSize => new() { Width = (float)Width, Height = (float)Height };
private void OnLoaded(object? sender, EventArgs e)
{
diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsGeneratedCode/SourceGenMapChart.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsGeneratedCode/SourceGenMapChart.cs
new file mode 100644
index 000000000..9353ecb5b
--- /dev/null
+++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsGeneratedCode/SourceGenMapChart.cs
@@ -0,0 +1,71 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using System;
+using LiveChartsCore.Drawing;
+using LiveChartsCore.Geo;
+using LiveChartsCore.Kernel.Sketches;
+using LiveChartsCore.Motion;
+using LiveChartsCore.SkiaSharpView.Maui;
+using Microsoft.Maui.ApplicationModel;
+
+namespace LiveChartsGeneratedCode;
+
+// ==============================================================================
+//
+// this file contains the MAUI specific code for the SourceGenMapChart class,
+// the rest of the code can be found in the _Shared project.
+//
+// ==============================================================================
+
+///
+public abstract partial class SourceGenMapChart : ChartView, IGeoMapView
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected SourceGenMapChart()
+ {
+ Content = new MotionCanvas(false);
+
+ SizeChanged += (s, e) =>
+ CoreChart.Update();
+
+ InitializeChartControl();
+
+ Unloaded += OnUnloaded;
+ }
+
+ private MotionCanvas CanvasView => (MotionCanvas)Content;
+
+ ///
+ public CoreMotionCanvas CoreCanvas => CanvasView.CanvasCore;
+
+ bool IGeoMapView.DesignerMode => false;
+ LvcSize IDrawnView.ControlSize => new() { Width = (float)Width, Height = (float)Height };
+
+ private void OnUnloaded(object? sender, EventArgs e) =>
+ CoreChart?.Unload();
+
+ void IGeoMapView.InvokeOnUIThread(Action action) =>
+ MainThread.BeginInvokeOnMainThread(action);
+}
diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.cs
index c8b869729..ad2a9d275 100644
--- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.cs
+++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.cs
@@ -38,6 +38,14 @@ public class MotionCanvas : AbsoluteLayout
static MotionCanvas()
{
+ if (!LiveChartsCoreMauiAppBuilderExtensions.AreHandlersRegistered)
+ {
+ throw new InvalidOperationException(
+ "`.UseLiveCharts()` and `.UseSkiaSharp()` must be " +
+ "chained to `.UseMauiApp()`, in the MauiProgram.cs file. For more info see: " +
+ "https://livecharts.dev/docs/Maui/latest/Overview.Installation");
+ }
+
_ = LiveChartsSkiaSharp
.EnsureInitialized()
.HasRenderingFactory(
diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/GeoMap.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/GeoMap.cs
deleted file mode 100644
index e61bc2267..000000000
--- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/GeoMap.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-// The MIT License(MIT)
-//
-// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using LiveChartsCore.Drawing;
-using LiveChartsCore.Geo;
-using LiveChartsCore.Kernel.Observers;
-using LiveChartsCore.Kernel.Sketches;
-using LiveChartsCore.Measure;
-using LiveChartsCore.Motion;
-using LiveChartsCore.Painting;
-using LiveChartsCore.SkiaSharpView.Painting;
-using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Controls;
-using Microsoft.UI.Xaml.Input;
-using SkiaSharp;
-
-namespace LiveChartsCore.SkiaSharpView.WinUI;
-
-///
-public sealed partial class GeoMap : UserControl, IGeoMapView
-{
- private readonly GeoMapChart _core;
- private readonly CollectionDeepObserver _seriesObserver;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public GeoMap()
- {
- Content = new MotionCanvas(false);
-
- _core = new GeoMapChart(this);
-
- PointerPressed += OnPointerPressed;
- PointerMoved += OnPointerMoved;
- PointerReleased += OnPointerReleased;
- PointerWheelChanged += OnWheelChanged;
- PointerExited += OnPointerExited;
-
- SizeChanged += GeoMap_SizeChanged;
-
- _seriesObserver = new CollectionDeepObserver(() => _core?.Update());
-
- SetValue(SeriesProperty, Enumerable.Empty());
- SetValue(ActiveMapProperty, Maps.GetWorldMap());
- SetValue(SyncContextProperty, new object());
-
- Unloaded += GeoMap_Unloaded;
- }
-
- #region dependency props
-
- ///
- /// The active map property
- ///
- public static readonly DependencyProperty ActiveMapProperty =
- DependencyProperty.Register(nameof(ActiveMap), typeof(DrawnMap), typeof(GeoMap),
- new PropertyMetadata(null, OnDependencyPropertyChanged));
-
- ///
- /// The sync context property.
- ///
- public static readonly DependencyProperty SyncContextProperty =
- DependencyProperty.Register(
- nameof(SyncContext), typeof(object), typeof(GeoMap), new PropertyMetadata(null, OnDependencyPropertyChanged));
-
- ///
- /// The sync context property.
- ///
- public static readonly DependencyProperty ViewCommandProperty =
- DependencyProperty.Register(
- nameof(ViewCommand), typeof(object), typeof(GeoMap), new PropertyMetadata(null,
- (DependencyObject o, DependencyPropertyChangedEventArgs args) =>
- {
- var chart = (GeoMap)o;
- chart._core.ViewTo(args.NewValue);
- }));
-
- ///
- /// The map projection property
- ///
- public static readonly DependencyProperty MapProjectionProperty =
- DependencyProperty.Register(nameof(MapProjection), typeof(MapProjection), typeof(GeoMap),
- new PropertyMetadata(MapProjection.Default, OnDependencyPropertyChanged));
-
- ///
- /// The series property
- ///
- public static readonly DependencyProperty SeriesProperty =
- DependencyProperty.Register(nameof(Series), typeof(IEnumerable),
- typeof(GeoMap), new PropertyMetadata(null, (DependencyObject o, DependencyPropertyChangedEventArgs args) =>
- {
- var chart = (GeoMap)o;
- var seriesObserver = chart._seriesObserver;
- seriesObserver?.Dispose();
- seriesObserver?.Initialize((IEnumerable)args.NewValue);
- chart._core.Update();
- }));
-
- ///
- /// The stroke property
- ///
- public static readonly DependencyProperty StrokeProperty =
- DependencyProperty.Register(
- nameof(Stroke), typeof(Paint), typeof(GeoMap),
- new PropertyMetadata(new SolidColorPaint(new SKColor(255, 255, 255, 255)) { PaintStyle = PaintStyle.Stroke }, OnDependencyPropertyChanged));
-
- ///
- /// The fill property
- ///
- public static readonly DependencyProperty FillProperty =
- DependencyProperty.Register(
- nameof(Fill), typeof(Paint), typeof(GeoMap),
- new PropertyMetadata(new SolidColorPaint(new SKColor(240, 240, 240, 255)) { PaintStyle = PaintStyle.Fill }, OnDependencyPropertyChanged));
-
- #endregion
-
- #region properties
-
- ///
- public bool AutoUpdateEnabled { get; set; } = true;
-
- ///
- bool IGeoMapView.DesignerMode => Windows.ApplicationModel.DesignMode.DesignModeEnabled;
-
- ///
- public object SyncContext
- {
- get => GetValue(SyncContextProperty);
- set => SetValue(SyncContextProperty, value);
- }
-
- ///
- public object? ViewCommand
- {
- get => GetValue(ViewCommandProperty);
- set => SetValue(ViewCommandProperty, value);
- }
-
- ///
- public CoreMotionCanvas Canvas => ((MotionCanvas)Content).CanvasCore;
-
- ///
- public DrawnMap ActiveMap
- {
- get => (DrawnMap)GetValue(ActiveMapProperty);
- set => SetValue(ActiveMapProperty, value);
- }
-
- ///
- float IGeoMapView.Width => (float)ActualWidth;
-
- ///
- float IGeoMapView.Height => (float)ActualHeight;
-
- ///
- public MapProjection MapProjection
- {
- get => (MapProjection)GetValue(MapProjectionProperty);
- set => SetValue(MapProjectionProperty, value);
- }
-
- ///
- public Paint? Stroke
- {
- get => (Paint)GetValue(StrokeProperty);
- set
- {
- if (value is not null) value.PaintStyle = PaintStyle.Stroke;
- SetValue(StrokeProperty, value);
- }
- }
-
- ///
- public Paint? Fill
- {
- get => (Paint)GetValue(FillProperty);
- set
- {
- if (value is not null) value.PaintStyle = PaintStyle.Fill;
- SetValue(FillProperty, value);
- }
- }
-
- ///
- public IEnumerable Series
- {
- get => (IEnumerable)GetValue(SeriesProperty);
- set => SetValue(SeriesProperty, value);
- }
-
- #endregion
-
- void IGeoMapView.InvokeOnUIThread(Action action)
- {
- _ = DispatcherQueue.TryEnqueue(
- Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal,
- () => action());
- }
-
- private void GeoMap_SizeChanged(object sender, SizeChangedEventArgs e) =>
- _core.Update();
-
- private void GeoMap_Unloaded(object sender, RoutedEventArgs e) =>
- _core.Unload();
-
- private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
- {
- _ = CapturePointer(e.Pointer);
- var p = e.GetCurrentPoint(this);
- _core?.InvokePointerDown(new LvcPoint((float)p.Position.X, (float)p.Position.Y));
- }
-
- private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
- {
- var p = e.GetCurrentPoint(this);
- _core?.InvokePointerMove(new LvcPoint((float)p.Position.X, (float)p.Position.Y));
- }
-
- private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
- {
- var p = e.GetCurrentPoint(this);
- _core?.InvokePointerUp(new LvcPoint((float)p.Position.X, (float)p.Position.Y));
- ReleasePointerCapture(e.Pointer);
- }
-
- private void OnPointerExited(object sender, PointerRoutedEventArgs e) =>
- _core?.InvokePointerLeft();
-
- private void OnWheelChanged(object sender, PointerRoutedEventArgs e)
- {
- if (_core == null) throw new Exception("core not found");
- var p = e.GetCurrentPoint(this);
-
- _core.ViewTo(
- new ZoomOnPointerView(
- new LvcPoint((float)p.Position.X, (float)p.Position.Y),
- p.Properties.MouseWheelDelta > 0 ? ZoomDirection.ZoomIn : ZoomDirection.ZoomOut));
- }
-
- private static void OnDependencyPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs args)
- {
- var chart = (GeoMap)o;
- chart._core.Update();
- }
-}
diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.WinUI/GeoMap.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.WinUI/GeoMap.cs
deleted file mode 100644
index 92dba5457..000000000
--- a/src/skiasharp/LiveChartsCore.SkiaSharpView.WinUI/GeoMap.cs
+++ /dev/null
@@ -1,267 +0,0 @@
-// The MIT License(MIT)
-//
-// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using LiveChartsCore.Drawing;
-using LiveChartsCore.Geo;
-using LiveChartsCore.Kernel.Observers;
-using LiveChartsCore.Kernel.Sketches;
-using LiveChartsCore.Measure;
-using LiveChartsCore.Motion;
-using LiveChartsCore.Painting;
-using LiveChartsCore.SkiaSharpView.Painting;
-using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Controls;
-using Microsoft.UI.Xaml.Input;
-using SkiaSharp;
-
-namespace LiveChartsCore.SkiaSharpView.WinUI;
-
-///
-public sealed partial class GeoMap : UserControl, IGeoMapView
-{
- private readonly GeoMapChart _core;
- private readonly CollectionDeepObserver _seriesObserver;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public GeoMap()
- {
- Content = new MotionCanvas(false);
- _core = new GeoMapChart(this);
-
- PointerPressed += OnPointerPressed;
- PointerMoved += OnPointerMoved;
- PointerReleased += OnPointerReleased;
- PointerWheelChanged += OnWheelChanged;
- PointerExited += OnPointerExited;
-
- SizeChanged += GeoMap_SizeChanged;
-
- _seriesObserver = new CollectionDeepObserver(() => _core?.Update());
-
- SetValue(SeriesProperty, Enumerable.Empty());
- SetValue(ActiveMapProperty, Maps.GetWorldMap());
- SetValue(SyncContextProperty, new object());
-
- Unloaded += GeoMap_Unloaded;
- }
-
- #region dependency props
-
- ///
- /// The active map property
- ///
- public static readonly DependencyProperty ActiveMapProperty =
- DependencyProperty.Register(nameof(ActiveMap), typeof(DrawnMap), typeof(GeoMap),
- new PropertyMetadata(null, OnDependencyPropertyChanged));
-
- ///
- /// The sync context property.
- ///
- public static readonly DependencyProperty SyncContextProperty =
- DependencyProperty.Register(
- nameof(SyncContext), typeof(object), typeof(GeoMap), new PropertyMetadata(null, OnDependencyPropertyChanged));
-
- ///
- /// The sync context property.
- ///
- public static readonly DependencyProperty ViewCommandProperty =
- DependencyProperty.Register(
- nameof(ViewCommand), typeof(object), typeof(GeoMap), new PropertyMetadata(null,
- (DependencyObject o, DependencyPropertyChangedEventArgs args) =>
- {
- var chart = (GeoMap)o;
- chart._core.ViewTo(args.NewValue);
- }));
-
- ///
- /// The map projection property
- ///
- public static readonly DependencyProperty MapProjectionProperty =
- DependencyProperty.Register(nameof(MapProjection), typeof(MapProjection), typeof(GeoMap),
- new PropertyMetadata(MapProjection.Default, OnDependencyPropertyChanged));
-
- ///
- /// The series property
- ///
- public static readonly DependencyProperty SeriesProperty =
- DependencyProperty.Register(nameof(Series), typeof(IEnumerable),
- typeof(GeoMap), new PropertyMetadata(null, (DependencyObject o, DependencyPropertyChangedEventArgs args) =>
- {
- var chart = (GeoMap)o;
- var seriesObserver = chart._seriesObserver;
- seriesObserver?.Dispose();
- seriesObserver?.Initialize((IEnumerable)args.NewValue);
- chart._core.Update();
- }));
-
- ///
- /// The stroke property
- ///
- public static readonly DependencyProperty StrokeProperty =
- DependencyProperty.Register(
- nameof(Stroke), typeof(Paint), typeof(GeoMap),
- new PropertyMetadata(new SolidColorPaint(new SKColor(255, 255, 255, 255)) { PaintStyle = PaintStyle.Stroke }, OnDependencyPropertyChanged));
-
- ///
- /// The fill property
- ///
- public static readonly DependencyProperty FillProperty =
- DependencyProperty.Register(
- nameof(Fill), typeof(Paint), typeof(GeoMap),
- new PropertyMetadata(new SolidColorPaint(new SKColor(240, 240, 240, 255)) { PaintStyle = PaintStyle.Fill }, OnDependencyPropertyChanged));
-
- #endregion
-
- #region properties
-
- ///
- public bool AutoUpdateEnabled { get; set; } = true;
-
- ///
- bool IGeoMapView.DesignerMode => Windows.ApplicationModel.DesignMode.DesignModeEnabled;
-
- ///
- public object SyncContext
- {
- get => GetValue(SyncContextProperty);
- set => SetValue(SyncContextProperty, value);
- }
-
- ///
- public object? ViewCommand
- {
- get => GetValue(ViewCommandProperty);
- set => SetValue(ViewCommandProperty, value);
- }
-
- ///
- public CoreMotionCanvas Canvas => ((MotionCanvas)Content).CanvasCore;
-
- ///
- public DrawnMap ActiveMap
- {
- get => (DrawnMap)GetValue(ActiveMapProperty);
- set => SetValue(ActiveMapProperty, value);
- }
-
- ///
- float IGeoMapView.Width => (float)ActualWidth;
-
- ///
- float IGeoMapView.Height => (float)ActualHeight;
-
- ///
- public MapProjection MapProjection
- {
- get => (MapProjection)GetValue(MapProjectionProperty);
- set => SetValue(MapProjectionProperty, value);
- }
-
- ///
- public Paint? Stroke
- {
- get => (Paint)GetValue(StrokeProperty);
- set
- {
- if (value is not null) value.PaintStyle = PaintStyle.Stroke;
- SetValue(StrokeProperty, value);
- }
- }
-
- ///
- public Paint? Fill
- {
- get => (Paint)GetValue(FillProperty);
- set
- {
- if (value is not null) value.PaintStyle = PaintStyle.Fill;
- SetValue(FillProperty, value);
- }
- }
-
- ///
- public IEnumerable Series
- {
- get => (IEnumerable)GetValue(SeriesProperty);
- set => SetValue(SeriesProperty, value);
- }
-
- #endregion
-
- void IGeoMapView.InvokeOnUIThread(Action action)
- {
- _ = DispatcherQueue.TryEnqueue(
- Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal,
- () => action());
- }
-
- private void GeoMap_SizeChanged(object sender, SizeChangedEventArgs e) =>
- _core.Update();
-
- private void GeoMap_Unloaded(object sender, RoutedEventArgs e) =>
- _core.Unload();
-
- private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
- {
- _ = CapturePointer(e.Pointer);
- var p = e.GetCurrentPoint(this);
- _core?.InvokePointerDown(new LvcPoint((float)p.Position.X, (float)p.Position.Y));
- }
-
- private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
- {
- var p = e.GetCurrentPoint(this);
- _core?.InvokePointerMove(new LvcPoint((float)p.Position.X, (float)p.Position.Y));
- }
-
- private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
- {
- var p = e.GetCurrentPoint(this);
- _core?.InvokePointerUp(new LvcPoint((float)p.Position.X, (float)p.Position.Y));
- ReleasePointerCapture(e.Pointer);
- }
-
- private void OnPointerExited(object sender, PointerRoutedEventArgs e) =>
- _core?.InvokePointerLeft();
-
- private void OnWheelChanged(object sender, PointerRoutedEventArgs e)
- {
- if (_core == null) throw new Exception("core not found");
- var p = e.GetCurrentPoint(this);
-
- _core.ViewTo(
- new ZoomOnPointerView(
- new LvcPoint((float)p.Position.X, (float)p.Position.Y),
- p.Properties.MouseWheelDelta > 0 ? ZoomDirection.ZoomIn : ZoomDirection.ZoomOut));
- }
-
- private static void OnDependencyPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs args)
- {
- var chart = (GeoMap)o;
- chart._core.Update();
- }
-}
diff --git a/src/skiasharp/_Shared.WinUI/GeoMap.cs b/src/skiasharp/_Shared.WinUI/GeoMap.cs
new file mode 100644
index 000000000..efb6e3486
--- /dev/null
+++ b/src/skiasharp/_Shared.WinUI/GeoMap.cs
@@ -0,0 +1,36 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using LiveChartsCore.Kernel.Sketches;
+
+namespace LiveChartsCore.SkiaSharpView.WinUI;
+
+// ==============================================================================
+//
+// use the LiveChartsGeneratedCode.SourceGenMapChart class to add winui/uno specific
+// code, this class is just to expose the GeoMap class in this namespace.
+//
+// ==============================================================================
+
+///
+public sealed partial class GeoMap : LiveChartsGeneratedCode.SourceGenMapChart
+{ }
diff --git a/src/skiasharp/_Shared.WinUI/LiveChartsGeneratedCode/SourceGenChart.cs b/src/skiasharp/_Shared.WinUI/LiveChartsGeneratedCode/SourceGenChart.cs
index 14f6c76e8..9f806f65a 100644
--- a/src/skiasharp/_Shared.WinUI/LiveChartsGeneratedCode/SourceGenChart.cs
+++ b/src/skiasharp/_Shared.WinUI/LiveChartsGeneratedCode/SourceGenChart.cs
@@ -80,7 +80,7 @@ public SourceGenChart()
private MotionCanvas MotionCanvas => (MotionCanvas)Content;
- ///
+ ///
public CoreMotionCanvas CoreCanvas => MotionCanvas.CanvasCore;
bool IChartView.DesignerMode => false;
@@ -89,7 +89,7 @@ public SourceGenChart()
Background is not SolidColorBrush b
? CoreCanvas._virtualBackgroundColor
: LvcColor.FromArgb(b.Color.A, b.Color.R, b.Color.G, b.Color.B);
- LvcSize IChartView.ControlSize => new() { Width = (float)ActualWidth, Height = (float)ActualHeight };
+ LvcSize IDrawnView.ControlSize => new() { Width = (float)ActualWidth, Height = (float)ActualHeight };
private void OnLoaded(object sender, RoutedEventArgs e)
{
diff --git a/src/skiasharp/_Shared.WinUI/LiveChartsGeneratedCode/SourceGenMapChart.cs b/src/skiasharp/_Shared.WinUI/LiveChartsGeneratedCode/SourceGenMapChart.cs
new file mode 100644
index 000000000..e51c5e7b7
--- /dev/null
+++ b/src/skiasharp/_Shared.WinUI/LiveChartsGeneratedCode/SourceGenMapChart.cs
@@ -0,0 +1,84 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using System;
+using System.Runtime.InteropServices;
+using LiveChartsCore.Drawing;
+using LiveChartsCore.Kernel.Sketches;
+using LiveChartsCore.SkiaSharpView.WinUI;
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+using LiveChartsCore.Motion;
+using LiveChartsCore.Geo;
+
+namespace LiveChartsGeneratedCode;
+
+// ==============================================================================
+//
+// this file contains the WinUI/UNO specific code for the SourceGenMapChart class,
+// the rest of the code can be found in the _Shared project.
+//
+// ==============================================================================
+
+///
+public abstract partial class SourceGenMapChart : UserControl, IGeoMapView
+{
+ private static readonly bool s_isWebAssembly = RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SourceGenMapChart()
+ {
+ Content = new MotionCanvas(false);
+
+ InitializeChartControl();
+
+ SizeChanged += (s, e) =>
+ CoreChart.Update();
+
+ Unloaded += OnUnloaded;
+ }
+
+ private MotionCanvas MotionCanvas => (MotionCanvas)Content;
+
+ ///
+ public CoreMotionCanvas CoreCanvas => MotionCanvas.CanvasCore;
+
+ bool IGeoMapView.DesignerMode => false;
+ LvcSize IDrawnView.ControlSize => new() { Width = (float)ActualWidth, Height = (float)ActualHeight };
+
+ private void OnUnloaded(object sender, RoutedEventArgs e) =>
+ CoreChart.Unload();
+
+ void IGeoMapView.InvokeOnUIThread(Action action)
+ {
+ if (s_isWebAssembly)
+ {
+ action();
+ return;
+ }
+
+ _ = DispatcherQueue.TryEnqueue(
+ Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () => action());
+ }
+}
diff --git a/src/skiasharp/_Shared.WinUI/_Shared.WinUI.projitems b/src/skiasharp/_Shared.WinUI/_Shared.WinUI.projitems
index e77c518f0..8e7910781 100644
--- a/src/skiasharp/_Shared.WinUI/_Shared.WinUI.projitems
+++ b/src/skiasharp/_Shared.WinUI/_Shared.WinUI.projitems
@@ -9,8 +9,10 @@
_Shared.WinUI
+
+
diff --git a/src/skiasharp/_Shared/SourceGenMapChart.cs b/src/skiasharp/_Shared/SourceGenMapChart.cs
new file mode 100644
index 000000000..ec0454c4f
--- /dev/null
+++ b/src/skiasharp/_Shared/SourceGenMapChart.cs
@@ -0,0 +1,54 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using LiveChartsCore;
+using LiveChartsCore.Geo;
+using LiveChartsCore.Kernel.Observers;
+
+namespace LiveChartsGeneratedCode;
+
+///
+#if SKIA_IMAGE_LVC
+public partial class SourceGenSKMapChart : IGeoMapView
+#else
+public partial class SourceGenMapChart : IGeoMapView
+#endif
+{
+ private CollectionDeepObserver _seriesObserver = null!;
+
+ ///
+ /// Gets the core chart.
+ ///
+ public GeoMapChart CoreChart { get; private set; } = null!;
+
+ ///
+ public bool AutoUpdateEnabled { get; set; } = true;
+
+ private void InitializeChartControl()
+ {
+ CoreChart = new GeoMapChart(this);
+ _seriesObserver = new CollectionDeepObserver(() => CoreChart?.Update());
+
+ ActiveMap = Maps.GetWorldMap();
+ SyncContext = new object();
+ }
+}
diff --git a/src/skiasharp/_Shared/SourceGenMapChart.sgp.cs b/src/skiasharp/_Shared/SourceGenMapChart.sgp.cs
new file mode 100644
index 000000000..3550d73d9
--- /dev/null
+++ b/src/skiasharp/_Shared/SourceGenMapChart.sgp.cs
@@ -0,0 +1,135 @@
+// The MIT License(MIT)
+//
+// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable IDE0005 // Using directive is unnecessary.
+#pragma warning disable IDE0060 // Remove unused parameter
+
+using LiveChartsCore;
+using LiveChartsCore.Geo;
+using LiveChartsCore.Generators;
+using System.Windows.Input;
+using System;
+using LiveChartsCore.Painting;
+using System.Collections.Generic;
+using SkiaSharp;
+using LiveChartsCore.Drawing;
+
+#if SKIA_IMAGE_LVC
+using SGChart = LiveChartsGeneratedCode.SourceGenSKMapChart;
+#else
+using SGChart = LiveChartsGeneratedCode.SourceGenMapChart;
+#endif
+
+// ==============================================================================================================
+// the static fileds in this file generate bindable/dependency/avalonia or whatever properties...
+// the disabled warning make it easier to maintain the code.
+//
+#pragma warning disable IDE1006 // Naming Styles
+#pragma warning disable IDE0052 // Remove unread private member
+#pragma warning disable IDE0051 // Remove unused private members
+#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor.
+#pragma warning disable CS0169 // The field is never used
+#pragma warning disable IDE0044 // Add readonly modifier
+#pragma warning disable IDE0040 // Add accessibility modifiers
+#pragma warning disable format
+// ==============================================================================================================
+
+namespace LiveChartsGeneratedCode;
+
+#if SKIA_IMAGE_LVC
+public partial class SourceGenSKMapChart
+#else
+public partial class SourceGenMapChart
+#endif
+{
+ ///
+ static UIProperty syncContext = new(onChanged: OnSyncContextChanged);
+
+ ///
+ static UIProperty activeMap;
+
+ ///
+ static UIProperty mapProjection = new(defaultValue: MapProjection.Default);
+
+ ///
+ static UIProperty stroke = new(defaultValue: GetPaint(new(255, 255, 255, 255), PaintStyle.Stroke), onChanged: OnPaintPropertyChanged(nameof(Stroke)));
+
+ ///
+ static UIProperty fill = new(defaultValue: GetPaint(new(240, 240, 240, 255), PaintStyle.Fill), onChanged: OnPaintPropertyChanged(nameof(Fill)));
+
+ ///
+ static UIProperty> series = new(onChanged: OnSeriesPropertyChanged);
+
+ static void OnSyncContextChanged(SGChart chart, object oldValue, object newValue)
+ {
+#if BLAZOR_LVC
+ // hack for blazor, we need to wait for the OnAfterRender to have
+ // a reference to the canvas in the UI, CoreChart is null until then.
+ if (chart.CoreChart is null) return;
+#endif
+ chart.CoreCanvas.Sync = newValue;
+ chart.CoreChart.Update();
+ }
+
+ static void OnSeriesPropertyChanged(SGChart chart, object oldValue, object newValue)
+ {
+#if BLAZOR_LVC
+ // hack for blazor, we need to wait for the OnAfterRender to have
+ // a reference to the canvas in the UI, CoreChart is null until then.
+ if (chart.CoreChart is null) return;
+#endif
+ chart._seriesObserver?.Dispose();
+ chart._seriesObserver?.Initialize((IEnumerable)newValue);
+ }
+
+ static Action OnPaintPropertyChanged(
+ string propertyName, object? oldValue = null, object? newValue = null) =>
+ (chart, o, n) =>
+ {
+ if (n is not Paint newPaint) return;
+
+ newPaint.PaintStyle = propertyName == nameof(Fill)
+ ? PaintStyle.Fill
+ : PaintStyle.Stroke;
+ };
+
+ static Paint GetPaint(LvcColor color, PaintStyle style)
+ {
+ var paint = LiveCharts.DefaultSettings.GetProvider().GetSolidColorPaint(color);
+ paint.PaintStyle = style;
+ return paint;
+ }
+
+#if AVALONIA_LVC
+ // avalonia hack to mock the DependencyProperty.OnPropertyChanged delegate.
+
+ ///
+ protected override void OnPropertyChanged(Avalonia.AvaloniaPropertyChangedEventArgs change)
+ {
+ base.OnPropertyChanged(change);
+
+ if (change.Property.Name == nameof(IsPointerOver)) return;
+
+ OnXamlPropertyChanged(change);
+ }
+#endif
+}
diff --git a/src/skiasharp/_Shared/_Shared.projitems b/src/skiasharp/_Shared/_Shared.projitems
index 38162f2fc..cb8ecdb34 100644
--- a/src/skiasharp/_Shared/_Shared.projitems
+++ b/src/skiasharp/_Shared/_Shared.projitems
@@ -10,6 +10,8 @@
+
+