React魔法堂:echarts-for-react源碼略讀

前言在當前工業4.0和智能制造的產業升級浪潮當中,智慧大屏無疑是展示企業IT成果的最有效方式之一 。然而其背后怎么能缺少ECharts的身影呢?對于React應用而言,直接使用ECharts并不是最高效且優雅的方式,而echarts-for-react則是針對React應用對ECharts進行輕量封裝和增強的工具庫 。
echarts-for-react的源碼非常精簡,本文將針對主要邏輯分析介紹 。
從與原生初始化對比開始原生ECharts中我們會通過如下代碼初始化圖表實例
【React魔法堂:echarts-for-react源碼略讀】<div id="container" style="width: 100px; height: 100px"></div><script>const chart = echarts.init(document.getElementById('container'))</script>那么生成的HTML Element結構為
<div id="container" style="width: 100px; height: 100px" _echarts_instance="....."><div style="width: 100px; height: 100px;position: relative;"><canvas width="100" height="100"></canvas></div></div>其中第二層的div和canvas的寬高默認為容器div#container的寬高,我們可以通過init入參指定兩者寬度 。
const chart = echarts.init(document.getElementById('container'),null,{width: 300, // 可顯式指定實例寬度,單位為像素 。如果傳入值為null/undefined/'auto',則表示自動取 dom(實例容器)的寬度height: 300 // 可顯式指定實例高度,單位為像素 。如果傳入值為null/undefined/'auto',則表示自動取 dom(實例容器)的高度})注意:若此時容器div#container尺寸發生變化,第二層div和canvas尺寸并不會自適應,需要我們手工調用chart.resize()觸發 。
而通過echarts-for-react上述步驟將被簡化為如下,并且生成相同的HTML Element結構:
import ReactECharts from 'echarts-for-react'function Demo() {return (<ReactEChartsstyle={{width: 100, height: 100}} // 設置容器的寬高autoResize={true} // 默認為true,自動監測容器尺寸的變化 , 并調用`chart.resize()`/>)}陷阱-默認值height為300px由于ReactEChartsstyle默認內置height: 300,源碼如下:
// src/core.tsxrender(): JSX.Element {const { style, className = '' } = this.propsconst newStyle = { height: 300, ...style }return (<divref={(e: HTMLElement) => {this.ele = e}}style={newStyle}className={`echarts-for-react ${className}`}/>)}因此通過className的方式設置容器高度時必須使用!important
<ReactEChartsclassName={styles.container}/>// index.module.css.container {height: 500px !important;}獲取ECharts實例const ref = useRef()useEffect(() => {const instance = ref.current.getEchartsInstance()}, [])<EchartsReactref={ref}/>主邏輯源碼剖析核心邏輯均在EChartsReactCore組件上(位于文件src/core.tsx),特點如下:

  1. 采用PureComponent方式編寫組件以便適配所有React版本;
  2. 僅對ECharts 命令式API進行聲明式API的封裝,并沒有將每種EChart圖表類型封裝為組件;
  3. 添加特性 , 監測容器尺寸的變化,并自動調用ECharts實例的resize方法實現自適應 。
掛載渲染過程
  1. componentDidMount時調用renderNewEcharts方法執行ECharts組件的生成邏輯;
  2. renderNewEcharts方法內部邏輯
    1. 通過echarts.getInstanceByDom(容器DOM元素)echarts.init(容器DOM元素,主題,配置)獲取已有ECharts實例或生成新的ECharts實例;
    2. 通過ECharts實例的setOption方法設置或更新圖表內容;
    3. 通過ECharts實例的showLoadinghideLoading控制圖表渲染前是否顯示加載進度條;
    4. 將通過props onEvents配置的ECharts支持的事件處理器綁定到ECharts實例上;
    5. 觸發props onChartsReady 方法;
    6. 訂閱通過size-sensor監測容器尺寸并自動調用ECharts實例的resize方法,實現圖表尺寸的自適應 。
更新渲染過程由于render方法無論執行多少遍,實際上僅僅有可能影響容器本身而已,對ECharts實例并沒有任何影響 。因此實際影響ECharts實例的邏輯被放置到componentDidUpdate那里,這做法和react-amap中在useEffect中通過Marker等實例內置的set方法更新狀態的原理是一致的 。
  1. 若更新的props包含theme, optsonEvents則要銷毀原來的ECharts實例,重新構建一個新的ECharts實例,并終止更新渲染過程;否則執行第2步 。
  2. 若props中的option

    推薦閱讀