【Echarts】如何封装一个简易通用的echarts组件【resize自适应/X轴和标题自定义点击事件/图表随接口实时更新/防内存泄漏】

如何封装一个简易的echarts组件

要求实现功能

  1. echarts图表要能自适应大小,并且能够岁窗口自适应resize
  2. 大屏首页有很echarts图标且要不停切换,需防止内存泄漏
  3. 接口定时刷新返回数据时,需要自动更新echarts
  4. 需要绑定自定义的echarts图表的X轴和标题的点击事件

2023.1.14
PS:当涉及到页面需要切换显示多个echarts,vue里需使用v-if进行切换而不是v-show,否则会出现加载时图表缩成一团的bug
2023.3.27
PS:flex布局下echarts的缩放会出现问题,例如出现在一行多列的弹性盒中,需要单独给flex-item子项设置一个最小宽度或高度
2023.6.21
PS:【Echarts】图表大屏自适应的升级解决方案,请滑到底部




以下是实现的核心代码,由于此次大屏项目中各个图形各异,考虑此处过分封装会导致耦合度过高,故没有对配置项option进行封装。




<template>
  <div ref="myChart" :class="className" :style="{ height: height, width: width }" :option="option"/>
</template>
<script>
import * as echarts from "echarts";
// 缩放作防抖
import { debounce } from "@/utils";
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 {
      chart: null,
    };
  },
  mounted() {
    // 生成echart实例
    this.initChart();
    // 给窗口缩放resize加防抖
    this.__resizeHandler = debounce(() => {
      if (this.chart) this.chart.resize()
    }, 500);
    // 绑定窗口缩放resize事件
    window.addEventListener("resize", this.__resizeHandler);
    // * 绑定echarts X轴,标题的点击事件(当X轴或者标题是动态生成时,绑定在mounted无效)
    // this.chart.on('click','xAxis',this.getDepartmentByxAxis)
    // this.chart.on('click','title',this.getDepartmentByTitle)
  },
  beforeDestroy() {
    // 销毁echart,防止内存泄露
    if (!this.chart) return;
    window.removeEventListener("resize", this.__resizeHandler);
    this.chart.off('click')
    this.$off()
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    initChart() {
      if (this.chart !== null)  this.chart.dispose();
      this.chart = echarts.init(this.$refs.myChart);
      // 因为有时候X轴是动态生成的,所以当绑定事件必须写在这里,否在单击未绑定在相应的位置
      this.chart.on('click','xAxis',this.getDepartmentByxAxis)
      this.chart.on('click','title',this.getDepartmentByTitle)
      this.chart.setOption(this.option,true); //设置为true时不会合并数据,而是重新刷新数据
    },
    getDepartmentByxAxis(params){
      this.$emit('departmentByAxis',params.value) // 通过X坐标,通知父组件部门的名字
    },
    getDepartmentByTitle(params){
      this.$emit('departmenByTitle',params?.event?.target?.style?.text) // 通过title,通知父组件部门的名字
    }
  },
  watch:{
    option:{
      deep:true,
      handler(){
        this.initChart()
      }
    }
  }
};
</script>

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

🚀【Echarts】图表大屏自适应的解决方案,博客园站内跳转

posted @ 2022-06-28 23:54  wanglei1900  阅读(698)  评论(0编辑  收藏  举报