| 
/* 
 | 
* 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; 
 | 
        var silent = regionModel.get('silent', true); 
 | 
        silent != null && (regionGroup.silent = silent); 
 | 
        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; 
 | 
      } 
 | 
      var silent = regionModel.get('silent', true); 
 | 
      silent != null && (el.silent = silent); 
 | 
      // 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(), { 
 | 
        totalZoom: controllerHost.zoom, 
 | 
        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"? 
 |