Commit 99e39109e9e97eeab44116c17b49a6ffc57c2d80

Authored by fengwotao
1 parent d18fe193

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

... ... @@ -2,7 +2,7 @@
2 2 <!-- 原生方式,没有使用vue-echarts -->
3 3 <n-space vertical>
4 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 6 </n-spin>
7 7 </n-space>
8 8 </template>
... ... @@ -29,6 +29,8 @@ const iconStr = ref(
29 29
30 30 const { w, h } = toRefs(props.chartConfig.attr)
31 31
  32 +const map3DRef = ref()
  33 +
32 34 const show = ref(true)
33 35
34 36 const chartInstance = ref()
... ... @@ -45,7 +47,7 @@ const toolBoxOption = ref({
45 47 iconStyle: {
46 48 color: ''
47 49 },
48   - onclick: () => mapClickBack()
  50 + onclick: () => watchAdcode()
49 51 }
50 52 }
51 53 })
... ... @@ -58,51 +60,40 @@ watch(
58 60 toolBoxOption.value.feature.myFullButton.iconStyle.color = iconColor
59 61 toolBoxOption.value.right = iconDistanceRight
60 62 toolBoxOption.value.top = iconDistanceTop
  63 + },
  64 + {
  65 + deep: true
61 66 }
62 67 )
63 68
64   -//追加右上角返回图标配置
65 69 props.chartConfig.option = {
66 70 ...props.chartConfig.option,
67 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 99 const regionMapParentArea = {
... ... @@ -112,7 +103,7 @@ const regionMapParentArea = {
112 103 [areaEnum.TOWN]: areaEnum.COUNTY //镇的上一级 县或者区
113 104 }
114 105
115   -//三维地图点击
  106 +//地图点击
116 107 const handleMap3DClick = async (params: Recordable) => {
117 108 if (props.chartConfig.option.drillingIn) {
118 109 const { name } = params
... ... @@ -120,55 +111,48 @@ const handleMap3DClick = async (params: Recordable) => {
120 111 if (item.properties.name === name) {
121 112 const level = item.properties.level.toUpperCase()
122 113 const adcode = item.properties.adcode
123   - //如果是区则终止,目前没有加区下面的geojson数据
124 114 if (level === 'DISTRICT') return
125   - //特殊处理15开头的geojson数据
126 115 if (String(adcode).startsWith('15') && level === areaEnum.CITY) return
127 116 props.chartConfig.option.mapRegion.adcode = adcode
128 117 saveLevelStr.level = level
  118 + handleDataPoint(adcode)
129 119 saveHistoryParent.value.push({
130 120 adcode: item.properties.parent.adcode,
131 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 133 const saveLevelStr = reactive<{ level: string | undefined }>({
147 134 level: ''
148 135 })
149 136
150   -// 保存上一级的adcode和行政级别
151 137 const saveHistoryParent = ref<HistoryParentType[]>([])
152 138
153 139 //动态注册地图
154   -const registerGeojson = (regionId: number | string) => {
  140 +const getGeojson = (regionId: number | string) => {
155 141 try {
156 142 return new Promise<boolean>(resolve => {
157   - const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
  143 + const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
158 144 getGeoJsonMap(
159 145 regionId === 'china' ? chinaDefaultRegionId.value : regionId,
160 146 !saveLevelStr.level ? levelStr : saveLevelStr.level
161 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 158 } catch (error) {
... ... @@ -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 167 const getParentAdcode = (adcode: number) => {
187 168 let adcodeNum = 100000
188   - saveGeojson.value?.features?.forEach((item: Recordable) => {
  169 + saveGeojson.value?.features.forEach((item: Recordable) => {
189 170 if (item.properties.adcode === adcode) {
190 171 adcodeNum = item.properties.parent.adcode
191 172 }
... ... @@ -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 200 const handleSetOption = (instance: any, option: Recordable) => {
  201 + if (!instance) return
233 202 try {
234   - if (!instance) return
235 203 instance.clear()
236 204 instance.setOption(option)
237 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 215 const handleDataPoint = (newData: string | number) => {
244 216 if (newData === 'china') {
245   - //全国则显示所有标点
246   - props.chartConfig.option.series[1].data=dataMaps
  217 + props.chartConfig.option.dataset = dataMaps
247 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 225 () => `${props.chartConfig.option.mapRegion.adcode}`,
256 226 async (newData: string | number) => {
257 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 236 handleSetOption(chartInstance.value, props.chartConfig.option)
261 237 handleDataPoint(newData)
262 238 } catch (error) {
263   - console.log('监听地图展示区域发生变化', error)
  239 + console.log('展示区域发生变化出错', error)
264 240 }
265 241 },
266 242 {
... ... @@ -269,13 +245,13 @@ watch(
269 245 )
270 246
271 247 // 监听地图右侧配置项变化
272   -watch(
  248 +const stopWatch = watch(
273 249 props.chartConfig.option,
274 250 async newData => {
275 251 try {
276 252 handleSetOption(chartInstance.value, newData)
277 253 } catch (error) {
278   - console.log('监听地图右侧配置项变化', error)
  254 + console.log(error)
279 255 }
280 256 },
281 257 {
... ... @@ -290,18 +266,16 @@ watch(
290 266 try {
291 267 props.chartConfig.option.series.forEach((item: Recordable) => {
292 268 if (item.type === 'map3D') {
293   - item.adcode = props.chartConfig.option.mapRegion.adcode
294 269 item.data = newData
295 270 }
296 271 })
297 272 handleSetOption(chartInstance.value, props.chartConfig.option)
298 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 281 </script>
... ...