【Echarts封装通用组件】开盒即用

前言

在数据可视化项目中,使用echarts开发时,如果遇到图表很多的情况,需要在每一个图表文件进行setOption操作和监听Resize操作,为了提高开发效率和图表开发过程,我们可以封装一个通用的echarts文件进行传参实现图表的动态渲染

一、基本结构

封装的前提下,我们知道echarts渲染需要一个容器,因此在封装组件是首先我们建一个容器也就是div,其次这个容器的样式需要设置宽高才可以展示图表,如果每个图表的宽高不同,即需要设置参数进行传递。

以下代码以Vue2示例,Vue3及react可参考进行调整

  <div class="echartBox" :style="myStyle"></div>

宽高的动态传递

  props: {
     EchartsWidth: {
       type: Number,
       default: 0
     },
     EchartsHeight: {
       type: Number,
       default: 0
     },
  },

 计算属性计算宽高并赋值给容器div

   computed: {
     myStyle() {
       return {
         '--Echart-width': this.EchartsWidth + 'rem',
         '--Echart-height': this.EchartsHeight + 'rem'
       }
     }
   },
<style lang="less" scoped>
.echartBox {
   width: var(--Echart-width);
   height: var(--Echart-height);
}
</style>

二、图表option动态传递及渲染

容器建好之后,图表option的渲染最为重要,我们把option作为参数进行传递

  props: {
    Options: {
      type: Object,
      default: () => {}
    }
  },

图表的option都不相同,所以我们需要watch属性进行监听从而触发组件的初始化事件并渲染option

  watch: {
    Options: {
      handler(newVal, oldVal) {
        if (this.Options) {
          this.myCharts.setOption(newVal, true)
        } else {
          this.init()
        }
      },
      deep: true
    }
  },

三、容器id问题

之前可能我们写图表文件是独立的,所以互相之间不会影响冲突。在通用的组件及echarts自身的渲染机制必须要独立性唯一性,所以为了区分每个图表的唯一性,我引入了UUid进行保持唯一性

首先我们要下载uuid的依赖,此处不过多介绍。下载之后引入到文件内

import { v4 as uuidv4 } from 'uuid'
  data() {
    return {
      uniqueId: uuidv4(),
    }
  },
  <div :id="uniqueId"></div>

四、组件初始化以及监听自适应

一切准备就绪,剩下的就是文件初始化,直接上代码~

    init() {
      this.$nextTick(() => {
        if (!this.myCharts) {
          this.myCharts = echarts.init(document.getElementById(this.uniqueId), null, { renderer: 'svg' })
        }
        if (this.Options) {
          this.myCharts.setOption(this.Options, true)
        }
        if (this.myCharts) window.addEventListener('resize', this.handleResize)
      })
    },

然后在挂载阶段init

五、组件销毁及移除监听

init时引入了监听自适应,因此在组件销毁时要移除掉

  beforeDestroy() {
    if (!this.myCharts) return
    // 移除监听
    window.removeEventListener('resize', this.handleResize)
    // 销毁echarts实例
    this.myCharts.clear()
    this.myCharts.dispose()
    this.myCharts = null
  },

六、防抖优化

  created() {
    this.handleResize = debounce(() => {
      this.myCharts.resize()
    }, 300)
  },

整体代码

<template>
  <div :id="uniqueId" class="echartBox"></div>
</template>

<script>
import * as echarts from 'echarts'
import debounce from 'lodash/debounce'
import { v4 as uuidv4 } from 'uuid'
export default {
  name: 'CommonEcharts',
  props: {
    Options: {
      type: Object,
      default: () => {}
    },
    // EchartsWidth: {
    //   type: Number,
    //   default: 0
    // },
    // EchartsHeight: {
    //   type: Number,
    //   default: 0
    // },
  },
  data() {
    return {
      myCharts: null,
      uniqueId: uuidv4(),
    }
  },
  // computed: {
  //   myStyle() {
  //     return {
  //       '--Echart-width': this.EchartsWidth + 'rem',
  //       '--Echart-height': this.EchartsHeight + 'rem'
  //     }
  //   }
  // },
  watch: {
    Options: {
      handler(newVal, oldVal) {
        if (this.Options) {
          this.myCharts.setOption(newVal, true)
        } else {
          this.init()
        }
      },
      deep: true
    }
  },
  created() {
    this.handleResize = debounce(() => {
      // if (this.myCharts) {
      this.myCharts.resize()
      // }
    }, 300)
  },
  mounted() {
    this.init()
  },
  beforeDestroy() {
    if (!this.myCharts) return
    // 移除监听
    window.removeEventListener('resize', this.handleResize)
    // 销毁echarts实例
    this.myCharts.clear()
    this.myCharts.dispose()
    this.myCharts = null
  },
  methods: {
    // 初始化
    init() {
      this.$nextTick(() => {
        if (!this.myCharts) {
          this.myCharts = echarts.init(document.getElementById(this.uniqueId), null, { renderer: 'svg' })
        }
        if (this.Options) {
          this.myCharts.setOption(this.Options, true)
        }
        if (this.myCharts) window.addEventListener('resize', this.handleResize)
      })
    }
  }
}
</script>

<style lang="less" scoped>
.echartBox {
  // width: var(--Echart-width);
  // height: var(--Echart-height);
  width: 100%;
  height: 100%;
}
</style>

有不明白的或者有其他问题的可以评论区留言噢

今天的知识分享就到这里啦~希望大家在这能学到知识一起分享一起进步,成为更好的自己!

你可以使用`v-for`指令配合组件封装来动态生成ECharts图表组件。下面是一个示例,展示如何使用`v-for`循环来创建多个图表组件: 首先,你可以创建一个名为`EChart`的组件,用于封装ECharts图表的渲染和数据传递逻辑。在该组件中,你可以接收一个`chartData`属性,用于传递给ECharts实例的数据。 ```vue <template> <div ref="chartDom" style="width: 400px; height: 300px;"></div> </template> <script> import echarts from 'echarts'; export default { props: { chartData: { type: Object, required: true } }, mounted() { this.renderChart(); }, methods: { renderChart() { const chartDom = this.$refs.chartDom; const myChart = echarts.init(chartDom); myChart.setOption(this.chartData); } } }; </script> ``` 接下来,在父组件中,你可以通过`v-for`指令循环遍历一个数据数组,并传递每个图表的数据给`EChart`组件。这样就可以动态创建多个图表组件。 ```vue <template> <div> <EChart v-for="(chartData, index) in chartDataArray" :key="index" :chartData="chartData" /> </div> </template> <script> import EChart from './EChart.vue'; // 导入EChart组件 export default { components: { EChart }, data() { return { chartDataArray: [ { /* 第一个图表的数据 */ }, { /* 第二个图表的数据 */ }, // ... ] }; } }; </script> ``` 在上述示例中,通过`v-for`指令循环遍历`chartDataArray`数组中的每个元素,并将每个元素作为`chartData`属性传递给`EChart`组件。这样就能够根据数组中的数据动态生成多个图表组件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Star Universe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值