C#使用dev的ChartControl控件绘图

一、准备数据

画图首先需要有数据,本教程使用Bogus生成测试数据

这个教程建了一个demo类,结构如下所示:  


        public class Demo
        {
            public int? Id { get; set; }
            public string? City { get; set; }
        }

只有两个属性,一个Id,一个City

使用Bogus生成测试数据的代码如下:

            Randomizer.Seed = new Random(8675309);
            var Cities = new[] { "武汉", "长沙", "福州", "南昌", "厦门", "泉州" };
            var orderIds = 0;
            var demoGenerator = new Faker<Demo>("zh_CN")
                .RuleFor(x => x.Id, f => orderIds++)
                .RuleFor(x => x.City, f => f.PickRandom(Cities));
            var demos = demoGenerator.Generate(1000);

指定Randomizer.Seed可以使生成的测试数据不变,具体怎么使用bogus不是本文讨论的内容,暂且不表。

查看生成的内容

本教程假定需求是要统计每个City出现的次数,并绘制图表

对列表中City字段进行去重,可以使用linq中的distinct方法,如下所示:

 var regionList = demos.Select(x => x.City).Distinct().ToList();

查看regionList的结果

然后利用linq中的count方法统计每个City出现的次数,为了方便画图,这里新建了一个DataPoint类

DataPoint类的结构如下所示:

        public class DataPoint
        {
            public string? name { get; set; } // X轴值
            public int? value { get; set; }    // Y轴值
        }

统计各个City出现的次数,并写入DataPoint类列表中,代码如下所示:

            for (int i = 0; i < regionList.Count; i++)
            {
                DataPoint point = new DataPoint();
                point.name = regionList[i];
                int count = demos.Count(x => x.City == regionList[i]);
                point.value = count;
                dataPoints.Add(point);
            }

结果如下图所示:

现在我们已经有画图的数据了,现在就可以正式开始画图了

二、使用ChartControl控件画图

添加控件

为了便于展示画图结果,添加了一个tabcontrol控件并添加了4个tabpage,在每个tabpage上添加对应的控件,并设置Dock为fill,如下图所示:

这种拖拉控件的方式比较简单,但是如果想在运行时生成也是可以的,这里也提供一下运行时生成的示例代码,如下所示:

            ChartControl chart = new ChartControl();
            xtraTabPage1.Controls.Add(chart);
            chart.Dock = DockStyle.Fill;

添加Series

新建Series的代码如下所示:

            // 创建一个折线图Series
            Series series = new Series("折线图", ViewType.Line);
            // 创建一个柱状图Series
            Series series1 = new Series("柱状图", ViewType.Bar);
            // 创建一个饼状图Series
            Series series2 = new Series("饼状图", ViewType.Pie);

将数据添加到Series的方法如下所示:

            // 将数据添加到Series中
            foreach (var dataPoint in dataPoints)
            {
                series.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
                series1.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
                series2.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
            }

将Series添加到ChartControl的方法如下所示:

            // 将Series添加到ChartControl中        
            chartControl1.Series.Add(series);
            chartControl2.Series.Add(series1);
            chartControl3.Series.Add(series2);

自定义图表样式

自定义图表的外观代码如下所示:

            // 自定义图表的外观       
            //将折线图的Legend隐藏
            series.ShowInLegend = false;
            //将柱状图的Legend隐藏
            series1.ShowInLegend = false;
            //显示饼状图的值和百分比
            series2.LegendTextPattern = "{A}: {VP:P2}";

     

添加标题

为图表添加标题的代码如下:

            // 添加标题
            ChartTitle chartTitle = new ChartTitle();
            chartTitle.Text = "City统计折线图";
            chartControl1.Titles.Add(chartTitle);

            ChartTitle chartTitle1 = new ChartTitle();
            chartTitle1.Text = "City统计柱状图";
            chartControl2.Titles.Add(chartTitle1);

            ChartTitle chartTitle2 = new ChartTitle();
            chartTitle2.Text = "City统计饼状图";
            chartControl3.Titles.Add(chartTitle2);

查看绘图结果

绘制的折线图如下图所示:

绘制的柱状图所下图所示:

绘制的饼状图如下所示:

补充

该Demo还有一个数据展示页签,使用了gridcontrol控件这里不展开讲,涉及到的代码如下:

 //新建DataTable类
 DataTable dt = new DataTable();
 //DataTable添加列
 dt.Columns.Add("Name", typeof(string));
 dt.Columns.Add("Value", typeof(int));
 // 将数据添加到Series中
 foreach (var dataPoint in dataPoints)
  {
         series.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
         series1.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
         series2.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
         DataRow dataRow = dt.NewRow();
         dataRow["Name"] = dataPoint.name;
         dataRow["Value"] = dataPoint.value;
         dt.Rows.Add(dataRow);
  }
 //将DataTable绑定到GridControl上
 gridControl1.DataSource = dt;

结果如下图所示:

完整代码

using Bogus;
using DevExpress.XtraBars;
using DevExpress.XtraCharts;
using DevExpress.XtraGrid;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ChartControlDemo
{
    public partial class ToolbarForm1 : DevExpress.XtraEditors.XtraForm
    {
        List<DataPoint> dataPoints = new List<DataPoint>();
        DataTable dt = new DataTable();
        public class Demo
        {
            public int? Id { get; set; }
            public string? City { get; set; }

        }
        public class DataPoint
        {
            public string? name { get; set; } // X轴值
            public int? value { get; set; }    // Y轴值
        }
        public ToolbarForm1()
        {
            InitializeComponent();
        }

        private void barButtonItem1_ItemClick(object sender, ItemClickEventArgs e)
        {
            Randomizer.Seed = new Random(8675309);
            var Cities = new[] { "武汉", "长沙", "福州", "南昌", "厦门", "泉州" };
            var orderIds = 0;
            var demoGenerator = new Faker<Demo>("zh_CN")
                .RuleFor(x => x.Id, f => orderIds++)
                .RuleFor(x => x.City, f => f.PickRandom(Cities));
            var demos = demoGenerator.Generate(1000);
            var regionList = demos.Select(x => x.City).Distinct().ToList();
            for (int i = 0; i < regionList.Count; i++)
            {
                DataPoint point = new DataPoint();
                point.name = regionList[i];
                int count = demos.Count(x => x.City == regionList[i]);
                point.value = count;
                dataPoints.Add(point);
            }

            //开始画图

            // 创建一个折线图Series
            Series series = new Series("折线图", ViewType.Line);
            // 创建一个柱状图Series
            Series series1 = new Series("柱状图", ViewType.Bar);
            // 创建一个饼状图Series
            Series series2 = new Series("饼状图", ViewType.Pie);

            //DataTable添加列
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Value", typeof(int));

            // 将数据添加到Series中
            foreach (var dataPoint in dataPoints)
            {
                series.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
                series1.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
                series2.Points.Add(new SeriesPoint(dataPoint.name, dataPoint.value));
                DataRow dataRow = dt.NewRow();
                dataRow["Name"] = dataPoint.name;
                dataRow["Value"] = dataPoint.value;
                dt.Rows.Add(dataRow);
            }

            // 将Series添加到ChartControl中        
            chartControl1.Series.Add(series);
            chartControl2.Series.Add(series1);
            chartControl3.Series.Add(series2);

            // 自定义图表的外观       
            //将折线图的Legend隐藏
            series.ShowInLegend = false;
            //将柱状图的Legend隐藏
            series1.ShowInLegend = false;
            //显示饼状图的值和百分比
            series2.LegendTextPattern = "{A}: {VP:P2}";

            // 添加标题
            ChartTitle chartTitle = new ChartTitle();
            chartTitle.Text = "City统计折线图";
            chartControl1.Titles.Add(chartTitle);

            ChartTitle chartTitle1 = new ChartTitle();
            chartTitle1.Text = "City统计柱状图";
            chartControl2.Titles.Add(chartTitle1);

            ChartTitle chartTitle2 = new ChartTitle();
            chartTitle2.Text = "City统计饼状图";
            chartControl3.Titles.Add(chartTitle2);

            //将DataTable绑定到GridControl上
            gridControl1.DataSource = dt;
        }

项目地址

GitHub - Ming-jiayou/ChartControlDemo: A simple example of using dev's ChartControl control in Winforms