Echarts在微信小程序中的使用
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
}
}
});
需要在data
option中提供一个具有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