Blame view

Yi.Vben5.Vue3/packages/effects/plugins/src/echarts/use-echarts.ts 2.69 KB
515fceeb   “wangming”   框架初始化
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  import type { EChartsOption } from 'echarts';
  
  import type { Ref } from 'vue';
  
  import type { Nullable } from '@vben/types';
  
  import type EchartsUI from './echarts-ui.vue';
  
  import { computed, nextTick, watch } from 'vue';
  
  import { usePreferences } from '@vben/preferences';
  
  import {
    tryOnUnmounted,
    useDebounceFn,
    useResizeObserver,
    useTimeoutFn,
    useWindowSize,
  } from '@vueuse/core';
  
  import echarts from './echarts';
  
  type EchartsUIType = typeof EchartsUI | undefined;
  
  type EchartsThemeType = 'dark' | 'light' | null;
  
  function useEcharts(chartRef: Ref<EchartsUIType>) {
    let chartInstance: echarts.ECharts | null = null;
    let cacheOptions: EChartsOption = {};
  
    const { isDark } = usePreferences();
    const { height, width } = useWindowSize();
    const resizeHandler: () => void = useDebounceFn(resize, 200);
  
    const getOptions = computed((): EChartsOption => {
      if (!isDark.value) {
        return {};
      }
  
      return {
        backgroundColor: 'transparent',
      };
    });
  
    const initCharts = (t?: EchartsThemeType) => {
      const el = chartRef?.value?.$el;
      if (!el) {
        return;
      }
      chartInstance = echarts.init(el, t || isDark.value ? 'dark' : null);
  
      return chartInstance;
    };
  
    const renderEcharts = (
      options: EChartsOption,
      clear = true,
    ): Promise<Nullable<echarts.ECharts>> => {
      cacheOptions = options;
      const currentOptions = {
        ...options,
        ...getOptions.value,
      };
      return new Promise((resolve) => {
        if (chartRef.value?.offsetHeight === 0) {
          useTimeoutFn(async () => {
            resolve(await renderEcharts(currentOptions));
          }, 30);
          return;
        }
        nextTick(() => {
          useTimeoutFn(() => {
            if (!chartInstance) {
              const instance = initCharts();
              if (!instance) return;
            }
            clear && chartInstance?.clear();
            chartInstance?.setOption(currentOptions);
            resolve(chartInstance);
          }, 30);
        });
      });
    };
  
    function resize(withAnimation = true) {
      chartInstance?.resize({
        animation: withAnimation
          ? {
              duration: 300,
              easing: 'quadraticIn',
            }
          : undefined,
      });
    }
  
    watch([width, height], () => {
      resizeHandler?.();
    });
  
    useResizeObserver(chartRef as never, resizeHandler);
  
    watch(isDark, () => {
      if (chartInstance) {
        chartInstance.dispose();
        initCharts();
        renderEcharts(cacheOptions);
        resize();
      }
    });
  
    tryOnUnmounted(() => {
      // 销毁实例,释放资源
      chartInstance?.dispose();
    });
    return {
      renderEcharts,
      resize,
      getChartInstance: () => chartInstance,
    };
  }
  
  export { useEcharts };
  
  export type { EchartsUIType };