Nested Pies
This sample uses C# 13 preview features such as partial properties, it also uses features from the CommunityToolkit.Mvvm package, you can learn more about it here.
This web site wraps every sample using a ContentPage instance, but LiveCharts controls can be used inside any container.
View model
using System;
using System.Linq;
using LiveChartsCore.Kernel;
namespace ViewModelsSamples.Pies.Nested;
public class SalesRecord(string country, string zone, string name, double value)
{
public string Country { get; set; } = country;
public string Zone { get; set; } = zone;
public string Name { get; set; } = name;
public double Value { get; set; } = value;
}
public class PieData(string name, double?[] values, string color)
{
public string Name { get; set; } = name;
public double?[] Values { get; set; } = values;
public string Color { get; set; } = color;
public bool IsTotal => Name is "Brazil" or "Colombia" or "Mexico";
public Func<ChartPoint, string> Formatter { get; } = point =>
$"{name}{Environment.NewLine}{point.StackedValue!.Share:P2}";
}
public class ViewModel
{
public SalesRecord[] Data { get; set; } = [
new("Brazil", "North", "John", 10),
new("Brazil", "North", "Mary", 5),
new("Brazil", "South", "John", 20),
new("Brazil", "South", "Mary", 8),
new("Colombia", "East", "Carla", 15),
new("Colombia", "East", "Charles", 15),
new("Colombia", "West", "Carla", 25),
new("Colombia", "West", "Charles", 25),
new("Mexico", "Central", "Sophia", 30),
new("Mexico", "Central", "Petter", 5),
new("Mexico", "North", "Sophia", 30),
new("Mexico", "North", "Petter", 5)
];
public PieData[] PieDataCollection { get; set; }
public ViewModel()
{
PieDataCollection = [
new("Brazil", [null, null, Sum("Brazil")], "#1976d2"),
new("North", [null, Sum("Brazil", "North"), null], "#1e88e5"),
new("John", [Sum("Brazil", "North", "John"), null, null], "#2196f3"),
new("Mary", [Sum("Brazil", "North", "Mary"), null, null], "#42a5f5"),
new("South", [null, Sum("Brazil", "South"), null], "#64b5f6"),
new("John", [Sum("Brazil", "South", "John"), null, null], "#90caf9"),
new("Mary", [Sum("Brazil", "South", "Mary"), null, null], "#bbdefb"),
new("Colombia", [null, null, Sum("Colombia")], "#d32f2f"),
new("East", [null, Sum("Colombia", "East"), null], "#e53935"),
new("Carla", [Sum("Colombia", "East", "Carla"), null, null], "#f44336"),
new("Charles", [Sum("Colombia", "East", "Charles"),null, null], "#ef5350"),
new("West", [null, Sum("Colombia", "West"), null], "#e57373"),
new("Carla", [Sum("Colombia", "West", "Carla"), null, null], "#ef9a9a"),
new("Charles", [Sum("Colombia", "West", "Charles"),null, null], "#ffcdd2"),
new("Mexico", [null, null, Sum("Mexico")], "#ffa000"),
new("Central", [null, Sum("Mexico", "Central"), null], "#ffb300"),
new("Sophia", [Sum("Mexico", "Central", "Sophia"),null, null], "#ffc107"),
new("Petter", [Sum("Mexico", "Central", "Petter"),null, null], "#ffca28"),
new("North", [null, Sum("Mexico", "North"), null], "#ffd54f"),
new("Sophia", [Sum("Mexico", "North", "Sophia"), null, null], "#ffe082"),
new("Petter", [Sum("Mexico", "North", "Petter"), null, null], "#ffecb3")
];
}
public double Sum(string country, string? zone = null, string? name = null)
{
return Data
.Where(x =>
(country is null || x.Country == country) &&
(zone is null || x.Zone == zone) &&
(name is null || x.Name == name))
.Sum(x => x.Value);
}
}
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="MauiSample.Pies.Nested.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.Pies.Nested;assembly=ViewModelsSamples"
xmlns:local="clr-namespace:MauiSample.Pies.Nested"
x:DataType="vms:ViewModel">
<ContentPage.BindingContext>
<vms:ViewModel/>
</ContentPage.BindingContext>
<ContentPage.Resources>
<local:StringToPaintConverter x:Key="StringToPaintConverter" />
</ContentPage.Resources>
<lvc:PieChart InitialRotation="120" SeriesSource="{Binding PieDataCollection}" LegendPosition="Right">
<lvc:PieChart.SeriesTemplate>
<DataTemplate x:DataType="vms:PieData">
<lvc:XamlPieSeries
SeriesName="{Binding Name}"
Values="{Binding Values}"
Stroke="{lvc:SolidColorPaint Color='#fff', StrokeWidth=2}"
Fill="{Binding Color, Converter={StaticResource StringToPaintConverter}}"
HoverPushout="0"
DataLabelsFormatter="{Binding Formatter}"
DataLabelsSize="20"
ShowDataLabels="{Binding IsTotal}"
DataLabelsPosition="Outer"
IsVisibleAtLegend="{Binding IsTotal}">
</lvc:XamlPieSeries>
</DataTemplate>
</lvc:PieChart.SeriesTemplate>
</lvc:PieChart>
</ContentPage>
StringToPaintConverter.cs
using System.Globalization;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;
namespace MauiSample.Pies.Nested;
public class StringToPaintConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
new SolidColorPaint(SKColor.Parse((string?)value));
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
value is SolidColorPaint paint
? paint.Color.Red.ToString("X2") +
paint.Color.Green.ToString("X2") +
paint.Color.Blue.ToString("X2")
: (object?)null;
}