Files
EmailBill/openspec/specs/chart-migration-patterns/spec.md
SunCheng c1e2adacea chore: archive migrate-remaining-echarts-to-chartjs change
- Synced chart-migration-patterns spec to main specs
- Archived to openspec/changes/archive/2026-02-16-migrate-remaining-echarts-to-chartjs
- All artifacts complete, 57/80 tasks complete (23 test tasks skipped)

Schema: spec-driven
Status: ✓ Complete with warnings (test tasks skipped)
2026-02-16 22:40:13 +08:00

116 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## ADDED Requirements
### Requirement: 仪表盘图表迁移模式
组件 SHALL 使用 Chart.js Doughnut 图表实现仪表盘Gauge效果替代 ECharts Gauge 图表。
#### Scenario: 半圆仪表盘渲染
- **WHEN** 组件接收预算统计数据current, limit
- **THEN** 系统使用 Doughnut 图表渲染半圆进度条,配置 `rotation: -90``circumference: 180`
#### Scenario: 中心文本叠加显示
- **WHEN** 仪表盘图表渲染完成
- **THEN** 系统在图表中心显示余额/超支文本,使用 CSS 绝对定位的覆盖层
#### Scenario: 动态颜色切换
- **WHEN** 实际值超过预算限额
- **THEN** 进度条颜色切换为危险色(`var(--van-danger-color)`),中心文本显示"超支"
#### Scenario: 暗色模式适配
- **WHEN** 用户切换到暗色主题
- **THEN** 图表颜色自动适配,使用 `useChartTheme` composable 获取主题色
### Requirement: 折线图迁移模式
组件 SHALL 使用 Chart.js Line 图表实现趋势折线图,替代 ECharts Line 图表。
#### Scenario: 单系列折线图渲染
- **WHEN** 组件接收月度支出数据(日期 + 金额数组)
- **THEN** 系统渲染折线图X 轴为日期标签Y 轴为金额,使用渐变填充
#### Scenario: 双系列折线图渲染
- **WHEN** 组件接收收支数据(包含收入和支出两个系列)
- **THEN** 系统渲染两条折线,支出为红色,收入为绿色,支持独立的 hover 交互
#### Scenario: 空数据处理
- **WHEN** 图表数据为空或所有数据点为 0
- **THEN** 系统显示 `<van-empty>` 空状态组件,而非空白图表
#### Scenario: Tooltip 格式化
- **WHEN** 用户 hover 到数据点
- **THEN** Tooltip 显示"¥XXX.XX"格式的金额,使用 `callbacks.label` 自定义
### Requirement: 饼图/环形图迁移模式
组件 SHALL 使用 Chart.js Doughnut 图表实现分类统计环形图,替代 ECharts Pie 图表。
#### Scenario: 环形图渲染
- **WHEN** 组件接收分类统计数据(分类名称 + 金额数组)
- **THEN** 系统渲染环形图,每个分类使用不同颜色,配置 `cutout: '50%'`
#### Scenario: 分类颜色映射
- **WHEN** 分类数据包含预定义颜色
- **THEN** 图表使用 props 传入的颜色数组,确保与列表中的分类色块一致
#### Scenario: 小分类合并
- **WHEN** 分类数量超过 10 个
- **THEN** 系统使用 `mergeSmallCategories()` 工具函数,将占比小于 5% 的分类合并为"其他"
#### Scenario: 点击分类跳转
- **WHEN** 用户点击环形图扇区
- **THEN** 系统触发 `@category-click` 事件,传递分类名称和类型
### Requirement: BaseChart 组件统一使用
所有图表组件 SHALL 使用 `BaseChart.vue` 包装组件,而非直接使用 vue-chartjs 组件。
#### Scenario: BaseChart 组件使用
- **WHEN** 组件需要渲染图表
- **THEN** 使用 `<BaseChart type="line|bar|doughnut" :data="chartData" :options="chartOptions" />`
#### Scenario: Loading 状态处理
- **WHEN** 图表数据加载中
- **THEN** BaseChart 显示 `<van-loading>` 组件
#### Scenario: 图表渲染回调
- **WHEN** 图表渲染完成
- **THEN** BaseChart 触发 `@chart:render` 事件,传递 Chart.js 实例引用
### Requirement: ECharts 代码完全移除
组件 SHALL 移除所有 ECharts 相关代码,包括导入语句、实例变量、环境变量判断。
#### Scenario: 移除 ECharts 导入
- **WHEN** 迁移组件
- **THEN** 删除 `import * as echarts from 'echarts'` 语句
#### Scenario: 移除环境变量开关
- **WHEN** 迁移组件
- **THEN** 删除 `const useChartJS = import.meta.env.VITE_USE_CHARTJS === 'true'` 和相关的 `v-if`/`v-else` 条件渲染
#### Scenario: 移除 ECharts 实例管理
- **WHEN** 迁移组件
- **THEN** 删除 `let chartInstance = null``echarts.init()``chartInstance.setOption()` 等代码
#### Scenario: 移除生命周期清理
- **WHEN** 迁移组件
- **THEN** 删除 `onBeforeUnmount()` 中的 `chartInstance.dispose()` 调用
### Requirement: 测试覆盖
迁移后的组件 SHALL 通过白盒和黑盒测试验证功能正确性。
#### Scenario: 单元测试 - 组件挂载
- **WHEN** 运行 Jest 单元测试
- **THEN** 组件能够成功挂载,不抛出错误
#### Scenario: 单元测试 - Props 传递
- **WHEN** 传入测试数据 props
- **THEN** 计算属性 `chartData``chartOptions` 返回正确的 Chart.js 配置对象
#### Scenario: E2E 测试 - 图表渲染
- **WHEN** 运行 Playwright E2E 测试
- **THEN** 浏览器中能看到图表元素Canvas且无控制台错误
#### Scenario: E2E 测试 - 用户交互
- **WHEN** 用户 hover 到图表数据点
- **THEN** Tooltip 正确显示,格式化后的金额信息可见
#### Scenario: 视觉回归测试
- **WHEN** 截图对比迁移前后的图表
- **THEN** 颜色、布局、字体大小差异在可接受范围内(像素差异 < 5%