Customize default legends

You can quickly change the position, the font, the text size or the background color:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="MauiSample.Axes.Multiple.View"
             xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.Maui;assembly=LiveChartsCore.SkiaSharpView.Maui"
             xmlns:vms="clr-namespace:ViewModelsSamples.Axes.Multiple;assembly=ViewModelsSamples"
             >
    <ContentPage.BindingContext>
        <vms:ViewModel/>
    </ContentPage.BindingContext>
    <lvc:CartesianChart
        Series="{Binding Series}"
        YAxes="{Binding YAxes}"
        LegendPosition="Bottom"
        LegendBackgroundPaint="{Binding LegendTextPaint}"
        LegendTextPaint="{Binding LegendTextPaint}"
        LegendTextSize="16">
    </lvc:CartesianChart>
</ContentPage>

View model

[ObservableObject]
public partial class ViewModel
{
    public ISeries[] Series { get; set; } = { ... };
    public Axis[] YAxes { get; set; } = { ... };

    public SolidColorPaint LegendTextPaint { get; set; } = // mark
        new SolidColorPaint // mark
        { // mark
            Color = new SKColor(50, 50, 50), // mark
            SKTypeface = SKTypeface.FromFamilyName("Courier New") // mark
        }; // mark

    public SolidColorPaint LegendBackgroundPaint { get; set; } = // mark
        new SolidColorPaint(new SKColor(240, 240, 240)); // mark
}

custom

Override the default legend behavior

You can inherit from SKDefaultLegend and override the GetLayout() method to define your own template, in the next example we set a larger miniature compared with the default size.

CustomLegend.cs

using System.Linq;
using LiveChartsCore;
using LiveChartsCore.Drawing;
using LiveChartsCore.Drawing.Layouts;
using LiveChartsCore.SkiaSharpView.Drawing;
using LiveChartsCore.SkiaSharpView.Drawing.Layouts;
using LiveChartsCore.SkiaSharpView.SKCharts;

namespace ViewModelsSamples.General.TemplatedLegends;

public class CustomLegend : SKDefaultLegend
{
    protected override Layout<SkiaSharpDrawingContext> GetLayout(Chart chart)
    {
        var stackLayout = new StackLayout
        {
            Orientation = ContainerOrientation.Vertical,
            Padding = new Padding(15, 4),
            HorizontalAlignment = Align.Start,
            VerticalAlignment = Align.Middle,
        };

        foreach (var series in chart.Series.Where(x => x.IsVisibleAtLegend))
            stackLayout.Children.Add(new LegendItem(series));

        return stackLayout;
    }
}

LegendItem.cs

using LiveChartsCore;
using LiveChartsCore.Drawing;
using LiveChartsCore.SkiaSharpView.Drawing;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
using LiveChartsCore.SkiaSharpView.Drawing.Layouts;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;

namespace ViewModelsSamples.General.TemplatedLegends;

public class LegendItem : StackLayout
{
    public LegendItem(ISeries series)
    {
        Orientation = ContainerOrientation.Horizontal;
        Padding = new Padding(12, 6);
        VerticalAlignment = Align.Middle;
        HorizontalAlignment = Align.Middle;
        Opacity = series.IsVisible ? 1 : 0.5f;

        var miniature = (IDrawnElement<SkiaSharpDrawingContext>)series.GetMiniatureGeometry(null);
        if (miniature is BoundedDrawnGeometry bounded)
            bounded.Height = 40;

        Children = [
            miniature,
            new LabelGeometry
            {
                Text = series.Name ?? "?",
                TextSize = 20,
                Paint = new SolidColorPaint(new SKColor(30, 30, 30)),
                Padding = new Padding(8, 2, 0, 2),
                VerticalAlign = Align.Start,
                HorizontalAlign = Align.Start
            }
        ];
    }
}

View

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="MauiSample.General.TemplatedLegends.View"
             xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:core="clr-namespace:LiveChartsCore;assembly=LiveChartsCore"
             xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.Maui;assembly=LiveChartsCore.SkiaSharpView.Maui"
             xmlns:vms="clr-namespace:ViewModelsSamples.General.TemplatedLegends;assembly=ViewModelsSamples"
             >

    <ContentPage.BindingContext>
        <vms:ViewModel/>
    </ContentPage.BindingContext>

    <ContentPage.Content>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <lvc:CartesianChart Grid.Row="0" Series="{Binding Series}" LegendPosition="Right">
                <!-- mark -untilCloses CartesianChart.Legend -->
                <lvc:CartesianChart.Legend>
                    <vms:CustomLegend></vms:CustomLegend>
                </lvc:CartesianChart.Legend>
            </lvc:CartesianChart>
        </Grid>
    </ContentPage.Content>
</ContentPage>

custom legend

Legend control from scratch

You can also create your own legend, the recommended way is to use the LiveCharts API but you can use anything as legend as soon as it implements the IChartLegend interface; You can use the SKDefaultLegend source code as a guide to build your own implementation, this class is the default legend used by the library.

Instead of using the LiveCharts API you can use your UI framework, see #1558 for more info, in that ticket, there is an example that implements the IChartTooltip interface on a WPF control, then LiveCharts uses this WPF control as the tooltip, even that example implements IChartTooltip, there are no big differences from creating a control that implements IChartLegend.