index.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <v-chart ref="vChartRef" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize>
  3. </v-chart>
  4. </template>
  5. <script setup lang="ts">
  6. import { PropType, reactive, watch, ref, nextTick } from 'vue'
  7. import config, { includes, MapDefaultConfig } from './config'
  8. import VChart from 'vue-echarts'
  9. import { use, registerMap, getMap } from 'echarts/core'
  10. import { EffectScatterChart, MapChart } from 'echarts/charts'
  11. import { CanvasRenderer } from 'echarts/renderers'
  12. import { useChartDataFetch } from '@/hooks'
  13. import { mergeTheme } from '@/packages/public/chart'
  14. import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  15. import { isPreview } from '@/utils'
  16. import mapJsonWithoutHainanIsLands from './mapWithoutHainanIsLands.json'
  17. import {
  18. DatasetComponent,
  19. GridComponent,
  20. TooltipComponent,
  21. LegendComponent,
  22. GeoComponent,
  23. VisualMapComponent
  24. } from 'echarts/components'
  25. const props = defineProps({
  26. themeSetting: {
  27. type: Object,
  28. required: true
  29. },
  30. themeColor: {
  31. type: Object,
  32. required: true
  33. },
  34. chartConfig: {
  35. type: Object as PropType<config>,
  36. required: true
  37. }
  38. })
  39. use([
  40. MapChart,
  41. DatasetComponent,
  42. CanvasRenderer,
  43. GridComponent,
  44. TooltipComponent,
  45. LegendComponent,
  46. GeoComponent,
  47. EffectScatterChart,
  48. VisualMapComponent
  49. ])
  50. const option = reactive({
  51. value: mergeTheme(props.chartConfig.option, props.themeSetting, includes)
  52. })
  53. const vChartRef = ref<typeof VChart>()
  54. //动态获取json注册地图
  55. const getGeojson = (regionId: string) => {
  56. return new Promise<boolean>((resolve, reject) => {
  57. import(`./mapGeojson/${regionId}.json`).then(data => {
  58. registerMap(regionId, { geoJSON: data.default as any, specialAreas: {} })
  59. resolve(true)
  60. })
  61. })
  62. }
  63. //异步时先注册空的 保证初始化不报错
  64. registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })
  65. // 进行更换初始化地图
  66. const registerMapInitAsync = async () => {
  67. await nextTick()
  68. await getGeojson(props.chartConfig.option.mapRegion.adcode)
  69. vEchartsSetOption()
  70. }
  71. registerMapInitAsync()
  72. const updateOptions = async () => {
  73. option.value = props.chartConfig.option
  74. }
  75. const vEchartsSetOption =()=>{
  76. vChartRef.value?.setOption(props.chartConfig.option)
  77. }
  78. const dataSetHandle = async (dataset: any) => {
  79. props.chartConfig.option.series.forEach((item: any) => {
  80. if (item.type === 'effectScatter' && dataset.point) item.data = dataset.point
  81. else if (item.type === 'map' && dataset.point) item.data = dataset.map
  82. })
  83. updateOptions()
  84. }
  85. // 更换地图
  86. const mapGeoHandle = async (regionId: string) => {
  87. await getGeojson(regionId)
  88. props.chartConfig.option.geo.map = regionId
  89. props.chartConfig.option.series.forEach((item: any) => {
  90. if (item.type === 'map') item.map = regionId
  91. })
  92. updateOptions()
  93. }
  94. //是否显示南海群岛
  95. const mapTypeHandle = async (show: boolean) => {
  96. if (show) {
  97. await getGeojson('china')
  98. } else {
  99. registerMap('china', { geoJSON: mapJsonWithoutHainanIsLands as any, specialAreas: {} })
  100. }
  101. vEchartsSetOption()
  102. }
  103. //层级发生变化
  104. const mapZoomHandle = async (newData: number) => {
  105. props.chartConfig.option.series[1].zoom = newData
  106. updateOptions()
  107. }
  108. //监听数据发生变化
  109. watch(
  110. () => props.chartConfig.option.dataset,
  111. newData => {
  112. dataSetHandle(newData)
  113. },
  114. {
  115. immediate: true,
  116. deep: false
  117. }
  118. )
  119. //监听是否显示南海群岛
  120. watch(
  121. () => props.chartConfig.option.mapRegion.showHainanIsLands,
  122. newData => {
  123. mapTypeHandle(newData)
  124. },
  125. {
  126. deep: false
  127. }
  128. )
  129. //监听地图区域发生变化
  130. watch(
  131. () => props.chartConfig.option.mapRegion.adcode,
  132. newData => {
  133. mapGeoHandle(newData)
  134. },
  135. {
  136. deep: false
  137. }
  138. )
  139. //监听大小发生变化
  140. watch(
  141. () => props.chartConfig.option.geo.zoom,
  142. newData => {
  143. mapZoomHandle(newData)
  144. },
  145. {
  146. deep: false
  147. }
  148. )
  149. // 预览
  150. useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
  151. console.log('预览', newData)
  152. dataSetHandle(newData)
  153. })
  154. </script>