modify:优化

This commit is contained in:
ECRZ
2026-01-07 10:13:21 +08:00
parent da4a055c1c
commit 60b5aba7f8
10 changed files with 3148 additions and 280 deletions

View File

@@ -0,0 +1,488 @@
[根目录](../../CLAUDE.md) > **components/ec-canvas**
---
# components/ec-canvas - ECharts 图表组件
> **模块状态**: ✅ 已完成
>
> **最后更新**: 2026-01-07 09:16:32
---
## 变更记录 (Changelog)
### 2026-01-07 09:16:32
- 生成组件文档
- 补充使用说明与配置项
- 添加常见问题与故障排查
### 2026-01-06
- 集成 ECharts 图表库
- 实现微信小程序 Canvas 适配
- 封装为通用组件
---
## 模块职责
**ec-canvas** 是 ECharts 图表组件,负责:
1. **图表渲染**:在微信小程序中渲染 ECharts 图表
2. **Canvas 适配**:适配小程序 Canvas 2D 接口
3. **事件处理**:处理触摸交互事件
4. **响应式布局**:自适应屏幕尺寸
---
## 入口与启动
### 组件路径
- **注册路径**`components/ec-canvas/ec-canvas`
- **物理路径**`components/ec-canvas/ec-canvas.js`
### 使用方式
```json
// 页面 JSON 配置
{
"usingComponents": {
"ec-canvas": "../../components/ec-canvas/ec-canvas"
}
}
```
```xml
<!-- 页面 WXML -->
<ec-canvas id="mychart-dom-line" canvas-id="mychart-line" ec="{{ ec }}"></ec-canvas>
```
---
## 对外接口
### 组件属性Properties
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| canvasId | String | 'ec-canvas' | Canvas 组件 ID |
| ec | Object | {} | 图表配置对象(必须包含 onInit 方法) |
| disableTouch | Boolean | false | 是否禁用触摸交互 |
### ec 对象结构
```javascript
ec: {
onInit: function(canvas, width, height, res) {
// 必须返回图表实例
const chart = echarts.init(canvas)
chart.setOption(option)
return chart
}
}
```
### 组件方法Methods
| 方法名 | 参数 | 说明 |
|--------|------|------|
| touchStart | event | 触摸开始事件 |
| touchMove | event | 触摸移动事件 |
| touchEnd | event | 触摸结束事件 |
---
## 关键依赖与配置
### 依赖文件
| 文件 | 用途 |
|------|------|
| `ec-canvas.js` | 组件逻辑91 行) |
| `ec-canvas.wxml` | 组件模板 |
| `ec-canvas.wxss` | 组件样式 |
| `ec-canvas.json` | 组件配置 |
| `echarts.js` | ECharts 库(简化版) |
| `wx-canvas.js` | Canvas 适配器 |
### 外部依赖
- **ECharts**:内置的简化版 ECharts 库
- **Canvas 2D**:微信小程序 Canvas 2D 接口
### 配置项
```javascript
// 组件配置
Component({
properties: {
canvasId: {
type: String,
value: 'ec-canvas'
},
ec: {
type: Object,
value: {}
}
}
})
```
---
## 数据模型
### 组件生命周期
```javascript
Component({
ready() {
// 1. 检查 ec 对象
if (!this.data.ec || !this.data.ec.onInit) {
console.warn('组件需绑定 ec 对象,且包含 onInit 方法')
return
}
// 2. 查询 Canvas 节点
const query = this.createSelectorQuery()
query.select(`#${this.data.canvasId}`)
.fields({ node: true, size: true })
.exec((res) => {
// 3. 初始化 Canvas
const canvasNode = res[0].node
const ctx = canvasNode.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
// 4. 设置 Canvas 尺寸
canvasNode.width = res[0].width * dpr
canvasNode.height = res[0].height * dpr
ctx.scale(dpr, dpr)
// 5. 调用 onInit 初始化图表
const canvas = {
width: res[0].width * dpr,
height: res[0].height * dpr,
getContext: () => ctx,
node: canvasNode
}
this.chart = this.data.ec.onInit(canvas, res[0].width, res[0].height, res)
})
}
})
```
---
## 核心功能实现
### 1. Canvas 初始化
```javascript
ready() {
const query = this.createSelectorQuery()
query.select(`#${this.data.canvasId}`)
.fields({ node: true, size: true })
.exec((res) => {
const canvasNode = res[0].node
const ctx = canvasNode.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
// 缩放以适配高清屏
canvasNode.width = res[0].width * dpr
canvasNode.height = res[0].height * dpr
ctx.scale(dpr, dpr)
// 创建 Canvas 对象
const canvas = {
width: res[0].width * dpr,
height: res[0].height * dpr,
getContext: () => ctx,
node: canvasNode
}
// 调用外部初始化函数
this.chart = this.data.ec.onInit(canvas, res[0].width, res[0].height, res)
})
}
```
### 2. 触摸事件处理
```javascript
methods: {
touchStart(e) {
if (this.chart && this.chart.touchStart) {
this.chart.touchStart(e)
}
},
touchMove(e) {
if (this.chart && this.chart.touchMove) {
this.chart.touchMove(e)
}
},
touchEnd(e) {
if (this.chart && this.chart.touchEnd) {
this.chart.touchEnd(e)
}
}
}
```
---
## 使用示例
### 1. 基础折线图
```javascript
// 页面 JS
Page({
data: {
ec: {
onInit: null
}
},
onLoad() {
this.setData({
ec: {
onInit: this.initChart.bind(this)
}
})
},
initChart(canvas, width, height, res) {
const chart = echarts.init(canvas)
const option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']
},
yAxis: {
type: 'value'
},
series: [{
data: [120, 200, 150, 80, 70],
type: 'line',
smooth: true
}]
}
chart.setOption(option)
return chart
}
})
```
### 2. 面积图(带渐变)
```javascript
initChart(canvas, width, height, res) {
const chart = echarts.init(canvas)
const option = {
xAxis: {
type: 'category',
data: ['1/1', '1/2', '1/3', '1/4', '1/5']
},
yAxis: {
type: 'value'
},
series: [{
data: [3850, 3860, 3840, 3870, 3890],
type: 'line',
smooth: true,
areaStyle: {
color: {
type: 'linear',
x: 0, y: 0, x2: 0, y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
{ offset: 1, color: 'rgba(24, 144, 255, 0.05)' }
]
}
}
}]
}
chart.setOption(option)
return chart
}
```
### 3. 动态更新数据
```javascript
// 更新图表数据
updateChart(newData) {
if (this.chart) {
this.chart.setOption({
series: [{
data: newData
}]
})
}
}
// 清空图表
clearChart() {
if (this.chart) {
this.chart.clear()
}
}
```
---
## WXML 模板结构
```xml
<!-- components/ec-canvas/ec-canvas.wxml -->
<canvas
type="2d"
id="{{canvasId}}"
canvas-id="{{canvasId}}"
class="ec-canvas"
bindtouchstart="touchStart"
bindtouchmove="touchMove"
bindtouchend="touchEnd">
</canvas>
```
---
## WXSS 样式
```css
/* components/ec-canvas/ec-canvas.wxss */
.ec-canvas {
width: 100%;
height: 100%;
display: block;
}
```
---
## 测试与质量
### 测试覆盖
- ✅ 在价格趋势页正常工作
- ✅ 图表渲染正确
- ✅ 触摸交互正常
- ✅ 响应式布局适配
### 测试要点
1. **图表渲染**:验证不同类型图表正常显示
2. **数据更新**:验证动态更新数据功能
3. **交互功能**:验证触摸、缩放、拖拽等交互
4. **性能测试**:大数据量时的渲染性能
5. **兼容性**iOS/Android 不同平台兼容性
---
## 常见问题 (FAQ)
### Q: 图表不显示?
**A**: 检查以下几点:
1. 确保 `ec` 对象包含 `onInit` 方法
2. 确保 Canvas 节点已正确渲染
3. 查看控制台是否有错误信息
4. 检查 ECharts 配置是否正确
### Q: 如何修改图表尺寸?
**A**: 在 WXML 中设置容器尺寸:
```xml
<view style="width: 100%; height: 500rpx;">
<ec-canvas ec="{{ ec }}"></ec-canvas>
</view>
```
### Q: 如何支持手势缩放?
**A**: 在 ECharts 配置中启用:
```javascript
const option = {
dataZoom: [{
type: 'inside',
start: 0,
end: 100
}],
// ... 其他配置
}
```
### Q: 如何导出图表为图片?
**A**: 使用 Canvas 的 `toDataURL` 方法:
```javascript
const canvas = this.chart.canvas
const url = canvas.toDataURL('image/png')
// 预览图片
wx.previewImage({
urls: [url]
})
```
### Q: 图表性能如何优化?
**A**: 优化建议:
1. 减少数据点数量(采样)
2. 关闭动画效果
3. 使用轻量级图表类型
4. 避免频繁更新
```javascript
// 关闭动画
const option = {
animation: false,
// ... 其他配置
}
```
---
## 相关文件清单
```
components/ec-canvas/
├── ec-canvas.js # 组件逻辑91 行)
├── ec-canvas.json # 组件配置
├── ec-canvas.wxml # 组件模板
├── ec-canvas.wxss # 组件样式
├── echarts.js # ECharts 库(简化版)
├── wx-canvas.js # Canvas 适配器
└── CLAUDE.md # 本文档
```
---
## 下一步建议
### 功能增强
1. **更多图表类型**
- 柱状图Bar
- 饼图Pie
- 散点图Scatter
- K 线图Candlestick
2. **交互增强**
- Tooltip 提示框
- 图例筛选
- 数据区域缩放
- 标记点/标记线
3. **性能优化**
- 虚拟滚动(大数据量)
- 增量渲染
- Web Worker 计算
### 最佳实践
1. **数据格式化**:统一数据格式转换逻辑
2. **错误处理**:添加图表渲染失败的降级方案
3. **加载状态**:显示加载动画
4. **空状态**:无数据时友好提示
---
**模块状态**: ✅ 已完成
**优先级**: 高(核心组件)
**预估工作量**: 已完成
**使用场景**: [pages/trend](../../pages/trend/CLAUDE.md) - 价格趋势图
**相关资源**: [ECharts 文档](https://echarts.apache.org/zh/index.html)