60 lines
1.0 KiB
Vue
60 lines
1.0 KiB
Vue
<script setup>
|
|
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
import * as echarts from "echarts";
|
|
let chart = null;
|
|
let resizeObserver = null;
|
|
const chartRef = ref();
|
|
const props = defineProps({
|
|
option: {
|
|
type: Object,
|
|
required: true
|
|
}
|
|
});
|
|
function applyOption(option) {
|
|
if (!chart || !option) {
|
|
return;
|
|
}
|
|
chart.clear();
|
|
chart.setOption(option);
|
|
}
|
|
onMounted(() => {
|
|
chart = echarts.init(chartRef.value, "t-theme");
|
|
applyOption(props.option);
|
|
resizeObserver = new ResizeObserver(() => {
|
|
chart?.resize();
|
|
});
|
|
resizeObserver.observe(chartRef.value);
|
|
nextTick(() => {
|
|
chart?.resize();
|
|
});
|
|
});
|
|
watch(
|
|
() => props.option,
|
|
(value) => {
|
|
applyOption(value);
|
|
},
|
|
{ deep: true }
|
|
);
|
|
onBeforeUnmount(() => {
|
|
if (resizeObserver) {
|
|
resizeObserver.disconnect();
|
|
resizeObserver = null;
|
|
}
|
|
if (chart) {
|
|
chart.dispose();
|
|
chart = null;
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div ref="chartRef" class="t-chart" />
|
|
</template>
|
|
|
|
<style scoped>
|
|
.t-chart {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|