Sanakey
2024-08-02 1ba88a00d3c7bb0f16a73feaa5ffcf7c1635e0ea
提交 | 用户 | age
215d8b 1 import type { EChartsOption } from 'echarts';
V 2 import type { Ref } from 'vue';
95abe0 3 import { computed, nextTick, ref, unref, watch } from 'vue';
fa1836 4 import { useTimeoutFn } from '@vben/hooks';
8e5a6b 5 import { tryOnUnmounted, useDebounceFn } from '@vueuse/core';
bab28a 6 import { useEventListener } from '@/hooks/event/useEventListener';
X 7 import { useBreakpoint } from '@/hooks/event/useBreakpoint';
8 import echarts from '@/utils/lib/echarts';
9 import { useRootSetting } from '@/hooks/setting/useRootSetting';
10 import { useMenuSetting } from '@/hooks/setting/useMenuSetting';
370b12 11
21d0ed 12 export function useECharts(
V 13   elRef: Ref<HTMLDivElement>,
56a966 14   theme: 'light' | 'dark' | 'default' = 'default',
21d0ed 15 ) {
93812f 16   const { getDarkMode: getSysDarkMode } = useRootSetting();
e962fa 17   const { getCollapsed } = useMenuSetting();
93812f 18
19   const getDarkMode = computed(() => {
20     return theme === 'default' ? getSysDarkMode.value : theme;
21   });
a09a0e 22   let chartInstance: echarts.ECharts | null = null;
21d0ed 23   let resizeFn: Fn = resize;
9035fd 24   const cacheOptions = ref({}) as Ref<EChartsOption>;
70fba7 25   let removeResizeFn: Fn = () => {};
21d0ed 26
203729 27   resizeFn = useDebounceFn(resize, 200);
21d0ed 28
9035fd 29   const getOptions = computed(() => {
fb6c76 30     if (getDarkMode.value !== 'dark') {
9035fd 31       return cacheOptions.value as EChartsOption;
5b8eb4 32     }
fb6c76 33     return {
34       backgroundColor: 'transparent',
35       ...cacheOptions.value,
9035fd 36     } as EChartsOption;
fb6c76 37   });
5b8eb4 38
V 39   function initCharts(t = theme) {
21d0ed 40     const el = unref(elRef);
V 41     if (!el || !unref(el)) {
42       return;
43     }
5cbfb2 44
5b8eb4 45     chartInstance = echarts.init(el, t);
d9b196 46     const { removeEvent } = useEventListener({
21d0ed 47       el: window,
V 48       name: 'resize',
49       listener: resizeFn,
50     });
70fba7 51     removeResizeFn = removeEvent;
95abe0 52
53     const resizeObserver = new ResizeObserver(resizeFn);
54     resizeObserver.observe(el);
55
21d0ed 56     const { widthRef, screenEnum } = useBreakpoint();
5cbfb2 57     if (unref(widthRef) <= screenEnum.MD || el.offsetHeight === 0) {
d9b196 58       useTimeoutFn(() => {
21d0ed 59         resizeFn();
52ee35 60       }, 30);
21d0ed 61     }
V 62   }
63
370b12 64   function setOptions(options: EChartsOption, clear = true) {
5b8eb4 65     cacheOptions.value = options;
3a1ec7 66     return new Promise((resolve) => {
L 67       if (unref(elRef)?.offsetHeight === 0) {
68         useTimeoutFn(() => {
69           setOptions(unref(getOptions));
70           resolve(null);
95abe0 71         }, 50);
3a1ec7 72       }
L 73       nextTick(() => {
74         useTimeoutFn(() => {
75           if (!chartInstance) {
76             initCharts(getDarkMode.value as 'default');
6d9585 77
3a1ec7 78             if (!chartInstance) return;
L 79           }
80           clear && chartInstance?.clear();
52ee35 81
3a1ec7 82           chartInstance?.setOption(unref(getOptions));
L 83           resolve(null);
84         }, 30);
85       });
21d0ed 86     });
V 87   }
88
89   function resize() {
e073b4 90     chartInstance?.resize({
C 91       animation: {
92         duration: 300,
93         easing: 'quadraticIn',
94       },
95     });
21d0ed 96   }
bb3b8f 97
5b8eb4 98   watch(
V 99     () => getDarkMode.value,
100     (theme) => {
101       if (chartInstance) {
102         chartInstance.dispose();
c9089c 103         initCharts(theme as 'default');
5b8eb4 104         setOptions(cacheOptions.value);
V 105       }
56a966 106     },
5b8eb4 107   );
V 108
e962fa 109   watch(getCollapsed, (_) => {
110     useTimeoutFn(() => {
111       resizeFn();
112     }, 300);
113   });
114
21d0ed 115   tryOnUnmounted(() => {
bb3b8f 116     if (!chartInstance) return;
6d9585 117     removeResizeFn();
21d0ed 118     chartInstance.dispose();
6d9585 119     chartInstance = null;
21d0ed 120   });
bb3b8f 121
fb6c76 122   function getInstance(): echarts.ECharts | null {
123     if (!chartInstance) {
124       initCharts(getDarkMode.value as 'default');
125     }
126     return chartInstance;
127   }
128
21d0ed 129   return {
V 130     setOptions,
6d9585 131     resize,
370b12 132     echarts,
fb6c76 133     getInstance,
21d0ed 134   };
V 135 }