6.3 KiB
6.3 KiB
数据中心 · 历史记录 · 曲线趋势图改造方案
1. 背景与问题
1.1 业务场景
路径:数据中心 → 历史记录(history.vue)。
页面含三个 Tab:设备、网关设备、场景,各自有「曲线趋势图」或网关下的计算量 / 多设备对比 / 单子设备折线图。
1.2 原始痛点
| 问题 | 说明 |
|---|---|
| 多曲线「压成直线」 | 多物模型量级差异大(如位移 168、角度 3、电压 12),共用单 Y 轴时范围被拉大,小幅波动在图上不可见。 |
| 多 Y 轴布局异常 | 为每条曲线建隐藏 Y 轴时,ECharts 会为多轴计算偏移,曲线一多时绘图区被挤到一侧。 |
| 图例占用空间 | 网关多设备对比图例项极多,默认换行占满高度,挤压 grid。 |
| X 轴可读性 | 时间点密集时标签重叠。 |
| 垂直空间不足 | 固定 480px 高度时,几十条归一化曲线仍显拥挤。 |
2. 总体思路
- 独立 Y 轴模式:不再使用「每 series 一个 Y 轴」,改为 按每条曲线自身 min-max 归一化到 [-100, 100],共用一条数值 Y 轴,避免多轴布局副作用;Tooltip 始终展示原始值。
- 共享 Y 轴模式:保留原逻辑,单 Y 轴 +
scale: true,便于对比绝对量级。 - 归一化坐标展示:独立模式下 Y 轴可见,刻度约 -100%~100%,并附说明性网格线。
- 网关图:图例与 grid 与设备 Tab 对齐策略;X 轴旋转 + 对齐刻度;必要时配合底部留白与 dataZoom。
- 动态高度:按 series 数量 增加图表容器高度(有上下限),并在 DOM 更新后
resize。
3. 功能开关
- 数据字段:
independentYAxis(默认true)。 - UI:设备 / 网关 / 场景三个图表卡片头部 「独立Y轴 | 共享Y轴」 开关。
- 切换行为:
handleYAxisModeChange在$nextTick内按当前 Tab 与已有数据调用对应draw*Line,无需重新请求接口。
4. 核心实现
4.1 归一化(独立模式)
方法:applyIndependentScale(series)
- 对每条
series.data中可解析为数字的点,取该 series 全体有效点的min、max。 - 映射公式:
value = ((num - min) / (max - min)) * 200 - 100,落在 [-100, 100]。 - 常量序列(
max === min):映射为 0(中间水平线)。 - 每个数据点存为
{ value, _original },_original为归一化前的原始值(兼容负数与非数字展示)。
返回的 Y 轴配置(单轴):
min: -100,max: 100axisLine/axisTick显示axisLabel.formatter: 显示为xx%(表示相对本曲线量程的位置,非物理单位)splitLine:虚线网格,便于读趋势
4.2 Tooltip
方法:independentScaleTooltip()
trigger: 'axis'formatter:时间轴标签 + 各 series 原始值(从p.data._original读取)
4.3 共享模式
yAxis:{ type: 'value', scale: true }tooltip:{ trigger: 'axis' }(默认)
4.4 涉及的绘图方法
| 方法 | Tab / 场景 |
|---|---|
drawDevLine |
设备 |
drawGwCalcLine |
网关 · 计算量 |
drawGwSingleLine |
网关 · 单子设备 |
drawSubCompareLine |
网关 · 多设备同一变量对比 |
drawSceneLine |
场景 |
以上方法在 independentYAxis === true 时均走 applyIndependentScale + independentScaleTooltip。
4.5 网关图布局要点
legend:align: 'right',left: '3%',top: '3%'(与多行图例协调)grid.top: '30%',为图例留出区域,避免与曲线重叠xAxis:boundaryGap: true,axisTick.alignWithLabel: true,axisLabel.rotate: 30dataZoom:inside+ 滑块,便于时间范围缩放toolbox: 数据视图、还原、保存图片(与设备 Tab 能力对齐)
4.6 动态图表高度
数据字段(像素):
devChartHeight,gwCalcChartHeight,gwSingleChartHeight,subCompareChartHeight,sceneChartHeight(默认 480)
方法:calcChartHeight(seriesCount)
height = clamp(480, seriesCount * 14 + 360, 1200)
即:最少 480px,随曲线数量增加,最多 1200px。
模板:各图表容器使用 :style="{ height: xxxChartHeight + 'px', ... }"。
绘制流程:
- 先算好
series与series.length,赋值对应xxxChartHeight this.$nextTick(() => { init/clear → setOption → chart.resize() })
保证先根据新高度更新 DOM,再初始化/重绘 ECharts。
5. 数据流(简图)
flowchart LR
subgraph input [数据]
API[历史接口]
end
subgraph mode [模式]
IND[独立Y轴]
SHR[共享Y轴]
end
subgraph render [渲染]
NORM[逐条 min-max 到 -100~100]
ONEAXIS[单 Y 轴]
TT[Tooltip 原始值]
end
API --> IND
API --> SHR
IND --> NORM --> ONEAXIS
ONEAXIS --> TT
SHR --> ONEAXIS
6. 使用说明(给产品/测试)
- 独立 Y 轴(推荐多曲线看趋势):纵轴为各曲线自身量程内的相对位置(-100%~100%),对比不同物理量时看形状;真实数值以 Tooltip 与下方表格为准。
- 共享 Y 轴:纵轴为真实数值,适合量级接近、需比大小的变量;量级差很大时仍可能出现「看起来像直线」。
- 曲线很多时:图会自动变高(上限约 1200px),页面可纵向滚动查看全图。
7. 相关文件
| 文件 | 说明 |
|---|---|
yack-web/src/views/dataCenter/history.vue |
全部图表逻辑、开关、高度、归一化 |
yack-web/src/api/data/center.js |
历史数据接口(未因本方案变更协议) |
8. 版本与维护建议
- 若需调整「多高算够」,改
calcChartHeight中的系数14、基础360、上下限480/1200即可。 - 若产品要求 Y 轴显示「归一化」文案而非
%,可在applyIndependentScale返回的axisLabel中改为固定文案或name/nameLocation。 - 新增同类折线图时,复用:
applyIndependentScale/independentScaleTooltip/calcChartHeight+$nextTick+resize模式。
文档对应实现:历史记录页曲线趋势图(多 Tab、独立/共享 Y 轴、归一化 -100~100、动态高度)。