当前位置: 首页 > news >正文

C# 曲线编写总览

目录

  • 前言
  • 一、LiveChart库
    • 1.代码编写
    • 2.其他 - 实时数据
  • 二、OxyPlot库
    • 1.代码编写
    • 2.其他 - 实时数据
  • 三、ScottPlot库
    • 1.代码编写
    • 2.其他 - 实时数据
  • 总结


前言

在项目中曲线是一个常用功能,这篇是整理所用曲线库:livechart库、oxyplot库、scottplot库,如何生成曲线。


一、LiveChart库

1.代码编写

1、xaml方面,代码如下:

//引用livechart库
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"<lvc:CartesianChart Grid.Row="1" DisableAnimations="True"Series="{Binding SeriesCollection}" LegendLocation="Top"><lvc:CartesianChart.DataTooltip><lvc:DefaultTooltip Background="White" FontSize="11" SelectionMode="SharedYValues" /></lvc:CartesianChart.DataTooltip><!--X轴--><lvc:CartesianChart.AxisX><!--MinValue = "0" : 强制从0开始 --><lvc:Axis Title="时间" Foreground="Black" Labels="{Binding Labels}"><lvc:Axis.Separator><lvc:Separator Step="1" StrokeThickness="1" /></lvc:Axis.Separator></lvc:Axis></lvc:CartesianChart.AxisX><!--Y轴--><lvc:CartesianChart.AxisY><lvc:Axis Title="测试值" Foreground="Black" MaxValue="675" MinValue="0"><lvc:Axis.Separator><lvc:Separator Step="100" StrokeThickness="1" /></lvc:Axis.Separator></lvc:Axis></lvc:CartesianChart.AxisY>
</lvc:CartesianChart>

代码分析以及属性扩展:

  • 图表基础属性
    1、Series:绑定图表的数据系列集合(Y轴数据集)
    2、LegendLocation:控制图例位置(如Top、Bottom、Left、Right)
    3、DisableAnimations:禁用图表动画(True/Flase),提升性能 - 动画会消耗计算资源,可能导致卡顿。
    4、zoom:用于配置图表的缩放和拖拽行为,需配合ZoomingMode枚举使用,适用图表数据量较大或局部放大查看细节。
    5、DataTooltip:用于控制鼠标悬停时显示的数据提示框(Tooltip),可以自定义样式、内容、触发方式等。
  • 坐标轴属性(AxisX / AxisY)
    1、Title:坐标轴标题(如“测试值”)。
    2、Labels:绑定X坐标轴标签集合(如{Binding Labels})
    3、MinValue / MaxValue:强制设置坐标轴范围(如 MinValue = “0”),一般常用于X、Y轴 0 点。
    4、Foreground:坐标轴文字颜色
    5、Separator:控制刻度分隔线:Step:刻度间隔(如Step = “100”), StroleThickness:分隔线粗细

2、ViewModel方面,代码如下:

class LiveChartViewModel : ObservableObject
{//属性public SeriesCollection SeriesCollection { get; set; }public List<string> Labels { get; set; }//构造函数public LiveChartViewModel(){// x轴数据集 5个空字符串,对应5个数据点Labels = new List<string> {"", "", "", "", ""}; SeriesCollection = new SeriesCollection{//初始化系列集合new LineSeries{Title = "实时数据",  //系列的名称(会显示在图例中)//需ADD{x,y}//Values = new ChartValues<ObservablePoint>(), //数据点的集合Values = new ChartValues<double>{ 0, 0, 0, 0, 0 },PointGeometrySize = 1   //数据点的大小(像素)}}}
}

功能:数据添加

  • 完整数据添加,代码如下:
//初始化X轴标签
Labels = new List<string> {"Jan", "Feb", "Mar", "Apr", "May"};//初始化系统数据
SeriesCollection = new SeriesCollection
{new LineSeries //折线图系列{Title = "Sales",Values = new ChartValues<double> {50, 120, 300, 250, 400},Stroke = Brushes.Blue,Fill = Brushes.Transparent}
}
  • 动态单个数据添加,代码如下:
Labels.Add(数据);
SeriesCollection[0].Values.Add(数据);

2.其他 - 实时数据

实时数据显示,代码如下:

//实时数据按钮点击事件
public void RealDatesTestCommandExecute()
{Task.Run(() => lineStart());
}/// <summary>
/// 实时数据运行
/// </summary>
public void lineStart()
{Random r = new Random();while (true){Thread.Sleep(1000);double _trend = r.NextDouble() * 500;//通过Dispatcher在工作线程中更新窗体的UI元素Application.Current.Dispatcher.Invoke(() =>{//更新横坐标时间Labels.Add(DateTime.Now.ToString("HH:mm:ss"));Labels.RemoveAt(0);//更新纵坐标数据SeriesCollection[0].Values.Add(_trend);SeriesCollection[0].Values.RemoveAt(0);});}
}

二、OxyPlot库

1.代码编写

1、xaml方面,代码如下:

//引用oxyplot库
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"<oxy:PlotView Grid.Row="1" Model="{Binding PlotModel}" />

2、ViewModel方面,代码如下:

class OxyPlotViewModel : ObservableObject
{private PlotModel plotModel;public PlotModel PlotModel{get { return plotModel; }set { SetProperty(ref plotModel, value); }}//构造函数public OxyPlotViewModel(){CreateCurve();}public void CreateCurve(){PlotModel = new PlotModel();//单曲线var lineSeries = new LineSeries{//数据点不显示形状MarkerType = MarkerType.None // 或者使用 lineSeries.MarkerType = MarkerType.None;};PlotModel.Series.Add(lineSeries);//1:DateTimeAxis(时间轴) LinearAxis(数值轴)var xAxis = new DateTimeAxis{Position = AxisPosition.Bottom,Title = "时间",StringFormat = "HH:mm:ss", //时间显示格式MajorGridlineStyle = LineStyle.Solid,MinorGridlineStyle = LineStyle.Dot};PlotModel.Axes.Add(xAxis);var yAxis = new LinearAxis{Position = AxisPosition.Left,Title = "测试值"};PlotModel.Axes.Add(yAxis);}
} 

功能:数据添加,代码如下:

var temp = PlotModel.Series[0] as LineSeries;temp.Points.Add(new DataPoint(数据1, 数据2));
PlotModel.InvalidatePlot(true); //刷新图表

2.其他 - 实时数据

实时数据显示,代码如下:

//实时数据按钮点击事件
public void RealDatesTestCommandExecute()
{Task.Run(() => LoadCurvesDates());
}/// <summary>
/// 实时加载曲线数据
/// </summary>
public void LoadCurvesDates()
{var temp = PlotModel.Series[0] as LineSeries;Random r = new Random();while (true){Thread.Sleep(1000);double element = r.NextDouble() * 500;DateTime labels = DateTime.Now;//将DateTime转换为OLE Automation日期(double)double timestamp = labels.ToOADate(); temp.Points.Add(new DataPoint(timestamp, element));PlotModel.InvalidatePlot(true); //刷新图表}
}

三、ScottPlot库

1.代码编写

1、xaml方面,代码如下:

//引用ScottPlot库
xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"<wpf:WpfPlot Grid.Row="1" Name="WpfPlot1" />

2、xaml.cs方面,代码如下:

public partial class ScottPlotPage : UserControl
{public ScottPlotPage(){InitializeComponent();WpfPlot1.Plot.Style(ScottPlot.Style.Light1);//初始化图表属性WpfPlot1.Plot.Title("测试曲线");WpfPlot1.Plot.XLabel("时间");WpfPlot1.Plot.YLabel("测试值");WpfPlot1.Plot.Legend(); //显示图例//配置X轴为时间格式WpfPlot1.Plot.XAxis.DateTimeFormat(true); //启用时间格式WpfPlot1.Plot.XAxis.TickLabelFormat("HH:mm:ss", dateTimeFormat: true); //设置显示格式WpfPlot1.Plot.SetAxisLimits(xMin: 0, xMax: 10, yMin: 0, yMax: 600); //初始范围 x:0-10 y: 0-600 }
}

功能:数据添加
基础变量定义,代码如下:

var plt = new ScottPlot.Plot(600, 400);//添加XY坐标数据
double[] xs = {1, 2, 3, 4, 5};
double[] ys = {1, 4, 9, 16, 25};

绘制数据方法
1)AddScatter

  • 功能:绘制离散散点,默认不连接数据点(仅显示标记点)。
  • 特点
    • 适合展示原始数据点,不自动连线。
    • 可通过参数lineStyle设置为非None来连接点。
var scatter = plt.AddScatter(xs, ys);
scatter.LineStyle = LineStyle.Solid; //手动启用连线

2)AddScatterLines

  • 功能:绘制散点+连线,默认连接所有数据点(带标记的折线图)。
  • 特点
    • 是AddScatter的变体,默认启用连线(LineStyle.Solid)。
    • 适合需要同时显示数据点和趋势的场景。
var scatterLines = plt.AddScatterLines(xs, ys, label: "趋势线");

3)AddLine

  • 功能:绘制单一线段(两点之间的直线)。
  • 特点
    • 仅需定义起点和终点(x1, y1, x2, y2), 不处理多数据点。
    • 适合绘制辅助线、参考线或简单线段。
plt.AddLine(0, 0, 10, 5, color: Color.Red, lineWith: 2);

4)AddSignal

  • 功能:绘制均匀采样信号(高性能折线图)。
  • 特点
    • 专为大数据量优化(如音频、传感器数据)。
    • 要求X轴为等间隔递增(自动生成0, 1, 2 … 或通过sampleRate指定间隔)。
    • 渲染速度极快(使用GPU优化),但不支持任意X坐标。
double[] ys = new double[100_000]; // 10万点数据
var signal = plt.AddSignal(ys, sampleRate: 20_000); // 采样率20kHz//添加仅Y值数据(自动生成0,1,2 ...)
double[] values = {5, 3, 7, 4, 6};
plt.AddSignal(values);

方法总结:

方法数据点连接标记显示适用数据量用途
AddScatter可选中小仅需标记点展示
AddScatterLines中小需要标记点 + 连线(带标记的趋势线)
AddLine两点一线-绘制简单线段(参考线、辅助线)
AddSignal超大等间隔信号(如音频、传感器)

2.其他 - 实时数据

实时数据显示,代码如下:

//属性
private double[] xdates = new double[10000]; //x轴 - 数据(时间轴)
private double[] ydates = new double[10000]; //y轴 - 测试值
private int nextIndex = 0; //下一个写入位置
private bool bufferFull = false; //缓冲区是否已填满private DispatcherTimer timer;/// <summary>
/// 按钮点击事件 - 实时数据测试
/// </summary>
public void RealDatesTestCommand(object sender, RoutedEventArgs e)
{// 重置数据缓冲区Array.Clear(xdates, 0, xdates.Length);Array.Clear(ydates, 0, ydates.Length);nextIndex = 0;bufferFull = false;// 重置图表WpfPlot1.Plot.Clear();WpfPlot1.Plot.SetAxisLimits(0, 10, 0, 600);WpfPlot1.Render();// 初始化定时器(如果未初始化)if (timer == null){timer = new DispatcherTimer{Interval = TimeSpan.FromMilliseconds(1000) // 1秒定时器};timer.Tick += (s, e) =>{// 模拟数据double newValue = new Random().NextDouble() * 600;AddDataPoint(newValue);};}// 启动定时器timer.Start();
}// 添加新数据点
public void AddDataPoint(double yValue)
{// 1. 计算当前时间(OADate格式)double currentTime = DateTime.Now.ToOADate();// 2. 写入缓冲区xdates[nextIndex] = currentTime;ydates[nextIndex] = yValue;// 3. 更新索引nextIndex++;if (nextIndex >= xdates.Length){nextIndex = 0;bufferFull = true;}// 4. 更新显示UpdatePlot();
}//更新图表显示
private void UpdatePlot()
{// 获取当前有效的连续数据段double[] xValid, yValid;if (bufferFull){// 缓冲区已满,数据是环形存储的xValid = new double[xdates.Length];yValid = new double[ydates.Length];// 重组数据(旧数据在前,新数据在后)Array.Copy(xdates, nextIndex, xValid, 0, xdates.Length - nextIndex);Array.Copy(ydates, nextIndex, yValid, 0, ydates.Length - nextIndex);Array.Copy(xdates, 0, xValid, xdates.Length - nextIndex, nextIndex);Array.Copy(ydates, 0, yValid, xdates.Length - nextIndex, nextIndex);}else{// 缓冲区未满,直接取前nextIndex个数据xValid = xdates.Take(nextIndex).ToArray();yValid = ydates.Take(nextIndex).ToArray();}// 更新曲线数据var plot = WpfPlot1.Plot.GetPlottables().FirstOrDefault() as ScottPlot.Plottable.ScatterPlot;if (plot != null){plot.Update(xValid, yValid);}else{WpfPlot1.Plot.AddScatterLines(xValid, yValid);}// 更新时间轴范围UpdateTimeAxis();// 刷新图表WpfPlot1.Render();
}//自动调整时间轴范围
private void UpdateTimeAxis()
{if (nextIndex == 0 && !bufferFull) return;double newestTime = bufferFull ?xdates[nextIndex == 0 ? xdates.Length - 1 : nextIndex - 1] :xdates[nextIndex - 1];// 显示最近60秒数据WpfPlot1.Plot.SetAxisLimitsX(newestTime - 60.0 / 86400, newestTime);
}

总结

库类型优点缺点
LiveChart库曲线美观,wpf中曲线数据能使用绑定Binding实时数据量庞大,会卡
OxyPlot库wpf中曲线数据能使用绑定Binding比livechart库实时数据量大点,比scottplot库实时数据量小
ScottPlot库数据量最大wpf中曲线数据不能使用绑定Binding

如果想要界面好看,可使用LiveChart库。如果想要界面好看一点并追求点实时效率,可使用OxyPlot库。如果追求极致实时数据效率,可使用ScottPlot库。

相关文章:

  • (17) 关于工具箱 QToolBox 的一个简单的范例使用,以了解其用法
  • 快速解决Linux 中yum镜像拉取失败问题
  • 从协议壁垒到无缝协同:Profibus转Profinet网关的智造赋能逻辑
  • Oracle基础知识(四)
  • 力扣HOT100之回溯:46. 全排列
  • 大数据治理:理论、实践与未来展望(一)
  • ROS云课三分钟-破壁篇GCompris-一小部分支持Edu应用列表-2025
  • 第一课如何学习课程
  • Dify源码学习
  • csp备考Day1|string和vector
  • 几个MySQL系统调优工具
  • 03-工具篇-SSH远程登录ubuntu系统
  • Kubernetes in action-机理
  • 【Web前端】jQuery入门与基础(一)
  • ISO 26262-5 评估硬件随机失效率
  • Linux—进程池实现
  • C++题解(33)2025年顺德区中小学生程序设计展示活动(初中组C++)U560876 美丽数(一)和 U560878 美丽数(二)题解
  • Python之两个爬虫案例实战(澎湃新闻+网易每日简报):附源码+解释
  • 爬虫核心概念与工作原理详解
  • AI专题:如何把DeepSeek变成你的AI个人助手
  • 浙江省杭州市建设厅网站/优化关键词排名的工具
  • 给网站做路由/餐饮最有效的营销方案
  • 济南网站价格/南京最新消息今天
  • 网页设计方案/廊坊seo排名霸屏
  • 专门做电路图的网站/seo关键词优化外包公司
  • 普通网站建设/万网