C# 之 WPF 统计图表开发方案

C# 之 WPF 统计图表开发文档

    • 一、前言
    • 二、环境配置
      • 1、开发环境
      • 2、加载 LiveCharts 库
      • 3、添加必须的头文件
    • 三、基础图形
      • 1、柱状图(ColumnCharts)
      • 2、饼状图(PieCharts)
      • 3、折线图(LineCharts)
      • 4、散点图(SactterCharts)
      • 5、堆叠图(StackedCharts)
      • 6、其他(OtherCharts)
    • 四、总结
      • 1、LiveCharts的优势
      • 2、LiveCharts的略势

一、前言

  • 本项目的统计图使用LiveCharts 控件集成。
  • LiveCharts, 官网:https://lvcharts.net 是一款简单,灵活,交互式和强大的 DOTNET数据可视化图表控件,内置多种统计图表,可满足本项目的需求。

二、环境配置

1、开发环境

  • 操作系统名称:Microsoft Windows 10 专业工作站版
  • IDE名称:Visual Studio 2017 15.9.9

2、加载 LiveCharts 库

这里演示通过命令行(DOTNET的包管理器NuGet)向中央仓库拉取 LiceCharts 库。

  • 在控制台键入下面的命令
PM> Install-Package LiveCharts.Wpf
  • 或者转到解决方案资源管理器,右键单击引用,然后管理NuGet包
    C# 之 WPF 统计图表开发方案_第1张图片
  • 浏览LiveCharts.Wpf,选择包并单击安装
    C# 之 WPF 统计图表开发方案_第2张图片

3、添加必须的头文件

  • 将命名空间添加到XAML
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
  • 在逻辑代码中添加头文件
using LiveCharts;
using LiveCharts.Wpf;

三、基础图形

LiveCharts旨在为用户提供便利,一切都自动更新和动画,库只会在认为有必要时更新,每次数据更改,添加/删除系列或添加/删除图表时都会更新将自己更新,除了你的业务,你真的不需要担心任何事情,让LiveCharts处理图表。

有许多类型已准备好已定义的绘图,您可以在 LiveCharts 官网(https://lvcharts.net)了解更多信息,下面介绍几种常用的图表视图绘制。

1、柱状图(ColumnCharts)

  • 将命名空间添加到XAML
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
  • 在逻辑代码(MainWindows.xaml.cs)中添加头文件
using LiveCharts;
using LiveCharts.Wpf;
  • 编写界面代码
<Grid>
    
    <lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Left">
        <lvc:CartesianChart.AxisX>
            
            <lvc:Axis Title="Salesman" Labels="{Binding Labels}"/>
        lvc:CartesianChart.AxisX>
        <lvc:CartesianChart.AxisY>
            
            <lvc:Axis Title="Sold Apps" LabelFormatter="{Binding Formatter}"/>
        lvc:CartesianChart.AxisY>
    lvc:CartesianChart>
Grid>

  • 逻辑代码(为方便查漏补缺把所有的代码都贴出来)
using LiveCharts;
using LiveCharts.Wpf;
using System;
using System.Windows;

namespace LiveChartsTest
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window
    {
    	// 构造函数
        public MainWindow()
        {
            InitializeComponent();
            SeriesCollection = new SeriesCollection
            {
                new ColumnSeries
                {
                    Title = "2015",
                    // 2015的条形值
                    // 动态改变数据只需要更改此处的 Values 便可
                    Values = new ChartValues<double> { 10, 50, 39, 50 }
                }
            };

            //adding series will update and animate the chart automatically
            SeriesCollection.Add(new ColumnSeries
            {
                Title = "2016",
                // 2016的条形值
                // 动态改变数据只需要更改此处的 Values 便可
                Values = new ChartValues<double> { 11, 56, 42 }
            });

            //also adding values updates and animates the chart automatically
            SeriesCollection[1].Values.Add(48d);

            Labels = new[] { "Maria", "Susan", "Charles", "Frida" };
            Formatter = value => value.ToString("N");

            DataContext = this;
        }

        // 图形数据属性
        public SeriesCollection SeriesCollection { get; set; }
        // 标签属性
        public string[] Labels { get; set; }
        // Y轴坐标属性
        public Func<double, string> Formatter { get; set; }
    }
}
  • 运行效果如下:
    C# 之 WPF 统计图表开发方案_第3张图片

2、饼状图(PieCharts)

  • 因为头文件都是一样的,这里就不贴了,此处有疑问请查看柱状图(LineCharts)

  • 直接上XAML代码:

<lvc:PieChart LegendLocation="Bottom" 
	DataClick="Chart_OnDataClick" Hoverable="False" DataTooltip="{x:Null}">
    <lvc:PieChart.Series>
        
        <lvc:PieSeries Title="Maria" Values="3" DataLabels="True"
                       LabelPoint="{Binding PointLabel}"/>
        <lvc:PieSeries Title="Charles" Values="4" DataLabels="True" 
                       LabelPoint="{Binding PointLabel}"/>
        <lvc:PieSeries Title="Frida" Values="6" DataLabels="True" 
                       LabelPoint="{Binding PointLabel}"/>
        <lvc:PieSeries Title="Frederic" Values="2" DataLabels="True" 
                       LabelPoint="{Binding PointLabel}"/>
    lvc:PieChart.Series>
lvc:PieChart>
  • 业务逻辑代码
// 构造函数
 public Pie()
 {
     InitializeComponent();
     // 自定义显示标签
     PointLabel = chartPoint =>
         string.Format("{0} ({1:P})", chartPoint.Y, chartPoint.Participation);

     DataContext = this;
 }

 // 使用泛型动态传入数据
 public Func<ChartPoint, string> PointLabel { get; set; }

 /**
  *  饼图鼠标点击事件
  */ 
 private void Chart_OnDataClick(object sender, ChartPoint chartpoint)
 {
     var chart = (LiveCharts.Wpf.PieChart)chartpoint.ChartView;

     //clear selected slice.
     foreach (PieSeries series in chart.Series)
         series.PushOut = 0;

     var selectedSeries = (PieSeries)chartpoint.SeriesView;
     selectedSeries.PushOut = 8;
 }
  • 运行效果:
    C# 之 WPF 统计图表开发方案_第4张图片

3、折线图(LineCharts)

  • XAML文件

<lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Right" >
    <lvc:CartesianChart.AxisY>
        
        <lvc:Axis Title="Sales" LabelFormatter="{Binding YFormatter}">lvc:Axis>
    lvc:CartesianChart.AxisY>
    <lvc:CartesianChart.AxisX>
        
        <lvc:Axis Title="Month" Labels="{Binding Labels}">lvc:Axis>
    lvc:CartesianChart.AxisX>
lvc:CartesianChart>
  • 业务逻辑代码
// 构造函数
public Line()
{
    InitializeComponent();

    SeriesCollection = new SeriesCollection
    {
        // 匿名新建LineSeries对象
        new LineSeries
        {
            // 折线的名称
            Title = "Series 1",
            // 折线的拐点值
            Values = new ChartValues<double> { 4, 6, 5, 2 ,4 }
        },
        new LineSeries
        {
            Title = "Series 2",
            Values = new ChartValues<double> { 6, 7, 3, 4 ,6 },
            // 折线拐点的表示形状,默认为原点
            PointGeometry = null
        },
        new LineSeries
        {
            Title = "Series 3",
            Values = new ChartValues<double> { 4,2,7,2,7 },
            // 折线拐点的表示形状,默认为原点,这里是正方形
            PointGeometry = DefaultGeometries.Square,
            // 折线拐点的形状尺寸
            PointGeometrySize = 15
        }
    };

    // X轴的坐标值
    Labels = new[] { "Jan", "Feb", "Mar", "Apr", "May" };
    // Y轴坐标值
    YFormatter = value => value.ToString("C");

    //modifying the series collection will animate and update the chart
    // 动态添加折线"Series 4"
    SeriesCollection.Add(new LineSeries
    {
        Title = "Series 4",
        Values = new ChartValues<double> { 5, 3, 2, 4 },
        LineSmoothness = 0, //0: straight lines, 1: really smooth lines
        PointGeometry = Geometry.Parse("m 25 70.36218 20 -28 -20 22 -8 -6 z"),
        PointGeometrySize = 50,
        // 折线拐点的表示形状,默认为原点,这里是正方形
        PointForeground = Brushes.Gray
    });

    //modifying any series values will also animate and update the chart
    // 动态为折线"Series 4"添加一个值
    SeriesCollection[3].Values.Add(5d);

    // 数据绑定源 
    DataContext = this;
}

// 相关属性
public SeriesCollection SeriesCollection { get; set; }
public string[] Labels { get; set; }
public Func<double, string> YFormatter { get; set; }
  • 效果图:
    C# 之 WPF 统计图表开发方案_第5张图片

4、散点图(SactterCharts)

  • XAML文件

<lvc:CartesianChart Grid.Row="1" LegendLocation="Bottom">
    <lvc:CartesianChart.Series>
        
        <lvc:ScatterSeries Title="Series A" Values="{Binding ValuesA}" />
        
        <lvc:ScatterSeries Title="Series B" Values="{Binding ValuesB}"
                           PointGeometry="{x:Static lvc:DefaultGeometries.Diamond}" />
        
        
        <lvc:ScatterSeries Title="Series C" Values="{Binding ValuesC}"
                           PointGeometry="{x:Static lvc:DefaultGeometries.Triangle}"
                           StrokeThickness="2" Fill="Transparent"/>
    lvc:CartesianChart.Series>
    <lvc:CartesianChart.AxisY>
        
        
        <lvc:Axis Unit="1">lvc:Axis>
    lvc:CartesianChart.AxisY>
lvc:CartesianChart>
  • 业务逻辑代码:
// 构造函数
public Scatter()
{
    InitializeComponent();

    // 使用随机数填充三种类型的散点
    var r = new Random();
    ValuesA = new ChartValues<ObservablePoint>();
    ValuesB = new ChartValues<ObservablePoint>();
    ValuesC = new ChartValues<ObservablePoint>();

    // 赋随机值
    for (var i = 0; i < 20; i++)
    {
        ValuesA.Add(new ObservablePoint(
        	r.NextDouble() * 10, r.NextDouble() * 10));
        ValuesB.Add(new ObservablePoint(
        	r.NextDouble() * 10, r.NextDouble() * 10));
        ValuesC.Add(new ObservablePoint(
        	r.NextDouble() * 10, r.NextDouble() * 10));
    }

    // 数据源绑定
    DataContext = this;
}

// 相关属性
public ChartValues<ObservablePoint> ValuesA { get; set; }
public ChartValues<ObservablePoint> ValuesB { get; set; }
public ChartValues<ObservablePoint> ValuesC { get; set; }
  • 效果图:
    C# 之 WPF 统计图表开发方案_第6张图片

5、堆叠图(StackedCharts)

  • 对于堆叠图,相比之前的统计图而言,头文件有所不同
  • 添加到XAML中
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
  • 添加到业务逻辑代码中
using LiveCharts;
using LiveCharts.Defaults;
using LiveCharts.Wpf;
  • XAML文件:

<lvc:CartesianChart 
	Grid.Row="2" Series="{Binding SeriesCollection}"  LegendLocation="Right">
    <lvc:CartesianChart.AxisX>
        
        <lvc:Axis Title="Year" LabelFormatter="{Binding XFormatter}"/>
    lvc:CartesianChart.AxisX>
    <lvc:CartesianChart.AxisY>
        
        <lvc:Axis Title="Population" LabelFormatter="{Binding YFormatter}"/>
    lvc:CartesianChart.AxisY>
lvc:CartesianChart>
  • 业务逻辑代码:
public Stacked()
{
    InitializeComponent();
    SeriesCollection = new SeriesCollection
    {
        new StackedAreaSeries
        {
            Title = "Africa",
            // Values 描点
            Values = new ChartValues<DateTimePoint>
            {
                new DateTimePoint(new DateTime(1950, 1, 1), .228),
                new DateTimePoint(new DateTime(1960, 1, 1), .145),
                new DateTimePoint(new DateTime(1970, 1, 1), .366),
                new DateTimePoint(new DateTime(1980, 1, 1), .34),
                new DateTimePoint(new DateTime(1990, 1, 1), .629),
                new DateTimePoint(new DateTime(2000, 1, 1), .242),
                new DateTimePoint(new DateTime(2010, 1, 1), 1.031),
                new DateTimePoint(new DateTime(2013, 1, 1), 1.110)
            },
            LineSmoothness = 0
        },
        new StackedAreaSeries
        {
            Title = "N & S America",
            // Values 描点
            Values = new ChartValues<DateTimePoint>
            {
                new DateTimePoint(new DateTime(1950, 1, 1), .456),
                new DateTimePoint(new DateTime(1960, 1, 1), .424),
                new DateTimePoint(new DateTime(1970, 1, 1), .31),
                new DateTimePoint(new DateTime(1980, 1, 1), 1.618),
                new DateTimePoint(new DateTime(1990, 1, 1), .247),
                new DateTimePoint(new DateTime(2000, 1, 1), .81),
                new DateTimePoint(new DateTime(2010, 1, 1), .942),
                new DateTimePoint(new DateTime(2013, 1, 1), .432)
            },
            LineSmoothness = 0
        },
        new StackedAreaSeries
        {
            Title = "Asia",
            // Values 描点
            Values = new ChartValues<DateTimePoint>
            {
                new DateTimePoint(new DateTime(1950, 1, 1), 0.395),
                new DateTimePoint(new DateTime(1960, 1, 1), 1.694),
                new DateTimePoint(new DateTime(1970, 1, 1), 0.128),
                new DateTimePoint(new DateTime(1980, 1, 1), 1.634),
                new DateTimePoint(new DateTime(1990, 1, 1), 0.213),
                new DateTimePoint(new DateTime(2000, 1, 1), 1.717),
                new DateTimePoint(new DateTime(2010, 1, 1), 0.165),
                new DateTimePoint(new DateTime(2013, 1, 1), 0.298)
            },
            LineSmoothness = 0
        },
        new StackedAreaSeries
        {
            Title = "Europe",
            // Values 描点
            Values = new ChartValues<DateTimePoint>
            {
                new DateTimePoint(new DateTime(1950, 1, 1),  .228),
                new DateTimePoint(new DateTime(1960, 1, 1),  .145),
                new DateTimePoint(new DateTime(1970, 1, 1),  .366),
                new DateTimePoint(new DateTime(1980, 1, 1),  .34),
                new DateTimePoint(new DateTime(1990, 1, 1),  .629),
                new DateTimePoint(new DateTime(2000, 1, 1), .231),
                new DateTimePoint(new DateTime(2010, 1, 1), .740),
                new DateTimePoint(new DateTime(2013, 1, 1), .742)
            },
            LineSmoothness = 0
        }
    };

    // X、Y坐标
    XFormatter = val => new DateTime((long)val).ToString("yyyy");
    YFormatter = val => val.ToString("N") + " M";

    // 数据绑定
    DataContext = this;
}

// 相关属性
public SeriesCollection SeriesCollection { get; set; }
public Func<double, string> XFormatter { get; set; }
public Func<double, string> YFormatter { get; set; }
  • 效果图:
    C# 之 WPF 统计图表开发方案_第7张图片

6、其他(OtherCharts)

  • LiveCharts 还有很多很好看的图表,但是多数的用法都是和以上几种常见的图表的使用方式都是一样的,剩下的就不重复累赘了,如果想要尝试可以参考上述五种图表。

四、总结

1、LiveCharts的优势

  • LiveCharts 使用简单,快速集成,更加容易的集成在项目上。

2、LiveCharts的略势

  • LiveCharts 集成简单,但是数据更新是导致整个页面都是重新绘制的,更新数据重新刷新界面的方式对用户不太友好,LiveCharts 也有相应的自动刷新的控件,可以免费体验15天,但是到期需要付费使用。
  • 实现图标动态刷新的方式还是相对简单粗暴,LiveCharts 内部刷新机制是当 Series、Values等等这个数值发生变化时,后台会自动触发图标界面刷新功能,从而重回整个 View。

你可能感兴趣的:(C#)