docs: /source 数据可视化设计文档
全屋污染柱状图(各房间5污染物占GB50325限值%) + 材料贡献饼图 (红→冷按占比配色),纯 SVG/CSS 手写,不引图表库。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ab76f8172a
commit
9cc2071bdf
|
|
@ -0,0 +1,113 @@
|
||||||
|
# 设计文档:/source 污染源识别页 数据可视化
|
||||||
|
|
||||||
|
- 日期:2026-07-07
|
||||||
|
- 目标项目:`C:\code\空气质量预测\源码\用户端\iapip-web`(纯前端,不涉及后端/数据库)
|
||||||
|
- 页面:`src/pages/source/index.tsx`(污染源识别 / 预测页)
|
||||||
|
- 状态:已通过需求评审,待写实现计划
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 背景与目标
|
||||||
|
|
||||||
|
`/source` 现状:左侧单房间输入(预设样板间 + 面积/层高/温湿度/换气 + 材料勾选),右侧结果为「5 项污染物浓度表」+「公式溯源·各材料贡献」(横向 CSS 条) +「整改建议」。预测走 `api.predict.space`(免认证),返回 `Space`:每污染物 `*_c` 浓度、`*_c_exceed` 超标、`materials[].*_cr` 贡献率、`is_*_ps` 污染源。当前**只预测选中的一个房间**。
|
||||||
|
|
||||||
|
本次新增两个可视化:
|
||||||
|
|
||||||
|
1. **全屋污染柱状图**:一套住宅各房间、5 种污染物浓度**占 GB50325 限值的百分比**,每房间 5 根柱。
|
||||||
|
2. **材料贡献饼图**:某污染物下各材料贡献率用饼图 + 百分比展示,配色按占比从高到低 红→橙→黄→青→蓝(越低越淡越冷),替换现有横条。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 技术选择:纯 SVG/CSS 手写图表(不引图表库)
|
||||||
|
|
||||||
|
项目无任何图表库。决定**手写 SVG/CSS**,不安装 `@ant-design/plots` 等:
|
||||||
|
- npmmirror 装包在本环境不稳定,避免引入构建风险。
|
||||||
|
- 需要精确的配色(饼图按排名的红→冷渐变)与百分比柱,手写完全可控。
|
||||||
|
- 页面现有贡献率即 CSS 条,风格一致。
|
||||||
|
|
||||||
|
实现时先加载 `dataviz` 技能校准配色的可访问性与一致性。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 图 1:全屋污染柱状图(新增)
|
||||||
|
|
||||||
|
### 3.1 数据
|
||||||
|
- 页面加载时,对 `PRESET_ROOMS`(当前 4 个:标准间/主卧/客厅/儿童房,组件按 N 个通用)**各跑一次** `api.predict.space`,并发执行,单个失败则跳过该房间。
|
||||||
|
- **固定使用 GB50325 限值**(`standards` 中 id 含 `GB50325` 的那条),不受页面上方「限值标准」选择器影响。
|
||||||
|
- 每房间每污染物计算:`pct = c / c_lmt * 100`(`c_lmt` 为 0 或缺失则该柱记为无数据、不绘制)。
|
||||||
|
|
||||||
|
### 3.2 展示(分组柱状图)
|
||||||
|
- x 轴按**房间**分组,每组 **5 根柱**(甲醛/TVOC/苯/甲苯/二甲苯,顺序同 `POLLUTANTS`)。4 房间 = 20 柱;房间多时按容器宽度**自动换行**成多行(每行若干房间组)。
|
||||||
|
- 柱高 = `min(pct, CAP) / CAP`,`CAP = 150`(%)。柱顶标注实际百分比数值。
|
||||||
|
- 画一条 **100% 虚线基准线**。
|
||||||
|
- 柱**按污染物着色**(5 色分类调色板,图例:颜色 → 污染物);`pct >= 100`(超标)的柱额外加**红色描边 + 红色数值**以突出。
|
||||||
|
- 组下方标注房间名。
|
||||||
|
- 无任何房间预测成功时,整个图区显示占位文案「暂无全屋数据」,不报错。
|
||||||
|
|
||||||
|
### 3.3 位置
|
||||||
|
- 作为一张新 card,放在右侧结果 `stack` 的**最顶部**(在「识别结论」表之上),标题「全屋污染概览 · 各房间占 GB50325 限值百分比」。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 图 2:材料贡献饼图(替换现有横条)
|
||||||
|
|
||||||
|
### 4.1 数据
|
||||||
|
- 复用现有 `pol`(污染物切换)与 `ranked`(当前选中房间、该污染物下 `*_cr>0` 的材料,按贡献率降序,含 `isSrc`)。
|
||||||
|
- 饼图各扇区占比 = 该材料贡献率归一化(`ranked` 的 rate 之和作分母;后端 `cr` 之和可能略小于 1,用其和归一以保证扇区闭合到 360°)。
|
||||||
|
|
||||||
|
### 4.2 展示
|
||||||
|
- SVG 饼图(各扇区用 `path` 弧或 `stroke-dasharray` 圆环),右侧/下方**百分比图例**:色块 + 材料名 + `(cr*100).toFixed(1)%`,污染源材料标注「(污染源)」。
|
||||||
|
- **配色(按 `ranked` 排名从高到低,越低越淡越冷)**,起始调色板(实现时经 dataviz 校准):
|
||||||
|
1. 红 `#C0392B` 2. 橙 `#E67E22` 3. 黄 `#F1C40F` 4. 青 `#16A085` 5. 蓝 `#2980B9` 6. 浅蓝 `#5DADE2` 7+. 冷灰 `#AEB6BF`
|
||||||
|
超出 7 项时后续用更浅的冷灰循环递减。
|
||||||
|
- `ranked` 为空(该污染物无材料释放)时显示「该污染物无材料释放」占位(沿用现有文案)。
|
||||||
|
|
||||||
|
### 4.3 位置
|
||||||
|
- 替换「公式溯源·各材料贡献」card 内的横条 `contrib` 区,保留该 card 标题与污染物切换 `pol-seg`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 组件拆分
|
||||||
|
|
||||||
|
- `src/pages/source/RoomBarChart.tsx` — 输入 `{ rooms: { name: string; pct: (number|null)[] }[], pollutantLabels: string[], colors: string[] }`,渲染分组柱状图(含 100% 线、换行、超标高亮)。纯展示,无数据请求。
|
||||||
|
- `src/pages/source/ContribPie.tsx` — 输入 `{ items: { name: string; rate: number; isSrc: boolean }[] }`,渲染饼图 + 图例(内部按序取配色)。纯展示。
|
||||||
|
- `src/pages/source/index.tsx` — 新增「加载时并发预测全屋」逻辑与状态 `homeStats`,组织两个子组件;替换 `contrib` 区为 `<ContribPie>`。
|
||||||
|
- `src/pages/source/source.css` — 新增柱状图/饼图相关样式类。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 数据流与错误处理
|
||||||
|
|
||||||
|
- 全屋预测:`Promise.allSettled` 并发 4 次 `api.predict.space`(各房间的 `buildPayload` 用其预设面积/材料/温湿度 + GB50325 限值);仅保留 fulfilled 的房间。
|
||||||
|
- GB50325 标准若在 `standards` 中不存在:柱状图整体显示占位、不报错(其余页面功能不受影响)。
|
||||||
|
- 饼图:贡献率和为 0 时显示占位。
|
||||||
|
- 全程无新增网络失败提示(沿用页面「静默」策略)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 测试
|
||||||
|
|
||||||
|
- **类型检查**:`npx tsc --noEmit -p tsconfig.json` 新增文件零错误(仅剩既有 2 条 eslint 类型根告警)。
|
||||||
|
- **浏览器**(登录后 `#/source`):
|
||||||
|
- 顶部出现「全屋污染概览」柱状图:4 房间 × 5 柱,柱顶百分比、100% 基准线;某柱超 100% 时标红。
|
||||||
|
- 「各材料贡献」显示为饼图 + 百分比图例;切换污染物(甲醛/TVOC/…)饼图与配色随之更新;占比最高扇区为红、依次转橙黄青蓝、越低越淡冷。
|
||||||
|
- 编辑单房间输入不影响顶部全屋概览(概览为加载时的预设快照)。
|
||||||
|
- 控制台无报错;GB50325 缺失或某房间预测失败时页面不崩。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 涉及文件清单
|
||||||
|
|
||||||
|
- 新建:`src/pages/source/RoomBarChart.tsx`
|
||||||
|
- 新建:`src/pages/source/ContribPie.tsx`
|
||||||
|
- 修改:`src/pages/source/index.tsx`(全屋并发预测 + 组织图表 + 替换 contrib)
|
||||||
|
- 修改:`src/pages/source/source.css`(图表样式)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 范围与非目标
|
||||||
|
|
||||||
|
- 不改后端、不改预测算法、不改数据库。
|
||||||
|
- 全屋柱状图为**加载时的预设快照**,不随单房间编辑实时联动(YAGNI;如需联动为后续增强)。
|
||||||
|
- 不引入任何图表/绘图第三方库。
|
||||||
|
- 柱状图固定 GB50325;单房间结果表仍用页面选择的标准(保持现有行为)。
|
||||||
Loading…
Reference in New Issue