166 lines
6.3 KiB
Markdown
166 lines
6.3 KiB
Markdown
# 数据中心 · 历史记录 · 曲线趋势图改造方案
|
||
|
||
## 1. 背景与问题
|
||
|
||
### 1.1 业务场景
|
||
|
||
路径:**数据中心 → 历史记录**([`history.vue`](../src/views/dataCenter/history.vue))。
|
||
|
||
页面含三个 Tab:**设备**、**网关设备**、**场景**,各自有「曲线趋势图」或网关下的计算量 / 多设备对比 / 单子设备折线图。
|
||
|
||
### 1.2 原始痛点
|
||
|
||
| 问题 | 说明 |
|
||
|------|------|
|
||
| 多曲线「压成直线」 | 多物模型量级差异大(如位移 168、角度 3、电压 12),共用单 Y 轴时范围被拉大,小幅波动在图上不可见。 |
|
||
| 多 Y 轴布局异常 | 为每条曲线建隐藏 Y 轴时,ECharts 会为多轴计算偏移,曲线一多时绘图区被挤到一侧。 |
|
||
| 图例占用空间 | 网关多设备对比图例项极多,默认换行占满高度,挤压 grid。 |
|
||
| X 轴可读性 | 时间点密集时标签重叠。 |
|
||
| 垂直空间不足 | 固定 480px 高度时,几十条归一化曲线仍显拥挤。 |
|
||
|
||
---
|
||
|
||
## 2. 总体思路
|
||
|
||
1. **独立 Y 轴模式**:不再使用「每 series 一个 Y 轴」,改为 **按每条曲线自身 min-max 归一化到 [-100, 100]**,**共用一条数值 Y 轴**,避免多轴布局副作用;**Tooltip 始终展示原始值**。
|
||
2. **共享 Y 轴模式**:保留原逻辑,单 Y 轴 + `scale: true`,便于对比绝对量级。
|
||
3. **归一化坐标展示**:独立模式下 Y 轴可见,刻度约 -100%~100%,并附说明性网格线。
|
||
4. **网关图**:图例与 grid 与设备 Tab 对齐策略;X 轴旋转 + 对齐刻度;必要时配合底部留白与 dataZoom。
|
||
5. **动态高度**:按 **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: 100`
|
||
- `axisLine` / `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: 30`
|
||
- `dataZoom`: `inside` + 滑块,便于时间范围缩放
|
||
- `toolbox`: 数据视图、还原、保存图片(与设备 Tab 能力对齐)
|
||
|
||
### 4.6 动态图表高度
|
||
|
||
**数据字段**(像素):
|
||
|
||
- `devChartHeight`, `gwCalcChartHeight`, `gwSingleChartHeight`, `subCompareChartHeight`, `sceneChartHeight`(默认 480)
|
||
|
||
**方法**:`calcChartHeight(seriesCount)`
|
||
|
||
```text
|
||
height = clamp(480, seriesCount * 14 + 360, 1200)
|
||
```
|
||
|
||
即:最少 480px,随曲线数量增加,**最多 1200px**。
|
||
|
||
**模板**:各图表容器使用 `:style="{ height: xxxChartHeight + 'px', ... }"`。
|
||
|
||
**绘制流程**:
|
||
|
||
1. 先算好 `series` 与 `series.length`,赋值对应 `xxxChartHeight`
|
||
2. `this.$nextTick(() => { init/clear → setOption → chart.resize() })`
|
||
保证先根据新高度更新 DOM,再初始化/重绘 ECharts。
|
||
|
||
---
|
||
|
||
## 5. 数据流(简图)
|
||
|
||
```mermaid
|
||
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. 使用说明(给产品/测试)
|
||
|
||
1. **独立 Y 轴(推荐多曲线看趋势)**:纵轴为各曲线**自身量程内的相对位置**(-100%~100%),对比不同物理量时看形状;**真实数值以 Tooltip 与下方表格为准**。
|
||
2. **共享 Y 轴**:纵轴为**真实数值**,适合量级接近、需比大小的变量;量级差很大时仍可能出现「看起来像直线」。
|
||
3. **曲线很多时**:图会自动变高(上限约 1200px),页面可纵向滚动查看全图。
|
||
|
||
---
|
||
|
||
## 7. 相关文件
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| [`yack-web/src/views/dataCenter/history.vue`](../src/views/dataCenter/history.vue) | 全部图表逻辑、开关、高度、归一化 |
|
||
| [`yack-web/src/api/data/center.js`](../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、动态高度)。*
|