在當前工業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()`
/>
)
}
由於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;
}
const ref = useRef()
useEffect(() => {
const instance = ref.current.getEchartsInstance()
}, [])
<EchartsReact
ref={ref}
/>
核心邏輯均在EChartsReactCore
元件上(位於檔案src/core.tsx
),特點如下:
resize
方法實現自適應。componentDidMount
時呼叫renderNewEcharts
方法執行ECharts元件的生成邏輯;renderNewEcharts
方法內部邏輯
echarts.getInstanceByDom(容器DOM元素)
或echarts.init(容器DOM元素,主題,設定)
獲取已有ECharts範例或生成新的ECharts範例;setOption
方法設定或更新圖表內容;showLoading
或hideLoading
控制圖表渲染前是否顯示載入進度條;onEvents
設定的ECharts支援的事件處理器繫結到ECharts範例上;onChartsReady
方法;resize
方法,實現圖表尺寸的自適應。由於render
方法無論執行多少遍,實際上僅僅有可能影響容器本身而已,對ECharts範例並沒有任何影響。因此實際影響ECharts範例的邏輯被放置到componentDidUpdate
那裡,這做法和react-amap中在useEffect
中通過Marker等範例內建的set
方法更新狀態的原理是一致的。
theme
, opts
或onEvents
則要銷燬原來的ECharts範例,重新構建一個新的ECharts範例,並終止更新渲染過程;否則執行第2步。option
,notMergela
,lazyUpdate
,showLoading
和loadingOption
均沒有變化,則不更新ECharts範例;style
或className
發生變化則會觸發ECharts範例的resize
方法。dispose
方法登出ECharts範例。echarts-for-react利用size-sensor實現圖表尺寸自適應容器尺寸,那麼size-sensor是怎樣做到這一點呢?敬請期待一下篇《React魔法堂:size-sensor原始碼略讀》。
尊重原創,轉載請註明來自:https://www.cnblogs.com/fsjohnhuang/p/16792575.html _肥仔John
歡迎新增我的公眾號一起深入探討技術手藝人的那些事!
如果您覺得本文的內容有趣就掃一下吧!捐贈互勉!