基于.NET的Windows窗体编程之WinForms图表控件

在软件开发中,常有“字不如表,表不如图”之说,一大段的文字数据描述,不如表格来得直观清晰,而图表则更加能描述数据的规律和走向,常见的有:销售直方图,股票K线图等,今天我们以一些简单的小例子,简述在基于.NET的Windows窗体编程中Chart图表的基本用法,仅供学习分享使用,如有不足之处,还请指正。

image

 

概述

 

Chart控件是WinForm框架自带的图标控件,它位于System.Windows.Forms.DataVisualization.Charting命名空间,此功能强大,可以绘制柱状图,折线图,波形图,饼状图等,利用Chart控件,可以快速的开发图标相关功能。Chart控件的相关概念:

  • ChartArea,表示图表区域,一个Chart可以绘制多个ChartArea,重叠在一起。
  • Series ,表示数据序列,每个ChartArea可以有多个数据线。即,Series属于ChartArea.
  • AxisX,AxisY,表示主坐标轴,每一个ChartArea都有对应的坐标轴,包括主坐标轴,辅坐标轴

 

Chart控件只支持基于.NET Framework的WinForm应用程序,如果是新的基于.NET5.0之后的,则不能应用此控件,可以采用其他第三方组件。默认在数据区域,如下所示:

image

如果在工具箱的数据栏中不存在,则可以手动添加到工具项。在工具箱空白处点击右键,在弹出的快捷菜单中,选择“选择项(I)...”,打开“选择工具箱项”对话框,如下所示:

image

在弹出的“选择工具箱项”对话框中,在“.NET Framework组件”Tab项中,选择Chart,然后点击“确定”即可,如下所示:

image

在Chart控件中,图表的类型主要有Series的ChartType属性决定,它是SeriesChartType类的枚举,主要有以下图标类型:

  • Point, 点图类型
  • FastPoint, 快速点图图表类型
  • Bubble, 气泡图类型
  • Line,折线图图表
  • Spline, 样条图类型
  • StepLine, 阶梯折线图
  • FastLine, 快速扫描线图
  • Bar, 条形图
  • StackedBar, 堆积条形图
  • StackedBar100, 百分比堆积条形图
  • Column, 柱状图直方图
  • StackedColumn, 堆积柱状图
  • StackedColumn100,百分比堆积柱状图
  • Area, 面积图
  • SplineArea, 样条面积图
  • StackedArea, 堆积面积图
  • StackedArea100,百分比堆积面积图
  • Pie,饼图
  • Doughnut, 圆环图图表类型
  • Stock, 股价图
  • Candlestick, K线图图表类型
  • Range,范围图
  • SplineRange, 样条范围图
  • RangeBar, 范围条形图
  • RangeColumn, 范围柱状图
  • Radar, 雷达图类型
  • Polar, 极坐标图
  • ErrorBar, 误差条形图
  • BoxPlot, 盒须图类型
  • Renko, 砖型图
  • ThreeLineBreak,
  • Kagi, 卡吉图图表类型
  • PointAndFigure,点数图图表类型
  • Funnel, 漏斗图
  • Pyramid 棱锥图类型

 

折线图Line

 

折线图主要是用线条起伏来展示数据随时间变化趋势的图表,核心作用是让人一眼看出数据是涨了还是跌了,适合用来分析销售走势、气温变化或股票行情等连续数据 。‌‌在Chart控件中,折线图的ChartType为SeriesChartType.Line。

首先拖动Chart控件到Form表单中,并命名为chartLine,在Form表单的Load事件中初始化Chart控件,步骤如下:

  1. 构造折线图表的数据,在此示例中构建了两个部门的累计销售数据。
  2. 清空Chart控件的示例数据,如ChartArea,Series,Titles等。
  3. 定义ChartArea,如背景色,轴的定义等。
  4. 定义Title,如标题的文本内容,位置,大小,颜色等。
  5. 定义数据序列Series,根据第1步构造的数据创建Series对象,每一个部门一个数据序列

核心代码如下所示:

private void InitChartLine()
{
    //构建数据,在此构建两个部门的累计销售数据
    List<double[]> datas = new List<double[]>()
    {
        new double[12] { 5, 18, 24, 32, 43, 48, 65, 73, 82, 90, 95, 100 },
        new double[12] { 8, 15, 26, 39, 58, 79, 81, 90, 93, 99,99,99 }
    };
    //清空原始数据
    this.chartLine.ChartAreas.Clear();
    this.chartLine.Series.Clear();
    this.chartLine.Titles.Clear();
    //定义图标区域,如:背景色,轴的定义
    ChartArea chartArea = new ChartArea("line");
    chartArea.BackColor = Color.White;
    chartArea.AxisX.ArrowStyle = AxisArrowStyle.Triangle;
    chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
    chartArea.AxisX.Title = "月份";
    chartArea.AxisX.Name = "月份";
    chartArea.AxisX.ScaleBreakStyle.BreakLineStyle = BreakLineStyle.Straight;
    chartArea.AxisX.LineColor = Color.Blue;
    chartArea.AxisY.ArrowStyle = AxisArrowStyle.Triangle;
    chartArea.AxisY.Minimum = 0;
    chartArea.AxisY.Maximum = 100;
    chartArea.AxisY.Interval = 10;
    chartArea.AxisY.Title = "累计销量(w)";
    chartArea.AxisY.IntervalAutoMode = IntervalAutoMode.FixedCount;
    chartArea.AxisY.Name = "累计销量(w)";
    chartArea.AxisY.LineColor = Color.Blue;
    this.chartLine.ChartAreas.Add(chartArea); 
    //定义标题,如标题文本,位置,字体,颜色等
    Title title = new Title("XXX公司年度报表1", Docking.Top, new Font("宋体", 14, FontStyle.Bold), Color.Blue);
    this.chartLine.Titles.Add(title);
    //定义序列Series,每一个部门的销售数据,一条Series
    for (int i = 0; i < datas.Count; i++)
    {
        double[] data = datas[i];
        Series series = new Series($"部门-{i}");
        series.ChartArea = $"line";
        series.ChartType = SeriesChartType.Line;
        series.MarkerStyle = MarkerStyle.Circle;
        series.Color = i == 0 ? Color.Red : Color.Green;
        series.ToolTip = "当前月份:#VAL\n最高分:#MAX\n最低分:#MIN";
        for (int j = 0; j < data.Length; j++)
        {
            series.Points.AddXY($"{j+1}月", data[j]);
        }

        this.chartLine.Series.Add(series);
    }
}

运行上述代码,示例效果如下所示:

image

 

柱状图Column

 

‌柱状图‌是用竖直柱子的高度来比较不同类别数据大小的图表,英文常译为 ‌Column Chart‌ 或 ‌Bar Chart‌,核心作用是一眼看出谁多谁少‌。在Chart控件中,柱状图的ChartType为SeriesChartType.Column。

首先拖动Chart控件到Form表单中,并命名为chartColumn,在Form表单的Load事件中初始化Chart控件,步骤如下:

  1. 构造柱状图表的数据,在此示例中构建了两个部门的月度销售数据。
  2. 清空Chart控件的示例数据,如ChartArea,Series,Titles等。
  3. 定义ChartArea,如背景色,轴的定义等。
  4. 定义Title,如标题的文本内容,位置,大小,颜色等。
  5. 定义数据序列Series,根据第1步构造的数据创建Series对象,每一个部门一个数据序列

核心代码如下所示:

private void InitChartColumn()
{
    //构造数据
    List<double[]> datas = new List<double[]>()
    {
        new double[12] { 5, 13, 6, 8, 8, 5, 17, 8, 9, 8, 5, 5 },
        new double[12] { 8, 7, 11, 13, 20, 21, 2, 9, 3, 6,0.1,2 }
    };
    //清空原始数据
    this.chartColumn.ChartAreas.Clear();
    this.chartColumn.Series.Clear();
    this.chartColumn.Titles.Clear();
    //定义图标区域,如:背景色,轴的定义
    ChartArea chartArea = new ChartArea("column");
    chartArea.BackColor = Color.White;
    chartArea.AxisX.ArrowStyle = AxisArrowStyle.Triangle;
    chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
    chartArea.AxisX.Title = "月份";
    chartArea.AxisX.Name = "月份";
    chartArea.AxisX.ScaleBreakStyle.BreakLineStyle = BreakLineStyle.Straight;
    chartArea.AxisY.ArrowStyle = AxisArrowStyle.Triangle;
    chartArea.AxisY.Title = "月度销量(w)";
    chartArea.AxisY.IntervalAutoMode = IntervalAutoMode.FixedCount;
    chartArea.AxisY.Name = "月度销量(w)";
    this.chartColumn.ChartAreas.Add(chartArea);
    //定义标题,如标题文本,位置,字体,颜色等
    Title title = new Title("XXX公司年度报表2", Docking.Top, new Font("宋体", 14, FontStyle.Bold), Color.Blue);
    this.chartColumn.Titles.Add(title);
    //构造数据序列Series,每一个部门一个series。
    for (int i = 0; i < datas.Count; i++)
    {
        double[] data = datas[i];
        Series series = new Series($"部门-{i}");
        series.ChartArea = $"column";//所属chartArea
        series.ChartType = SeriesChartType.Column;//图表类型为柱状图
        series.ToolTip = "当前月份:#VAL\n最高分:#MAX\n最低分:#MIN";
        series.Color = i == 0 ? Color.Red : Color.Green;
        for (int j = 0; j < data.Length; j++)
        {
            series.Points.AddXY($"{j + 1}月", data[j]);
        }

        this.chartColumn.Series.Add(series);
    }
}

运行上述代码,示例效果如下所示:

image

 

饼图Pie

 

饼图是用扇形面积表示部分占整体比例的统计图‌,常用于展示结构关系。在Chart控件中,饼状图的ChartType为SeriesChartType.Pie。

首先拖动Chart控件到Form表单中,并命名为chartPie,在Form表单的Load事件中初始化Chart控件,步骤如下:

  1. 构造饼状图表的数据,在此示例中构建了公司水果年度销量占比数据。
  2. 清空Chart控件的示例数据,如ChartArea,Series,Titles等。
  3. 定义ChartArea,如背景色,饼状图不需要显示轴信息等。
  4. 定义Title,如标题的文本内容,位置,大小,颜色等。
  5. 定义数据序列Series,根据第1步构造的数据创建Series对象

核心代码如下所示:

private void InitChartPie()
{
    //构造数据
    double[] datas = new double[6] { 5, 13, 6, 8, 8, 5 };
    string[] fruits = new string[6] { "苹果", "香蕉", "梨子", "西瓜", "火龙果", "榴莲" };
    //清除数据
    this.chartPie.ChartAreas.Clear();
    this.chartPie.Series.Clear();
    this.chartPie.Titles.Clear();
    //构造图表区域
    ChartArea chartArea = new ChartArea("pie");
    chartArea.BackColor = Color.White;
    this.chartPie.ChartAreas.Add(chartArea);
    //设置标题
    Title title = new Title("XXX公司年度水果销量报表", Docking.Top, new Font("宋体", 14, FontStyle.Bold), Color.Blue);
    this.chartPie.Titles.Add(title);
    //设置数据序列
    Series series = new Series($"水果销量");
    series.ChartArea = $"pie";
    series.ChartType = SeriesChartType.Pie;
    series.IsValueShownAsLabel = false;
    series.Label = "#VALX:#VAL";
    series.ToolTip = "当前月份:#VAL\n最高分:#MAX\n最低分:#MIN";
    for (int i = 0; i < datas.Length; i++)
    {
        series.Points.AddXY($"{fruits[i]}", datas[i]);
    }
    this.chartPie.Series.Add(series);
}

运行上述代码,示例效果如下所示:

image

 

样条图Spline

 

样条图是通过一组给定点集生成平滑曲线图,即折线图看起来是有转折点,样条图看起来更平滑。在Chart控件中,样条图的ChartType为SeriesChartType.Spline。

首先拖动Chart控件到Form表单中,并命名为chartSpline,在Form表单的Load事件中初始化Chart控件,步骤如下:

  1. 构造样条图表的数据,在此示例中构建了数学函数中的Sin和Cos数据。
  2. 清空Chart控件的示例数据,如ChartArea,Series,Titles等。
  3. 定义ChartArea,如背景色,轴信息等。
  4. 定义Title,如标题的文本内容,位置,大小,颜色等。
  5. 定义数据序列Series,根据第1步构造的数据创建Series对象

核心代码如下所示:

private void InitChartSpline()
{
    //构建数据
    List<double[]> datas = new List<double[]>();
    for (int i = 0; i < 2; i++)
    {
        List<double> data = new List<double>();
        for (double j = -2; j < 2; j = j + 0.1)
        {
            data.Add(i == 0 ? Math.Sin(j * Math.PI) : Math.Cos(j * Math.PI));
        }
        datas.Add(data.ToArray());
    }
    //曲线名称
    List<string> names = new List<string>()
    {
        "sin",
        "cos"
        };
    //清空初始数据
    this.chartSpline.ChartAreas.Clear();
    this.chartSpline.Series.Clear();
    this.chartSpline.Titles.Clear();
    //定义图标区域,如背景色,轴定义等
    ChartArea chartArea = new ChartArea("spline");
    chartArea.BackColor = Color.White;
    chartArea.AxisX.ArrowStyle = AxisArrowStyle.Triangle;
    chartArea.AxisX.Minimum = -2;
    chartArea.AxisX.Maximum = 2;
    chartArea.AxisX.Interval = 0.2;
    chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
    chartArea.AxisX.Title = "x轴";
    chartArea.AxisX.Name = "x";
    chartArea.AxisX.ScaleBreakStyle.BreakLineStyle = BreakLineStyle.Straight;
    chartArea.AxisX.LineColor = Color.Blue;
    chartArea.AxisY.ArrowStyle = AxisArrowStyle.Triangle;
    chartArea.AxisY.Title = "y轴";
    chartArea.AxisY.IntervalAutoMode = IntervalAutoMode.FixedCount;
    chartArea.AxisY.Name = "y";
    chartArea.AxisY.LineColor = Color.Blue;
    this.chartSpline.ChartAreas.Add(chartArea);
    //定义标题
    Title title = new Title("数值曲线", Docking.Top, new Font("宋体", 14, FontStyle.Bold), Color.Blue);
    this.chartSpline.Titles.Add(title);
    //构造数据序列,每一条曲线一个数据序列
    for (int i = 0; i < datas.Count; i++)
    {
        double[] data = datas[i];
        Series series = new Series($"{names[i]}曲线");
        series.ChartArea = $"spline";
        series.ChartType = SeriesChartType.Spline;
        series.Color = i == 0 ? Color.Red : Color.Green;
        int startNum = -2;
        for (int j = 0; j < data.Length; j++)
        {
            series.Points.AddXY(Math.Round(startNum+j*0.1,3), data[j]);
        }

        this.chartSpline.Series.Add(series);
    }
}

运行上述代码,示例效果如下所示:

image

说明:Chart控件只支持基于.NET Framework的WinForm应用程序,如果是新的开发框架(如.NET5.0,6.0及之后的),则不支持此控件,可以采用其他第三方组件。

源码获取

 

关于本系列的完整代码,可以通过gitee上的库进行获取:https://gitee.com/ahsiang/winforms

image

以上就是《基于.NET的Windows窗体编程之WinForms图表控件》的全部内容,旨在抛砖引玉,一起学习,共同进步。

posted @ 2026-06-15 12:00  老码识途呀  阅读(44)  评论(0)    收藏  举报