diff --git a/README.md b/README.md index 92190f9..e2bed82 100644 --- a/README.md +++ b/README.md @@ -257,29 +257,38 @@ m_dotsProg->release(); - 想要更柔和的圆边:用 `smoothstep` 做 alpha 边缘 + 开启 blending - 想要真正的 3D 圆柱/球:就不能靠 discard 了,需要真正的几何或法线光照 -## Metrics ???? +## Metrics(指标计算) -Metrics ?????????? payload?`DataFrame.data`??????? `metricsChanged` ??? +Metrics 是对**单帧 payload**的统计结果,payload 即 `DataFrame.data`。每次接收新帧或回放 tick, +`DataBackend::emitFrame_()` 会先调用 `updateMetrics_()`,然后发出 `metricsChanged`,QML 端通过 +`Backend.data.metric*` 读取这些值。 -- ?????? -- ????sqrt(mean(v^2)) -- ????mean(v) -- ??????? - ??? +- Peak:`max(v)` +- RMS:`sqrt(mean(v^2))` +- Avg:`mean(v)` +- Delta:`max(v) - min(v)` +- Sum:`sum(v)` -## Live Trend ?? +代码位置:`src/data_backend.cpp`(`updateMetrics_()`) -Live Trend ????? payload ???sum of `DataFrame.data`???????????????? `src/data_backend.cpp` ? `updateMetrics_()` ???? `metricSum`??? `qml/content/RightPanel.qml` ??? `Backend.data.metricSum` ?????? +## Live Trend(Payload Sum) -## Live Trend ?????????? +右侧面板的 **Payload Sum** 折线图来自 `metricSum`:每次 `metricsChanged` 时,如果已有帧数据, +就会执行 `card.plot.append(Backend.data.metricSum)`。 -????????? `QImage` ?????????? DPI?devicePixelRatio??????? DPI ??????????????????????? y ??????????????????????? +- 计算来源:`DataBackend::updateMetrics_()`(`metricSum = sum(DataFrame.data)`) +- 触发位置:`qml/content/RightPanel.qml`(`Connections { onMetricsChanged { ... } }`) +- 绘图组件:`qml/content/LiveTrendCard.qml` + `SparklinePlot`(`LiveTrend` 模块) -????? -- ???????? `devicePixelRatio` ??????? -- ???????????????????? -- ???????? y ???????????????? +## Live Trend 的 HiDPI 对齐(文字清晰度/位置) -????????? +SparklinePlot 的刻度文字通过 `QImage -> QSGTexture` 绘制。为避免高 DPI 下文字发虚或 y 方向偏移, +实现上做了两件事: + +- 按 `devicePixelRatio` 生成缓存 key 与 QImage 像素尺寸 +- `QImage::setDevicePixelRatio(dpr)`,并在布局时按像素网格对齐 + +相关实现: ```cpp // src/sparkline_plotitem.h @@ -320,16 +329,23 @@ QSGNode* SparklinePlotItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeDat } ``` -## Export Logic +## Export Logic(导出流程) -Export is driven by the Save dialog and DataBackend::exportHandler(): +导出由保存对话框驱动,最终落到 `DataBackend::exportHandler()`: -- QML triggers Backend.data.exportHandler(folder, filename, format, method) from qml/content/LeftPanel.qml. -- older is a local QUrl (e.g. ile:///C:/...), converted to a local path on the C++ side. -- Supported formats: csv, json. -- Supported methods: overwrite (default), ppend. - - CSV append: appends all current frames to the file. - - JSON append: loads existing array (if any), appends all current frames, and rewrites the file. -- xlsx and zip are not implemented yet and will log a warning. +- 触发入口:`qml/content/LeftPanel.qml` → `SaveAsExportDialog` → `Backend.data.exportHandler(...)` +- `folder` 为本地 `QUrl`(如 `file:///C:/...`),C++ 端会转换为本地路径 +- `format`:`csv` / `json` / `xlsx`(为空时会根据文件后缀推断) +- `method`:`overwrite`(默认) / `append` / `zip`(UI 有入口但后端未实现压缩) -Relevant code: src/data_backend.cpp (exportHandler, uildCsv_, uildJson_), qml/content/SaveAsExportDialog.qml. +追加行为: + +- CSV append:以追加模式写入 `buildCsv_()` 的内容(无表头) +- JSON append:读取已有数组(如果存在),追加当前帧后整体重写 + +当前限制: + +- `xlsx` 仅提示未实现(不会写出文件) +- `zip` 未实现压缩逻辑(请视为暂不支持) + +相关代码:`src/data_backend.cpp`(`exportHandler` / `buildCsv_` / `buildJson_`),`qml/content/SaveAsExportDialog.qml`