Commit d61d4d358399c9289238573d5cb8c328223bc8be

Authored by fengwotao
1 parent 0f13f3c4

feat(src/packages): 图表3d地图也支持下钻 修改地图注册方式为服务端接口请求

@@ -24,7 +24,8 @@ const selectOptions = reactive({ @@ -24,7 +24,8 @@ const selectOptions = reactive({
24 const selectValues = reactive({ 24 const selectValues = reactive({
25 provinceValue: 'china', 25 provinceValue: 'china',
26 cityValue: null, 26 cityValue: null,
27 - countyValue: null 27 + countyValue: null,
  28 + levelStr: areaEnum.COUNTRY
28 }) 29 })
29 30
30 const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { 31 const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => {
@@ -49,13 +50,15 @@ onMounted(async () => { @@ -49,13 +50,15 @@ onMounted(async () => {
49 const onHandleSelectProvince = async (value: number | string) => { 50 const onHandleSelectProvince = async (value: number | string) => {
50 selectValues.cityValue = null 51 selectValues.cityValue = null
51 selectValues.countyValue = null 52 selectValues.countyValue = null
52 - if (value === 'china') return 53 + if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY)
53 selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value as any) 54 selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value as any)
  55 + selectValues.levelStr = areaEnum.PROVINCE
54 } 56 }
55 57
56 const onHandleSelectCity = async (value: number) => { 58 const onHandleSelectCity = async (value: number) => {
57 selectValues.countyValue = null 59 selectValues.countyValue = null
58 selectOptions.countryOptions = await getAreaLists(areaEnum.COUNTY, value) 60 selectOptions.countryOptions = await getAreaLists(areaEnum.COUNTY, value)
  61 + selectValues.levelStr = areaEnum.CITY
59 } 62 }
60 63
61 const onHandleSubmit = () => { 64 const onHandleSubmit = () => {
@@ -7,9 +7,11 @@ import dataMaps from './data.json' @@ -7,9 +7,11 @@ import dataMaps from './data.json'
7 7
8 //省市区枚举 8 //省市区枚举
9 export const enum areaEnum { 9 export const enum areaEnum {
10 - PROVINCE = 'PROVINCE',  
11 - CITY = 'CITY',  
12 - COUNTY = 'COUNTY' 10 + PROVINCE = 'PROVINCE', //省份
  11 + CITY = 'CITY', //城市
  12 + COUNTY = 'COUNTY', //县
  13 + COUNTRY = 'COUNTRY', //国家
  14 + TOWN = 'TOWN' //镇
13 } 15 }
14 16
15 export const includes = [] 17 export const includes = []
@@ -24,34 +26,28 @@ export const option = { @@ -24,34 +26,28 @@ export const option = {
24 mapRegion: { 26 mapRegion: {
25 adcode: 'china', 27 adcode: 'china',
26 showHainanIsLands: true, 28 showHainanIsLands: true,
27 - saveSelect: {} 29 + saveSelect: {
  30 + levelStr: areaEnum.COUNTRY
  31 + }
28 }, 32 },
29 tooltip: { 33 tooltip: {
30 show: true 34 show: true
31 }, 35 },
32 geo3D: { 36 geo3D: {
  37 + show: false, // 隐藏该层,为true时会导致出现两个地图
33 map: 'centerMap', 38 map: 'centerMap',
34 roam: true, 39 roam: true,
35 regionHeight: 0, 40 regionHeight: 0,
36 - label: {  
37 - show: true,  
38 - textStyle: {  
39 - fontSize: 14,  
40 - color: 'blue',  
41 - borderWidth: 0,  
42 - borderColor: '#000'  
43 - }  
44 - },  
45 emphasis: { 41 emphasis: {
46 label: { 42 label: {
47 show: true, 43 show: true,
48 textStyle: { 44 textStyle: {
49 - color: 'black',  
50 - fontSize: 32 45 + color: '#000',
  46 + fontSize: 14
51 } 47 }
52 }, 48 },
53 itemStyle: { 49 itemStyle: {
54 - color: '#fd9c5a' 50 + color: '#ff0'
55 } 51 }
56 } 52 }
57 }, 53 },
@@ -63,8 +59,10 @@ export const option = { @@ -63,8 +59,10 @@ export const option = {
63 regionHeight: 3, 59 regionHeight: 3,
64 label: { 60 label: {
65 show: true, 61 show: true,
66 - color: 'yellow',  
67 - fontSize: 14 62 + textStyle: {
  63 + color: '#fff',
  64 + fontSize: 14
  65 + }
68 }, 66 },
69 itemStyle: { 67 itemStyle: {
70 color: 'green', 68 color: 'green',
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <!-- Echarts 全局设置 --> 2 <!-- Echarts 全局设置 -->
3 <global-setting :optionData="optionData"></global-setting> 3 <global-setting :optionData="optionData"></global-setting>
4 <CollapseItem name="地图" :expanded="true"> 4 <CollapseItem name="地图" :expanded="true">
5 - <!-- <SettingItemBox name="开启下钻"> 5 + <SettingItemBox name="开启下钻">
6 <SettingItem name=""> 6 <SettingItem name="">
7 <n-switch v-model:value="optionData.drillingIn" size="small"></n-switch> 7 <n-switch v-model:value="optionData.drillingIn" size="small"></n-switch>
8 </SettingItem> 8 </SettingItem>
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 placeholder="请输入" 34 placeholder="请输入"
35 ></n-input-number> 35 ></n-input-number>
36 </SettingItem> 36 </SettingItem>
37 - </SettingItemBox> --> 37 + </SettingItemBox>
38 <SelectCity :optionData="optionData" :drillingIn="optionData.drillingIn" @submit="onHandleSelectValues" /> 38 <SelectCity :optionData="optionData" :drillingIn="optionData.drillingIn" @submit="onHandleSelectValues" />
39 <SettingItemBox name="颜色"> 39 <SettingItemBox name="颜色">
40 <SettingItem name="区域颜色"> 40 <SettingItem name="区域颜色">
@@ -69,11 +69,15 @@ @@ -69,11 +69,15 @@
69 <n-switch v-model:value="seriesList[0].label.show" size="small"></n-switch> 69 <n-switch v-model:value="seriesList[0].label.show" size="small"></n-switch>
70 </SettingItem> 70 </SettingItem>
71 <SettingItem name="颜色"> 71 <SettingItem name="颜色">
72 - <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[0].label.color"></n-color-picker> 72 + <n-color-picker
  73 + size="small"
  74 + :modes="['hex']"
  75 + v-model:value="seriesList[0].label.textStyle.color"
  76 + ></n-color-picker>
73 </SettingItem> 77 </SettingItem>
74 <SettingItem name="大小"> 78 <SettingItem name="大小">
75 <n-input-number 79 <n-input-number
76 - v-model:value="seriesList[0].label.fontSize" 80 + v-model:value="seriesList[0].label.textStyle.fontSize"
77 :min="0" 81 :min="0"
78 size="small" 82 size="small"
79 placeholder="请输入" 83 placeholder="请输入"
@@ -4,12 +4,12 @@ @@ -4,12 +4,12 @@
4 </template> 4 </template>
5 5
6 <script setup lang="ts"> 6 <script setup lang="ts">
7 -import { onMounted, ref, nextTick, PropType, toRefs, watch } from 'vue' 7 +import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue'
8 import * as echarts from 'echarts' 8 import * as echarts from 'echarts'
9 import { registerMap } from 'echarts/core' 9 import { registerMap } from 'echarts/core'
10 import 'echarts-gl' 10 import 'echarts-gl'
11 -import config from './config'  
12 -import cityMap from '../OverrideMapBase/mapGeojson/china-main-city-map.json' 11 +import config, { areaEnum } from './config'
  12 +import { getGeoJsonMap } from '@/api/external/common'
13 13
14 type historyDataType = { name: string; code: string } 14 type historyDataType = { name: string; code: string }
15 15
@@ -71,40 +71,76 @@ props.chartConfig.option = { @@ -71,40 +71,76 @@ props.chartConfig.option = {
71 } 71 }
72 72
73 //地图点击返回 73 //地图点击返回
74 -const watchAdcode = () => { 74 +const watchAdcode = async () => {
75 if (props.chartConfig.option.drillingIn) { 75 if (props.chartConfig.option.drillingIn) {
76 - const code = historyData.value.at(-2)?.code  
77 - props.chartConfig.option.mapRegion.adcode = code ? code : 'china'  
78 - historyData.value.pop() 76 + saveLevelStr.level = saveLevelStr.parentInfo.level
  77 + await getGeojson(saveLevelStr.parentInfo.adcode)
  78 + props.chartConfig.option.geo3D.map =
  79 + saveLevelStr.parentInfo.adcode === 100000 ? 'china' : saveLevelStr.parentInfo.adcode
  80 + props.chartConfig.option.series.forEach((item: any) => {
  81 + if (item.type === 'map3D')
  82 + item.map = saveLevelStr.parentInfo.adcode === 100000 ? 'china' : saveLevelStr.parentInfo.adcode
  83 + item.data = props.chartConfig.option.dataset
  84 + })
  85 + handleSetOption(chartInstance.value, props.chartConfig.option)
79 } 86 }
80 } 87 }
81 88
  89 +const regionMapParentArea = {
  90 + [areaEnum.PROVINCE]: areaEnum.COUNTRY, //省份的上一级 中国
  91 + [areaEnum.CITY]: areaEnum.PROVINCE, //城市的上一级 省份
  92 + [areaEnum.COUNTY]: areaEnum.CITY, //县或者区的上一级 城市
  93 + [areaEnum.TOWN]: areaEnum.COUNTY //镇的上一级 县或者区
  94 +}
  95 +
82 //地图点击 96 //地图点击
83 const handleMap3DClick = async (params: any) => { 97 const handleMap3DClick = async (params: any) => {
84 if (props.chartConfig.option.drillingIn) { 98 if (props.chartConfig.option.drillingIn) {
85 const { name } = params 99 const { name } = params
86 - saveSelectValue.value = name  
87 - const findAdcode = (cityMap as any)[name]  
88 - if (!findAdcode) return  
89 - props.chartConfig.option.mapRegion.adcode = findAdcode  
90 - historyData.value.push({  
91 - name,  
92 - code: findAdcode 100 + saveGeojson.value?.features.forEach((item: any) => {
  101 + if (item.properties.name === name) {
  102 + const level = item.properties.level.toUpperCase()
  103 + const adcode = item.properties.adcode
  104 + props.chartConfig.option.mapRegion.adcode = adcode
  105 + saveLevelStr.level = level
  106 + saveLevelStr.parentInfo.adcode = item.properties.parent.adcode //保存上一级的地区编码
  107 + saveLevelStr.parentInfo.level = (regionMapParentArea as any)[level] //保存上一级的行政级别
  108 + }
93 }) 109 })
94 } 110 }
95 } 111 }
96 112
  113 +const saveGeojson: any = ref({}) // 保存geojson
  114 +
  115 +const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000
  116 +
  117 +const saveLevelStr = reactive({
  118 + // 保存行政级别和上一级的adcode和level
  119 + level: '',
  120 + parentInfo: {
  121 + adcode: 0,
  122 + level: ''
  123 + }
  124 +})
  125 +
97 //动态获取geojson文件进行注册地图 126 //动态获取geojson文件进行注册地图
98 -const getGeojson = (regionId: string) => { 127 +const getGeojson = (regionId: any) => {
99 try { 128 try {
100 return new Promise<boolean>(resolve => { 129 return new Promise<boolean>(resolve => {
101 - import(`../OverrideMapBase/mapGeojson/${regionId}.json`).then(data => {  
102 - registerMap(regionId, { geoJSON: data.default as any, specialAreas: {} }) 130 + const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
  131 + getGeoJsonMap(
  132 + regionId === 'china' ? chinaDefaultRegionId.value : regionId,
  133 + !saveLevelStr.level ? levelStr : saveLevelStr.level
  134 + ).then(res => {
  135 + const { geoJson, name, code, level } = res.data
  136 + const geoJsonFile = JSON.parse(geoJson)
  137 + saveGeojson.value = geoJsonFile
  138 + registerMap(level === areaEnum.COUNTRY ? name : code, { geoJSON: geoJsonFile as any, specialAreas: {} })
103 resolve(true) 139 resolve(true)
104 }) 140 })
105 }) 141 })
106 - } catch (e) {  
107 - console.log(e) 142 + } catch (error) {
  143 + console.error('注册地图出错', error)
108 } 144 }
109 } 145 }
110 146
@@ -126,8 +162,7 @@ const initMap = async () => { @@ -126,8 +162,7 @@ const initMap = async () => {
126 handleSetOption(chartInstance.value, props.chartConfig.option) 162 handleSetOption(chartInstance.value, props.chartConfig.option)
127 }) 163 })
128 chartInstance.value.on('click', (e: any) => { 164 chartInstance.value.on('click', (e: any) => {
129 - console.log(`地图点击`, e)  
130 - // handleMap3DClick(e) 165 + handleMap3DClick(e)
131 }) 166 })
132 } 167 }
133 168
@@ -137,8 +172,8 @@ const handleSetOption = (instance: any, option: any) => { @@ -137,8 +172,8 @@ const handleSetOption = (instance: any, option: any) => {
137 try { 172 try {
138 instance.clear() 173 instance.clear()
139 instance.setOption(option) 174 instance.setOption(option)
140 - // eslint-disable-next-line no-empty  
141 - } finally { 175 + } catch (error) {
  176 + console.error('触发渲染出错', error)
142 } 177 }
143 } 178 }
144 179
@@ -161,7 +196,7 @@ watch( @@ -161,7 +196,7 @@ watch(
161 }) 196 })
162 handleSetOption(chartInstance.value, props.chartConfig.option) 197 handleSetOption(chartInstance.value, props.chartConfig.option)
163 } catch (error) { 198 } catch (error) {
164 - console.log(error) 199 + console.log('展示区域发生变化出错', error)
165 } 200 }
166 }, 201 },
167 { 202 {
@@ -152,7 +152,7 @@ const getGeojson = async (regionId: any) => { @@ -152,7 +152,7 @@ const getGeojson = async (regionId: any) => {
152 } 152 }
153 153
154 //异步时先注册空的 保证初始化不报错 154 //异步时先注册空的 保证初始化不报错
155 -registerMap(`${props.chartConfig.option.mapRegion.adcode}`, { geoJSON: {} as any, specialAreas: {} }) 155 +registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })
156 156
157 // 进行更换初始化地图 如果为china 单独处理 157 // 进行更换初始化地图 如果为china 单独处理
158 const registerMapInitAsync = async () => { 158 const registerMapInitAsync = async () => {