// 导入 EChartsOption 类型 import type { EChartsOption } from 'echarts'; // 导入 Ref 类型 import type { Ref } from 'vue'; // 导入 useTimeoutFn 函数 import { useTimeoutFn } from '/@/hooks/core/useTimeout'; // 导入 tryOnUnmounted 函数 import { tryOnUnmounted } from '@vueuse/core'; // 导入 unref, nextTick, watch, computed, ref 函数 import { unref, nextTick, watch, computed, ref } from 'vue'; // 导入 useDebounceFn 函数 import { useDebounceFn } from '@vueuse/core'; // 导入 useEventListener 函数 import { useEventListener } from '/@/hooks/event/useEventListener'; // 导入 useBreakpoint 函数 import { useBreakpoint } from '/@/hooks/event/useBreakpoint'; // 导入 echarts import echarts from '/@/utils/lib/echarts'; // 导入 useRootSetting 函数 import { useRootSetting } from '/@/hooks/setting/useRootSetting'; // 定义 useECharts 函数,接收 elRef 和 theme 参数 export function useECharts( elRef: Ref, theme: 'light' | 'dark' | 'default' = 'light' ) { // 获取 getDarkMode 函数 const { getDarkMode } = useRootSetting(); // 定义 chartInstance 变量,初始值为 null let chartInstance: echarts.ECharts | null = null; // 定义 resizeFn 变量,初始值为 resize 函数 let resizeFn: Fn = resize; // 定义 cacheOptions 变量,初始值为空对象 const cacheOptions = ref({}) as Ref; // 定义 removeResizeFn 变量,初始值为空函数 let removeResizeFn: Fn = () => {}; // 使用 useDebounceFn 函数对 resize 函数进行防抖处理,延迟 200ms resizeFn = useDebounceFn(resize, 200); // 定义 getOptions 计算属性 const getOptions = computed(() => { // 如果不是暗黑模式,返回 cacheOptions 的值 if (getDarkMode.value !== 'dark') { return cacheOptions.value as EChartsOption; } // 如果是暗黑模式,返回带有透明背景色的 cacheOptions 的值 return { backgroundColor: 'transparent', ...cacheOptions.value, } as EChartsOption; }); // 定义 initCharts 函数,接收 t 参数,默认值为 theme function initCharts(t = theme) { // 获取 elRef 的值 const el = unref(elRef); // 如果 el 不存在,直接返回 if (!el || !unref(el)) { return; } // 使用 echarts.init 初始化图表实例 chartInstance = echarts.init(el, t); // 使用 useEventListener 监听窗口 resize 事件 const { removeEvent } = useEventListener({ el: window, name: 'resize', listener: resizeFn, }); // 设置 removeResizeFn 为 removeEvent removeResizeFn = removeEvent; // 使用 useBreakpoint 获取屏幕宽度和枚举值 const { widthRef, screenEnum } = useBreakpoint(); // 如果屏幕宽度小于等于 MD 或者元素高度为 0,延迟 30ms 执行 resizeFn if (unref(widthRef) <= screenEnum.MD || el.offsetHeight === 0) { useTimeoutFn(() => { resizeFn(); }, 30); } } // 定义 setOptions 函数,接收 options 和 clear 参数,默认值为 true function setOptions(options: EChartsOption, clear = true) { // 设置 cacheOptions 的值为 options cacheOptions.value = options; // 如果 elRef 的高度为 0,延迟 30ms 执行 setOptions 函数 if (unref(elRef)?.offsetHeight === 0) { useTimeoutFn(() => { setOptions(unref(getOptions)); }, 30); return; } // 在下一个 tick 执行 nextTick(() => { // 延迟 30ms 执行 useTimeoutFn(() => { // 如果 chartInstance 不存在,初始化图表实例 if (!chartInstance) { initCharts(getDarkMode.value as 'default'); if (!chartInstance) return; } // 如果 clear 为 true,清空图表实例 clear && chartInstance?.clear(); // 设置图表实例的选项 chartInstance?.setOption(unref(getOptions)); }, 30); }); } // 定义 resize 函数 function resize() { // 调用图表实例的 resize 方法 chartInstance?.resize(); } // 监听 getDarkMode.value 的变化 watch( () => getDarkMode.value, (theme) => { // 如果图表实例存在 if (chartInstance) { // 销毁图表实例 chartInstance.dispose(); // 重新初始化图表实例 initCharts(theme as 'default'); // 设置图表实例的选项 setOptions(cacheOptions.value); } } ); // 当组件卸载时执行 tryOnUnmounted(() => { // 如果图表实例不存在,直接返回 if (!chartInstance) return; // 移除 resize 事件监听 removeResizeFn(); // 销毁图表实例 chartInstance.dispose(); // 将 chartInstance 设置为 null chartInstance = null; }); // 定义 getInstance 函数 function getInstance(): echarts.ECharts | null { // 如果图表实例不存在,初始化图表实例 if (!chartInstance) { initCharts(getDarkMode.value as 'default'); } // 返回图表实例 return chartInstance; } // 定义 destory 函数 function destory() { // 如果图表实例不存在,直接返回 if (!chartInstance) return; // 销毁图表实例 chartInstance.dispose(); // 将 chartInstance 设置为 null chartInstance = null; } // 返回对象,包含 setOptions, resize, echarts, getInstance, destory 方法 return { setOptions, resize, echarts, getInstance, destory, }; }