useECharts.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import type { EChartsOption } from 'echarts';
  2. import type { Ref } from 'vue';
  3. import { useTimeoutFn } from '/@/hooks/core/useTimeout';
  4. import { tryOnUnmounted } from '@vueuse/core';
  5. import { unref, nextTick, watch, computed, ref } from 'vue';
  6. import { useDebounceFn } from '@vueuse/core';
  7. import { useEventListener } from '/@/hooks/event/useEventListener';
  8. import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
  9. import echarts from '/@/utils/lib/echarts';
  10. import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  11. export function useECharts(elRef: Ref<HTMLDivElement>, theme: 'light' | 'dark' | 'default' = 'default') {
  12. console.log("---useECharts---初始化加载---")
  13. const { getDarkMode: getSysDarkMode } = useRootSetting();
  14. const getDarkMode = computed(() => {
  15. return theme === 'default' ? getSysDarkMode.value : theme;
  16. });
  17. let chartInstance: echarts.ECharts | null = null;
  18. let resizeFn: Fn = resize;
  19. const cacheOptions = ref({}) as Ref<EChartsOption>;
  20. let removeResizeFn: Fn = () => {};
  21. resizeFn = useDebounceFn(resize, 200);
  22. const getOptions = computed(() => {
  23. if (getDarkMode.value !== 'dark') {
  24. return cacheOptions.value as EChartsOption;
  25. }
  26. return {
  27. backgroundColor: 'transparent',
  28. ...cacheOptions.value,
  29. } as EChartsOption;
  30. });
  31. function initCharts(t = theme) {
  32. const el = unref(elRef);
  33. if (!el || !unref(el)) {
  34. return;
  35. }
  36. chartInstance = echarts.init(el, t, );
  37. const { removeEvent } = useEventListener({
  38. el: window,
  39. name: 'resize',
  40. listener: resizeFn,
  41. });
  42. removeResizeFn = removeEvent;
  43. const { widthRef, screenEnum } = useBreakpoint();
  44. if (unref(widthRef) <= screenEnum.MD || el.offsetHeight === 0) {
  45. useTimeoutFn(() => {
  46. resizeFn();
  47. }, 30);
  48. }
  49. }
  50. function setOptions(options: EChartsOption, clear = true) {
  51. cacheOptions.value = options;
  52. if (unref(elRef)?.offsetHeight === 0) {
  53. useTimeoutFn(() => {
  54. setOptions(unref(getOptions));
  55. }, 30);
  56. return;
  57. }
  58. nextTick(() => {
  59. useTimeoutFn(() => {
  60. if (!chartInstance) {
  61. initCharts(getDarkMode.value as 'default');
  62. if (!chartInstance) return;
  63. }
  64. clear && chartInstance?.clear();
  65. chartInstance?.setOption(unref(getOptions));
  66. }, 30);
  67. });
  68. }
  69. function resize() {
  70. chartInstance?.resize();
  71. }
  72. watch(
  73. () => getDarkMode.value,
  74. (theme) => {
  75. if (chartInstance) {
  76. chartInstance.dispose();
  77. initCharts(theme as 'default');
  78. setOptions(cacheOptions.value);
  79. }
  80. }
  81. );
  82. tryOnUnmounted(() => {
  83. if (!chartInstance) return;
  84. removeResizeFn();
  85. chartInstance.dispose();
  86. chartInstance = null;
  87. });
  88. function getInstance(): echarts.ECharts | null {
  89. if (!chartInstance) {
  90. initCharts(getDarkMode.value as 'default');
  91. }
  92. return chartInstance;
  93. }
  94. return {
  95. setOptions,
  96. resize,
  97. echarts,
  98. getInstance,
  99. };
  100. }