Commit 1b052dfc269f85221389c413a577131b0dbbbf6b
Committed by
xp.Huang
1 parent
1aa17ab8
perf(src/views/chart): 优化三维地图右侧区块配置项,并且修复兼容之前旧地图
Showing
5 changed files
with
269 additions
and
210 deletions
| 1 | <script lang="ts" setup name="SelectCity"> | 1 | <script lang="ts" setup name="SelectCity"> |
| 2 | -import { onMounted, reactive } from 'vue' | 2 | +import { onMounted, reactive, nextTick } from 'vue' |
| 3 | import { getAreaList } from '@/api/external/common/index' | 3 | import { getAreaList } from '@/api/external/common/index' |
| 4 | import { areaEnum } from '../config' | 4 | import { areaEnum } from '../config' |
| 5 | 5 | ||
| @@ -25,7 +25,8 @@ const selectValues = reactive({ | @@ -25,7 +25,8 @@ 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 | + levelStr: areaEnum.COUNTRY, |
| 29 | + areaName: '' | ||
| 29 | }) | 30 | }) |
| 30 | 31 | ||
| 31 | const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { | 32 | const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { |
| @@ -34,36 +35,40 @@ const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { | @@ -34,36 +35,40 @@ const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { | ||
| 34 | parentId | 35 | parentId |
| 35 | }) | 36 | }) |
| 36 | if (!resp) return [] | 37 | if (!resp) return [] |
| 37 | - return resp.map((item: any) => ({ label: item.name, value: item.code })) | 38 | + return resp.map((item: Recordable) => ({ label: item.name, value: item.code })) |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | onMounted(async () => { | 41 | onMounted(async () => { |
| 41 | selectOptions.provinceOptions = await getAreaLists() | 42 | selectOptions.provinceOptions = await getAreaLists() |
| 42 | - ;(selectOptions.provinceOptions as never as any).unshift({ | 43 | + ;(selectOptions.provinceOptions as never as Recordable[]).unshift({ |
| 43 | label: '中国', | 44 | label: '中国', |
| 44 | value: 'china' | 45 | value: 'china' |
| 45 | }) | 46 | }) |
| 46 | - onHandleSelectProvince(props.optionData?.mapRegion.saveSelect['provinceValue']) | 47 | + onHandleSelectProvince(props.optionData?.mapRegion.saveSelect['provinceValue'], {}) |
| 47 | for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i]) | 48 | for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i]) |
| 48 | }) | 49 | }) |
| 49 | 50 | ||
| 50 | -const onHandleSelectProvince = async (value: number | string) => { | 51 | +const onHandleSelectProvince = async (value: number | string, options: Recordable) => { |
| 51 | selectValues.cityValue = null | 52 | selectValues.cityValue = null |
| 52 | selectValues.countyValue = null | 53 | selectValues.countyValue = null |
| 53 | if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY) | 54 | if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY) |
| 54 | - selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value as any) | 55 | + selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value as number) |
| 55 | selectValues.levelStr = areaEnum.PROVINCE | 56 | selectValues.levelStr = areaEnum.PROVINCE |
| 57 | + selectValues.areaName = options.label | ||
| 56 | } | 58 | } |
| 57 | 59 | ||
| 58 | -const onHandleSelectCity = async (value: number) => { | 60 | +const onHandleSelectCity = async (value: number, options: Recordable) => { |
| 59 | selectValues.countyValue = null | 61 | selectValues.countyValue = null |
| 60 | selectOptions.countryOptions = await getAreaLists(areaEnum.COUNTY, value) | 62 | selectOptions.countryOptions = await getAreaLists(areaEnum.COUNTY, value) |
| 61 | selectValues.levelStr = areaEnum.CITY | 63 | selectValues.levelStr = areaEnum.CITY |
| 64 | + selectValues.areaName = options.label | ||
| 62 | } | 65 | } |
| 63 | 66 | ||
| 64 | -const onHandleSubmit = () => { | 67 | +const onHandleSubmit = async () => { |
| 68 | + await nextTick() | ||
| 65 | emits('submit', selectValues) | 69 | emits('submit', selectValues) |
| 66 | } | 70 | } |
| 71 | + | ||
| 67 | const resetValue = () => { | 72 | const resetValue = () => { |
| 68 | selectValues.provinceValue = 'china' | 73 | selectValues.provinceValue = 'china' |
| 69 | selectValues.cityValue = null | 74 | selectValues.cityValue = null |
| @@ -72,6 +77,7 @@ const resetValue = () => { | @@ -72,6 +77,7 @@ const resetValue = () => { | ||
| 72 | selectOptions.cityOptions = [] | 77 | selectOptions.cityOptions = [] |
| 73 | selectOptions.countryOptions = [] | 78 | selectOptions.countryOptions = [] |
| 74 | } | 79 | } |
| 80 | + | ||
| 75 | defineExpose({ | 81 | defineExpose({ |
| 76 | resetValue | 82 | resetValue |
| 77 | }) | 83 | }) |
| @@ -20,6 +20,7 @@ export interface regionInfo { | @@ -20,6 +20,7 @@ export interface regionInfo { | ||
| 20 | cityValue: string | null | 20 | cityValue: string | null |
| 21 | countyValue: string | null | 21 | countyValue: string | null |
| 22 | levelStr: areaEnum | 22 | levelStr: areaEnum |
| 23 | + areaName: string | ||
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | type itemOption = { | 26 | type itemOption = { |
| @@ -36,6 +37,7 @@ export interface regionOption { | @@ -36,6 +37,7 @@ export interface regionOption { | ||
| 36 | export interface historyParentType { | 37 | export interface historyParentType { |
| 37 | adcode: number | 38 | adcode: number |
| 38 | level: string | 39 | level: string |
| 40 | + areaName: string | ||
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | export interface backMapLevel { | 43 | export interface backMapLevel { |
| @@ -50,6 +52,7 @@ export interface levelFunc { | @@ -50,6 +52,7 @@ export interface levelFunc { | ||
| 50 | //数据源接口 | 52 | //数据源接口 |
| 51 | export interface dataPointI { | 53 | export interface dataPointI { |
| 52 | name: string | 54 | name: string |
| 55 | + city_name: string | ||
| 53 | value: number[] | 56 | value: number[] |
| 54 | adcode: number | 57 | adcode: number |
| 55 | height: number | 58 | height: number |
| @@ -69,6 +72,70 @@ export const regionMapParentArea = { | @@ -69,6 +72,70 @@ export const regionMapParentArea = { | ||
| 69 | TOWN: areaEnum.COUNTY //镇的上一级 县或者区 | 72 | TOWN: areaEnum.COUNTY //镇的上一级 县或者区 |
| 70 | } | 73 | } |
| 71 | 74 | ||
| 75 | +// 缩放配置文件 | ||
| 76 | +export const setScale = (adcode: string | number) => { | ||
| 77 | + switch (adcode) { | ||
| 78 | + case 'china': | ||
| 79 | + return { distance: 100, zoom: 1, alpha: 45 } | ||
| 80 | + case '110000': | ||
| 81 | + return { distance: 150, zoom: 0.8, alpha: 45 } | ||
| 82 | + case '120000': | ||
| 83 | + return { distance: 190, zoom: 0.8, alpha: 45 } | ||
| 84 | + case '130000': | ||
| 85 | + return { distance: 165, zoom: 0.8, alpha: 45 } | ||
| 86 | + case '140000': | ||
| 87 | + return { distance: 216, zoom: 0.8, alpha: 45 } | ||
| 88 | + case '150000': | ||
| 89 | + return { distance: 130, zoom: 0.8, alpha: 45 } | ||
| 90 | + case '210000': | ||
| 91 | + return { distance: 130, zoom: 0.8, alpha: 45 } | ||
| 92 | + case '310000': | ||
| 93 | + return { distance: 135, zoom: 0.8, alpha: 45 } | ||
| 94 | + case '320000': | ||
| 95 | + return { distance: 145, zoom: 0.8, alpha: 45 } | ||
| 96 | + case '330000': | ||
| 97 | + return { distance: 135, zoom: 0.8, alpha: 45 } | ||
| 98 | + case '340000': | ||
| 99 | + return { distance: 170, zoom: 0.8, alpha: 45 } | ||
| 100 | + case '350000': | ||
| 101 | + return { distance: 150, zoom: 0.8, alpha: 45 } | ||
| 102 | + case '360000': | ||
| 103 | + return { distance: 190, zoom: 0.8, alpha: 45 } | ||
| 104 | + case '370000': | ||
| 105 | + return { distance: 135, zoom: 0.8, alpha: 45 } | ||
| 106 | + case '420000': | ||
| 107 | + return { distance: 145, zoom: 0.8, alpha: 45 } | ||
| 108 | + case '430000': | ||
| 109 | + return { distance: 165, zoom: 0.8, alpha: 45 } | ||
| 110 | + case '440000': | ||
| 111 | + return { distance: 165, zoom: 0.8, alpha: 45 } | ||
| 112 | + case '500000': | ||
| 113 | + return { distance: 145, zoom: 0.8, alpha: 45 } | ||
| 114 | + case '520000': | ||
| 115 | + return { distance: 135, zoom: 0.8, alpha: 45 } | ||
| 116 | + case '530000': | ||
| 117 | + return { distance: 145, zoom: 0.8, alpha: 45 } | ||
| 118 | + case '540000': | ||
| 119 | + return { distance: 140, zoom: 0.8, alpha: 45 } | ||
| 120 | + case '610000': | ||
| 121 | + return { distance: 210, zoom: 0.8, alpha: 45 } | ||
| 122 | + case '620000': | ||
| 123 | + return { distance: 135, zoom: 0.8, alpha: 45 } | ||
| 124 | + case '640000': | ||
| 125 | + return { distance: 195, zoom: 0.8, alpha: 45 } | ||
| 126 | + case '650000': | ||
| 127 | + return { distance: 135, zoom: 0.8, alpha: 45 } | ||
| 128 | + case '710000': | ||
| 129 | + return { distance: 135, zoom: 0.8, alpha: 45 } | ||
| 130 | + case '810000': | ||
| 131 | + return { distance: 145, zoom: 0.8, alpha: 45 } | ||
| 132 | + case '820000': | ||
| 133 | + return { distance: 240, zoom: 0.8, alpha: 45 } | ||
| 134 | + default: | ||
| 135 | + return { distance: 125, zoom: 1, alpha: 45 } | ||
| 136 | + } | ||
| 137 | +} | ||
| 138 | + | ||
| 72 | export const includes = [] | 139 | export const includes = [] |
| 73 | 140 | ||
| 74 | // 特殊处理安徽省的下钻 | 141 | // 特殊处理安徽省的下钻 |
| @@ -105,11 +172,13 @@ export const option = { | @@ -105,11 +172,13 @@ export const option = { | ||
| 105 | mapRegion: { | 172 | mapRegion: { |
| 106 | adcode: 'china', | 173 | adcode: 'china', |
| 107 | showHainanIsLands: true, | 174 | showHainanIsLands: true, |
| 175 | + areaName: '', | ||
| 108 | saveSelect: { | 176 | saveSelect: { |
| 109 | levelStr: areaEnum.COUNTRY, | 177 | levelStr: areaEnum.COUNTRY, |
| 110 | cityValue: null, | 178 | cityValue: null, |
| 111 | countyValue: null, | 179 | countyValue: null, |
| 112 | - provinceValue: 'china' | 180 | + provinceValue: 'china', |
| 181 | + areaName: '' | ||
| 113 | } | 182 | } |
| 114 | }, | 183 | }, |
| 115 | tooltip: { | 184 | tooltip: { |
| @@ -118,30 +187,30 @@ export const option = { | @@ -118,30 +187,30 @@ export const option = { | ||
| 118 | //三维地图有两种,一种是geo3D,另一种是map3D,但是如果使用geo3D,地图点击获取不到点击区域name | 187 | //三维地图有两种,一种是geo3D,另一种是map3D,但是如果使用geo3D,地图点击获取不到点击区域name |
| 119 | geo3D: { | 188 | geo3D: { |
| 120 | show: false, // 隐藏该层,为true时会导致出现两个地图 | 189 | show: false, // 隐藏该层,为true时会导致出现两个地图 |
| 121 | - map: 'centerMap', | 190 | + map: '', |
| 122 | roam: true | 191 | roam: true |
| 123 | }, | 192 | }, |
| 124 | series: [ | 193 | series: [ |
| 125 | { | 194 | { |
| 126 | type: 'map3D', | 195 | type: 'map3D', |
| 127 | - map: 'centerMap', | ||
| 128 | - name: 'centerMap', | ||
| 129 | - regionHeight: 3, | 196 | + map: '', |
| 197 | + name: '', | ||
| 198 | + regionHeight: 0, | ||
| 130 | label: { | 199 | label: { |
| 131 | show: true, | 200 | show: true, |
| 132 | formatter: function (params: Recordable) { | 201 | formatter: function (params: Recordable) { |
| 133 | return params.data.name ? params.data.name : ' ' | 202 | return params.data.name ? params.data.name : ' ' |
| 134 | }, | 203 | }, |
| 135 | textStyle: { | 204 | textStyle: { |
| 136 | - color: '#fff', | 205 | + color: '#ffffffff', |
| 137 | fontSize: 14 | 206 | fontSize: 14 |
| 138 | } | 207 | } |
| 139 | }, | 208 | }, |
| 140 | itemStyle: { | 209 | itemStyle: { |
| 141 | - color: '#4482B1FF', //背景颜色 | 210 | + color: '#3c7effff', //背景颜色 |
| 142 | opacity: 1, | 211 | opacity: 1, |
| 143 | borderWidth: 0.8, | 212 | borderWidth: 0.8, |
| 144 | - borderColor: '#4482B1FF' | 213 | + borderColor: '#51d6a9FF' |
| 145 | }, | 214 | }, |
| 146 | emphasis: { | 215 | emphasis: { |
| 147 | // 鼠标hover 高亮时图形和标签的样式 (当鼠标放上去时 label和itemStyle 的样式) | 216 | // 鼠标hover 高亮时图形和标签的样式 (当鼠标放上去时 label和itemStyle 的样式) |
| @@ -149,12 +218,12 @@ export const option = { | @@ -149,12 +218,12 @@ export const option = { | ||
| 149 | // label高亮时的配置 | 218 | // label高亮时的配置 |
| 150 | show: true, | 219 | show: true, |
| 151 | textStyle: { | 220 | textStyle: { |
| 152 | - color: 'green', | 221 | + color: '#57c3c2ff', |
| 153 | fontSize: 14 | 222 | fontSize: 14 |
| 154 | } | 223 | } |
| 155 | }, | 224 | }, |
| 156 | itemStyle: { | 225 | itemStyle: { |
| 157 | - color: 'red' | 226 | + color: '#1ba784ff' |
| 158 | } | 227 | } |
| 159 | }, | 228 | }, |
| 160 | data: [], | 229 | data: [], |
| @@ -163,28 +232,19 @@ export const option = { | @@ -163,28 +232,19 @@ export const option = { | ||
| 163 | } | 232 | } |
| 164 | }, | 233 | }, |
| 165 | { | 234 | { |
| 166 | - name: 'scatter3D', | ||
| 167 | - type: 'scatter3D', | ||
| 168 | - coordinateSystem: 'geo3D', | ||
| 169 | - symbol: 'circle', | ||
| 170 | - symbolSize: 20, | ||
| 171 | - animation: true, | ||
| 172 | - data: [] | ||
| 173 | - }, | ||
| 174 | - { | ||
| 175 | name: 'bar3D', | 235 | name: 'bar3D', |
| 176 | type: 'bar3D', | 236 | type: 'bar3D', |
| 177 | coordinateSystem: 'geo3D', | 237 | coordinateSystem: 'geo3D', |
| 178 | // 倒角尺寸 | 238 | // 倒角尺寸 |
| 179 | bevelSize: 0, | 239 | bevelSize: 0, |
| 180 | - minHeight: 12, | 240 | + minHeight: 5, |
| 181 | shading: 'lambert', | 241 | shading: 'lambert', |
| 182 | barSize: 1, | 242 | barSize: 1, |
| 183 | itemStyle: { | 243 | itemStyle: { |
| 184 | color: '#4482B1FF' | 244 | color: '#4482B1FF' |
| 185 | }, | 245 | }, |
| 186 | data: [] | 246 | data: [] |
| 187 | - }, | 247 | + } |
| 188 | ] | 248 | ] |
| 189 | } | 249 | } |
| 190 | 250 |
| @@ -43,7 +43,7 @@ | @@ -43,7 +43,7 @@ | ||
| 43 | /> | 43 | /> |
| 44 | <div style="height: 30px"></div> | 44 | <div style="height: 30px"></div> |
| 45 | <n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag> | 45 | <n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag> |
| 46 | - <SettingItemBox name="区块配置"> | 46 | + <SettingItemBox name="地图配置"> |
| 47 | <SettingItem name="区域颜色"> | 47 | <SettingItem name="区域颜色"> |
| 48 | <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[0].itemStyle.color"></n-color-picker> | 48 | <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[0].itemStyle.color"></n-color-picker> |
| 49 | </SettingItem> | 49 | </SettingItem> |
| @@ -126,24 +126,10 @@ | @@ -126,24 +126,10 @@ | ||
| 126 | ></n-color-picker> | 126 | ></n-color-picker> |
| 127 | </SettingItem> | 127 | </SettingItem> |
| 128 | </SettingItemBox> | 128 | </SettingItemBox> |
| 129 | - <SettingItemBox name="散点配置"> | ||
| 130 | - <SettingItem name="大小"> | ||
| 131 | - <n-input-number | ||
| 132 | - v-model:value="seriesList[1].symbolSize" | ||
| 133 | - :min="0" | ||
| 134 | - :step="1" | ||
| 135 | - size="small" | ||
| 136 | - placeholder="请输入" | ||
| 137 | - ></n-input-number> | ||
| 138 | - </SettingItem> | ||
| 139 | - <SettingItem name="形状"> | ||
| 140 | - <n-select :options="symbolOption" v-model:value="seriesList[1].symbol"></n-select> | ||
| 141 | - </SettingItem> | ||
| 142 | - </SettingItemBox> | ||
| 143 | <SettingItemBox name="柱状配置"> | 129 | <SettingItemBox name="柱状配置"> |
| 144 | <SettingItem name="最小高度"> | 130 | <SettingItem name="最小高度"> |
| 145 | <n-input-number | 131 | <n-input-number |
| 146 | - v-model:value="seriesList[2].minHeight" | 132 | + v-model:value="seriesList[1].minHeight" |
| 147 | :min="0" | 133 | :min="0" |
| 148 | :step="1" | 134 | :step="1" |
| 149 | size="small" | 135 | size="small" |
| @@ -152,7 +138,7 @@ | @@ -152,7 +138,7 @@ | ||
| 152 | </SettingItem> | 138 | </SettingItem> |
| 153 | <SettingItem name="大小"> | 139 | <SettingItem name="大小"> |
| 154 | <n-input-number | 140 | <n-input-number |
| 155 | - v-model:value="seriesList[2].barSize" | 141 | + v-model:value="seriesList[1].barSize" |
| 156 | :min="0" | 142 | :min="0" |
| 157 | :step="1" | 143 | :step="1" |
| 158 | size="small" | 144 | size="small" |
| @@ -161,7 +147,7 @@ | @@ -161,7 +147,7 @@ | ||
| 161 | </SettingItem> | 147 | </SettingItem> |
| 162 | <SettingItem name="倒角尺寸"> | 148 | <SettingItem name="倒角尺寸"> |
| 163 | <n-input-number | 149 | <n-input-number |
| 164 | - v-model:value="seriesList[2].bevelSize" | 150 | + v-model:value="seriesList[1].bevelSize" |
| 165 | :min="0" | 151 | :min="0" |
| 166 | :max="1" | 152 | :max="1" |
| 167 | :step="0.1" | 153 | :step="0.1" |
| @@ -170,15 +156,22 @@ | @@ -170,15 +156,22 @@ | ||
| 170 | ></n-input-number> | 156 | ></n-input-number> |
| 171 | </SettingItem> | 157 | </SettingItem> |
| 172 | </SettingItemBox> | 158 | </SettingItemBox> |
| 173 | - <SettingItemBox name="区块配置"> | 159 | + </CollapseItem> |
| 160 | + <CollapseItem name="地区配置" :expanded="true"> | ||
| 161 | + <SettingItemBox name="地区配置" :alone="true"> | ||
| 174 | <template v-for="(item, map3DIndex) in optionData.dataset.map3D" :key="map3DIndex"> | 162 | <template v-for="(item, map3DIndex) in optionData.dataset.map3D" :key="map3DIndex"> |
| 175 | - <setting-item name="地区名称"> | ||
| 176 | - <n-input v-model:value="item.name"> </n-input> | 163 | + <setting-item name="省份名称"> |
| 164 | + <n-select | ||
| 165 | + @change="(v:number,o:Recordable,w:Recordable,s1:number)=> onHandleSelectProvince(v,o,item, map3DIndex)" | ||
| 166 | + placeholder="请选择省份" | ||
| 167 | + v-model:value="item.name" | ||
| 168 | + :options="item.provinceOptions" | ||
| 169 | + /> | ||
| 177 | </setting-item> | 170 | </setting-item> |
| 178 | - <setting-item name="地区代码"> | ||
| 179 | - <n-input v-model:value="item.adcode"> </n-input> | 171 | + <setting-item name="城市名称"> |
| 172 | + <n-select placeholder="请选择城市" v-model:value="item.city_name" :options="item.cityOptions" /> | ||
| 180 | </setting-item> | 173 | </setting-item> |
| 181 | - <setting-item name="离地高度"> | 174 | + <setting-item name="区块厚度"> |
| 182 | <n-input-number v-model:value="item.height"> </n-input-number> | 175 | <n-input-number v-model:value="item.height"> </n-input-number> |
| 183 | </setting-item> | 176 | </setting-item> |
| 184 | <setting-item name="区块颜色"> | 177 | <setting-item name="区块颜色"> |
| @@ -187,71 +180,27 @@ | @@ -187,71 +180,27 @@ | ||
| 187 | <setting-item name="区块透明度"> | 180 | <setting-item name="区块透明度"> |
| 188 | <n-input-number v-model:value="item.itemStyle.opacity"> </n-input-number> | 181 | <n-input-number v-model:value="item.itemStyle.opacity"> </n-input-number> |
| 189 | </setting-item> | 182 | </setting-item> |
| 183 | + <setting-item></setting-item> | ||
| 190 | <setting-item> | 184 | <setting-item> |
| 191 | <n-button size="small" @click="optionData.dataset.map3D.splice(map3DIndex, 1)"> - </n-button> | 185 | <n-button size="small" @click="optionData.dataset.map3D.splice(map3DIndex, 1)"> - </n-button> |
| 192 | </setting-item> | 186 | </setting-item> |
| 193 | </template> | 187 | </template> |
| 194 | - <n-button | ||
| 195 | - style="float: right" | ||
| 196 | - size="small" | ||
| 197 | - @click="optionData.dataset.map3D.push(cloneDeep(STATIC_SCATTER_CONFIG))" | ||
| 198 | - > | ||
| 199 | - + | ||
| 200 | - </n-button> | 188 | + <div class="h-space"></div> |
| 189 | + <n-button size="small" @click="handleAddRegion"> + </n-button> | ||
| 201 | </SettingItemBox> | 190 | </SettingItemBox> |
| 202 | - <SettingItemBox name="散点配置"> | ||
| 203 | - <template v-for="(item, scatterIndex) in optionData.dataset.scatter3D" :key="scatterIndex"> | ||
| 204 | - <setting-item name="地区名称"> | ||
| 205 | - <n-input v-model:value="item.name"> </n-input> | ||
| 206 | - </setting-item> | ||
| 207 | - <setting-item name="地区代码"> | ||
| 208 | - <n-input v-model:value="item.adcode"> </n-input> | ||
| 209 | - </setting-item> | ||
| 210 | - <setting-item name="离地高度"> | ||
| 211 | - <n-input-number v-model:value="item.height"> </n-input-number> | ||
| 212 | - </setting-item> | 191 | + </CollapseItem> |
| 192 | + <CollapseItem name="柱状配置" :expanded="true"> | ||
| 193 | + <SettingItemBox name="柱状配置" :alone="true"> | ||
| 194 | + <template v-for="(item, barIndex) in optionData.dataset.bar3D" :key="barIndex"> | ||
| 213 | <setting-item name="经度"> | 195 | <setting-item name="经度"> |
| 214 | <n-input-number v-model:value="item.value[0]"> </n-input-number> | 196 | <n-input-number v-model:value="item.value[0]"> </n-input-number> |
| 215 | </setting-item> | 197 | </setting-item> |
| 216 | <setting-item name="纬度"> | 198 | <setting-item name="纬度"> |
| 217 | <n-input-number v-model:value="item.value[1]"> </n-input-number> | 199 | <n-input-number v-model:value="item.value[1]"> </n-input-number> |
| 218 | </setting-item> | 200 | </setting-item> |
| 219 | - <setting-item name="散点颜色"> | ||
| 220 | - <n-color-picker size="small" :modes="['hex']" v-model:value="item.itemStyle.color"></n-color-picker> | ||
| 221 | - </setting-item> | ||
| 222 | - <setting-item name="散点透明度"> | ||
| 223 | - <n-input-number v-model:value="item.itemStyle.opacity"> </n-input-number> | ||
| 224 | - </setting-item> | ||
| 225 | - <setting-item> </setting-item> | ||
| 226 | - <setting-item> | ||
| 227 | - <n-button size="small" @click="optionData.dataset.scatter3D.splice(scatterIndex, 1)"> - </n-button> | ||
| 228 | - </setting-item> | ||
| 229 | - </template> | ||
| 230 | - <n-button | ||
| 231 | - style="float: right" | ||
| 232 | - size="small" | ||
| 233 | - @click="optionData.dataset.scatter3D.push(cloneDeep(STATIC_SCATTER_CONFIG))" | ||
| 234 | - > | ||
| 235 | - + | ||
| 236 | - </n-button> | ||
| 237 | - </SettingItemBox> | ||
| 238 | - <SettingItemBox name="柱状配置"> | ||
| 239 | - <template v-for="(item, barIndex) in optionData.dataset.bar3D" :key="barIndex"> | ||
| 240 | - <setting-item name="地区名称"> | ||
| 241 | - <n-input v-model:value="item.name"> </n-input> | ||
| 242 | - </setting-item> | ||
| 243 | - <setting-item name="地区代码"> | ||
| 244 | - <n-input v-model:value="item.adcode"> </n-input> | ||
| 245 | - </setting-item> | ||
| 246 | <setting-item name="离地高度"> | 201 | <setting-item name="离地高度"> |
| 247 | <n-input-number v-model:value="item.height"> </n-input-number> | 202 | <n-input-number v-model:value="item.height"> </n-input-number> |
| 248 | </setting-item> | 203 | </setting-item> |
| 249 | - <setting-item name="经度"> | ||
| 250 | - <n-input-number v-model:value="item.value[0]"> </n-input-number> | ||
| 251 | - </setting-item> | ||
| 252 | - <setting-item name="纬度"> | ||
| 253 | - <n-input-number v-model:value="item.value[1]"> </n-input-number> | ||
| 254 | - </setting-item> | ||
| 255 | <setting-item name="柱状颜色"> | 204 | <setting-item name="柱状颜色"> |
| 256 | <n-color-picker size="small" :modes="['hex']" v-model:value="item.itemStyle.color"></n-color-picker> | 205 | <n-color-picker size="small" :modes="['hex']" v-model:value="item.itemStyle.color"></n-color-picker> |
| 257 | </setting-item> | 206 | </setting-item> |
| @@ -262,6 +211,7 @@ | @@ -262,6 +211,7 @@ | ||
| 262 | <n-button size="small" @click="optionData.dataset.bar3D.splice(barIndex, 1)"> - </n-button> | 211 | <n-button size="small" @click="optionData.dataset.bar3D.splice(barIndex, 1)"> - </n-button> |
| 263 | </setting-item> | 212 | </setting-item> |
| 264 | </template> | 213 | </template> |
| 214 | + <div class="h-space"></div> | ||
| 265 | <n-button | 215 | <n-button |
| 266 | style="float: right" | 216 | style="float: right" |
| 267 | size="small" | 217 | size="small" |
| @@ -274,13 +224,15 @@ | @@ -274,13 +224,15 @@ | ||
| 274 | </template> | 224 | </template> |
| 275 | 225 | ||
| 276 | <script setup lang="ts"> | 226 | <script setup lang="ts"> |
| 277 | -import { PropType, computed, ref } from 'vue' | 227 | +import { PropType, computed, ref, onMounted } from 'vue' |
| 278 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | 228 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
| 279 | import { GlobalThemeJsonType } from '@/settings/chartThemes/index' | 229 | import { GlobalThemeJsonType } from '@/settings/chartThemes/index' |
| 280 | import { GlobalSetting } from '@/components/Pages/ChartItemSetting' | 230 | import { GlobalSetting } from '@/components/Pages/ChartItemSetting' |
| 281 | import SelectCity from './components/SelectCity.vue' | 231 | import SelectCity from './components/SelectCity.vue' |
| 282 | import { regionInfo } from './config' | 232 | import { regionInfo } from './config' |
| 283 | import { cloneDeep } from 'lodash' | 233 | import { cloneDeep } from 'lodash' |
| 234 | +import { getAreaList } from '@/api/external/common/index' | ||
| 235 | +import { areaEnum } from '../../../Decorates/Mores/Weather/config' | ||
| 284 | 236 | ||
| 285 | const props = defineProps({ | 237 | const props = defineProps({ |
| 286 | optionData: { | 238 | optionData: { |
| @@ -293,67 +245,83 @@ const seriesList = computed(() => { | @@ -293,67 +245,83 @@ const seriesList = computed(() => { | ||
| 293 | return props.optionData.series | 245 | return props.optionData.series |
| 294 | }) | 246 | }) |
| 295 | 247 | ||
| 248 | +const datasetMap3DList = computed(() => { | ||
| 249 | + return props.optionData.dataset['map3D'] | ||
| 250 | +}) | ||
| 251 | + | ||
| 296 | const STATIC_SCATTER_CONFIG = { | 252 | const STATIC_SCATTER_CONFIG = { |
| 297 | - name: '', | 253 | + name: null, |
| 254 | + adcode: 510000, | ||
| 255 | + city_name:null, | ||
| 298 | value: [0, 0, 0], | 256 | value: [0, 0, 0], |
| 299 | - adcode: 0, | ||
| 300 | - height: 0, | 257 | + height: 2, |
| 301 | itemStyle: { | 258 | itemStyle: { |
| 302 | - color: '', | 259 | + color: '#4482B1FF', |
| 303 | opacity: 1 | 260 | opacity: 1 |
| 304 | } | 261 | } |
| 305 | } | 262 | } |
| 306 | 263 | ||
| 307 | -const symbolOption = ref([ | ||
| 308 | - { | ||
| 309 | - label: 'circle', | ||
| 310 | - value: 'circle' | ||
| 311 | - }, | ||
| 312 | - { | ||
| 313 | - label: 'rect', | ||
| 314 | - value: 'rect' | ||
| 315 | - }, | ||
| 316 | - { | ||
| 317 | - label: 'roundRect', | ||
| 318 | - value: 'roundRect' | ||
| 319 | - }, | ||
| 320 | - { | ||
| 321 | - label: 'triangle', | ||
| 322 | - value: 'triangle' | ||
| 323 | - }, | ||
| 324 | - { | ||
| 325 | - label: 'diamond', | ||
| 326 | - value: 'diamond' | ||
| 327 | - }, | ||
| 328 | - { | ||
| 329 | - label: 'pin', | ||
| 330 | - value: 'pin' | ||
| 331 | - }, | ||
| 332 | - { | ||
| 333 | - label: 'arrow', | ||
| 334 | - value: 'arrow' | ||
| 335 | - }, | ||
| 336 | - { | ||
| 337 | - label: 'none', | ||
| 338 | - value: 'none' | ||
| 339 | - } | ||
| 340 | -]) | ||
| 341 | - | ||
| 342 | const SelectCityRef = ref<InstanceType<typeof SelectCity>>() | 264 | const SelectCityRef = ref<InstanceType<typeof SelectCity>>() |
| 343 | 265 | ||
| 266 | +const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { | ||
| 267 | + const resp = await getAreaList({ | ||
| 268 | + level, | ||
| 269 | + parentId | ||
| 270 | + }) | ||
| 271 | + if (!resp) return [] | ||
| 272 | + return resp.map((item: Recordable) => ({ label: item.name, value: item.name, adcode: item.code })) | ||
| 273 | +} | ||
| 274 | + | ||
| 275 | +onMounted(async () => { | ||
| 276 | + datasetMap3DList.value.forEach(async (item: Recordable) => { | ||
| 277 | + item.provinceOptions = await getAreaLists() | ||
| 278 | + item.cityOptions = await getAreaLists(areaEnum.CITY, !item.adcode ? mapRegionCache.value.adcode : item.adcode) | ||
| 279 | + item.adcode = !item.adcode ? mapRegionCache.value.adcode : item.adcode | ||
| 280 | + }) | ||
| 281 | +}) | ||
| 282 | + | ||
| 283 | +const onHandleSelectProvince = async (value: number, option: Recordable, item: Recordable, mapIndex: number) => { | ||
| 284 | + const findIndex = datasetMap3DList.value.findIndex((findItem: Recordable) => findItem.name === item.name) | ||
| 285 | + datasetMap3DList.value[findIndex].city_name = null | ||
| 286 | + datasetMap3DList.value[findIndex].adcode = option.adcode | ||
| 287 | + datasetMap3DList.value[findIndex].cityOptions = await getAreaLists(areaEnum.CITY, option.adcode) | ||
| 288 | +} | ||
| 289 | + | ||
| 290 | +const handleAddRegion = () => { | ||
| 291 | + props.optionData.dataset.map3D.push(cloneDeep(STATIC_SCATTER_CONFIG)) | ||
| 292 | + datasetMap3DList.value.forEach(async (item: Recordable) => { | ||
| 293 | + item.provinceOptions = await getAreaLists() | ||
| 294 | + }) | ||
| 295 | +} | ||
| 296 | + | ||
| 297 | +const mapRegionCache = computed(() => { | ||
| 298 | + return props.optionData.mapRegion | ||
| 299 | +}) | ||
| 300 | + | ||
| 344 | const onHandleSelectValues = (values: regionInfo) => { | 301 | const onHandleSelectValues = (values: regionInfo) => { |
| 345 | - const { cityValue, countyValue, provinceValue } = values | ||
| 346 | - props.optionData.mapRegion.saveSelect = values | ||
| 347 | - props.optionData.mapRegion.adcode = countyValue | 302 | + const { cityValue, countyValue, provinceValue, areaName } = values |
| 303 | + mapRegionCache.value.areaName = areaName | ||
| 304 | + mapRegionCache.value.saveSelect = values | ||
| 305 | + mapRegionCache.value.adcode = countyValue | ||
| 348 | ? countyValue | 306 | ? countyValue |
| 349 | : cityValue | 307 | : cityValue |
| 350 | ? cityValue | 308 | ? cityValue |
| 351 | : provinceValue === 'china' | 309 | : provinceValue === 'china' |
| 352 | ? 'china' | 310 | ? 'china' |
| 353 | : provinceValue | 311 | : provinceValue |
| 312 | + props.optionData.mapRegion = mapRegionCache.value | ||
| 354 | } | 313 | } |
| 355 | 314 | ||
| 356 | const handleChangeDrillingIn = () => { | 315 | const handleChangeDrillingIn = () => { |
| 357 | SelectCityRef.value?.resetValue() | 316 | SelectCityRef.value?.resetValue() |
| 317 | + props.optionData.mapRegion.adcode = 'china' | ||
| 318 | + props.optionData.mapRegion.areaName = '' | ||
| 319 | + props.optionData.mapRegion.saveSelect.areaName = '' | ||
| 358 | } | 320 | } |
| 359 | </script> | 321 | </script> |
| 322 | + | ||
| 323 | +<style scoped> | ||
| 324 | +.h-space { | ||
| 325 | + height: 10px; | ||
| 326 | +} | ||
| 327 | +</style> |
| @@ -2,37 +2,9 @@ | @@ -2,37 +2,9 @@ | ||
| 2 | "map3D": [ | 2 | "map3D": [ |
| 3 | { | 3 | { |
| 4 | "name": "四川省", | 4 | "name": "四川省", |
| 5 | - "height": 5, | ||
| 6 | - "adcode": "510000", | ||
| 7 | - "itemStyle": { | ||
| 8 | - "color": "#4482B1FF", | ||
| 9 | - "opacity": 1, | ||
| 10 | - "borderWidth": 0.4, | ||
| 11 | - "borderColor": "#5F9EA0" | ||
| 12 | - } | ||
| 13 | - }, | ||
| 14 | - { | ||
| 15 | - "name": "山西省", | ||
| 16 | - "height": 6, | ||
| 17 | - "adcode": "140000", | ||
| 18 | - "itemStyle": { | ||
| 19 | - "color": "#4482B1FF", | ||
| 20 | - "opacity": 1, | ||
| 21 | - "borderWidth": 0.4, | ||
| 22 | - "borderColor": "#5F9EA0" | ||
| 23 | - } | ||
| 24 | - } | ||
| 25 | - ], | ||
| 26 | - "scatter3D": [ | ||
| 27 | - { | ||
| 28 | - "name": "广东省", | ||
| 29 | - "value": [ | ||
| 30 | - 113.2592945, | ||
| 31 | - 23.1301964, | ||
| 32 | - 20000 | ||
| 33 | - ], | ||
| 34 | - "adcode": "440000", | ||
| 35 | - "height": 5, | 5 | + "adcode": 510000, |
| 6 | + "city_name": "成都市", | ||
| 7 | + "height": 2, | ||
| 36 | "itemStyle": { | 8 | "itemStyle": { |
| 37 | "color": "#4482B1FF", | 9 | "color": "#4482B1FF", |
| 38 | "opacity": 1, | 10 | "opacity": 1, |
| @@ -43,14 +15,12 @@ | @@ -43,14 +15,12 @@ | ||
| 43 | ], | 15 | ], |
| 44 | "bar3D": [ | 16 | "bar3D": [ |
| 45 | { | 17 | { |
| 46 | - "name": "安徽省", | ||
| 47 | "value": [ | 18 | "value": [ |
| 48 | 117.283042, | 19 | 117.283042, |
| 49 | 31.86119, | 20 | 31.86119, |
| 50 | 20000 | 21 | 20000 |
| 51 | ], | 22 | ], |
| 52 | - "adcode": "340000", | ||
| 53 | - "height": 5, | 23 | + "height": 2, |
| 54 | "itemStyle": { | 24 | "itemStyle": { |
| 55 | "color": "#4482B1FF", | 25 | "color": "#4482B1FF", |
| 56 | "opacity": 1, | 26 | "opacity": 1, |
| @@ -59,4 +29,4 @@ | @@ -59,4 +29,4 @@ | ||
| 59 | } | 29 | } |
| 60 | } | 30 | } |
| 61 | ] | 31 | ] |
| 62 | -} | ||
| 32 | +} |
| @@ -20,10 +20,12 @@ import config, { | @@ -20,10 +20,12 @@ import config, { | ||
| 20 | backMapLevel, | 20 | backMapLevel, |
| 21 | levelFunc, | 21 | levelFunc, |
| 22 | regionMapParentArea, | 22 | regionMapParentArea, |
| 23 | - specialTreatmentAnhui | 23 | + specialTreatmentAnhui, |
| 24 | + setScale | ||
| 24 | } from './config' | 25 | } from './config' |
| 25 | import { getGeoJsonMap } from '@/api/external/common' | 26 | import { getGeoJsonMap } from '@/api/external/common' |
| 26 | import { ThreeMapEnum } from '@/enums/external/mapEnum' | 27 | import { ThreeMapEnum } from '@/enums/external/mapEnum' |
| 28 | +import cloneDeep from 'lodash/cloneDeep' | ||
| 27 | 29 | ||
| 28 | const props = defineProps({ | 30 | const props = defineProps({ |
| 29 | chartConfig: { | 31 | chartConfig: { |
| @@ -115,13 +117,14 @@ props.chartConfig.option = { | @@ -115,13 +117,14 @@ props.chartConfig.option = { | ||
| 115 | 117 | ||
| 116 | //地图点击返回 | 118 | //地图点击返回 |
| 117 | const handleBack = async () => { | 119 | const handleBack = async () => { |
| 120 | + stopWatch() | ||
| 118 | if (drillingIn.value) { | 121 | if (drillingIn.value) { |
| 119 | //如果是从右边配置里设置的,比如点击四川省,然后点击返回 | 122 | //如果是从右边配置里设置的,比如点击四川省,然后点击返回 |
| 120 | const savePopParent = saveHistoryParent.value.pop() | 123 | const savePopParent = saveHistoryParent.value.pop() |
| 121 | let saveAdcode = savePopParent?.adcode as string | number | 124 | let saveAdcode = savePopParent?.adcode as string | number |
| 122 | saveLevelStr.level = savePopParent?.level as string | 125 | saveLevelStr.level = savePopParent?.level as string |
| 123 | if (!savePopParent) { | 126 | if (!savePopParent) { |
| 124 | - saveAdcode = getParentAdcode(mapRegion.value.adcode) | 127 | + saveAdcode = getParentAdcode(mapRegion.value.adcode).adcodeNum |
| 125 | saveLevelStr.level = (regionMapParentArea as Recordable)[mapRegion.value.saveSelect.levelStr] | 128 | saveLevelStr.level = (regionMapParentArea as Recordable)[mapRegion.value.saveSelect.levelStr] |
| 126 | } | 129 | } |
| 127 | if (saveAdcode === 0) { | 130 | if (saveAdcode === 0) { |
| @@ -132,6 +135,7 @@ const handleBack = async () => { | @@ -132,6 +135,7 @@ const handleBack = async () => { | ||
| 132 | const adcode = saveAdcode === 100000 ? 'china' : saveAdcode | 135 | const adcode = saveAdcode === 100000 ? 'china' : saveAdcode |
| 133 | saveClickRegion.value.level = saveLevelStr.level | 136 | saveClickRegion.value.level = saveLevelStr.level |
| 134 | if (exist) { | 137 | if (exist) { |
| 138 | + mapRegion.value.areaName = getParentAdcode(mapRegion.value.adcode).areaName | ||
| 135 | //fix 解决点击下钻返回后页面为空问题 | 139 | //fix 解决点击下钻返回后页面为空问题 |
| 136 | mapRegion.value.adcode = adcode | 140 | mapRegion.value.adcode = adcode |
| 137 | } | 141 | } |
| @@ -142,20 +146,24 @@ const handleBack = async () => { | @@ -142,20 +146,24 @@ const handleBack = async () => { | ||
| 142 | const handleMap3DClick = async (params: Recordable) => { | 146 | const handleMap3DClick = async (params: Recordable) => { |
| 143 | if (drillingIn.value) { | 147 | if (drillingIn.value) { |
| 144 | const { name } = params | 148 | const { name } = params |
| 145 | - saveGeojson.value?.features.forEach((item: Recordable) => { | 149 | + const geoJson = JSON.parse(saveGeojson.value?.geoJson) |
| 150 | + geoJson?.features.forEach((item: Recordable) => { | ||
| 146 | if (item.properties.name === name) { | 151 | if (item.properties.name === name) { |
| 147 | const level = item.properties.level.toUpperCase() | 152 | const level = item.properties.level.toUpperCase() |
| 148 | const adcode = item.properties.adcode | 153 | const adcode = item.properties.adcode |
| 154 | + const areaName = item.properties.name | ||
| 149 | if (level === 'DISTRICT') return //下钻暂且不支持地区 | 155 | if (level === 'DISTRICT') return //下钻暂且不支持地区 |
| 150 | if (String(adcode).startsWith('15') && level === areaEnum.CITY) return //特殊处理地区码15开头的 | 156 | if (String(adcode).startsWith('15') && level === areaEnum.CITY) return //特殊处理地区码15开头的 |
| 151 | mapRegion.value.adcode = adcode | 157 | mapRegion.value.adcode = adcode |
| 158 | + mapRegion.value.areaName = areaName | ||
| 152 | saveClickRegion.value.level = level | 159 | saveClickRegion.value.level = level |
| 153 | saveLevelStr.level = level | 160 | saveLevelStr.level = level |
| 154 | saveHistoryParent.value.push({ | 161 | saveHistoryParent.value.push({ |
| 155 | adcode: specialTreatmentAnhui.includes(item.properties.name) | 162 | adcode: specialTreatmentAnhui.includes(item.properties.name) |
| 156 | ? JSON.parse(item.properties.parent)?.adcode | 163 | ? JSON.parse(item.properties.parent)?.adcode |
| 157 | : item.properties.parent.adcode, | 164 | : item.properties.parent.adcode, |
| 158 | - level: (regionMapParentArea as Recordable)[level] | 165 | + level: (regionMapParentArea as Recordable)[level], |
| 166 | + areaName: saveGeojson.value.name | ||
| 159 | }) | 167 | }) |
| 160 | } | 168 | } |
| 161 | }) | 169 | }) |
| @@ -182,18 +190,22 @@ const getGeojson = (regionId: number | string) => { | @@ -182,18 +190,22 @@ const getGeojson = (regionId: number | string) => { | ||
| 182 | regionId === 'china' ? chinaDefaultRegionId.value : regionId, | 190 | regionId === 'china' ? chinaDefaultRegionId.value : regionId, |
| 183 | !saveLevelStr.level ? levelStr : saveLevelStr.level //没有则获取右侧配置的行政级别 | 191 | !saveLevelStr.level ? levelStr : saveLevelStr.level //没有则获取右侧配置的行政级别 |
| 184 | ).then(res => { | 192 | ).then(res => { |
| 185 | - const { geoJson, name, code, level } = res.data | 193 | + saveGeojson.value = res.data //保存一份服务端返回的数据 |
| 194 | + const { geoJson, name, level, code } = res.data | ||
| 186 | const geoJsonFile = JSON.parse(geoJson) | 195 | const geoJsonFile = JSON.parse(geoJson) |
| 187 | if (!geoJsonFile) return | 196 | if (!geoJsonFile) return |
| 188 | - saveGeojson.value = geoJsonFile //保存一份服务端返回的geojson | ||
| 189 | const nameChina = name === '中国' ? 'china' : name //为中国的话,registerMap第一个必须是china,否则显示不出来 | 197 | const nameChina = name === '中国' ? 'china' : name //为中国的话,registerMap第一个必须是china,否则显示不出来 |
| 190 | /** | 198 | /** |
| 191 | * 主要注意的点,registerMap中的第一个参数需要和series中的map匹配,否则渲染不出地图, | 199 | * 主要注意的点,registerMap中的第一个参数需要和series中的map匹配,否则渲染不出地图, |
| 192 | * 比如map: '北京市' echarts.registerMap('北京市', beijingGeoJSON); | 200 | * 比如map: '北京市' echarts.registerMap('北京市', beijingGeoJSON); |
| 193 | */ | 201 | */ |
| 194 | - registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile, specialAreas: {} }) //注册geoJSON | 202 | + registerMap(level === areaEnum.COUNTRY ? nameChina : !mapRegion.value.areaName ? code : name, { |
| 203 | + geoJSON: geoJsonFile, | ||
| 204 | + specialAreas: {} | ||
| 205 | + }) //注册geoJSON | ||
| 195 | resolve(true) | 206 | resolve(true) |
| 196 | show.value = false | 207 | show.value = false |
| 208 | + changeOption.value = true | ||
| 197 | }) | 209 | }) |
| 198 | }) | 210 | }) |
| 199 | } catch (error) { | 211 | } catch (error) { |
| @@ -210,12 +222,15 @@ registerMap(mapRegion.value.adcode, { geoJSON: {} as any, specialAreas: {} }) | @@ -210,12 +222,15 @@ registerMap(mapRegion.value.adcode, { geoJSON: {} as any, specialAreas: {} }) | ||
| 210 | //传adcode 获取上级 | 222 | //传adcode 获取上级 |
| 211 | const getParentAdcode = (adcode: number) => { | 223 | const getParentAdcode = (adcode: number) => { |
| 212 | let adcodeNum = 100000 | 224 | let adcodeNum = 100000 |
| 213 | - saveGeojson.value?.features.forEach((item: Recordable) => { | 225 | + let areaName = '' |
| 226 | + const geoJson = JSON.parse(saveGeojson.value?.geoJson) | ||
| 227 | + geoJson.features.forEach((item: Recordable) => { | ||
| 214 | if (item.properties.adcode === adcode) { | 228 | if (item.properties.adcode === adcode) { |
| 215 | adcodeNum = item.properties.parent.adcode | 229 | adcodeNum = item.properties.parent.adcode |
| 230 | + areaName = saveGeojson.value.name | ||
| 216 | } | 231 | } |
| 217 | }) | 232 | }) |
| 218 | - return adcodeNum | 233 | + return { adcodeNum, areaName } |
| 219 | } | 234 | } |
| 220 | 235 | ||
| 221 | // 初始化三维地图 | 236 | // 初始化三维地图 |
| @@ -224,7 +239,7 @@ const initMap3D = async () => { | @@ -224,7 +239,7 @@ const initMap3D = async () => { | ||
| 224 | await nextTick() | 239 | await nextTick() |
| 225 | await getGeojson(mapRegion.value.adcode) | 240 | await getGeojson(mapRegion.value.adcode) |
| 226 | await nextTick().then(() => { | 241 | await nextTick().then(() => { |
| 227 | - handleRegisterMapNameAndData(mapRegion.value.adcode, dataset.value) | 242 | + handleRegisterMapNameAndData(mapRegion.value.adcode, dataset.value, 'china') |
| 228 | }) | 243 | }) |
| 229 | chartInstance.value?.on('click', (e: Recordable) => { | 244 | chartInstance.value?.on('click', (e: Recordable) => { |
| 230 | if (!e) return | 245 | if (!e) return |
| @@ -235,16 +250,13 @@ const initMap3D = async () => { | @@ -235,16 +250,13 @@ const initMap3D = async () => { | ||
| 235 | onMounted(() => initMap3D()) | 250 | onMounted(() => initMap3D()) |
| 236 | 251 | ||
| 237 | // 动态注册 series中的map必须和registerMap的第一个参数匹配,否则渲染不出 | 252 | // 动态注册 series中的map必须和registerMap的第一个参数匹配,否则渲染不出 |
| 238 | -const handleRegisterMapNameAndData = (adcode: string | number, data: Recordable) => { | ||
| 239 | - geo3D.value.map = adcode // coordinateSystem使用了geo3D,不能删除这一行 | 253 | +const handleRegisterMapNameAndData = (adcode: string | number, data: Recordable, areaName: string) => { |
| 254 | + geo3D.value.map = !areaName ? adcode : areaName // coordinateSystem使用了geo3D,不能删除这一行 | ||
| 240 | series.value.forEach((item: Recordable) => { | 255 | series.value.forEach((item: Recordable) => { |
| 241 | if (item.type === ThreeMapEnum.MAP3D) { | 256 | if (item.type === ThreeMapEnum.MAP3D) { |
| 242 | - item.map = adcode | 257 | + item.map = !areaName ? adcode : areaName |
| 243 | item.data = data[ThreeMapEnum.MAP3D] | 258 | item.data = data[ThreeMapEnum.MAP3D] |
| 244 | } | 259 | } |
| 245 | - if (item.type === ThreeMapEnum.SCATTER3D) { | ||
| 246 | - item.data = data[ThreeMapEnum.SCATTER3D] | ||
| 247 | - } | ||
| 248 | if (item.type === ThreeMapEnum.BAR3D) { | 260 | if (item.type === ThreeMapEnum.BAR3D) { |
| 249 | item.data = data[ThreeMapEnum.BAR3D] | 261 | item.data = data[ThreeMapEnum.BAR3D] |
| 250 | } | 262 | } |
| @@ -274,18 +286,27 @@ watch( | @@ -274,18 +286,27 @@ watch( | ||
| 274 | ) | 286 | ) |
| 275 | 287 | ||
| 276 | //处理数据标点 | 288 | //处理数据标点 |
| 277 | -const handleDataPoint = (newData: string | number) => { | 289 | +const handleDataPoint = (newData: string | number, areaName: string) => { |
| 278 | if (newData === 'china') { | 290 | if (newData === 'china') { |
| 279 | // 全国则展示所有的标点 | 291 | // 全国则展示所有的标点 |
| 280 | - handleRegisterMapNameAndData(newData, dataset.value) | 292 | + handleRegisterMapNameAndData(newData, dataset.value, 'china') |
| 281 | } else { | 293 | } else { |
| 282 | // 展示对应区域的标点 | 294 | // 展示对应区域的标点 |
| 283 | series.value.forEach((item: Recordable) => { | 295 | series.value.forEach((item: Recordable) => { |
| 284 | if (item.type === ThreeMapEnum.MAP3D) { | 296 | if (item.type === ThreeMapEnum.MAP3D) { |
| 285 | - item.data = [] //置空,否则鼠标移上去点击不了,不知道原因! | ||
| 286 | - } | ||
| 287 | - if (item.type === ThreeMapEnum.SCATTER3D) { | ||
| 288 | - item.data = dataset.value[ThreeMapEnum.SCATTER3D].filter((dataItem: dataPointI) => dataItem.adcode === newData) | 297 | + item.map = !areaName ? newData : areaName |
| 298 | + item.data = dataset.value[ThreeMapEnum.MAP3D].filter((dataItem: dataPointI) => { | ||
| 299 | + if (String(dataItem.adcode) === String(!areaName ? newData : areaName)) { | ||
| 300 | + return dataItem | ||
| 301 | + } else if (dataItem.name === String(!areaName ? newData : areaName)) { | ||
| 302 | + return dataItem | ||
| 303 | + } | ||
| 304 | + }) | ||
| 305 | + const cloneDeepData = cloneDeep(item.data) | ||
| 306 | + cloneDeepData.forEach((item: dataPointI) => { | ||
| 307 | + item.name = item.city_name | ||
| 308 | + }) | ||
| 309 | + item.data = cloneDeepData.filter((item: Recordable) => item.name !== null) || [] | ||
| 289 | } | 310 | } |
| 290 | if (item.type === ThreeMapEnum.BAR3D) { | 311 | if (item.type === ThreeMapEnum.BAR3D) { |
| 291 | item.data = dataset.value[ThreeMapEnum.BAR3D].filter((dataItem: dataPointI) => dataItem.adcode === newData) | 312 | item.data = dataset.value[ThreeMapEnum.BAR3D].filter((dataItem: dataPointI) => dataItem.adcode === newData) |
| @@ -293,22 +314,56 @@ const handleDataPoint = (newData: string | number) => { | @@ -293,22 +314,56 @@ const handleDataPoint = (newData: string | number) => { | ||
| 293 | }) | 314 | }) |
| 294 | } | 315 | } |
| 295 | } | 316 | } |
| 317 | +const changeOption = ref(false) | ||
| 296 | 318 | ||
| 297 | // 监听地图展示区域发生变化 | 319 | // 监听地图展示区域发生变化 |
| 298 | watch( | 320 | watch( |
| 299 | () => `${props.chartConfig.option.mapRegion.adcode}`, | 321 | () => `${props.chartConfig.option.mapRegion.adcode}`, |
| 300 | - async (newData: string | number) => { | 322 | + async (newData: number | string) => { |
| 301 | try { | 323 | try { |
| 302 | await getGeojson(newData) | 324 | await getGeojson(newData) |
| 303 | - handleRegisterMapNameAndData(newData, dataset.value) | ||
| 304 | - handleDataPoint(newData) | ||
| 305 | - handleSetOption(chartInstance.value!, props.chartConfig.option) | 325 | + const { distance, zoom, alpha } = setScale(String(newData)) |
| 326 | + const option = props.chartConfig.option | ||
| 327 | + // 修复缩放 | ||
| 328 | + const { series } = option || {} | ||
| 329 | + series?.forEach((item: Recordable) => { | ||
| 330 | + if (item.type === 'map3D') { | ||
| 331 | + item.viewControl = { | ||
| 332 | + ...item?.viewControl, | ||
| 333 | + distance, | ||
| 334 | + zoom, | ||
| 335 | + alpha | ||
| 336 | + } | ||
| 337 | + } | ||
| 338 | + }) | ||
| 339 | + handleRegisterMapNameAndData(newData, dataset.value, mapRegion.value.areaName) | ||
| 340 | + handleDataPoint(newData, mapRegion.value.areaName) | ||
| 341 | + changeOption.value = true | ||
| 342 | + handleSetOption(chartInstance.value!, { ...option, series }) | ||
| 306 | } catch (error) { | 343 | } catch (error) { |
| 307 | console.error('展示区域发生变化出错,出错原因->', error) | 344 | console.error('展示区域发生变化出错,出错原因->', error) |
| 308 | } | 345 | } |
| 309 | }, | 346 | }, |
| 310 | { | 347 | { |
| 311 | - immediate: true | 348 | + immediate: true, |
| 349 | + deep: true | ||
| 350 | + } | ||
| 351 | +) | ||
| 352 | + | ||
| 353 | +// 实时监听地图右侧配置项变化 | ||
| 354 | +const stopWatch = watch( | ||
| 355 | + props.chartConfig.option, | ||
| 356 | + async newData => { | ||
| 357 | + try { | ||
| 358 | + if (changeOption.value) { | ||
| 359 | + // handleSetOption(chartInstance.value!, newData) | ||
| 360 | + } | ||
| 361 | + } catch (error) { | ||
| 362 | + console.error('监听地图右侧配置项变化,出错原因->', error) | ||
| 363 | + } | ||
| 364 | + }, | ||
| 365 | + { | ||
| 366 | + deep: true | ||
| 312 | } | 367 | } |
| 313 | ) | 368 | ) |
| 314 | </script> | 369 | </script> |