ECharts.js 移動端顯示
現在很多時候,我們是在用手機、pad等一些移動端設備來進行辦公獲取數據。所以我們的圖表很多時候是需要用移動端設置來查看的,而我們的圖表有時候因為數據的偏多,會出現遮擋和重疊的情況。這個時候就需要對移動端的圖標顯示做一些優化,ECharts對於移動端的優化和支持主要有2個方面。
一、ECharts組件的定位和布局
組件的定位官方描寫的比較詳細也比較全,我的簡單理解為,ECharts.js對於圖表里面每個組件和工具都采用了兩種尺寸單位和設置固定位置。
一種是比較直接的 像素(px),設置的時間直接以 number 形式填寫。比如
title:{ text:'ECharts 數據統計', top:20 }
這里就是設置標題組件的距離上面的高度是20px。
還有一種是安裝百分比(%)的形式來設置的,百分比值是 string 類型,需要加上引號。比如
legend:{ data:['訪問量','用戶量'], left:'50%' }
這里標識legend組件的位置距離左側的距離是整個圖表的50%寬度
另外可以通過固定的值來設置所在位置,比如:
- 可以設置
left: 'center'
,表示水平居中。 - 可以設置
top: 'middle'
,表示垂直居中。
另外針對不同類型的圖標還有不同的定位方式。
布局這塊可以簡單歸結為兩種,一種是 橫向(horizontal)顯示,一種是 縱向(vertical)顯示。
二、ECharts自適應能力Media Query
Media Query 提供了『隨着容器的尺寸改變而改變』的能力。
option = { baseOption: { // 這里是基本的『原子option』。 title: {...}, legend: {...}, series: [{...}, {...}, ...], ... }, media: [ // 這里定義了 media query 的逐條規則。 { query: {...}, // 這里寫規則。 option: { // 這里寫此規則滿足下的option。 legend: {...}, ... } }, { query: {...}, // 第二個規則。 option: { // 第二個規則對應的option。 legend: {...}, ... } }, { // 這條里沒有寫規則,表示『默認』, option: { // 即所有規則都不滿足時,采納這個option。 legend: {...}, ... } } ] };
上面的例子中,baseOption
、以及 media
每個 option 都是『原子 option』,即普通的含有各組件、系列定義的 option。而由『原子option』組合成的整個 option,我們稱為『復合 option』。baseOption
是必然被使用的,此外,滿足了某個 query
條件時,對應的 option 會被使用 chart.mergeOption()
來 merge 進去。
多個 query 被滿足時的優先級:
注意,可以有多個 query
同時被滿足,會都被 mergeOption
,定義在后的后被 merge(即優先級更高)。
默認 query:
如果 media
中有某項不寫 query
,則表示『默認值』,即所有規則都不滿足時,采納這個option。
容器大小實時變化時的注意事項:
在不少情況下,並不需要容器DOM節點任意隨着拖拽變化大小,而是只是根據不同終端設置幾個典型尺寸。
但是如果容器DOM節點需要能任意隨着拖拽變化大小,那么目前使用時需要注意這件事:某個配置項,如果在某一個 query option
中出現,那么在其他 query option
中也必須出現,否則不能夠回歸到原來的狀態。(left/right/top/bottom/width/height
不受這個限制。)
『復合 option』 中的 media
不支持 merge
也就是說,當第二(或三、四、五 ...)次 chart.setOption(rawOption)
時,如果 rawOption
是 復合option
(即包含 media
列表),那么新的 rawOption.media
列表不會和老的 media
列表進行 merge,而是簡單替代。當然,rawOption.baseOption
仍然會正常和老的 option 進行merge。
其實,很少有場景需要使用『復合 option』來多次 setOption
,而我們推薦的做法是,使用 mediaQuery 時,第一次setOption使用『復合 option』,后面 setOption
時僅使用 『原子 option』,也就是僅僅用 setOption 來改變 baseOption
。
以上是EChart提供的關於移動端小屏幕自適應的方法,我另外提供一種方式
通過JS識別瀏覽器信息,然后根據所得的信息,設置圖表容器的尺寸,然后再結合EChart的media query更好的展示圖表
檢測是否為移動端的JS
var ismobile = false; var browser = { versions: function () { var u = navigator.userAgent, app = navigator.appVersion; return { trident: u.indexOf('Trident') > -1, //IE內核 presto: u.indexOf('Presto') > -1, //opera內核 webKit: u.indexOf('AppleWebKit') > -1, //蘋果、谷歌內核 gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐內核 mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/), //是否為移動終端 ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios終端 android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android終端或者uc瀏覽器 iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否為iPhone或者QQHD瀏覽器 iPad: u.indexOf('iPad') > -1, //是否iPad webApp: u.indexOf('Safari') == -1 //是否web應該程序,沒有頭部與底部 }; }(), language: (navigator.browserLanguage || navigator.language).toLowerCase() } ismobile = browser.versions.mobile;
這段代碼能夠識別大部分的移動端設備的瀏覽器信息,對於一些特殊的瀏覽器可能會存在缺陷
根據瀏覽器尺寸,設置圖表容器的大小
if (browser.versions.mobile) { window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", hengshuping, false); $("#chartmain").height(pageheight*0.6); $("#chartmain").width(pagewidth * 0.95); } else { $("#chartmain").height("500px"); $("#chartmain").width("700px"); } function hengshuping(){ if(window.orientation==180||window.orientation==0){ $("#chartmain").height($(window).height()-20); $("#chartmain").width("100%"); } if(window.orientation==90||window.orientation==-90){ $("#chartmain").height($(window).height()-20); $("#chartmain").width("100%"); } }
結合EChart的 Media Query 設置圖表參數
function init(){ ///折現報表實現代碼 var myChart = echarts.init(document.getElementById('chartmain')); option = { baseOption:{ title : { text: '奶牛數字化養殖報表', subtext: '西部電子數據采集' }, tooltip : { trigger: 'axis' }, legend: { data:['每日飼喂量','產奶量'] }, toolbox: { show : true, feature : { mark : {show: true}, dataView : {show: true, readOnly: false}, magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']}, restore : {show: true}, saveAsImage : {show: true} } }, calculable : true, xAxis : [ { type : 'category', boundaryGap : false, data : ['周一','周二','周三','周四','周五','周六','周日'] } ], yAxis : [ { type : 'value' } ], series : [ { name:'每日飼喂量', type:'line', smooth:true, itemStyle: {normal: {areaStyle: {type: 'default'}}}, data:[100, 200, 150, 130, 260, 830, 710] }, { name:'產奶量', type:'line', smooth:true, itemStyle: {normal: {areaStyle: {type: 'default'}}}, data:[30, 182, 216, 156, 390, 300, 356] } ] }, media:[ //media開始 { query:{}, option:{ title : { text: '奶牛數字化養殖報表', subtext: '西部電子數據采集' }, tooltip : { trigger: 'axis' }, legend: { data:['每日飼喂量','產奶量'] }, toolbox: { show : true, feature : { mark : {show: true}, dataView : {show: true, readOnly: false}, magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']}, restore : {show: true}, saveAsImage : {show: true} } }, calculable : true, xAxis : [ { type : 'category', boundaryGap : false, data : ['周一','周二','周三','周四','周五','周六','周日'] } ], yAxis : [ { type : 'value' } ], series : [ { name:'每日飼喂量', type:'line', smooth:true, itemStyle: {normal: {areaStyle: {type: 'default'}}}, data:[100, 200, 150, 130, 260, 830, 710] }, { name:'產奶量', type:'line', smooth:true, itemStyle: {normal: {areaStyle: {type: 'default'}}}, data:[30, 182, 216, 156, 390, 300, 356] } ] } }, { query:{maxWidth:400,ismobile:true}, option:{ title : { text: '奶牛數字化養殖報表', subtext: '西部電子數據采集' }, tooltip : { trigger: 'axis' }, legend: { data:['每日飼喂量','產奶量'], right: 'center', bottom: 0, orient: 'horizontal' }, toolbox: { show : true, orient:'vertical', feature : { mark : {show: true}, dataView : {show: true, readOnly: false}, magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']}, restore : {show: true}, saveAsImage : {show: true} } }, calculable : true, xAxis : [ { type : 'category', boundaryGap : false, data : ['周一','周二','周三','周四','周五','周六','周日'] } ], yAxis : [ { type : 'value' } ], series : [ { name:'每日飼喂量', type:'line', smooth:true, itemStyle: {normal: {areaStyle: {type: 'default'}}}, data:[100, 200, 150, 130, 260, 830, 710] }, { name:'產奶量', type:'line', smooth:true, itemStyle: {normal: {areaStyle: {type: 'default'}}}, data:[30, 182, 216, 156, 390, 300, 356] } ] } } //media結束 ] }; myChart.setOption(option); }