# 星程桑基图(`todo.md`)详细实现方案 ## 1. 目标与范围 ### 1.1 项目目标 - 构建一个可在 `Web` 与 `微信小程序` 使用的桑基图制作工具。 - 支持用户上传 `Excel/CSV`,通过列映射配置自动生成桑基图节点与连线。 - 支持图表配置(方向、配色、间距)与导出(`PNG`、`SVG`)。 - 提供标准模板文件,降低数据准备成本。 ### 1.2 本期范围(MVP) - 文件上传与解析(`xlsx/csv`)。 - 列选择映射(`source data`、`source description`、`target description`)。 - 基于“合并单元格语义”的 target 聚合计算(按 target 描述聚合 source 数值)。 - 桑基图渲染与基础交互(缩放/悬浮提示)。 - 导出 `PNG/SVG`。 - 基础配置项:方向、配色、节点间距(gap/padding)。 ### 1.3 暂不纳入本期 - 用户账号、云端存储、多人协作。 - 历史版本管理与回滚。 - 大屏动画编排、复杂主题系统。 ## 2. 技术与工程方案 ### 2.1 技术选型 - Web:`Vue 3 + TypeScript + Vite`。 - 图表:`ECharts Sankey`(Web 直接渲染;小程序可复用 ECharts 小程序适配方案)。 - 数据解析: - `csv`:轻量解析器(如 `papaparse`)或自研分隔处理(优先可维护方案)。 - `xlsx`:`SheetJS (xlsx)`(仅用于读取,不引入重型扩展能力)。 - 导出: - `SVG`:图表实例导出或序列化容器 SVG。 - `PNG`:基于 `canvas`/图表导出接口生成并下载。 ### 2.2 架构分层(Web 与小程序共用核心) - `core/`(可复用纯函数层) - 文件解析适配(CSV/XLSX -> 统一二维表结构)。 - 列映射与数据清洗。 - 节点/边构建算法(Sankey 输入结构)。 - 校验与错误码。 - `web/`(Vue 页面) - 上传、映射配置、预览表格、图表渲染、导出。 - `miniapp/`(后续) - 复用 `core` 算法,仅替换 UI/上传/导出实现。 ## 3. 数据模型与规则定义 ### 3.1 输入数据统一模型 - `RawTable` - `headers: string[]` - `rows: string[][]` - 列索引统一使用 `0-based`,UI 展示使用“列名 + 1-based 序号”。 ### 3.2 用户映射配置模型 - `sourceDataColumn: number`(必填,数值列) - `sourceDescriptionColumns: number[]`(可空,空则回退为 `sourceDataColumn`) - `targetDescriptionColumns: number[]`(必填) - `delimiter: string`(默认 `-`) ### 3.3 业务规则(来自 `todo.md`) - `source`: - `value` 取 `sourceDataColumn`。 - `name` 由 `sourceDescriptionColumns` 拼接;若未配置则使用 `sourceDataColumn` 文本。 - `target`: - `name` 由 `targetDescriptionColumns` 拼接。 - 多行若 target 名称一致,视为“合并单元格语义”,其 `value` 为对应 source 数值求和。 - 空值处理: - 参与拼接时忽略空串,但保留字段顺序。 - `source value` 非法(空/非数值)时记录错误并默认跳过该行。 ### 3.4 输出结构(供桑基图渲染) - `nodes: Array<{ name: string; kind: "source" | "target" }>` - `links: Array<{ source: string; target: string; value: number }>` - `meta: { droppedRows: number; warnings: string[] }` ## 4. 核心算法设计 ### 4.1 处理流程 1. 读取文件 -> 统一 `RawTable`。 2. 基于映射配置遍历每一行,构造 `sourceName/sourceValue/targetName`。 3. 使用 `Map` 以键 `sourceName@@targetName` 累加 `value`。 4. 从聚合结果提取 `nodes/links`,去重节点。 5. 输出告警信息(非法值、空 target、全空行等)。 ### 4.2 关键细节 - 数值解析支持千分位、空格清理(如 `"12,000"` -> `12000`)。 - 统一字符串 `trim`,避免同名节点因空格被拆分。 - 当方向切换为 `target -> source` 时,仅交换链接方向,不改原始聚合逻辑。 ## 5. 页面与交互方案(Web) ### 5.1 页面结构 - `上传区`:拖拽/点击上传,显示文件名与解析状态。 - `列映射区`: - 选择 `source data`(单选)。 - 选择 `source description`(多选,可空)。 - 选择 `target description`(多选,必填)。 - 实时生成示例文本(如:`宁波北欧10-2582 -> 嘉兴四级算力池-11623-小模型`)。 - `图表区`:桑基图预览。 - `配置区`:方向、配色方案、节点间距(gap/padding)。 - `导出区`:下载 `PNG`、`SVG`、模板文件。 ### 5.2 交互约束 - 未完成必填映射前禁用“生成图表”。 - 显示解析异常明细(行号 + 错误原因)。 - 切换配置时图表实时刷新,不重新解析文件。 ## 6. 导出与模板方案 ### 6.1 导出 - `SVG`:优先使用图表库原生导出能力,确保矢量质量。 - `PNG`:支持倍率参数(默认 `2x`)以保证清晰度。 - 文件命名:`sankey_YYYYMMDD_HHmmss.png|svg`。 ### 6.2 模板 - 提供 `csv` 与 `xlsx` 两份模板,含示例数据与列说明。 - 模板首行固定列名,便于自动映射建议。 ## 7. 小程序落地策略 ### 7.1 复用策略 - `core` 代码以纯 TypeScript 编写,不依赖 DOM。 - 小程序端复用 `core`,仅替换: - 文件读取适配层。 - 图表组件容器。 - 导出能力(若受限,首期可仅支持图片保存)。 ### 7.2 分阶段接入 - 第一期先完成 Web 全流程。 - 第二期迁移至小程序并补齐端差异。 ## 8. 测试与质量保障 ### 8.1 单元测试(核心) - 文件解析: - CSV 基础解析、空值、引号、逗号场景。 - XLSX 读取与表头提取。 - 业务聚合: - target 合并语义正确性。 - source/target 描述回退逻辑。 - 非法数值行过滤。 - 输出结构: - 节点去重、连线值聚合。 ### 8.2 组件与集成测试 - 上传 -> 映射 -> 生成图 -> 导出全链路。 - 配置项修改触发图表更新。 - 错误提示可见性与可读性。 ### 8.3 质量门禁 - `lint`、`type-check`、`test` 全通过后合并。 - 对关键样例建立快照(链接与节点数量、总流量)。 ## 9. 里程碑与任务拆分 ### M1:项目骨架与核心解析(2 天) - 初始化 Vue3 + TS 工程结构。 - 完成 `core`:CSV/XLSX 解析、列映射模型、聚合算法。 - 输出可直接喂给 Sankey 的 `nodes/links`。 ### M2:Web MVP 页面与图表(2 天) - 完成上传区、映射区、图表区。 - 接入 Sankey 渲染与方向/间距配置。 - 增加错误提示与示例预览。 ### M3:导出与模板(1 天) - 实现 PNG/SVG 导出。 - 增加模板下载入口与示例文件。 ### M4:测试完善与发布准备(1 天) - 补齐单元测试与集成测试。 - 完成 lint/type-check/test,修复问题。 - 输出使用说明文档(含列映射示例)。 ## 10. 风险与应对 - 风险:Excel“合并单元格”在导出为值时存在空白行语义差异。 - 应对:按“target 描述拼接结果为空则跳过”的规则兜底,并提示行号。 - 风险:大文件渲染性能下降。 - 应对:解析与聚合在 Worker(后续)或分段处理;图表数据量阈值预警。 - 风险:小程序导出能力受限。 - 应对:先保障 Web 全能力;小程序阶段提供可替代导出链路。 ## 11. 验收标准(Definition of Done) - 能上传并解析 `csv/xlsx`。 - 能按映射生成正确桑基图(含示例中的聚合语义)。 - 可切换方向、配色、间距并实时预览。 - 可导出 `PNG` 与 `SVG`。 - 提供模板下载。 - 核心测试通过,且 lint/type-check/test 全绿。