modify:优化
This commit is contained in:
488
Sale/components/ec-canvas/CLAUDE.md
Normal file
488
Sale/components/ec-canvas/CLAUDE.md
Normal 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)
|
||||
Reference in New Issue
Block a user