winfrom图标控件chart使用(一)——Chart控件使用介绍及制作显示百分比的饼图

1,004 阅读13分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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属性IsValueShownAsLabelTrue,将数据点的值显示在标签

显示:

设置显示百分比

  • 设置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 对象)

参考

微软官方文档

Winform中Chart图表的简单使用

【207】WinForm Chart类