逐步完成前后端服务器

This commit is contained in:
2025-09-09 15:00:30 +08:00
parent fcb09432e9
commit c7dfa1e9fc
2937 changed files with 1477567 additions and 0 deletions

View File

@ -0,0 +1,745 @@
/*
* 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 { __extends } from "tslib";
import { curry, each, map, bind, merge, clone, defaults, assert } from 'zrender/lib/core/util.js';
import Eventful from 'zrender/lib/core/Eventful.js';
import * as graphic from '../../util/graphic.js';
import * as interactionMutex from './interactionMutex.js';
import DataDiffer from '../../data/DataDiffer.js';
var BRUSH_PANEL_GLOBAL = true;
var mathMin = Math.min;
var mathMax = Math.max;
var mathPow = Math.pow;
var COVER_Z = 10000;
var UNSELECT_THRESHOLD = 6;
var MIN_RESIZE_LINE_WIDTH = 6;
var MUTEX_RESOURCE_KEY = 'globalPan';
var DIRECTION_MAP = {
w: [0, 0],
e: [0, 1],
n: [1, 0],
s: [1, 1]
};
var CURSOR_MAP = {
w: 'ew',
e: 'ew',
n: 'ns',
s: 'ns',
ne: 'nesw',
sw: 'nesw',
nw: 'nwse',
se: 'nwse'
};
var DEFAULT_BRUSH_OPT = {
brushStyle: {
lineWidth: 2,
stroke: 'rgba(210,219,238,0.3)',
fill: '#D2DBEE'
},
transformable: true,
brushMode: 'single',
removeOnClick: false
};
var baseUID = 0;
/**
* params:
* areas: Array.<Array>, coord relates to container group,
* If no container specified, to global.
* opt {
* isEnd: boolean,
* removeOnClick: boolean
* }
*/
var BrushController = /** @class */function (_super) {
__extends(BrushController, _super);
function BrushController(zr) {
var _this = _super.call(this) || this;
/**
* @internal
*/
_this._track = [];
/**
* @internal
*/
_this._covers = [];
_this._handlers = {};
if (process.env.NODE_ENV !== 'production') {
assert(zr);
}
_this._zr = zr;
_this.group = new graphic.Group();
_this._uid = 'brushController_' + baseUID++;
each(pointerHandlers, function (handler, eventName) {
this._handlers[eventName] = bind(handler, this);
}, _this);
return _this;
}
/**
* If set to `false`, select disabled.
*/
BrushController.prototype.enableBrush = function (brushOption) {
if (process.env.NODE_ENV !== 'production') {
assert(this._mounted);
}
this._brushType && this._doDisableBrush();
brushOption.brushType && this._doEnableBrush(brushOption);
return this;
};
BrushController.prototype._doEnableBrush = function (brushOption) {
var zr = this._zr;
// Consider roam, which takes globalPan too.
if (!this._enableGlobalPan) {
interactionMutex.take(zr, MUTEX_RESOURCE_KEY, this._uid);
}
each(this._handlers, function (handler, eventName) {
zr.on(eventName, handler);
});
this._brushType = brushOption.brushType;
this._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
};
BrushController.prototype._doDisableBrush = function () {
var zr = this._zr;
interactionMutex.release(zr, MUTEX_RESOURCE_KEY, this._uid);
each(this._handlers, function (handler, eventName) {
zr.off(eventName, handler);
});
this._brushType = this._brushOption = null;
};
/**
* @param panelOpts If not pass, it is global brush.
*/
BrushController.prototype.setPanels = function (panelOpts) {
if (panelOpts && panelOpts.length) {
var panels_1 = this._panels = {};
each(panelOpts, function (panelOpts) {
panels_1[panelOpts.panelId] = clone(panelOpts);
});
} else {
this._panels = null;
}
return this;
};
BrushController.prototype.mount = function (opt) {
opt = opt || {};
if (process.env.NODE_ENV !== 'production') {
this._mounted = true; // should be at first.
}
this._enableGlobalPan = opt.enableGlobalPan;
var thisGroup = this.group;
this._zr.add(thisGroup);
thisGroup.attr({
x: opt.x || 0,
y: opt.y || 0,
rotation: opt.rotation || 0,
scaleX: opt.scaleX || 1,
scaleY: opt.scaleY || 1
});
this._transform = thisGroup.getLocalTransform();
return this;
};
// eachCover(cb, context): void {
// each(this._covers, cb, context);
// }
/**
* Update covers.
* @param coverConfigList
* If coverConfigList is null/undefined, all covers removed.
*/
BrushController.prototype.updateCovers = function (coverConfigList) {
if (process.env.NODE_ENV !== 'production') {
assert(this._mounted);
}
coverConfigList = map(coverConfigList, function (coverConfig) {
return merge(clone(DEFAULT_BRUSH_OPT), coverConfig, true);
});
var tmpIdPrefix = '\0-brush-index-';
var oldCovers = this._covers;
var newCovers = this._covers = [];
var controller = this;
var creatingCover = this._creatingCover;
new DataDiffer(oldCovers, coverConfigList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute();
return this;
function getKey(brushOption, index) {
return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType;
}
function oldGetKey(cover, index) {
return getKey(cover.__brushOption, index);
}
function addOrUpdate(newIndex, oldIndex) {
var newBrushInternal = coverConfigList[newIndex];
// Consider setOption in event listener of brushSelect,
// where updating cover when creating should be forbidden.
if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
newCovers[newIndex] = oldCovers[oldIndex];
} else {
var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushInternal, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushInternal));
updateCoverAfterCreation(controller, cover);
}
}
function remove(oldIndex) {
if (oldCovers[oldIndex] !== creatingCover) {
controller.group.remove(oldCovers[oldIndex]);
}
}
};
BrushController.prototype.unmount = function () {
if (process.env.NODE_ENV !== 'production') {
if (!this._mounted) {
return;
}
}
this.enableBrush(false);
// container may 'removeAll' outside.
clearCovers(this);
this._zr.remove(this.group);
if (process.env.NODE_ENV !== 'production') {
this._mounted = false; // should be at last.
}
return this;
};
BrushController.prototype.dispose = function () {
this.unmount();
this.off();
};
return BrushController;
}(Eventful);
function createCover(controller, brushOption) {
var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
cover.__brushOption = brushOption;
updateZ(cover, brushOption);
controller.group.add(cover);
return cover;
}
function endCreating(controller, creatingCover) {
var coverRenderer = getCoverRenderer(creatingCover);
if (coverRenderer.endCreating) {
coverRenderer.endCreating(controller, creatingCover);
updateZ(creatingCover, creatingCover.__brushOption);
}
return creatingCover;
}
function updateCoverShape(controller, cover) {
var brushOption = cover.__brushOption;
getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
}
function updateZ(cover, brushOption) {
var z = brushOption.z;
z == null && (z = COVER_Z);
cover.traverse(function (el) {
el.z = z;
el.z2 = z; // Consider in given container.
});
}
function updateCoverAfterCreation(controller, cover) {
getCoverRenderer(cover).updateCommon(controller, cover);
updateCoverShape(controller, cover);
}
function getCoverRenderer(cover) {
return coverRenderers[cover.__brushOption.brushType];
}
// return target panel or `true` (means global panel)
function getPanelByPoint(controller, e, localCursorPoint) {
var panels = controller._panels;
if (!panels) {
return BRUSH_PANEL_GLOBAL; // Global panel
}
var panel;
var transform = controller._transform;
each(panels, function (pn) {
pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
});
return panel;
}
// Return a panel or true
function getPanelByCover(controller, cover) {
var panels = controller._panels;
if (!panels) {
return BRUSH_PANEL_GLOBAL; // Global panel
}
var panelId = cover.__brushOption.panelId;
// User may give cover without coord sys info,
// which is then treated as global panel.
return panelId != null ? panels[panelId] : BRUSH_PANEL_GLOBAL;
}
function clearCovers(controller) {
var covers = controller._covers;
var originalLength = covers.length;
each(covers, function (cover) {
controller.group.remove(cover);
}, controller);
covers.length = 0;
return !!originalLength;
}
function trigger(controller, opt) {
var areas = map(controller._covers, function (cover) {
var brushOption = cover.__brushOption;
var range = clone(brushOption.range);
return {
brushType: brushOption.brushType,
panelId: brushOption.panelId,
range: range
};
});
controller.trigger('brush', {
areas: areas,
isEnd: !!opt.isEnd,
removeOnClick: !!opt.removeOnClick
});
}
function shouldShowCover(controller) {
var track = controller._track;
if (!track.length) {
return false;
}
var p2 = track[track.length - 1];
var p1 = track[0];
var dx = p2[0] - p1[0];
var dy = p2[1] - p1[1];
var dist = mathPow(dx * dx + dy * dy, 0.5);
return dist > UNSELECT_THRESHOLD;
}
function getTrackEnds(track) {
var tail = track.length - 1;
tail < 0 && (tail = 0);
return [track[0], track[tail]];
}
;
function createBaseRectCover(rectRangeConverter, controller, brushOption, edgeNameSequences) {
var cover = new graphic.Group();
cover.add(new graphic.Rect({
name: 'main',
style: makeStyle(brushOption),
silent: true,
draggable: true,
cursor: 'move',
drift: curry(driftRect, rectRangeConverter, controller, cover, ['n', 's', 'w', 'e']),
ondragend: curry(trigger, controller, {
isEnd: true
})
}));
each(edgeNameSequences, function (nameSequence) {
cover.add(new graphic.Rect({
name: nameSequence.join(''),
style: {
opacity: 0
},
draggable: true,
silent: true,
invisible: true,
drift: curry(driftRect, rectRangeConverter, controller, cover, nameSequence),
ondragend: curry(trigger, controller, {
isEnd: true
})
}));
});
return cover;
}
function updateBaseRect(controller, cover, localRange, brushOption) {
var lineWidth = brushOption.brushStyle.lineWidth || 0;
var handleSize = mathMax(lineWidth, MIN_RESIZE_LINE_WIDTH);
var x = localRange[0][0];
var y = localRange[1][0];
var xa = x - lineWidth / 2;
var ya = y - lineWidth / 2;
var x2 = localRange[0][1];
var y2 = localRange[1][1];
var x2a = x2 - handleSize + lineWidth / 2;
var y2a = y2 - handleSize + lineWidth / 2;
var width = x2 - x;
var height = y2 - y;
var widtha = width + lineWidth;
var heighta = height + lineWidth;
updateRectShape(controller, cover, 'main', x, y, width, height);
if (brushOption.transformable) {
updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
}
}
function updateCommon(controller, cover) {
var brushOption = cover.__brushOption;
var transformable = brushOption.transformable;
var mainEl = cover.childAt(0);
mainEl.useStyle(makeStyle(brushOption));
mainEl.attr({
silent: !transformable,
cursor: transformable ? 'move' : 'default'
});
each([['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']], function (nameSequence) {
var el = cover.childOfName(nameSequence.join(''));
var globalDir = nameSequence.length === 1 ? getGlobalDirection1(controller, nameSequence[0]) : getGlobalDirection2(controller, nameSequence);
el && el.attr({
silent: !transformable,
invisible: !transformable,
cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
});
});
}
function updateRectShape(controller, cover, name, x, y, w, h) {
var el = cover.childOfName(name);
el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]])));
}
function makeStyle(brushOption) {
return defaults({
strokeNoScale: true
}, brushOption.brushStyle);
}
function formatRectRange(x, y, x2, y2) {
var min = [mathMin(x, x2), mathMin(y, y2)];
var max = [mathMax(x, x2), mathMax(y, y2)];
return [[min[0], max[0]], [min[1], max[1]] // y range
];
}
function getTransform(controller) {
return graphic.getTransform(controller.group);
}
function getGlobalDirection1(controller, localDirName) {
var map = {
w: 'left',
e: 'right',
n: 'top',
s: 'bottom'
};
var inverseMap = {
left: 'w',
right: 'e',
top: 'n',
bottom: 's'
};
var dir = graphic.transformDirection(map[localDirName], getTransform(controller));
return inverseMap[dir];
}
function getGlobalDirection2(controller, localDirNameSeq) {
var globalDir = [getGlobalDirection1(controller, localDirNameSeq[0]), getGlobalDirection1(controller, localDirNameSeq[1])];
(globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
return globalDir.join('');
}
function driftRect(rectRangeConverter, controller, cover, dirNameSequence, dx, dy) {
var brushOption = cover.__brushOption;
var rectRange = rectRangeConverter.toRectRange(brushOption.range);
var localDelta = toLocalDelta(controller, dx, dy);
each(dirNameSequence, function (dirName) {
var ind = DIRECTION_MAP[dirName];
rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
});
brushOption.range = rectRangeConverter.fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]));
updateCoverAfterCreation(controller, cover);
trigger(controller, {
isEnd: false
});
}
function driftPolygon(controller, cover, dx, dy) {
var range = cover.__brushOption.range;
var localDelta = toLocalDelta(controller, dx, dy);
each(range, function (point) {
point[0] += localDelta[0];
point[1] += localDelta[1];
});
updateCoverAfterCreation(controller, cover);
trigger(controller, {
isEnd: false
});
}
function toLocalDelta(controller, dx, dy) {
var thisGroup = controller.group;
var localD = thisGroup.transformCoordToLocal(dx, dy);
var localZero = thisGroup.transformCoordToLocal(0, 0);
return [localD[0] - localZero[0], localD[1] - localZero[1]];
}
function clipByPanel(controller, cover, data) {
var panel = getPanelByCover(controller, cover);
return panel && panel !== BRUSH_PANEL_GLOBAL ? panel.clipPath(data, controller._transform) : clone(data);
}
function pointsToRect(points) {
var xmin = mathMin(points[0][0], points[1][0]);
var ymin = mathMin(points[0][1], points[1][1]);
var xmax = mathMax(points[0][0], points[1][0]);
var ymax = mathMax(points[0][1], points[1][1]);
return {
x: xmin,
y: ymin,
width: xmax - xmin,
height: ymax - ymin
};
}
function resetCursor(controller, e, localCursorPoint) {
if (
// Check active
!controller._brushType
// resetCursor should be always called when mouse is in zr area,
// but not called when mouse is out of zr area to avoid bad influence
// if `mousemove`, `mouseup` are triggered from `document` event.
|| isOutsideZrArea(controller, e.offsetX, e.offsetY)) {
return;
}
var zr = controller._zr;
var covers = controller._covers;
var currPanel = getPanelByPoint(controller, e, localCursorPoint);
// Check whether in covers.
if (!controller._dragging) {
for (var i = 0; i < covers.length; i++) {
var brushOption = covers[i].__brushOption;
if (currPanel && (currPanel === BRUSH_PANEL_GLOBAL || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) {
// Use cursor style set on cover.
return;
}
}
}
currPanel && zr.setCursorStyle('crosshair');
}
function preventDefault(e) {
var rawE = e.event;
rawE.preventDefault && rawE.preventDefault();
}
function mainShapeContain(cover, x, y) {
return cover.childOfName('main').contain(x, y);
}
function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
var creatingCover = controller._creatingCover;
var panel = controller._creatingPanel;
var thisBrushOption = controller._brushOption;
var eventParams;
controller._track.push(localCursorPoint.slice());
if (shouldShowCover(controller) || creatingCover) {
if (panel && !creatingCover) {
thisBrushOption.brushMode === 'single' && clearCovers(controller);
var brushOption = clone(thisBrushOption);
brushOption.brushType = determineBrushType(brushOption.brushType, panel);
brushOption.panelId = panel === BRUSH_PANEL_GLOBAL ? null : panel.panelId;
creatingCover = controller._creatingCover = createCover(controller, brushOption);
controller._covers.push(creatingCover);
}
if (creatingCover) {
var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
var coverBrushOption = creatingCover.__brushOption;
coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track));
if (isEnd) {
endCreating(controller, creatingCover);
coverRenderer.updateCommon(controller, creatingCover);
}
updateCoverShape(controller, creatingCover);
eventParams = {
isEnd: isEnd
};
}
} else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) {
// Help user to remove covers easily, only by a tiny drag, in 'single' mode.
// But a single click do not clear covers, because user may have casual
// clicks (for example, click on other component and do not expect covers
// disappear).
// Only some cover removed, trigger action, but not every click trigger action.
if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
eventParams = {
isEnd: isEnd,
removeOnClick: true
};
}
}
return eventParams;
}
function determineBrushType(brushType, panel) {
if (brushType === 'auto') {
if (process.env.NODE_ENV !== 'production') {
assert(panel && panel.defaultBrushType, 'MUST have defaultBrushType when brushType is "atuo"');
}
return panel.defaultBrushType;
}
return brushType;
}
var pointerHandlers = {
mousedown: function (e) {
if (this._dragging) {
// In case some browser do not support globalOut,
// and release mouse out side the browser.
handleDragEnd(this, e);
} else if (!e.target || !e.target.draggable) {
preventDefault(e);
var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
this._creatingCover = null;
var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);
if (panel) {
this._dragging = true;
this._track = [localCursorPoint.slice()];
}
}
},
mousemove: function (e) {
var x = e.offsetX;
var y = e.offsetY;
var localCursorPoint = this.group.transformCoordToLocal(x, y);
resetCursor(this, e, localCursorPoint);
if (this._dragging) {
preventDefault(e);
var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
eventParams && trigger(this, eventParams);
}
},
mouseup: function (e) {
handleDragEnd(this, e);
}
};
function handleDragEnd(controller, e) {
if (controller._dragging) {
preventDefault(e);
var x = e.offsetX;
var y = e.offsetY;
var localCursorPoint = controller.group.transformCoordToLocal(x, y);
var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
controller._dragging = false;
controller._track = [];
controller._creatingCover = null;
// trigger event should be at final, after procedure will be nested.
eventParams && trigger(controller, eventParams);
}
}
function isOutsideZrArea(controller, x, y) {
var zr = controller._zr;
return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
}
/**
* key: brushType
*/
var coverRenderers = {
lineX: getLineRenderer(0),
lineY: getLineRenderer(1),
rect: {
createCover: function (controller, brushOption) {
function returnInput(range) {
return range;
}
return createBaseRectCover({
toRectRange: returnInput,
fromRectRange: returnInput
}, controller, brushOption, [['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']]);
},
getCreatingRange: function (localTrack) {
var ends = getTrackEnds(localTrack);
return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
},
updateCoverShape: function (controller, cover, localRange, brushOption) {
updateBaseRect(controller, cover, localRange, brushOption);
},
updateCommon: updateCommon,
contain: mainShapeContain
},
polygon: {
createCover: function (controller, brushOption) {
var cover = new graphic.Group();
// Do not use graphic.Polygon because graphic.Polyline do not close the
// border of the shape when drawing, which is a better experience for user.
cover.add(new graphic.Polyline({
name: 'main',
style: makeStyle(brushOption),
silent: true
}));
return cover;
},
getCreatingRange: function (localTrack) {
return localTrack;
},
endCreating: function (controller, cover) {
cover.remove(cover.childAt(0));
// Use graphic.Polygon close the shape.
cover.add(new graphic.Polygon({
name: 'main',
draggable: true,
drift: curry(driftPolygon, controller, cover),
ondragend: curry(trigger, controller, {
isEnd: true
})
}));
},
updateCoverShape: function (controller, cover, localRange, brushOption) {
cover.childAt(0).setShape({
points: clipByPanel(controller, cover, localRange)
});
},
updateCommon: updateCommon,
contain: mainShapeContain
}
};
function getLineRenderer(xyIndex) {
return {
createCover: function (controller, brushOption) {
return createBaseRectCover({
toRectRange: function (range) {
var rectRange = [range, [0, 100]];
xyIndex && rectRange.reverse();
return rectRange;
},
fromRectRange: function (rectRange) {
return rectRange[xyIndex];
}
}, controller, brushOption, [[['w'], ['e']], [['n'], ['s']]][xyIndex]);
},
getCreatingRange: function (localTrack) {
var ends = getTrackEnds(localTrack);
var min = mathMin(ends[0][xyIndex], ends[1][xyIndex]);
var max = mathMax(ends[0][xyIndex], ends[1][xyIndex]);
return [min, max];
},
updateCoverShape: function (controller, cover, localRange, brushOption) {
var otherExtent;
// If brushWidth not specified, fit the panel.
var panel = getPanelByCover(controller, cover);
if (panel !== BRUSH_PANEL_GLOBAL && panel.getLinearBrushOtherExtent) {
otherExtent = panel.getLinearBrushOtherExtent(xyIndex);
} else {
var zr = controller._zr;
otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
}
var rectRange = [localRange, otherExtent];
xyIndex && rectRange.reverse();
updateBaseRect(controller, cover, rectRange, brushOption);
},
updateCommon: updateCommon,
contain: mainShapeContain
};
}
export default BrushController;

View File

@ -0,0 +1,343 @@
/*
* 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 { each, indexOf, curry, assert, map, createHashMap } from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import * as brushHelper from './brushHelper.js';
import { parseFinder as modelUtilParseFinder } from '../../util/model.js';
// FIXME
// how to genarialize to more coordinate systems.
var INCLUDE_FINDER_MAIN_TYPES = ['grid', 'xAxis', 'yAxis', 'geo', 'graph', 'polar', 'radiusAxis', 'angleAxis', 'bmap'];
var BrushTargetManager = /** @class */function () {
/**
* @param finder contains Index/Id/Name of xAxis/yAxis/geo/grid
* Each can be {number|Array.<number>}. like: {xAxisIndex: [3, 4]}
* @param opt.include include coordinate system types.
*/
function BrushTargetManager(finder, ecModel, opt) {
var _this = this;
this._targetInfoList = [];
var foundCpts = parseFinder(ecModel, finder);
each(targetInfoBuilders, function (builder, type) {
if (!opt || !opt.include || indexOf(opt.include, type) >= 0) {
builder(foundCpts, _this._targetInfoList);
}
});
}
BrushTargetManager.prototype.setOutputRanges = function (areas, ecModel) {
this.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
(area.coordRanges || (area.coordRanges = [])).push(coordRange);
// area.coordRange is the first of area.coordRanges
if (!area.coordRange) {
area.coordRange = coordRange;
// In 'category' axis, coord to pixel is not reversible, so we can not
// rebuild range by coordRange accrately, which may bring trouble when
// brushing only one item. So we use __rangeOffset to rebuilding range
// by coordRange. And this it only used in brush component so it is no
// need to be adapted to coordRanges.
var result = coordConvert[area.brushType](0, coordSys, coordRange);
area.__rangeOffset = {
offset: diffProcessor[area.brushType](result.values, area.range, [1, 1]),
xyMinMax: result.xyMinMax
};
}
});
return areas;
};
BrushTargetManager.prototype.matchOutputRanges = function (areas, ecModel, cb) {
each(areas, function (area) {
var targetInfo = this.findTargetInfo(area, ecModel);
if (targetInfo && targetInfo !== true) {
each(targetInfo.coordSyses, function (coordSys) {
var result = coordConvert[area.brushType](1, coordSys, area.range, true);
cb(area, result.values, coordSys, ecModel);
});
}
}, this);
};
/**
* the `areas` is `BrushModel.areas`.
* Called in layout stage.
* convert `area.coordRange` to global range and set panelId to `area.range`.
*/
BrushTargetManager.prototype.setInputRanges = function (areas, ecModel) {
each(areas, function (area) {
var targetInfo = this.findTargetInfo(area, ecModel);
if (process.env.NODE_ENV !== 'production') {
assert(!targetInfo || targetInfo === true || area.coordRange, 'coordRange must be specified when coord index specified.');
assert(!targetInfo || targetInfo !== true || area.range, 'range must be specified in global brush.');
}
area.range = area.range || [];
// convert coordRange to global range and set panelId.
if (targetInfo && targetInfo !== true) {
area.panelId = targetInfo.panelId;
// (1) area.range should always be calculate from coordRange but does
// not keep its original value, for the sake of the dataZoom scenario,
// where area.coordRange remains unchanged but area.range may be changed.
// (2) Only support converting one coordRange to pixel range in brush
// component. So do not consider `coordRanges`.
// (3) About __rangeOffset, see comment above.
var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange);
var rangeOffset = area.__rangeOffset;
area.range = rangeOffset ? diffProcessor[area.brushType](result.values, rangeOffset.offset, getScales(result.xyMinMax, rangeOffset.xyMinMax)) : result.values;
}
}, this);
};
BrushTargetManager.prototype.makePanelOpts = function (api, getDefaultBrushType) {
return map(this._targetInfoList, function (targetInfo) {
var rect = targetInfo.getPanelRect();
return {
panelId: targetInfo.panelId,
defaultBrushType: getDefaultBrushType ? getDefaultBrushType(targetInfo) : null,
clipPath: brushHelper.makeRectPanelClipPath(rect),
isTargetByCursor: brushHelper.makeRectIsTargetByCursor(rect, api, targetInfo.coordSysModel),
getLinearBrushOtherExtent: brushHelper.makeLinearBrushOtherExtent(rect)
};
});
};
BrushTargetManager.prototype.controlSeries = function (area, seriesModel, ecModel) {
// Check whether area is bound in coord, and series do not belong to that coord.
// If do not do this check, some brush (like lineX) will controll all axes.
var targetInfo = this.findTargetInfo(area, ecModel);
return targetInfo === true || targetInfo && indexOf(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0;
};
/**
* If return Object, a coord found.
* If return true, global found.
* Otherwise nothing found.
*/
BrushTargetManager.prototype.findTargetInfo = function (area, ecModel) {
var targetInfoList = this._targetInfoList;
var foundCpts = parseFinder(ecModel, area);
for (var i = 0; i < targetInfoList.length; i++) {
var targetInfo = targetInfoList[i];
var areaPanelId = area.panelId;
if (areaPanelId) {
if (targetInfo.panelId === areaPanelId) {
return targetInfo;
}
} else {
for (var j = 0; j < targetInfoMatchers.length; j++) {
if (targetInfoMatchers[j](foundCpts, targetInfo)) {
return targetInfo;
}
}
}
}
return true;
};
return BrushTargetManager;
}();
function formatMinMax(minMax) {
minMax[0] > minMax[1] && minMax.reverse();
return minMax;
}
function parseFinder(ecModel, finder) {
return modelUtilParseFinder(ecModel, finder, {
includeMainTypes: INCLUDE_FINDER_MAIN_TYPES
});
}
var targetInfoBuilders = {
grid: function (foundCpts, targetInfoList) {
var xAxisModels = foundCpts.xAxisModels;
var yAxisModels = foundCpts.yAxisModels;
var gridModels = foundCpts.gridModels;
// Remove duplicated.
var gridModelMap = createHashMap();
var xAxesHas = {};
var yAxesHas = {};
if (!xAxisModels && !yAxisModels && !gridModels) {
return;
}
each(xAxisModels, function (axisModel) {
var gridModel = axisModel.axis.grid.model;
gridModelMap.set(gridModel.id, gridModel);
xAxesHas[gridModel.id] = true;
});
each(yAxisModels, function (axisModel) {
var gridModel = axisModel.axis.grid.model;
gridModelMap.set(gridModel.id, gridModel);
yAxesHas[gridModel.id] = true;
});
each(gridModels, function (gridModel) {
gridModelMap.set(gridModel.id, gridModel);
xAxesHas[gridModel.id] = true;
yAxesHas[gridModel.id] = true;
});
gridModelMap.each(function (gridModel) {
var grid = gridModel.coordinateSystem;
var cartesians = [];
each(grid.getCartesians(), function (cartesian, index) {
if (indexOf(xAxisModels, cartesian.getAxis('x').model) >= 0 || indexOf(yAxisModels, cartesian.getAxis('y').model) >= 0) {
cartesians.push(cartesian);
}
});
targetInfoList.push({
panelId: 'grid--' + gridModel.id,
gridModel: gridModel,
coordSysModel: gridModel,
// Use the first one as the representitive coordSys.
coordSys: cartesians[0],
coordSyses: cartesians,
getPanelRect: panelRectBuilders.grid,
xAxisDeclared: xAxesHas[gridModel.id],
yAxisDeclared: yAxesHas[gridModel.id]
});
});
},
geo: function (foundCpts, targetInfoList) {
each(foundCpts.geoModels, function (geoModel) {
var coordSys = geoModel.coordinateSystem;
targetInfoList.push({
panelId: 'geo--' + geoModel.id,
geoModel: geoModel,
coordSysModel: geoModel,
coordSys: coordSys,
coordSyses: [coordSys],
getPanelRect: panelRectBuilders.geo
});
});
}
};
var targetInfoMatchers = [
// grid
function (foundCpts, targetInfo) {
var xAxisModel = foundCpts.xAxisModel;
var yAxisModel = foundCpts.yAxisModel;
var gridModel = foundCpts.gridModel;
!gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model);
!gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model);
return gridModel && gridModel === targetInfo.gridModel;
},
// geo
function (foundCpts, targetInfo) {
var geoModel = foundCpts.geoModel;
return geoModel && geoModel === targetInfo.geoModel;
}];
var panelRectBuilders = {
grid: function () {
// grid is not Transformable.
return this.coordSys.master.getRect().clone();
},
geo: function () {
var coordSys = this.coordSys;
var rect = coordSys.getBoundingRect().clone();
// geo roam and zoom transform
rect.applyTransform(graphic.getTransform(coordSys));
return rect;
}
};
var coordConvert = {
lineX: curry(axisConvert, 0),
lineY: curry(axisConvert, 1),
rect: function (to, coordSys, rangeOrCoordRange, clamp) {
var xminymin = to ? coordSys.pointToData([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp);
var xmaxymax = to ? coordSys.pointToData([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp);
var values = [formatMinMax([xminymin[0], xmaxymax[0]]), formatMinMax([xminymin[1], xmaxymax[1]])];
return {
values: values,
xyMinMax: values
};
},
polygon: function (to, coordSys, rangeOrCoordRange, clamp) {
var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]];
var values = map(rangeOrCoordRange, function (item) {
var p = to ? coordSys.pointToData(item, clamp) : coordSys.dataToPoint(item, clamp);
xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]);
xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]);
xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]);
xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]);
return p;
});
return {
values: values,
xyMinMax: xyMinMax
};
}
};
function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) {
if (process.env.NODE_ENV !== 'production') {
assert(coordSys.type === 'cartesian2d', 'lineX/lineY brush is available only in cartesian2d.');
}
var axis = coordSys.getAxis(['x', 'y'][axisNameIndex]);
var values = formatMinMax(map([0, 1], function (i) {
return to ? axis.coordToData(axis.toLocalCoord(rangeOrCoordRange[i]), true) : axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i]));
}));
var xyMinMax = [];
xyMinMax[axisNameIndex] = values;
xyMinMax[1 - axisNameIndex] = [NaN, NaN];
return {
values: values,
xyMinMax: xyMinMax
};
}
var diffProcessor = {
lineX: curry(axisDiffProcessor, 0),
lineY: curry(axisDiffProcessor, 1),
rect: function (values, refer, scales) {
return [[values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]], [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]]];
},
polygon: function (values, refer, scales) {
return map(values, function (item, idx) {
return [item[0] - scales[0] * refer[idx][0], item[1] - scales[1] * refer[idx][1]];
});
}
};
function axisDiffProcessor(axisNameIndex, values, refer, scales) {
return [values[0] - scales[axisNameIndex] * refer[0], values[1] - scales[axisNameIndex] * refer[1]];
}
// We have to process scale caused by dataZoom manually,
// although it might be not accurate.
// Return [0~1, 0~1]
function getScales(xyMinMaxCurr, xyMinMaxOrigin) {
var sizeCurr = getSize(xyMinMaxCurr);
var sizeOrigin = getSize(xyMinMaxOrigin);
var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]];
isNaN(scales[0]) && (scales[0] = 1);
isNaN(scales[1]) && (scales[1] = 1);
return scales;
}
function getSize(xyMinMax) {
return xyMinMax ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]] : [NaN, NaN];
}
export default BrushTargetManager;

View File

@ -0,0 +1,678 @@
/*
* 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"?

View File

@ -0,0 +1,245 @@
/*
* 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 { __extends } from "tslib";
import Eventful from 'zrender/lib/core/Eventful.js';
import * as eventTool from 'zrender/lib/core/event.js';
import * as interactionMutex from './interactionMutex.js';
import { isString, bind, defaults, clone } from 'zrender/lib/core/util.js';
;
var RoamController = /** @class */function (_super) {
__extends(RoamController, _super);
function RoamController(zr) {
var _this = _super.call(this) || this;
_this._zr = zr;
// Avoid two roamController bind the same handler
var mousedownHandler = bind(_this._mousedownHandler, _this);
var mousemoveHandler = bind(_this._mousemoveHandler, _this);
var mouseupHandler = bind(_this._mouseupHandler, _this);
var mousewheelHandler = bind(_this._mousewheelHandler, _this);
var pinchHandler = bind(_this._pinchHandler, _this);
/**
* Notice: only enable needed types. For example, if 'zoom'
* is not needed, 'zoom' should not be enabled, otherwise
* default mousewheel behaviour (scroll page) will be disabled.
*/
_this.enable = function (controlType, opt) {
// Disable previous first
this.disable();
this._opt = defaults(clone(opt) || {}, {
zoomOnMouseWheel: true,
moveOnMouseMove: true,
// By default, wheel do not trigger move.
moveOnMouseWheel: false,
preventDefaultMouseMove: true
});
if (controlType == null) {
controlType = true;
}
if (controlType === true || controlType === 'move' || controlType === 'pan') {
zr.on('mousedown', mousedownHandler);
zr.on('mousemove', mousemoveHandler);
zr.on('mouseup', mouseupHandler);
}
if (controlType === true || controlType === 'scale' || controlType === 'zoom') {
zr.on('mousewheel', mousewheelHandler);
zr.on('pinch', pinchHandler);
}
};
_this.disable = function () {
zr.off('mousedown', mousedownHandler);
zr.off('mousemove', mousemoveHandler);
zr.off('mouseup', mouseupHandler);
zr.off('mousewheel', mousewheelHandler);
zr.off('pinch', pinchHandler);
};
return _this;
}
RoamController.prototype.isDragging = function () {
return this._dragging;
};
RoamController.prototype.isPinching = function () {
return this._pinching;
};
RoamController.prototype.setPointerChecker = function (pointerChecker) {
this.pointerChecker = pointerChecker;
};
RoamController.prototype.dispose = function () {
this.disable();
};
RoamController.prototype._mousedownHandler = function (e) {
if (eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
return;
}
var el = e.target;
while (el) {
if (el.draggable) {
return;
}
// check if host is draggable
el = el.__hostTarget || el.parent;
}
var x = e.offsetX;
var y = e.offsetY;
// Only check on mosedown, but not mousemove.
// Mouse can be out of target when mouse moving.
if (this.pointerChecker && this.pointerChecker(e, x, y)) {
this._x = x;
this._y = y;
this._dragging = true;
}
};
RoamController.prototype._mousemoveHandler = function (e) {
if (!this._dragging || !isAvailableBehavior('moveOnMouseMove', e, this._opt) || e.gestureEvent === 'pinch' || interactionMutex.isTaken(this._zr, 'globalPan')) {
return;
}
var x = e.offsetX;
var y = e.offsetY;
var oldX = this._x;
var oldY = this._y;
var dx = x - oldX;
var dy = y - oldY;
this._x = x;
this._y = y;
this._opt.preventDefaultMouseMove && eventTool.stop(e.event);
trigger(this, 'pan', 'moveOnMouseMove', e, {
dx: dx,
dy: dy,
oldX: oldX,
oldY: oldY,
newX: x,
newY: y,
isAvailableBehavior: null
});
};
RoamController.prototype._mouseupHandler = function (e) {
if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
this._dragging = false;
}
};
RoamController.prototype._mousewheelHandler = function (e) {
var shouldZoom = isAvailableBehavior('zoomOnMouseWheel', e, this._opt);
var shouldMove = isAvailableBehavior('moveOnMouseWheel', e, this._opt);
var wheelDelta = e.wheelDelta;
var absWheelDeltaDelta = Math.abs(wheelDelta);
var originX = e.offsetX;
var originY = e.offsetY;
// wheelDelta maybe -0 in chrome mac.
if (wheelDelta === 0 || !shouldZoom && !shouldMove) {
return;
}
// If both `shouldZoom` and `shouldMove` is true, trigger
// their event both, and the final behavior is determined
// by event listener themselves.
if (shouldZoom) {
// Convenience:
// Mac and VM Windows on Mac: scroll up: zoom out.
// Windows: scroll up: zoom in.
// FIXME: Should do more test in different environment.
// wheelDelta is too complicated in difference nvironment
// (https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel),
// although it has been normallized by zrender.
// wheelDelta of mouse wheel is bigger than touch pad.
var factor = absWheelDeltaDelta > 3 ? 1.4 : absWheelDeltaDelta > 1 ? 1.2 : 1.1;
var scale = wheelDelta > 0 ? factor : 1 / factor;
checkPointerAndTrigger(this, 'zoom', 'zoomOnMouseWheel', e, {
scale: scale,
originX: originX,
originY: originY,
isAvailableBehavior: null
});
}
if (shouldMove) {
// FIXME: Should do more test in different environment.
var absDelta = Math.abs(wheelDelta);
// wheelDelta of mouse wheel is bigger than touch pad.
var scrollDelta = (wheelDelta > 0 ? 1 : -1) * (absDelta > 3 ? 0.4 : absDelta > 1 ? 0.15 : 0.05);
checkPointerAndTrigger(this, 'scrollMove', 'moveOnMouseWheel', e, {
scrollDelta: scrollDelta,
originX: originX,
originY: originY,
isAvailableBehavior: null
});
}
};
RoamController.prototype._pinchHandler = function (e) {
if (interactionMutex.isTaken(this._zr, 'globalPan')) {
return;
}
var scale = e.pinchScale > 1 ? 1.1 : 1 / 1.1;
checkPointerAndTrigger(this, 'zoom', null, e, {
scale: scale,
originX: e.pinchX,
originY: e.pinchY,
isAvailableBehavior: null
});
};
return RoamController;
}(Eventful);
function checkPointerAndTrigger(controller, eventName, behaviorToCheck, e, contollerEvent) {
if (controller.pointerChecker && controller.pointerChecker(e, contollerEvent.originX, contollerEvent.originY)) {
// When mouse is out of roamController rect,
// default befavoius should not be be disabled, otherwise
// page sliding is disabled, contrary to expectation.
eventTool.stop(e.event);
trigger(controller, eventName, behaviorToCheck, e, contollerEvent);
}
}
function trigger(controller, eventName, behaviorToCheck, e, contollerEvent) {
// Also provide behavior checker for event listener, for some case that
// multiple components share one listener.
contollerEvent.isAvailableBehavior = bind(isAvailableBehavior, null, behaviorToCheck, e);
// TODO should not have type issue.
controller.trigger(eventName, contollerEvent);
}
// settings: {
// zoomOnMouseWheel
// moveOnMouseMove
// moveOnMouseWheel
// }
// The value can be: true / false / 'shift' / 'ctrl' / 'alt'.
function isAvailableBehavior(behaviorToCheck, e, settings) {
var setting = settings[behaviorToCheck];
return !behaviorToCheck || setting && (!isString(setting) || e.event[setting + 'Key']);
}
export default RoamController;

View File

@ -0,0 +1,71 @@
/*
* 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 BoundingRect from 'zrender/lib/core/BoundingRect.js';
import { onIrrelevantElement } from './cursorHelper.js';
import * as graphicUtil from '../../util/graphic.js';
export function makeRectPanelClipPath(rect) {
rect = normalizeRect(rect);
return function (localPoints) {
return graphicUtil.clipPointsByRect(localPoints, rect);
};
}
export function makeLinearBrushOtherExtent(rect, specifiedXYIndex) {
rect = normalizeRect(rect);
return function (xyIndex) {
var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex;
var brushWidth = idx ? rect.width : rect.height;
var base = idx ? rect.x : rect.y;
return [base, base + (brushWidth || 0)];
};
}
export function makeRectIsTargetByCursor(rect, api, targetModel) {
var boundingRect = normalizeRect(rect);
return function (e, localCursorPoint) {
return boundingRect.contain(localCursorPoint[0], localCursorPoint[1]) && !onIrrelevantElement(e, api, targetModel);
};
}
// Consider width/height is negative.
function normalizeRect(rect) {
return BoundingRect.create(rect);
}

View File

@ -0,0 +1,58 @@
/*
* 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.
*/
var IRRELEVANT_EXCLUDES = {
'axisPointer': 1,
'tooltip': 1,
'brush': 1
};
/**
* Avoid that: mouse click on a elements that is over geo or graph,
* but roam is triggered.
*/
export function onIrrelevantElement(e, api, targetCoordSysModel) {
var model = api.getComponentByElement(e.topTarget);
// If model is axisModel, it works only if it is injected with coordinateSystem.
var coordSys = model && model.coordinateSystem;
return model && model !== targetCoordSysModel && !IRRELEVANT_EXCLUDES.hasOwnProperty(model.mainType) && coordSys && coordSys.model !== targetCoordSysModel;
}

View File

@ -0,0 +1,77 @@
/*
* 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.
*/
// @ts-nocheck
import * as echarts from '../../core/echarts.js';
import { noop } from 'zrender/lib/core/util.js';
var ATTR = '\0_ec_interaction_mutex';
export function take(zr, resourceKey, userKey) {
var store = getStore(zr);
store[resourceKey] = userKey;
}
export function release(zr, resourceKey, userKey) {
var store = getStore(zr);
var uKey = store[resourceKey];
if (uKey === userKey) {
store[resourceKey] = null;
}
}
export function isTaken(zr, resourceKey) {
return !!getStore(zr)[resourceKey];
}
function getStore(zr) {
return zr[ATTR] || (zr[ATTR] = {});
}
/**
* payload: {
* type: 'takeGlobalCursor',
* key: 'dataZoomSelect', or 'brush', or ...,
* If no userKey, release global cursor.
* }
*/
// TODO: SELF REGISTERED.
echarts.registerAction({
type: 'takeGlobalCursor',
event: 'globalCursorTaken',
update: 'update'
}, noop);

View File

@ -0,0 +1,87 @@
/*
* 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.
*/
// @ts-nocheck
import { getLayoutRect, box as layoutBox, positionElement } from '../../util/layout.js';
import * as formatUtil from '../../util/format.js';
import * as graphic from '../../util/graphic.js';
/**
* Layout list like component.
* It will box layout each items in group of component and then position the whole group in the viewport
* @param {module:zrender/group/Group} group
* @param {module:echarts/model/Component} componentModel
* @param {module:echarts/ExtensionAPI}
*/
export function layout(group, componentModel, api) {
var boxLayoutParams = componentModel.getBoxLayoutParams();
var padding = componentModel.get('padding');
var viewportSize = {
width: api.getWidth(),
height: api.getHeight()
};
var rect = getLayoutRect(boxLayoutParams, viewportSize, padding);
layoutBox(componentModel.get('orient'), group, componentModel.get('itemGap'), rect.width, rect.height);
positionElement(group, boxLayoutParams, viewportSize, padding);
}
export function makeBackground(rect, componentModel) {
var padding = formatUtil.normalizeCssArray(componentModel.get('padding'));
var style = componentModel.getItemStyle(['color', 'opacity']);
style.fill = componentModel.get('backgroundColor');
rect = new graphic.Rect({
shape: {
x: rect.x - padding[3],
y: rect.y - padding[0],
width: rect.width + padding[1] + padding[3],
height: rect.height + padding[0] + padding[2],
r: componentModel.get('borderRadius')
},
style: style,
silent: true,
z2: -1
});
// FIXME
// `subPixelOptimizeRect` may bring some gap between edge of viewpart
// and background rect when setting like `left: 0`, `top: 0`.
// graphic.subPixelOptimizeRect(rect);
return rect;
}

View File

@ -0,0 +1,74 @@
/*
* 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.
*/
/**
* For geo and graph.
*/
export function updateViewOnPan(controllerHost, dx, dy) {
var target = controllerHost.target;
target.x += dx;
target.y += dy;
target.dirty();
}
/**
* For geo and graph.
*/
export function updateViewOnZoom(controllerHost, zoomDelta, zoomX, zoomY) {
var target = controllerHost.target;
var zoomLimit = controllerHost.zoomLimit;
var newZoom = controllerHost.zoom = controllerHost.zoom || 1;
newZoom *= zoomDelta;
if (zoomLimit) {
var zoomMin = zoomLimit.min || 0;
var zoomMax = zoomLimit.max || Infinity;
newZoom = Math.max(Math.min(zoomMax, newZoom), zoomMin);
}
var zoomScale = newZoom / controllerHost.zoom;
controllerHost.zoom = newZoom;
// Keep the mouse center when scaling
target.x -= (zoomX - target.x) * (zoomScale - 1);
target.y -= (zoomY - target.y) * (zoomScale - 1);
target.scaleX *= zoomScale;
target.scaleY *= zoomScale;
target.dirty();
}

View File

@ -0,0 +1,114 @@
/*
* 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.
*/
/**
* Calculate slider move result.
* Usage:
* (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as
* maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`.
* (2) If handle0 is forbidden to cross handle1, set minSpan as `0`.
*
* @param delta Move length.
* @param handleEnds handleEnds[0] can be bigger then handleEnds[1].
* handleEnds will be modified in this method.
* @param extent handleEnds is restricted by extent.
* extent[0] should less or equals than extent[1].
* @param handleIndex Can be 'all', means that both move the two handleEnds.
* @param minSpan The range of dataZoom can not be smaller than that.
* If not set, handle0 and cross handle1. If set as a non-negative
* number (including `0`), handles will push each other when reaching
* the minSpan.
* @param maxSpan The range of dataZoom can not be larger than that.
* @return The input handleEnds.
*/
export default function sliderMove(delta, handleEnds, extent, handleIndex, minSpan, maxSpan) {
delta = delta || 0;
var extentSpan = extent[1] - extent[0];
// Notice maxSpan and minSpan can be null/undefined.
if (minSpan != null) {
minSpan = restrict(minSpan, [0, extentSpan]);
}
if (maxSpan != null) {
maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0);
}
if (handleIndex === 'all') {
var handleSpan = Math.abs(handleEnds[1] - handleEnds[0]);
handleSpan = restrict(handleSpan, [0, extentSpan]);
minSpan = maxSpan = restrict(handleSpan, [minSpan, maxSpan]);
handleIndex = 0;
}
handleEnds[0] = restrict(handleEnds[0], extent);
handleEnds[1] = restrict(handleEnds[1], extent);
var originalDistSign = getSpanSign(handleEnds, handleIndex);
handleEnds[handleIndex] += delta;
// Restrict in extent.
var extentMinSpan = minSpan || 0;
var realExtent = extent.slice();
originalDistSign.sign < 0 ? realExtent[0] += extentMinSpan : realExtent[1] -= extentMinSpan;
handleEnds[handleIndex] = restrict(handleEnds[handleIndex], realExtent);
// Expand span.
var currDistSign;
currDistSign = getSpanSign(handleEnds, handleIndex);
if (minSpan != null && (currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan)) {
// If minSpan exists, 'cross' is forbidden.
handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan;
}
// Shrink span.
currDistSign = getSpanSign(handleEnds, handleIndex);
if (maxSpan != null && currDistSign.span > maxSpan) {
handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan;
}
return handleEnds;
}
function getSpanSign(handleEnds, handleIndex) {
var dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex];
// If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0]
// is at left of handleEnds[1] for non-cross case.
return {
span: Math.abs(dist),
sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1
};
}
function restrict(value, extend) {
return Math.min(extend[1] != null ? extend[1] : Infinity, Math.max(extend[0] != null ? extend[0] : -Infinity, value));
}