響應式 React Native Echarts 組件

一種在 React Native 中封裝的響應式 Echarts 組件,使用與示例請參見: react-native-echarts-demo

近年來,隨着移動端對數據可視化的要求愈來愈高,相似 MPAndroidChart 這樣的傳統圖表庫已經不能知足產品經理日益變態的需求。前端領域數據可視化的發展相對繁榮一些,經過 WebView 在移動端使用 Echarts 這樣功能強大的前端數據可視化庫,是解決問題的好辦法。html

React Native 開發中,因爲使用的是與前端相同的 JavaScript 語言,銜接 Echarts 的工做相對順暢些,不過一些必要的組件封裝仍是可以大大提升開發效率的。前端

Echarts 官方推薦過一個第三方封裝庫:react-native-echarts(注:它對應的 nmp package 名字爲 native-echarts ),目前有 400+ stars 和 100+ 的周下載量,可見仍是被普遍使用的。可是咱們通過調研,發現 react-native-echarts 存在如下一些問題:react

  • 該庫已半年多未更新,Echarts 版本停留在 3.0 ,Android 端打包需手動添加 assets 的問題也一直未處理
  • 庫的接口靈活度較低,好比只能經過 width、height 設置大小;沒法使用 Echarts 擴展包;沒法進行事件註冊、WebView 通訊等

因爲用 WebView 封裝 Echarts 涉及到本地 html,不是純 JavaScript 語言層面的功能,又沒有 native 代碼,因此作成 nmp package 並非一個很好的選擇,寫成項目裏的內部組件,本身進行配置反而是更方便更靈活的方案。android

所以咱們決定不使用第三方的 Echarts 封裝庫,本身寫一個通用組件 WebChart 。爲方便開發中使用,該組件具備如下特色:ios

  • 按照響應式進行設計,只需在 option 中配置好數據源,數據變化後圖表就會自動刷新,更符合 React 的風格。

    咱們的方案是在組件每次 update 時判斷傳入的 option 參數是否發生變化,若是變化經過 webView.postMessage ,以 JSON 的形式傳入新的 option ,通知 Echarts 從新 setOption 。git

    雖然 Echarts 自己會對 option 進行對比,但事先判斷能夠減小 update 致使的與 WebView 頻繁通訊,這一點在容器父組件中有大量異步請求時仍是很明顯的;在 WebView 內部,更新則是採用 Echarts 自己的 setOption 而無需 reload 整個 WebViewgithub

  • 利用 WebView 的 postMessage 和 onMessage 接口,可實現圖表與其它 React Native 組件的事件通訊
  • 經過組件的 exScript 參數,可爲 WebView 添加任意腳本,使用靈活
  • 因爲是本身寫的組件, echarts 版本、擴展包,svg/canvas 、數據增量加載均可以本身設定

Demo 與使用方法

使用與示例請參見:react-native-echarts-demo,若是你須要直接使用,可按如下步驟移植:web

  1. 將根目錄下的 WebChart 組件文件夾拷到你項目中合適的地方
  2. 將 /android/app/src/main/assets/web 文件夾拷到你項目一樣位置,沒有 assets 文件夾需手動建立。

只需以上兩步就能夠在項目中使用 WebChart 組件了。npm

若是須要進一步定製的話,Echarts 代碼在以上兩個文件夾中的 index.html 裏 <script /> 標籤內,目前是放的是 4.0 完整版,無擴展包,可到官網下載所需的版本和擴展包替換;svg/canvas 、數據增量加載等可在 WebChart/index.js 中直接進行修改。在移動端,出於性能的考慮,咱們通常使用 svg 的渲染模式。canvas

WebChart 具體使用可參見 App.js ,style 的設置就和普通的 React Native 組件同樣,可以使用 flex ,也可設爲定值。額外的三個參數:

  • option(object):賦給 setOption 的參數對象,發生變化後 WebChart 內部會自動調用 setOption ,實現響應式刷新。特別注意,JSON 解析時未進行函數的處理,因此需避免使用函數式的 formatter 和類形式的 LinearGradient ,和 demo 同樣使用模板式和普通對象的吧
  • exScript(string):任何你想在 WebView 加載時執行的代碼,通常會是事件註冊之類的,推薦使用模板字面量
  • onMessage(function):WebView 內部觸發 postMessage 以後的回調,postMessage 需先在 exScript 中進行設置,用於圖表與其它 React Native 組件的通訊

固然這是根據咱們的業務須要設計的參數,你徹底能夠自由從新設定。

Echarts與React Native組件的通訊

在 React Native 的 WebView 組件中,提供了 onMessage 和 postMessage 來進行 html 與組件的雙向通訊,具體使用可參加文檔。

利用 webView.postMessage ,WebChart 實現了通知 Echarts 執行 setOption ;在 exScript 中,可利用 window.postMessage 實現 Echarts 的事件向 React Native 組件的通訊。

通常咱們會約定通訊的 data 爲這樣格式的對象:

{
  type: 'someType',
  payload: {
      value: 111,
  },
}

因爲 onMessage 和 postMessage 只能進行字符串的傳遞,在 exScript 需進行 JSON 序列化,相似這樣:

exScript={`
  chart.on('click', (params) => {
    if(params.componentType === 'series') {
      window.postMessage(JSON.stringify({
        type: 'select',
        payload: {
            index: params.dataIndex,
        },
      }));
    }
  });
`}

以上就是咱們封裝的響應式 WebChart 組件及使用,完整代碼請參見:react-native-echarts-demo

在使用中,還有如下幾個坑未解決,目前只能繞過,歡迎知道的同窗指正:

  • 在 IOS 中,Echarts 好像渲染不出透明的效果,用 rgba 設置的顏色不能正常
  • React Native 的 WebView 好像 style.height 屬性無效,所以不得不在外面套了個 View
  • 按如今的資源加載方式,index.html 在 Android 上會有兩份。由於平臺判斷是運行時進行的,哪怕分開設置 index.anroid.js 和 index.ios.js 打包時也會都打包進去,而 Android 中又必須手動添加 assets
  • index.html 中必須內聯引入 Echarts 的代碼,外部引用單獨的 js 文件好像無效
相關文章
相關標籤/搜索