Skip to content

Commit

Permalink
Merge pull request #1041 from beto-rodriguez/fixes-731
Browse files Browse the repository at this point in the history
Fixes 731
  • Loading branch information
beto-rodriguez committed Jun 5, 2023
2 parents 0e8d712 + 8ffd831 commit 7c51b18
Show file tree
Hide file tree
Showing 23 changed files with 890 additions and 376 deletions.
103 changes: 31 additions & 72 deletions samples/ViewModelsSamples/General/TemplatedLegends/CustomLegend.cs
@@ -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);
}
}
@@ -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
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

0 comments on commit 7c51b18

Please sign in to comment.