H5时代用来做图表的插件有很多比如:ECharts
、Bizcharts
、JSCharts
等,而这次的小程序本人选用了 ECharts 作为图表组件。
1、选择原因主要有3点:
- 官方某度在持续维护这个插件
- 官方推出了直接适配小程序的版本,且有demo,开盖即食,不用迁移
- 简单实用,覆盖面广且可通过配置控制包的大小,小程序毕竟大小有限制~
eCharts来自BAT中的B前端团队,对应的小程序版本为:echarts-for-weixin
官网地址
github地址
https://github.com/ecomfe/echarts-for-weixin
小程序demo地址
https://github.com/ecomfe/echarts-examples
2、用法
(1)官方教程
index.json
配置如下:
{
"usingComponents": {
"ec-canvas": "../../ec-canvas/ec-canvas"
}
}
这一配置的作用是,允许我们在 pages/bar/index.wxml
中使用 <ec-canvas>
组件。注意路径的相对位置要写对,如果目录结构和本例相同,就应该像上面这样配置。
index.wxml
中创建了一个 <ec-canvas>
组件:
<view class="container">
<ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
</view>
其中 ec
是一个我们在 index.js
中定义的对象,它使得图表能够在页面加载后被初始化并设置。
index.js
配置:
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
}
}
});
这对于所有 ECharts 图表都是通用的,用户只需要修改上面 option
的内容,即可改变图表。option
的使用方法参见 ECharts 配置项文档。
官方demo里的一些用法指导:
如何延迟加载图表?
参见 pages/lazyLoad
的例子,可以在获取数据后再初始化数据。
如何在一个页面中加载多个图表?
参见 pages/multiCharts
的例子。
如何使用 Tooltip?
目前,本项目已支持 ECharts Tooltip,但是由于 ECharts 相关功能尚未发版,因此需要使用当前本项目中 ec-canvas/echarts.js
,这个文件包含了可以在微信中使用 Tooltip 的相关代码。目前在 ECharts 官网下载的 echarts.js
还不能直接替换使用,等 ECharts 正式发版后即可。
具体使用方法和 ECharts 相同,例子参见 pages/line/index.js
。
如何保存为图片?
参见 pages/saveCanvas
的例子。
(2)本人实战操作
import * as echarts from '../ec-canvas/echarts';
const app = getApp();
let chart;
function initChart(canvas, width, height, dpr) {
chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: dpr // new
});
canvas.setChart(chart);
chart.setOption(option);
return chart;
}
var option = {
title: {
text: '智酷君 echarts 切换效果测试',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 10,
data: ['AAA', 'BBB', 'CCC', 'DDD', 'EEE']
},
series: [
{
name: '访问来源',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '30',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{value: 335, name: 'AAA'},
{value: 310, name: 'BBB'},
{value: 234, name: 'CCC'},
{value: 135, name: 'DDD'},
{value: 1548, name: 'EEE'}
]
}
]
};
Page({
data: {
ec: {
onInit: initChart
}
},
onLoad: function () {},
//单曲线
line() {
let option2 = {
title: {
text: '同一canvas更新成折线图',
left: 'center'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line'
}]
};
chart.setOption(option2)
},
//切换柱状图
bar(){
let option3 = {
title: {
text: '直接更新数据,减少性能消耗',
left: 'center'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar',
showBackground: true,
backgroundStyle: {
color: 'rgba(220, 220, 220, 0.8)'
}
}]
};
chart.setOption(option3)
}
})
建议大家尽量使用同一个canvas对象来切换不同的图表效果,而不是初始加载多个不同的,我们可以将
chart
对象设置为全局,然后通过chart.setOption()
的方法来更新配置数据,可以减少性能消耗避免闪退等
(3)代码片段
代码段:https://developers.weixin.qq.com/s/OOTwnsms7Cin
建议将IDE工具升级到 1.02.18以上,避免一些BUG
3、Tips
(1)包大小可以配置
在线定制地址:
https://echarts.apache.org/zh/builder.html
通过选择和配置想要的功能,可以大大减少原本JS包的尺寸。
(2)Canvas 2d 版本要求
最新版的 ECharts 微信小程序支持微信 Canvas 2d,当用户的基础库版本 >= 2.9.0 且没有设置 force-use-old-canvas="true"
的情况下,使用新的 Canvas 2d(默认)。
使用新的 Canvas 2d 可以提升渲染性能,解决非同层渲染问题,强烈建议开启
如果仍需使用旧版 Canvas,使用方法如下:
<ec-canvas id="xxx" canvas-id="xxx" ec="{{ ec }}" force-use-old-canvas="true"></ec-canvas>
(3)数据点过多造成闪退和卡死
本人简单测试了下,iphone7p手机在1500个
左右数据点的时候,出现了小程序闪退,iphoneX 测试下来大概在2500个
左右,猜测可能由于微信本身给小程序的内存有限,所以建议大家控制数据点的个数
(4)单页面图表canvas加载过多卡死
建议单页面图表加载不要超过5个canvas
,尽可能共用一个图表Canvas对象,通过动态更新数据的方式来展示内容(还有帅气的特效),如果一定要加载多个canvas的话,建议控制数量,提供复用性~
入坑警告:不支持PC
<ec-canvas id="mychart" canvas-id="mychart" ec="{{ ec }}" force-use-old-canvas="{{true}}"></ec-canvas>
问题描述:option使用数据集dataset的方式配置后,图表报错
使用你的demo,经反复测试,有一个很大的问题,如果option使用数据集dataset的方式配置后,图表不能渲染出来,在开发者工具控制台报错“TypeError: t.count is not a function”,不知如何解决,还请楼主查看回复此问题!
问题重现:将楼主的line方法里的option改为echarts官方数据集方式的条形图配置,运行并点击按钮
echarts官方数据集示例:
https://echarts.apache.org/examples/zh/editor.html?c=data-transform-sort-bar
//单曲线 line() { let option2 = { dataset: [{ dimensions: ['name', 'age', 'profession', 'score', 'date'], source: [ [' Hannah Krause ', 41, 'Engineer', 314, '2011-02-12'], ['Zhao Qian ', 20, 'Teacher', 351, '2011-03-01'], [' Jasmin Krause ', 52, 'Musician', 287, '2011-02-14'], ['Li Lei', 37, 'Teacher', 219, '2011-02-18'], [' Karle Neumann ', 25, 'Engineer', 253, '2011-04-02'], [' Adrian Groß', 19, 'Teacher', null, '2011-01-16'], ['Mia Neumann', 71, 'Engineer', 165, '2011-03-19'], [' Böhm Fuchs', 36, 'Musician', 318, '2011-02-24'], ['Han Meimei ', 67, 'Engineer', 366, '2011-03-12'], ] }, { transform: { type: 'sort', config: { dimension: 'score', order: 'desc' } } }], xAxis: { type: 'category', axisLabel: { interval: 0, rotate: 30 }, }, yAxis: {}, series: { type: 'bar', encode: { x: 'name', y: 'score' }, datasetIndex: 1 } }; chart.setOption(option2) }
示例图:
https://echarts.apache.org/zh/tutorial.html#%E5%9C%A8%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%B8%AD%E4%BD%BF%E7%94%A8%20ECharts
初始化之后要怎么更改option中的值动态刷新图表
请问pages/saveCanvas保存图片的示例在哪里?
请问小程序上面可以实现y轴的标签在中间吗?这个怎么实现
你好,我用自己定制的echarts.js替换了原来echarts.js时报了错,更新了版本也没用,这种的话,有什么解决方法吗
formatter不支持自定义标签吗?
在添加markPoint时,使用自定义图片,new Image()会报错,这个如何解决?
echarts版本4.8
看下这个贴子,不知道对你有没有帮助
legend这个属性需要配置什么吗 我好像在option里面些legend这个属性 然后都不显示出来?
你好,图表加载出来后,点击按钮进行保存echart图表没有反应,请问是什么问题?
this.echartsComponnet = this.selectComponent('#mychart');
下载代码
setTimeout(()=>{
console.log("setTimeout==============")
//后面的console都没有打印
this.echartsComponnet.canvasToTempFilePath({
success: res => {
console.log("success=====res.tempFilePath:", res.tempFilePath)
// 存入系统相册
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath || '',
success: res => {
console.log("success", res)
},
fail: res => {
console.log("fail", res)
if(res.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || res.errMsg === "saveImageToPhotosAlbum:fail auth deny" || res.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
wx.showModal({
title: '提示',
content: '需要您授权保存相册',
showCancel: false,
success: modalSuccess => {
wx.openSetting({
success(settingdata) {
if (settingdata.authSetting['scope.writePhotosAlbum']) {
console.log('获取权限成功,给出再次点击图片保存到相册的提示。')
}else {
console.log('获取权限失败,给出不给权限就无法正常使用的提示')
}
}
})
}
})
}
}
})
},
fail: res => console.log("fail======",res)
})
},500)