小程式引入多個e-charts圖表

Csun發表於2019-02-26

小程式引入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. 引入檔案的路徑,改成自己專案中的實際路徑。

  2. option配置可檢視e-charts官方文件按需配置。

  3. 小程式的層級因為是原生元件,所以小程式的層級無法修改。

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

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

這裡狗尾草的解決是通過修改佈局。因為這裡本人造成圖表不隨螢幕滾動的原因是採用了,聖盃佈局。因此在將聖盃佈局去掉後。採用本來的預設佈局,就修改了這個問題。

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

引入多個圖表元件

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

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

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

在父元件得到資料後,將資料傳入子元件。子元件更新view即可。但是會遇到這麼一個問題

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

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

  1. 父元件給子元件傳遞資料
  2. 子元件做檢視的option配置
  3. 原始碼元件接受資料

大概就是這麼個意思

先來看一下目錄結構 juejin.im1.png

小程式引入多個e-charts圖表
這裡只給大家引用一下餅狀圖

父元件

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就是傳遞過來的資料 wxss

/* 資料日報 二級科室診療統計 */
.box {
	width:100%;
	height:100%;
  font-size: 14px!important;
}
複製程式碼

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為父傳子,子傳這裡
  },
複製程式碼

在這裡將傳的資料作為引數 juejim.im2.png

小程式引入多個e-charts圖表
打完,收工~ 至此,一條資料流就算完成。其他型別的圖示也按照這種方式引入即可

補充,讓小程式支援ES7

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

npm install regenerator
複製程式碼

引用:

const regeneratorRuntime = require('../../libs/regenerator-runtime')
複製程式碼

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

當然大家可以引入相關的js檔案也是可以的。百度上很多就不在此說明了。

狗尾草的網站剛剛搭建完成,有興趣的可以參觀一下。www.bgwhite.cn或 百度搜尋狗尾草的前端部落格,剩餘的其他文章,狗尾草的部落格園也都有說明,百度搜尋狗尾草的部落格。

相關文章