feat: base 优化xtChart

This commit is contained in:
caoqianming 2025-11-06 16:08:56 +08:00
parent 75c9087f25
commit ac5ca4ba81
1 changed files with 121 additions and 11 deletions

View File

@ -1,42 +1,152 @@
<template> <template>
<div ref="myChart" :style="{ width: width, height: height }"></div> <div ref="myChart" :style="{ width: width, height: height }"></div>
</template> </template>
<script setup> <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 * as echarts from "echarts";
import echartTheme from "@/assets/echarts_theme.json"; 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({ const props = defineProps({
option: { type: Object, default: () => ({}) }, option: { type: Object, default: () => ({}) },
theme: { type: String, default: "essos" }, theme: { type: String, default: "essos" },
width: { type: String, default: "100%" }, 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) const myChart = ref(null)
let myChartInstance = 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) { if (props.theme in echartTheme) {
echarts.registerTheme(props.theme, echartTheme[props.theme]); echarts.registerTheme(props.theme, echartTheme[props.theme]);
} else{ } else {
console.warn("echarts未找到该主题") console.warn("echarts未找到该主题:", props.theme)
} }
myChartInstance = echarts.init(myChart.value, props.theme); myChartInstance = echarts.init(myChart.value, props.theme);
myChartInstance.setOption(props.option); 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) => { watch(() => props.option, (newOption) => {
if (myChartInstance) { if (myChartInstance) {
myChartInstance.setOption(newOption); myChartInstance.setOption(newOption);
} }
}, { deep: true }) }, { deep: true })
onUnmounted(() => { // events
// watch(() => props.events, (newEvents, oldEvents) => {
if (myChartInstance) { 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> </script>