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,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 () => { |