網站首頁 編程語言 正文
前言
在當前工業4.0和智能制造的產業升級浪潮當中,智慧大屏無疑是展示企業IT成果的最有效方式之一。然而其背后怎么能缺少ECharts的身影呢?對于React應用而言,直接使用ECharts并不是最高效且優雅的方式,而echarts-for-react則是針對React應用對ECharts進行輕量封裝和增強的工具庫。
echarts-for-react的源碼非常精簡,本文將針對主要邏輯分析介紹。
從與原生初始化對比開始
原生ECharts中我們會通過如下代碼初始化圖表實例
<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 ( <ReactECharts style={{width: 100, height: 100}} // 設置容器的寬高 autoResize={true} // 默認為true,自動監測容器尺寸的變化,并調用`chart.resize()` /> ) }
陷阱-默認值height為300px
由于ReactECharts
的style
默認內置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的方式設置容器高度時必須使用!important
<ReactECharts className={styles.container} />
// index.module.css .container { height: 500px !important; }
獲取ECharts實例
const ref = useRef() useEffect(() => { const instance = ref.current.getEchartsInstance() }, []) <EchartsReact ref={ref} />
主邏輯源碼剖析
核心邏輯均在EChartsReactCore
組件上(位于文件src/core.tsx
),特點如下:
- 采用PureComponent方式編寫組件以便適配所有React版本;
- 僅對ECharts 命令式API進行聲明式API的封裝,并沒有將每種EChart圖表類型封裝為組件;
- 添加特性,監測容器尺寸的變化,并自動調用ECharts實例的
resize
方法實現自適應。
掛載渲染過程
- 在
componentDidMount
時調用renderNewEcharts
方法執行ECharts組件的生成邏輯; -
renderNewEcharts
方法內部邏輯通過
echarts.getInstanceByDom(容器DOM元素)
或echarts.init(容器DOM元素,主題,配置)
獲取已有ECharts實例或生成新的ECharts實例;通過ECharts實例的
setOption
方法設置或更新圖表內容;通過ECharts實例的
showLoading
或hideLoading
控制圖表渲染前是否顯示加載進度條;將通過props?
onEvents
配置的ECharts支持的事件處理器綁定到ECharts實例上;觸發props?
onChartsReady
?方法;訂閱通過size-sensor監測容器尺寸并自動調用ECharts實例的
resize
方法,實現圖表尺寸的自適應。
更新渲染過程
由于render
方法無論執行多少遍,實際上僅僅有可能影響容器本身而已,對ECharts實例并沒有任何影響。因此實際影響ECharts實例的邏輯被放置到componentDidUpdate
那里,這做法和react-amap中在useEffect
中通過Marker等實例內置的set
方法更新狀態的原理是一致的。
- 若更新的props包含
theme
,?opts
或onEvents
則要銷毀原來的ECharts實例,重新構建一個新的ECharts實例,并終止更新渲染過程;否則執行第2步。 - 若props中的
option
,notMergela
,lazyUpdate
,showLoading
和loadingOption
均沒有變化,則不更新ECharts實例;
注意:EChartsReactCore繼承PureComponent,若上述props進行shallow equal比較為true時也不會更新ECharts實例;但這一步采用deep equal比較,來減少ECharts實例的更新。 - 若props中的
style
或className
發生變化則會觸發ECharts實例的resize
方法。
卸載過程
- 取消通過size-sensor訂閱的容器尺寸變化事件;
- 通過ECharts實例的
dispose
方法注銷ECharts實例。
項目依賴
fast-deep-equal: 遍歷對象屬性進行對比size-sensor: DOM元素尺寸監聽器,當元素尺寸變化時會觸發回調函數
后續
echarts-for-react利用size-sensor實現圖表尺寸自適應容器尺寸,那么size-sensor是怎樣做到這一點呢?敬請期待一下篇《React魔法堂:size-sensor源碼略讀》。
原文鏈接:https://www.cnblogs.com/fsjohnhuang/p/16792575.html
相關推薦
- 2022-09-08 Pytorch中transforms.Resize()的簡單使用_python
- 2022-05-27 Flutter狀態管理Bloc之登錄示例_Android
- 2023-04-19 TypeError [ERR_INVALID_ARG_TYPE]: The “path“ argum
- 2022-12-11 C語言冷知識之預處理字符串操作符詳解_C 語言
- 2022-05-16 Qt5中QML自定義環形菜單/環形選擇框的實現_C 語言
- 2022-12-29 Kotlin?Service服務組件開發詳解_Android
- 2022-05-06 Go在Window平臺下編譯出來的exe如何添加一個圖標
- 2022-06-01 解決IIS不識別PUT和DELETE請求_win服務器
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支