Vue3 + echarts 图表组件
图表组件
- 传入options自动生成图表
- 传入width,height 可配置图表大小
- 窗口改变,图表大小自适应
- options 改表时,重新生成图表
<MyEcharts :options="options" width="50%" height="300px"/>
MyECharts.vue
<template>
<div>
<div :id="uuid" :style="style"></div>
</div>
</template>
<script lang='ts' setup>
import * as echarts from 'echarts'
import { debounce, throttle } from 'lodash';
import { ref, defineProps, watch, computed, onBeforeMount, onMounted, shallowRef, onBeforeUnmount } from 'vue'
const props = defineProps({
// 图表高度
height: {
type: String,
default: '200px',
},
// 图标宽度
width: {
type: String,
default: '700px',
},
// 配置项
options: {
type: Object,
default: null,
},
})
const uuid = ref(null)
let myChart = shallowRef(null)
watch(() => props.options,
(newVal, oldVal) => {
console.log('options newVal',newVal);
changeData()
},
{deep: true}
)
const style = computed(()=>{
// 当宽高变化时,重新计算echarts图表style样式
return {
height: props.height,
width: props.width,
}
})
const changeData = () =>{
myChart.value.clear()
myChart.value.setOption(props.options, true, true) //第一个true表示noMerge,第二个true表示lazyUpdata
}
const changeStyle = debounce(() => {
console.log('changeStyle');
myChart.value.resize()
},100)
const guid = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c,) {
let r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}
onBeforeMount(()=>{
console.log('onBeforeMount');
uuid.value = guid() // "a1ca0f7b-51bd-4bf3-a5d5-6a74f6adc1c7"
console.log(uuid.value);
})
let observer = ref(null)
onMounted(()=>{
console.log('onMounted');
myChart.value = echarts.init(document.getElementById(uuid.value))
myChart.value.setOption(props.options) //第一个true表示noMerge,第二个true表示lazyUpdata
window.addEventListener('resize', changeStyle)
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount');
window.removeEventListener('resize', changeStyle)
})
</script>
<style scoped lang="scss">
</style>
支持svg渲染
echarts默认使用canvas渲染,可以设置使用svg渲染图表
注意: SVG暂不支持 富文本、材质、炫光尾迹特效、带有混合效果的热力图
myChart.value = echarts.init(document.getElementById(uuid.value),null,{renderer:'svg'})
Vue2 echarts 图表组件
- 只需传入 options,width,heigth
- 支持宽高自适应
- 支持 options 改变图表自动更新
<MyEcharts :options="options" width="50%" height="300px"/>
MyECharts.vue
<template>
<div :id="uuid" :style="style"></div>
</template>
<script>
import * as echarts from 'echarts'
import { debounce, throttle } from 'lodash';
export default {
props: {
// 图表高度
height: {
type: String,
default: '200px',
},
// 图标宽度
width: {
type: String,
default: '700px',
},
// 配置项
options: {
type: Object,
default: null,
},
},
data() {
return {
uuid: null, //唯一标识echarts图表实例,id不能重复
myChart: null, //将创建的echarts实例被data管理(也就是被vue管理)
}
},
watch: {
width() {
// 监听width改变,width改变时重置echarts实例
if (this.myChart) {
this.changeStyle() // 重置echarts实例大小
}
},
options: {
// 监听options改变,options改变时重置echarts实例
handler() {
this.changeData()
},
deep: true,
},
},
computed: {
style() {
// 当宽高变化时,重新计算echarts图表style样式
return {
height: this.height,
width: this.width,
}
},
},
methods: {
changeStyle() {
debounce(this.myChart.resize(),100)
},
changeData() {
this.myChart.clear()
this.myChart.setOption(this.options, true, true) //第一个true表示noMerge,第二个true表示lazyUpdata
},
},
created() {
function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (
c,
) {
let r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}
this.uuid = guid() // "a1ca0f7b-51bd-4bf3-a5d5-6a74f6adc1c7"
},
mounted() {
// 准备实例
this.myChart = echarts.init(document.getElementById(this.uuid))
// 使用配置项
this.myChart.setOption(this.options)
window.addEventListener('resize',changeStyle)
},
beforeDestroy() {
window.removeEventListener('resize',changeStyle)
},
}
</script>
<style></style>