diff --git a/src/chart/map/MapSeries.ts b/src/chart/map/MapSeries.ts index 157678f412..83da5b0535 100644 --- a/src/chart/map/MapSeries.ts +++ b/src/chart/map/MapSeries.ts @@ -45,6 +45,7 @@ import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup'; import {createSymbol, ECSymbol} from '../../util/symbol'; import {LegendIconParams} from '../../component/legend/LegendModel'; import {Group} from '../../util/graphic'; +import { GeoJSONRegion } from '../../coord/geo/Region'; export interface MapStateOption { itemStyle?: GeoItemStyleOption @@ -117,26 +118,36 @@ class MapSeries extends SeriesModel { coordDimensions: ['value'], encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this) }); - const dataNameMap = zrUtil.createHashMap(); - const toAppendNames = [] as string[]; + const dataNameIndexMap = zrUtil.createHashMap(); + const toAppendItems: MapDataItemOption[] = []; for (let i = 0, len = data.count(); i < len; i++) { const name = data.getName(i); - dataNameMap.set(name, true); + dataNameIndexMap.set(name, i); } const geoSource = geoSourceManager.load(this.getMapType(), this.option.nameMap, this.option.nameProperty); zrUtil.each(geoSource.regions, function (region) { const name = region.name; - if (!dataNameMap.get(name)) { - toAppendNames.push(name); + const dataNameIdx = dataNameIndexMap.get(name); + // apply specified echarts style in GeoJSON data + const specifiedGeoJSONRegionStyle = (region as GeoJSONRegion).properties + && (region as GeoJSONRegion).properties.echartsStyle; + let dataItem: MapDataItemOption; + if (dataNameIdx == null) { + dataItem = { name: name }; + toAppendItems.push(dataItem); } + else { + dataItem = data.getRawDataItem(dataNameIdx) as MapDataItemOption; + } + specifiedGeoJSONRegionStyle && zrUtil.merge(dataItem, specifiedGeoJSONRegionStyle); }); // Complete data with missing regions. The consequent processes (like visual // map and render) can not be performed without a "full data". For example, // find `dataIndex` by name. - data.appendValues([], toAppendNames); + data.appendData(toAppendItems); return data; } diff --git a/src/component/helper/MapDraw.ts b/src/component/helper/MapDraw.ts index 635b998f88..b8bbb8676f 100644 --- a/src/component/helper/MapDraw.ts +++ b/src/component/helper/MapDraw.ts @@ -30,7 +30,7 @@ import { import geoSourceManager from '../../coord/geo/geoSourceManager'; import {getUID} from '../../util/component'; import ExtensionAPI from '../../core/ExtensionAPI'; -import GeoModel, { GeoCommonOptionMixin, GeoItemStyleOption, RegoinOption } from '../../coord/geo/GeoModel'; +import GeoModel, { GeoCommonOptionMixin, GeoItemStyleOption, RegionOption } from '../../coord/geo/GeoModel'; import MapSeries, { MapDataItemOption } from '../../chart/map/MapSeries'; import GlobalModel from '../../model/Global'; import { Payload, ECElement, LineStyleOption, InnerFocus, DisplayState } from '../../util/types'; @@ -240,7 +240,7 @@ class MapDraw { const regionsGroupByName = this._regionsGroupByName = zrUtil.createHashMap(); const regionsInfoByName = zrUtil.createHashMap<{ dataIdx: number; - regionModel: Model | Model; + regionModel: Model | Model; }, string>(); const regionsGroup = this._regionsGroup; const transformInfoRaw = viewBuildCtx.transformInfoRaw; @@ -302,10 +302,6 @@ class MapDraw { ? mapOrGeoModel.getRegionModel(regionName) : (data ? data.getItemModel(dataIdx) as Model : null); - // allow specified echarts style in GeoJSON data - const specifiedRegionStyle = region.properties && region.properties.echartsStyle; - specifiedRegionStyle && zrUtil.merge(regionModel.option, specifiedRegionStyle); - regionsInfoByName.set(regionName, { dataIdx, regionModel }); } diff --git a/src/coord/geo/GeoModel.ts b/src/coord/geo/GeoModel.ts index c3dde67848..8caca01ea7 100644 --- a/src/coord/geo/GeoModel.ts +++ b/src/coord/geo/GeoModel.ts @@ -59,12 +59,17 @@ interface GeoLabelFormatterDataParams { status: DisplayState; } -export interface RegoinOption extends GeoStateOption, StatesOptionMixin { +export interface RegionOption extends GeoStateOption, StatesOptionMixin { name?: string selected?: boolean tooltip?: CommonTooltipOption } +/** + * @deprecated Use `RegionOption` instead. + */ +export interface RegoinOption extends RegionOption {} + export interface GeoTooltipFormatterParams { componentType: 'geo' geoIndex: number @@ -118,7 +123,7 @@ export interface GeoOption extends show?: boolean; silent?: boolean; - regions?: RegoinOption[]; + regions?: RegionOption[]; stateAnimation?: AnimationOptionMixin @@ -137,7 +142,7 @@ class GeoModel extends ComponentModel { static layoutMode = 'box' as const; - private _optionModelMap: zrUtil.HashMap>; + private _optionModelMap: zrUtil.HashMap>; static defaultOption: GeoOption = { @@ -263,7 +268,7 @@ class GeoModel extends ComponentModel { /** * Get model of region. */ - getRegionModel(name: string): Model { + getRegionModel(name: string): Model { return this._optionModelMap.get(name) || new Model(null, this, this.ecModel); } diff --git a/src/coord/geo/Region.ts b/src/coord/geo/Region.ts index e03863dcd7..29eb84faea 100644 --- a/src/coord/geo/Region.ts +++ b/src/coord/geo/Region.ts @@ -25,7 +25,7 @@ import { GeoJSON, GeoProjection, GeoSVGGraphicRoot } from './geoTypes'; import * as matrix from 'zrender/src/core/matrix'; import type Element from 'zrender/src/Element'; import { each } from 'zrender/src/core/util'; -import type { RegoinOption } from './GeoModel'; +import type { RegionOption } from './GeoModel'; const TMP_TRANSFORM = [] as number[]; @@ -137,7 +137,7 @@ export class GeoJSONRegion extends Region { // Injected outside. properties: GeoJSON['features'][0]['properties'] & { - echartsStyle?: Omit + echartsStyle?: Omit }; constructor( diff --git a/src/coord/geo/geoCreator.ts b/src/coord/geo/geoCreator.ts index f51700ae0b..4e948d771d 100644 --- a/src/coord/geo/geoCreator.ts +++ b/src/coord/geo/geoCreator.ts @@ -22,7 +22,7 @@ import Geo, { geo2DDimensions } from './Geo'; import * as layout from '../../util/layout'; import * as numberUtil from '../../util/number'; import geoSourceManager from './geoSourceManager'; -import GeoModel, { GeoCommonOptionMixin, GeoOption, RegoinOption } from './GeoModel'; +import GeoModel, { GeoCommonOptionMixin, GeoOption, RegionOption } from './GeoModel'; import MapSeries, { MapSeriesOption } from '../../chart/map/MapSeries'; import ExtensionAPI from '../../core/ExtensionAPI'; import { CoordinateSystemCreator } from '../CoordinateSystem'; @@ -34,6 +34,7 @@ import type GlobalModel from '../../model/Global'; import type SeriesModel from '../../model/Series'; import type ComponentModel from '../../model/Component'; import * as vector from 'zrender/src/core/vector'; +import type { GeoJSONRegion } from './Region'; export type resizeGeoType = typeof resizeGeo; @@ -254,11 +255,11 @@ class GeoCreator implements CoordinateSystemCreator { * Fill given regions array */ getFilledRegions( - originRegionArr: RegoinOption[], + originRegionArr: RegionOption[], mapName: string, nameMap: NameMap, nameProperty: string - ): RegoinOption[] { + ): RegionOption[] { // Not use the original const regionsArr = (originRegionArr || []).slice(); @@ -270,7 +271,16 @@ class GeoCreator implements CoordinateSystemCreator { const source = geoSourceManager.load(mapName, nameMap, nameProperty); zrUtil.each(source.regions, function (region) { const name = region.name; - !dataNameMap.get(name) && regionsArr.push({name: name}); + if (!dataNameMap.get(name)) { + const regionOption = { + name: name + }; + // apply specified echarts style in GeoJSON data + const specifiedGeoJSONRegionStyle = (region as GeoJSONRegion).properties + && (region as GeoJSONRegion).properties.echartsStyle; + specifiedGeoJSONRegionStyle && zrUtil.merge(regionOption, specifiedGeoJSONRegionStyle); + regionsArr.push(regionOption); + } }); return regionsArr; diff --git a/src/data/SeriesData.ts b/src/data/SeriesData.ts index 456ddeceb6..bc48a9a4d6 100644 --- a/src/data/SeriesData.ts +++ b/src/data/SeriesData.ts @@ -583,7 +583,7 @@ class SeriesData< * Each item is exactly corresponding to a dimension. */ appendValues(values: any[][], names?: string[]): void { - const {start, end} = this._store.appendValues(values, names.length); + const {start, end} = this._store.appendValues(values, names && names.length); const shouldMakeIdFromName = this._shouldMakeIdFromName(); this._updateOrdinalMeta(); diff --git a/test/geo-map.html b/test/geo-map.html index 5c7da0ecc2..ad79a496c2 100644 --- a/test/geo-map.html +++ b/test/geo-map.html @@ -685,6 +685,12 @@ } } }; + features[26].properties.echartsStyle = { + selected: true, + label: { + formatter: 'Default Selected' + } + } echarts.registerMap('usa', usaGeoJSON, { Alaska: { // 把阿拉斯加移到美国主大陆左下方 diff --git a/test/map-nested.html b/test/map-nested.html index 388d842bdc..31295ed5e6 100644 --- a/test/map-nested.html +++ b/test/map-nested.html @@ -66,6 +66,38 @@ ], function (ec, geoJSON) { echarts = ec; + geoJSON.features[0].properties.echartsStyle = { + itemStyle: { + areaColor: 'green' + } + } + + geoJSON.features[1].properties.echartsStyle = { + selected: true, + label: { + formatter: 'Default Selected:\n{b}' + } + } + + geoJSON.features[2].properties.echartsStyle = { + itemStyle: { + borderType: 'dotted', + borderColor: 'blue' + } + } + + geoJSON.features[11].properties.echartsStyle = { + itemStyle: { + // This region will be overridden as `cyan` by the data item option + areaColor: 'black' + }, + tooltip: { + formatter: function (params) { + return 'This is a custom tooltip from GeoJSON: ' + params.name; + } + } + } + echarts.registerMap('nestedMap', geoJSON); var option = { @@ -102,8 +134,8 @@ }, data:[ {name: 'Praha', value: 123}, - {name: 'Plzeňský kraj', value: 321}, - {name: 'Středočeský kraj', value: 521} + {name: 'Plzeňský kraj', value: 321, itemStyle: {areaColor: 'cyan'}}, + {name: 'Středočeský kraj', value: 521}, ] } ] @@ -115,4 +147,4 @@ - \ No newline at end of file +