小程序使用echarts 在一个页面打印多个饼图的坑
一、下载echarts微信版
下载地址:https://github.com/ecomfe/echarts-for-weixin
或者直接云盘下载 https://pan.baidu.com/s/1iOXILEZlmGYzzSin_TK22A 提取码 fwhx
二、创建所需文件
同时将下载的echarts 文件拷入,目录如下

三、创建一个配置option 的js
echart-option-config.js 配置option相关数据
var getOption = function (title,seriesName, dataArray) {
var option = {
title: {
text: title ||'数据来源',
x: 'left',
textStyle:{
fontSize:36
}
},
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b}: {c} ({d}%)"
},
series: [
{
name: seriesName || '访问来源',
type: 'pie',
radius: ['30%', '55%'],
labelLine: { // 设置指示线的长度
normal: {
length: 8,
length2: 8
}
},
label: {
normal: {
formatter: '{b|{b}:}\n{c}\n{per|{d}%} ',
rich: {
b: {
fontSize: 12,
lineHeight: 20,
align: 'center' // 设置文字居中
},
per: {
color: '#eee',
backgroundColor: '#334455',
padding: [2, 4],
borderRadius: 2,
align: 'center',
}
}
}
},
data: dataArray || [
{ value: 135, name: '视频广告' },
{ value: 148, name: '百度' },
{ value: 251, name: '谷歌' },
]
}
]
};
return option;
}
module.exports = getOption;
四、页面布局和具体实现
1、report-detail.wxml 布局页面
<view>
<view class="detail-head">
<text>{{caption}}月报</text>
</view>
<text class="caption-sub">数据来源</text>
<view class="desc">
<text>截止</text>
<text>{{caption}}</text>
<text> {{contentTxt}}</text>
<text class="data-list-num">{{spaceNum}}</text>
<text>条,其中:</text>
<view class="data-list">
<view>
<text>存量数据导入:</text>
<text class="data-list-num">{{stockNum}}</text>
<text>条;</text>
</view>
<view>
<text>异构接入数据:</text>
<text class="data-list-num">{{specialNum}}</text>
<text>条;</text>
</view>
<view>
<text>互联网抓取数据:</text>
<text class="data-list-num">{{internetNum}}</text>
<text>条;</text>
</view>
</view>
</view>
<view class="echart_panel">
<ec-canvas id="sorce-pie" canvas-id="source-pie" ec="{{ecLine}}" bind:init="echartInit_source"></ec-canvas>
</view>
<view class="hr"></view>
<view class="echart_panel">
<ec-canvas id="type-pie" canvas-id="type-pie" ec="{{ecLineSeason}}" bind:init="echartInit_type"></ec-canvas>
</view>
</view>
2、report-detail.js加载页面数据
import * as echarts from '../../../ec-canvas/echarts';
var getOptionByExternalJs = require('../../../echart-template/echart-option-config.js');
var optionConfig = new getOptionByExternalJs();
Page({
/**
* 页面的初始数据
*/
data: {
contentTxt: '平台通过存量数据导入,异构数据导入、异构系统/平台计入及互联网抓取方式,共汇集空间信息数据',
spaceNum: 23423,
stockNum: 234422,
specialNum: 347458,
internetNum: 89079,
ecLine: {},
ecLineSeason: {}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
// 接收上一个页面传入的年、季、月
var month = options.month;
var year = options.year;
var season = options.season;
// 将其挂载到data便于页面使用
this.setData({
caption: year + month
});
this.printPie(); // 打印饼图
},
/**
* 打印饼图
*
*/
printPie: function() {
let that = this;
// 初始化echarts ,同时挂载到data
wx.showLoading({
title: '数据加载中......',
})
// 此处假设我们使用wx.requiest请求后台获取到了所需数据,重置option
//打印第一个图形 [数据来源]
setTimeout(function() {
that.loadEchartsByBackstage(
that.data.initchartSource,
'数据来源',
'当月月报', [{
value: 9432,
name: '互联网抓取数据'
},
{
value: 24123,
name: '存量导入数据'
},
{
value: 14242,
name: '异构接入数据'
}
]);
//打印第二个图形【数据分类】
that.loadEchartsByBackstage(
that.data.initchartType,
'数据分类',
'当前季度', [{
value: 19432,
name: '春节'
},
{
value: 24123,
name: '秋季'
},
{
value: 14242,
name: '夏季'
},
{
value: 24242,
name: '冬季'
}
]);
wx.hideLoading();
}, 200);
},
/**
* 初始化echats
* @return {Object} echart
*
*/
initChart: function(canvas, width, height) {
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
canvas.setChart(chart);
chart.setOption(optionConfig);
return chart;
},
// 来源
echartInit_source(e) {
this.data.initchartSource = this.initChart(e.detail.canvas, e.detail.width, e.detail.height);
},
//分类
echartInit_type(e) {
this.data.initchartType = this.initChart(e.detail.canvas, e.detail.width, e.detail.height);
},
/**
* 从服务器获取数据
*
*/
loadEchartsByBackstage: function(echarCasch, title, seriesName, dataArray) {
echarCasch.setOption({
title: {
text: title
},
series: [{
name: seriesName,
data: dataArray
}]
});
}
})
3、report-detail.json 引入echarts
{
"navigationBarTitleText": "报告详情",
"usingComponents": {
"ec-canvas": "../../../ec-canvas/ec-canvas"
}
}
4、report-detail.wxss 设置页面样式
.detail-head {
margin-left: 12px;
font-weight: 700;
}
.caption-sub {
margin-left: 12px;
font-size: 12px;
font-weight: bold;
}
.desc {
margin: 12px;
font-size: 14px;
line-height: 28px;
}
.data-list{
display: flex;
flex-direction: column;
}
.data-list-num{
color:#3cbaff;
}
.echart_panel{
width: 100%;
height: 600rpx;
}
.hr {
border: 1px solid #ccc;
opacity: 0.2;
width: 78%;
margin: 0 auto;
background-color: red;
margin-bottom: 20px;
}
五、测试真机运行异常
上面代码在电脑模拟运行完全没问题,但是使用真机测试就会报错,如下图

WAService.js:1 thirdScriptError
Cannot read property 'setOption' of undefined;at pages/analysis-report/report-detail/report-detail onLoad function;at setTimeout callback function
TypeError: Cannot read property 'setOption' of undefined
at ge.loadEchartsByBackstage (weapp:///pages/analysis-report/report-detail/report-detail.js:110:16)
at Function.<anonymous> (weapp:///pages/analysis-report/report-detail/report-detail.js:54:12)
at WAService.js:1:102995
at Timeout._onTimeout (WAService.js:1:90534)
at listOnTimeout (internal/timers.js:535:17)
at processTimers (internal/timers.js:479:7)
一直纠结于为什么setOption未定义,找了好久都没明白为啥!
最后改了无数次代码,想到了可能是初始化echarts实例并未完成,就使用setTimeout模拟后台请求数据,
造成了在调用loadEchartsByBackstage时传入的that.data.initchartSource,
其实就是一个undefined(因为echartInit_source函数尚未初始完,
理所当然此时将ecahrts挂载到data中的操作也还没有执行)所以会有如上错误
最后我将setTimeout延时加长问题就没有了
/**
* 打印饼图
*
*/
printPie: function () {
let that = this;
// 初始化echarts ,同时挂载到data
wx.showLoading({
title: '数据加载中......',
})
// 此处假设我们使用wx.requiest请求后台获取到了所需数据,重置option
//打印第一个图形 [数据来源]
setTimeout(function () {
...
}, 2000);
但是这个肯定不是最终的处理办法(假如应用出现初始化卡顿,延时是否就不够了呢)!
最后想到了使用promise 来先获得echarts 实例
/**
* 初始化echats
* 使用promise获取初始化echarts 实例
* @return {Object} echart
*
*/
initChart: function (canvas, width, height) {
return new Promise(resolve => {
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
canvas.setChart(chart);
chart.setOption(optionConfig);
resolve(chart);
});
},
再将onload中的printPie()函数移到echarts的初始化中,再在data挂载变量标识printPie()是否已经被调用,如果未调用就调用该函数模拟获取数据重新渲染option;这样就OK了。
// 来源
echartInit_source(e) {
this.initChart(e.detail.canvas, e.detail.width, e.detail.height).then(res => {
this.data.initchartSource = res;
// 判断所以echarts 实例都初始完毕;并且invokePrintPie为false
if (this.data.initchartType && this.data.initchartSource && !this.data.invokePrintPie){
this.printPie(); // 打印饼图
this.data.invokePrintPie = true;
}
return res;
});
},
修改后的report-detail.js完整代码
import * as echarts from '../../../ec-canvas/echarts';
var getOptionByExternalJs = require('../../../echart-template/echart-option-config.js');
var optionConfig = new getOptionByExternalJs();
Page({
/**
* 页面的初始数据
*/
data: {
contentTxt: '平台通过存量数据导入,异构数据导入、异构系统/平台计入及互联网抓取方式,共汇集空间信息数据',
spaceNum: 23423,
stockNum: 234422,
specialNum: 347458,
internetNum: 89079,
invokePrintPie:false,//标识是否已经调用打印饼图操作
ecLine: {},
ecLineSeason: {}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 接收上一个页面传入的年、季、月
var month = options.month;
var year = options.year;
var season = options.season;
// 将其挂载到data便于页面使用
this.setData({
caption: year + month
});
//this.printPie(); // 打印饼图
},
/**
* 打印饼图
*
*/
printPie: function () {
let that = this;
// 初始化echarts ,同时挂载到data
wx.showLoading({
title: '数据加载中......',
})
// 此处假设我们使用wx.requiest请求后台获取到了所需数据,重置option
//打印第一个图形 [数据来源]
setTimeout(function () {
that.loadEchartsByBackstage(
that.data.initchartSource,
'数据来源',
'当月月报', [{
value: 9432,
name: '互联网抓取数据'
},
{
value: 24123,
name: '存量导入数据'
},
{
value: 14242,
name: '异构接入数据'
}
]);
//打印第二个图形【数据分类】
that.loadEchartsByBackstage(
that.data.initchartType,
'数据分类',
'当前季度', [{
value: 19432,
name: '春节'
},
{
value: 24123,
name: '秋季'
},
{
value: 14242,
name: '夏季'
},
{
value: 24242,
name: '冬季'
}
]);
wx.hideLoading();
}, 200);
},
/**
* 初始化echats
* 使用promise获取初始化echarts 实例
* @return {Object} echart
*
*/
initChart: function (canvas, width, height) {
return new Promise(resolve => {
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
canvas.setChart(chart);
chart.setOption(optionConfig);
resolve(chart);
});
},
// 来源
echartInit_source(e) {
this.initChart(e.detail.canvas, e.detail.width, e.detail.height).then(res => {
this.data.initchartSource = res;
// 判断所以echarts 实例都初始完毕;并且invokePrintPie为false
if (this.data.initchartType && this.data.initchartSource && !this.data.invokePrintPie){
this.printPie(); // 打印饼图
this.data.invokePrintPie = true;
}
return res;
});
},
//分类
echartInit_type(e) {
this.initChart(e.detail.canvas, e.detail.width, e.detail.height).then(res => {
this.data.initchartType = res;
// 判断所以echarts 实例都初始完毕;并且invokePrintPie为false
if (this.data.initchartType && this.data.initchartSource && !this.data.invokePrintPie) {
this.printPie(); // 打印饼图
this.data.invokePrintPie = true;
}
return res;
});
},
/**
* 从服务器获取数据
*
*/
loadEchartsByBackstage: function (echarCasch, title, seriesName, dataArray) {
echarCasch && echarCasch.setOption({
title: {
text: title
},
series: [{
name: seriesName,
data: dataArray
}]
});
}
})
六、修改后真机预览
预览如下图 :
加载之前使用默认数据
|
模拟加载真实数据后
|
七、 字体大小无法控制
不知道大家又没注意到,echarts 的title 有些小呢?然而echarts 的optin中title 设置的字体大小是36了呢。
运行时截图
|
option字体设置如图
|
最终的解决办法是去官网定制了一个新的library;
也可以在云盘直接下载:云盘地址 https://pan.baidu.com/s/1kSsYfI0M36KVc1JdeEjvBA 提取码 lrpg
,如图:
定制柱状、折线、饼图图表
|
定制所需组件
|
下载定制的library
|
编译完成自动下载
|
最后将下载的echarts-mini.js改名为echarts.js 替换ec-canvas目录下载的echarts.js即可

小程序使用echarts 在一个页面打印多个饼图的坑的更多相关文章
- 微信小程序遍历Echarts图表,实现多个饼图
如何在微信小程序中使用Echarts可以看我的另一个教程:点击查看 首先看一个简单的例子 1.wxml文件 <view style='width:100%;height:200rpx'> ...
- 微信小程序使用 ECharts 实现数据可视化
微信小程序使用 ECharts 显示图表 首先创建微信小程序 这里就不再赘述 下载 GitHub 上的 ecomfe/echarts-for-weixin 下载后解压,打开文件夹,里面的 ec-can ...
- 微信小程序左右滑动切换页面示例代码--转载
微信小程序——左右滑动切换页面事件 微信小程序的左右滑动触屏事件,主要有三个事件:touchstart,touchmove,touchend. 这三个事件最重要的属性是pageX和pageY,表示X, ...
- 小程序webview跳转页面后没有返回按钮完美解决方案
随着小程序越来越火爆,使一个产品如果只有公众号H5页面和APP显得不怎么完美,总感觉不搭上小程序这趟流量车,就会少了点什么,心里别扭地很.在此驱动下,我所在公司也决定赶紧上车. 但是,如果要按照小程序 ...
- 小程序swiper实现订单页面
小程序swiper实现订单页面 myOrder.wxml <!--pages/myorder/myorder.wxml--> <view class="swiper-tab ...
- 小程序-web-view嵌入H5页面遇到的bug
遇到的问题1:ios页面中,内容过多时有下滑真是功能,但是下滑的时候回看到底部的微信自带的灰色背景及H5的域名(ios的webview中上/下拉露出黑灰色背景问题) 解决办法:给body添加样式--- ...
- 小程序内嵌H5页面判断微信及小程序环境
判断微信及小程序环境 1.H5页面引入jweixin-1.3.2.js 2. var ua = window.navigator.userAgent.toLowerCase(); if(ua.matc ...
- 微信小程序生命周期、页面生命周期、组件生命周期
1. 生命周期 App(全局) 位置:项目根目录app.js文件 App({ onLaunch (options) { // console.log('小程序初始化') }, onShow(optio ...
- 微信小程序引入ECharts组件
首先打开ECharts网页 https://echarts.apache.org/zh/tutorial.html#%E5%9C%A8%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8 ...
- 微信小程序使用echarts/数据刷新重新渲染/图层遮挡问题
1.微信小程序使用echarts,首先下载echarts并导入小程序项目中,因小程序后期上线对文件大小有要求,所以建议进行定制下载导入可减少文件大小占比,也可以下载以前旧版本文件比较小的应付使用 下载 ...
随机推荐
- golang中关于死锁的思考与学习
1.Golang中死锁的触发条件 1.1 书上关于死锁的四个必要条件的讲解 发生死锁时,线程永远不能完成,系统资源被阻碍使用,以致于阻止了其他作业开始执行.在讨论处理死锁问题的各种方法之前,我们首先深 ...
- urllib.parse的使用
urllib简介 urllib是pyhton自带的标准库用于网络请求库,无需安装,直接引用 通常用于爬虫开发,API(应用程序编程接口)数据获取和测试 urllib库的4大模块 urllib.requ ...
- 设计模式(三十一)----综合应用-自定义Spring框架-自定义Spring IOC-定义解析器、IOC容器相关类
3 定义解析器相关类 3.1 BeanDefinitionReader接口 BeanDefinitionReader是用来解析配置文件并在注册表中注册bean的信息.定义了两个规范: 获取注册表的功能 ...
- 【杂绪】#4 & 【Diary】CSP-S1 2021 游记(慎) & CSP-S 备赛发狂日记
减少..减少掉 我没法同时做那么多事情了........ -------------------------------------------- 但是我\(\color{#EEEEEE}{真真切切地 ...
- 部署:mysql搭建多主一从源复制环境
问题描述:搭建过一主多从的环境,由于数据库数据一致性要求高,有些情景会搭建一主多从的架构,搭建多主一从的模式,相对来说适合数据整合,将多个业务的库整合到一起,方便做查询,也可以当做一个监控其他主库数据 ...
- JQuery点击复制文本框内容的方法插件
[导读] 文章介绍了两种常用的点击复制文本框内容方法,一种是but IE only,同样的这个也是我们经常使用的.优点是体积小,仅有十来行代码,但缺点也很明显,只支持IE及以IE为内核的浏览器,另一种 ...
- 【谷粒商城】(一)docker搭建以及项目的创建
网络地址转换-端口转发 VmWare网络配置可以参考这篇:VMWare虚拟机网络连接设置_santirenpc的博客-CSDN博客_vmware 上网设置,真的是被折磨到了.. Docker 虚拟化容 ...
- switch case 穿透 示例
public class SwitchCase { //判断输入的月份属于第几季度 public static void main(String[] args) { //随机获得 1-12个月份中的一 ...
- CopyOnWriteArrayList的使用和优缺点
CopyOnWriteArrayList允许并发读,读操作无锁,性能较高: 而写操作(含删除),比如向容器中添加/删除一个元素,则首先将当前容器复制一份,然后在新副本上执行写操作,结束之后再将原容器的 ...
- vue中使用西瓜视频api
https://v2.h5player.bytedance.com/en/api/ 1 npm install xgplayer 1 <div id="mse">< ...
加载之前使用默认数据
模拟加载真实数据后
运行时截图
option字体设置如图
定制柱状、折线、饼图图表
定制所需组件
下载定制的library
编译完成自动下载