React之echarts-for-react源碼解讀
前言
在當(dāng)前工業(yè)4.0和智能制造的產(chǎn)業(yè)升級浪潮當(dāng)中,智慧大屏無疑是展示企業(yè)IT成果的最有效方式之一。然而其背后怎么能缺少ECharts的身影呢?對于React應(yīng)用而言,直接使用ECharts并不是最高效且優(yōu)雅的方式,而echarts-for-react則是針對React應(yīng)用對ECharts進(jìn)行輕量封裝和增強(qiáng)的工具庫。
echarts-for-react的源碼非常精簡,本文將針對主要邏輯分析介紹。
從與原生初始化對比開始
原生ECharts中我們會通過如下代碼初始化圖表實(shí)例
<div id="container" style="width: 100px; height: 100px"></div> <script> const chart = echarts.init(document.getElementById('container')) </script>
那么生成的HTML Element結(jié)構(gòu)為
<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的寬高默認(rèn)為容器div#container的寬高,我們可以通過init入?yún)⒅付▋烧邔挾取?/p>
const chart = echarts.init( document.getElementById('container'), null, { width: 300, // 可顯式指定實(shí)例寬度,單位為像素。如果傳入值為null/undefined/'auto',則表示自動取 dom(實(shí)例容器)的寬度 height: 300 // 可顯式指定實(shí)例高度,單位為像素。如果傳入值為null/undefined/'auto',則表示自動取 dom(實(shí)例容器)的高度 } )
注意:若此時(shí)容器div#container尺寸發(fā)生變化,第二層div和canvas尺寸并不會自適應(yīng),需要我們手工調(diào)用chart.resize()
觸發(fā)。
而通過echarts-for-react上述步驟將被簡化為如下,并且生成相同的HTML Element結(jié)構(gòu):
import ReactECharts from 'echarts-for-react' function Demo() { return ( <ReactECharts style={{width: 100, height: 100}} // 設(shè)置容器的寬高 autoResize={true} // 默認(rèn)為true,自動監(jiān)測容器尺寸的變化,并調(diào)用`chart.resize()` /> ) }
陷阱-默認(rèn)值height為300px
由于ReactECharts
的style
默認(rèn)內(nèi)置height: 300
,源碼如下:
// src/core.tsx render(): JSX.Element { const { style, className = '' } = this.props const newStyle = { height: 300, ...style } return ( <div ref={(e: HTMLElement) => { this.ele = e }} style={newStyle} className={`echarts-for-react ${className}`} /> ) }
因此通過className的方式設(shè)置容器高度時(shí)必須使用!important
<ReactECharts className={styles.container} />
// index.module.css .container { height: 500px !important; }
獲取ECharts實(shí)例
const ref = useRef() useEffect(() => { const instance = ref.current.getEchartsInstance() }, []) <EchartsReact ref={ref} />
主邏輯源碼剖析
核心邏輯均在EChartsReactCore
組件上(位于文件src/core.tsx
),特點(diǎn)如下:
- 采用PureComponent方式編寫組件以便適配所有React版本;
- 僅對ECharts 命令式API進(jìn)行聲明式API的封裝,并沒有將每種EChart圖表類型封裝為組件;
- 添加特性,監(jiān)測容器尺寸的變化,并自動調(diào)用ECharts實(shí)例的
resize
方法實(shí)現(xiàn)自適應(yīng)。
掛載渲染過程
- 在
componentDidMount
時(shí)調(diào)用renderNewEcharts
方法執(zhí)行ECharts組件的生成邏輯; renderNewEcharts
方法內(nèi)部邏輯通過
echarts.getInstanceByDom(容器DOM元素)
或echarts.init(容器DOM元素,主題,配置)
獲取已有ECharts實(shí)例或生成新的ECharts實(shí)例;通過ECharts實(shí)例的
setOption
方法設(shè)置或更新圖表內(nèi)容;通過ECharts實(shí)例的
showLoading
或hideLoading
控制圖表渲染前是否顯示加載進(jìn)度條;將通過props
onEvents
配置的ECharts支持的事件處理器綁定到ECharts實(shí)例上;觸發(fā)props
onChartsReady
方法;訂閱通過size-sensor監(jiān)測容器尺寸并自動調(diào)用ECharts實(shí)例的
resize
方法,實(shí)現(xiàn)圖表尺寸的自適應(yīng)。
更新渲染過程
由于render
方法無論執(zhí)行多少遍,實(shí)際上僅僅有可能影響容器本身而已,對ECharts實(shí)例并沒有任何影響。因此實(shí)際影響ECharts實(shí)例的邏輯被放置到componentDidUpdate
那里,這做法和react-amap中在useEffect
中通過Marker等實(shí)例內(nèi)置的set
方法更新狀態(tài)的原理是一致的。
- 若更新的props包含
theme
,opts
或onEvents
則要銷毀原來的ECharts實(shí)例,重新構(gòu)建一個(gè)新的ECharts實(shí)例,并終止更新渲染過程;否則執(zhí)行第2步。 - 若props中的
option
,notMergela
,lazyUpdate
,showLoading
和loadingOption
均沒有變化,則不更新ECharts實(shí)例;
注意:EChartsReactCore繼承PureComponent,若上述props進(jìn)行shallow equal比較為true時(shí)也不會更新ECharts實(shí)例;但這一步采用deep equal比較,來減少ECharts實(shí)例的更新。 - 若props中的
style
或className
發(fā)生變化則會觸發(fā)ECharts實(shí)例的resize
方法。
卸載過程
- 取消通過size-sensor訂閱的容器尺寸變化事件;
- 通過ECharts實(shí)例的
dispose
方法注銷ECharts實(shí)例。
項(xiàng)目依賴
fast-deep-equal: 遍歷對象屬性進(jìn)行對比size-sensor: DOM元素尺寸監(jiān)聽器,當(dāng)元素尺寸變化時(shí)會觸發(fā)回調(diào)函數(shù)
后續(xù)
echarts-for-react利用size-sensor實(shí)現(xiàn)圖表尺寸自適應(yīng)容器尺寸,那么size-sensor是怎樣做到這一點(diǎn)呢?敬請期待一下篇《React魔法堂:size-sensor源碼略讀》。
到此這篇關(guān)于React之echarts-for-react源碼解讀的文章就介紹到這了,更多相關(guān)echarts-for-react源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
前端 react 實(shí)現(xiàn)圖片上傳前壓縮(縮率圖)
這篇文章主要介紹了前端 react 實(shí)現(xiàn)圖片上傳前壓縮(縮率圖),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08關(guān)于antd tree和父子組件之間的傳值問題(react 總結(jié))
這篇文章主要介紹了關(guān)于antd tree 和父子組件之間的傳值問題,是小編給大家總結(jié)的一些react知識點(diǎn),本文通過一個(gè)項(xiàng)目需求實(shí)例代碼詳解給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-06-06前端開發(fā)使用Ant Design項(xiàng)目評價(jià)
這篇文章主要為大家介紹了前端開發(fā)使用Ant Design項(xiàng)目評價(jià),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08React-native橋接Android原生開發(fā)詳解
本篇文章主要介紹了React-native橋接Android原生開發(fā)詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01react+antd實(shí)現(xiàn)動態(tài)編輯表格數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了react+antd實(shí)現(xiàn)動態(tài)編輯表格數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08