WinForm 图表控件(Chart)从零入门笔记

适用场景:上位机 / 工业自动化
阅读目标:跟着做,4 个小例子全都能跑起来,顺便把常用属性记熟
前提:你会一点点 C# 语法(变量、循环、判断)就行,控件操作我一步步带你点


0. 先认识一下 Chart 这个控件

  • 它是干嘛的:把你采集到的数据变成"图"——曲线、柱子、饼图,让人一眼看懂趋势和占比。
  • 工业里能干嘛:温度传感器曲线、各班次产量对比、设备运行状态占比、实时数据看板。
  • 它住哪:命名空间 System.Windows.Forms.DataVisualization.Charting,.NET Framework 项目自带,不用装额外包。

一句话:Chart = 把数字画成图的小工具。


1. 第一步:把 Chart 控件请进窗体

  1. 打开 Visual Studio,新建一个 Windows 窗体应用(.NET Framework 或 .NET 6/8 均可)。
  2. 在右侧 工具箱 里找到 Chart(一般在"数据"分类下),拖到窗体上。
  3. 在右下角 属性 面板里,把控件名字 (Name) 改成 chart1,好记也好写代码。
  4. 拖动控件四角放大,让它占窗体大半个位置。

【提示】如果工具箱里找不到 Chart:右键工具箱空白处 → "选择项" → ".NET Framework 组件" → 勾上 System.Windows.Forms.DataVisualization.Charting.Chart → 确定。

【提示】如果你用的是 .NET 6/8(非 Framework):需要先在"NuGet 包管理器"里搜索安装 System.Windows.Forms.DataVisualization,装完重启设计器就能看到 Chart 了。


2. 搞懂 Chart 的"三层结构"(最重要)

把 Chart 想象成一张画布:

层级 中文名 干什么的
Chart 图表控件 整张图,负责显示
ChartArea 绘图区 真正画图的那个框,决定坐标轴、背景
Series 数据系列 一条线 / 一排柱子 / 一块饼,数据就挂在这里
Legend 图例 右上角说明"这根线代表什么"
Title 标题 图的名字

记住一句核心逻辑:往 Series 里塞数据 → 调 ChartArea 决定坐标轴和外观 → Chart 负责显示出来。

下文的代码全部围绕这三层来写,看懂了就不会乱。


3. 第一个能跑的例子:温度传感器折线图

目标:显示一天里 5 个时刻的温度,画成一条曲线。

操作:

  1. 拖一个 Chart 到窗体,(Name) 设为 chart1。
  2. 双击窗体空白处,进入 Form1_Load 事件,把下面代码整段粘进去。
private void Form1_Load(object sender, EventArgs e)
{
    // 1. 这条系列画成"折线"
    chart1.Series[0].ChartType =
        System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;

    // 2. 给系列起个名(会显示在图例里)
    chart1.Series[0].Name = "温度";

    // 3. 塞数据:X 是时间,Y 是温度值(℃)
    chart1.Series[0].Points.AddXY("08:00", 23.5);
    chart1.Series[0].Points.AddXY("10:00", 26.1);
    chart1.Series[0].Points.AddXY("12:00", 29.8);
    chart1.Series[0].Points.AddXY("14:00", 31.2);
    chart1.Series[0].Points.AddXY("16:00", 28.4);

    // 4. 坐标轴标题
    chart1.ChartAreas[0].AxisX.Title = "时间";
    chart1.ChartAreas[0].AxisY.Title = "温度(℃)";

    // 5. 图表标题
    chart1.Titles.Add("车间温度传感器曲线");
}

按 F5 运行,你就能看到一条温度曲线了。✅

【小结】Series[0] 是默认就存在的第一条数据系列。Points.AddXY(x, y) 就是"往图上加一个点"。


4. 常用属性逐个看(大白话版)

4.1 Series(数据系列)常用属性

属性 作用 常用写法
ChartType 图表类型 Line(折线) / Column(柱状) / Pie(饼图) / Bar(横条) / Spline(平滑曲线)
Name 系列名称(显示图例) series.Name = "温度"
Color 线条/柱子的颜色 series.Color = Color.Red
BorderWidth 线条粗细 series.BorderWidth = 3
MarkerStyle 数据点标记形状 series.MarkerStyle = MarkerStyle.Circle
MarkerSize 标记大小 series.MarkerSize = 6
IsValueShownAsLabel 是否在点上显示数值 series.IsValueShownAsLabel = true
LegendText 图例里显示的文字 series.LegendText = "1号传感器"

4.2 ChartArea(绘图区)常用属性

属性 作用 常用写法
AxisX.Title / AxisY.Title X / Y 轴标题 chart1.ChartAreas[0].AxisY.Title = "温度"
AxisX.Minimum / Maximum 坐标轴最小值/最大值 AxisY.Minimum = 0; AxisY.Maximum = 100
AxisX.Interval 刻度间隔 AxisX.Interval = 1(每 1 个单位一个刻度)
AxisX.LabelStyle.Angle 坐标轴文字倾斜角度 AxisX.LabelStyle.Angle = -45(斜着防重叠)
BackColor 绘图区背景色 ChartAreas[0].BackColor = Color.WhiteSmoke

4.3 Chart(控件整体)常用属性

属性 作用 常用写法
Titles 图表标题集合 chart1.Titles.Add("标题文字")
Dock 控件停靠方式 chart1.Dock = DockStyle.Fill(填满父容器)
Palette 配色方案 chart1.Palette = ChartColorPalette.BrightPastel
Legends 图例集合 默认有一个,可改 Legend[0].Title

【记忆窍门】属性很多,记住最常用的 8 个就够入门:ChartType、Points.AddXY、AxisX/Y.Title、Minimum/Maximum、IsValueShownAsLabel、Color、Titles.Add、Dock。剩下的用到再查。


5. 第二个例子:各班次产量柱状图

目标:对比早/中/晚班的产量。

private void Form1_Load(object sender, EventArgs e)
{
    // 画成柱状
    chart1.Series[0].ChartType =
        System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column;

    chart1.Series[0].Name = "产量(件)";
    chart1.Series[0].Color = Color.SteelBlue;
    chart1.Series[0].IsValueShownAsLabel = true; // 柱顶显示数字

    chart1.Series[0].Points.AddXY("早班", 320);
    chart1.Series[0].Points.AddXY("中班", 285);
    chart1.Series[0].Points.AddXY("晚班", 360);

    chart1.ChartAreas[0].AxisX.Title = "班次";
    chart1.ChartAreas[0].AxisY.Title = "产量(件)";
    chart1.ChartAreas[0].AxisY.Minimum = 0;

    chart1.Titles.Add("今日各班次产量对比");
}

只改了 ChartType 和 Color,其余结构跟折线图一模一样。✅


6. 第三个例子:设备状态占比饼图

目标:看一台设备"运行 / 待机 / 故障"时间占比。

private void Form1_Load(object sender, EventArgs e)
{
    chart1.Series[0].ChartType =
        System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Pie;

    chart1.Series[0].Name = "设备状态";
    chart1.Series[0].IsValueShownAsLabel = true; // 显示百分比
    chart1.Series[0].Label = "#PERCENT";          // 标签显示成百分比

    chart1.Series[0].Points.AddXY("运行", 70);
    chart1.Series[0].Points.AddXY("待机", 20);
    chart1.Series[0].Points.AddXY("故障", 10);

    chart1.Titles.Add("设备运行状态占比");
}

【提示】饼图一般不用坐标轴标题(饼图没有 X/Y 轴)。Label = "#PERCENT" 是内置关键字,会自动把数值算成百分比显示。


7. 第四个例子(进阶但很实用):实时刷新曲线

目标:模拟 PLC 每 1 秒发来一个压力值,曲线从左往右"滚动"显示最近 20 个点。这是工业看板最常见的玩法。

操作:

  1. 拖一个 Chart((Name)=chart1)到窗体。
  2. 拖一个 Button((Name)=btnStart,Text=开始采集)。
  3. 拖一个 Timer((Name)=timer1)。
  4. 双击窗体进 Form1_Load,双击按钮进 btnStart_Click,双击 Timer 进 timer1_Tick,把下面三段分别粘进去。
// ===== 窗体加载时:先把图表框架搭好 =====
private int count = 0;
private Random rand = new Random();

private void Form1_Load(object sender, EventArgs e)
{
    chart1.Series[0].ChartType =
        System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
    chart1.Series[0].Name = "实时压力";
    chart1.Series[0].BorderWidth = 2;

    chart1.ChartAreas[0].AxisX.Title = "采样次数";
    chart1.ChartAreas[0].AxisY.Title = "压力(kPa)";
    chart1.ChartAreas[0].AxisY.Minimum = 0;
    chart1.ChartAreas[0].AxisY.Maximum = 100;

    timer1.Interval = 1000; // 每 1000 毫秒(1秒)触发一次
}

// ===== 点按钮:启动定时器 =====
private void btnStart_Click(object sender, EventArgs e)
{
    timer1.Start();
}

// ===== 定时器每秒触发:加一个新点,超出的删最老的 =====
private void timer1_Tick(object sender, EventArgs e)
{
    count++;
    double val = rand.Next(40, 90);          // 模拟 PLC 来的数据
    chart1.Series[0].Points.AddXY(count, val);

    // 只保留最近 20 个点,曲线就会"滚动"
    if (chart1.Series[0].Points.Count > 20)
        chart1.Series[0].Points.RemoveAt(0);
}

运行后点"开始采集",曲线就开始一秒一跳地动了。✅
以后把 rand.Next(...) 换成你从串口 / Modbus 读到的真实数值,就是真正的监控看板。


8. 新手常踩的坑

  • 图是空白的:忘记往 Series 加数据,或者没设 ChartType。
  • 中文变成方框/乱码:把控件或坐标轴字体设成"微软雅黑"等系统有的中文字体。
  • .NET 新版本找不到 Chart:去 NuGet 装 System.Windows.Forms.DataVisualization。
  • 多条线重叠看不清:给每个 Series 设不同的 Color。
  • X 轴文字挤在一起:AxisX.LabelStyle.Angle = -45 让它斜着显示。

posted @ 2026-08-25 13:50  春煦景明  阅读(51)  评论(0)    收藏  举报