[WeChat Mini Program - Native Development] Practical Tutorial 22 - Drawing Charts (Introducing echarts, including lazy loading of charts-rendering charts after obtaining data, loading multiple charts, etc.)

final effect preview

insert image description here

Implementation process

The use of echarts in the WeChat applet needs to use the official ec-canvas component

1. Download the ec-canvas component

Click the link below to download the ec-canvas component
https://gitcode.net/mirrors/ecomfe/echarts-for-weixin/-/tree/master

insert image description here

ec-canvasCopy the folder in it to the subpackage of the WeChat applet

(Because ec-canvasthe component is large, about 1M, if it is placed in the main package, it will easily exceed the size limit of 2M. Friends who do not know about subcontracting can refer to the blog post https://blog.csdn.net/weixin_41192489/article/details/130249743 )

insert image description here
insert image description here

2. Introduce the ec-canvas component

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"
  }
}

The core code is

    "ec-canvas": "/package1/ec-canvas/ec-canvas"

3. Use the ec-canvas component in the page

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>

The core code is

<ec-canvas id="mychart1" canvas-id="mychart1" ec="{
     
     { ec }}"></ec-canvas>

This example renders multiple charts for one page, please note that each component needs to have a different id

      <ec-canvas id="mychart2" canvas-id="mychart2" ec="{
     
     { ec }}"></ec-canvas>

4. Add the necessary css

The ec-canvas component has no size by default, and the necessary css needs to be manually added to display it.

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. Get the data and render the chart

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);
  }
})

Core code analysis

  • Import echarts
import * as echarts from '../../../ec-canvas/echarts';
  • Get the page graph node
that.ecComponent1 = that.selectComponent('#mychart1');
  • draw a chart
  // 绘制图表
  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;
    });
  },
  • Add chart configuration
  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);
  }

If you want to draw other types of charts, you can modify this configuration by referring to the echarts official website
https://echarts.apache.org/examples/zh/index.html

insert image description here

Guess you like

Origin blog.csdn.net/weixin_41192489/article/details/130250281