UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

509 lines (508 loc) 19.2 kB
import { createHashMap, each, extend } from "../../../../zrender/lib/core/util.mjs"; import RoamController from "./RoamController.mjs"; import { updateViewOnPan, updateViewOnZoom } from "./roamHelper.mjs"; import { onIrrelevantElement } from "./cursorHelper.mjs"; import { setTooltipConfig } from "../../util/graphic.mjs"; import { setDefaultStateProxy, toggleHoverEmphasis, enableComponentHighDownFeatures } from "../../util/states.mjs"; import geoSourceManager from "../../coord/geo/geoSourceManager.mjs"; import { getUID } from "../../util/component.mjs"; import { setLabelStyle, getLabelStatesModels } from "../../label/labelStyle.mjs"; import { getECData } from "../../util/innerStore.mjs"; import { createOrUpdatePatternFromDecal } from "../../util/decal.mjs"; import Displayable from "../../../../zrender/lib/graphic/Displayable.mjs"; import { makeInner } from "../../util/model.mjs"; import Group from "../../../../zrender/lib/graphic/Group.mjs"; import { updateProps } from "../../animation/basicTransition.mjs"; import Polygon from "../../../../zrender/lib/graphic/shape/Polygon.mjs"; import Polyline from "../../../../zrender/lib/graphic/shape/Polyline.mjs"; import CompoundPath from "../../../../zrender/lib/graphic/CompoundPath.mjs"; var OPTION_STYLE_ENABLED_TAGS = ["rect", "circle", "line", "ellipse", "polygon", "polyline", "path"]; var OPTION_STYLE_ENABLED_TAG_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS); var STATE_TRIGGER_TAG_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(["g"])); var LABEL_HOST_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(["g"])); var mapLabelRaw = makeInner(); function getFixedItemStyle(model) { var itemStyle = model.getItemStyle(); var areaColor = model.get("areaColor"); if (areaColor != null) { itemStyle.fill = areaColor; } return itemStyle; } function fixLineStyle(styleHost) { var style = styleHost.style; if (style) { style.stroke = style.stroke || style.fill; style.fill = null; } } var MapDraw = function() { function MapDraw2(api) { var group = new 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 Group()); group.add(this._svgGroup = new Group()); } MapDraw2.prototype.draw = function(mapOrGeoModel, ecModel, api, fromView, payload) { var isGeo = mapOrGeoModel.mainType === "geo"; 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; 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 { updateProps(group, transformInfoRoam, mapOrGeoModel); } var isVisualEncodedByVisualMap = data && data.getVisual("visualMeta") && data.getVisual("visualMeta").length > 0; var viewBuildCtx = { api, geo, mapOrGeoModel, data, isVisualEncodedByVisualMap, isGeo, 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); }; MapDraw2.prototype._buildGeoJSON = function(viewBuildCtx) { var regionsGroupByName = this._regionsGroupByName = createHashMap(); var regionsInfoByName = 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) { point = project(point); } return point && [point[0] * transformInfoRaw.scaleX + transformInfoRaw.x, point[1] * transformInfoRaw.scaleY + transformInfoRaw.y]; } function transformPolygonPoints(inPoints) { var outPoints = []; 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(); each(viewBuildCtx.geo.regions, function(region) { var regionName = region.name; var regionGroup = regionsGroupByName.get(regionName); var _a = regionsInfoByName.get(regionName) || {}, dataIdx = _a.dataIdx, regionModel = _a.regionModel; if (!regionGroup) { regionGroup = regionsGroupByName.set(regionName, new 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, regionModel }); } var polygonSubpaths = []; var polylineSubpaths = []; each(region.geometries, function(geometry) { if (geometry.type === "polygon") { var polys = [geometry.exterior].concat(geometry.interiors || []); if (projectionStream) { polys = projectPolys(polys, projectionStream); } each(polys, function(poly) { polygonSubpaths.push(new Polygon(getPolyShape(poly))); }); } else { var points = geometry.points; if (projectionStream) { points = projectPolys(points, projectionStream, true); } each(points, function(points2) { polylineSubpaths.push(new Polyline(getPolyShape(points2))); }); } }); var centerPt = transformPoint(region.getCenter(), projection && projection.project); function createCompoundPath(subpaths, isLine) { if (!subpaths.length) { return; } var compoundPath = new 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); each(compoundPath.states, fixLineStyle); } } createCompoundPath(polygonSubpaths); createCompoundPath(polylineSubpaths, true); }); 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); }; MapDraw2.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 = createHashMap(); var focusSelf = false; each(this._svgGraphicRecord.named, function(namedItem) { 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; } el.z2EmphasisLift = 0; if (!namedItem.namedFrom) { 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); }; MapDraw2.prototype._enableBlurEntireSVG = function(focusSelf, viewBuildCtx) { if (focusSelf && viewBuildCtx.isGeo) { var blurStyle = viewBuildCtx.mapOrGeoModel.getModel(["blur", "itemStyle"]).getItemStyle(); var opacity_1 = blurStyle.opacity; this._svgGraphicRecord.root.traverse(function(el) { if (!el.isGroup) { setDefaultStateProxy(el); var style = el.ensureState("blur").style || {}; if (style.opacity == null && opacity_1 != null) { style.opacity = opacity_1; } el.ensureState("emphasis"); } }); } }; MapDraw2.prototype.remove = function() { this._regionsGroup.removeAll(); this._regionsGroupByName = null; this._svgGroup.removeAll(); this._freeSVG(); this._controller.dispose(); this._controllerHost = null; }; MapDraw2.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) || []; } }; MapDraw2.prototype._svgResourceChanged = function(mapName) { return this._svgMapName !== mapName; }; MapDraw2.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; } }; MapDraw2.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; }; MapDraw2.prototype._updateController = function(mapOrGeoModel, ecModel, api) { var geo = mapOrGeoModel.coordinateSystem; var controller = this._controller; var controllerHost = this._controllerHost; controllerHost.zoomLimit = mapOrGeoModel.get("scaleLimit"); controllerHost.zoom = geo.getZoom(); 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; updateViewOnPan(controllerHost, e.dx, e.dy); api.dispatchAction(extend(makeActionBase(), { dx: e.dx, dy: e.dy, animation: { duration: 0 } })); }, this); controller.off("zoom").on("zoom", function(e) { this._mouseDownFlag = false; updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY); api.dispatchAction(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); }); }; MapDraw2.prototype.resetForLabelLayout = function() { this.group.traverse(function(el) { var label = el.getTextContent(); if (label) { label.ignore = mapLabelRaw(label).ignore; } }); }; MapDraw2.prototype._updateMapSelectHandler = function(mapOrGeoModel, regionsGroup, api, fromView) { var mapDraw = this; regionsGroup.off("mousedown"); regionsGroup.off("click"); if (mapOrGeoModel.get("selectedMode")) { regionsGroup.on("mousedown", function() { mapDraw._mouseDownFlag = true; }); regionsGroup.on("click", function(e) { if (!mapDraw._mouseDownFlag) { return; } mapDraw._mouseDownFlag = false; }); } }; return MapDraw2; }(); function applyOptionStyleForRegion(viewBuildCtx, el, dataIndex, regionModel) { var normalStyleModel = regionModel.getModel("itemStyle"); var emphasisStyleModel = regionModel.getModel(["emphasis", "itemStyle"]); var blurStyleModel = regionModel.getModel(["blur", "itemStyle"]); var selectStyleModel = regionModel.getModel(["select", "itemStyle"]); var normalStyle = getFixedItemStyle(normalStyleModel); var emphasisStyle = getFixedItemStyle(emphasisStyleModel); var selectStyle = getFixedItemStyle(selectStyleModel); var blurStyle = getFixedItemStyle(blurStyleModel); var data = viewBuildCtx.data; if (data) { 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); } } el.setStyle(normalStyle); el.style.strokeNoScale = true; el.ensureState("emphasis").style = emphasisStyle; el.ensureState("select").style = selectStyle; el.ensureState("blur").style = blurStyle; setDefaultStateProxy(el); } function resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx, 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); if (isGeo || isDataNaN || itemLayout && itemLayout.showLabel) { var query = !isGeo ? dataIdx : regionName; var labelFetcher = void 0; if (!data || dataIdx >= 0) { labelFetcher = mapOrGeoModel; } var specifiedTextOpt = labelXY ? { normal: { align: "center", verticalAlign: "middle" } } : null; setLabelStyle(el, getLabelStatesModels(regionModel), { labelFetcher, labelDataIndex: query, defaultText: regionName }, specifiedTextOpt); var textEl = el.getTextContent(); if (textEl) { mapLabelRaw(textEl).ignore = textEl.ignore; if (el.textConfig && labelXY) { var rect = el.getBoundingRect().clone(); el.textConfig.layoutRect = rect; el.textConfig.position = [(labelXY[0] - rect.x) / rect.width * 100 + "%", (labelXY[1] - rect.y) / rect.height * 100 + "%"]; } } el.disableLabelAnimation = true; } else { el.removeTextContent(); el.removeTextConfig(); el.disableLabelAnimation = null; } } function resetEventTriggerForRegion(viewBuildCtx, eventTrigger, regionName, regionModel, mapOrGeoModel, dataIdx) { if (viewBuildCtx.data) { viewBuildCtx.data.setItemGraphicEl(dataIdx, eventTrigger); } else { 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) { setTooltipConfig({ el, componentModel: mapOrGeoModel, itemName: regionName, itemTooltipOption: regionModel.get("tooltip") }); } } function resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) { el.highDownSilentOnTouch = !!mapOrGeoModel.get("selectedMode"); 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, 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) { if (isFinite(x) && isFinite(y)) { curPoly.push([x, y]); } }, sphere: function() { } }); !isLine && stream.polygonStart(); 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; } var MapDraw$1 = MapDraw; export { MapDraw$1 as default };