From 71f315d30e01aab73a462b5480c886d5b2320f4c Mon Sep 17 00:00:00 2001 From: wisonic Date: Thu, 28 Nov 2024 18:52:51 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E5=9B=BE=E8=A1=A8):=20=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=E8=87=AA=E5=AE=9A=E4=B9=89=E5=8C=BA=E5=9F=9F=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=BD=AE=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/core-frontend/src/models/chart/map.d.ts | 1 + .../js/panel/charts/map/bubble-map.ts | 49 ++++++++++-- .../components/js/panel/charts/map/map.ts | 48 ++++++------ .../js/panel/charts/map/tooltip-carousel.ts | 74 +++++++++++++++---- 4 files changed, 130 insertions(+), 42 deletions(-) diff --git a/core/core-frontend/src/models/chart/map.d.ts b/core/core-frontend/src/models/chart/map.d.ts index 914269ba46..a2ecdc6dfb 100644 --- a/core/core-frontend/src/models/chart/map.d.ts +++ b/core/core-frontend/src/models/chart/map.d.ts @@ -14,4 +14,5 @@ interface CustomGeoArea { type CustomGeoSubArea = CustomGeoArea & { geoAreaId: string scope: string + scopeArr?: string[] } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts index b90f488d15..b7d4ed018b 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts @@ -63,15 +63,48 @@ export class BubbleMap extends L7PlotChartView { chart.container = container let geoJson = {} as FeatureCollection let customSubArea: CustomGeoSubArea[] = [] - if (areaId.startsWith('custom_') || scope) { + let data = chart.data?.data + if (areaId.startsWith('custom_')) { customSubArea = (await getCustomGeoArea(areaId)).data || [] customSubArea.forEach(a => (a.scopeArr = a.scope?.split(',') || [])) geoJson = cloneDeep(await getGeoJsonFile('156')) - if (scope) { - geoJson.features = geoJson.features.filter(f => scope.includes('156' + f.properties.adcode)) - } + const areaNameMap = geoJson.features.reduce((p, n) => { + p['156' + n.properties.adcode] = n.properties.name + return p + }, {}) + const { areaMapping } = parseJson(chart.senior) + const areaMap = customSubArea.reduce((p, n) => { + const mappedName = areaMapping?.[areaId]?.[n.name] + if (mappedName) { + n.name = mappedName + } + p[n.name] = n + n.scopeArr = n.scope?.split(',') || [] + return p + }, {}) + const fakeData = [] + data?.forEach(d => { + const area = areaMap[d.name] + if (area) { + area.scopeArr.forEach(adcode => { + fakeData.push({ + ...d, + name: areaNameMap[adcode], + field: areaNameMap[adcode], + scope: area.scopeArr, + areaName: d.name + }) + }) + } + }) + data = fakeData } else { - geoJson = cloneDeep(await getGeoJsonFile(areaId)) + if (scope) { + geoJson = cloneDeep(await getGeoJsonFile('156')) + geoJson.features = geoJson.features.filter(f => scope.includes('156' + f.properties.adcode)) + } else { + geoJson = cloneDeep(await getGeoJsonFile(areaId)) + } } let options: ChoroplethOptions = { preserveDrawingBuffer: true, @@ -83,7 +116,7 @@ export class BubbleMap extends L7PlotChartView { type: 'geojson' }, source: { - data: chart.data?.data || [], + data: data || [], joinBy: { sourceField: 'name', geoField: 'name', @@ -164,7 +197,7 @@ export class BubbleMap extends L7PlotChartView { }) dotLayer.once('loaded', () => { chart.container = container - configCarouselTooltip(chart, view, chart.data?.data || [], null) + configCarouselTooltip(chart, view, data || [], null, customSubArea, drawOption) }) }) return view @@ -239,6 +272,8 @@ export class BubbleMap extends L7PlotChartView { features: areaJsonArr } const center = centroid(areaJson) + // 轮播用 + area.centroid = [center.geometry.coordinates[0], center.geometry.coordinates[1]] dotData.push({ name: area.name, size: d.value, diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts index ce6ccc819e..2ca0434a23 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts @@ -235,7 +235,7 @@ export class Map extends L7PlotChartView { }) }) chart.container = container - configCarouselTooltip(chart, view, data, null) + configCarouselTooltip(chart, view, data, null, customSubArea, drawOption) }) return view } @@ -455,31 +455,38 @@ export class Map extends L7PlotChartView { const customAttr = parseJson(chart.customAttr) const { label } = customAttr const data = chart.data.data - const areaMap = data.reduce((obj, value) => { + const areaMap = data?.reduce((obj, value) => { obj[value['field']] = value return obj }, {}) + const geoJsonMap = geoJson.features.reduce((p, n) => { + if (n.properties['adcode']) { + p['156' + n.properties['adcode']] = n + } + return p + }, {}) + customSubArea.forEach(area => { + const areaJsonArr = [] + area.scopeArr?.forEach(adcode => { + const json = geoJsonMap[adcode] + json && areaJsonArr.push(json) + }) + if (areaJsonArr.length) { + const areaJson: FeatureCollection = { + type: 'FeatureCollection', + features: areaJsonArr + } + const center = centroid(areaJson) + // 轮播用 + area.centroid = [center.geometry.coordinates[0], center.geometry.coordinates[1]] + } + }) //处理label options.label = false if (label.show) { - const geoJsonMap = geoJson.features.reduce((p, n) => { - if (n.properties['adcode']) { - p['156' + n.properties['adcode']] = n - } - return p - }, {}) const labelLocation = [] customSubArea.forEach(area => { - const areaJsonArr = [] - area.scopeArr?.forEach(adcode => { - const json = geoJsonMap[adcode] - json && areaJsonArr.push(json) - }) - if (areaJsonArr.length) { - const areaJson: FeatureCollection = { - type: 'FeatureCollection', - features: areaJsonArr - } + if (area.centroid) { const content = [] if (label.showDimension) { content.push(area.name) @@ -488,11 +495,10 @@ export class Map extends L7PlotChartView { areaMap[area.name] && content.push(valueFormatter(areaMap[area.name].value, label.quotaLabelFormatter)) } - const center = centroid(areaJson) labelLocation.push({ name: content.join('\n\n'), - x: center.geometry.coordinates[0], - y: center.geometry.coordinates[1] + x: area.centroid[0], + y: area.centroid[1] }) } }) diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/map/tooltip-carousel.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/map/tooltip-carousel.ts index bf91cbf1b0..e4fbf4e035 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/map/tooltip-carousel.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/map/tooltip-carousel.ts @@ -6,13 +6,17 @@ import { parseJson } from '@/views/chart/components/js/util' import { Scene } from '@antv/l7-scene' import { deepCopy } from '@/utils/utils' -export const configCarouselTooltip = (chart, view, data, scene) => { +export const configCarouselTooltip = (chart, view, data, scene, customSubArea, drawOption?) => { if (['bubble-map', 'map'].includes(chart.type)) { data = view.source.data.dataArray ?.filter(i => i.dimensionList?.length > 0) .reduce((acc, current) => { const existingItem = acc.find(obj => { - return obj.name === current.name || (obj.adcode && obj.adcode === current.adcode) + if (drawOption?.areaId?.startsWith('custom_')) { + return obj.areaName === current.areaName + } else { + return obj.name === current.name || (obj.adcode && obj.adcode === current.adcode) + } }) if (!existingItem) { acc.push(current) @@ -22,9 +26,9 @@ export const configCarouselTooltip = (chart, view, data, scene) => { } if (carouselManagerInstances[chart.container]) { const instances = carouselManagerInstances[chart.container] - instances.update(scene, chart, view, data) + instances.update(scene, chart, view, data, customSubArea, drawOption) } else { - new CarouselManager(scene, chart, view, data) + new CarouselManager(scene, chart, view, data, customSubArea, drawOption) } } export const carouselManagerInstances: { [key: string]: CarouselManager } = {} @@ -81,18 +85,30 @@ export class CarouselManager { */ private popup: Popup + /** + * 自定义区域列表 + * @private + */ + private customSubArea: CustomGeoSubArea[] + + /** + * 渲染参数 + * @private + */ + private drawOption: L7PlotDrawOptions + // 保存事件监听函数的引用 private onMouseEnterHandler: () => void private onMouseLeaveHandler: () => void private onVisibilityChangeHandler: () => void - constructor(scene, chart, view, data: any[]) { + constructor(scene, chart, view, data: any[], customSubArea, drawOption?) { // 绑定事件处理函数 this.onMouseEnterHandler = this.pauseCarouselPopups.bind(this) this.onMouseLeaveHandler = this.resumeCarouselPopups.bind(this) this.onVisibilityChangeHandler = this.handleVisibilityChange.bind(this) this.clearExistingTimers = this.clearExistingTimers.bind(this) - this.init(scene, chart, view, data) + this.init(scene, chart, view, data, customSubArea, drawOption) } /** @@ -101,9 +117,10 @@ export class CarouselManager { * @param chart * @param view * @param data + * @param customSubArea */ - public update(scene, chart, view, data: any[]) { - this.init(scene, chart, view, data) + public update(scene, chart, view, data: any[], customSubArea, drawOption?) { + this.init(scene, chart, view, data, customSubArea, drawOption) } /** @@ -114,13 +131,15 @@ export class CarouselManager { * @param data * @private */ - private init(scene, chart, view, data: any[]) { + private init(scene, chart, view, data: any[], customSubArea, drawOption?) { this.view = view this.chart = chart this.scene = scene this.data = data this.popup = null this.currentIndex = 0 + this.customSubArea = customSubArea + this.drawOption = drawOption this.clearPreviousInstance(this.chart.container) if ( this.chart.customAttr?.tooltip?.show && @@ -336,6 +355,23 @@ export class CarouselManager { } private getActiveData(index): any { + if (this.drawOption?.areaId?.startsWith('custom_')) { + const result = { + type: 'FeatureCollection', + features: [] + } + const area = this.customSubArea.find(a => a.name === this.data[index].areaName) + const areaMap = this.view.currentDistrictData.features.reduce((p, n) => { + p['156' + n.properties.adcode] = n + return p + }, {}) + area?.scopeArr?.forEach(s => { + if (areaMap[s]) { + result.features.push(areaMap[s]) + } + }) + return result + } return { type: 'FeatureCollection', features: [ @@ -352,11 +388,21 @@ export class CarouselManager { * @private */ private getPopupData(index: number): any { - return { - data: this.data[index], - centroid: this.view.currentDistrictData.features.find( - i => i.properties.name === this.data[index].name - )?.properties.centroid + if (this.drawOption?.areaId?.startsWith('custom_')) { + const data = this.data[index] + const area = this.customSubArea?.find(a => a.name === data.areaName) + data.name = data.areaName + return { + data, + centroid: area.centroid + } + } else { + return { + data: this.data[index], + centroid: this.view.currentDistrictData.features.find( + i => i.properties.name === this.data[index].name + )?.properties.centroid + } } }