浏览器全屏时 echarts.resize() 无效/滞后解决办法
前言
- echarts 在 dom 上初始化时使用 echarts. init ,这个 dom 是实例容器,一般是一个具有高宽的 DIV 元素。
- 不能在单个容器上初始化多个 ECharts 实例。
- echartsInstance.resize 改变图表尺寸,在容器大小发生改变时需要手动调用。
- echarts.resize() 的核心是监听 id=“myChart” 的那个 div 的尺寸变化,在其发生变化后调用 echarts.resize()。
一、 布局+样式
因为后面要测试高度变化,所以设定了高度 chartHeight 为变量。(直接写 height:100% 图表不显示)
<template> <div id="myChart" :style="{ height: chartHeight + 'px' }"></div> </template> <style> body { background-color: lightblue; } #myChart { width: 90%; background-color: lightgoldenrodyellow; } </style>
二、js基本代码(vue3 写法)
初始化 mychart 的高度,初始化一个柱状图:
var myChart = null; const chartHeight = ref(0); updateChartHeight(); function updateChartHeight() { chartHeight.value = window.innerHeight * 0.9; } function initEcharts() { myChart = echarts.init(document.getElementById('myChart')); myChart.setOption({ title: { text: 'ECharts 入门示例' }, tooltip: {}, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] }); }
三、监听 echarts 容器尺寸变化(以下简称div)
1. 没有全屏时,div 宽度、高度发生变化
这个很好办,直接用 window.addEventListener("resize", function()) 监听就可以。
function windowResize() { window.addEventListener("resize", () => { updateChartHeight(); console.log('%c window.innerWidth', "color:blue", window.innerWidth); console.log('%c window.innerHeight', "color:blue", window.innerHeight); myChart.resize();//改变图表尺寸 }) }
效果如图:
2. 全屏时,div 高度发生变化
(解决了高度变化时echarts图表不能正确自适应问题后可知,从非最大化-->全屏,宽度、高度均发生变化,且均无问题。)
浏览器从“最大化--> 全屏”时,宽度不发生变化,只有高度变化,如图:
从理论上讲,浏览器按 F11 进入的全屏既然可以被 window.addEventListener("resize")监听到,id="myChart" 的div尺寸也变化了,myChart.resize() 也调用了,那么图表就该正常自适应。
但是由实际情况可知,图表的高度变化和div的高度变化不是同步的,而是滞后了。从非全屏-->全屏,图表没变大;从全屏-->非全屏,图表是全屏时的尺寸。
解决办法:
1. 把 div 的高度单位改成 vh: https://juejin.cn/post/7083382244307370014
<div id="myChart"></div> #myChart { width: 90%; height: 80vh; background-color: lightgoldenrodyellow; }
2. 用 ResizeObserver 监听DOM元素尺寸的变化,在监测到变化后调用 myChart.resize();
function windowResize() { window.addEventListener("resize", () => { updateChartHeight();//这里只修改div高度 console.log('%c window.innerWidth', "color:blue", window.innerWidth); console.log('%c window.innerHeight', "color:blue", window.innerHeight); }) } function watchEchart() { const myChartSize = document.getElementById("myChart"); var ro = new ResizeObserver(entries => { for (let entry of entries) { const cr = entry.contentRect; console.log('myChart Element:', entry.target); console.log(`%c myChart Element w:${cr.width}px h:${cr.height}px`, "color:red"); myChart.resize();//监测到div尺寸变化后调用 } }); ro.observe(myChartSize); }
用 ResizeObserver 解决全部代码如下(展开查看):
<script setup> import { ref, onMounted } from 'vue'; import * as echarts from 'echarts'; var myChart = null; const chartHeight = ref(0); updateChartHeight(); onMounted(() => { initEcharts(); windowResize(); watchEchart(); }) function updateChartHeight() { chartHeight.value = window.innerHeight * 0.9; } function initEcharts() { myChart = echarts.init(document.getElementById('myChart')); myChart.setOption({ title: { text: 'ECharts 入门示例' }, tooltip: {}, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] }); } function windowResize() { window.addEventListener("resize", () => { updateChartHeight();//这个必须放在这里 console.log('%c window.innerWidth', "color:blue", window.innerWidth); console.log('%c window.innerHeight', "color:blue", window.innerHeight); // console.log("%c windowResize chartHeight ", "color:blue", chartHeight.value); }) } function watchEchart() { const myChartSize = document.getElementById("myChart"); var ro = new ResizeObserver(entries => { for (let entry of entries) { const cr = entry.contentRect; // console.log('myChart Element:', entry.target); console.log(`%c myChart Element w:${cr.width}px h:${cr.height}px`, "color:red"); chartResize(); } }); ro.observe(myChartSize); } function chartResize() { myChart.resize(); } </script> <template> <div id="myChart" :style="{ height: chartHeight + 'px' }"></div> </template> <style> body { background-color: lightblue; } #myChart { width: 90%; background-color: lightgoldenrodyellow; } </style>
效果图如下: