微信小程序Echarts動態(tài)使用及圖表層級踩坑解決方案
前言
最近收到一個需求,要在小程序上去做數(shù)據(jù)看板,能讓公司運營和老板看到那些銷售的數(shù)據(jù)情況。

這就導(dǎo)致需要我去重新?lián)炱餎charts了,距離上一次用它還是五年前了吧。
不過好在現(xiàn)在的Echarts已經(jīng)能很好的適配微信小程序了,不需要處理一些額外的bug,只需要看著官方的案例和文檔去做就行。
但是,官方給的Echarts示例都是簡易的、靜態(tài)的,數(shù)據(jù)也都是固定的,還得需要自己去做動態(tài)適配,在做的過程中,還發(fā)現(xiàn)了當(dāng)使用Vant組件彈出層置頂?shù)臅r候,底部的Echarts圖的層級會蓋住彈出層的層級。
查了Echarts文檔和微信小程序文檔之后,發(fā)現(xiàn)Echarts是用canvas去繪制的,而小程序中原生的canvas組件層級是最高的。
介紹一下Echarts for weixin
- Echarts-for-weixin是一種數(shù)據(jù)可視化庫,可以幫助開發(fā)者為微信小程序創(chuàng)建交互式圖表和圖形。
- 它是Echarts庫的一個子集,專門為Web應(yīng)用程序設(shè)計而來。
- Echarts-for-weixin為開發(fā)者提供了一個簡單易用的界面,以創(chuàng)建可自定義的圖表和圖形,可以嵌入微信小程序中。
- 它支持許多不同類型的圖表,包括折線圖、柱狀圖、餅圖、散點圖等等。
導(dǎo)入源碼
通過倉庫里面的介紹,我們可以直接下載代碼,并導(dǎo)入到微信開發(fā)者工具中。(以下是導(dǎo)入后并運行起來的效果)


可以看到圖表示例中包含了所有常用的Echarts實例,并且根據(jù)小程序的特性,給出了延遲加載、單頁面多圖表、頁面阻塞、保存文件等實例。
文件夾
- ec-canvas:我們需要復(fù)制到自己項目中,作為一個子組件去使用的文件。
- pages:可以根據(jù)當(dāng)前圖表示例查看對應(yīng)的源碼文件
需要注意的是,官方示例中的ec-canvas文件中包含了所有圖表代碼,我們可以根據(jù)自己的需求去自定義構(gòu)建圖表,從而降低代碼的大小。點擊進入自定義圖表鏈接
了解源碼
我們可以隨意打開一個示例圖表,點擊開發(fā)工具下方的頁面路徑,可以進入到對應(yīng)圖表的js文件中。
- 我打開了一個餅狀圖示例

- 根據(jù)官方提供的源碼,我們可以看到定義的內(nèi)容如下:
<view class="container">
<ec-canvas id="mychart-dom-pie" canvas-id="mychart-pie" ec="{{ ec }}"></ec-canvas>
</view>
- 在頁面上使用 ec-canvas 組件,需要定義 canvas 的id 和 ec(會在js中定義 ec)
import * as echarts from '../../ec-canvas/echarts';
const app = getApp();
function initChart(canvas, width, height, dpr) {
const chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: dpr // new
});
canvas.setChart(chart);
var option = {
backgroundColor: "#ffffff",
series: [{
label: {
normal: {
fontSize: 14
}
},
type: 'pie',
center: ['50%', '50%'],
radius: ['20%', '40%'],
data: [{
value: 55,
name: '北京'
}, {
value: 20,
name: '武漢'
}, {
value: 10,
name: '杭州'
}, {
value: 20,
name: '廣州'
}, {
value: 38,
name: '上海'
}]
}]
};
chart.setOption(option);
return chart;
}
Page({
data: {
ec: {
onInit: initChart
}
}
});
- 首行import表示引入當(dāng)前 ec-canvas 組件
- initChart方法用于定義canvas、echarts中的option的內(nèi)容,并渲染到canvas上
- 在data中定義了一個ec的對象,里面的 onInit 引入上面的 initChart 方法
動態(tài)Echarts for weixin
通過閱讀不同的Echarts示例源碼,我們只是了解了Echarts在小程序中的使用過程,但是我們在實際運用中,是需要和后端進行接口對接等動態(tài)操作數(shù)據(jù)的。
動態(tài)的過程,對于頁面上組件其實是不需要改動的,可以直接按照官方示例去寫。我們只需要修改小程序中 js 的邏輯即可。
- 下面是以折線圖為例去實現(xiàn)動態(tài)效果
<view class="echarts_wrapper">
<ec-canvas id="data-trend-chart" canvas-id="data-trend-chart" ec="{{ ecTrend }}"></ec-canvas>
</view>
這里需要注意的是,需要在 ec-canvas 外面包一層元素,并指定寬高,否則 canvas 會無法渲染出來。
data: {
ecTrend: { // echarts初始化
lazyLoad: true
},
}
- 需要在data 中定義一個值
ecTrend和頁面中的 ec 對應(yīng) - 將 lazyLoad 設(shè)為 true 后,需要手動初始化圖表(即懶加載)
/**
* 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
*/
onReady() {
// 初始化數(shù)據(jù)趨勢 echarts
this.ecDataTrendComponent = this.selectComponent('#data-trend-chart');
this.getTrend()
}
- 既然需要手動初始化,那么我們就需要在進入頁面時的生命周期中進行初始化
- selectComponent 中對應(yīng)頁面中的canvas id(id是頁面中唯一值,如果有多個圖表時,不可重復(fù))
- getTrend 是用來讀取接口數(shù)據(jù)的方法(下面會使用 setTimeout 去代替接口請求)
getTrend() {
setTimeout(() => {
// 初始化完成之后,直接獲取后臺數(shù)據(jù)進行繪制canvas
this.ecDataTrendComponent.init((canvas, width, height, dpr) => {
// 獲取組件的 canvas、width、height 后的回調(diào)函數(shù)
// 在這里初始化圖表
const chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: dpr // new
});
let xAxis = ["3.1","3.2","3.3","3.4","3.5","3.6","3.7","3.8","3.9","3.10","3.11","3.12","3.13","3.14","3.15","3.16","3.17","3.18","3.19","3.20","3.21","3.22","3.23","3.24","3.25","3.26","3.27","3.28","3.29","3.30","3.31"]
let series = [{"data":[0,0,0,0,0,0,0,0,1,0,0,0,0,17],"name":"單量","type":"line"}]
// 將后臺的值傳遞給 setTrendOption 方法
setTrendOption(chart, xAxis, series);
// 將圖表實例綁定到 this 上,可以在其他成員函數(shù)(如 dispose)中訪問
this.ecDataTrendChart = chart;
// 注意這里一定要返回 chart 實例,否則會影響事件處理等
return chart;
});
}, 0)
},
- init方法和官方源碼中的示例差不多,就是用來定義canvas中的值,并將接口中獲取到的數(shù)據(jù)傳遞給外部定義的方法中。
- setTrendOption 中傳入了當(dāng)前實例,和兩個參數(shù)(參數(shù)均由后端接口返回,此處定義成靜態(tài)數(shù)據(jù))
- 最后將初始化圖表的實例綁定并返回。
這里需要注意一下,必須要返回實例,否則頁面上無法渲染出圖表數(shù)據(jù)
function setTrendOption(chart, xAxis, series) {
const option = {
tooltip: {
show: true,
trigger: 'axis'
},
grid: {
top: '10',
left: '5',
right: '5',
bottom: '10',
containLabel: true
},
toolbox: {
show: false
},
xAxis: {
type: 'category',
boundaryGap: false,
data: xAxis
},
yAxis: {
type: 'value'
},
series: series
};
chart.setOption(option);
}
- setTrendOption 方法需要定義在 Page 方法外部
- xAxis 接收到的參數(shù)用于定義 X 坐標(biāo)軸的 data
- series 接收到的參數(shù)直接用于它本身即可
后端接口返回的數(shù)據(jù)可能有差異,可以根據(jù)不同的參數(shù)進行適配(具體參數(shù)可參見Echarts官方文檔說明)
數(shù)據(jù)展示
根據(jù)上方代碼,我們可以生成對應(yīng)的數(shù)據(jù)圖表


踩坑系列(持續(xù)更新)
圖表層級

當(dāng)我們點擊日期彈出層時,會發(fā)現(xiàn)數(shù)據(jù)趨勢的圖表層級置于最頂端了,那么我們就需要對圖表的層級進行修改。
由于小程序的限制,原生組件的層級是頂級的且無法修改的,那么我們就只能對圖表進行顯示和隱藏操作。
wx:if vs hidden (此部分是在微信官方文檔中摘錄)
因為
wx:if之中的模板也可能包含數(shù)據(jù)綁定,所以當(dāng)wx:if的條件值切換時,框架有一個局部渲染的過程,因為它會確保條件塊在切換時銷毀或重新渲染。同時
wx:if也是惰性的,如果在初始渲染條件為false,框架什么也不做,在條件第一次變成真的時候才開始局部渲染。相比之下,
hidden就簡單的多,組件始終會被渲染,只是簡單的控制顯示與隱藏。一般來說,
wx:if有更高的切換消耗而hidden有更高的初始渲染消耗。因此,如果需要頻繁切換的情景下,用hidden更好,如果在運行時條件不大可能改變則wx:if較好。
根據(jù)微信文檔中的說明,我們不需要使用 wx:if,可以使用 hidden 來代替。
<view class="echarts_wrapper" hidden="{{calendarShow}}">
<ec-canvas id="data-trend-chart" canvas-id="data-trend-chart" ec="{{ ecTrend }}"></ec-canvas>
</view>
- 我們可以在 ec-canvas 外部包裹的層級元素中使用
hidden來定義canvas顯示和隱藏 - 當(dāng) calendarShow 為 true 時,則是日歷彈出層顯示的時候,此時就需要隱藏 canvas 元素

總結(jié)
此文主要是記錄 Echarts-for-weixin 的使用過程,通過官方的靜態(tài)源碼衍生出動態(tài)使用方式。
在開發(fā)過程中有很多避免不了的坑需要去踩,仔細(xì)研究一下官方文檔,可以解決大部分的坑。
以上就是微信小程序Echarts動態(tài)使用及圖表層級踩坑解決方案的詳細(xì)內(nèi)容,更多關(guān)于微信小程序Echarts動態(tài)圖表層級的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue3如何使用vant-picker封裝省市二級聯(lián)動
這篇文章主要介紹了vue3如何使用vant-picker封裝省市二級聯(lián)動,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
vue用Object.defineProperty手寫一個簡單的雙向綁定的示例
這篇文章主要介紹了用Object.defineProperty手寫一個簡單的雙向綁定的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Vue使用高德地圖搭建實時公交應(yīng)用功能(地圖 + 附近站點+線路詳情 + 輸入提示+換乘詳情)
這篇文章主要介紹了vue中使用高德地圖搭建實時公交應(yīng)用(地圖 + 附近站點+線路詳情 + 輸入提示+換乘詳情),主要是讓大家熟悉下高德地圖在vue中的使用及vue的常用指令,需要的朋友可以參考下2018-05-05
前端Vue數(shù)據(jù)不更新問題的深入分析與解決方案
在前端開發(fā)中,Vue.js 是一個非常流行的 JavaScript 框架,它以其簡潔的語法和強大的響應(yīng)式系統(tǒng)而聞名,然而,盡管 Vue 的響應(yīng)式系統(tǒng)非常強大,但在實際開發(fā)中,開發(fā)者仍然可能會遇到數(shù)據(jù)不更新的問題,本文將深入探討 Vue 數(shù)據(jù)不更新的常見原因,并提供詳細(xì)的解決方案2025-03-03
關(guān)于Nuxt的五種渲染模式的差異和使用場景全解析
這篇文章主要介紹了關(guān)于Nuxt的五種渲染模式的差異和使用場景全解析,在過去傳統(tǒng)開發(fā)中,頁面渲染任務(wù)是由服務(wù)端完成的,那么Nuxt是如何渲染的呢,需要的朋友可以參考下2023-04-04

