useECharts.ts
1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
import { unref, Ref, nextTick } from 'vue';
import type { EChartOption, ECharts } from 'echarts';
import echarts from 'echarts';
import { useDebounce } from '/@/hooks/core/useDebounce';
import { useEventListener } from '/@/hooks/event/useEventListener';
import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
export type { EChartOption, ECharts };
export function useECharts(
elRef: Ref<HTMLDivElement>,
theme: 'light' | 'dark' | 'default' = 'light'
) {
let chartInstance: Nullable<ECharts> = null;
let resizeFn: Fn = resize;
let removeResizeFn: Fn = () => {};
const [debounceResize] = useDebounce(resize, 200);
resizeFn = debounceResize;
function init() {
const el = unref(elRef);
if (!el || !unref(el)) {
return;
}
chartInstance = echarts.init(el, theme);
const { removeEvent } = useEventListener({
el: window,
name: 'resize',
listener: resizeFn,
});
removeResizeFn = removeEvent;
const { widthRef, screenEnum } = useBreakpoint();
if (unref(widthRef) <= screenEnum.MD) {
useTimeoutFn(() => {
resizeFn();
}, 30);
}
}
function setOptions(options: any, clear = true) {
nextTick(() => {
useTimeoutFn(() => {
if (!chartInstance) {
init();
if (!chartInstance) return;
}
clear && chartInstance.clear();
chartInstance && chartInstance.setOption(options);
}, 30);
});
}
function resize() {
if (!chartInstance) return;
chartInstance.resize();
}
tryOnUnmounted(() => {
if (!chartInstance) return;
removeResizeFn();
chartInstance.dispose();
chartInstance = null;
});
return {
setOptions,
echarts,
resize,
};
}