cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
509 lines (508 loc) • 19.2 kB
JavaScript
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 };