- 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
4.7 KiB
4.7 KiB
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和useChartThemecomposable - ✅ 引入
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)
构建验证
cd Web && pnpm build
结果: ✅ 构建成功
- 无 TypeScript 错误
- 无 ESLint 错误
- 无 Vue 编译错误
- 产物大小正常
性能优势
-
包体积减小
- ECharts 较大(~300KB gzipped)
- Chart.js 较小(~60KB gzipped)
-
更好的 Vue 集成
- 使用 Vue 响应式系统
- 无需手动管理实例生命周期
- 自动 resize 和 cleanup
-
一致的 API
- 所有图表使用统一的 BaseChart 组件
- 统一的主题配置(useChartTheme)
- 统一的颜色变量(CSS Variables)
后续工作
- 移除 VITE_USE_CHARTJS 环境变量(已不需要)
- 清理所有 ECharts 相关代码
- 测试所有图表功能(手动测试)
- 验证暗色模式下的显示效果
- 验证移动端触控交互
注意事项
-
仪表盘中心文本
- 使用 CSS 绝对定位的
.gauge-text-overlay显示中心文本 - 不使用 gaugePlugin 的 centerText(因为需要 scaleX(-1) 翻转)
- 使用 CSS 绝对定位的
-
偏差分析图表
- 使用
_meta字段传递额外数据到 tooltip - 颜色根据
activeTab(支出/收入)动态计算
- 使用
-
响应式更新
- 所有数据通过 computed 属性计算
- 无需手动调用 update 或 resize
- BaseChart 自动处理 props 变化