Commit 99e39109e9e97eeab44116c17b49a6ffc57c2d80

Authored by fengwotao
1 parent d18fe193

fix(src/packages): 3D地图,中国下钻到四川省,再下钻到成都市,成都市点击返回没有回显,再点击返回回显为全国地图

@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <!-- 原生方式,没有使用vue-echarts --> 2 <!-- 原生方式,没有使用vue-echarts -->
3 <n-space vertical> 3 <n-space vertical>
4 <n-spin :show="show"> 4 <n-spin :show="show">
5 - <div id="map3DId" :style="`width:${w}px;height:${h}px;`"></div> 5 + <div :style="`width:${w}px;height:${h}px;`" ref="map3DRef"></div>
6 </n-spin> 6 </n-spin>
7 </n-space> 7 </n-space>
8 </template> 8 </template>
@@ -29,6 +29,8 @@ const iconStr = ref( @@ -29,6 +29,8 @@ const iconStr = ref(
29 29
30 const { w, h } = toRefs(props.chartConfig.attr) 30 const { w, h } = toRefs(props.chartConfig.attr)
31 31
  32 +const map3DRef = ref()
  33 +
32 const show = ref(true) 34 const show = ref(true)
33 35
34 const chartInstance = ref() 36 const chartInstance = ref()
@@ -45,7 +47,7 @@ const toolBoxOption = ref({ @@ -45,7 +47,7 @@ const toolBoxOption = ref({
45 iconStyle: { 47 iconStyle: {
46 color: '' 48 color: ''
47 }, 49 },
48 - onclick: () => mapClickBack() 50 + onclick: () => watchAdcode()
49 } 51 }
50 } 52 }
51 }) 53 })
@@ -58,51 +60,40 @@ watch( @@ -58,51 +60,40 @@ watch(
58 toolBoxOption.value.feature.myFullButton.iconStyle.color = iconColor 60 toolBoxOption.value.feature.myFullButton.iconStyle.color = iconColor
59 toolBoxOption.value.right = iconDistanceRight 61 toolBoxOption.value.right = iconDistanceRight
60 toolBoxOption.value.top = iconDistanceTop 62 toolBoxOption.value.top = iconDistanceTop
  63 + },
  64 + {
  65 + deep: true
61 } 66 }
62 ) 67 )
63 68
64 -//追加右上角返回图标配置  
65 props.chartConfig.option = { 69 props.chartConfig.option = {
66 ...props.chartConfig.option, 70 ...props.chartConfig.option,
67 ...{ toolbox: toolBoxOption.value } 71 ...{ toolbox: toolBoxOption.value }
68 } 72 }
69 73
70 //地图点击返回 74 //地图点击返回
71 -const mapClickBack = async () => {  
72 - try {  
73 - if (props.chartConfig.option.drillingIn) {  
74 - //如果是从右边配置里设置的,比如点击四川省,然后点击返回  
75 - const savePopParent = saveHistoryParent.value.pop()  
76 - let saveAdcode = savePopParent?.adcode as string | number  
77 - saveLevelStr.level = savePopParent?.level  
78 - if (!savePopParent) {  
79 - saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode)  
80 - saveLevelStr.level = (regionMapParentArea as Recordable)[props.chartConfig.option.mapRegion.saveSelect.levelStr]  
81 - }  
82 - if (saveAdcode === 0) {  
83 - saveAdcode = 'china'  
84 - saveLevelStr.level = 'COUNTRY'  
85 - }  
86 - await registerGeojson(saveAdcode)  
87 - const adcode = saveAdcode === 100000 ? 'china' : saveAdcode  
88 - setMap3DPartOption(adcode)  
89 - handleSetOption(chartInstance.value, props.chartConfig.option)  
90 - handleDataPoint(adcode) 75 +const watchAdcode = async () => {
  76 + stopWatch()
  77 + if (props.chartConfig.option.drillingIn) {
  78 + //如果是从右边配置里设置的,比如点击四川省,然后点击返回
  79 + const savePopParent = saveHistoryParent.value.pop()
  80 + let saveAdcode = savePopParent?.adcode as string | number
  81 + saveLevelStr.level = savePopParent?.level
  82 + if (!savePopParent) {
  83 + saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode)
  84 + saveLevelStr.level = (regionMapParentArea as Recordable)[props.chartConfig.option.mapRegion.saveSelect.levelStr]
91 } 85 }
92 - } catch (error) {  
93 - console.error('地图点击返回出错', error)  
94 - }  
95 -}  
96 -  
97 -//设置map3D部分属性  
98 -const setMap3DPartOption = (adcode: number | string) => {  
99 - props.chartConfig.option.geo3D.map = adcode  
100 - props.chartConfig.option.series.forEach((item: Recordable) => {  
101 - if (item.type === 'map3D') {  
102 - item.map = adcode  
103 - item.data = props.chartConfig.option.dataset 86 + if (saveAdcode === 0) {
  87 + saveAdcode = 'china'
  88 + saveLevelStr.level = 'COUNTRY'
104 } 89 }
105 - }) 90 + const exist = await getGeojson(saveAdcode)
  91 + const adcode = saveAdcode === 100000 ? 'china' : saveAdcode
  92 + if (exist) {
  93 + //fix解决点击下钻返回后页面为空问题
  94 + props.chartConfig.option.mapRegion.adcode = adcode
  95 + }
  96 + }
106 } 97 }
107 98
108 const regionMapParentArea = { 99 const regionMapParentArea = {
@@ -112,7 +103,7 @@ const regionMapParentArea = { @@ -112,7 +103,7 @@ const regionMapParentArea = {
112 [areaEnum.TOWN]: areaEnum.COUNTY //镇的上一级 县或者区 103 [areaEnum.TOWN]: areaEnum.COUNTY //镇的上一级 县或者区
113 } 104 }
114 105
115 -//三维地图点击 106 +//地图点击
116 const handleMap3DClick = async (params: Recordable) => { 107 const handleMap3DClick = async (params: Recordable) => {
117 if (props.chartConfig.option.drillingIn) { 108 if (props.chartConfig.option.drillingIn) {
118 const { name } = params 109 const { name } = params
@@ -120,55 +111,48 @@ const handleMap3DClick = async (params: Recordable) => { @@ -120,55 +111,48 @@ const handleMap3DClick = async (params: Recordable) => {
120 if (item.properties.name === name) { 111 if (item.properties.name === name) {
121 const level = item.properties.level.toUpperCase() 112 const level = item.properties.level.toUpperCase()
122 const adcode = item.properties.adcode 113 const adcode = item.properties.adcode
123 - //如果是区则终止,目前没有加区下面的geojson数据  
124 if (level === 'DISTRICT') return 114 if (level === 'DISTRICT') return
125 - //特殊处理15开头的geojson数据  
126 if (String(adcode).startsWith('15') && level === areaEnum.CITY) return 115 if (String(adcode).startsWith('15') && level === areaEnum.CITY) return
127 props.chartConfig.option.mapRegion.adcode = adcode 116 props.chartConfig.option.mapRegion.adcode = adcode
128 saveLevelStr.level = level 117 saveLevelStr.level = level
  118 + handleDataPoint(adcode)
129 saveHistoryParent.value.push({ 119 saveHistoryParent.value.push({
130 adcode: item.properties.parent.adcode, 120 adcode: item.properties.parent.adcode,
131 level: (regionMapParentArea as Recordable)[level] 121 level: (regionMapParentArea as Recordable)[level]
132 }) 122 })
133 - handleDataPoint(adcode)  
134 } 123 }
135 }) 124 })
136 } 125 }
137 } 126 }
138 127
139 -// 保存geojson  
140 -const saveGeojson: Recordable = ref({}) 128 +const saveGeojson: Recordable = ref({}) // 保存geojson
141 129
142 -//如果是china则adcode为100000  
143 -const chinaDefaultRegionId = ref(100000) 130 +const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000
144 131
145 // 保存地区级别 132 // 保存地区级别
146 const saveLevelStr = reactive<{ level: string | undefined }>({ 133 const saveLevelStr = reactive<{ level: string | undefined }>({
147 level: '' 134 level: ''
148 }) 135 })
149 136
150 -// 保存上一级的adcode和行政级别  
151 const saveHistoryParent = ref<HistoryParentType[]>([]) 137 const saveHistoryParent = ref<HistoryParentType[]>([])
152 138
153 //动态注册地图 139 //动态注册地图
154 -const registerGeojson = (regionId: number | string) => { 140 +const getGeojson = (regionId: number | string) => {
155 try { 141 try {
156 return new Promise<boolean>(resolve => { 142 return new Promise<boolean>(resolve => {
157 - const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别 143 + const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
158 getGeoJsonMap( 144 getGeoJsonMap(
159 regionId === 'china' ? chinaDefaultRegionId.value : regionId, 145 regionId === 'china' ? chinaDefaultRegionId.value : regionId,
160 !saveLevelStr.level ? levelStr : saveLevelStr.level 146 !saveLevelStr.level ? levelStr : saveLevelStr.level
161 ).then(res => { 147 ).then(res => {
162 - if (res.data) {  
163 - const { geoJson, name, code, level } = res.data  
164 - if (!geoJson) return  
165 - const geoJsonFile = JSON.parse(geoJson)  
166 - saveGeojson.value = geoJsonFile  
167 - const nameChina = name === '中国' ? 'china' : name  
168 - registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile, specialAreas: {} })  
169 - resolve(true)  
170 - show.value = false  
171 - } 148 + const { geoJson, name, code, level } = res.data
  149 + const geoJsonFile = JSON.parse(geoJson)
  150 + if (!geoJsonFile) return
  151 + saveGeojson.value = geoJsonFile
  152 + const nameChina = name === '中国' ? 'china' : name
  153 + registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile as any, specialAreas: {} })
  154 + show.value = false
  155 + resolve(true)
172 }) 156 })
173 }) 157 })
174 } catch (error) { 158 } catch (error) {
@@ -179,13 +163,10 @@ const registerGeojson = (regionId: number | string) => { @@ -179,13 +163,10 @@ const registerGeojson = (regionId: number | string) => {
179 } 163 }
180 } 164 }
181 165
182 -//注册出错则注册空的,不然在选择正确的adcode,则视图无法更新  
183 -registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })  
184 -  
185 -//获取上级adcode 166 +//传adcode 获取上级
186 const getParentAdcode = (adcode: number) => { 167 const getParentAdcode = (adcode: number) => {
187 let adcodeNum = 100000 168 let adcodeNum = 100000
188 - saveGeojson.value?.features?.forEach((item: Recordable) => { 169 + saveGeojson.value?.features.forEach((item: Recordable) => {
189 if (item.properties.adcode === adcode) { 170 if (item.properties.adcode === adcode) {
190 adcodeNum = item.properties.parent.adcode 171 adcodeNum = item.properties.parent.adcode
191 } 172 }
@@ -203,50 +184,39 @@ watch( @@ -203,50 +184,39 @@ watch(
203 } 184 }
204 ) 185 )
205 186
206 -//初始化3D地图  
207 -const initMap3D = async () => {  
208 - try {  
209 - const dom = document.getElementById('map3DId') as HTMLElement  
210 - chartInstance.value = echarts.init(dom)  
211 - await nextTick()  
212 - await registerGeojson(props.chartConfig.option.mapRegion.adcode)  
213 - await nextTick().then(() => {  
214 - handleSetOption(chartInstance.value, props.chartConfig.option)  
215 - })  
216 - //三维地图点击  
217 - chartInstance.value.on('click', (e: Recordable) => {  
218 - handleMap3DClick(e)  
219 - })  
220 - } catch (error) {  
221 - console.error('[initMap3D]初始化3d地图出错', error)  
222 - } 187 +const initMap = async () => {
  188 + chartInstance.value = echarts.init(map3DRef.value)
  189 + await nextTick()
  190 + await getGeojson(props.chartConfig.option.mapRegion.adcode)
  191 + await nextTick().then(() => {
  192 + handleSetOption(chartInstance.value, props.chartConfig.option)
  193 + })
  194 + chartInstance.value.on('click', (e: Recordable) => {
  195 + handleMap3DClick(e)
  196 + })
223 } 197 }
224 198
225 -onMounted(() => {  
226 - setTimeout(() => {  
227 - initMap3D()  
228 - }, 500)  
229 -})  
230 -  
231 // 手动触发渲染 199 // 手动触发渲染
232 const handleSetOption = (instance: any, option: Recordable) => { 200 const handleSetOption = (instance: any, option: Recordable) => {
  201 + if (!instance) return
233 try { 202 try {
234 - if (!instance) return  
235 instance.clear() 203 instance.clear()
236 instance.setOption(option) 204 instance.setOption(option)
237 } catch (error) { 205 } catch (error) {
238 - console.error('手动触发渲染出错', error) 206 + console.error('触发渲染出错', error)
239 } 207 }
240 } 208 }
241 209
  210 +onMounted(() => {
  211 + initMap()
  212 +})
  213 +
242 //处理数据标点 214 //处理数据标点
243 const handleDataPoint = (newData: string | number) => { 215 const handleDataPoint = (newData: string | number) => {
244 if (newData === 'china') { 216 if (newData === 'china') {
245 - //全国则显示所有标点  
246 - props.chartConfig.option.series[1].data=dataMaps 217 + props.chartConfig.option.dataset = dataMaps
247 } else { 218 } else {
248 - //显示对应区域标点  
249 - props.chartConfig.option.series[1].data = dataMaps.filter((item: dataPointI) => item.adcode === newData) 219 + props.chartConfig.option.dataset = dataMaps.filter((item: dataPointI) => item.adcode === newData)
250 } 220 }
251 } 221 }
252 222
@@ -255,12 +225,18 @@ watch( @@ -255,12 +225,18 @@ watch(
255 () => `${props.chartConfig.option.mapRegion.adcode}`, 225 () => `${props.chartConfig.option.mapRegion.adcode}`,
256 async (newData: string | number) => { 226 async (newData: string | number) => {
257 try { 227 try {
258 - await registerGeojson(newData)  
259 - setMap3DPartOption(newData) 228 + await getGeojson(newData)
  229 + props.chartConfig.option.geo3D.map = newData
  230 + props.chartConfig.option.series.forEach((item: Recordable) => {
  231 + if (item.type === 'map3D') {
  232 + item.map = newData
  233 + item.data = props.chartConfig.option.dataset
  234 + }
  235 + })
260 handleSetOption(chartInstance.value, props.chartConfig.option) 236 handleSetOption(chartInstance.value, props.chartConfig.option)
261 handleDataPoint(newData) 237 handleDataPoint(newData)
262 } catch (error) { 238 } catch (error) {
263 - console.log('监听地图展示区域发生变化', error) 239 + console.log('展示区域发生变化出错', error)
264 } 240 }
265 }, 241 },
266 { 242 {
@@ -269,13 +245,13 @@ watch( @@ -269,13 +245,13 @@ watch(
269 ) 245 )
270 246
271 // 监听地图右侧配置项变化 247 // 监听地图右侧配置项变化
272 -watch( 248 +const stopWatch = watch(
273 props.chartConfig.option, 249 props.chartConfig.option,
274 async newData => { 250 async newData => {
275 try { 251 try {
276 handleSetOption(chartInstance.value, newData) 252 handleSetOption(chartInstance.value, newData)
277 } catch (error) { 253 } catch (error) {
278 - console.log('监听地图右侧配置项变化', error) 254 + console.log(error)
279 } 255 }
280 }, 256 },
281 { 257 {
@@ -290,18 +266,16 @@ watch( @@ -290,18 +266,16 @@ watch(
290 try { 266 try {
291 props.chartConfig.option.series.forEach((item: Recordable) => { 267 props.chartConfig.option.series.forEach((item: Recordable) => {
292 if (item.type === 'map3D') { 268 if (item.type === 'map3D') {
293 - item.adcode = props.chartConfig.option.mapRegion.adcode  
294 item.data = newData 269 item.data = newData
295 } 270 }
296 }) 271 })
297 handleSetOption(chartInstance.value, props.chartConfig.option) 272 handleSetOption(chartInstance.value, props.chartConfig.option)
298 } catch (error) { 273 } catch (error) {
299 - console.log('监听地图dataset配置项变化', error) 274 + console.log(error)
300 } 275 }
301 }, 276 },
302 { 277 {
303 - deep: true,  
304 - immediate: true 278 + deep: true
305 } 279 }
306 ) 280 )
307 </script> 281 </script>