mhpn.cn mhpn.cn

Article

从零搭建灌装监控系统(十七):LiveCharts 实时温度曲线

TEMPLATE PREVIEW · 文章页模板示意 · 正文由后台文章数据自动填充 · 配图自动生成
特种作业理论考场全景示意图
LiveCharts 实时温度曲线这是「从零搭建灌装监控系统」系列第17篇。数字只能告诉你此刻的温度曲线才能告诉你温度在往哪走。这篇用 LiveCharts 画实时温度重点不是“怎么画出来”而是怎么在几百毫秒一次的刷新下不卡、不崩、不无限膨胀。曲线跑到第二天就卡住了首页加温度曲线的时候我的实现非常朴素每次收到数据就往ChartValues里Add一个点。刚开始特别顺。跑了一上午曲线像心电图一样漂亮。第二天早上同事说软件卡了——切页面要等两秒拖动窗口一顿一顿。原因很直白数据点只增不减。200ms 一次采样一小时就是 18000 个点一天 43 万个点。LiveCharts 每个点都要参与布局和重绘几万个点之后每次刷新都在做无用功——因为屏幕上根本显示不下那么多点。还有一个更隐蔽的问题有时候刚启动就崩异常信息指向图表但代码看起来完全正常。这两个问题的解法就是这篇的全部内容。为什么选 LiveChartsWPF 上画实时曲线有几个选择我选 LiveCharts 0.9.7 的原因纯 WPF 原生控件不依赖浏览器或 OpenGL 上下文SeriesCollectionChartValues的数据模型跟 MVVM 合得来支持虚线、点样式、图例这些工业界面常用的细节包体积小部署到现场不需要额外运行时代价是它的老版本0.9.x对线程比较敏感这点后面专门讲。两条曲线实际值 vs 设定值温度只看一条线是不够的。操作员真正关心的是实际值和设定值的偏差所以画两条TempLiveChartsnewSeriesCollection{newLineSeries{Title实际温度,ValuesnewChartValuesdouble(),StrokeBrushes.Cyan,StrokeThickness2,PointGeometrynull,},newLineSeries{Title设定温度,ValuesnewChartValuesdouble(),StrokeBrushes.Orange,StrokeThickness2,PointGeometrynull,StrokeDashArraynewDoubleCollection{4,2},}};三个刻意的选择实际值实线、设定值虚线。StrokeDashArray {4, 2}是 4 像素实线加 2 像素空。两条线颜色不同还不够色觉差异或者屏幕反光时颜色容易混线型不同才能一眼分开。而且设定值本来就该是“参考线”的语义虚线正好。PointGeometry null。默认每个数据点会画一个小圆点。几百个点就是几百个图形对象纯属浪费——曲线本身已经把趋势表达清楚了。关掉之后渲染量明显下降。两条线用同一个 Y 轴。实际值和设定值量纲相同共用纵轴才能直观看出偏差。如果量纲不同比如温度和压力才需要拆双轴。滚动窗口只保留最近 40 点解决无限膨胀的核心是让集合长度恒定privatevoidUpdateChart(DeviceStatesstate){if(TempLiveChartsnull||TempLiveCharts.Count0)return;TempLiveCharts[0].Values.Add(state.CurrentTemp);if(TempLiveCharts[0].Values.Count40)TempLiveCharts[0].Values.RemoveAt(0);if(TempLiveCharts.Count1){TempLiveCharts[1].Values.Add(state.SettingTemp);if(TempLiveCharts[1].Values.Count40)TempLiveCharts[1].Values.RemoveAt(0);}}加一个到尾部超长就从头部删一个。集合长度永远是 40内存和渲染开销都恒定。为什么是 40按 200ms 采样算40 个点大约覆盖 8 秒。这个窗口要跟工艺节奏匹配窗口太短曲线抖动剧烈看不出趋势窗口太长温度变化的细节被压缩报警前的爬升看不出来8 秒对灌装加热这种慢过程偏短实际项目可以放宽到 100-200 点。文章里用 40 是为了讲清机制具体数值要按工艺周期调。原则是窗口时长应该能覆盖一次完整的状态变化。流程如下是否轮询收到数据Dispatcher 切回 UI 线程实际值集合 Add点数超过 40?移除头部一个点保持设定值同样处理图表自动重绘必须在 UI 线程创建这是那个“刚启动就崩”的根因。SeriesCollection、LineSeries、ChartValues都是 WPF 的DependencyObject体系里的对象有线程亲和性。如果在非 UI 线程创建之后 UI 线程去渲染它就会抛异常——而且异常点往往在渲染阶段堆栈指向 LiveCharts 内部看起来跟你的代码无关。所以创建过程要用 Dispatcher 包起来publicDashBoardViewModel(){PlcService.DataReceivedOnDataReceived;Application.Current.Dispatcher.BeginInvoke((){TempLiveChartsnewSeriesCollection{// ... 两条 LineSeries};});}用BeginInvoke而不是Invoke构造过程不需要等图表建完异步投递到 UI 队列就行不会阻塞当前线程。同样的道理后续每次改Values也要在 UI 线程。DataReceived是从轮询线程发出的所以更新前必须切线程privatevoidOnDataReceived(object?sender,DeviceStatesstate){Application.Current.Dispatcher.Invoke((){CurrentTempstate.CurrentTemp;SettingTempstate.SettingTemp;UpdateChart(state);});}Invoke同步在这里是合适的因为更新图表和更新卡片数值要在一个批次里完成避免界面出现“数字已经是新值、曲线还是旧点”的错位。不要每帧重建集合我见过一种写法每次收到数据就TempLiveCharts new SeriesCollection {...}把整个集合换掉。看起来“数据总是最新的”实际上每次都在重建图形对象、重新绑定、重新布局。数据一快GC 压力和渲染压力一起上来。正确做法是建一次之后只改Values。ChartValues实现了集合变更通知增删元素会自动触发增量重绘这才是 LiveCharts 的设计意图。断线时把曲线也清掉第 16 篇讲过断线要清零曲线同样适用privatevoidOnConnectionChanged(object?sender,boolconnected){if(!connected){Application.Current.Dispatcher.Invoke((){CurrentTemp0;SettingTemp0;TempLiveCharts[0].Values.Clear();TempLiveCharts[1].Values.Clear();});}}保留断线前的曲线会让操作员误判——曲线停在 25.5℃看起来像“温度稳定”其实是没数据了。清空之后图表是空的配合报警提示语义才正确。踩坑记录后台线程直接改 ChartValues崩在渲染阶段堆栈在 LiveCharts 内部看不出跟自己的代码有关。所有图表对象操作都要切 UI 线程。数据点只增不减跑几小时就卡跑一天基本不能看。用滚动窗口把集合长度固定住。每次刷新重建 SeriesCollection数据越快越卡而且图表会闪。建一次之后只改Values。实际值和设定值不做区分两条同色实线叠在一起操作员分不清哪条是哪条。颜色 线型双区分。本篇小结问题做法集合无限膨胀滚动窗口超长移除头部渲染开销大PointGeometry null只画线不画点两条线分不清实际值实线、设定值虚线后台线程崩溃创建和更新都在 UI 线程频繁重建集合建一次之后只改Values断线误判清空曲线不保留旧数据图表让趋势可见了但界面上还有一堆重复的视觉元素每个页面都要一个红绿圆点、一个状态标签、一个液位指示。复制粘贴到最后改一次配色要翻十几个文件。下一篇把这些做成可复用的自定义控件。下期预告第18篇自定义控件三色灯与状态指示下一篇把三色灯和状态指示器做成独立的UserControl用依赖属性和值转换器驱动顺便讲一个 WPF 里非常容易踩的坑本地值为什么会让触发器失效。

看完文章还有疑问?直接问顾问

三门峡、驻马店特种作业考证问题:报名条件、考试批次、材料整理、证书复审,电话或邮箱都能找到我们,当天回复,企业团报另对接 HR 专人。

预约咨询 18236992212

Keep Reading

继续阅读相关资讯

考试公告、政策解读、行业动态持续更新,考证路上保持关注不踩坑;看完本文想动手报名的,往下看服务流程。

服务窗口递交复审与报考资料

How We Help

看懂文章之后,报名这样走不绕路,材料不返工

三门峡、驻马店两地学员,从咨询到拿证复审的完整路径,四步走完。每一步该准备什么、容易卡在哪,顾问会提前讲清楚,不用自己摸索,也不用被网上各种说法绕晕,更不用怕遇到"免考拿证"的骗子。

1

条件自查

年龄、学历、体检三项硬性条件先过一遍,不符合的讲清楚补救办法,避免材料做了一半才发现报不上名。

2

材料预审

身份证、学历证明、体检报告、照片提前把关,规格不对一次说清,缺项一次补齐,报名窗口一开就能提交。

3

赶批次报名 + 考前辅导

同步河南应急管理厅考试批次,开报即报不拖堂;理论按题库结构梳理重点,实操陪练走一遍考核流程。

4

考后跟踪

成绩查询、证书领取方式、复审到期提醒都记在台账里,企业团报的客户,台账对接到 HR 统一管理。

Renewal Reminder

证书快到期?别等失效才想起来,提前三个月排期

特种作业操作证按周期复审,过期未复审不能继续上岗。把发证日期告诉我们,到期前三个月主动提醒,材料、培训、考试一次性排好,三门峡、驻马店均可办理;企业客户可批量核对在岗人员证书有效期,检查前一次盘清。

查看复审办理流程
特种作业报考与复审材料整理

Next Step

文章看完了,下一步按您的状态选,别一步跨太大

还没报名的、材料在准备的、证书快到期的,对应动作不一样,按自己的阶段对号入座,不用全看一遍。

还没报名:先查条件

年龄、学历、体检三项硬条件先过一遍,再看批次窗口。条件卡住别硬报,先电话问补救办法,确定能报再准备材料,方向感更清楚。

查最近考试批次

材料在准备:先做预审

身份证、学历证明、体检报告、照片规格逐项核对,缺项一次补齐,别等到报名窗口开了才发现材料不对,白白错过这一批。

了解材料预审

证书快到期:提前复审

复审要走培训与考核流程,提前三个月安排最稳妥。把发证日期告诉我们,到期前主动提醒,不用自己记着日子。

复审办理流程

Local Service

三门峡、驻马店,两地都能办,企业个人各有通道

个人学员按批次走,企业客户按排期走,两条流程互不干扰。

三门峡方向

湖滨、陕州、灵宝、渑池、卢氏学员常见诉求是配合项目工期拿证:按最近批次排材料,考前辅导集中安排,理论与实操都有人盯进度,不用自己追着问。

驻马店方向

驿城、平舆、汝南、西平方向工厂与物业岗位占比高,低压电工咨询最多;企业团报可按车间统一建档,复审节点统一提醒,HR 不用逐个追。

企业客户

资质检查、项目备案要核对持证台账。团报通道统一排期、统一培训、档案归口,到期复审批量通知,检查前心里有底。

FAQ

报考前经常被问到的几个问题,一次写清楚

收费、材料、团报门槛——电话里回答过无数遍的问题,这里一次写清楚,不用您再重复问,也不用翻聊天记录找答案,看完就有底。

咨询收费吗?

不收费。报名条件、工种方向、批次窗口这些问题,电话里直接讲清楚,您听完再决定要不要跟着走流程,没有"必须报班"这一说。

材料不齐能先报上名吗?

不建议。报名审核对材料规格卡得严,缺项或照片不合规都会被打回,反而耽误批次。先做材料预审,补齐了再提交更稳妥,窗口开了当天就能报上名。

企业团报最低多少人起?

没有硬性门槛,三五人的班组也能按团报流程走,只是人数越多排期效率越高、档案管理越省事。三门峡、驻马店企业可先电话报人数、说清工期节点谈细节。

这篇文章没解决的问题,电话里说清楚,方案当场给

报名条件、考试批次、材料清单、复审周期——咨询免费,方案当场给。企业团报可统一排期、档案归口,合同与发票流程当面讲清,不用线上扯皮。

咨询电话 18236992212 · 809451989@qq.com · 三门峡 / 驻马店两地均可办理
预约咨询