Echarts实现随容器大小改变实时更新大小及采坑记录

12,196 阅读3分钟

本文是工作中使用Echarts遇到的问题汇总,如果能帮到你,那就再好不过了

根据窗口大小动态更新Echarts

echarts自身提供了 resize API,用来改变图表尺寸,但它并不会监听外层容器尺寸的改变自动调用,动态更新逻辑需要手动实现。 echarts.apache.org/zh/api.html…

实现动态更新的功能有两种情况,一种是图表容器不会发生改变,只有浏览器窗口大小变化;另外一种是图表容器本身也会发生变化。不管是哪种方式,内部逻辑都非常简单,直接调用echarts提供的resize方法就可以了,重点是我们该如何去监听外层容器或者window的改变,以及其中会遇到什么问题,接下来分别就这两种情况进行分析。

只有浏览器窗口可以改变大小

这种情况只需要监听window的resize事件就可以了。我们所熟知往DOM上注册事件监听器有两种方式

1. window.onresize = function() {}
2. window.addEventListener('resize', function() {})

如果你的页面上只有一个图表实例,没有进行复用,应该感觉不到两种方式的区别。但如果有多个复用图表,使用 方法1 你会发现每次更新只有最后一个图表大小会发生改变,这是最容易遇到的问题。至于为什么会遇到这样的问题,我们去MDN一看究竟~

addEventListener

MDN 中为什么使用 addEventListener 提到它允许给一个事件注册多个监听器,也就是说通过 addEventListener 添加事件监听,比如我们要用到的 resize,是可以多次给这个事件注册监听器的。

window.addEventListener('resize', function() { console.log('监听器1') })
window.addEventListener('resize', function() { console.log('监听器2') })
//上面两次添加的监听器都会执行

然后我们再这个文档下面还可以看到这段内容

on...

文档中写到 onclick 方法会替换当前元素上所有已存在的事件监听器,我们对echarts组件复用时,只有最后一个图表大小会发生变化就是因为每次最新的 window.onresize 监听器到来后都会把之前定义的监听器替换掉。

至此,监听window窗口变化的操作就完成了,这种情况下保险起见,我们还是使用 addEventListener 进行事件监听。

图表容器可以调整大小

这种情况我们最直接需要监听的就是可调整大小DOM的尺寸变化。但是 onresize 是只有window才有的属性,因为不能用它去监听普通div的尺寸变化。

换一种思路,容器改变尺寸时,我们一般需要使用 transition 属性实现动画渐变。普通div元素是可以实现监听 transition 属性周期的,对应的是 transitionstart 和 transitionend 两个事件,因此我们可以通过给echarts父元素绑定 transitionstart 和 transitionend 监听器,在它们触发时执行echarts的resize事件。

但是这个方法有一个问题,因为transitionstart 和 transitionend分别只能监听 transition 动画开始执行和结束执行的瞬间,并不能监听中间过程,因此如果我们只在监听器中执行一次 echarts.resize() 并不能达到想要的效果。

所以我选择在 transitionstart 监听器中初始化一个 setInterval,循环执行 echarts.resize(),至于具体的时间间隔,需要大家根据实际情况调整;然后在 transitionend 监听器中销毁 setInterval。

上简要代码:

parentElement.addEventListener('transitionstart', () => {
  this.lineCharts.resize()
  transitionInterval = setInterval(() => {
    this.lineCharts.resize()
  },100)
})
parentElement.addEventListener('transitionend', () => {
  this.lineCharts.resize()
  clearInterval(transitionInterval)
})

这种情况下,依然需要进行 window resize 的监听,因为window大小发生变化时并不会主动触发上面对echarts父元素的监听。

如果能够实现直接监听echarts父元素尺寸变化,那理论上window大小改变时是可以直接触发父元素监听器的。但是目前我还没有发现比较好的监听普通DOM元素尺寸变化的方法,如果各位大佬知道的话,欢迎交流~