feat: base 优化xtChart
This commit is contained in:
parent
75c9087f25
commit
ac5ca4ba81
|
|
@ -1,42 +1,152 @@
|
|||
<template>
|
||||
<div ref="myChart" :style="{ width: width, height: height }"></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref, defineProps, watch, onUnmounted } from 'vue'
|
||||
import { onMounted, ref, defineProps, defineEmits, watch, onUnmounted } from 'vue'
|
||||
import * as echarts from "echarts";
|
||||
import echartTheme from "@/assets/echarts_theme.json";
|
||||
|
||||
// 定义所有可能的事件类型
|
||||
const emit = defineEmits([
|
||||
'chart-click',
|
||||
'chart-dblclick',
|
||||
'chart-mouseover',
|
||||
'chart-mouseout',
|
||||
'chart-legendselectchanged',
|
||||
'chart-datazoom',
|
||||
'chart-dataviewchanged',
|
||||
'chart-restore',
|
||||
'chart-finished'
|
||||
])
|
||||
|
||||
const props = defineProps({
|
||||
option: { type: Object, default: () => ({}) },
|
||||
theme: { type: String, default: "essos" },
|
||||
width: { type: String, default: "100%" },
|
||||
height: { type: String, default: "300px" }
|
||||
height: { type: String, default: "300px" },
|
||||
// 支持自定义事件类型
|
||||
events: {
|
||||
type: Array,
|
||||
default: () => ['click']
|
||||
},
|
||||
// 是否开启自动调整大小
|
||||
autoResize: { type: Boolean, default: true }
|
||||
})
|
||||
|
||||
const myChart = ref(null)
|
||||
let myChartInstance = null;
|
||||
onMounted(() => {
|
||||
|
||||
// 事件映射 - 将 ECharts 事件名映射到 emit 事件名
|
||||
const eventMap = {
|
||||
'click': 'chart-click',
|
||||
'dblclick': 'chart-dblclick',
|
||||
'mouseover': 'chart-mouseover',
|
||||
'mouseout': 'chart-mouseout',
|
||||
'legendselectchanged': 'chart-legendselectchanged',
|
||||
'datazoom': 'chart-datazoom',
|
||||
'dataviewchanged': 'chart-dataviewchanged',
|
||||
'restore': 'chart-restore'
|
||||
}
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
if (props.theme in echartTheme) {
|
||||
echarts.registerTheme(props.theme, echartTheme[props.theme]);
|
||||
} else {
|
||||
console.warn("echarts未找到该主题")
|
||||
console.warn("echarts未找到该主题:", props.theme)
|
||||
}
|
||||
|
||||
myChartInstance = echarts.init(myChart.value, props.theme);
|
||||
myChartInstance.setOption(props.option);
|
||||
window.addEventListener("resize", ()=>{myChartInstance?.resize()})
|
||||
})
|
||||
|
||||
// 注册事件监听
|
||||
registerEvents();
|
||||
|
||||
// 自动调整大小
|
||||
if (props.autoResize) {
|
||||
window.addEventListener("resize", handleResize);
|
||||
}
|
||||
}
|
||||
|
||||
// 注册事件
|
||||
const registerEvents = () => {
|
||||
props.events.forEach(eventName => {
|
||||
if (eventMap[eventName]) {
|
||||
myChartInstance.on(eventName, (params) => {
|
||||
emit(eventMap[eventName], params);
|
||||
});
|
||||
} else {
|
||||
console.warn(`不支持的事件类型: ${eventName}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 调整大小处理
|
||||
const handleResize = () => {
|
||||
myChartInstance?.resize();
|
||||
}
|
||||
|
||||
// 清理事件
|
||||
const cleanup = () => {
|
||||
if (myChartInstance) {
|
||||
// 移除所有事件监听
|
||||
props.events.forEach(eventName => {
|
||||
myChartInstance.off(eventName);
|
||||
});
|
||||
|
||||
if (props.autoResize) {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
}
|
||||
|
||||
myChartInstance.dispose();
|
||||
myChartInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(initChart)
|
||||
|
||||
// 监听 option 变化
|
||||
watch(() => props.option, (newOption) => {
|
||||
if (myChartInstance) {
|
||||
myChartInstance.setOption(newOption);
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
onUnmounted(() => {
|
||||
// 清理资源
|
||||
// 监听 events 变化,重新注册事件
|
||||
watch(() => props.events, (newEvents, oldEvents) => {
|
||||
if (myChartInstance) {
|
||||
myChartInstance.dispose();
|
||||
myChartInstance = null;
|
||||
// 移除旧事件
|
||||
oldEvents.forEach(eventName => {
|
||||
myChartInstance.off(eventName);
|
||||
});
|
||||
// 注册新事件
|
||||
newEvents.forEach(eventName => {
|
||||
if (eventMap[eventName]) {
|
||||
myChartInstance.on(eventName, (params) => {
|
||||
emit(eventMap[eventName], params);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// 监听 theme 变化
|
||||
watch(() => props.theme, (newTheme) => {
|
||||
if (myChartInstance) {
|
||||
cleanup();
|
||||
initChart();
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
cleanup();
|
||||
})
|
||||
|
||||
// 暴露实例给父组件
|
||||
defineExpose({
|
||||
getInstance: () => myChartInstance,
|
||||
resize: handleResize,
|
||||
dispose: cleanup
|
||||
})
|
||||
</script>
|
||||
Loading…
Reference in New Issue