<template>
<div class="content_body" ref="chartContainer">
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import { ref, markRaw, onMounted, onBeforeUnmount, watch, nextTick } from "vue";
import { ResizeObserverHelper } from '@/utils/resizeObserverHelper.js';
const props = defineProps({
yearData: {
type: String,
default: new Date().getFullYear().toString(),
},
});
watch(() => props.yearData, (newVal) => {
if (newVal) {
getPageData(newVal)
}
}, { immediate: false });
const chartContainer = ref(null);
const chart = ref(null);
const observer = ref(null);
const loading = ref(false);
function initChart (newData) {
try {
chart.value = markRaw(echarts.init(chartContainer.value));
updateChartData(newData)
observer.value = new ResizeObserverHelper(chartContainer.value, (width, height) => {
chart.value && chart.value.resize();
});
} catch (error) {
}
}
function updateChartData (newData) {
if (!chart.value) {
nextTick(() => {
initChart(newData);
});
return;
}
chart.value.setOption({})
}
function getPageData () {
scoreBarChart({ endYear: props.yearData }).then((res) => {
if (res.code == "200") {
updateChartData(res.data);
} else {
}
});
}
onMounted(() => {
getPageData();
})
onBeforeUnmount(() => {
if (chart.value) {
chart.value.dispose();
chart.value = null;
}
observer.value && observer.value.disconnect();
})
</script>
<style lang="scss" scoped>
.content_body {
height: calc(100% - 26px);
}
</style>
export class ResizeObserverHelper {
constructor(target, callback, debounceDelay = 200) {
this.target = typeof target === 'string' ? document.querySelector(target) : target;
this.callback = callback;
this.debounceDelay = debounceDelay;
this.debounceTimer = null;
this.resizeObserver = null;
this.init();
}
init() {
if (this.target === window) {
this.handleWindowResize();
return;
}
if (this.target instanceof HTMLElement) {
this.handleElementResize();
return;
}
throw new Error('Invalid target: must be HTMLElement, window, or CSS selector');
}
handleWindowResize() {
const handler = () => {
this.debouncedCallback(window.innerWidth, window.innerHeight);
};
window.addEventListener('resize', handler);
this.disconnect = () => window.removeEventListener('resize', handler);
handler();
}
handleElementResize() {
this.resizeObserver = new ResizeObserver((entries) => {
const { width, height } = entries[0].contentRect;
this.debouncedCallback(width, height);
});
this.resizeObserver.observe(this.target);
this.disconnect = () => this.resizeObserver.disconnect();
}
debouncedCallback = (width, height) => {
clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.callback(width, height);
}, this.debounceDelay);
};
disconnect() {
if (this.disconnect) this.disconnect();
clearTimeout(this.debounceTimer);
}
}