前言
在以后工业 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/fsjoh… ^_^ 肥仔 John