前言
在数据可视化项目中,使用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>
有不明白的或者有其他问题的可以评论区留言噢
今天的知识分享就到这里啦~希望大家在这能学到知识一起分享一起进步,成为更好的自己!