1. 程式人生 > >小程序引入多個e-charts

小程序引入多個e-charts

span 方式 this dex true list round nes ada

小程序引入e-charts圖表

這裏是狗尾草第一次發表掘金文章,日後望各位大佬多多支持~

前言:運營助手,見名知意,沒有圖表數據的展示,看上去是有多空白。因此,俺們UI做了很好的交互,一個頁面來了4個e-charts圖表,且基本都不一樣。身為一個職業前端,怎麽能猥瑣呢?

幹就完了~

實現思路

因為一個頁面要引入多個圖表,所以需要對e-charts圖表進行封裝。然鵝問題來了,怎麽引入呢?

為了兼容小程序 Canvas,ECharts提供了一個小程序的組件,用這種方式可以方便地使用 ECharts。插件下載地址

其中,ec-canvas 是ECharts提供的組件,其他文件是如何使用該組件的示例。

ec-canvas 目錄下有一個 echarts.js,默認ECharts會在每次 echarts-for-weixin 項目發版的時候替換成最新版的 ECharts。如有必要,可以自行從 ECharts 項目中下載最新發布版,或者從官網自定義構建以減小文件大小

這裏引入,我們只需要引入ec-canvas目錄到小程序項目即可。

單頁面引入

一個頁面只需要引入一個圖表的,我們在相關的js文件書寫即可。這樣引入比較簡單,也可以減少不必要的很多問題。但只限於一個頁面引入一個圖表 ,如果有一種情況,正如狗尾草所要完成的,一個頁面4個圖表,各不相同。則就需要封裝組件了

話不多說,直接擼~

index.json配置

 {
   "usingComponents": {
     "ec-canvas": "../../ec-canvas/ec-canvas"
   }
 }

index.wxml

 <view class="container">
   <ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
 </view>

index.js

 
function initChart(canvas, width, height) {
   const chart 
= echarts.init(canvas, null, { width: width, height: height }); canvas.setChart(chart); ? var option = { ... }; chart.setOption(option); return chart; } ? Page({ data: { ec: { onInit: initChart } } });

以上為單頁面引入圖表,需要註意的是,

  1. 引入文件的路徑,改成自己項目中的實際路徑。

  1. option配置可查看e-charts官方文檔按需配置。

  2. 小程序的層級因為是原生組件,所以小程序的層級無法修改。

  3. 由於原生組件脫離在 WebView 渲染流程外,因此在使用時有以下限制: 組件的層級是最高的,所以頁面中的其他組件無論設置 z-index 為多少,都無法蓋在原生組件上。 後插入的原生組件可以覆蓋之前的原生組件。 原生組件還無法在 scroll-view、swiper、picker-view、movable-view 中使用。 部分CSS樣式無法應用於原生組件,例如: 無法對原生組件設置 CSS 動畫 無法定義原生組件為 position: fixed 不能在父級節點使用 overflow:hidden 來裁剪原生組件的顯示區域,

因此在使用時,可能遇到這個問題,圖表的層級很高,而且不會跟隨屏幕滾動。大概就是以上原因造成的。

這裏狗尾草的解決是通過修改布局。因為這裏本人造成圖表不隨屏幕滾動的原因是采用了,聖杯布局。因此在將聖杯布局去掉後。采用本來的默認布局,就修改了這個問題。

雖然問題得到了解決,但需求比較急,還沒有查找到完美的解決方案,小夥伴有的話,可以告知一下,在這裏先說一聲謝謝啦~

引入多個圖表

狗尾草的完成,頁面引入多個圖表,如果還如上面所示,在單頁面中引入多個方法,配置會更加復雜。

這裏,需要引入豎向柱狀圖,橫向柱狀圖,餅狀圖。

因此將每個類型的圖標單獨放到一個組件中,在需要引入的頁面只引入這些個組件就夠。

在父組件得到數據後,將數據傳入子組件。子組件更新view即可。但是會遇到這麽一個問題

子組件在得到傳遞的值後,並不會更新view。因此狗尾草是通過修改引入的ec-canvas組件來完成視圖的更新。

聽著可能有點懵逼,理一下。

  1. 父組件給子組件傳遞數據

  2. 子組件做視圖的option配置

  3. 源碼組件接受數據

大概就是這麽個意思

先來看一下目錄結構

技術分享圖片

技術分享圖片

這裏只給大家引用一下餅狀圖

父組件

Wxml

 <view class=‘echarts-department‘>
     <echarts-depart oData="{{echarts.departNumber}}"></echarts-depart>
 </view>

Wxss

 .echarts-department {
   width: 100%;
   height: 498rpx;
 }

Json

 {
   "usingComponents": {
     "echarts-depart": "/components/eChartsSubDepartment/index"
   }
 }

Js

 
// 數據日報
 const $api = require(‘../../api/index.js‘);
 const $util = require(‘../../utils/utils.js‘);
 const regeneratorRuntime = require(‘../../utils/runtime.js‘);
 Page({
   onShareAppMessage: function (res) {
     return {
       title: ‘數據日報‘,
       path: ‘/pages/eCharts/index‘,
       success: function () { },
       fail: function () { }
     }
   },
   data: {
     subParams: {
       distCode: "",
       beginTime: $util.formatDate(new Date()),
       endTime: $util.formatDate(new Date())
     }, //獲取除過審醫生數外的其他的所有api params
     echarts: {
       departNumber: [],
     }               //圖標傳入的數據
   },
   // 獲取二級科室診療統計
   getDepartNumber() {
     $api.DATADAILY.getDepartNumber(this.data.subParams)
     .then(res => {
       if(res.length == 0) {
         this.setData({
           "echarts.departNumber": [{name:‘‘,value:‘‘}]
         })
         return ;
       }
       let arr = [];
       res.map(item => {
         let obj = {};
         obj.value = item.count;
         obj.name = item.date;
         arr.push(obj);
       })
       this.setData({
         "echarts.departNumber":arr
       })
     })
   },
   onReady() {
     this.getDepartNumber();      //獲取二級科室診療總排行
   },
 });

這裏就是父組件的引入

封裝的子組件

wxml

 <!-- 數據日報 二級科室診療排行 -->
 <view class=‘box‘>
   <ec-canvas id="mychart-dom-bar" oData = "{{oData}}" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
 </view>

需要註意的是oData就是傳遞過來的數據

wx.json

 {
   "component": true,
   "usingComponents": {
     "ec-canvas": "/ec-canvas/ec-canvas"
   }
 }

js

 
// 數據日報 二級科室診療統計
 // 1、引入依賴腳本
 import * as echarts from ‘../../ec-canvas/echarts‘;
 ?
 let chart = null;
 // 2、進行初始化數據
 function initChart(canvas, width, height,data) {
   chart = echarts.init(canvas, null, {
     width: width,
     height: height
   });
   canvas.setChart(chart);
 ?
   var option = {
     tooltip: {
       position: function (px) {
         return [px[0], ‘20%‘];
       }
     },
     color: [‘#48C6EB‘, ‘#60E3CA‘, ‘#5E9ED5‘, ‘#9F9FF5‘, ‘#72C7FD‘],
     grid: {
       x: 0,
       y: 0,
       x2: 0,
       y2: 0
     }, //圖標距離上下左右的距離
     series: [{
       // name: ‘pie‘,
       type: ‘pie‘,
       // selectedMode: ‘single‘, //點擊的時候是否區域進行分離
       // selectedOffset: 30, //區域分離的距離
       clockwise: true,
       label: {
         normal: {
           show: false,
           textStyle: {
             fontSize: ‘14px‘,
             color: ‘#333333‘
           },
           // backgroundColor: ‘#061F3D‘,
         }
       },
       // labelLine: {
       //   normal: {
       //     lineStyle: {
       //       color: ‘#999999‘
       //     }
       //   }
       // }, //label線條的顏色
       data: data,
       itemStyle: {
         normal: {
           borderWidth: 2,
           borderColor: ‘#ffffff‘,
           opacity: .7
         }
       }
     }]
   };
 ?
   chart.setOption(option);
   return chart;
 }
 ?
 ?
 Component({
   /**
    * Component properties
    */
   properties: {
     oData: {
       type: Array,
       value: [],
       observer: function (newVal, oldVal, changedPath) {
         // 屬性被改變時執行的函數(可選),也可以寫成在methods段中定義的方法名字符串, 如:‘_propertyChange‘
         // 通常 newVal 就是新設置的數據, oldVal 是舊數據
       }
     }
   },
 ?
   /**
    * Component initial data
    */
   data: {
     ec: {
       onInit: initChart // 3、將數據放入到裏面
     }
   },
 ?
   /**
    * Component methods
    */
   methods: {
   },
 })
 

需要修改的源碼組件

ec-canvas > ec-canvas.js

 
 properties: {
     canvasId: {
       type: String,
       value: ‘ec-canvas‘
     },
 ?
     ec: {
       type: Object
     },
     oData: {
       type: Object,
       observer: function(newVal,oldVal) {
         if(newVal.length == 0) {
           return ;
         }
         this.init();
       }
     } //oData為父傳子,子傳這裏
   },

在這裏將傳的數據作為參數

技術分享圖片

啊,噗~

至此,一條數據流就算完成。其他類型的圖標也按照這種方式引入即可

補充,讓小程序支持ES7

因為引入多個圖表的話,更多的需要控制順序,因此,這裏給大家補充一下ES7的引入

 npm install regenerator

引用:

const regeneratorRuntime = require(‘../../libs/regenerator-runtime‘)

這裏就可以放心使用async和await來控制api請求的順序了。

當然大家可以引入相關的js文件也是可以的。

技術分享圖片

小程序引入多個e-charts