开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
最近需要用到图表库的操作,原本想着找.Net下的开源图表库(如NPlot),后来发现winfrom自带有chart控件,可以很方便的创建图表,但是中间也遇到一个大坑,下面介绍一下相关用法。
.Net 3.5及以下需要单独下载MSChart组件,可从Nuget安装
先看一下生成三维饼图的效果
简介
Chart控件
Chart控件可以实现很多炫酷的图表,各个属性的介绍如图
或者查看微软官方文档的介绍
属性
-
ChartAreas属性
ChartAreas属性指绘图的图表区域,一个控件可以有多个绘图区,比如要想在同一个控件中显示饼图和柱状图,可以在Chart控件ChartAreas中添加两个ChartArea,并分别绑定Serie对象。
-
Series属性
Series属性是图表的数据序列,通过将数据绑定到Serie,然后Serie对应的图表就可以生成。比如通过Series[0].Points.DataBindXY()绑定数据
-
Legends属性
Legend是图表的图例,一个Serie对应一个图标区域ChartArea和一个Legend图例(可以设置不启用图例)
不能通过给图例指定颜色改变图例的颜色,它是与Series填充的颜色相对应的,要想改变需要改变Series的颜色Formatting Series Colors on a Chart.
-
Titles属性
设置图表标题有关的属性,比如标题内容、样式、对齐等。
制作饼图
控件添加
工具项中添加Chart控件,控件名为Piechart,设置Series属性中的ChartType类型为Pie。
也可通过代码直接创建控件对象,设置属性。
绑定数据
通过Serie.Points.DataBindXY()或DataBind(),方法绑定数据
绑定数据的方式使用的是IEnumerable类型的数据(如数组、LIst)
绑定List数据
假设如下数据
List<string[]> list = new List<string[]>()
{
new string[2]{"P1","90" },
new string[2]{"W2","126" },
new string[2]{"W3","16" },
new string[2]{"C4","102" },
new string[2]{"P5","12" },
new string[2]{"M6","18" },
new string[2]{"O7","426" },
new string[2]{"M8","20" },
new string[2]{"O9","90" }
};
绑定数据
List<string> listx = new List<string>(); ;
List<int> listy = new List<int>();
foreach (var item in list)
{
listx.Add(item[0]);
listy.Add(Convert.ToInt32(item[1]));//不用进行数字转换
}
Piechart.Series[0].Points.DataBindXY(listx, listy);
////或者 数组
//Piechart.Series[0].Points.DataBindXY(listx.ToArray(), listy.ToArray());
//绑定是指定X Y列的名称
Piechart.Series[0].Points.DataBindXY(listx,"Type", listy,"Value");
使用DataTable
将上面的List转换为DataTable(模拟DataTable类型),绑定如下:
DataTable dt = new DataTable();
dt.Columns.Add("Type");
dt.Columns.Add("Value");
foreach (var item in list)
{
DataRow dr = dt.NewRow();
dr["Type"] = item[0];
dr["Value"] = item[1];
dt.Rows.Add(dr);
}
Piechart.Series[0].Points.DataBind(dt.AsEnumerable(),"Type","Value","");
修改图例显示位置
修改Legend的Docking位置为Top
修改饼图的Label显示内容
-
饼图的Label默认显示的是图例的名称,即绑定的X的名称
设置显示数据点的值
通过设置Label属性IsValueShownAsLabel为True,将数据点的值显示在标签
显示:
设置显示百分比
-
设置Serie的Labe取值为
#PERCENT{P2}
如下
Piechart.Series[0].Label = "#PERCENT{P2}";
或者在Series属性集合中,点击Label,插入关键字,选择Y值百分比
此时饼图显示百分比,但是图例也会显示百分比。
-
设置Legend的
LegendText取值为#VALX,即X轴的内容。
Piechart.Series[0].LegendText = "#VALX";
但是查看时整个图例显示为O,解决办法是设置X轴的值类型为String
//设置Piechart.Series[0].XValueType 类型为String,否则设置百分比后,取X轴的值时可能会变成0
Piechart.Series[0].XValueType = ChartValueType.String;
后来测试图例可以正常显示X轴的值,不知是因为Bug还是什么情况导致,第一次测试时,整个图例会显示为O,类似没有获取X轴的取值
这个问题困扰了很久,查资料正常设置就是不行,
无意中通过返现这个提问bbs.csdn.net/topics/3919…
设置提示
- 设置图表的Label百分比的提示为Y值
Piechart.Series[0].LabelToolTip = "#VAL";//或"#VALY";
-
设置图标的提示
x的取值为y(单位s)
Piechart.Series[0].ToolTip = "#VALX:#VAL(s)";//显示提示
取值类型
以上通过设置取值的类型,可以设定显示的数据源,主要取值类型如下:
-
#VALX: 显示当前图例的X轴的对应文本(或数据)
-
#VAL, #VALY, 显示当前图例的Y轴的对应文本(或数据)
-
#VALY2, #VALY3, 显示当前图例的辅助Y轴的对应文本(或数据)
-
#SER: 显示当前图例的名称
-
#LABEL 显示当前图例的标签文本
-
#INDEX 显示当前图例的索引
-
#PERCENT 显示当前图例的所占的百分比
-
#TOTAL 总数量
-
#LEGENDTEXT 图例文本
这些取值无法应用在Title上
设置标题
//标题
Piechart.Titles.Add("饼状图图显示分析");//会将文字赋值给Title.Text属性
Piechart.Titles[0].Visible = true;
Piechart.Titles[0].ForeColor = Color.Black;
Piechart.Titles[0].Font = new Font("微软雅黑", 12f, FontStyle.Regular);
Piechart.Titles[0].Alignment = ContentAlignment.TopCenter;
或者属性中
设置饼图Label说明位置
饼图的说明位于外侧,同时使用连线指明
Piechart.Series[0]["PieLabelStyle"] = "Outside";//将文字移动到外侧
Piechart.Series[0]["PieLineColor"] = "Black";//绘制黑色的连线
PieLabelStyle属于自定义属性,枚举类型取值只有三种
- Outside: Label位于外面
- Inside: Label位于饼图内部(位置固定,要想调整估计只能查看源码)
- Disabled:不显示标签
饼图lable位于外部时,靠近饼图设置
如下,在杂项中或者代码中设置
MachineErrorCodePiehart.Series[0]["PieLabelStyle"] = "Outside";
MachineErrorCodePiehart.Series[0]["LabelsHorizontalLineSize"] = "0";
MachineErrorCodePiehart.Series[0]["LabelsRadialLineSize"] = "0";
指定图例的颜色
饼图的图例
指定图例或者指定类型的颜色(图例与之对应)
//指定图例颜色
Piechart.Series[0].Points[0].Color = Color.Black;
Piechart.Series[0].Points[1].Color = Color.Blue;
Piechart.Series[0].Points[2].Color = Color.Gray;
Piechart.Series[0].Points[3].Color = Color.Yellow;
Piechart.Series[0].Points[4].Color = SystemColors.Control;
Piechart.Series[0].Points[5].Color = Color.Red;
Piechart.Series[0].Points[6].Color = Color.Purple;
Piechart.Series[0].Points[7].Color = Color.Pink;
Piechart.Series[0].Points[8].Color = Color.SeaShell;
效果
设置图例渐变色
设置Series 的BackGradientStyle指定渐变色的方向,BackSecondaryColor指定渐变色淡出的颜色,Color为渐变色进入的颜色
Piechart.Series[0].Points[0].BackGradientStyle = GradientStyle.DiagonalRight;
Piechart.Series[0].Points[0].Color = Color.Red;
Piechart.Series[0].Points[0].BackSecondaryColor = Color.Brown;
...
只有一个图例的柱状图
对于只有一个图例的柱状图,可以指定调色板,实现不同的颜色(饼图也可以使用这种方式)
//启用并指定调色板
Piechart.Series[0].Palette = ChartColorPalette.Bright;
多Series时指定颜色
//指定颜色
currentSeries.Color= Color.Red;
启用3D样式
-
启用
Piechart.ChartAreas[0].Area3DStyle.Enable3D = true;
Piechart.ChartAreas[0].Area3DStyle.WallWidth = 7;//获取或设置3D中显示的墙的宽度
- 设置旋转
Piechart.ChartAreas[0].Area3DStyle.Inclination = 30;//水平轴旋转的角度
Piechart.ChartAreas[0].Area3DStyle.Rotation=30;//Y轴旋转的角度
关于3D的位置变化,通过TransformPoints函数设置3D图片的变化没有效果,网上和微软官网都没给出相应的示例,暂不知其用法。
Piechart.ChartAreas[0].TransformPoints(Point3D[] Args);
数据点分离
饼图或环形图可以通过自定义属性Exploded,设置数据点和图标的分离。
如设置第一个数据点分离:
Piechart.Series[0].Points[0]["Exploded"] = "True";
效果如图:
更多自定义属性,详见自定义属性列表(图表控件)
改为圆环图
修改Serie的ChartType图表类型为Doughnut,
-
设置圆环的大小通过自定义参数
DoughnutRadius设置
//自定义参数另一种使用方法
productionPiechart.Series[0].CustomProperties = "DoughnutRadius = 25";
//productionPiechart.Series[0]["DoughnutRadius"] = "25";
其他图表
条形图
-
添加条形图
添加一个Chart控件(name为chart),默认Serie的属性ChartType类型为Column,即为条形图。
属性Series中增加两个Serie对象,名字为张三、李四、王五,添加Title
-
添加绑定数据
List<string> x = new List<string>() { "语文","数学","英语","物理","化学"};
List<int> zhang = new List<int>() { 10, 20, 30, 40, 50 };
List<int> li = new List<int>() { 10, 12, 23, 46, 65 };
List<int> wang = new List<int>() { 50, 40, 39, 21, 9 };
//添加数据集。此处为添加多个数据序列,仙童x序列值绘制在一起
chart.Series["张三"].Points.DataBindXY( x,zhang);
chart.Series["李四"].Points.DataBindXY( x,li);
chart.Series["王五"].Points.DataBindXY( x,wang);
-
显示如图
设置条形图样式为圆柱图
在Series属性中,将上面的条形图中的杂项>CustomProperties自定义属性中的DrawingStyle设置为Cylingder(Bar类型图同样适用)。
chart.Series[0].CustomProperties = "DrawingStyle=Cylinder";
不可见图例
chart.Series[0].Palette = ChartColorPalette.BrightPastel;//亮色表示
chart.Series[0].IsVisibleInLegend = false;//不可见图例
设置轴文字的倾斜
chart.ChartAreas[0].AxisX.LabelStyle.Angle =-45;//x轴倾斜的角度。
堆积柱形图
选择Series的ChartType属性类型为StackedColumn,实现堆积柱形图(在柱形图中,数值进行累加叠放)
设置IsValueShownAsLabel属性Label显示数据点
重叠柱状图
在Series的自定义属性中,设置DrawSideBySide(并行绘制具有相同X值的数据点)为False。柱状图将重叠在一起
如图
3D柱状图
启用3D样式(为方便观看,此处Series改为一个)
chart.ChartAreas[0].Area3DStyle.Enable3D = true;
网格线
- 设置
//设置网格线
chart.ChartAreas[i].AxisX.MajorGrid.LineColor = Color.Blue;
chart.ChartAreas[i].AxisX.MajorGrid.Interval = 2;//网格间隔
chart.ChartAreas[i].AxisX.MinorGrid.Interval = 2;
chart.ChartAreas[i].AxisY.MajorGrid.LineColor = Color.Blue;
chart.ChartAreas[i].AxisY.MajorGrid.Interval = 2;
chart.ChartAreas[i].AxisY.MinorGrid.Interval = 2;
- 取消网格线
chart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;//取消x轴,网格中竖线
//取消横线
chart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
chart.ChartAreas[0].AxisY2.MajorGrid.Enabled = false;
x或y轴设置自定义标签
CustomLabel类实现
CustomLabel label = new CustomLabel();
label.Text = "自定义标签";
label.ToPosition = 1;//设置自定义标签在轴坐标的位置
chart.ChartAreas[0].AxisX.CustomLabels.Add(label);//添加自定义标签
其他
图表控件抗锯齿
//是否使用抗锯齿
Piechart.AntiAliasing = AntiAliasingStyles.All;
//抗锯齿应用于文本的质量
Piechart.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
X轴或Y轴显示数据显示不全问题
暂时没碰到,但有看到这个问题,原文chart控件X轴(Y轴)数值显示不全
设置间隔模式实现
//设置间隔模式
Chart1.ChartAreas["Default"].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
Chart所属类说明
下面是对类的一些较详细的介绍,大概了解下
ChartAreas属性中的类
- ChartArea 类:表示图表图像上的图表区域。
- AxisX:获取或设置表示主 X 轴的 Axis 对象。
- AxisY:获取或设置表示主 Y 轴的 Axis 对象。
- BackColor:获取或设置 ChartArea 对象的背景色。
- BackGradientStyle:获取或设置图表区域的背景渐变方向,还确定是否使用渐变。
- ShadowColor:获取或设置 ChartArea 对象的阴影颜色。
- ShadowOffset:获取或设置 ChartArea 对象的阴影偏移量(以像素为单位)。
- Axis 类:提供管理 Chart 控件中的轴的方法和属性。
- MajorGrid:获取或设置用于设置轴的主要网格线属性的 Grid 对象。
- Title:获取或设置轴的标题。
- ArrowStyle:获取或设置二维轴的箭头样式;此样式不适用于三维图表区域。
- Interval:获取或设置轴的间隔。(坐标轴数据间隔)
- IntervalOffset:获取或设置轴的间隔偏移量。(坐标轴第一个数据距离原点的间隔)
- Maximum:获取或设置轴的最大值。
- Minimum:获取或设置轴的最小值。
- Grid 类:提供用于管理 Axis 对象的主要和次要网格的方法和属性。
- Interval:获取或设置主要网格线或次要网格线之间的间隔。(相邻两个网格线间的间隔,int)
- IntervalType:获取或设置主要网格线或次要网格线的间隔类型。(计算单位)
- IntervalOffset:获取或设置网格线的偏移量。(第一个网格线偏移坐标轴的间隔,int)
- IntervalOffsetType:获取或设置主要网格线和次要网格线的间隔偏移量类型。(计算单位)
- LineColor:获取或设置网格线颜色。
- LineDashStyle:获取或设置网格的线型。
- LineWidth:获取或设置主要网格线和次要网格线的线条宽度。
Series属性下的类
- Series 类:存储数据点和序列特性。
- ChartType:获取或设置序列的图表类型。用以控制ChartArea属性指定的ChartArea显示的类型。
- SeriesChartType 枚举:指定 Series 的图表类型。
- XValueType:获取或设置沿 X 轴绘制的值类型,默认AUto。
- YValueType:获取或设置序列所存储的数据点中的 Y 值数据类型,默认Auto。
- IsValueShownAsLabel:获取或设置一个标志,该标志指示是否在标签上显示数据点的值。
- Points:获取 DataPointCollection 对象,序列数据点的集合。(比如数据表中的数据点)
- DataPointCollection 类:表示 DataPoint 对象的集合。
- Item:获取或设置指定索引处的元素。(即 DataPoint 对象)
- AddXY(Double, Double):使用指定的 X 值和 Y 值将 DataPoint 对象添加到集合末尾。
- AddY(Double):使用指定的 Y 值将 DataPoint 对象添加到集合末尾。
- Clear:从 Collection 中移除所有元素。
- Insert:将元素插入 Collection 的指定索引处。
- InsertXY:插入具有指定 X 值和一个或多个指定 Y 值的数据点。
- InsertY:插入具有一个或多个指定 Y 值的数据点。
- DataPoint 类:表示存储在 DataPointCollection 类中的数据点。
- XValue:获取或设置数据点的 X 值。
- YValues:获取或设置数据点的 Y 值。(数组的形式,值一般是[0])
- Color:获取或设置数据点的颜色。
- BorderColor:获取或设置数据点的边框颜色。
- MarkerStyle:获取或设置标记样式。
- MarkerStyle 枚举:获取或设置标记样式。
- MarkerColor:获取或设置标记颜色。(数据点)
- MarkerSize:获取或设置标记的大小。
- MarkerBorderColor:获取或设置标记的边框颜色。
- MarkerBorderWidth:获取或设置标记的边框宽度。
- Color:获取或设置数据点的颜色。(数据点和连接的线)
- BorderWidth:获取或设置数据点的边框宽度。
- BorderDashStyle:获取或设置数据点的边框样式。
- BorderColor:获取或设置数据点的边框颜色。
- EmptyPointStyle:获取或设置标记为空的点的绘制样式。
- LabelBackColor:获取或设置数据点标签的背景色。
- LabelBorderColor:获取或设置数据点标签的边框颜色。
- LabelBorderDashStyle:获取或设置标签的边框样式。
- LabelBorderWidth:获取或设置标签的边框宽度。
- IsVisibleInLegend:获取或设置一个标志,该标志指示是否在图例中显示项。
- LegendText:获取或设置图例中项的文本。
- Palette:调色板,用于不同条目显示不同颜色(可自己尝试)
Titles相关类
Titles集合时Title类的集合
- Title 类:表示整个图表图像的标题。
- Alignment:获取或设置标题的对齐方式。
- ForeColor:获取或设置标题文本的颜色。
- ShadowColor:获取或设置标题的阴影颜色。
- ShadowOffset:获取或设置标题的阴影偏移量(以像素为单位)。
- Position:获取或设置可用于获取或设置标题位置的 ElementPosition 对象。
- Text:获取或设置标题的文本。
- TextOrientation:获取或设置标题中文本的方向。
- TextStyle:获取或设置标题的文本样式。
Legends相关类
Legends表示 Legend 对象的集合。
- Legend 类:表示图表图像的图例。
- Alignment:获取或设置图例的对齐方式,图例位置为AUto时可用。
- Near:如果图例停靠到顶部或底部,则 Near 位于左侧;如果图例停靠到左侧或右侧,则 Near 位于顶部。
- Center:总是将图例垂直或水平居中。
- Far:如果图例停靠到顶部或底部,则 Far 位于右侧;如果图例停靠到左侧或右侧,则 Far 位于底部。
- Docking:图例停靠的位置,上下左右位置
- Title:获取或设置图例标题的文本。
- ShadowColor:获取或设置图例的阴影颜色。
- ShadowOffset:获取或设置图例的阴影偏移量(以像素为单位)。
Annotations批注集合
Chart.Annotations 集合属性包含图表控件中的所有批注(Annotation 对象)