【WinForm UI控件系列】散点图/折线图控件 (支持数值型、时间型、字符串型)

前言:c# winform UI控件系列(Net6+),纯GDI绘图无依赖,虽然做不到最好,争取做好更好用!

一、效果图 (x轴三种类型:数值、时间、字符串)





  • 支持五种颜色风格。
  • 标题:位置支持(左中右布局)
  • x轴标题、y轴标题:支持旋转角度。图例支持位置定义(选择合适位置)
  • 是否显示连线,是否显示网格线,是否圆滑曲线

二、使用说明

ScatterPlot 散点图/折线图控件

控件简介

ScatterPlot 是一个功能强大的散点图和折线图控件,参考 ScottPlot 设计,支持平滑曲线、多种X轴类型(数值型、字符串型、日期时间型)、网格线、值提示和图例显示。

主要特性

  • 多种X轴类型:支持 Numeric(数值)、Category(字符串类别)、DateTime(日期时间)
  • 平滑曲线:支持 Smooth 平滑曲线显示,可调整张力
  • 网格线:支持 X/Y 轴网格线显示控制
  • 值提示:鼠标悬停显示数据点值,支持自动格式化
  • 图例位置控制:支持 7 种图例位置(None, TopLeft, TopCenter, TopRight, BottomLeft, BottomCenter, BottomRight)
  • 轴标签旋转:支持 X/Y 轴标签旋转角度设置
  • 自动日期时间格式:根据时间跨度自动选择最优显示格式
  • 属性变更通知:实现 INotifyPropertyChanged,属性值改变立即生效

基本使用

简单散点图

csharp 复制代码
// 创建散点图控件
var scatterPlot = new ScatterPlot
{
    Dock = DockStyle.Fill,
    ColorType = ColorType.Primary
};

// 添加数据系列
var series = new ScatterSeries
{
    Name = "系列1",
    ShowLine = true,
    ShowMarkers = true,
    Smooth = true
};

// 添加数据点
for (int i = 0; i < 10; i++)
{
    series.Points.Add(new ScatterPoint(i, Math.Sin(i * 0.5) * 10 + 20));
}

scatterPlot.Series.Add(series);
scatterPlot.RefreshPlot();
this.Controls.Add(scatterPlot);

X轴类型设置

csharp 复制代码
// 数值型(默认)
scatterPlot.XAxisType = XAxisType.Numeric;

// 字符串类别型
scatterPlot.XAxisType = XAxisType.Category;

// 日期时间型
scatterPlot.XAxisType = XAxisType.DateTime;

日期时间型数据

当使用 XAxisType.DateTime 时,控件会自动根据时间跨度选择合适的显示格式:

时间跨度 X轴显示格式 Tooltip格式
≤24小时 HH:mm HH:mm
≤72小时 MM-dd HH:mm MM-dd HH:mm
≤30天 MM-dd MM-dd
≤1年 yyyy-MM yyyy-MM
>1年 yyyy-MM-dd yyyy-MM-dd
csharp 复制代码
// 日期时间型示例(24小时内数据)
scatterPlot.XAxisType = XAxisType.DateTime;
scatterPlot.Title = "24小时温度变化";
scatterPlot.XAxisLabel = "时间";

var series = new ScatterSeries
{
    Name = "今日温度",
    ShowLine = true,
    ShowMarkers = true
};

// 添加24小时内的数据点
DateTime today = DateTime.Now.Date;
series.Add(today.AddHours(0), 18);
series.Add(today.AddHours(6), 20);
series.Add(today.AddHours(12), 28);
series.Add(today.AddHours(18), 24);
series.Add(today.AddHours(24), 19);

scatterPlot.AddSeries(series);
scatterPlot.RefreshPlot();

图例位置控制

csharp 复制代码
scatterPlot.ShowLegend = true;
scatterPlot.LegendPosition = LegendPosition.TopRight;  // 右上角
scatterPlot.LegendOrientation = LegendOrientation.Horizontal;  // 水平排列

轴标签旋转

csharp 复制代码
// X轴标签旋转 45 度
scatterPlot.AxisLabelStyle.XAxisRotation = 45;

// Y轴标签旋转 -90 度
scatterPlot.AxisLabelStyle.YAxisRotation = -90;

网格线控制

csharp 复制代码
// 显示 X 轴网格线
scatterPlot.GridLineStyle.ShowX = true;

// 显示 Y 轴网格线
scatterPlot.GridLineStyle.ShowY = true;

// 设置网格线颜色
scatterPlot.GridLineStyle.Color = Color.FromArgb(230, 230, 230);

属性说明

主要属性

属性名 类型 默认值 说明
Series List - 数据系列集合
XAxisType XAxisType Numeric X轴类型
ColorType ColorType Primary 色彩类型
Title string "" 图表标题
XAxisLabel string "" X轴标题
YAxisLabel string "" Y轴标题

图例属性

属性名 类型 默认值 说明
ShowLegend bool true 是否显示图例
LegendPosition LegendPosition BottomCenter 图例位置
LegendOrientation LegendOrientation Horizontal 图例排列方向

轴标签样式

属性名 类型 默认值 说明
AxisLabelStyle.XAxisRotation int 0 X轴标签旋转角度
AxisLabelStyle.YAxisRotation int 0 Y轴标签旋转角度
AxisLabelStyle.FontSize float 9 标签字体大小
AxisLabelStyle.Color Color Gray 标签颜色

网格线样式

属性名 类型 默认值 说明
GridLineStyle.ShowX bool true 是否显示X轴网格线
GridLineStyle.ShowY bool true 是否显示Y轴网格线
GridLineStyle.Color Color LightGray 网格线颜色
GridLineStyle.Width int 1 网格线宽度

事件

PointClicked

数据点点击事件,可用于显示详细信息:

csharp 复制代码
scatterPlot.PointClicked += (sender, args) =>
{
    string xValue;
    if (scatterPlot.XAxisType == XAxisType.DateTime)
    {
        xValue = new DateTime((long)args.Point.X).ToString("MM-dd HH:mm");
    }
    else
    {
        xValue = args.Point.X.ToString();
    }
    
    MessageBox.Show($"系列: {args.Series.Name}\nX: {xValue}\nY: {args.Point.Y:F2}");
};

完整示例

24小时温度变化

csharp 复制代码
var scatterPlot = new ScatterPlot
{
    Dock = DockStyle.Fill,
    Title = "24小时温度变化",
    XAxisLabel = "时间",
    YAxisLabel = "温度 (°C)",
    XAxisType = XAxisType.DateTime,
    ShowLegend = true,
    LegendPosition = LegendPosition.BottomCenter
};

// 今日温度
var todaySeries = new ScatterSeries
{
    Name = "今日温度",
    LegendText = "今日",
    ShowLine = true,
    ShowMarkers = true,
    Smooth = true,
    SmoothTension = 0.4f,
    LineWidth = 2
};

DateTime today = DateTime.Now.Date;
todaySeries.Add(today.AddHours(0), 18);
todaySeries.Add(today.AddHours(2), 17);
todaySeries.Add(today.AddHours(4), 16);
todaySeries.Add(today.AddHours(6), 17);
todaySeries.Add(today.AddHours(8), 20);
todaySeries.Add(today.AddHours(10), 24);
todaySeries.Add(today.AddHours(12), 28);
todaySeries.Add(today.AddHours(14), 30);
todaySeries.Add(today.AddHours(16), 29);
todaySeries.Add(today.AddHours(18), 26);
todaySeries.Add(today.AddHours(20), 23);
todaySeries.Add(today.AddHours(22), 20);
todaySeries.Add(today.AddHours(24), 19);

scatterPlot.AddSeries(todaySeries);
scatterPlot.RefreshPlot();
this.Controls.Add(scatterPlot);

多日期温度对比

csharp 复制代码
var scatterPlot = new ScatterPlot
{
    Dock = DockStyle.Fill,
    Title = "温度趋势图",
    XAxisLabel = "日期",
    YAxisLabel = "温度 (°C)",
    XAxisType = XAxisType.DateTime,
    ShowLegend = true,
    LegendPosition = LegendPosition.TopRight
};

// 本周温度
var series1 = new ScatterSeries
{
    Name = "本周温度",
    LegendText = "本周",
    ShowLine = true,
    ShowMarkers = true,
    Smooth = true,
    LineWidth = 2
};

// 添加7天数据
for (int i = -6; i <= 0; i++)
{
    series1.Add(DateTime.Now.AddDays(i).Date, 20 + Math.Sin(i * 0.5) * 5);
}

scatterPlot.AddSeries(series1);
scatterPlot.RefreshPlot();

注意事项

  1. 日期时间数据 :使用 DateTime.ToOADate()DateTime.Ticks 转换为数值存储
  2. 刷新图表 :修改数据后调用 RefreshPlot() 重新绘制
  3. 平滑曲线 :设置 Smooth = true 并可通过 SmoothTension 调整平滑度(0-1之间)
  4. 图例绘制:图例始终在最上层显示,不会被网格线遮挡
  5. 轴标题 :设置 XAxisLabelYAxisLabel 会自动预留空间,避免与轴标签重叠

三、后记

陆续补充完善中,敬请关注,如有需求,有好的建议,请留言(xue5zhijing)

相关推荐
xy34532 天前
Axure 9.0 中继器创建与设置步骤
前端·ui·html·axure·原型·产品设计
大蓝头2 天前
安装包UI美化之路-借助AI快速使用nsNiuniuSkin制作安装包
ui·安装包·nsis·安装包美化·nsniuniuskin
兰亭妙微UI设计公司2 天前
兰亭妙微APP界面设计公司分享: iPhone Duo 登场|3 大核心要点,拆解折叠屏 UI 适配设计思路
ui·交互
智购科技自动售货机工厂3 天前
2026自动售货机端侧AI降本逻辑:从云端API到本地推理的成本重构~YH
人工智能·python·ui·面试·交互
HwJack204 天前
【HarmonyOS开发小实践】ArkUI 应用级状态AppStorage 与跨页面共享、持久化
ui·华为·性能优化·harmonyos
undsky_4 天前
传统色 × 现代和弦:专为 UI/UX 打造的国风配色 Skill
ui·ai·aigc·ai编程·ux
Wang's Blog5 天前
Java框架快速入门: Spring Security+OAuth2之多因子认证与TOTP实战
java·spring·ui
Huanzhi_Lin6 天前
UI业务模块化随笔
ui·mvc·mvp·ecs·ui框架·模块化开发
Quor6 天前
Zorv AI GenUI 技术架构深度解析:从双面设计到安全边界
人工智能·ui·架构