likes
comments
collection
share

Echarts在微信小程序中的使用

作者站长头像
站长
· 阅读数 19

Echarts提供了小程序版本echarts-for-weixin,封装了成了一个名为ec-canvas的自定义组件供我们直接引用。

下面会先介绍一下echarts的特性等,不需要的直接跳到在小程序中使用部分

特性

  • 支持在线定制,勾选需要的图标和组件,而非下载整个包。
  • v5.0.1开始支持按需引入
  • 提供了类型接口,方便使用了TS的项目进行类型检查。
  • Echarts内含了默认主题、dark和light这三种主题色,此外还支持在主题编辑器中下载、自行编辑更多的主题色
  • 自定义图表样式:包括配置调色盘、通过itemStyle/lineStyle等精细的配置、鼠标悬浮高亮等。

小程序版本中不支持的特性:

  • npm安装方式,需要将整个/ec-canvas目录放到诸如/components目录下
  • 按需引入。只支持在线定制,将定制的包替换/ec-canvas/echarts.js
  • chartInstance.showLoading()chartInstance.hideLoading()不支持
  • 主题色目前也没有找到相关说明如何使用

概念概览

  • 组件

echarts上的内容被抽象为了组件,包括坐标轴、legend、series、tooltip、toolbox等。option 每个属性是一类组件。

  • series

表示一组数据以及它们映射成的图。至少包含图标类型、数据配置项以及如何映射的参数。

(备注:第i个x轴点要映射series中每个item的第i个data作为y轴数据,相当于遍历一遍series中的item的第i个数据,横坐标对纵坐标是一对多的关系)。

使用

  • 引入

可下载源码自行编译或者编译后的产出物、npm安装以及在线定制。

  • 创建图表

提供一个具有宽高的容器节点,初始化,之后传入option来表述图表。

  • 异步数据加载和更新

获取到数据后,通过setOption填入数据和配置项。

多提一下关于数据的处理,echarts提供了在series中分别传入每个系列的数据,以及在dataset属性中统一管理数据两种方式。推荐后者,a.将数据和其他配置项分开管理,提高维护性; b.此外也可用于复用; c. 支持二维数组和对象数组,减少数据格式转换。

默认series映射为y轴。dataset中默认series声明的图被安放到列,可通过series[i].seriesLayoutBy设置series映射到行还是列。

小程序中使用

官方文档echarts-for-weixin,对于如何在小程序中使用echarts进行了比较详细的描述。在此不做过于基础的说明,只列举在真实项目中可能会遇到的场景。

缩减包的大小

ec-canvas文件夹整个有将近1M,还是比较大了,建议在分包中组织可视化页面。此外,考虑在线定制需要的图表,下载的文件替换掉ec-canvas/echarts.js

由于我的项目中只用到了柱状图和折线图,再加上坐标系、toolTip等工具,压缩后的代码减到了500多K。

延迟加载图表

通常图表数据都是通过异步请求拿到,因此会希望获取到数据后才初始化图表,否则一开始会有一个只有坐标轴的图,比较丑。

先来看看如果是页面一进来就初始化图表,官方给的例子:

<view class="container">
  <ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
</view>
function initChart(canvas, width, height, dpr) {
  const chart = echarts.init(canvas, null, {
    width: width,
    height: height,
    devicePixelRatio: dpr // 像素
  });
  canvas.setChart(chart);

  var option = {
    ...
  };
  chart.setOption(option);
  return chart;
}

Page({
  data: {
    ec: {
      onInit: initChart
    }
  }
});

需要在dataoption中提供一个具有onInit属性的对象,该属性值为初始化的方法。

由于此时无法访问this,所以initChart需要定义在Page之外。这样的问题就是如果要在后面访问chart实例,需要提供一个page之外的变量来接收,是全局存在的。如果直接封装成一个小程序自定义组件,这个chart实例变量需要额外处理一下复用问题。

再来看一下延迟加载图表:

Page({
    data: {
        ec: {
            lazyLoad: true
        }
    },
    onReady: function () {
        // 手动获取到echart节点
        this.compBar = this.selectComponent('#mychart-dom-bar')
        this.loadData()
    },
    loadData: function() {
        api.getData().then(res => {
            // 更新数据等配置项
            const opts = {
              dataset: {
                dimensions: res.dimensions,
                source: res.source
              }
            }
            
            if(this.chartBar) {
                this.chartBar.setOption(opts)
            } else {
                this.initBar(opts)
            }
        })
    },
    initBar: function(options) {
        this.compBar.init((canvas, width, height, dpr) => {
            const chart = echarts.init(canvas, null, {
              width: width,
              height: height,
              devicePixelRatio: dpr
            });
            
            // 这个是给chart注入一些初始化的配置项,数据项初始化为空数组,后面再解释该方法
            configBar(chart)
            chart.setOption(option)
        
            this.chartBar = chart
            return chart
        })
    }
});

可见需要首先通过selectComponent拿到ec-canvas组件节点,然后调用init方法手动初始化。当数据有更新时,调用chartInstance.setOption进行更新。

代码组织

图表的配置项除了数据以外,其他诸如坐标轴,lengend,label等的样都比较固定,可以在一个config文件中进行管理,如上面代码中的configBar:

// chart-config.js
export function configBar(chart) {
    const opts = {
        //...各种配置项
        dataset: {
            dimensions: [],
            source: []
        },
        series: [
            {
                type: 'bar'
            }
        ]
    }
    chart.setOption(option)
}

如果图表需要复用,还可以进一步封装为一个小程序自定义组件:

<view class="report-group-bar">
  <ec-canvas id="{{chartDomId}}" canvas-id="{{canvasId}}" ec="{{ec}}" type="2d"></ec-canvas>
</view>
import * as echarts from '../../ec-canvas/echarts'

Component({
  properties: {
    chartId: {
      type: String,
      value: 'chart-group-bar'
    },
    canvasId: {
      type: String,
      value: 'canvas-group-bar'
    },
    chartData: {
      type: Array,
      value: []
    }
  },
  data: {
    ec: {
      lazyLoad: true
    }
  },
  lifetimes: {
    attached() {
      this.chartComp = this.selectComponent(this.properties.chartId)
    }
  },

  methods: {
    initChart(options) {
      this.chartComp && this.chartComp.init((canvas, width, height, dpr) => {
        const chart = echarts.init(canvas, null, {
          width: width,
          height: height,
          devicePixelRatio: dpr
        })
        configChart(chart)
        chart.setOption(options)
        this.chart = chart
        return chart
      })
    }
  },

  observers: {
    'chartData': function (value) {
      const opts = {
        // ...
      }
      if (this.chart) {
        this.chart.setOption(opts)
      } else {
        this.initChart(opts)
      }
    }
  }
})

其他

小程序基础库2.9.0 起支持一套新Canvas 2D 接口),使用新的 Canvas 2d 可以提升渲染性能,解决非同层渲染问题,强烈建议开启:

<view class="report-group-bar">
  <ec-canvas id="{{chartDomId}}" canvas-id="{{canvasId}}" ec="{{ec}}" type="2d"></ec-canvas>
</view>
转载自:https://juejin.cn/post/6994742503207337991
评论
请登录