diff --git a/APP_FLOW.md b/APP_FLOW.md new file mode 100644 index 0000000..1f0f36e --- /dev/null +++ b/APP_FLOW.md @@ -0,0 +1,141 @@ +# APP_FLOW.md + +## 1. Scope +This file defines every user-visible flow for the current product scope. +Primary web route is `/` (single-page app). Miniapp flow is skeleton-only. + +Related docs: +- PRD.md +- FRONTEND_GUIDELINES.md +- BACKEND_STRUCTURE.md + +## 2. Screen List and Route Map +- `Web /` : Main Sankey workspace (header + mapping panels + chart preview). +- `Miniapp /pages/index/index` : Layout skeleton only (not full feature parity). + +## 3. Web Flow: Initial Page Load +Trigger: +- User opens `/`. + +Steps: +1. Render header, mapping panels, and chart container. +2. Initialize ECharts instance. +3. Try loading `/data/example0.xlsx`. +4. Parse file and set default column mapping. +5. Build Sankey data and render preview. + +Decision points: +- If sample file request fails, show parse error text and keep page interactive. + +Success result: +- User sees a chart without manual upload. + +Error result: +- User sees a clear message and can still upload a file manually. + +## 4. Web Flow: File Upload (Click) +Trigger: +- User clicks upload icon and selects a local file. + +Steps: +1. Validate extension (`csv/xls/xlsx`). +2. Parse file to `RawTable`. +3. Reset default mapping by column count. +4. Rebuild Sankey data via reactive effect. +5. Update upload message with filename and row count. + +Decision points: +- Unsupported file type. +- Parse failure (CSV parser/XLSX parser errors). + +Success result: +- Mapping list updates to current headers and preview updates. + +Error result: +- Error message appears; previous valid state remains usable. + +## 5. Web Flow: File Upload (Drag and Drop) +Trigger: +- User drops one file into upload area. + +Steps: +1. Read first file from drop payload. +2. Reuse the same pipeline as click upload. + +Decision points: +- No file in payload. + +Success and error behaviors: +- Same as click upload. + +## 6. Web Flow: Mapping Configuration +Trigger: +- User changes any mapping item in the left panels. + +Steps: +1. Select one source data column (radio). +2. Toggle source description columns (checkbox list). +3. Toggle target description columns (checkbox list). +4. Optional: toggle target total label display. +5. Reactive builder recomputes links and warnings. + +Decision points: +- Missing source data column -> block build with message. +- Empty target description selection -> block build with message. +- Invalid numeric source value -> row dropped with warning. +- Empty source/target name after rules -> row dropped with warning. + +Success result: +- Chart updates immediately. + +Error result: +- Build error or warning list shown in preview panel. + +## 7. Web Flow: Preview Controls +Trigger: +- User changes direction, gap, padding, or theme. + +Steps: +1. Direction toggle swaps link direction (`source<->target`). +2. Gap/padding sliders update chart series layout. +3. Theme picker updates node palette. + +Decision points: +- Theme popover closes on outside pointer down. + +Success result: +- Chart visual changes apply in-place. + +## 8. Web Flow: Export +Trigger: +- User clicks `Export SVG` or `Export PNG`. + +Steps: +1. Ensure chart instance exists. +2. Build filename with timestamp. +3. For SVG: prefer serializing DOM ``; fallback to `getDataURL`. +4. For PNG: use `getDataURL(type='png', pixelRatio=2)`. +5. Trigger browser download. + +Decision points: +- No chart instance -> no action. + +Success result: +- Downloaded file appears with expected naming. + +## 9. Miniapp Skeleton Flow (Current State) +Trigger: +- Open miniapp index page. + +Steps: +1. Render static layout blocks. +2. Allow opening/closing theme bottom sheet. + +Current limitations: +- No real file parsing, no Sankey rendering, no export pipeline. + +## 10. Flow Completion Checklist +A flow is considered complete only when: +1. Success path works end-to-end. +2. Error path shows deterministic message. +3. UI state remains recoverable after errors. diff --git a/BACKEND_STRUCTURE.md b/BACKEND_STRUCTURE.md new file mode 100644 index 0000000..d49333c --- /dev/null +++ b/BACKEND_STRUCTURE.md @@ -0,0 +1,77 @@ +# BACKEND_STRUCTURE.md + +## 1. 当前结论(v0.1) +当前项目为纯前端本地处理架构: +- 无后端服务 +- 无数据库 +- 无认证系统 +- 无远程 API + +这不是遗漏,而是产品范围定义(见 PRD.md 的 Non-Goals)。 + +## 2. 数据处理位置 +所有数据处理均在客户端完成: +- 文件解析:`src/core/parser.ts` +- 聚合构建:`src/core/sankey.ts` +- 状态承载:`src/App.vue`(内存态) + +## 3. 当前“数据结构合同” +虽然没有数据库,但有稳定的数据结构合同。 + +### 3.1 RawTable +```ts +interface RawTable { + headers: string[]; + rows: string[][]; +} +``` + +### 3.2 MappingConfig +```ts +interface MappingConfig { + sourceDataColumn: number | null; + sourceDescriptionColumns: number[]; + targetDescriptionColumns: number[]; + delimiter: string; +} +``` + +### 3.3 SankeyBuildResult +```ts +interface SankeyBuildResult { + nodes: Array<{ name: string; kind: 'source' | 'target' }>; + links: Array<{ source: string; target: string; value: number }>; + meta: { + droppedRows: number; + warnings: string[]; + }; +} +``` + +## 4. 存储规则 +- 运行时数据仅驻留内存(浏览器刷新后丢失)。 +- 不写入 localStorage / IndexedDB / 远程存储。 +- 导出结果通过浏览器下载能力交付给用户。 + +## 5. 认证与权限 +- 当前不存在用户登录、权限校验、租户隔离。 +- 所有用户在本地环境有相同行为能力。 + +## 6. API 合约 +- 当前无 HTTP API。 +- 唯一远程读取是静态样例文件:`GET /data/example0.xlsx`(同站静态资源,不是业务 API)。 + +## 7. 边界与异常处理 +- 文件类型不支持:直接抛错并提示。 +- 解析错误:保留页面可操作状态,允许重新上传。 +- 聚合错误:展示错误信息,不产生图表。 +- 行级数据问题:通过 warning 列表给出行号并跳过坏行。 + +## 8. 未来后端接入约束(预留) +仅当 PRD 明确扩展范围(账号、云保存、协作)时,才允许新增后端。届时必须先补充: +1. 数据库表结构(表、字段、类型、索引、关系) +2. API OpenAPI 合约 +3. 认证模型(会话、令牌、权限) +4. 存储策略(文件与图快照) + +在 PRD 未变更前,禁止实现任何后端功能。 diff --git a/FRONTEND_GUIDELINES.md b/FRONTEND_GUIDELINES.md new file mode 100644 index 0000000..7321b98 --- /dev/null +++ b/FRONTEND_GUIDELINES.md @@ -0,0 +1,110 @@ +# FRONTEND_GUIDELINES.md + +## 1. 目的 +定义 Web 与小程序端 UI 的统一视觉与交互规范,避免样式漂移。 + +关联文档: +- PRD.md +- APP_FLOW.md + +## 2. 设计基线 +- 设计来源:Figma 对应节点(Web 与小程序骨架) +- 风格关键词:工具化、轻量、高密度信息、低装饰 +- 基础布局:顶部工具栏 + 左侧映射面板 + 右侧预览面板 + +## 3. 设计令牌(Web) + +### 3.1 颜色变量(`src/styles.css`) +- `--primary-7: #8552A1` +- `--primary-6: #9B6BC2` +- `--fill-1: #F7F8FA` +- `--fill-3: #E5E6EB` +- `--fill-4: #C9CDD4` +- `--text-1: #FFFFFF` +- `--text-3: #86909C` +- `--text-4: #4E5969` +- `--danger-3: #FBACA3` + +### 3.2 字体 +- 主字体变量:`--font-pingfang` +- 字体栈:`PingFang SC`, `Hiragino Sans GB`, `Microsoft YaHei`, `sans-serif` +- 默认字号:12 / 14 / 16 / 18 / 20 / 24 / 28 + +### 3.3 圆角 +- 工具类组件:`4px`、`6px`、`8px` +- 主卡片:`16px` +- 主题弹窗:`24px 24px 0 0` +- 胶囊控件:`999px` + +### 3.4 间距尺度 +建议仅使用以下值(已在现有样式大量出现): +- `2, 4, 6, 8, 10, 12, 16, 18, 24` + +## 4. 主题系统 +- 主题源:`src/theme-presets.ts` +- 每个主题包含:`id + name + 10色数组` +- 默认主题:`figma-violet` +- 主题应用范围:Sankey 节点颜色轮换 + +## 5. 组件规范(Web) + +### 5.1 顶部工具栏 +- 包含:Logo、主题选择、上传入口、导出入口 +- 上传区需支持点击与拖拽 +- 导出区固定显示 SVG/PNG 两个动作按钮 + +### 5.2 左侧映射面板 +- 分组:`源数据`、`目标数据` +- 子块: + - 源数据-数据列(单选) + - 源数据-描述列(多选) + - 目标数据-描述列(多选) + - 目标总和显示开关(复选) +- 每个子块支持展开/折叠 +- 行高基线:`32px` + +### 5.3 预览面板 +- 标题:`桑基图预览` +- 控件:`gap`、`padding` 滑块 + 方向开关 +- 图表容器最小高度: + - 桌面:`480px` + - 中屏:`360px` +- 告警与错误文本必须显示在图表区域外,避免遮挡图 + +### 5.4 主题弹窗 +- 定位:`fixed` +- 需要视口边界钳制 +- 点击外部自动关闭 +- 选中项透明度 100%,非选中项按距离降低 + +## 6. 响应式规则 +- 断点 A:`max-width: 1024px` + - 顶栏竖排 + - 主区从双栏改为单栏 + - 左侧卡片支持换行 +- 断点 B:`max-width: 640px` + - 页面内边距缩小 + - Logo、标题、标题文字按移动端尺寸缩放 + +## 7. 图表视觉规则 +- 背景色:`#f7f8fa` +- 节点宽度:`14` +- 连线:`color='source'`, `curveness=0.45`, `opacity=0.45` +- 标签字体大小:`12` + +## 8. 图标与资源 +- 图标目录:`assets/icons/` +- Web 与 miniapp 共用同一套图标资源命名 +- 禁止在组件中硬编码新的图标路径 + +## 9. 可访问性与可读性 +- 关键图标必须有 `alt` 文本 +- 错误文本颜色与普通文本明显区分 +- 文本截断区域需保留可读主体(列名优先显示前缀) + +## 10. 小程序样式约束(当前) +- 仅用于骨架视觉对齐,不作为完整功能规范 +- 维持与 Web 一致的色板、图标命名和信息分区 + +## 11. 变更规则 +任何新增组件或样式改动,必须同步更新本文件对应条目。 diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..99ab143 --- /dev/null +++ b/IMPLEMENTATION_PLAN.md @@ -0,0 +1,91 @@ +# IMPLEMENTATION_PLAN.md + +## 1. 目的 +将 PRD 的需求拆为可执行、可验证的小步任务,减少实现时猜测。 + +关联文档: +- PRD.md +- APP_FLOW.md +- TECH_STACK.md +- FRONTEND_GUIDELINES.md +- BACKEND_STRUCTURE.md + +## 2. 里程碑视图 +- M1:工程与核心数据层 +- M2:Web 交互与图表预览 +- M3:导出与体验增强 +- M4:质量门禁与文档闭环 +- M5:小程序从骨架到可用(未来) + +## 3. 详细步骤 + +### M1 工程与核心数据层 +- [x] 1.1 初始化 `Vue + TS + Vite` 工程 +- [x] 1.2 按 TECH_STACK 安装依赖并配置脚本 +- [x] 1.3 建立 `src/core` 模块边界 +- [x] 1.4 实现 CSV 解析为 `RawTable` +- [x] 1.5 实现 XLS/XLSX 解析为 `RawTable` +- [x] 1.6 实现 `MappingConfig` 与 `SankeyBuildResult` 类型 +- [x] 1.7 实现 target 向下补全 + 聚合算法 +- [x] 1.8 覆盖核心单元测试 + +验收命令: +- `npm run test` + +### M2 Web 交互与图表预览 +- [x] 2.1 实现主页面结构(头部、左侧、预览) +- [x] 2.2 实现文件点击上传 +- [x] 2.3 实现拖拽上传 +- [x] 2.4 实现 source/target 列映射交互 +- [x] 2.5 建立实时重算机制(watchEffect) +- [x] 2.6 接入 ECharts Sankey 渲染 +- [x] 2.7 支持方向切换 +- [x] 2.8 支持 gap/padding 调节 +- [x] 2.9 支持主题选择器与配色应用 +- [x] 2.10 增加错误与告警展示 +- [x] 2.11 首次加载默认样例文件 + +验收命令: +- `npm run type-check` +- `npm run lint` + +### M3 导出与体验增强 +- [x] 3.1 实现 SVG 导出(DOM 序列化优先) +- [x] 3.2 实现 PNG 导出(pixelRatio=2) +- [x] 3.3 统一导出命名规则(时间戳) +- [x] 3.4 增加目标总和显示开关 + +验收清单: +- 本地下载文件可打开 +- 命名格式符合约定 + +### M4 质量门禁与文档闭环 +- [x] 4.1 建立/维护测试命令 +- [x] 4.2 建立/维护 lint 与 type-check 门禁 +- [x] 4.3 补充 README 与规划文档 +- [x] 4.4 补充本轮知识库文档(PRD/Flow/Stack/Guidelines/Backend/Plan) +- [x] 4.5 更新会话记忆文件 `progress.txt` + +验收命令: +- `npm run test` +- `npm run type-check` +- `npm run lint` +- `npm run format` + +### M5 小程序从骨架到可用(未来) +- [ ] 5.1 接入文件上传能力 +- [ ] 5.2 复用 `src/core` 解析与聚合逻辑 +- [ ] 5.3 接入小程序图表渲染容器 +- [ ] 5.4 接入导出或保存图片能力 +- [ ] 5.5 建立小程序端测试与验收用例 + +## 4. 每次迭代执行模板 +1. 从 `progress.txt` 读取上下文 +2. 选择一个最小可交付任务 +3. 实现并补充/更新测试 +4. 运行质量命令 +5. 更新 `progress.txt` 与相关规范文档 + +## 5. 变更控制 +- 任何超出 PRD 范围的能力,先改 PRD,再改计划。 +- 任何新增依赖,先确认,再更新 TECH_STACK。 diff --git a/PRD.md b/PRD.md new file mode 100644 index 0000000..eeabf2b --- /dev/null +++ b/PRD.md @@ -0,0 +1,106 @@ +# PRD.md + +## 1. 文档目的 +本文件定义「星程桑基图」的产品需求合同(v0.1),用于约束范围、功能验收标准与成功标准。 + +关联文档: +- APP_FLOW.md +- TECH_STACK.md +- FRONTEND_GUIDELINES.md +- BACKEND_STRUCTURE.md +- IMPLEMENTATION_PLAN.md + +## 2. 产品概述 +星程桑基图是一个本地优先的数据可视化工具,用户上传 `csv/xls/xlsx` 后,通过列映射规则生成桑基图,支持实时预览、主题切换与 `PNG/SVG` 导出。 + +## 3. 目标用户 +- 数据分析师:快速从表格生成流向关系图。 +- 业务运营人员:无需编程即可配置 source/target 映射。 +- 演示与汇报人员:导出图用于文档与汇报。 + +## 4. 核心问题 +- 表格到桑基图映射过程复杂,人工制作耗时。 +- Excel 存在“合并单元格语义”(下方空值继承上方值),常规可视化工具处理不稳定。 +- 需要稳定导出图像用于跨平台传播。 + +## 5. 产品目标(Goals) +- G1:用户可在 3 分钟内完成一次从上传到导出的全流程。 +- G2:支持目标描述列的“向下补全”语义并正确聚合。 +- G3:在映射配置变更后即时刷新预览,避免重复上传。 +- G4:导出结果可直接用于 PPT/文档(PNG、SVG)。 + +## 6. 非目标(Non-Goals) +- 不做账号体系、登录、权限。 +- 不做云端存储、多人协作、历史版本。 +- 不做后端 API 与数据库(见 BACKEND_STRUCTURE.md)。 +- 不做三级/多级桑基图编辑器(当前仅由列拼接形成单级 source->target 关系)。 +- 不做 APP 端正式实现(仅保留小程序骨架)。 + +## 7. 功能范围与验收标准 + +### F1 文件上传与默认样例 +需求:支持点击与拖拽上传;首次进入自动加载样例文件。 + +验收标准: +- 支持扩展名:`.csv/.xls/.xlsx`。 +- 首次加载时,若用户未上传文件,自动读取 `data/example0.xlsx`。 +- 上传成功后,显示文件名与行数。 +- 上传失败时展示明确错误信息。 + +### F2 列映射配置 +需求:支持 source 数据列单选、source 描述列多选、target 描述列多选。 + +验收标准: +- `source data` 为单选且必选。 +- `source description` 可为空;为空时回退为 source data 单元格文本。 +- `target description` 为多选且至少选择 1 列。 +- 映射变更后无需点击“生成”,图表实时刷新。 + +### F3 聚合规则 +需求:按映射配置构建 `nodes/links` 并做容错。 + +验收标准: +- source 数值支持千分位解析,如 `12,000`。 +- 非法 source 数值(空或非数字)跳过并记录告警。 +- target 描述列支持“向下补全”(空值继承上一次非空值)。 +- source/target 描述为空行跳过并记录告警。 +- 相同 `sourceName@@targetName` 累加值。 + +### F4 预览与交互 +需求:提供可视化预览并支持关键配置。 + +验收标准: +- 支持方向切换:`source->target` / `target->source`(仅交换链接方向)。 +- 支持节点间距(gap)与图内边距(padding)调整。 +- 支持主题选择并应用到节点颜色。 +- 支持“目标总和”显示开关(只影响 target 标签展示,不影响聚合值)。 + +### F5 导出 +需求:支持导出 `SVG` 与 `PNG`。 + +验收标准: +- 文件名格式:`sankey_YYYYMMDD_HHmmss.svg|png`。 +- PNG 使用 `pixelRatio=2` 导出。 +- 若 DOM 可获取 ``,优先序列化导出 SVG,否则使用图表实例导出。 + +### F6 小程序骨架 +需求:提供页面结构与视觉骨架,不承诺完整业务逻辑。 + +验收标准: +- 存在页面结构、列选择区、主题底部弹层。 +- 明确标注为“骨架”,不作为完整功能验收对象。 + +## 8. 成功标准(Success Metrics) +- S1:核心单元测试稳定通过(`npm run test`)。 +- S2:类型检查与 lint 稳定通过(`npm run type-check && npm run lint`)。 +- S3:核心样例 `data/example0.xlsx` 可在默认加载后正常出图。 +- S4:导出文件在本地可打开且内容与当前视图一致。 + +## 9. 约束与依赖 +- 技术实现必须遵循 TECH_STACK.md 固定版本。 +- UI 实现必须遵循 FRONTEND_GUIDELINES.md 设计规范。 +- 不得在未确认情况下引入新生产依赖。 + +## 10. 版本状态 +- 当前合同版本:`v0.1` +- 最后更新:`2026-02-13` diff --git a/TECH_STACK.md b/TECH_STACK.md new file mode 100644 index 0000000..67bba69 --- /dev/null +++ b/TECH_STACK.md @@ -0,0 +1,70 @@ +# TECH_STACK.md + +## 1. 目的 +本文件锁定当前项目技术栈与精确版本,避免生成代码时发生版本漂移。 + +关联文档: +- PRD.md +- IMPLEMENTATION_PLAN.md + +## 2. 运行环境 +- Node.js: `24.11.0` +- npm: `11.6.1` +- OS(当前开发环境): macOS + +## 3. Web 框架与构建 +- Vue: `3.5.28` +- Vite: `7.3.1` +- @vitejs/plugin-vue: `6.0.4` +- TypeScript: `5.9.3` +- vue-tsc: `3.2.4` + +## 4. 核心业务依赖 +- echarts: `5.6.0` +- papaparse: `5.5.3` +- xlsx (SheetJS): `0.18.5` + +## 5. 代码质量与测试 +- vitest: `3.2.4` +- eslint: `8.57.1` +- @typescript-eslint/eslint-plugin: `8.55.0` +- @typescript-eslint/parser: `8.55.0` +- eslint-plugin-vue: `9.33.0` +- vue-eslint-parser: `9.4.3` +- eslint-config-prettier: `10.1.8` +- prettier: `3.8.1` + +## 6. 类型依赖 +- @types/node: `24.10.13` +- @types/papaparse: `5.5.2` + +## 7. NPM Scripts(唯一入口) +- `npm run dev`: 启动开发服务器 +- `npm run build`: 类型检查 + 生产构建 +- `npm run preview`: 预览构建产物 +- `npm run type-check`: 仅类型检查 +- `npm run lint`: ESLint 检查 +- `npm run test`: Vitest 单测 +- `npm run format`: Prettier 检查 + +## 8. 目录与模块边界 +- `src/core/*`: 纯业务逻辑(解析、聚合、类型) +- `src/App.vue`: Web 页面与交互 +- `src/styles.css`: 全局样式 +- `src/theme-presets.ts`: 主题色预设 +- `miniapp/*`: 小程序骨架 + +## 9. 开发服务器约束 +`vite.config.ts` 当前使用本地 HTTPS 证书路径: +- `~/mac.biboer.cn_ecc/fullchain.cer` +- `~/mac.biboer.cn_ecc/mac.biboer.cn.key` + +若本机无该证书,`npm run dev` 需要先调整 Vite 配置。 + +## 10. 依赖治理规则 +- 生产依赖新增/升级必须先确认。 +- 版本锁定以 `package-lock.json` + 本文档为准。 +- 未在本文档出现的库,默认不可在实现中使用。 + +## 11. 后端说明 +当前无后端服务、无数据库、无认证(详见 BACKEND_STRUCTURE.md)。 diff --git a/progress.txt b/progress.txt new file mode 100644 index 0000000..e946da2 --- /dev/null +++ b/progress.txt @@ -0,0 +1,43 @@ +[更新时间] 2026-02-13 +[项目] 星程桑基图 + +一、已完成(Done) +1. Web 单页主流程已打通:上传 -> 列映射 -> 预览 -> 导出。 +2. 已支持文件格式:csv / xls / xlsx。 +3. 已实现核心聚合规则: + - source 数值列解析(含千分位) + - source 描述列拼接(可为空) + - target 描述列向下补全(合并单元格语义) + - source-target 键值聚合 +4. 已实现预览配置:方向切换、gap、padding、主题切换。 +5. 已实现导出:PNG/SVG(带时间戳命名)。 +6. 已实现默认样例加载:页面首次进入自动读取 `data/example0.xlsx`。 +7. 已有核心单测(parser + sankey 聚合 + xlsx 读取)。 +8. 小程序端已完成视觉骨架(非完整业务)。 + +二、当前状态(In Progress) +1. 无进行中的代码重构任务。 +2. 文档体系已补齐为知识库结构: + - PRD.md + - APP_FLOW.md + - TECH_STACK.md + - FRONTEND_GUIDELINES.md + - BACKEND_STRUCTURE.md + - IMPLEMENTATION_PLAN.md + +三、已知问题 / 风险(Known Issues) +1. 当前无后端、无持久化,刷新页面后状态丢失(符合当前范围)。 +2. Vite 开发配置依赖本机 HTTPS 证书路径,换机器可能无法直接启动。 +3. 当前“目标数据”无独立数值列,数值始终来自 source data 列;若未来业务需要需先改 PRD。 +4. 小程序仅骨架,尚未接入真实解析、渲染与导出。 + +四、下一步建议(Next) +1. 决策是否引入“目标数值列”能力(先更新 PRD 后实现)。 +2. 将小程序由骨架升级为可用版本(优先复用 `src/core`)。 +3. 补充更多异常用例测试(空文件、超大文件、乱码表头、极端数值)。 +4. 评估并处理 dev HTTPS 证书本地耦合问题,降低新环境接入成本。 + +五、执行约定(Session Memory Rules) +1. 新会话开始先读取本文件,再读取 6 份规范文档。 +2. 每次功能完成后,必须更新:Done / Known Issues / Next。 +3. 任何范围变化先改 PRD,再改实现与计划。