123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- /**
- * AUTO-GENERATED FILE. DO NOT MODIFY.
- */
- /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- import * as zrUtil from 'zrender/lib/core/util.js';
- import RoamController from './RoamController.js';
- import * as roamHelper from '../../component/helper/roamHelper.js';
- import { onIrrelevantElement } from '../../component/helper/cursorHelper.js';
- import * as graphic from '../../util/graphic.js';
- import { toggleHoverEmphasis, enableComponentHighDownFeatures, setDefaultStateProxy } from '../../util/states.js';
- import geoSourceManager from '../../coord/geo/geoSourceManager.js';
- import { getUID } from '../../util/component.js';
- import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle.js';
- import { getECData } from '../../util/innerStore.js';
- import { createOrUpdatePatternFromDecal } from '../../util/decal.js';
- import Displayable from 'zrender/lib/graphic/Displayable.js';
- import { makeInner } from '../../util/model.js';
- /**
- * Only these tags enable use `itemStyle` if they are named in SVG.
- * Other tags like <text> <tspan> <image> might not suitable for `itemStyle`.
- * They will not be considered to be styled until some requirements come.
- */
- var OPTION_STYLE_ENABLED_TAGS = ['rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path'];
- var OPTION_STYLE_ENABLED_TAG_MAP = zrUtil.createHashMap(OPTION_STYLE_ENABLED_TAGS);
- var STATE_TRIGGER_TAG_MAP = zrUtil.createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g']));
- var LABEL_HOST_MAP = zrUtil.createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g']));
- var mapLabelRaw = makeInner();
- function getFixedItemStyle(model) {
- var itemStyle = model.getItemStyle();
- var areaColor = model.get('areaColor'); // If user want the color not to be changed when hover,
- // they should both set areaColor and color to be null.
- if (areaColor != null) {
- itemStyle.fill = areaColor;
- }
- return itemStyle;
- } // Only stroke can be used for line.
- // Using fill in style if stroke not exits.
- // TODO Not sure yet. Perhaps a separate `lineStyle`?
- function fixLineStyle(styleHost) {
- var style = styleHost.style;
- if (style) {
- style.stroke = style.stroke || style.fill;
- style.fill = null;
- }
- }
- var MapDraw =
- /** @class */
- function () {
- function MapDraw(api) {
- var group = new graphic.Group();
- this.uid = getUID('ec_map_draw');
- this._controller = new RoamController(api.getZr());
- this._controllerHost = {
- target: group
- };
- this.group = group;
- group.add(this._regionsGroup = new graphic.Group());
- group.add(this._svgGroup = new graphic.Group());
- }
- MapDraw.prototype.draw = function (mapOrGeoModel, ecModel, api, fromView, payload) {
- var isGeo = mapOrGeoModel.mainType === 'geo'; // Map series has data. GEO model that controlled by map series
- // will be assigned with map data. Other GEO model has no data.
- var data = mapOrGeoModel.getData && mapOrGeoModel.getData();
- isGeo && ecModel.eachComponent({
- mainType: 'series',
- subType: 'map'
- }, function (mapSeries) {
- if (!data && mapSeries.getHostGeoModel() === mapOrGeoModel) {
- data = mapSeries.getData();
- }
- });
- var geo = mapOrGeoModel.coordinateSystem;
- var regionsGroup = this._regionsGroup;
- var group = this.group;
- var transformInfo = geo.getTransformInfo();
- var transformInfoRaw = transformInfo.raw;
- var transformInfoRoam = transformInfo.roam; // No animation when first draw or in action
- var isFirstDraw = !regionsGroup.childAt(0) || payload;
- if (isFirstDraw) {
- group.x = transformInfoRoam.x;
- group.y = transformInfoRoam.y;
- group.scaleX = transformInfoRoam.scaleX;
- group.scaleY = transformInfoRoam.scaleY;
- group.dirty();
- } else {
- graphic.updateProps(group, transformInfoRoam, mapOrGeoModel);
- }
- var isVisualEncodedByVisualMap = data && data.getVisual('visualMeta') && data.getVisual('visualMeta').length > 0;
- var viewBuildCtx = {
- api: api,
- geo: geo,
- mapOrGeoModel: mapOrGeoModel,
- data: data,
- isVisualEncodedByVisualMap: isVisualEncodedByVisualMap,
- isGeo: isGeo,
- transformInfoRaw: transformInfoRaw
- };
- if (geo.resourceType === 'geoJSON') {
- this._buildGeoJSON(viewBuildCtx);
- } else if (geo.resourceType === 'geoSVG') {
- this._buildSVG(viewBuildCtx);
- }
- this._updateController(mapOrGeoModel, ecModel, api);
- this._updateMapSelectHandler(mapOrGeoModel, regionsGroup, api, fromView);
- };
- MapDraw.prototype._buildGeoJSON = function (viewBuildCtx) {
- var regionsGroupByName = this._regionsGroupByName = zrUtil.createHashMap();
- var regionsInfoByName = zrUtil.createHashMap();
- var regionsGroup = this._regionsGroup;
- var transformInfoRaw = viewBuildCtx.transformInfoRaw;
- var mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
- var data = viewBuildCtx.data;
- var projection = viewBuildCtx.geo.projection;
- var projectionStream = projection && projection.stream;
- function transformPoint(point, project) {
- if (project) {
- // projection may return null point.
- point = project(point);
- }
- return point && [point[0] * transformInfoRaw.scaleX + transformInfoRaw.x, point[1] * transformInfoRaw.scaleY + transformInfoRaw.y];
- }
- ;
- function transformPolygonPoints(inPoints) {
- var outPoints = []; // If projectionStream is provided. Use it instead of single point project.
- var project = !projectionStream && projection && projection.project;
- for (var i = 0; i < inPoints.length; ++i) {
- var newPt = transformPoint(inPoints[i], project);
- newPt && outPoints.push(newPt);
- }
- return outPoints;
- }
- function getPolyShape(points) {
- return {
- shape: {
- points: transformPolygonPoints(points)
- }
- };
- }
- regionsGroup.removeAll(); // Only when the resource is GeoJSON, there is `geo.regions`.
- zrUtil.each(viewBuildCtx.geo.regions, function (region) {
- var regionName = region.name; // Consider in GeoJson properties.name may be duplicated, for example,
- // there is multiple region named "United Kindom" or "France" (so many
- // colonies). And it is not appropriate to merge them in geo, which
- // will make them share the same label and bring trouble in label
- // location calculation.
- var regionGroup = regionsGroupByName.get(regionName);
- var _a = regionsInfoByName.get(regionName) || {},
- dataIdx = _a.dataIdx,
- regionModel = _a.regionModel;
- if (!regionGroup) {
- regionGroup = regionsGroupByName.set(regionName, new graphic.Group());
- regionsGroup.add(regionGroup);
- dataIdx = data ? data.indexOfName(regionName) : null;
- regionModel = viewBuildCtx.isGeo ? mapOrGeoModel.getRegionModel(regionName) : data ? data.getItemModel(dataIdx) : null;
- regionsInfoByName.set(regionName, {
- dataIdx: dataIdx,
- regionModel: regionModel
- });
- }
- var polygonSubpaths = [];
- var polylineSubpaths = [];
- zrUtil.each(region.geometries, function (geometry) {
- // Polygon and MultiPolygon
- if (geometry.type === 'polygon') {
- var polys = [geometry.exterior].concat(geometry.interiors || []);
- if (projectionStream) {
- polys = projectPolys(polys, projectionStream);
- }
- zrUtil.each(polys, function (poly) {
- polygonSubpaths.push(new graphic.Polygon(getPolyShape(poly)));
- });
- } // LineString and MultiLineString
- else {
- var points = geometry.points;
- if (projectionStream) {
- points = projectPolys(points, projectionStream, true);
- }
- zrUtil.each(points, function (points) {
- polylineSubpaths.push(new graphic.Polyline(getPolyShape(points)));
- });
- }
- });
- var centerPt = transformPoint(region.getCenter(), projection && projection.project);
- function createCompoundPath(subpaths, isLine) {
- if (!subpaths.length) {
- return;
- }
- var compoundPath = new graphic.CompoundPath({
- culling: true,
- segmentIgnoreThreshold: 1,
- shape: {
- paths: subpaths
- }
- });
- regionGroup.add(compoundPath);
- applyOptionStyleForRegion(viewBuildCtx, compoundPath, dataIdx, regionModel);
- resetLabelForRegion(viewBuildCtx, compoundPath, regionName, regionModel, mapOrGeoModel, dataIdx, centerPt);
- if (isLine) {
- fixLineStyle(compoundPath);
- zrUtil.each(compoundPath.states, fixLineStyle);
- }
- }
- createCompoundPath(polygonSubpaths);
- createCompoundPath(polylineSubpaths, true);
- }); // Ensure children have been added to `regionGroup` before calling them.
- regionsGroupByName.each(function (regionGroup, regionName) {
- var _a = regionsInfoByName.get(regionName),
- dataIdx = _a.dataIdx,
- regionModel = _a.regionModel;
- resetEventTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel, dataIdx);
- resetTooltipForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
- resetStateTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
- }, this);
- };
- MapDraw.prototype._buildSVG = function (viewBuildCtx) {
- var mapName = viewBuildCtx.geo.map;
- var transformInfoRaw = viewBuildCtx.transformInfoRaw;
- this._svgGroup.x = transformInfoRaw.x;
- this._svgGroup.y = transformInfoRaw.y;
- this._svgGroup.scaleX = transformInfoRaw.scaleX;
- this._svgGroup.scaleY = transformInfoRaw.scaleY;
- if (this._svgResourceChanged(mapName)) {
- this._freeSVG();
- this._useSVG(mapName);
- }
- var svgDispatcherMap = this._svgDispatcherMap = zrUtil.createHashMap();
- var focusSelf = false;
- zrUtil.each(this._svgGraphicRecord.named, function (namedItem) {
- // Note that we also allow different elements have the same name.
- // For example, a glyph of a city and the label of the city have
- // the same name and their tooltip info can be defined in a single
- // region option.
- var regionName = namedItem.name;
- var mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
- var data = viewBuildCtx.data;
- var svgNodeTagLower = namedItem.svgNodeTagLower;
- var el = namedItem.el;
- var dataIdx = data ? data.indexOfName(regionName) : null;
- var regionModel = mapOrGeoModel.getRegionModel(regionName);
- if (OPTION_STYLE_ENABLED_TAG_MAP.get(svgNodeTagLower) != null && el instanceof Displayable) {
- applyOptionStyleForRegion(viewBuildCtx, el, dataIdx, regionModel);
- }
- if (el instanceof Displayable) {
- el.culling = true;
- } // We do not know how the SVG like so we'd better not to change z2.
- // Otherwise it might bring some unexpected result. For example,
- // an area hovered that make some inner city can not be clicked.
- el.z2EmphasisLift = 0; // If self named:
- if (!namedItem.namedFrom) {
- // label should batter to be displayed based on the center of <g>
- // if it is named rather than displayed on each child.
- if (LABEL_HOST_MAP.get(svgNodeTagLower) != null) {
- resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx, null);
- }
- resetEventTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx);
- resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);
- if (STATE_TRIGGER_TAG_MAP.get(svgNodeTagLower) != null) {
- var focus_1 = resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);
- if (focus_1 === 'self') {
- focusSelf = true;
- }
- var els = svgDispatcherMap.get(regionName) || svgDispatcherMap.set(regionName, []);
- els.push(el);
- }
- }
- }, this);
- this._enableBlurEntireSVG(focusSelf, viewBuildCtx);
- };
- MapDraw.prototype._enableBlurEntireSVG = function (focusSelf, viewBuildCtx) {
- // It's a little complicated to support blurring the entire geoSVG in series-map.
- // So do not support it until some requirements come.
- // At present, in series-map, only regions can be blurred.
- if (focusSelf && viewBuildCtx.isGeo) {
- var blurStyle = viewBuildCtx.mapOrGeoModel.getModel(['blur', 'itemStyle']).getItemStyle(); // Only support `opacity` here. Because not sure that other props are suitable for
- // all of the elements generated by SVG (especially for Text/TSpan/Image/... ).
- var opacity_1 = blurStyle.opacity;
- this._svgGraphicRecord.root.traverse(function (el) {
- if (!el.isGroup) {
- // PENDING: clear those settings to SVG elements when `_freeSVG`.
- // (Currently it happen not to be needed.)
- setDefaultStateProxy(el);
- var style = el.ensureState('blur').style || {}; // Do not overwrite the region style that already set from region option.
- if (style.opacity == null && opacity_1 != null) {
- style.opacity = opacity_1;
- } // If `ensureState('blur').style = {}`, there will be default opacity.
- // Enable `stateTransition` (animation).
- el.ensureState('emphasis');
- }
- });
- }
- };
- MapDraw.prototype.remove = function () {
- this._regionsGroup.removeAll();
- this._regionsGroupByName = null;
- this._svgGroup.removeAll();
- this._freeSVG();
- this._controller.dispose();
- this._controllerHost = null;
- };
- MapDraw.prototype.findHighDownDispatchers = function (name, geoModel) {
- if (name == null) {
- return [];
- }
- var geo = geoModel.coordinateSystem;
- if (geo.resourceType === 'geoJSON') {
- var regionsGroupByName = this._regionsGroupByName;
- if (regionsGroupByName) {
- var regionGroup = regionsGroupByName.get(name);
- return regionGroup ? [regionGroup] : [];
- }
- } else if (geo.resourceType === 'geoSVG') {
- return this._svgDispatcherMap && this._svgDispatcherMap.get(name) || [];
- }
- };
- MapDraw.prototype._svgResourceChanged = function (mapName) {
- return this._svgMapName !== mapName;
- };
- MapDraw.prototype._useSVG = function (mapName) {
- var resource = geoSourceManager.getGeoResource(mapName);
- if (resource && resource.type === 'geoSVG') {
- var svgGraphic = resource.useGraphic(this.uid);
- this._svgGroup.add(svgGraphic.root);
- this._svgGraphicRecord = svgGraphic;
- this._svgMapName = mapName;
- }
- };
- MapDraw.prototype._freeSVG = function () {
- var mapName = this._svgMapName;
- if (mapName == null) {
- return;
- }
- var resource = geoSourceManager.getGeoResource(mapName);
- if (resource && resource.type === 'geoSVG') {
- resource.freeGraphic(this.uid);
- }
- this._svgGraphicRecord = null;
- this._svgDispatcherMap = null;
- this._svgGroup.removeAll();
- this._svgMapName = null;
- };
- MapDraw.prototype._updateController = function (mapOrGeoModel, ecModel, api) {
- var geo = mapOrGeoModel.coordinateSystem;
- var controller = this._controller;
- var controllerHost = this._controllerHost; // @ts-ignore FIXME:TS
- controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit');
- controllerHost.zoom = geo.getZoom(); // roamType is will be set default true if it is null
- // @ts-ignore FIXME:TS
- controller.enable(mapOrGeoModel.get('roam') || false);
- var mainType = mapOrGeoModel.mainType;
- function makeActionBase() {
- var action = {
- type: 'geoRoam',
- componentType: mainType
- };
- action[mainType + 'Id'] = mapOrGeoModel.id;
- return action;
- }
- controller.off('pan').on('pan', function (e) {
- this._mouseDownFlag = false;
- roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
- api.dispatchAction(zrUtil.extend(makeActionBase(), {
- dx: e.dx,
- dy: e.dy,
- animation: {
- duration: 0
- }
- }));
- }, this);
- controller.off('zoom').on('zoom', function (e) {
- this._mouseDownFlag = false;
- roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
- api.dispatchAction(zrUtil.extend(makeActionBase(), {
- zoom: e.scale,
- originX: e.originX,
- originY: e.originY,
- animation: {
- duration: 0
- }
- }));
- }, this);
- controller.setPointerChecker(function (e, x, y) {
- return geo.containPoint([x, y]) && !onIrrelevantElement(e, api, mapOrGeoModel);
- });
- };
- /**
- * FIXME: this is a temporarily workaround.
- * When `geoRoam` the elements need to be reset in `MapView['render']`, because the props like
- * `ignore` might have been modified by `LabelManager`, and `LabelManager#addLabelsOfSeries`
- * will subsequently cache `defaultAttr` like `ignore`. If do not do this reset, the modified
- * props will have no chance to be restored.
- * Note: This reset should be after `clearStates` in `renderSeries` because `useStates` in
- * `renderSeries` will cache the modified `ignore` to `el._normalState`.
- * TODO:
- * Use clone/immutable in `LabelManager`?
- */
- MapDraw.prototype.resetForLabelLayout = function () {
- this.group.traverse(function (el) {
- var label = el.getTextContent();
- if (label) {
- label.ignore = mapLabelRaw(label).ignore;
- }
- });
- };
- MapDraw.prototype._updateMapSelectHandler = function (mapOrGeoModel, regionsGroup, api, fromView) {
- var mapDraw = this;
- regionsGroup.off('mousedown');
- regionsGroup.off('click'); // @ts-ignore FIXME:TS resolve type conflict
- if (mapOrGeoModel.get('selectedMode')) {
- regionsGroup.on('mousedown', function () {
- mapDraw._mouseDownFlag = true;
- });
- regionsGroup.on('click', function (e) {
- if (!mapDraw._mouseDownFlag) {
- return;
- }
- mapDraw._mouseDownFlag = false;
- });
- }
- };
- return MapDraw;
- }();
- ;
- function applyOptionStyleForRegion(viewBuildCtx, el, dataIndex, regionModel) {
- // All of the path are using `itemStyle`, because
- // (1) Some SVG also use fill on polyline (The different between
- // polyline and polygon is "open" or "close" but not fill or not).
- // (2) For the common props like opacity, if some use itemStyle
- // and some use `lineStyle`, it might confuse users.
- // (3) Most SVG use <path>, where can not detect whether to draw a "line"
- // or a filled shape, so use `itemStyle` for <path>.
- var normalStyleModel = regionModel.getModel('itemStyle');
- var emphasisStyleModel = regionModel.getModel(['emphasis', 'itemStyle']);
- var blurStyleModel = regionModel.getModel(['blur', 'itemStyle']);
- var selectStyleModel = regionModel.getModel(['select', 'itemStyle']); // NOTE: DON'T use 'style' in visual when drawing map.
- // This component is used for drawing underlying map for both geo component and map series.
- var normalStyle = getFixedItemStyle(normalStyleModel);
- var emphasisStyle = getFixedItemStyle(emphasisStyleModel);
- var selectStyle = getFixedItemStyle(selectStyleModel);
- var blurStyle = getFixedItemStyle(blurStyleModel); // Update the itemStyle if has data visual
- var data = viewBuildCtx.data;
- if (data) {
- // Only visual color of each item will be used. It can be encoded by visualMap
- // But visual color of series is used in symbol drawing
- // Visual color for each series is for the symbol draw
- var style = data.getItemVisual(dataIndex, 'style');
- var decal = data.getItemVisual(dataIndex, 'decal');
- if (viewBuildCtx.isVisualEncodedByVisualMap && style.fill) {
- normalStyle.fill = style.fill;
- }
- if (decal) {
- normalStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
- }
- } // SVG text, tspan and image can be named but not supporeted
- // to be styled by region option yet.
- el.setStyle(normalStyle);
- el.style.strokeNoScale = true;
- el.ensureState('emphasis').style = emphasisStyle;
- el.ensureState('select').style = selectStyle;
- el.ensureState('blur').style = blurStyle; // Enable blur
- setDefaultStateProxy(el);
- }
- function resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, // Exist only if `viewBuildCtx.data` exists.
- dataIdx, // If labelXY not provided, use `textConfig.position: 'inside'`
- labelXY) {
- var data = viewBuildCtx.data;
- var isGeo = viewBuildCtx.isGeo;
- var isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx));
- var itemLayout = data && data.getItemLayout(dataIdx); // In the following cases label will be drawn
- // 1. In map series and data value is NaN
- // 2. In geo component
- // 3. Region has no series legendIcon, which will be add a showLabel flag in mapSymbolLayout
- if (isGeo || isDataNaN || itemLayout && itemLayout.showLabel) {
- var query = !isGeo ? dataIdx : regionName;
- var labelFetcher = void 0; // Consider dataIdx not found.
- if (!data || dataIdx >= 0) {
- labelFetcher = mapOrGeoModel;
- }
- var specifiedTextOpt = labelXY ? {
- normal: {
- align: 'center',
- verticalAlign: 'middle'
- }
- } : null; // Caveat: must be called after `setDefaultStateProxy(el);` called.
- // because textContent will be assign with `el.stateProxy` inside.
- setLabelStyle(el, getLabelStatesModels(regionModel), {
- labelFetcher: labelFetcher,
- labelDataIndex: query,
- defaultText: regionName
- }, specifiedTextOpt);
- var textEl = el.getTextContent();
- if (textEl) {
- mapLabelRaw(textEl).ignore = textEl.ignore;
- if (el.textConfig && labelXY) {
- // Compute a relative offset based on the el bounding rect.
- var rect = el.getBoundingRect().clone(); // Need to make sure the percent position base on the same rect in normal and
- // emphasis state. Otherwise if using boundingRect of el, but the emphasis state
- // has borderWidth (even 0.5px), the text position will be changed obviously
- // if the position is very big like ['1234%', '1345%'].
- el.textConfig.layoutRect = rect;
- el.textConfig.position = [(labelXY[0] - rect.x) / rect.width * 100 + '%', (labelXY[1] - rect.y) / rect.height * 100 + '%'];
- }
- } // PENDING:
- // If labelLayout is enabled (test/label-layout.html), el.dataIndex should be specified.
- // But el.dataIndex is also used to determine whether user event should be triggered,
- // where el.seriesIndex or el.dataModel must be specified. At present for a single el
- // there is not case that "only label layout enabled but user event disabled", so here
- // we depends `resetEventTriggerForRegion` to do the job of setting `el.dataIndex`.
- el.disableLabelAnimation = true;
- } else {
- el.removeTextContent();
- el.removeTextConfig();
- el.disableLabelAnimation = null;
- }
- }
- function resetEventTriggerForRegion(viewBuildCtx, eventTrigger, regionName, regionModel, mapOrGeoModel, // Exist only if `viewBuildCtx.data` exists.
- dataIdx) {
- // setItemGraphicEl, setHoverStyle after all polygons and labels
- // are added to the regionGroup
- if (viewBuildCtx.data) {
- // FIXME: when series-map use a SVG map, and there are duplicated name specified
- // on different SVG elements, after `data.setItemGraphicEl(...)`:
- // (1) all of them will be mounted with `dataIndex`, `seriesIndex`, so that tooltip
- // can be triggered only mouse hover. That's correct.
- // (2) only the last element will be kept in `data`, so that if trigger tooltip
- // by `dispatchAction`, only the last one can be found and triggered. That might be
- // not correct. We will fix it in future if anyone demanding that.
- viewBuildCtx.data.setItemGraphicEl(dataIdx, eventTrigger);
- } // series-map will not trigger "geoselectchange" no matter it is
- // based on a declared geo component. Because series-map will
- // trigger "selectchange". If it trigger both the two events,
- // If users call `chart.dispatchAction({type: 'toggleSelect'})`,
- // it not easy to also fire event "geoselectchanged".
- else {
- // Package custom mouse event for geo component
- getECData(eventTrigger).eventData = {
- componentType: 'geo',
- componentIndex: mapOrGeoModel.componentIndex,
- geoIndex: mapOrGeoModel.componentIndex,
- name: regionName,
- region: regionModel && regionModel.option || {}
- };
- }
- }
- function resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) {
- if (!viewBuildCtx.data) {
- graphic.setTooltipConfig({
- el: el,
- componentModel: mapOrGeoModel,
- itemName: regionName,
- // @ts-ignore FIXME:TS fix the "compatible with each other"?
- itemTooltipOption: regionModel.get('tooltip')
- });
- }
- }
- function resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) {
- // @ts-ignore FIXME:TS fix the "compatible with each other"?
- el.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode'); // @ts-ignore FIXME:TS fix the "compatible with each other"?
- var emphasisModel = regionModel.getModel('emphasis');
- var focus = emphasisModel.get('focus');
- toggleHoverEmphasis(el, focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
- if (viewBuildCtx.isGeo) {
- enableComponentHighDownFeatures(el, mapOrGeoModel, regionName);
- }
- return focus;
- }
- function projectPolys(rings, // Polygons include exterior and interiors. Or polylines.
- createStream, isLine) {
- var polygons = [];
- var curPoly;
- function startPolygon() {
- curPoly = [];
- }
- function endPolygon() {
- if (curPoly.length) {
- polygons.push(curPoly);
- curPoly = [];
- }
- }
- var stream = createStream({
- polygonStart: startPolygon,
- polygonEnd: endPolygon,
- lineStart: startPolygon,
- lineEnd: endPolygon,
- point: function (x, y) {
- // May have NaN values from stream.
- if (isFinite(x) && isFinite(y)) {
- curPoly.push([x, y]);
- }
- },
- sphere: function () {}
- });
- !isLine && stream.polygonStart();
- zrUtil.each(rings, function (ring) {
- stream.lineStart();
- for (var i = 0; i < ring.length; i++) {
- stream.point(ring[i][0], ring[i][1]);
- }
- stream.lineEnd();
- });
- !isLine && stream.polygonEnd();
- return polygons;
- }
- export default MapDraw; // @ts-ignore FIXME:TS fix the "compatible with each other"?
|