返回系列

Web Console:Monitor、Lab、ECharts 和记录回看的前端边界

解释 RespiraScope 前端为什么采用统一 Console + 多个静态页面,Monitor 如何消费实时数据,Lab 如何服务模拟和滤波调参。

背景问题

RespiraScope 的前端要服务两类人:使用者需要 Monitor 看实时波形、BPM、稳定性和记录片段;开发者需要 Lab 调模拟信号、滤波参数和异常场景。如果把所有内容塞进一个巨大 JS 文件,维护会很困难;如果拆成多个独立站点,启动和访问又会复杂。

当前方案是统一 Web Console:frontend-console 是入口,里面用 tab 切换 Monitor、Lab、Guide 和 API Docs。

设计方案对比

方案优点问题项目判断
单个巨型页面启动简单代码膨胀,职责混乱不利于维护
多个独立前端服务页面边界清楚多端口、多入口、用户容易迷路不适合演示工具
Console + tab/iframe一个入口,页面可独立维护需要语言同步和运行时配置注入当前采用
React/Vue SPA工程能力强构建链路和打包复杂度更高当前静态页面足够

项目选择静态页面,是因为前端的核心任务是展示和控制,不需要复杂状态管理框架。ECharts 和原生模块化 JS 已经能支撑当前规模。

当前方案

frontend-console/app.js 负责读取 window.CT_BREATH_RUNTIME_CONFIG,判断哪些 tab 可用,并把语言选择通过 postMessage 发送给 iframe。Monitor 和 Lab 各自维护自己的业务逻辑。

Monitor 被拆成几个模块:

模块职责
app.js全局状态、DOM、语言、模块组装
modules/socket.js启动接收、连接 Socket.IO、消费实时消息
modules/chart.jsECharts 实时图和记录图
modules/record.js记录、scan、保存、加载和离线复算
modules/status.js接收状态、无数据提示和统计信息
RespiraScope 异常信号监测界面

为什么这样选

Monitor 的前端状态必须同时包含实时数据和记录数据。实时数据保存在 state.raw、state.filtered、state.peaks、state.valleys;记录过程中还要把进入 capture 范围的点追加到 state.activeRecord。这就是为什么前端也有记录逻辑:它需要及时显示用户交互反馈,即使后端接口短暂失败,也能维持本地记录体验。

ECharts 的选择是工程效率。实时波形需要缩放、散点 marker、markArea 区间、dataZoom 和大量点绘制。手写 canvas 可以更轻,但交互和坐标轴成本高;ECharts 对这些场景支持成熟。

Console Shell tab / language / runtime Monitor Lab Guide / API Socket Module Chart Module Record Module

Lab 的价值

Lab 不是一个附属页面。它让开发者在不启动真实设备的情况下选择模拟场景、调整 BPM、幅度、噪声、不规则度,再调用 /mock/preview 和 /applyFilter 查看结果。这个流程把参数调试从后端日志里搬到了可视化界面。

Lab 也承担教学价值。用户能直观看到不同场景下 raw、filtered、peak、valley 的变化,从而理解为什么 gaussian_sigma、peak_threshold_ratio 和 auto_peak_detection 会影响结果。

代价和边界

静态前端没有完整构建系统,所以复用和类型检查比 React/Vue 项目弱。项目通过模块拆分和清晰的 moduleContext 控制复杂度,但如果未来 UI 功能继续膨胀,迁移到框架会更合适。

前端本地记录逻辑和后端记录逻辑存在一定重复。这是为了 UI 及时反馈和容错,但也要求双方字段保持兼容。record.js 中大量 normalize 函数就是为了兼容后端返回和本地保存文件。

关键函数表

函数或模块作用设计点
resolveBackendHost()根据页面 host 修正后端地址支持局域网访问时不写死 localhost
createSocketModule()连接 Socket.IO 并消费消息raw 到达后标记数据已收到
chartOption()生成 ECharts 配置同时支持实时和回看模式
recordMarkArea()绘制 record 和 scan 区间让记录范围在波形上可见
createRecordModule()管理记录状态和文件兼容后端 record 和本地导出
previewAndFilter()Lab 生成预览并离线滤波参数调试闭环
postMessage 语言同步Console 到 iframe多页面保持语言一致

读源码建议

先读 frontend-console/app.js,理解统一入口如何加载各页面。再读 frontend-monitor/app.js 的 moduleContext,看模块如何共享状态。随后读 modules/socket.js 和 modules/chart.js,就能看到实时消息如何变成图表。最后读 frontend-lab/app.js,理解模拟和滤波预览如何串起来。