index.ts 2.6 KB

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