最终效果预览
实现流程
微信小程序中使用 echarts 需使用官方提供的 ec-canvas 组件
1. 下载 ec-canvas 组件
点击下方链接,下载 ec-canvas 组件
https://gitcode.net/mirrors/ecomfe/echarts-for-weixin/-/tree/master
将其中的 ec-canvas
文件夹拷贝到微信小程序的分包中
( 因 ec-canvas
组件较大,约 1M,若放在主包中很容易超出 2M 的大小限制,不了解分包的朋友,可以参考博文 https://blog.csdn.net/weixin_41192489/article/details/130249743)
2. 引入 ec-canvas 组件
package1\pages\account\statistics\index.json
{ "navigationBarTitleText": "记账统计", "usingComponents": { "t-collapse": "tdesign-miniprogram/collapse/collapse", "t-collapse-panel": "tdesign-miniprogram/collapse-panel/collapse-panel", "ec-canvas": "/package1/ec-canvas/ec-canvas" } }
其中的核心代码为
"ec-canvas": "/package1/ec-canvas/ec-canvas"
3. 页面中使用 ec-canvas 组件
package1\pages\account\statistics\index.wxml
<view class="titleBox"> {{year}} 年{{month}} 月 </view> <t-collapse value="{{activeValues}}" bind:change="cardChange"> <t-collapse-panel value="{{0}}" header="收入( 合计 {{sumIn}} 元 )" expandIcon> <view hidden="{{hideInChart}}" class="container"> <ec-canvas id="mychart1" canvas-id="mychart1" ec="{{ ec }}"></ec-canvas> </view> </t-collapse-panel> <t-collapse-panel value="{{1}}" header="支出( 合计 {{sumOut}} 元 )" expandIcon> <view hidden="{{hideOutChart}}" class="container"> <ec-canvas id="mychart2" canvas-id="mychart2" ec="{{ ec }}"></ec-canvas> </view> </t-collapse-panel> </t-collapse>
核心代码为
<ec-canvas id="mychart1" canvas-id="mychart1" ec="{{ ec }}"></ec-canvas>
此范例为一个页面渲染多个图表,需留意每个组件需有不同的 id
<ec-canvas id="mychart2" canvas-id="mychart2" ec="{{ ec }}"></ec-canvas>
4. 添加必要的 css
ec-canvas 组件默认没有尺寸,需手动添加必要的 css,才能显示。
package1\pages\account\statistics\index.wxss
.container { position: relative; width: 98%; height: 500rpx; margin: 0rpx auto; } ec-canvas { position: relative; width: 300rpx; height: 400rpx; } .titleBox { font-weight: bold; padding-top: 30rpx; font-size: 40rpx; text-align: center; }
5. 获取数据,渲染图表
package1\pages\account\statistics\index.js
import * as echarts from '../../../ec-canvas/echarts'; Page({ data: { // 数据列表 dataList: [], // 是否隐藏收入图表 hideInChart: false, // 是否隐藏支出图表 hideOutChart: false, // 折叠卡片的值 activeValues: [0, 1], // 图表配置 ec: { // 图表懒加载的必要参数 lazyLoad: true }, // 收入类型 inTypeList: ['工资', '兼职', '理财', '其他收入'], // 支出类型 outTypeList: ['衣', '食', '住', '行', '娱', '医', '学', '其他支出'] }, // 折叠卡片切换 cardChange(e) { this.setData({ activeValues: e.detail.value, }); this.updateData() }, // 更新数据状态(控制图表的显隐) updateData() { let { activeValues } = this.data this.setData({ hideInChart: !activeValues.includes(0), hideOutChart: !activeValues.includes(1) }) }, // 分类统计收入数据 getInResult(dataList) { let { inTypeList } = this.data let inResultDic = {} dataList.forEach(item => { inTypeList.forEach(type => { if (!inResultDic[type]) { inResultDic[type] = 0 } if (item.type === type) { inResultDic[type] += item.money } }) }) let yDataList = [] inTypeList.forEach(type => { yDataList.push(inResultDic[type] || 0) }) this.drawChart(this.ecComponent1, inTypeList, yDataList) }, // 分类统计支出数据 getOutResult(dataList) { let { outTypeList } = this.data let outResultDic = {} dataList.forEach(item => { outTypeList.forEach(type => { if (!outResultDic[type]) { outResultDic[type] = 0 } if (item.type === type) { outResultDic[type] += item.money } }) }) let yDataList = [] outTypeList.forEach(type => { yDataList.push(outResultDic[type] || 0) }) // 因页面宽度有限,删除支出二字 outTypeList[7] = '其他' this.drawChart(this.ecComponent2, outTypeList, yDataList) }, onLoad() { let that = this // 接收传入的复杂数据 const eventChannel = this.getOpenerEventChannel() eventChannel.on('sendData', function (res) { let { sumIn, sumOut, sumResult, year, month, dataList } = res that.setData({ sumIn, sumOut, // 月结余 balance: sumResult, year, month, dataList }) that.ecComponent1 = that.selectComponent('#mychart1'); that.ecComponent2 = that.selectComponent('#mychart2'); that.getInResult(dataList) that.getOutResult(dataList) }) }, // 绘制图表 drawChart(ecComponent, xDataList, yDataList) { ecComponent.init((canvas, width, height, dpr) => { // 获取组件的 canvas、width、height 后的回调函数 // 在这里初始化图表 const chart = echarts.init(canvas, null, { width: width, height: height, devicePixelRatio: dpr }); this.setOption(chart, xDataList, yDataList); // 注意这里一定要返回 chart 实例,否则会影响事件处理等 return chart; }); }, // 柱状图配置 setOption(chart, xDataList, yDataList) { let option = { xAxis: { type: 'category', data: xDataList }, yAxis: { type: 'value' }, series: [{ data: yDataList, type: 'bar', label: { show: true, position: "top" } }] } chart.setOption(option); } })
核心代码解析
- 导入 echarts
import * as echarts from '../../../ec-canvas/echarts';
- 获取页面图表节点
that.ecComponent1 = that.selectComponent('#mychart1');
- 绘制图表
// 绘制图表 drawChart(ecComponent, xDataList, yDataList) { ecComponent.init((canvas, width, height, dpr) => { // 获取组件的 canvas、width、height 后的回调函数 // 在这里初始化图表 const chart = echarts.init(canvas, null, { width: width, height: height, devicePixelRatio: dpr }); this.setOption(chart, xDataList, yDataList); // 注意这里一定要返回 chart 实例,否则会影响事件处理等 return chart; }); },
- 添加图表配置
setOption(chart, xDataList, yDataList) { let option = { xAxis: { type: 'category', data: xDataList }, yAxis: { type: 'value' }, series: [{ data: yDataList, type: 'bar', label: { show: true, position: "top" } }] } chart.setOption(option); }
https://echarts.apache.org/examples/zh/index.html