Echart.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <script lang="ts" name="EChart" setup>
  2. import type { EChartsOption } from 'echarts'
  3. import echarts from '@/plugins/echarts'
  4. import { debounce } from 'lodash-es'
  5. import 'echarts-wordcloud'
  6. import { propTypes } from '@/utils/propTypes'
  7. import { PropType } from 'vue'
  8. import { useAppStore } from '@/store/modules/app'
  9. import { isString } from '@/utils/is'
  10. import { useDesign } from '@/hooks/web/useDesign'
  11. const { getPrefixCls, variables } = useDesign()
  12. const prefixCls = getPrefixCls('echart')
  13. const appStore = useAppStore()
  14. const props = defineProps({
  15. options: {
  16. type: Object as PropType<EChartsOption>,
  17. required: true
  18. },
  19. width: propTypes.oneOfType([Number, String]).def(''),
  20. height: propTypes.oneOfType([Number, String]).def('500px')
  21. })
  22. const isDark = computed(() => appStore.getIsDark)
  23. const theme = computed(() => {
  24. const echartTheme: boolean | string = unref(isDark) ? true : 'auto'
  25. return echartTheme
  26. })
  27. const options = computed(() => {
  28. return Object.assign(props.options, {
  29. darkMode: unref(theme)
  30. })
  31. })
  32. const elRef = ref<ElRef>()
  33. let echartRef: Nullable<echarts.ECharts> = null
  34. const contentEl = ref<Element>()
  35. const styles = computed(() => {
  36. const width = isString(props.width) ? props.width : `${props.width}px`
  37. const height = isString(props.height) ? props.height : `${props.height}px`
  38. return {
  39. width,
  40. height
  41. }
  42. })
  43. const initChart = () => {
  44. if (unref(elRef) && props.options) {
  45. echartRef = echarts.init(unref(elRef) as HTMLElement)
  46. echartRef?.setOption(unref(options))
  47. }
  48. }
  49. watch(
  50. () => options.value,
  51. (options) => {
  52. if (echartRef) {
  53. echartRef?.setOption(options)
  54. }
  55. },
  56. {
  57. deep: true
  58. }
  59. )
  60. const resizeHandler = debounce(() => {
  61. if (echartRef) {
  62. echartRef.resize()
  63. }
  64. }, 100)
  65. const contentResizeHandler = async (e: TransitionEvent) => {
  66. if (e.propertyName === 'width') {
  67. resizeHandler()
  68. }
  69. }
  70. onMounted(() => {
  71. initChart()
  72. window.addEventListener('resize', resizeHandler)
  73. contentEl.value = document.getElementsByClassName(`${variables.namespace}-layout-content`)[0]
  74. unref(contentEl) &&
  75. (unref(contentEl) as Element).addEventListener('transitionend', contentResizeHandler)
  76. })
  77. onBeforeUnmount(() => {
  78. window.removeEventListener('resize', resizeHandler)
  79. unref(contentEl) &&
  80. (unref(contentEl) as Element).removeEventListener('transitionend', contentResizeHandler)
  81. })
  82. onActivated(() => {
  83. if (echartRef) {
  84. echartRef.resize()
  85. }
  86. })
  87. </script>
  88. <template>
  89. <div ref="elRef" :class="[$attrs.class, prefixCls]" :style="styles"></div>
  90. </template>