在用户改变浏览器窗口大小或者侧边栏展开时,需要重新调整ECharts图表的大小,以适应窗口。

监听方法

ECharts有resize()方法,监听到变化时,调用该函数。

  1. 对window的Resize事件进行监听

    window.addEventListener('resize', this.chartResize);

    这样只能对浏览器窗口大小变化时进行监听,侧边栏展开时,窗口大小无变化,所以还需要对侧边栏状态等设置监听

    computed: {
       // 侧边栏是否打开
       sideBarFlag: () => {
         return this.$store.state.app.sidebar.opened
       }
    },
    watch: {
       // 侧边栏展开收起状态变化时改变大小
       sideBarFlag: function () {
         this.chartResize()
       }
    }
  2. 单独对存放ECharts的DOM进行监听

    const resizeObserver = new ResizeObserver(entries => {
       this.myChart.resize()
    })
    resizeObserver.observe(document.getElementById(this.id))

    ResizeObserver的具体用法参考MDN

    由于直接对DOM大小进行监听,所以不用再对侧边栏变化等设置监听,但是IE浏览器不支持这个API

图表大小调整时的优化

重绘会消耗较多的资源,如果监听到后立即进行重绘,可能会造成频繁重绘,造成页面卡顿。所以通过设置定时器,在一段时间内没有监听到变化后,再进行重绘

// 图表重绘方法
chartResize() {
   if (this.chartResizeTimer) {
     // 先清除上个定时器
     clearTimeout(this.chartResizeTimer)
   }
   // 设置定时器
   this.chartResizeTimer = setTimeout(() => {
     this.myChart.resize()	// 进行重绘
   }, 300)
},

完整代码

<template>
  <div
    :id="id"
    :style="{width: '100%', height: '100%'}"
  ></div>
</template>

<script>
import echarts from 'echarts'
export default {
  name: 'EChartsContainer',
  props: {
    id: {
      type: String,
      default: '',
    },
    option: {
      type: Object,
      default: () => null,
    },
  },
  data() {
    return {
      myChart: null,
      chartResizeTimer: null,
    }
  },
  mounted() {
    this.myChart = echarts.init(document.getElementById(this.id), 'light')
    this.setOption()
    // 监听window的Resize
    window.addEventListener('resize', this.chartResize)
    // 监听指定Dom的Resize,IE不支持
    // const resizeObserver = new ResizeObserver(entries => {
    //   this.myChart.resize()
    // })
    // resizeObserver.observe(document.getElementById(this.id))
  },
  activated() {
    // 切换标签页后resize
    this.myChart.resize()
  },
  beforeDestoryed() {
    window.removeEventListener('resize', this.chartResize)
  },
  methods: {
    setOption() {
      this.myChart.setOption(this.option)
    },
    // 图表大小调整,设置定时器避免频繁重绘
    chartResize() {
      if (this.chartResizeTimer) {
        clearTimeout(this.chartResizeTimer)
      }
      this.chartResizeTimer = setTimeout(() => {
        this.myChart.resize()
      }, 300)
    },
  },
  computed: {
    // 侧边栏是否打开
    sideBarFlag: () => {
      return this.$store.state.app.sidebar.opened
    },
  },
  watch: {
    // 监听option参数变化
    option: function () {
      this.setOption()
    },
    // 侧边栏展开收起状态变化时改变大小
    sideBarFlag: function () {
      this.chartResize()
    },
  },
}
</script>

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

防抖与节流 上一篇
函数与call,apply与bind的使用 下一篇