Winform中原生Chart绘制曲线卡顿替代方案(ScottPlot Signal)

winform中遇到需要长时间监控和记录数据曲线时候,我们经常用到chart这个原生控件,但是对于大量的数据显示会造成界面卡顿和无响应。使用ScottPlot Signal则会解决这一问题

1.安装NuGet包

image

2.使用控件FormsPlot

image

3.示例界面

image

 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.运行效果

image

 

posted @ 2026-04-30 15:28  田宏伟_thw  阅读(123)  评论(0)    收藏  举报