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

Fixes 731 #1041

Merged
merged 13 commits into from
Jun 5, 2023
103 changes: 31 additions & 72 deletions samples/ViewModelsSamples/General/TemplatedLegends/CustomLegend.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Linq;
using LiveChartsCore;
using LiveChartsCore;
using LiveChartsCore.Drawing;
using LiveChartsCore.Kernel.Sketches;
using LiveChartsCore.Measure;
Expand All @@ -12,103 +11,63 @@

namespace ViewModelsSamples.General.TemplatedLegends;

public class CustomLegend : IChartLegend<SkiaSharpDrawingContext>, IImageControl
public class CustomLegend : IChartLegend<SkiaSharpDrawingContext>
{
private static readonly int s_zIndex = 10050;
private StackPanel<RoundedRectangleGeometry, SkiaSharpDrawingContext>? _stackPanel;
private readonly StackPanel<RoundedRectangleGeometry, SkiaSharpDrawingContext> _stackPanel = new();
private readonly SolidColorPaint _backgroundPaint = new(new SKColor(28, 49, 58)) { ZIndex = s_zIndex };
private readonly SolidColorPaint _fontPaint = new(new SKColor(230, 230, 230)) { ZIndex = s_zIndex + 1 };

public LvcSize Size { get; set; }

public void Draw(Chart<SkiaSharpDrawingContext> chart)
{
if (chart.LegendPosition == LegendPosition.Hidden) return;

Measure(chart);
if (_stackPanel is null) return;
var actualChartSize = chart.ControlSize;
var legendPosition = chart.GetLegendPosition();

if (chart.LegendPosition == LegendPosition.Top)
{
chart.Canvas.StartPoint = new LvcPoint(0, Size.Height);
_stackPanel.X = actualChartSize.Width * 0.5f - Size.Width * 0.5f;
_stackPanel.Y = -Size.Height;
}
if (chart.LegendPosition == LegendPosition.Bottom)
{
_stackPanel.X = actualChartSize.Width * 0.5f - Size.Width * 0.5f;
_stackPanel.Y = actualChartSize.Height;
}
if (chart.LegendPosition == LegendPosition.Left)
{
chart.Canvas.StartPoint = new LvcPoint(Size.Width, 0);
_stackPanel.X = -Size.Width;
_stackPanel.Y = actualChartSize.Height * 0.5f - Size.Height * 0.5f;
}
if (chart.LegendPosition == LegendPosition.Right)
{
_stackPanel.X = actualChartSize.Width;
_stackPanel.Y = actualChartSize.Height * 0.5f - Size.Height * 0.5f;
}
_stackPanel.X = legendPosition.X;
_stackPanel.Y = legendPosition.Y;

chart.AddVisual(_stackPanel);
if (chart.LegendPosition == LegendPosition.Hidden) chart.RemoveVisual(_stackPanel);
}

public void Measure(IChart chart)
public LvcSize Measure(Chart<SkiaSharpDrawingContext> chart)
{
var skiaChart = (Chart<SkiaSharpDrawingContext>)chart;
BuildLayout(skiaChart);
if (_stackPanel is null) return;
Size = _stackPanel.Measure(skiaChart);
}

private void BuildLayout(Chart<SkiaSharpDrawingContext> chart)
{
_stackPanel ??= new StackPanel<RoundedRectangleGeometry, SkiaSharpDrawingContext>
{
Padding = new Padding(15),
Orientation = ContainerOrientation.Vertical,
HorizontalAlignment = Align.Start,
VerticalAlignment = Align.Middle,
BackgroundPaint = _backgroundPaint
};
_stackPanel.Orientation = ContainerOrientation.Vertical;
_stackPanel.MaxWidth = double.MaxValue;
_stackPanel.MaxHeight = chart.ControlSize.Height;
_stackPanel.BackgroundPaint = _backgroundPaint;

// clear the previous elements.
foreach (var child in _stackPanel.Children.ToArray())
foreach (var visual in _stackPanel.Children.ToArray())
{
_ = _stackPanel.Children.Remove(child);
chart.RemoveVisual(child);
_ = _stackPanel.Children.Remove(visual);
chart.RemoveVisual(visual);
}

foreach (var series in chart.ChartSeries)
{
var sketch = series.GetMiniaturesSketch();
var relativePanel = sketch.AsDrawnControl();
if (!series.IsVisibleAtLegend) continue;

var label = new LabelVisual
_stackPanel.Children.Add(new StackPanel<RectangleGeometry, SkiaSharpDrawingContext>
{
Text = series.Name ?? string.Empty,
Paint = _fontPaint,
TextSize = 15,
Padding = new Padding(8, 0, 0, 0),
VerticalAlignment = Align.Start,
HorizontalAlignment = Align.Start
};

var sp = new StackPanel<RoundedRectangleGeometry, SkiaSharpDrawingContext>
{
Padding = new Padding(0, 4),
Padding = new Padding(12, 6),
VerticalAlignment = Align.Middle,
HorizontalAlignment = Align.Middle,
Children =
{
relativePanel,
label
series.GetMiniaturesSketch().AsDrawnControl(),
new LabelVisual
{
Text = series.Name ?? string.Empty,
Paint = _fontPaint,
TextSize = 10,
Padding = new Padding(8, 0, 0, 0),
VerticalAlignment = Align.Start,
HorizontalAlignment = Align.Start
}
}
};

_stackPanel?.Children.Add(sp);
});
}

return _stackPanel.Measure(chart);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using LiveChartsCore;
using LiveChartsCore.Drawing;
using LiveChartsCore.Kernel;
Expand All @@ -12,25 +13,30 @@

namespace ViewModelsSamples.General.TemplatedTooltips;

public class CustomTooltip : IChartTooltip<SkiaSharpDrawingContext>, IImageControl
public class CustomTooltip : IChartTooltip<SkiaSharpDrawingContext>
{
private StackPanel<RoundedRectangleGeometry, SkiaSharpDrawingContext>? _stackPanel;
private static readonly int s_zIndex = 10050;
private readonly SolidColorPaint _backgroundPaint = new(new SKColor(28, 49, 58)) { ZIndex = s_zIndex };
private readonly SolidColorPaint _fontPaint = new(new SKColor(230, 230, 230)) { ZIndex = s_zIndex + 1 };

public LvcSize Size { get; private set; }

public void Show(IEnumerable<ChartPoint> foundPoints, Chart<SkiaSharpDrawingContext> chart)
{
_stackPanel ??= new StackPanel<RoundedRectangleGeometry, SkiaSharpDrawingContext>
if (_stackPanel is null)
{
Padding = new Padding(25),
Orientation = ContainerOrientation.Vertical,
HorizontalAlignment = Align.Start,
VerticalAlignment = Align.Middle,
BackgroundPaint = _backgroundPaint
};
_stackPanel = new StackPanel<RoundedRectangleGeometry, SkiaSharpDrawingContext>
{
Padding = new Padding(25),
Orientation = ContainerOrientation.Vertical,
HorizontalAlignment = Align.Start,
VerticalAlignment = Align.Middle,
BackgroundPaint = _backgroundPaint
};

_stackPanel
.Animate(new Animation(
EasingFunctions.ElasticOut, TimeSpan.FromSeconds(1)));
}

// clear the previous elements.
foreach (var child in _stackPanel.Children.ToArray())
Expand All @@ -46,7 +52,7 @@ public void Show(IEnumerable<ChartPoint> foundPoints, Chart<SkiaSharpDrawingCont

var label = new LabelVisual
{
//Text = point.AsTooltipString,
Text = point.SecondaryValue.ToString("C2"),
Paint = _fontPaint,
TextSize = 15,
Padding = new Padding(8, 0, 0, 0),
Expand All @@ -69,22 +75,16 @@ public void Show(IEnumerable<ChartPoint> foundPoints, Chart<SkiaSharpDrawingCont
_stackPanel?.Children.Add(sp);
}

Measure(chart);
var size = _stackPanel.Measure(chart);

var location = foundPoints.GetTooltipLocation(Size, chart);
var location = foundPoints.GetTooltipLocation(size, chart);

_stackPanel.X = location.X;
_stackPanel.Y = location.Y;

chart.AddVisual(_stackPanel);
}

public void Measure(IChart chart)
{
if (_stackPanel is null) return;
Size = _stackPanel.Measure((Chart<SkiaSharpDrawingContext>)chart);
}

public void Hide(Chart<SkiaSharpDrawingContext> chart)
{
if (chart is null || _stackPanel is null) return;
Expand Down
17 changes: 11 additions & 6 deletions src/LiveChartsCore/CartesianChart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -551,10 +551,7 @@ protected internal override void Measure()

InitializeVisualsCollector();

var seriesInLegend = Series.Where(x => x.IsVisibleAtLegend).ToArray();
DrawLegend(seriesInLegend);

// calculate draw margin
// measure and draw title.
var title = View.Title;
var m = new Margin();
float ts = 0f, bs = 0f, ls = 0f, rs = 0f;
Expand All @@ -563,7 +560,17 @@ protected internal override void Measure()
var titleSize = title.Measure(this);
m.Top = titleSize.Height;
ts = titleSize.Height;
_titleHeight = titleSize.Height;
}

// measure and draw legend.
DrawLegend(ref ts, ref bs, ref ls, ref rs);

m.Top = ts;
m.Bottom = bs;
m.Left = ls;
m.Right = rs;

SetDrawMargin(ControlSize, m);

foreach (var axis in XAxes)
Expand Down Expand Up @@ -837,8 +844,6 @@ protected internal override void Measure()
if (_isToolTipOpen) DrawToolTip();
IsFirstDraw = false;
ThemeId = LiveCharts.DefaultSettings.CurrentThemeId;
PreviousSeriesAtLegend = Series.Where(x => x.IsVisibleAtLegend).ToList();
PreviousLegendPosition = LegendPosition;

Canvas.Invalidate();
}
Expand Down