Commit d61d4d358399c9289238573d5cb8c328223bc8be
1 parent
0f13f3c4
feat(src/packages): 图表3d地图也支持下钻 修改地图注册方式为服务端接口请求
Showing
5 changed files
with
89 additions
and
49 deletions
... | ... | @@ -24,7 +24,8 @@ const selectOptions = reactive({ |
24 | 24 | const selectValues = reactive({ |
25 | 25 | provinceValue: 'china', |
26 | 26 | cityValue: null, |
27 | - countyValue: null | |
27 | + countyValue: null, | |
28 | + levelStr: areaEnum.COUNTRY | |
28 | 29 | }) |
29 | 30 | |
30 | 31 | const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { |
... | ... | @@ -49,13 +50,15 @@ onMounted(async () => { |
49 | 50 | const onHandleSelectProvince = async (value: number | string) => { |
50 | 51 | selectValues.cityValue = null |
51 | 52 | selectValues.countyValue = null |
52 | - if (value === 'china') return | |
53 | + if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY) | |
53 | 54 | selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value as any) |
55 | + selectValues.levelStr = areaEnum.PROVINCE | |
54 | 56 | } |
55 | 57 | |
56 | 58 | const onHandleSelectCity = async (value: number) => { |
57 | 59 | selectValues.countyValue = null |
58 | 60 | selectOptions.countryOptions = await getAreaLists(areaEnum.COUNTY, value) |
61 | + selectValues.levelStr = areaEnum.CITY | |
59 | 62 | } |
60 | 63 | |
61 | 64 | const onHandleSubmit = () => { | ... | ... |
... | ... | @@ -7,9 +7,11 @@ import dataMaps from './data.json' |
7 | 7 | |
8 | 8 | //省市区枚举 |
9 | 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 | 17 | export const includes = [] |
... | ... | @@ -24,34 +26,28 @@ export const option = { |
24 | 26 | mapRegion: { |
25 | 27 | adcode: 'china', |
26 | 28 | showHainanIsLands: true, |
27 | - saveSelect: {} | |
29 | + saveSelect: { | |
30 | + levelStr: areaEnum.COUNTRY | |
31 | + } | |
28 | 32 | }, |
29 | 33 | tooltip: { |
30 | 34 | show: true |
31 | 35 | }, |
32 | 36 | geo3D: { |
37 | + show: false, // 隐藏该层,为true时会导致出现两个地图 | |
33 | 38 | map: 'centerMap', |
34 | 39 | roam: true, |
35 | 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 | 41 | emphasis: { |
46 | 42 | label: { |
47 | 43 | show: true, |
48 | 44 | textStyle: { |
49 | - color: 'black', | |
50 | - fontSize: 32 | |
45 | + color: '#000', | |
46 | + fontSize: 14 | |
51 | 47 | } |
52 | 48 | }, |
53 | 49 | itemStyle: { |
54 | - color: '#fd9c5a' | |
50 | + color: '#ff0' | |
55 | 51 | } |
56 | 52 | } |
57 | 53 | }, |
... | ... | @@ -63,8 +59,10 @@ export const option = { |
63 | 59 | regionHeight: 3, |
64 | 60 | label: { |
65 | 61 | show: true, |
66 | - color: 'yellow', | |
67 | - fontSize: 14 | |
62 | + textStyle: { | |
63 | + color: '#fff', | |
64 | + fontSize: 14 | |
65 | + } | |
68 | 66 | }, |
69 | 67 | itemStyle: { |
70 | 68 | color: 'green', | ... | ... |
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | <!-- Echarts 全局设置 --> |
3 | 3 | <global-setting :optionData="optionData"></global-setting> |
4 | 4 | <CollapseItem name="地图" :expanded="true"> |
5 | - <!-- <SettingItemBox name="开启下钻"> | |
5 | + <SettingItemBox name="开启下钻"> | |
6 | 6 | <SettingItem name=""> |
7 | 7 | <n-switch v-model:value="optionData.drillingIn" size="small"></n-switch> |
8 | 8 | </SettingItem> |
... | ... | @@ -34,7 +34,7 @@ |
34 | 34 | placeholder="请输入" |
35 | 35 | ></n-input-number> |
36 | 36 | </SettingItem> |
37 | - </SettingItemBox> --> | |
37 | + </SettingItemBox> | |
38 | 38 | <SelectCity :optionData="optionData" :drillingIn="optionData.drillingIn" @submit="onHandleSelectValues" /> |
39 | 39 | <SettingItemBox name="颜色"> |
40 | 40 | <SettingItem name="区域颜色"> |
... | ... | @@ -69,11 +69,15 @@ |
69 | 69 | <n-switch v-model:value="seriesList[0].label.show" size="small"></n-switch> |
70 | 70 | </SettingItem> |
71 | 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 | 77 | </SettingItem> |
74 | 78 | <SettingItem name="大小"> |
75 | 79 | <n-input-number |
76 | - v-model:value="seriesList[0].label.fontSize" | |
80 | + v-model:value="seriesList[0].label.textStyle.fontSize" | |
77 | 81 | :min="0" |
78 | 82 | size="small" |
79 | 83 | placeholder="请输入" | ... | ... |
... | ... | @@ -4,12 +4,12 @@ |
4 | 4 | </template> |
5 | 5 | |
6 | 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 | 8 | import * as echarts from 'echarts' |
9 | 9 | import { registerMap } from 'echarts/core' |
10 | 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 | 14 | type historyDataType = { name: string; code: string } |
15 | 15 | |
... | ... | @@ -71,40 +71,76 @@ props.chartConfig.option = { |
71 | 71 | } |
72 | 72 | |
73 | 73 | //地图点击返回 |
74 | -const watchAdcode = () => { | |
74 | +const watchAdcode = async () => { | |
75 | 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 | 97 | const handleMap3DClick = async (params: any) => { |
84 | 98 | if (props.chartConfig.option.drillingIn) { |
85 | 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 | 126 | //动态获取geojson文件进行注册地图 |
98 | -const getGeojson = (regionId: string) => { | |
127 | +const getGeojson = (regionId: any) => { | |
99 | 128 | try { |
100 | 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 | 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 | 162 | handleSetOption(chartInstance.value, props.chartConfig.option) |
127 | 163 | }) |
128 | 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 | 172 | try { |
138 | 173 | instance.clear() |
139 | 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 | 196 | }) |
162 | 197 | handleSetOption(chartInstance.value, props.chartConfig.option) |
163 | 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 | 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 | 157 | // 进行更换初始化地图 如果为china 单独处理 |
158 | 158 | const registerMapInitAsync = async () => { | ... | ... |