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