React魔法堂:echarts-for-react源码略读
前言
在当前工业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 _肥仔John
React魔法堂:echarts-for-react源码略读的更多相关文章
- JS魔法堂: Native Promise Only源码剖析
一, 前言 深入学习Promise的朋友应该都看过<深入理解Promise五部曲>这一系列的文章, 以解除回调地狱之外的观点来剖析Promise更多的内涵,确实十分精彩. Part 1: ...
- React魔法堂:size-sensor源码略读
前言 echarts-for-react在对echarts进行轻量级封装的基础上,额外提供图表尺寸自适应容器尺寸的这小而实用的功能,而这功能的背后就是本文想介绍的size-sensor了. 源码介绍 ...
- java基础集合类——ArrayList 源码略读
ArrayList是java的动态数组,底层是基于数组实现. 1. 成员变量 public class ArrayList<E> extends AbstractList<E> ...
- react面试题——理解setState(源码object.assign)
setState是异步的方式 this.setState({ counter:this.state.counter+1 }) console.log(this.state.counter) s ...
- 【React自制全家桶】一、Webstrom+React+Ant Design+echarts搭建react项目
前言 一.React是Facebook推出的一个前端框架,之前被用于著名的社交媒体Instagram中,后来由于取得了不错的反响,于是Facebook决定将其开源.出身名门的React也不负众望,成功 ...
- 从源码的角度看 React JS 中批量更新 State 的策略(下)
这篇文章我们继续从源码的角度学习 React JS 中的批量更新 State 的策略,供我们继续深入学习研究 React 之用. 前置文章列表 深入理解 React JS 中的 setState 从源 ...
- React躬行记(16)——React源码分析
React可大致分为三部分:Core.Reconciler和Renderer,在阅读源码之前,首先需要搭建测试环境,为了方便起见,本文直接采用了网友搭建好的环境,React版本是16.8.6,与最新版 ...
- Redux源码学习笔记
https://github.com/reduxjs/redux 版本 4.0.0 先了解一下redux是怎么用的,此处摘抄自阮一峰老师的<Redux 入门教程> // Web 应用是一个 ...
- 带着问题看redux源码
前言 作为前端状态管理器,这个比较跨时代的工具库redux有很多实现和思想值得我们思考.在深入源码之前,我们可以相关注下一些常见问题,这样带着问题去看实现,也能更加清晰的了解. 常见问题 大概看了下主 ...
随机推荐
- cmd命令行工具
在windows下进行python开发,需要经常使用cmd命令行工具.打开命令行工具有很多种方法,最简单的就是win键+R键弹出运行窗口,然后输入cmd, 就会打开下面这样的窗口. 不同版本,可能配色 ...
- MySQL金融应用场景下跨数据中心的MGR架构方案(2)
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 如何在多个数据中心部署多套MGR集群,并实现故障快速切换. 上篇文章介绍了如何在多数据中心部署多套MGR集群,并构建集群间 ...
- CSP-J2021 题解
分糖果 题意 选择L~R中的某个数 , 使得x mod k的结果最大. 思路 分两种情况考虑: 若 L 和 R 对 K 取模后在同一区间,则必然在 x=R 位置取到最大值: 否则 L~R 必然跨越多个 ...
- 论语音社交视频直播平台与 Apache DolphinScheduler 的适配度有多高
在 Apache DolphinScheduler& Apache ShenYu(Incubating) Meetup 上,YY 直播 软件工程师 袁丙泽 为我们分享了<YY直播基于Ap ...
- Apache 首次亚洲在线峰会: Workflow & 数据治理专场
背景 大数据发展到今天已有 10 年时间,早已渗透到各个行业,数据需 求越来越多,这使得大数据 业务间的依赖关系也越来越复杂,另外也相信做数据的伙伴肯定对如何治理数据也是痛苦之至,再加上现今云原生时代 ...
- 让Python更优雅更易读(第一集)
变量和注释 1.变量 在编写变量尽量要让其清晰只给,让人清除搞清楚代码的意图 下方两段代码作用完全一样,但第二段代码是不是更容易让人理解 value = s.strip() username = in ...
- Luogu3803 【模板】多项式乘法(FFT)
为什么我这么弱 其实FFT也挺水的,一点数学基础加上细心即可.细节·技巧挺多. 递归 在TLE的边缘苦苦挣扎 #include <iostream> #include <cstdio ...
- MyBatis 02 配置
导入jar包 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</a ...
- WPF中使用System.Windows.Interactivity实现事件绑定的替代方法
一.问题描述 对于 Button 等控件,在 MVVM 中我们能通过 Command 绑定解决 Click 事件.具体如下所示: <Button Margin="10" He ...
- java-异常处理和线程的一些简单方法及使用
1.1 子类重写父类含有throws声明异常抛出的方法时的规则: 1.允许不再抛出任何异常. 2.仅抛出部分异常. 3.抛出父类方法抛出异常的子类型异常. 4.不可以抛出额外异常. 5.不能抛出父类方 ...