【Echarts】图表大屏自适应的解决方案

发布时间 2023-04-07 17:28:14作者: wanglei1900

echarts图表的自适应有两种方案

1.通过window.onresize api 监听页面视口大小改变时,自适应变化(echarts.resize())

2.通过ResizeObserver api 监听组装echarts容器的大小,自适应变化(echarts.resize())

两种方式各有优缺点,
window.onresize 兼容性好,但是只能根据视口改变才能自适应。假如当组装echarts的容器大小改变但是页面视口并没有改变是无法自适应的。比如后台管理页面,侧边栏伸缩展开时。比如父组件大小是卡片可以拉拽调整大小
ResizeObserver 是有兼容性问题。他能够监听指定父容器的大小来进行自适应。也有其他补充方法可以解决兼容性问题。

?监听页面视口的自适应方案,博客园站内跳转

以下是ResizeObserver 的解决方案。
this.resizeObserver.observe 调用的时机十分重要,不然会出错

<template>
  <div ref="myChart" :class="className" :style="{ height: height, width: width }" :option="option" />
</template>
<script>
import { debounce } from "@/core/util/util";
export default {
  props: {
    className: { type: String, default: "chart", },
    width: { type: String, default: "100%", },
    height: { type: String, default: "100%", },
    option: { type: Object, required: true, default: () => ({}), }
  },
  data() {
    return {
      instance: null,
      resizeObserver: null,
    };
  },
  mounted() {
    this.initChart();
  },
  beforeDestroy() {
    if (!this.instance) return;
    this.disposeResizeObserver()
    this.disposeChart()
    this.resizeObserver = null
    this.instance = null;
  },
  methods: {
    // 初始化Chart
    initChart() {
      if (this.instance) return;
      this.disposeChart();
      this.disposeResizeObserver();
      this.instance = window.echarts.init(this.$refs.myChart)
      this.initResizeObserver()
    },
    // 加载表格
    loadChart() {
      this.instance?.setOption(this.option, true); //设置为true时不会合并数据,而是重新刷新数据
      this.resizeObserver && this.instance?.on('finished', () => this.loadResizeObserver());
    },
    // 销毁Chart
    disposeChart() {
      this.instance?.dispose();
    },
    // 初始化ResizeObserver
    initResizeObserver() {
      if (!this.instance) return;

      const __resizeHandler = debounce(() => {
        this.instance?.resize()
      }, 100)

      this.resizeObserver = new ResizeObserver((entries, observer) => {
        __resizeHandler();
      });
    },
    // 开启监视ResizeObserver
    loadResizeObserver() {
      this.resizeObserver?.observe(this.$refs.myChart);
    },
    // 销毁ResizeObserver
    disposeResizeObserver() {
      this.resizeObserver?.unobserve(this.$refs.myChart);
      this.resizeObserver?.disconnect()
    },
  },
  watch: {
    option: {
      // immediate:true,
      deep: true,
      handler() {
        this.loadChart();
      },
    },
  },
};
</script>