Skip to content

Commit

Permalink
Merge pull request #20564 from apache/feat/geo/styling-in-geojson
Browse files Browse the repository at this point in the history
feat(geo): support styling region in original GeoJSON data
  • Loading branch information
plainheart authored Dec 6, 2024
2 parents 5d1d34e + 3ec7b26 commit ab5de8e
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 26 deletions.
23 changes: 17 additions & 6 deletions src/chart/map/MapSeries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<TCbParams = never> {
itemStyle?: GeoItemStyleOption<TCbParams>
Expand Down Expand Up @@ -117,26 +118,36 @@ class MapSeries extends SeriesModel<MapSeriesOption> {
coordDimensions: ['value'],
encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
});
const dataNameMap = zrUtil.createHashMap();
const toAppendNames = [] as string[];
const dataNameIndexMap = zrUtil.createHashMap<number>();
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;
}
Expand Down
8 changes: 2 additions & 6 deletions src/component/helper/MapDraw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -240,7 +240,7 @@ class MapDraw {
const regionsGroupByName = this._regionsGroupByName = zrUtil.createHashMap<RegionsGroup, string>();
const regionsInfoByName = zrUtil.createHashMap<{
dataIdx: number;
regionModel: Model<RegoinOption> | Model<MapDataItemOption>;
regionModel: Model<RegionOption> | Model<MapDataItemOption>;
}, string>();
const regionsGroup = this._regionsGroup;
const transformInfoRaw = viewBuildCtx.transformInfoRaw;
Expand Down Expand Up @@ -302,10 +302,6 @@ class MapDraw {
? mapOrGeoModel.getRegionModel(regionName)
: (data ? data.getItemModel(dataIdx) as Model<MapDataItemOption> : 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 });
}

Expand Down
13 changes: 9 additions & 4 deletions src/coord/geo/GeoModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,17 @@ interface GeoLabelFormatterDataParams {
status: DisplayState;
}

export interface RegoinOption extends GeoStateOption, StatesOptionMixin<GeoStateOption, StatesMixinBase> {
export interface RegionOption extends GeoStateOption, StatesOptionMixin<GeoStateOption, StatesMixinBase> {
name?: string
selected?: boolean
tooltip?: CommonTooltipOption<GeoTooltipFormatterParams>
}

/**
* @deprecated Use `RegionOption` instead.
*/
export interface RegoinOption extends RegionOption {}

export interface GeoTooltipFormatterParams {
componentType: 'geo'
geoIndex: number
Expand Down Expand Up @@ -118,7 +123,7 @@ export interface GeoOption extends
show?: boolean;
silent?: boolean;

regions?: RegoinOption[];
regions?: RegionOption[];

stateAnimation?: AnimationOptionMixin

Expand All @@ -137,7 +142,7 @@ class GeoModel extends ComponentModel<GeoOption> {

static layoutMode = 'box' as const;

private _optionModelMap: zrUtil.HashMap<Model<RegoinOption>>;
private _optionModelMap: zrUtil.HashMap<Model<RegionOption>>;

static defaultOption: GeoOption = {

Expand Down Expand Up @@ -263,7 +268,7 @@ class GeoModel extends ComponentModel<GeoOption> {
/**
* Get model of region.
*/
getRegionModel(name: string): Model<RegoinOption> {
getRegionModel(name: string): Model<RegionOption> {
return this._optionModelMap.get(name) || new Model(null, this, this.ecModel);
}

Expand Down
4 changes: 2 additions & 2 deletions src/coord/geo/Region.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];

Expand Down Expand Up @@ -137,7 +137,7 @@ export class GeoJSONRegion extends Region {

// Injected outside.
properties: GeoJSON['features'][0]['properties'] & {
echartsStyle?: Omit<RegoinOption, 'name' | 'selected'>
echartsStyle?: Omit<RegionOption, 'name'>
};

constructor(
Expand Down
18 changes: 14 additions & 4 deletions src/coord/geo/geoCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;

Expand Down Expand Up @@ -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();

Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/data/SeriesData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions test/geo-map.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 35 additions & 3 deletions test/map-nested.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ab5de8e

Please sign in to comment.