无木
2021-06-04 fb6c76db535bd0c6305d03c0cff876a1f079100b
提交 | 用户 | age
215d8b 1 import type { EChartsOption } from 'echarts';
V 2 import type { Ref } from 'vue';
3
b49950 4 import { useTimeoutFn } from '/@/hooks/core/useTimeout';
2c6aa8 5 import { tryOnUnmounted } from '@vueuse/core';
215d8b 6 import { unref, nextTick, watch, computed, ref } from 'vue';
203729 7 import { useDebounceFn } from '@vueuse/core';
d9b196 8 import { useEventListener } from '/@/hooks/event/useEventListener';
21d0ed 9 import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
V 10
663d13 11 import echarts from '/@/utils/lib/echarts';
215d8b 12 import { useRootSetting } from '/@/hooks/setting/useRootSetting';
370b12 13
21d0ed 14 export function useECharts(
V 15   elRef: Ref<HTMLDivElement>,
16   theme: 'light' | 'dark' | 'default' = 'light'
17 ) {
5b8eb4 18   const { getDarkMode } = useRootSetting();
a09a0e 19   let chartInstance: echarts.ECharts | null = null;
21d0ed 20   let resizeFn: Fn = resize;
5b8eb4 21   const cacheOptions = ref<EChartsOption>({});
70fba7 22   let removeResizeFn: Fn = () => {};
21d0ed 23
203729 24   resizeFn = useDebounceFn(resize, 200);
21d0ed 25
fb6c76 26   const getOptions = computed((): EChartsOption => {
27     if (getDarkMode.value !== 'dark') {
28       return cacheOptions.value;
5b8eb4 29     }
fb6c76 30     return {
31       backgroundColor: 'transparent',
32       ...cacheOptions.value,
33     };
34   });
5b8eb4 35
V 36   function initCharts(t = theme) {
21d0ed 37     const el = unref(elRef);
V 38     if (!el || !unref(el)) {
39       return;
40     }
5cbfb2 41
5b8eb4 42     chartInstance = echarts.init(el, t);
d9b196 43     const { removeEvent } = useEventListener({
21d0ed 44       el: window,
V 45       name: 'resize',
46       listener: resizeFn,
47     });
70fba7 48     removeResizeFn = removeEvent;
21d0ed 49     const { widthRef, screenEnum } = useBreakpoint();
5cbfb2 50     if (unref(widthRef) <= screenEnum.MD || el.offsetHeight === 0) {
d9b196 51       useTimeoutFn(() => {
21d0ed 52         resizeFn();
52ee35 53       }, 30);
21d0ed 54     }
V 55   }
56
370b12 57   function setOptions(options: EChartsOption, clear = true) {
5b8eb4 58     cacheOptions.value = options;
5cbfb2 59     if (unref(elRef)?.offsetHeight === 0) {
V 60       useTimeoutFn(() => {
5b8eb4 61         setOptions(unref(getOptions));
5cbfb2 62       }, 30);
V 63       return;
64     }
21d0ed 65     nextTick(() => {
d9b196 66       useTimeoutFn(() => {
52ee35 67         if (!chartInstance) {
c9089c 68           initCharts(getDarkMode.value as 'default');
6d9585 69
V 70           if (!chartInstance) return;
52ee35 71         }
5cbfb2 72         clear && chartInstance?.clear();
52ee35 73
5b8eb4 74         chartInstance?.setOption(unref(getOptions));
21d0ed 75       }, 30);
V 76     });
77   }
78
79   function resize() {
5cbfb2 80     chartInstance?.resize();
21d0ed 81   }
bb3b8f 82
5b8eb4 83   watch(
V 84     () => getDarkMode.value,
85     (theme) => {
86       if (chartInstance) {
87         chartInstance.dispose();
c9089c 88         initCharts(theme as 'default');
5b8eb4 89         setOptions(cacheOptions.value);
V 90       }
91     }
92   );
93
21d0ed 94   tryOnUnmounted(() => {
bb3b8f 95     if (!chartInstance) return;
6d9585 96     removeResizeFn();
21d0ed 97     chartInstance.dispose();
6d9585 98     chartInstance = null;
21d0ed 99   });
bb3b8f 100
fb6c76 101   function getInstance(): echarts.ECharts | null {
102     if (!chartInstance) {
103       initCharts(getDarkMode.value as 'default');
104     }
105     return chartInstance;
106   }
107
21d0ed 108   return {
V 109     setOptions,
6d9585 110     resize,
370b12 111     echarts,
fb6c76 112     getInstance,
21d0ed 113   };
V 114 }