Oxyplot实时绘图学习笔记(上)

(本项目来源于嵌入式系统实践课程项目)

目标

作为嵌入式系统的考核项目之一,我们小组选择项目是“基于串行通信的智能传感器和数据采集”,我们拟开发的项目是“基于智能传感器的户外健身环境及体征监测系统”。
本人负责的其中一个模块是对于workstation收集到的多个传感器数据,在图形界面上采用实时绘图的形式显示出来,达成“实时监控”的效果。经过收集资料以及综合平台(WPF)考虑,我最后选择的是使用C#中的Oxyplot绘图工具作为实时图表的实现工具。

需求

  1. 在同一窗口内显示多个实时数据图表 ,形式类似于Win10的任务管理器
  2. 对于每一个图表,以曲线图的形式实时反应数值变化
  3. 调整绘图设置以符合每个传感器数值的变化水平 ,对于简要监视部分,重点在于坐标轴的设置,可以直观看出当前数值;对于重点监视部分,可以容纳更多的数据,并且曲线和绘图区域参照线要足够醒目
  4. 为“模拟”,“切换监视”等功能的实现设计代码控制

同时绘制多个实时曲线图

因为是第一次接触C#编程,大作业时间也很紧,所以我选择了对现成的项目的代码进行修改,缩短开发时间。什么叫Ctrlc-Ctrlv速成C#啊(后仰
(初始源码来源:https://blog.csdn.net/weixin_42930928/article/details/89143908)
(截图来自最后完成的工程项目,源码链接:https://gitee.com/soheavyrain/group_11_homework)

方式选择

原项目使用了两种不同的方式来绘制实时曲线图:

第一种方式,布局文件相对简单,大量代码都需要在ViewModel类中进行处理
第二种方式,布局文件相对复杂,但是在ViewModel类中的代码量相对较少
原项目作者的两种方式示意图

我选择的是第二种方式,不想把太多代码放到当时看不懂的Xaml文件里,这种方式将图表的属性在类内直接定义完整,在布局文件中只需要引用相应的model即可。

同时显示多个实时图表

首先去掉了第一个方案创建的图表相关的代码,然后在类内新建了多个新的PlotModel对象,对应要同时显示的多个数据图表。
在这里插入图片描述
(图片为“温度”对象的相关设置,其中还包括坐标轴等的配置,下一篇再说)
然后需要在布局文件中为图表设置位置和大小等属性,这里小小修改了一下上一位同学的设计的布局文件,然后在留白的相应位置使用PlotView和binding将图表展示出来。
在这里插入图片描述

布局文件中图表的数据来源(?

原项目中有一个“ViewModelLocator.cs”文件,这个文件的代码实现的功能是让布局文件中只需要使用关键词,就可以使图表绑定在MainViewModel类内的名字相同的对应对象上(原理暂且不明),但是用起来相当方便。
在这里插入图片描述在这里插入图片描述
(这两段代码分别来自ViewModelLocator.cs和布局文件)

重点监视窗口的数据来源设置

在重点监控窗口中,图表的数据来源并不是固定来自某个传感器,而是随着用户的选择而改变监视的对象,所以需要对于数据来源进行相关的设置。
才疏学浅,我只能想到两个方式:

1.在布局文件中让重点监视窗口的图表控件随着用户的选择而改变绑定的对象
然而,布局文件中并不能同时出现多个PlotView绑定在同一个对象上的情况。
我随后搜索了对象克隆等方式,但是由于ViewModelLocator的存在,绘图的控件对象都被定义在同一个类内,并且这些绘图控件的类由Oxyplot已经设置好了,并没有设计“复制相同的绘图控件”这种功能。
随后尝试使用序列化,逆序列化的方式强行克隆对象,但是似乎由于对象设置过于复杂,无法进行序列化。
(序列化方法来源:https://www.cnblogs.com/DebugLZQ/archive/2013/05/06/3062409.html)
2.创建并一个新的对象,随着用户的选择改变,这个对象改变绘图画点的数据来源
没办法,我只能尝试这种方法,在用户切换观测对象的时候,还需要将之前的数据清空,才能接受新的数据,否则会导致前后不同数据来源的数据差距过大,对绘图产生影响。
对于该控件数据来源的选择,我使用了上一个同学定义的含有全局变量的Common类(如何定义全局变量:https://blog.csdn.net/weixin_40486955/article/details/96559596)
这样可以实现简单粗暴的按按钮→修改全局变量→监测变量值的改变→清空图表数据→根据新的全局变量的值调整数据来源。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总之,因为不太理解ViewModelLocator的工作原理(期末时间真得太紧了),虽然代码写的比较奇形怪状,但是好在经过调试后是可以正常运行的,效果还不错。