c# 从0实现一个温湿度监测的小工具 (8)

语言: CN / TW / HK

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

概述:

这一章节,我们主要实现的功能是为软件增加实时显示曲线。\ winform在4.x版本的时候,还有charts组建,到了5.0时代,没有了原生的charts组件\ 我这边选择第三方曲线包。ScottPlot

安装插件包

比较简单,已经提了很多次了。工具,nuget包管理。搜索scottplot,之后点击安装\ 注意安装的是scottplot.winform

image.png

修改界面,增加曲线显示

在表格下方,增加一个曲线。在工具栏中搜索plot

image.png

如果没有搜索到,可以重新启动一下vs\ 修改完毕的界面如图

image.png

修改代码

增加曲线初始化

具体的曲线配置我们可以参考scottplot的demo,这里我直接给出code\ 本次窗口比较小,因此我禁止了x轴的显示

js /// <summary> /// 初始化曲线 /// </summary> private void InitPlot() { //line formsPlot1.Plot.Style(Style.Seaborn); formsPlot1.Plot.Title("数据曲线"); //不显示x轴 formsPlot1.Plot.XAxis.Ticks(false); formsPlot1.Plot.XAxis.Line(false); formsPlot1.Plot.YAxis2.Line(false); formsPlot1.Plot.XAxis2.Line(false); }

增加曲线刷新

scottplot的刷新目前没有找到合适的办法\ 使用了比较笨的办法,就是先clear然后重新赋值\ 有什么好的办法,欢迎交流

js /// <summary> /// 刷新曲线 /// </summary> private void RefreshLine(DataTable ThisData) { try { if (ThisData.Rows.Count < 1) return; //清空 formsPlot1.Plot.Clear(); //温度 string[] data = ThisData.AsEnumerable().Select(d => d.Field<string>("温度")).ToArray(); double[] ys = Array.ConvertAll<string, double>(data, s => double.Parse(s)); //湿度 string[] data2 = ThisData.AsEnumerable().Select(d => d.Field<string>("湿度")).ToArray(); double[] ys2 = Array.ConvertAll<string, double>(data2, s => double.Parse(s)); formsPlot1.Plot.AddSignal(ys); formsPlot1.Plot.AddSignal(ys2); formsPlot1.Refresh(); } catch (Exception ex) { MessageBox.Show(ex.Message + ex.StackTrace); MyLogger._.Error(ex.Message + "\r\n" + ex.StackTrace); } }

修改load函数,增加曲线初始化

js /// <summary> /// 界面加载函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { MyLogger._.Debug("程序启动"); //扫描串口 string[] comlist = ComPort.V_ScanPort(); if (comlist.Length < 1) { MessageBox.Show("没有扫描到串口,请检查硬件连接"); return; } else { foreach (string name in comlist) { this.comboBox1.Items.Add(name); } //默认 this.comboBox1.Text = comlist[0]; } //波特率初始化 this.comboBox2.Items.Add("4800"); this.comboBox2.Items.Add("9600"); this.comboBox2.Items.Add("115200"); //默认 this.comboBox2.Text = "9600"; //默认地址 this.textBox1.Text = "01"; //默认背景色 this.button1.BackColor = Color.LightGreen; //初始化数据 InitDataTable(); InitDataGrid(); InitPlot(); }

修改定时器函数,增加曲线实时刷新

js /// <summary> /// 定时器回调 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timer1_Tick(object sender, EventArgs e) { if (Runport.IsOpen) { //获取地址 byte addr = byte.Parse(this.textBox1.Text); string ret = THSensor.ReadTHDataFromSensor(Runport, addr); if (!string.IsNullOrEmpty(ret)) { string temp = ret.Split('&')[0]; string humi = ret.Split('&')[1]; //入库操作 DB_SerAPI.SaveTHData(temp, humi); //刷新列表 string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); if (DataBuffer != null) { Index++; DataRow row = DataBuffer.NewRow(); row["ID"] = Index.ToString(); row["时间"] = time; row["温度"] = temp; row["湿度"] = humi; DataBuffer.Rows.Add(row); } //刷新曲线 RefreshLine(DataBuffer); } else { MessageBox.Show("无数据,请检查配置参数"); } } }

测试

image.png

到目前为止,我们做的功能都是基于一个固定不变的小窗口驱完成。\ 后续,我们为了给工具增加历史数据查询,报警设置等基本的功能。需要对界面进行重新的布局和设计。\ 下一节,我们将主要修改布局,是窗体可以自适应分辨率。