57 lines
2.4 KiB
Markdown
57 lines
2.4 KiB
Markdown
|
|
## Context
|
|||
|
|
|
|||
|
|
当前统计页面使用 Chart.js 渲染折线图和饼图,但存在以下技术问题:
|
|||
|
|
|
|||
|
|
1. **折线图溢出**: 图表 canvas 尺寸计算未考虑容器边界,导致图表绘制超出卡片范围
|
|||
|
|
2. **时间范围显示**: 折线图 X 轴显示整个自然周期(如整月),但数据仅到当前日期,导致后半段为平直线
|
|||
|
|
3. **饼图标签**: 当前饼图使用图例(legend)展示分类,用户需要在图例和图表间来回查看
|
|||
|
|
|
|||
|
|
项目使用 Vue 3 + Chart.js + vue-chartjs 技术栈,图表配置通过 `useChartTheme` composable 统一管理。
|
|||
|
|
|
|||
|
|
## Goals / Non-Goals
|
|||
|
|
|
|||
|
|
**Goals:**
|
|||
|
|
- 实现图表在容器内的自适应布局,无溢出
|
|||
|
|
- 折线图动态计算数据截止时间,仅显示有效数据范围
|
|||
|
|
- 饼图扇区直接渲染分类名称标签
|
|||
|
|
- 保持现有主题配置和响应式行为
|
|||
|
|
|
|||
|
|
**Non-Goals:**
|
|||
|
|
- 不更换图表库(保持 Chart.js)
|
|||
|
|
- 不修改数据 API 或数据结构
|
|||
|
|
- 不添加新的图表类型
|
|||
|
|
- 不影响其他页面的图表显示
|
|||
|
|
|
|||
|
|
## Decisions
|
|||
|
|
|
|||
|
|
### 1. 布局约束方案: CSS 容器 + Chart.js responsive 配置
|
|||
|
|
- **选择**: 结合 CSS `overflow: hidden` 和 Chart.js `maintainAspectRatio: false` + `responsive: true`
|
|||
|
|
- **理由**: 利用 Chart.js 内置的响应式机制,同时通过 CSS 确保容器边界约束
|
|||
|
|
- **替代方案**: 手动计算 canvas 尺寸(复杂,需监听 resize)
|
|||
|
|
|
|||
|
|
### 2. 折线图数据过滤: 前端日期截断
|
|||
|
|
- **选择**: 在组件内根据当前日期过滤数据数组,仅传递有效数据给 Chart.js
|
|||
|
|
- **理由**: 最小化改动,不修改 API;保持数据完整性以备他用
|
|||
|
|
- **替代方案**: 后端 API 支持日期参数(需后端改动,过度设计)
|
|||
|
|
|
|||
|
|
### 3. 饼图标签方案: Chart.js datalabels 插件
|
|||
|
|
- **选择**: 使用 `chartjs-plugin-datalabels` 插件在扇区上渲染标签
|
|||
|
|
- **理由**: 官方推荐方案,支持自动位置计算和碰撞检测
|
|||
|
|
- **替代方案**: 自定义绘制(复杂,需处理重叠)
|
|||
|
|
|
|||
|
|
## Risks / Trade-offs
|
|||
|
|
|
|||
|
|
| Risk | Mitigation |
|
|||
|
|
|------|------------|
|
|||
|
|
| 饼图标签在扇区过小时显示不全 | 设置最小扇区角度阈值,小分类合并为"其他" |
|
|||
|
|
| 暗色模式切换时标签颜色适配 | 通过 `useChartTheme` 动态计算对比色 |
|
|||
|
|
| 性能影响(datalabels 插件) | 仅在饼图启用,监控渲染耗时 |
|
|||
|
|
|
|||
|
|
## Migration Plan
|
|||
|
|
|
|||
|
|
无需迁移,纯视觉修复,向后兼容。
|
|||
|
|
|
|||
|
|
## Open Questions
|
|||
|
|
|
|||
|
|
- 饼图标签在移动端小屏幕上的显示策略(待实现时验证)
|