LiveCharts2总结-饼图、折线图、柱状图

一、下载

1、 下载NuGet包:LiveChartsCore.SkiaSharpView.WPF

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('汉')));
    }
}

或者在使用Livecharts的窗口的构造函数中添加中文设置,防止此设置干扰其他窗口控件

3、添加命名空间声明

xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"

官方文档链接:Overview.Installation - LiveCharts2icon-default.png?t=O83Ahttps://livecharts.dev/docs/WPF/2.0.0-rc4/Overview.Installation

注意下载的NuGet包版本和官方文档版本一致

二、图表

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>

 绑定的属性依次是

  1. 绑定 Series 属性,显示图表的系列数据
  2. 绑定 YAxes 属性,配置 Y 轴
  3. 绑定 YAxes 属性,配置 Y 轴
  4. 设置图例位置为顶部
  5. 绑定图例文本的颜色

 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;
}

  属性说明:

红框标注部分可以设置图例形状,需要注意柱状图设置图例后,图表中每个柱体形状会根据所选图例形状进行改变。其他属性和折线图类似。

官方文档:samples.lines.custom - LiveCharts2

具体图例形状查看文档链接:LiveChartsCore.SkiaSharpView.Drawing.Geometries.StarGeometry - LiveCharts2

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。

题外话,关于SKColors颜色

C#中使用LiveCharts绘制多条曲线,并将X坐标设置为实时时间,Y坐标为值,可以按照以下步骤进行: 1. **安装LiveCharts**: 首先,确保你的项目中安装了LiveCharts。你可以通过NuGet包管理器安装它。 2. **设置X轴为时间轴**: 使用`DateTimeAxis`作为X轴,并设置其格式。 3. **添加多条曲线**: 使用`LineSeries`来添加多条曲线,并为每条曲线设置不同的名称和颜色。 4. **实时更新数据**: 使用`DispatcherTimer`来定时更新数据,并刷新表。 以下是一个完整的示例代码: ```csharp using System; using System.Windows; using System.Windows.Threading; using LiveCharts; using LiveCharts.Wpf; namespace LiveChartsExample { public partial class MainWindow : Window { private DispatcherTimer timer; private Random rand; private DateTime startTime; public MainWindow() { InitializeComponent(); rand = new Random(); startTime = DateTime.Now; // 设置X轴为时间轴 cartesianChart1.AxisX.Add(new DateTimeAxis { Title = "Time", LabelFormatter = value => new DateTime((long)value).ToString("HH:mm:ss") }); // 添加多条曲线 cartesianChart1.Series.Add(new LineSeries { Title = "Series 1", Values = new ChartValues<double>(), PointGeometry = null }); cartesianChart1.Series.Add(new LineSeries { Title = "Series 2", Values = new ChartValues<double>(), PointGeometry = null }); // 初始化定时器 timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { // 更新X轴 var now = DateTime.Now; var x = now.ToOADate(); // 生成随机Y值 var y1 = rand.Next(0, 100); var y2 = rand.Next(0, 100); // 更新数据 ((LineSeries)cartesianChart1.Series[0]).Values.Add(y1); ((LineSeries)cartesianChart1.Series[1]).Values.Add(y2); // 保持数据长度 if (((LineSeries)cartesianChart1.Series[0]).Values.Count > 60) { ((LineSeries)cartesianChart1.Series[0]).Values.RemoveAt(0); ((LineSeries)cartesianChart1.Series[1]).Values.RemoveAt(0); } // 更新X轴范围 cartesianChart1.AxisX[0].MinValue = DateTime.Now.AddSeconds(-60).ToOADate(); cartesianChart1.AxisX[0].MaxValue = DateTime.Now.ToOADate(); } } } ``` 在这个示例中,我们创建了一个WPF窗口,并使用LiveCharts绘制了两条实时更新的曲线。X轴为时间轴,Y轴为随机生成的值。定时器每秒钟更新一次数据,并保持数据长度为60。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值