Files
EmailBill/.doc/chartjs-migration-complete.md
SunCheng 9921cd5fdf chore: migrate remaining ECharts components to Chart.js
- 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
2026-02-16 21:55:38 +08:00

4.7 KiB
Raw Blame 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
  • 删除 watchrenderPieChart() 函数
  • 移除 if (!useChartJS) return null 判断chartData 和 chartOptions 始终返回有效值

保留功能:

  • Doughnut 图表(支出分类环形图)
  • 数据预处理逻辑(prepareChartData()
  • 分类列表展示
  • 点击事件category-click

2. BudgetChartAnalysis.vue

文件路径: Web/src/components/Budget/BudgetChartAnalysis.vue

变更内容:

  • 删除 import * as echarts from 'echarts'
  • 引入 BaseChartuseChartTheme 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

构建验证

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

后续工作

  • 移除 VITE_USE_CHARTJS 环境变量(已不需要)
  • 清理所有 ECharts 相关代码
  • 测试所有图表功能(手动测试)
  • 验证暗色模式下的显示效果
  • 验证移动端触控交互

注意事项

  1. 仪表盘中心文本

    • 使用 CSS 绝对定位的 .gauge-text-overlay 显示中心文本
    • 不使用 gaugePlugin 的 centerText因为需要 scaleX(-1) 翻转)
  2. 偏差分析图表

    • 使用 _meta 字段传递额外数据到 tooltip
    • 颜色根据 activeTab(支出/收入)动态计算
  3. 响应式更新

    • 所有数据通过 computed 属性计算
    • 无需手动调用 update 或 resize
    • BaseChart 自动处理 props 变化

参考文档