前言
在以后工业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.tsxrender(): 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