80 lines
1.7 KiB
JavaScript
80 lines
1.7 KiB
JavaScript
|
|
import { nextTick, onBeforeUnmount, onMounted, watch } from 'vue'
|
||
|
|
import { init } from 'echarts/core'
|
||
|
|
|
||
|
|
export function useEcharts(chartElement, chartOptions) {
|
||
|
|
let chartInstance = null
|
||
|
|
let resizeObserver = null
|
||
|
|
let renderFrame = 0
|
||
|
|
|
||
|
|
function renderChart() {
|
||
|
|
if (!chartElement.value) {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if (!chartInstance) {
|
||
|
|
chartInstance = init(chartElement.value, null, { renderer: 'canvas' })
|
||
|
|
chartInstance.resize()
|
||
|
|
}
|
||
|
|
chartInstance.setOption(chartOptions.value, true)
|
||
|
|
}
|
||
|
|
|
||
|
|
function handleResize() {
|
||
|
|
chartInstance?.resize()
|
||
|
|
}
|
||
|
|
|
||
|
|
function scheduleRender() {
|
||
|
|
if (typeof window === 'undefined') {
|
||
|
|
renderChart()
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if (renderFrame) {
|
||
|
|
window.cancelAnimationFrame(renderFrame)
|
||
|
|
}
|
||
|
|
renderFrame = window.requestAnimationFrame(() => {
|
||
|
|
renderFrame = 0
|
||
|
|
renderChart()
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
function bindResize() {
|
||
|
|
if (!chartElement.value) {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if (typeof ResizeObserver !== 'undefined') {
|
||
|
|
resizeObserver = new ResizeObserver(handleResize)
|
||
|
|
resizeObserver.observe(chartElement.value)
|
||
|
|
}
|
||
|
|
window.addEventListener('resize', handleResize)
|
||
|
|
}
|
||
|
|
|
||
|
|
function unbindResize() {
|
||
|
|
resizeObserver?.disconnect()
|
||
|
|
resizeObserver = null
|
||
|
|
window.removeEventListener('resize', handleResize)
|
||
|
|
}
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
renderChart()
|
||
|
|
bindResize()
|
||
|
|
})
|
||
|
|
|
||
|
|
onBeforeUnmount(() => {
|
||
|
|
unbindResize()
|
||
|
|
if (renderFrame && typeof window !== 'undefined') {
|
||
|
|
window.cancelAnimationFrame(renderFrame)
|
||
|
|
renderFrame = 0
|
||
|
|
}
|
||
|
|
if (chartInstance) {
|
||
|
|
chartInstance.dispose()
|
||
|
|
chartInstance = null
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
watch(chartOptions, () => {
|
||
|
|
nextTick(scheduleRender)
|
||
|
|
}, { deep: true })
|
||
|
|
|
||
|
|
return {
|
||
|
|
renderChart
|
||
|
|
}
|
||
|
|
}
|