LiveCharts2总结-饼图、折线图、柱状图
在 Avalonia 中,LiveCharts2.Avalonia是目前生态最完善、功能最强大的开源图表库,支持折线图、柱状图、饼图、散点图等多种图表类型,使用简单且定制性强。
一、下载
开源组件下载地址:https://github.com/kuyz123/LiveCharts2
2、全局中文设置:在App.xaml.cs文件添加代码,防止图表中文乱码.
public partial class App : Application { // 设置全局字体-中文 protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); LiveCharts.Configure(config => config.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('汉'))); } }3、添加命名空间声明
<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:suki="https://github.com/kikipoulet/SukiUI" xmlns:converters="clr-namespace:UAVMonitor.Converters" xmlns:lang="clr-namespace:AppCore.Lang" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:mapsui="clr-namespace:Mapsui.UI.Avalonia;assembly=Mapsui.UI.Avalonia" xmlns:angif="using:AnimatedImage.Avalonia" xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.Avalonia;assembly=LiveChartsCore.SkiaSharpView.Avalonia" xmlns:vm="clr-namespace:UAVMonitor.ViewModels" mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800" x:DataType="vm:HomeViewModel" x:Class="UAVMonitor.Views.HomeView">二、图表
1、饼图
1. MainWindow.xaml代码
添加饼图控件PieChart
<lvc:PieChart Series="{Binding PieSeries}"> </lvc:PieChart>2. MainWindow.xaml.cs代码
DataContext作为一个容器,提供了UI层和数据层之间的连接点。在MVVM中,DataContext主要用于在View和ViewModel之间建立数据绑定关系,这样View可以通过绑定访问ViewModel中的数据和命令。
public partial class MainWindow : Window { private ViewModel _viewModel { get; set; } public MainWindow() { // 设置字体-中文 LiveCharts.Configure(config => config.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('汉'))); _viewModel = new ViewModel(); // 将 ViewModel 设置为主窗口的 DataContext DataContext = _viewModel; InitializeComponent(); } }3. ViewModel.cs代码
创建ViewModel.cs用来绑定数据、创建图表
ViewModel处理Model提供的数据,将其转换为适合View展示的形式。所以ViewModel需要实现INotifyPropertyChanged接口用来通知UI界面修改数据。
3.1 数据绑定
public class ViewModel : INotifyPropertyChanged { // 存储饼图数据 private ISeries[] _PieSeries; public ISeries[] PieSeries { get { return _PieSeries; } set { if (_PieSeries != value) { _PieSeries = value; OnPropertyChanged(); } } } //数据绑定 public event PropertyChangedEventHandler? PropertyChanged; // [CallerMemberName]用于自动传递调用者的名称。这样在调用 OnPropertyChanged 时,可以省略属性名参数。 protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }3.2 创建饼图和饼图数据设置
在ViewModel.cs添加如下代码
public ViewModel() { InitPieChart(); } private void InitPieChart() { var titles = new string[] { "A", "B", "C" }; var data = new double[] { 1, 0, 3 }; PieSeries = CreatePieChart(titles, data); } private bool _isAllZero; // 判断饼图中是否所有数据都是0 /// <summary> /// 创建饼图 /// </summary> /// <param name="titles">饼图标签</param> /// <param name="data">饼图数据</param> /// <returns></returns> private ISeries[] CreatePieChart(string[] titles, double[] data) { ISeries[] seriesCollection; _isAllZero = data.All(x => x == 0); // 如果所有数据不都为0 if (!_isAllZero) { // 创建饼图数据 List<PieSeries<double>> seriesList = new List<PieSeries<double>>(); // 定义一个颜色数组 var colors = new SKColor[] { SKColors.DodgerBlue, SKColors.OrangeRed, SKColors.YellowGreen }; for (int i = 0; i < titles.Length; i++) { if (data[i] != 0) { var series = new PieSeries<double> { // 设置扇形名称 Name = titles[i], // 设置饼图扇形数据 Values = new double[] { data[i] }, // 设置饼图扇形填充颜色 Fill = new SolidColorPaint(colors[i]), // 设置数据标签字体大小 DataLabelsSize = 15, // 设置数据标签颜色 DataLabelsPaint = new SolidColorPaint(SKColors.White), // 设置数据标签位置 DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Middle, // 设置数据标签格式化器 DataLabelsFormatter = point => point.Context.Series.Name + ":" + point.Coordinate.PrimaryValue.ToString(), // DataLabelsFormatter = _ => "", // 隐藏数据标签 }; seriesList.Add(series); } } seriesCollection = seriesList.ToArray(); } // 如果所有数据都为0,则添加一个虚拟的系列 else { seriesCollection = new ISeries[1]; // 添加一个虚拟的系列,确保总有一部分被显示 var virtualSeries = new PieSeries<double> { Name = "无", Values = new double[] { 1 }, Fill = new SolidColorPaint(SKColor.Parse("#55B155")), // 设置数据标签字体大小 DataLabelsSize = 15, // 设置数据标签颜色 DataLabelsPaint = new SolidColorPaint(SKColors.White) { SKFontStyle = SKFontStyle.Italic, }, // 设置数据标签位置 DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Middle, DataLabelsFormatter = point => point.Context.Series.Name ?? "无", // 提示框文字格式 ToolTipLabelFormatter = _ => "", }; seriesCollection[0] = virtualSeries; } return seriesCollection; }左侧为数据包含零的饼图,中间为数据不为零,右侧为数据全为零
2、折线图
与饼图不同的是,折线图属性lineChart是CartesianChart类型,通常用于存储和显示折线图、柱状图等二维坐标系图表。而ISeries[] PieSeries是饼图的数据,每个元素代表饼图中的一个扇区。所以前端绑定也不同。
1. MainWindow.xaml代码
<lvc:CartesianChart Grid.Column="1" Margin="10,10" Series="{Binding LineChart.Series}" XAxes="{Binding LineChart.XAxes}" YAxes="{Binding LineChart.YAxes}" LegendPosition="Top" LegendTextPaint="{Binding LegendTextPaint}"> </lvc:CartesianChart>绑定的属性依次是
- 绑定 Series 属性,显示图表的系列数据
- 绑定 YAxes 属性,配置 Y 轴
- 绑定 YAxes 属性,配置 Y 轴
- 设置图例位置为顶部
- 绑定图例文本的颜色
2. ViewModel.cs代码
2.1 数据绑定
// 折线图 private CartesianChart _LineChart; public CartesianChart LineChart { get { return _LineChart; } set { if (_LineChart != value) { _LineChart = value; OnPropertyChanged(); } } } // 柱状图和折线图图例文字颜色 public SolidColorPaint LegendTextPaint { get; set; } = new SolidColorPaint { Color = SKColors.Black};2.2 创建折线图
/// <summary> /// 创建折线图 /// </summary> /// <param name="titles">图例</param> /// <param name="data">数据</param> /// <param name="lables">X轴标签</param> /// <returns></returns> private CartesianChart CreateLineChart(string[] titles, double[][] data, string[] lables) { ISeries[] seriesCollection = new ISeries[titles.Length]; // 定义一个颜色数组,用于设置折现和图例的颜色 var colors = new SKColor[] { SKColors.Red, SKColors.YellowGreen, SKColors.MediumTurquoise, SKColors.RoyalBlue }; for (int i = 0; i < titles.Length; i++) { var series = new LineSeries<double> { // 设置折线名称 Name = titles[i], Values = new List<double>(data[i]), // 使用整个数组作为数据点 Fill = new SolidColorPaint(SKColors.Transparent), // 移除填充颜色 LineSmoothness = 0.2, // 设置线条平滑度 Stroke = new SolidColorPaint(colors[i], 3),// 设置线条颜色和宽度 GeometryStroke = new SolidColorPaint(colors[i], 3), // 设置图例及数据点颜色和宽度 GeometrySize = 8, // 设置数据点大小 // GeometryFill = new SolidColorPaint(SKColors.Transparent), // 设置数据点的填充颜色 }; seriesCollection[i] = series; } var XAxes = new Axis[] // 配置 X 轴 { new Axis { IsVisible = true,// 轴是否可见 Name = "日期", // 轴名称 LabelsRotation = 0, // 标签不旋转 TextSize = 15, // 标签文字大小设置为15 ShowSeparatorLines = false, // 不显示X轴坐标线 NamePaint = new SolidColorPaint(SKColors.YellowGreen), // 轴名称Name的颜色 LabelsPaint = new SolidColorPaint(SKColors.Red), // X轴标签的颜色 TicksPaint = new SolidColorPaint(SKColors.Green) { StrokeThickness = 5 } ,// 设置刻度线的颜色和宽度 Position = LiveChartsCore.Measure.AxisPosition.Start, // 设置X轴的位置 Labels = lables, // 设置X轴标签 NameTextSize = 15, // 设置轴名称字体大小 } }; var YAxes = new Axis[] // 配置 Y 轴 { new Axis { IsVisible = true,// 轴是否可见 Name = "数量", // 轴名称 MinLimit=0, // 设置 Y 轴的最小值(从0开始) Labeler = value => Math.Floor(value).ToString(), // 设置 Y 轴标签格式,只显示整数 LabelsPaint = new SolidColorPaint(SKColors.Gray), // Y轴标签颜色 SeparatorsPaint = new SolidColorPaint(SKColors.SlateBlue) { StrokeThickness = 1 }, // 设置分隔线的颜色和宽度 } }; // 创建折线图 var cartesianChart = new CartesianChart() { Series = seriesCollection, // 配置折线图 XAxes = XAxes, // 配置 X 轴 YAxes = YAxes, // 配置 Y 轴 }; return cartesianChart; }复制2.3 数据设置
public ViewModel() { InitPieChart(); InitLineChart(); } private void InitLineChart() { var titles = new string[] { "A", "B", "C" }; var data = new double[][] { new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 }, new double[] { 7, 8, 9 } }; var lables = new string[] { "昨天", "今天", "明天" }; lineChart = CreateLineChart(titles, data, lables); }3、柱状图
1. MainWindow.xaml代码
<lvc:CartesianChart Margin="10,10" Series="{Binding ColumnChart.Series}" XAxes="{Binding ColumnChart.XAxes}" YAxes="{Binding ColumnChart.YAxes}" LegendPosition="Top" LegendTextPaint="{Binding LegendTextPaint}"> </lvc:CartesianChart>2. ViewModel.cs代码
2.1 数据绑定
// 柱状图 private CartesianChart _ColumnChart; public CartesianChart ColumnChart { get { return _ColumnChart; } set { if (_ColumnChart != value) { _ColumnChart = value; OnPropertyChanged(); } } }2.2 创建柱状图
/// <summary> /// 创建柱状图 /// </summary> /// <param name="titles">柱状图图例</param> /// <param name="data">柱状图数据</param> /// <param name="lables">柱状图X轴标签</param> /// <returns></returns> private CartesianChart CreateColumnChart(string[] titles, double[][] data, string[] lables) { ISeries[] seriesCollection = new ISeries[titles.Length]; var colors = new SKColor[] { SKColors.RoyalBlue, SKColors.LightGreen, SKColors.Goldenrod }; for (int i = 0; i < titles.Length; i++) { var series = new ColumnSeries<double, LiveChartsCore.SkiaSharpView.Drawing.Geometries.RectangleGeometry> { Name = titles[i], Values = new List<double>(data[i]), Fill = new SolidColorPaint(colors[i]), }; seriesCollection[i] = series; } var XAxes = new Axis[] // 配置 X 轴 { new () { IsVisible = true,// 轴是否可见 //Name = "X Axis", // 轴名称 LabelsRotation = 0, // 标签不旋转 TextSize = 15, // 标签文字大小设置为10 ShowSeparatorLines = false, // 显示坐标线 NamePaint = new SolidColorPaint(SKColors.Black), // 轴名称颜色 LabelsPaint = new SolidColorPaint(SKColors.Black), // 标签颜色 SeparatorsPaint = new SolidColorPaint(SKColors.Gray) { StrokeThickness = 1 }, // 设置分隔线的颜色和宽度 TicksPaint = new SolidColorPaint(SKColors.Gray) { StrokeThickness = 1 } ,// 设置刻度线的颜色和宽度 Position = LiveChartsCore.Measure.AxisPosition.Start, // 设置轴的位置 Labels = lables, } }; var YAxes = new Axis[] // 配置 Y 轴 { new () { IsVisible = true,// 轴是否可见 //Name = "Y Axis", // 轴名称 MinLimit=0, // 设置 Y 轴的最小值 Labeler = value => Math.Floor(value).ToString(), // 设置 Y 轴标签格式,只显示整数 LabelsPaint = new SolidColorPaint(SKColors.Black), // 标签颜色设置为白色 } }; var cartesianChart = new CartesianChart() { Series = seriesCollection, XAxes = XAxes, YAxes = YAxes, }; return cartesianChart; }2.3 数据设置
public ViewModel() { InitPieChart(); InitLineChart(); InitColumnChart(); } private void InitColumnChart() { var titles = new string[] { "数据一", "数据二", "数据三" }; var data = new double[][] { new double[] { 1, 2, 3, 2, 1 }, new double[] { 4, 5, 6 ,5, 4 }, new double[] { 7, 8, 9, 8, 7 } }; var lables = new string[] { "星期一", "星期二", "星期三", "星期四", "星期五" }; ColumnChart = CreateColumnChart(titles, data, lables); }三、总结
饼图控件为PieChart,而折线图和柱状图的控件都为CartesianChart。
虽然前端使用相同的 CartesianChart控件来展示折线图和柱状图,但后端通过创建不同的数据系列对象(LineSeries或 ColumnSeries),实现折线图和柱状图,折线图用LineSeries,柱状图用ColumnSeries。
