解决 ECharts 切换图表时的 Resize 问题
问题
场景:页面中需要切换展示多个图表——只有第一个切换的图表会自动应用 resize
方法,而后续切换的图表则无法正确响应尺寸变化,有时甚至连第一个图表都无法正常调整尺寸。
分析
ECharts 的 resize
方法是用于手动触发图表尺寸调整的。在正常情况下,当浏览器窗口大小发生变化时,ECharts 会自动调用 resize
方法来重新渲染图表。但在图表切换的场景下,由于 ECharts 实例的切换和 DOM 元素的动态变化,可能导致 resize
方法无法正确触发。此外,如果图表实例没有正确保存,或者在切换过程中没有及时调用 resize
方法,也会导致图表无法正确响应尺寸变化。
解决
全部代码可见博客echarts图表的轮播切换功能_echarts 轮播-CSDN博客
初始化图表实例
在初始化图表时,我们需要保存当前图表实例的引用,以便在需要时调用其 resize
方法。
let currentChartInstance: ECharts | null = null;
const myChart = initEcharts(ref, annularList, gradientColors, gradientColors, title);
currentChartInstance = myChart; // 保存当前图表实例
当组件销毁或不再需要图表时,可以通过 dispose
方法销毁图表实例,释放资源,避免内存泄漏。例如:
if (currentChartInstance) {
currentChartInstance.dispose();
currentChartInstance = null; // 清空引用
}
如果图表需要根据数据的变化动态更新,可以通过保存的实例快速响应。例如,在 Vue 的生命周期中,可以在 onMounted
初始化图表,在 onUnmounted
销毁图表:
import { onMounted, onUnmounted } from 'vue';
onMounted(() => {
const myChart = initEcharts(containerRef, data, colors, title);
currentChartInstance = myChart;
});
onUnmounted(() => {
if (currentChartInstance) {
currentChartInstance.dispose();
currentChartInstance = null;
}
});
自定义 Resize 函数
定义 resizeChart
函数,通过 setTimeout
延迟调用当前图表实例的 resize
方法。这样可以确保在 DOM 元素完成更新后,图表能够正确获取到新的尺寸并重新渲染。
let timer: ReturnType<typeof setTimeout> | undefined = undefined;
let currentChartInstance: ECharts | null = null;
const resizeChart = (): void => {
// 清除之前的定时器,避免重复触发
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
if (currentChartInstance) {
currentChartInstance.resize(); // 调用当前图表实例的 resize 方法
}
}, 500);
};
监听窗口大小变化
为了确保图表在窗口大小发生变化时能够正确调整尺寸,我们需要在组件挂载时监听 resize
事件,并在组件卸载时移除监听器。
import { onMounted, onBeforeUnmount } from 'vue';
onMounted(() => {
window.addEventListener('resize', resizeChart);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
clearTimeout(timer); // 清除定时器
});
总结
成功解决了 ECharts 在切换图表时无法正确触发 resize
方法的问题。自定义的 resizeChart
函数通过延迟调用 resize
方法,确保了图表能够在 DOM 元素更新完成后正确获取新的尺寸并重新渲染。同时,通过监听窗口大小变化事件,图表在浏览器窗口调整时也能正确响应尺寸变化。