# 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 初始化代码 - ✅ 简化模板,只保留 `` - ✅ 删除 `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)