Winform中原生Chart绘制曲线卡顿替代方案(ScottPlot Signal)
winform中遇到需要长时间监控和记录数据曲线时候,我们经常用到chart这个原生控件,但是对于大量的数据显示会造成界面卡顿和无响应。使用ScottPlot Signal则会解决这一问题
1.安装NuGet包

2.使用控件FormsPlot

3.示例界面

4.示例代码
namespace ScottPlotSignalTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //我这里创建了三条曲线,需要几条曲线就创建几个Signal对象 private Signal sig1, sig2, sig3; //总的缓存区长度--曲线1数据,根据实际情况调整 double[] a = new double[1000000]; double[] b = new double[1000000]; double[] c = new double[1000000]; //记录当前最新数据位置 private int _currentIndex = 0; /// <summary> /// 主要是初始化操作 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { sig1 = formsPlot1.Plot.Add.Signal(a);//初始化操作,要将设置好的缓存区加载到绘图区域,只需要初始化一次就行了 sig2 = formsPlot1.Plot.Add.Signal(b);//初始化操作,要将设置好的缓存区加载到绘图区域,只需要初始化一次就行了 sig3 = formsPlot1.Plot.Add.Signal(c);//初始化操作,要将设置好的缓存区加载到绘图区域,只需要初始化一次就行了 //设置曲线的颜色和粗细 sig1.LineColor=Color.FromColor(System.Drawing.Color.SkyBlue); sig1.LineWidth=3; sig2.LineColor=Color.FromColor(System.Drawing.Color.Red); sig2.LineWidth=3; sig3.LineColor=Color.FromColor(System.Drawing.Color.LightGreen); sig3.LineWidth=3; //这行代码是用来设置Y轴的显示区域的,不设置的话Y轴的间隔会很小,可根据最终的数据范围进行设置 formsPlot1.Plot.Axes.SetLimitsY(0, 100); // 设置鼠标滚轮事件处理,因为自带的滚轮缩放功能会将X轴和Y轴同时缩放,但是我这里主要需要看曲线的走势,只需要缩放X轴就行了 formsPlot1.MouseWheel += FormsPlot1_MouseWheel; formsPlot1.Refresh(); } /// <summary> /// 鼠标滚轮缩放触发事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormsPlot1_MouseWheel(object sender, MouseEventArgs e) { // 获取当前的轴范围 var limits = formsPlot1.Plot.Axes.GetLimits(); // 计算缩放因子(滚轮向上为缩小,向下为放大) double zoomFactor = e.Delta > 0 ? 0.9 : 1.1; // 计算新的X轴范围 double xCenter = (limits.Left + limits.Right) / 2; double xSpan = (limits.Right - limits.Left) * zoomFactor; // 设置新的X轴范围,Y轴保持不变 formsPlot1.Plot.Axes.SetLimitsX( xCenter - xSpan / 2, xCenter + xSpan / 2 ); // 保持Y轴固定 formsPlot1.Plot.Axes.SetLimitsY(0, 100); formsPlot1.Refresh(); } /// <summary> /// 按钮开始 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Random rnd = new Random(); Task.Run(() => { while (_currentIndex < 999999) { a[_currentIndex] = rnd.Next(0,20); b[_currentIndex] = rnd.Next(30,50); c[_currentIndex] = rnd.Next(60,80); formsPlot1.Invoke(new Action(() => { sig1.MaxRenderIndex = _currentIndex; sig2.MaxRenderIndex = _currentIndex; sig3.MaxRenderIndex = _currentIndex; formsPlot1.Refresh(); })); _currentIndex++; Thread.Sleep(1); } }); } } }
5.运行效果


浙公网安备 33010602011771号