Files
EmailBill/.doc/chartjs-migration-complete.md

147 lines
4.7 KiB
Markdown
Raw Normal View History

# 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)