ZedGraph 绘制动态曲线

news2024/11/19 22:46:21

文章目录

      • 前言:
      • 开发环境:
      • 1 下载ZedGraph 控件并设置图形界面
      • 2 功能实现
      • 3 需求升级
      • 4 小结

话不多数,先上一个效果图:

在这里插入图片描述

前言:

需要采集一些设备的数据以图表的形式展示出来,研究数据的走向是否平稳,波动范围等。

开发环境:

IDEA: VS2019 社区版本
框架: .NET Framework 4
绘图控件:ZedGraph

1 下载ZedGraph 控件并设置图形界面

1 使用 VS自带的NuGet包管理器下载安装ZedGraph控件。在“工具”->“NuGet包管理器”->“管理解决方案的Nuget程序包”, 搜索ZedGraph并下载即可。

在这里插入图片描述
在这里插入图片描述

打开下载好的ZedGraph所在文件夹,将其拖拽到工具箱,此时就会发现工具箱多了一个ZedGraph,这样就可以像其它控件一样使用了。建立一个Winform窗口,将ZedGraph放上去,如图
在这里插入图片描述

2 功能实现

这里使用随机数据来模拟设备的数据,使用定时器Timer更新曲线。直接上代码,有注释比较容易看得懂。

2.1 先添加对ZedGraph的引用

using ZedGraph;

2.2 具体功能

  public partial class TrendChart : Form
    {
        //定时器刷新曲线
        Timer ChartTimer;

        //时间
        int time = 30;

        //记录曲线值
        PointPairList vlist = new PointPairList();

        public TrendChart()
        {
            InitializeComponent();
            //初始化ZedGraph
            InitZedGraph();

            ChartTimer = new Timer()
            {
                Interval = 300,
            };
            ChartTimer.Tick += ChartTimer_Tick;
            ChartTimer.Start();
        }

     

        #region 初始化图表控件
        private void InitZedGraph()
        {
            GraphPane myPane = myZedgraph.GraphPane;
            myPane.IsAlignGrids = true;
            myPane.Title.Text = "测试速度";
            myPane.XAxis.Title.Text = "时间";
            myPane.YAxis.Title.Text = "速度";


            for (int i = 0; i < 30; i++)
            {
                double time = (double)i;
                double acceleration = 2.0;
                double velocity = acceleration * time;
                vlist.Add(time, velocity);
            }

            //生成一条红色的菱形样式曲线,将曲线和值vlist绑定
            //生成速度图例
            LineItem myCurve = myPane.AddCurve("速度", vlist, Color.Red, SymbolType.Diamond);
            //填充白色
            myCurve.Symbol.Fill = new Fill(Color.White);  


            //显示X的网格线
            myPane.XAxis.MajorGrid.IsVisible = true;

            //设置Y轴刻度为红色
            myPane.YAxis.Scale.FontSpec.FontColor = Color.Red;
            myPane.YAxis.Title.FontSpec.FontColor = Color.Red;

            //隐藏Y轴对面的刻度显示
            myPane.YAxis.MajorTic.IsOpposite = false;
            myPane.YAxis.MinorTic.IsOpposite = false;

            // 不显示Y轴的0刻度线
            myPane.YAxis.MajorGrid.IsZeroLine = false;
            myPane.YAxis.MajorGrid.IsVisible = true;
            myPane.YAxis.MajorGrid.Color = Color.Red;
          
            //设置刻度范围
            myPane.YAxis.Scale.Align = AlignP.Inside;
            myPane.YAxis.Scale.Max = 100;
            myPane.YAxis.Scale.MaxAuto = true;
           

            //设置chart的背景颜色
            myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f);
            
            //刷新轴
            myZedgraph.AxisChange();
        }
        #endregion


        /// <summary>
        /// 刷新曲线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ChartTimer_Tick(object sender, EventArgs e)
        {
            //随机数据模拟
            Random random = new Random();
            double v = random.Next(30, 60);

            //添加新的数据
            vlist.Add(time, v);
            time += 2;

            //曲线刷新
            myZedgraph.AxisChange();
            myZedgraph.Refresh();
            
        }
    }

2.3 效果图如下:
运行的时候可以看到全部采集的数据都绘制在曲线上了,随着时间的越长,显示的点就越密集。
在这里插入图片描述

3 需求升级

客户不想看到这么多数据,只想看到最新的前三十条数据怎么做呢?
方法1 判断数据是否超过30,大于30之后每添加新的数据就把最前面的一个数据移除掉
方法2 不需要移除数据,更新X轴的范围,让其只绘制前面30个数据。这个方法需要知道30个数据X轴的具体值是多少。

方法1:修改定时器刷新函数ChartTimer_Tick(object sender, EventArgs e)

       private void ChartTimer_Tick(object sender, EventArgs e)
        {
            //随机数据模拟
            Random random = new Random();
            double v = random.Next(30, 60);

            //添加新的数据
            vlist.Add(time, v);
            time += 2;

            #region 方法1
            if (vlist.Count > 30)
            {// 保留最新的30个数据
                vlist.RemoveAt(0);
            }
            #endregion

            //曲线刷新
            myZedgraph.AxisChange();
            myZedgraph.Refresh();
        }

效果图:可以看到数据量一直保持在30个,前面的数据会被移除掉。
在这里插入图片描述

方法2:

 private void ChartTimer_Tick(object sender, EventArgs e)
        {
            //随机数据模拟
            Random random = new Random();
            double v = random.Next(30, 60);

            //添加新的数据
            vlist.Add(time, v);
            //每个点的时间间隔
            time += 2;

            #region 方法1
            //if (vlist.Count > 30)
            //{// 保留最新的30个数据
            //    vlist.RemoveAt(0);
            //}
            #endregion

            #region 方法2
            if(vlist.Count >= 30)
            {//更新X轴的显示范围

                myZedgraph.GraphPane.XAxis.Scale.Max = time;
                //每个点的时间间隔
                myZedgraph.GraphPane.XAxis.Scale.Min = time - (30 * 2);
            }
            #endregion


            //曲线刷新
            myZedgraph.AxisChange();
            myZedgraph.Refresh();
        }

效果图:这个效果就看着比较连续,没有太多空旷的地方
在这里插入图片描述

4 小结

1 绘制动态示波器的主要是 更新实时数据,将新的数据点添加到绑定曲线的数据类型上,记得刷新曲线。这个可以使用定时器或线程来实现。

2 对于曲线上点的显示范围可以有两种方式。一个是使用固定点数,超过固定点就移除旧的数据。另外一个是调整X轴的显示范围,仅显示最近一段时间的数据。

3 固定点数:好处:很方便简易实现,绘制速度快,消耗内存小。弊端:不能保存全部数据
调整X轴范围:好处:能存储全部数据,可以整体分析。弊端:占用内存大

以上便是简单的曲线绘制了,使用何种方式绘图可以根据自己的实际需求出发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/444594.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mac Homebrew方式安装 activemq

两种方式安装 activemq 一、通过Homebrew管理安装 1. 确保homebrew可用 查看brew版本 brew -v 如果报错&#xff0c;则可能是未启用brew&#xff0c;需要安装或更新 更新并重新查看是否安装成功 brew update brew -v 2. 安装 activemq&#xff1a;下载activemq前 会先下载相…

Direct3D 12——纹理——寻址模式

可将经过常数插值或线性插值的纹理定义为一个返回向量值的函数T&#xff08;u, v&#xff09; &#xff08;r,g,b,a&#xff09;&#xff0c;即给 定纹理坐标&#xff08;u,v&#xff09;∈[0,1]^2,则上述纹理函数T将返回颜色&#xff08;r,g, b, a&#xff09;。 Direct3D允许…

MLCC周期性分析:当前时点处于周期反转前夜

MLCC是电子工业大米&#xff0c;供需波动导致行业成周期性波动 MLCC是最常用的被动元器件之一&#xff0c;终端下游涵盖消费电子、家电、汽车、通信等。在5g、汽车电子、智能硬件的推动下&#xff0c;MLCC行业需求稳步增长。供给端来看&#xff0c;中国大陆厂商合计市场份额不…

MFC加载动态gif图片文件C++语言,基于MFC的动画播放控件

MFC加载动态gif图片&#xff0c;使用VS2015环境 一、将下载的PictureEx.h和PictureEx.cpp放在工程文件的目录下&#xff0c;动态gif图片放在工程文件的res文件夹下&#xff1b;&#xff08;GIF动图下载 https://icons8.com/preloaders/en/search/move&#xff09; &#xff08…

企业级VUE前端项目各目录文件的作用

概述 本文项目是基于Vue CLI3构建工具&#xff08;基于 webpack)生成的脚手架项目。Vue CLI 现已处于维护模式&#xff0c;VUE官方推荐使用 create-vue&#xff08;基于 Vite&#xff09;构建工具。 vue-cli2.0与3.0在目录结构方面&#xff0c;有明显的不同,vue-cli3.0移除了…

Linux性能优化实战

1. TCP/IP报文详解 TCP/IP 定义了电子设备如何连入因特网&#xff0c;以及数据如何在它们之间传输的标准。协议采用了4层的层级结构&#xff0c;每一层都呼叫它的下一层所提供的协议来完成自己的需求。TCP负责发现传输的问题&#xff0c;一有问题就发出信号&#xff0c;要求重…

根据cadence设计图学习硬件知识day04了解一些芯片

1.PI3PCIE3212 &#xff08;双向信道多路复用器/多路分解器开关&#xff09; PI3PCIE3212是PCIe Gen3.0、8Gbps、4对2差分&#xff0c;PCI ExpressR 3.0性能&#xff0c;8.0Gbps 双向信道多路复用器/多路分解器开关。由于其低的位对位偏斜&#xff0c;高的通道对通道噪声隔离…

邂逅Node.js开发

目录&#xff1a; 1 Node.js是什么&#xff1f; 2 Node的应用场景 3 Node安装和管理 4 JavaScript代码执行 5 Node的输入和输出 6 Node的全局对象 node命令是可以直接运行js脚本的,在某文件夹底下只要有js文件&#xff0c;就可以通过命令提示符运行该js文件。格式是 &…

简单聊聊煤炭行业的数字化和可持续发展

煤在普通人的心目中是一种能引起复杂感情的东西。我们喜欢它在冬天给我们带来温暖&#xff0c;我们不喜欢它因为它黢黑黢黑的&#xff0c;沾在身上特别黑&#xff0c;看起来脏兮兮的。在笔者的记忆中&#xff0c;小时候煤可是生活的必需品。 小时候在冬天的河北必须要生炉子&a…

电源常识-纹波-EMI

1、纹波﹔纹波就是一个直流电压中的交流成分。直流电压本来应该是一个固定的值&#xff0c;但是很多时候它是通过交流电压整流、滤波后得来的&#xff0c;如图1,由于滤波不彻底&#xff0c;就会有剩余的交流成分&#xff0c;即使采用电池供电也会因负载的波动而产生波纹。事实上…

FreeRTOS 任务相关 API 函数

FreeRTOS 中用于创建和删除任务的 API 函数如下表所示&#xff1a; 1. 函数 xTaskCreate() 此函数用于使用动态的方式创建任务&#xff0c;任务的任务控制块以及任务的栈空间所需的内存&#xff0c; 均由 FreeRTOS 从 FreeRTOS 管理的堆中分配&#xff0c;若使用此函数&#x…

聚焦慕思欧洲设计中心,用设计谱写健康睡眠新篇章

4月20日&#xff0c;在意大利米兰&#xff0c;多位欧洲顶尖设计师齐聚ADI博物馆&#xff0c;共同见证“梦享之美”——慕思欧洲设计中心暨设计国际梦之队成立发布会的盛大召开。慕思此次发布会特地选定在米兰国际家具展期间&#xff0c;而这是公认的世界三大家具展之一&#xf…

DF竞赛平台携手嬴彻科技与清华大学智能产业研究院,助力自动驾驶挑战赛圆满落幕!

由DataFountain竞赛平台&#xff08;简称DF平台&#xff09;提供办赛支持的「首届“嬴彻-清华AIR杯”自动驾驶挑战赛&#xff1a;决策规划算法」已圆满落幕。作为一场前沿性自动驾驶类比赛&#xff0c;本次大赛立足“高速道路”和“城市道路”两大真实场景&#xff0c;选择“半…

SEO文章批量生成

SEO文章生成器 想必大部分人对于 SEO 这个词不会陌生&#xff0c;它是指一系列的优化策略&#xff0c;目的是让网站能够在搜索引擎上更容易地被检索&#xff0c;并获得更多的流量和曝光度。但是&#xff0c;SEO 的优化并非易事&#xff0c;尤其对于那些没有相关技术知识和经验…

科技云报到:存储开源,风雨飘摇下“披着羊皮的狼”?

科技云报道原创。 这些年开源界的风风雨雨&#xff0c;时不时撼动着人们的内心。 2022年&#xff0c;俄乌冲突导致全球最大的独立开源软件公司SUSE、美国开源软件巨头Redhat、主流开源容器引擎Docker&#xff0c;纷纷宣布停止与俄罗斯的合作。 而全球最大的开源及私有代码项目…

react-8 Redux 状态管理 - 持久化存储 => 进阶:React-Redux()和模块化

1.redux redux是独立于react的库&#xff0c;是js状态管理库&#xff0c;提供可预测的状态管理。Vue也可用&#xff0c;但是和react比较搭配 。 2. 什么时候用 redux? 解决&#xff1a;任意&#xff1a;多组件共享状态&#xff0c; 解决&#xff1a;任意&#xff1a;两个…

83.qt qml-初步学习2D粒子影响器(二)

由于QmlBook in chinese翻译过来的文字有些比较生疏难于理解,所以本章在它的基础上做些个人理解,建议学习的小伙伴最好配合QmlBook in chinese一起学习。 QML粒子所有类型: Qt Quick Particles QML Types | Qt Quick 6.5.0 Affector类型: Attractor QML Type | Qt Quick 6.5.…

TouchGFX界面开发 | TouchGFX软件安装

TouchGFX软件安装 TouchGFX和STemWin类似&#xff0c;都是一个GUI框架&#xff0c;可以方便的在STM32 Cortex-M4 以及更高级别的STM32芯片上创建GUI应用程序。 本文中的TouchGFX软件安装&#xff0c;是基于已经安装有STM32CubeMX Keil MDK-ARM开发环境的情况下进行的&#x…

CSS3 2D变换

CSS3 2D变换 位移&#xff1a; div {transform: translateX(30px); /*水平位移*/transform: translateY(30px); /*垂直位移*/transform: translate(30px, 30px); /*两个方向位移*/ }注意&#xff1a;位移的百分比是元素本身&#xff0c;不是父元素 div {transform:…

JVM常用调优参数 ——JVM篇

JVM常用性能调优参数详解 ​ 在学习完整个JVM内容后&#xff0c;其实目标不仅是学习了解整个JVM的基础知识&#xff0c;而是为了进行JVM性能调优做准备&#xff0c;所以以下的内容就是来说说JVM性能调优的知识。 一、性能调优 ​ 性能调优包含多个层次&#xff0c;比如&…