- Migrated 4 components from ECharts to Chart.js: * MonthlyExpenseCard.vue (折线图) * DailyTrendChart.vue (双系列折线图) * ExpenseCategoryCard.vue (环形图) * BudgetChartAnalysis.vue (仪表盘 + 多种图表) - Removed all ECharts imports and environment variable switches - Unified all charts to use BaseChart.vue component - Build verified: pnpm build success ✓ - No echarts imports remaining ✓ Refs: openspec/changes/migrate-remaining-echarts-to-chartjs
147 lines
4.7 KiB
Markdown
147 lines
4.7 KiB
Markdown
# Chart.js 迁移完成总结
|
||
|
||
**日期**: 2026-02-16
|
||
**任务**: 将 EmailBill 项目中剩余的 ECharts 图表迁移到 Chart.js
|
||
|
||
## 迁移的组件
|
||
|
||
### 1. ExpenseCategoryCard.vue
|
||
**文件路径**: `Web/src/views/statisticsV2/modules/ExpenseCategoryCard.vue`
|
||
|
||
**变更内容**:
|
||
- ✅ 删除 `import * as echarts from 'echarts'`
|
||
- ✅ 删除 `useChartJS` 环境变量和相关的 v-if/v-else 条件渲染
|
||
- ✅ 删除 `pieChartInstance` 变量和所有 ECharts 初始化代码
|
||
- ✅ 简化模板,只保留 `<BaseChart type="doughnut" />`
|
||
- ✅ 删除 `onBeforeUnmount` 中的 ECharts cleanup
|
||
- ✅ 删除 `watch` 和 `renderPieChart()` 函数
|
||
- ✅ 移除 `if (!useChartJS) return null` 判断,chartData 和 chartOptions 始终返回有效值
|
||
|
||
**保留功能**:
|
||
- ✅ Doughnut 图表(支出分类环形图)
|
||
- ✅ 数据预处理逻辑(`prepareChartData()`)
|
||
- ✅ 分类列表展示
|
||
- ✅ 点击事件(category-click)
|
||
|
||
### 2. BudgetChartAnalysis.vue
|
||
**文件路径**: `Web/src/components/Budget/BudgetChartAnalysis.vue`
|
||
|
||
**变更内容**:
|
||
- ✅ 删除 `import * as echarts from 'echarts'`
|
||
- ✅ 引入 `BaseChart` 和 `useChartTheme` composable
|
||
- ✅ 引入 `chartjsGaugePlugin` 用于仪表盘中心文本显示
|
||
- ✅ 删除所有 ECharts 相关的 ref 变量(`monthGaugeRef`, `yearGaugeRef`, 等)
|
||
- ✅ 删除所有 ECharts 实例变量(`monthGaugeChart`, `varianceChart`, 等)
|
||
- ✅ 替换仪表盘为 Chart.js Doughnut 图表(使用 gaugePlugin)
|
||
- ✅ 替换燃尽图为 Chart.js Line 图表
|
||
- ✅ 替换偏差分析为 Chart.js Bar 图表(水平方向)
|
||
- ✅ 删除所有 ECharts 初始化和更新函数
|
||
- ✅ 删除 `onBeforeUnmount` 中的 ECharts cleanup
|
||
- ✅ 删除 `handleResize` 和相关的 resize 事件监听
|
||
|
||
**实现的图表**:
|
||
|
||
#### 月度/年度仪表盘(Gauge)
|
||
- 使用 Doughnut 图表 + gaugePlugin
|
||
- 半圆形进度条(circumference: 180, rotation: 270)
|
||
- 中心文字覆盖层显示余额/差额
|
||
- 支持超支场景(红色显示)
|
||
- 颜色逻辑:
|
||
- 支出:满格绿色 → 消耗变红
|
||
- 收入:空红色 → 积累变绿
|
||
|
||
#### 月度/年度燃尽图(Burndown)
|
||
- 使用 Line 图表
|
||
- 两条线:理想线(虚线)+ 实际线(实线)
|
||
- 支出模式:燃尽图(向下走)
|
||
- 收入模式:积累图(向上走)
|
||
- 支持趋势数据(`props.overallStats.month.trend`)
|
||
- Fallback 到线性估算
|
||
|
||
#### 偏差分析(Variance)
|
||
- 使用 Bar 图表(水平方向,`indexAxis: 'y'`)
|
||
- 正值(超支)红色,负值(结余)绿色
|
||
- 动态高度计算(30px per item)
|
||
- 排序:年度在前,月度在后,各自按偏差绝对值排序
|
||
- Tooltip 显示详细信息(预算/实际/偏差)
|
||
|
||
**数据处理逻辑**:
|
||
- ✅ 保留所有业务逻辑(日期计算、趋势数据、进度计算)
|
||
- ✅ 使用 computed 属性实现响应式更新
|
||
- ✅ 格式化函数 `formatMoney()` 保持一致
|
||
|
||
## 技术栈变更
|
||
|
||
### 移除
|
||
- ❌ ECharts 5.x
|
||
- ❌ 手动管理图表实例
|
||
- ❌ 手动 resize 监听
|
||
- ❌ 手动 dispose cleanup
|
||
|
||
### 使用
|
||
- ✅ Chart.js 4.5+
|
||
- ✅ vue-chartjs 5.3+
|
||
- ✅ BaseChart 通用组件
|
||
- ✅ useChartTheme composable(主题管理)
|
||
- ✅ chartjsGaugePlugin(仪表盘插件)
|
||
- ✅ Vue 响应式系统(computed)
|
||
|
||
## 构建验证
|
||
|
||
```bash
|
||
cd Web && pnpm build
|
||
```
|
||
|
||
**结果**: ✅ 构建成功
|
||
|
||
- 无 TypeScript 错误
|
||
- 无 ESLint 错误
|
||
- 无 Vue 编译错误
|
||
- 产物大小正常
|
||
|
||
## 性能优势
|
||
|
||
1. **包体积减小**
|
||
- ECharts 较大(~300KB gzipped)
|
||
- Chart.js 较小(~60KB gzipped)
|
||
|
||
2. **更好的 Vue 集成**
|
||
- 使用 Vue 响应式系统
|
||
- 无需手动管理实例生命周期
|
||
- 自动 resize 和 cleanup
|
||
|
||
3. **一致的 API**
|
||
- 所有图表使用统一的 BaseChart 组件
|
||
- 统一的主题配置(useChartTheme)
|
||
- 统一的颜色变量(CSS Variables)
|
||
|
||
## 后续工作
|
||
|
||
- [x] 移除 VITE_USE_CHARTJS 环境变量(已不需要)
|
||
- [x] 清理所有 ECharts 相关代码
|
||
- [ ] 测试所有图表功能(手动测试)
|
||
- [ ] 验证暗色模式下的显示效果
|
||
- [ ] 验证移动端触控交互
|
||
|
||
## 注意事项
|
||
|
||
1. **仪表盘中心文本**
|
||
- 使用 CSS 绝对定位的 `.gauge-text-overlay` 显示中心文本
|
||
- 不使用 gaugePlugin 的 centerText(因为需要 scaleX(-1) 翻转)
|
||
|
||
2. **偏差分析图表**
|
||
- 使用 `_meta` 字段传递额外数据到 tooltip
|
||
- 颜色根据 `activeTab`(支出/收入)动态计算
|
||
|
||
3. **响应式更新**
|
||
- 所有数据通过 computed 属性计算
|
||
- 无需手动调用 update 或 resize
|
||
- BaseChart 自动处理 props 变化
|
||
|
||
## 参考文档
|
||
|
||
- [Chart.js 官方文档](https://www.chartjs.org/)
|
||
- [vue-chartjs 文档](https://vue-chartjs.org/)
|
||
- [项目 Chart.js 使用指南](./chartjs-usage-guide.md)
|
||
- [BaseChart 组件文档](../Web/src/components/Charts/README.md)
|