echart图表自适应,当左边有菜单的时候,图表自适应

521 阅读2分钟

背景

当管理系统左边有菜单,右边内容区有echart图表的时候,点击收起展开菜单,echart图表的内容会超出或者留有空档,如下: image.png (ps:图是某位博主的图,原文链接blog.csdn.net/weixin_4421…

问题

echart图表我们在加载渲染完成之后,它只会初始化一次,此时已经有了固定的宽高,然后菜单展开收起改变内容区大小,它不会再重新渲染,所以导致了超出或者留有空档的问题。

思考方案

想了如下的解决办法:

1.监听一下左边菜单栏的收起和折叠状态,然后存为全局的store,在业务组件进行echart图表的resize(), 发现不好使;

使用myEcharts.resize(); // echart自带的resize方法

2.使用插件element-resize-detector,左边菜单栏的收起和折叠动画的时间是300ms,结合节流策略+resize重新设置大小来解决

解决

下载插件

npm install element-resize-detector --save

封装成公共函数:

import elementResizeDetectorMaker from "element-resize-detector";
import * as echarts from "echarts";
import { nextTick } from "vue";
import { throttle } from "lodash-es";

const initChart = (instanceRef, data) => {
    const instanceChart = echarts.init(instanceRef);
    instanceChart.setOption(data);
    // 菜单的动画是300毫秒,这里300毫秒刷新
    const throttleResize = throttle(() => {
        instanceChart && instanceChart.resize();
    }, 300);
    const erd = elementResizeDetectorMaker();
    erd.listenTo(instanceRef, () => {
        nextTick(() => {
            throttleResize(instanceChart)
        });
    });
}

在业务代码中onMounted初始化的时候,传入对应的ref和数据

const yourDivRef = ref(null)
onMounted(() => {
    initChartResize(yourDivRef.value, data);  // ref.value 你echart图表的ref data 图表数据
})
onBeforeUnmount(() => {
  // 卸载组件的的时候取消监听
    const erd = elementResizeDetectorMaker();
    instanceRef && erd.uninstall(instanceRef);
});

ok,换成这样初始化之后,echart就报错了(我的版本是5+)报错如下:

barPolar.js:63 Uncaught TypeError: Cannot read property 'type' of undefined
    at barPolar.js:63
    at GlobalModel2.<anonymous> (Global.js:661)
    at Array.forEach (<anonymous>)
    at each (util.js:206)
    at GlobalModel2.eachSeriesByType (Global.js:657)
    at Object.barLayoutPolar (barPolar.js:61)
    at Object.overallReset (util.js:311)
    at Task2.overallTaskReset [as _reset] (Scheduler.js:460)
    at Task2._doReset (task.js:202)
    at Task2.perform (task.js:117)

具体的报错内容为:
if (seriesModel.coordinateSystem.type !== 'polar') {
      return;
}

查阅资料:github.com/apache/echa…

ref 会把包裹的值变成响应式的对象,可能会影响 echarts 内部一些 model 属性的正常访问,暂时还不清楚具体原因。而 shallowRef 则是浅引用,不会将值变成响应式对象,不会影响 echarts 内部属性的访问。

解决办法+完整的初始化代码如下:

const yourDivRef = shallowRef(null) // 用这种方式来定义
onMounted(() => {
    initChartResize(yourDivRef.value, data);  // ref.value 你echart图表的ref data 图表数据
})
onBeforeUnmount(() => {
  // 卸载组件的的时候取消监听
    const erd = elementResizeDetectorMaker();
    instanceRef && erd.uninstall(instanceRef);
});

提一嘴

当然还有一种是浏览器大小变化的时候,echart图表的自适应,这种监听window.resize事件,重新调用chart.resize()方法就好了,就不赘述了,感兴趣的小伙伴自行研究下。

如果文章中有错误的地方或者误导的地方,请私聊,感谢~