| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 |
- /*
- * 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 BoundingRect, { boundingRectApplyTransform, boundingRectCalculateTransform, boundingRectContain, boundingRectCopy, boundingRectCreate } from 'zrender/lib/core/BoundingRect.js';
- import Transformable, { copyTransform, transformableCreate, transformableGetLocalTransform } from 'zrender/lib/core/Transformable.js';
- import { isPositionSizeOptionPercent, mathAbs, parsePercent } from '../util/number.js';
- import { assert, each } from 'zrender/lib/core/util.js';
- import { getViewOfComponentOrSeries } from '../core/ExtensionAPI.js';
- import { decomposeTransform, payloadDisableAnimation, updateProps, WH, XY } from '../util/graphic.js';
- import { invert as matrixInvert, mul as matrixMul, create as matrixCreate, copy as matrixCopy } from 'zrender/lib/core/matrix.js';
- import { applyTransform as vectorApplyTransform, copy as vectorCopy, set as vectorSet } from 'zrender/lib/core/vector.js';
- /**
- * @tutorial [VIEW_COORD_SYS_ANIMATION]
- *
- * Some VIEW_COORD_SYS may need to support roaming animation, which may be required when the original
- * inputs (such as `center/zoom/left/top/right/bottomwidth/height/etc.`) are changed via `setOption`.
- * Roaming animation requires strict visual alignment between VIEW_COORD_SYS itself (consider "geo map")
- * and its content (e.g., scatter series).
- * A logically correct implementation is probably applying animation to VIEW_COORD_SYS's inputs and
- * calculate VIEW_COORD_SYS's transformation and lay out its dependent series per frame via
- * `dispatchAction`-ish pattern. But this approach require more mechanism to be introduced and careful
- * refactoring.
- * Instead, we currently still follow the conventional implementation - create animation separately on
- * each element (typically via `graphic.updateProps`) . See VIEW_COORD_SYS_ANIMATION_PROPS_CONSTRAINT.
- *
- * [VIEW_COORD_SYS_ANIMATION_PROPS_CONSTRAINT]:
- * The animation should only interpolate `x/y/scaleX/scaleY`, thereby ensuring visual alignment, even
- * though `MapDraw` applies animations only on a "VIEW_COORD_SYS_TRANS_ROAM" but scatter series applies
- * animation on a "VIEW_COORD_SYS_TRANS_OVERALL".
- * But this constraint must always be respected by all relevant components and series.
- *
- * [VIEW_COORD_SYS_ANIMATION_INTERRUPTION]:
- * The animation should be able to be interrupted, such as when users roam it by mouse or touch.
- * When interrupted, `center` and `zoom` must be synchronized back to the VIEW_COORD_SYS and host models
- * (e.g., geo components or map series). Otherwise, a next `setOption` can cause unexpected result due to
- * the outdated `center` and `zoom`.
- * But see FIXME_VIEW_COORD_SYS_SYNC_BACK for some existing bugs.
- *
- * [VIEW_COORD_SYS_UPDATE_FLOW]:
- * To avoid bidirectional flow, we consider the original inputs (center/zoom/dataRect/viewRect/etc.) as
- * the single source of truth, and always calculate transformations based on that.
- * - Roaming interactions ('pan'/'zoom') can trigger an update to the original inputs via
- * `dispatchAction({type: 'xxxRoam', ...})`.
- * - Roaming animation can synchronize back to the original inputs when interrupted.
- * See `syncBackEl`: It is zrender elements that are assigned with VIEW_COORD_SYS_TRANSFORMATION,
- * and may be modified outside, typically by animation.
- */
- /**
- * @tutorial [VIEW_COORD_SYS_TRANSFORMATION]
- *
- * @tutorial [VIEW_COORD_SYS_TRANS_RAW]
- * It is the transformation from `ViewInner['dataRect']` to `ViewInner['viewRect']`.
- * - ViewInner['dataRect']:
- * A rect in a source space (or say, data space).
- * The unit is defined by the source. For example,
- * - for geo source, the unit defined as lat/lng,
- * - for SVG source, the unit is the same as the width/height defined in SVG.
- * - for series.graph/series.tree/series.sankey, the unit defined as px directly.
- * - ViewInner['viewRect']:
- * A rect in the canvas pixel space.
- * For example, it can be ec option left/right/top/bottom/width/height of a component or series.
- * NOTICE:
- * - ViewInner['dataRect'] and ViewInner['viewRect'] affect the behavior when centerOption contains
- * absolute values. See VIEW_COORD_SYS_CENTER_ZOOM_DEFINITION .
- *
- * @tutorial [VIEW_COORD_SYS_TRANS_ROAM]
- * It is built with respect to `RoamOptionMixin['center']` and `RoamOptionMixin['zoom']`.
- * [VIEW_COORD_SYS_CENTER_ZOOM_DEFINITION]:
- * {pxSpace} <-roamTrans- {viewRectSpace} <-rawTrans- {dataRectSpace} <-- ...
- * | |
- * zoomOption centerOption
- * `RoamOptionMixin['center']` is a user specified point on the space of `ViewInner['dataRect']`,
- * which will be located to the center of `ViewInner['viewRect']`.
- * It can also be a percent value (e.g. '50%'), based on ViewInner['dataRect'].width/height` (since v6).
- * Under this definition, users can use '0%' to map the top-left of `ViewInner['dataRect']`
- * to the center of `ViewInner['viewRect']`.
- * NOTICE:
- * - `RoamOptionMixin['center']` is in a linear space regardless of `GeoCommonOptionMixin['projection']`
- * - Absolute values in centerOption may hardly have a rigorous meaningful definition if the layout
- * is auto-calculated, since users are unlikely to known the exact value of the bounding rect.
- * And it is affected by the settings of ViewInner['dataRect'] and ViewInner['viewRect'].
- * Therefore, percent centerOption is preferred.
- * Use cases:
- * geo and map series (`MapDraw`) use this transformation for roamming, since the source
- * has been converted with respect to VIEW_COORD_SYS_TRANS_RAW.
- *
- * @tutorial [VIEW_COORD_SYS_TRANS_OVERALL]
- * This is the result of
- * `matrix_left_multiply(VIEW_COORD_SYS_TRANS_ROAM, VIEW_COORD_SYS_TRANS_RAW)`.
- * Use case:
- * sankey/tree/graph series use this transformation for roamming.
- *
- * @tutorial [VIEW_COORD_SYS_TRANSFORMATION_FORMULA]
- * [Basic]:
- * {pxSpace} <-roamTrans- {viewRectSpace} <-rawTrans- {dataRectSpace} <-- ...
- * pxPoint = roamTrans * rawTrans * dataPoint
- * overallTrans = roamTrans * rawTrans
- * [e.g., geo case]:
- * pxPoint = roamTrans * (rawTrans * (projection * dataPoint))
- * Hence: pxPoint = group_syncBackType_ROAM * (rawTrans * (projection * dataPoint))
- * Hence: pxPoint = group_syncBackType_ROAM * rawTrans_projection_precalculated_point
- * [e.g., graph series case]:
- * pxPoint = (roamTrans * rawTrans) * upper_els
- * Hence: pxPoint = group_syncBackType_OVERALL * upper_els
- * (NOTE: upper_els can have their own transformations)
- *
- * @see viewCoordSysCopyTrans for fetching transformations.
- */
- export var VIEW_COORD_SYS_TRANS_RAW = 0;
- export var VIEW_COORD_SYS_TRANS_ROAM = 1;
- export var VIEW_COORD_SYS_TRANS_OVERALL = 2;
- function inner(viewCoordSys) {
- return viewCoordSys;
- }
- export var VIEW_COORD_SYS_TYPE = 'view';
- /**
- * [VIEW_COORD_SYS]
- *
- * @final [NOTICE] Inheritance of this class is not recommended. Use composition instead.
- */
- var View = /** @class */function (_super) {
- __extends(View, _super);
- function View(invertY, legacyCenterBase, legacyGeo) {
- var _this = _super.call(this) || this;
- _this.type = VIEW_COORD_SYS_TYPE;
- _this.dimensions = ['x', 'y'];
- var viewInner = inner(_this);
- viewInner.invertY = invertY;
- viewInner.lgCt = legacyCenterBase;
- viewInner.lgGeo = legacyGeo;
- var trans = viewInner.trans = [];
- trans[VIEW_COORD_SYS_TRANS_RAW] = transformableCreate();
- trans[VIEW_COORD_SYS_TRANS_ROAM] = transformableCreate();
- trans[VIEW_COORD_SYS_TRANS_OVERALL] = transformableCreate();
- viewInner.mtRaw = matrixCreate();
- viewInner.mtRawInv = matrixCreate();
- viewInner.mtOverall = matrixCreate();
- viewInner.mtOverallInv = matrixCreate();
- viewInner.zoom = 1;
- return _this;
- }
- /**
- * @implements CoordinateSystem['getBoundingRect']
- * @see VIEW_COORD_SYS_TRANS_RAW
- *
- * This is a rect in data space.
- * For historicall reason, the name is `getBoundingRect` - preserve it for backward compatibility.
- */
- View.prototype.getBoundingRect = function () {
- return viewCoordSysCopyBoundingRect(null, this);
- };
- /**
- * @implements CoordinateSystem['getViewRect']
- * @see VIEW_COORD_SYS_TRANS_RAW
- */
- View.prototype.getViewRect = function () {
- return viewCoordSysCopyViewRect(null, this);
- };
- /**
- * @implements CoordinateSystem['getRoamTransform']
- */
- View.prototype.getRoamTransform = function () {
- return transformableGetLocalTransform(inner(this).trans[VIEW_COORD_SYS_TRANS_ROAM]);
- };
- View.prototype.dataToPoint = function (data, noRoam, out) {
- var transform = noRoam ? inner(this).mtRaw : inner(this).mtOverall;
- out = out || [];
- return transform ? vectorApplyTransform(out, data, transform) : vectorCopy(out, data);
- };
- View.prototype.pointToData = function (point, reserved, out) {
- out = out || [];
- var invTransform = inner(this).mtOverallInv;
- return invTransform ? vectorApplyTransform(out, point, invTransform) : vectorCopy(out, point);
- };
- View.prototype.convertToPixel = function (ecModel, finder, value) {
- var coordSys = getCoordSys(finder);
- return coordSys === this ? coordSys.dataToPoint(value) : null;
- };
- View.prototype.convertFromPixel = function (ecModel, finder, pixel) {
- var coordSys = getCoordSys(finder);
- return coordSys === this ? coordSys.pointToData(pixel) : null;
- };
- View.prototype.containPoint = function (point) {
- var viewInner = inner(this);
- boundingRectCopy(tmpPixelRectForContain, viewInner.dataRect);
- boundingRectApplyTransform(tmpPixelRectForContain, tmpPixelRectForContain, viewInner.mtOverall);
- return boundingRectContain(tmpPixelRectForContain, point[0], point[1]);
- };
- View.dimensions = ['x', 'y'];
- return View;
- }(Transformable);
- var tmpPixelRectForContain = boundingRectCreate();
- export function viewCoordSysCopyOverallMatrix(out, viewCoordSys) {
- return matrixCopy(out || [], inner(viewCoordSys).mtOverall);
- }
- export function viewCoordSysGetZoomOption(viewCoordSys) {
- return inner(viewCoordSys).zoom;
- }
- export function viewCoordSysCopyBoundingRect(out, viewCoordSys) {
- return boundingRectCopy(out || boundingRectCreate(), inner(viewCoordSys).dataRect);
- }
- export function viewCoordSysCopyViewRect(out, viewCoordSys) {
- return boundingRectCopy(out || boundingRectCreate(), inner(viewCoordSys).viewRect);
- }
- export function viewCoordSysCopyTrans(out, viewCoordSys, transKind
- // @return The input `out` or create an object.
- ) {
- return copyTransform(out || transformableCreate(), inner(viewCoordSys).trans[transKind]);
- }
- function viewCoordSysIsInputReady(viewInner) {
- return !!(viewInner.dataRect && viewInner.viewRect);
- // NOTE: Other parameters has default values. Only parameters
- // above are required to be input.
- }
- function calcOverallTransFromSyncBackEl(out, viewInner, syncBackEl, syncBackType) {
- if (syncBackType === VIEW_COORD_SYS_TRANS_ROAM) {
- calcOverallTrans(out, viewInner.trans[VIEW_COORD_SYS_TRANS_RAW], syncBackEl);
- } else {
- copyTransform(out, syncBackEl);
- }
- }
- function calcRoamTransFromOverallTrans(out, viewInner, overallTrans) {
- // Convert overallTrans to roamTrans. If update animation is applied to overallTrans,
- // we assume that rawTrans is changed instantly, and roamTrans takes that animation.
- // Formula:
- // overallTrans = roamTrans * rawTrans
- // overallTrans * invert(rawTrans) = roamTrans
- transformableGetLocalTransform(overallTrans, tmpMtRTO);
- matrixMul(tmpMtRTO, tmpMtRTO, viewInner.mtRawInv);
- decomposeTransform(out, tmpMtRTO);
- }
- var tmpMtRTO = matrixCreate();
- /**
- * [NOTICE]
- * The definition of this center has always been irrelevant to some other series center like
- * 'series-pie.center' - this center is a point in the space of `ViewInner['dataRect'].x/y`,
- * rather than canvas viewport, and the unit is not necessarily pixel (e.g., in geo case).
- */
- export function viewCoordSysSetRoamOptionFromModel(viewCoordSys, hostModel) {
- var viewInner = inner(viewCoordSys);
- viewInner.centerOption = hostModel.getShallow('center');
- var zoomLimit = viewInner.zoomLimit = hostModel.getShallow('scaleLimit');
- var zoomOption = hostModel.getShallow('zoom');
- viewInner.zoom = clampByZoomLimit(zoomOption || 1, zoomLimit) || 1;
- if (viewCoordSysIsInputReady(viewInner)) {
- viewCoordSysUpdateTransform(viewInner);
- }
- }
- /**
- * @see ViewInner['dataRect']
- */
- export function viewCoordSysSetBoundingRect(viewCoordSys, x, y, width, height) {
- var viewInner = inner(viewCoordSys);
- viewInner.dataRect = new BoundingRect(x, y, width, height);
- if (viewCoordSysIsInputReady(viewInner)) {
- viewCoordSysUpdateTransform(viewInner);
- }
- }
- /**
- * @see ViewInner['viewRect']
- */
- export function viewCoordSysSetViewRect(viewCoordSys, x, y, width, height) {
- var viewInner = inner(viewCoordSys);
- viewInner.viewRect = new BoundingRect(x, y, width, height);
- if (viewCoordSysIsInputReady(viewInner)) {
- viewCoordSysUpdateTransform(viewInner);
- }
- }
- function viewCoordSysUpdateTransform(viewInner) {
- // The order matters.
- viewCoordSysUpdateRawTrans(viewInner);
- viewCoordSysUpdateRoamTrans(viewInner);
- viewCoordSysUpdateOverallTrans(viewInner);
- }
- function viewCoordSysUpdateRawTrans(viewInner) {
- var dataRect = viewInner.dataRect;
- var viewRect = viewInner.viewRect;
- var rawTrans = viewInner.trans[VIEW_COORD_SYS_TRANS_RAW];
- var invertY = viewInner.invertY;
- if (invertY) {
- dataRect = boundingRectCopy(tmpRectURT, dataRect);
- dataRect.y = -dataRect.y - dataRect.height;
- }
- boundingRectCalculateTransform(tmpMtURT, dataRect, viewRect);
- decomposeTransform(rawTrans, tmpMtURT);
- if (invertY) {
- rawTrans.scaleY = -rawTrans.scaleY;
- }
- var mtRaw = transformableGetLocalTransform(rawTrans, viewInner.mtRaw);
- matrixInvert(viewInner.mtRawInv, mtRaw);
- }
- var tmpMtURT = matrixCreate();
- var tmpRectURT = boundingRectCreate();
- /**
- * NOTICE: It depends on `viewCoordSysUpdateRawTrans`.
- */
- function viewCoordSysUpdateRoamTrans(viewInner) {
- var viewRectCenter = viewCoordSysGetViewRectCenter(viewInner);
- var roamViewCenter = parseCenterOption(tmpCenterURT, viewInner, viewInner.centerOption) ? vectorApplyTransform(tmpCenterURT, tmpCenterURT, viewInner.mtRaw) : viewRectCenter;
- var zoom = viewInner.zoom;
- var roamTrans = viewInner.trans[VIEW_COORD_SYS_TRANS_ROAM];
- roamTrans.x = viewRectCenter[0] - zoom * roamViewCenter[0];
- roamTrans.y = viewRectCenter[1] - zoom * roamViewCenter[1];
- roamTrans.scaleX = roamTrans.scaleY = zoom;
- // [VIEW_COORD_SYS_APPLY_ROAM_CENTER_AND_ZOOM]
- // Ordinarily, the definition is:
- // roamTrans.originX = roamViewCenter[0];
- // roamTrans.originY = roamViewCenter[1];
- // roamTrans.x = viewRectCenter[0] - roamViewCenter[0];
- // roamTrans.y = viewRectCenter[1] - roamViewCenter[1];
- // roamTrans.scaleX = roamTrans.scaleY = zoom;
- // But `el.originX`/`originY` should not be set.
- // (see VIEW_COORD_SYS_ANIMATION_PROPS_CONSTRAINT for the reason),
- // so we use the above formula instead.
- }
- var tmpCenterURT = [];
- /**
- * NOTICE: It depends on `viewCoordSysUpdateRoamTrans` and `viewCoordSysUpdateRawTrans`
- */
- function viewCoordSysUpdateOverallTrans(viewInner) {
- var trans = viewInner.trans;
- var roamTrans = trans[VIEW_COORD_SYS_TRANS_ROAM];
- var rawTrans = trans[VIEW_COORD_SYS_TRANS_RAW];
- var overallTrans = trans[VIEW_COORD_SYS_TRANS_OVERALL];
- calcOverallTrans(overallTrans, rawTrans, roamTrans);
- var mtOverall = transformableGetLocalTransform(overallTrans, viewInner.mtOverall);
- var mtOverallInv = matrixInvert(viewInner.mtOverallInv, mtOverall);
- legacyCopyOverallTrans(viewInner, overallTrans, mtOverall, mtOverallInv);
- legacyCopyOverallTrans(viewInner.lgGeo, overallTrans, mtOverall, mtOverallInv);
- }
- /**
- * [VIEW_COORD_SYS_TRANS_OVERALL_BACKWARD_COMPATIBILITY]
- * VIEW_COORD_SYS_TRANS_OVERALL transformable has long been View or Geo instance itself.
- * We keep backward compatibility, since some users may have visited it directly (e.g.
- * for drawing a computed bounding rect).
- */
- function legacyCopyOverallTrans(target, overallTrans, mtOverall, mtOverallInv) {
- if (target) {
- copyTransform(target, overallTrans);
- matrixCopy(target.transform || (target.transform = []), mtOverall);
- matrixCopy(target.invTransform || (target.invTransform = []), mtOverallInv);
- }
- }
- function calcOverallTrans(out, rawTrans, roamTrans) {
- transformableGetLocalTransform(rawTrans, tmpMtCOT1);
- transformableGetLocalTransform(roamTrans, tmpMtCOT2);
- matrixMul(tmpMtCOT2, tmpMtCOT2, tmpMtCOT1);
- decomposeTransform(out, tmpMtCOT2);
- }
- var tmpMtCOT1 = matrixCreate();
- var tmpMtCOT2 = matrixCreate();
- function getCoordSys(finder) {
- var seriesModel = finder.seriesModel;
- return seriesModel ? seriesModel.coordinateSystem : null; // e.g., graph.
- }
- function viewCoordSysGetViewRectCenter(viewInner) {
- var viewRect = viewInner.viewRect;
- tmpViewRectCenter[0] = viewRect.x + viewRect.width / 2;
- tmpViewRectCenter[1] = viewRect.y + viewRect.height / 2;
- return tmpViewRectCenter;
- }
- var tmpViewRectCenter = [];
- export function isViewCoordSys(coordSys) {
- return coordSys && coordSys.type === 'view';
- }
- /**
- * NOTICE:
- * - `syncBackEl` should be in the pixel space without any other transformation
- * in its accesters, otherwise the roaming may incorrect.
- * - `syncBackEl` can be a `Group`, having its own descendants and transformation.
- * But in this case, `dataToPoint` can only reach the space of `syncBackEl` itself.
- */
- export function applyViewCoordSysTransToElement(syncBackEl, syncBackType, viewCoordSys,
- // If NullUndefined, no animation.
- // Typically, there should be no animation in the first render and in `__updateOnOwnRoam`.
- animatableModel) {
- var viewInner = inner(viewCoordSys);
- viewInner.syncBackEl = syncBackEl;
- viewInner.syncBackType = syncBackType;
- if (!animatableModel) {
- viewCoordSysCopyTrans(syncBackEl, viewCoordSys, syncBackType);
- syncBackEl.dirty();
- } else {
- updateProps(syncBackEl, viewCoordSysCopyTrans(null, viewCoordSys, syncBackType), animatableModel);
- }
- }
- /**
- * FIXME: [FIXME_VIEW_COORD_SYS_SYNC_BACK]
- * Currently the "sync back" is only performed on roam action. But these cases are not
- * covered:
- * 1. Consider both center change and series data adding is requested via `setOption`
- * and animation is not finished, the new added series symbols should lay out based
- * on the "intermediate state" rather than the "final state" of the VIEW_COORD_SYS,
- * otherwise, visual artifacts can arise.
- * 2. See the case of FIXME_SYMBOL_CLIP_CONSIDERING_COORD_SYS_ALIGNMENT_DURING_ANIMATION .
- */
- function viewCoordSysSyncBack(viewCoordSys, hostModel, otherModelsToSync, payload) {
- var viewInner = inner(viewCoordSys);
- var syncBackEl = viewInner.syncBackEl;
- if (syncBackEl) {
- if (process.env.NODE_ENV !== 'production') {
- assert(viewInner.syncBackType != null);
- }
- // @see VIEW_COORD_SYS_ANIMATION_INTERRUPTION
- syncBackEl.stopAnimation();
- // syncBackEl may have been changed regardless of animation,
- // therefore, need to sync back.
- calcOverallTransFromSyncBackEl(tmpTransSB1, viewInner, syncBackEl, viewInner.syncBackType);
- } else {
- copyTransform(tmpTransSB1, viewInner.trans[VIEW_COORD_SYS_TRANS_OVERALL]);
- }
- // Sync back to model.
- calcRoamTransFromOverallTrans(tmpTransSB2, viewInner, tmpTransSB1);
- payload ? applyRoamPayloadToOverallTrans(tmpTransSB1, tmpTransSB2, viewInner, payload) : copyTransform(tmpTransSB1, tmpTransSB2);
- calcRoamTransFromOverallTrans(tmpTransSB1, viewInner, tmpTransSB1);
- syncBackToRoamOptionFromRoamTrans(viewInner, hostModel, otherModelsToSync, tmpTransSB1);
- }
- var tmpTransSB1 = transformableCreate();
- var tmpTransSB2 = transformableCreate();
- /**
- * Invert to `center` and `zoom` of VIEW_COORD_SYS and host models based on
- * - `syncBackEl` or VIEW_COORD_SYS_TRANS_OVERALL
- * - Delta in `payload`.
- *
- * Should be only called in action handlers.
- *
- * @see RoamHostView['__updateOnOwnRoam']
- */
- export function ownRoamModelCoordSysUpdateInAction(payload, hostModel,
- // This is only used for MAP_SERIES_GROUP, where the change need to sync to all series,
- // otherwise when legend filter some series and the other series take the responsibility
- // to draw map, or roam then legend restored, the result will be incorrect.
- otherModelsToSync) {
- // NOTE: VIEW_COORD_SYS instances are depended on by this action handler.
- // Under the current design, actions should not be triggered before `setOption`
- // being called, therefore coord sys instances always exist.
- var viewCoordSys = getOwnRoamViewCoordSys(hostModel);
- if (viewCoordSys) {
- // Sync back to model.
- viewCoordSysSyncBack(viewCoordSys, hostModel, otherModelsToSync, payload);
- // Recalculate from model.
- viewCoordSysSetRoamOptionFromModel(viewCoordSys, hostModel);
- }
- }
- export function getOwnRoamViewCoordSys(hostModel) {
- return hostModel.__ownRoamView ? hostModel.__ownRoamView() : null;
- }
- export function ownRoamViewUpdateDirectlyInAction(payload, componentOrSeries, ecModel, api) {
- // Tricky: disable animation in `updateProps` of `graphic.ts`.
- ecModel.setUpdatePayload(payloadDisableAnimation(payload));
- var componentOrSeriesView = getViewOfComponentOrSeries(api, componentOrSeries);
- if (componentOrSeriesView && componentOrSeriesView.__updateOnOwnRoam) {
- componentOrSeriesView.__updateOnOwnRoam(payload, componentOrSeries, api);
- }
- }
- function applyRoamPayloadToOverallTrans(targetOverallTrans, roamTrans, viewInner, payload) {
- // NOTE: payload.dx/dy should always applied to pixel space, i.e., "overallTrans".
- if (payload.dx != null && payload.dy != null) {
- targetOverallTrans.x += payload.dx;
- targetOverallTrans.y += payload.dy;
- }
- var deltaZoom = payload.zoom;
- if (deltaZoom != null) {
- // Although `zoomOption` is defined on roamTrans
- var oldZoom = getZoomFromRoamTrans(roamTrans);
- var newZoom = clampByZoomLimit(oldZoom * deltaZoom, viewInner.zoomLimit);
- var deltaZoom2 = newZoom / oldZoom;
- // Keep the mouse center when scaling.
- targetOverallTrans.x -= (payload.originX - targetOverallTrans.x) * (deltaZoom2 - 1);
- targetOverallTrans.y -= (payload.originY - targetOverallTrans.y) * (deltaZoom2 - 1);
- // Although `zoomOption` is defined on roamTrans,
- // deltaZoom can be applied to overallTrans directly.
- targetOverallTrans.scaleX *= deltaZoom2;
- targetOverallTrans.scaleY *= deltaZoom2;
- }
- }
- function getZoomFromRoamTrans(trans) {
- if (process.env.NODE_ENV !== 'production') {
- // scaleX and scaleY should be the same even during animation.
- // See VIEW_COORD_SYS_APPLY_ROAM_CENTER_AND_ZOOM .
- assert(mathAbs(trans.scaleX - trans.scaleY) < 1e-5);
- }
- return trans.scaleX;
- }
- function parseCenterOption(
- // `out` is a center in `dataRect` space.
- out, viewInner, centerOption
- // @return Whether a valid center is obtained.
- ) {
- if (process.env.NODE_ENV !== 'production') {
- assert(viewCoordSysIsInputReady(viewInner));
- }
- var dataRect = viewInner.dataRect;
- if (!centerOption) {
- return false;
- }
- // #16904 introduced percentage string here, such as '33%'. But it was based on canvas
- // width/height, which is not reasonable - the unit may incorrect, and it is unpredictable if
- // the `ViewInner['dataRect']` is not calculated based on the current canvas rect. Therefore the percentage
- // value is changed to based on `ViewInner['dataRect'].width/height` since v6. Under this definition, users
- // can use '0%' to map the top-left of `ViewInner['dataRect']` to the center of `ViewInner['viewRect']`.
- var lgCt = viewInner.lgCt;
- if (lgCt) {
- vectorSet(out, parsePercent(centerOption[0], lgCt.w), parsePercent(centerOption[1], lgCt.h));
- } else if (dataRect) {
- vectorSet(out, parsePercent(centerOption[0], dataRect.width, dataRect.x), parsePercent(centerOption[1], dataRect.height, dataRect.y));
- }
- return true;
- }
- /**
- * An inverse operation to `parseCenterOption`.
- * Mainly for percentage center option.
- */
- function invertBackToCenterOption(viewInner, center) {
- var lastCenterOption = viewInner.centerOption;
- var dataRect = viewInner.dataRect;
- if (process.env.NODE_ENV !== 'production') {
- assert(center && dataRect);
- }
- return !lastCenterOption || viewInner.lgCt ? center.slice() : [invertToPercentPerCenterDim(0, center, lastCenterOption, dataRect), invertToPercentPerCenterDim(1, center, lastCenterOption, dataRect)];
- }
- function invertToPercentPerCenterDim(dimIdx, center, lastCenterOption, dataRect) {
- return lastCenterOption && dataRect && dataRect[WH[dimIdx]] && isPositionSizeOptionPercent(lastCenterOption[dimIdx]) ? (center[dimIdx] - dataRect[XY[dimIdx]]) / dataRect[WH[dimIdx]] * 100 + '%' : center[dimIdx];
- }
- export function useLegacyViewCoordSysCenterBase(ecModel, api) {
- return api && ecModel && ecModel.getShallow('legacyViewCoordSysCenterBase') ? {
- w: api.getWidth(),
- h: api.getHeight()
- } : null;
- }
- /**
- * @see VIEW_COORD_SYS_ANIMATION_INTERRUPTION
- */
- function syncBackToRoamOptionFromRoamTrans(viewInner, hostModel, otherModelsToSync, roamTrans) {
- // This is the inverse operation of `viewCoordSysSetRoamOptionFromModel`.
- var viewRectCenter = viewCoordSysGetViewRectCenter(viewInner);
- var zoom = getZoomFromRoamTrans(roamTrans);
- var notZoomNearZero = mathAbs(zoom) > 1e-6;
- tmpCenterITR[0] = notZoomNearZero ? (viewRectCenter[0] - roamTrans.x) / zoom : viewRectCenter[0]; // Unlikely to occur.
- tmpCenterITR[1] = notZoomNearZero ? (viewRectCenter[1] - roamTrans.y) / zoom : viewRectCenter[1]; // Unlikely to occur.
- vectorApplyTransform(tmpCenterITR, tmpCenterITR, viewInner.mtRawInv);
- var centerOption = invertBackToCenterOption(viewInner, tmpCenterITR);
- syncBackRoamOptionToRoamHostModel(hostModel, centerOption, zoom);
- each(otherModelsToSync, function (otherModel) {
- if (otherModel !== hostModel) {
- syncBackRoamOptionToRoamHostModel(otherModel, centerOption.slice(), zoom);
- }
- });
- }
- var tmpCenterITR = [];
- /**
- * Models should be updated, otherwise consequent `setOption()` can cause outdated `center`
- * and `zoom` to be used.
- */
- function syncBackRoamOptionToRoamHostModel(hostModel, center, zoom) {
- var option = hostModel.option;
- option.center = center;
- option.zoom = zoom;
- }
- export function clampByZoomLimit(zoom, zoomLimit) {
- if (zoomLimit) {
- var zoomMin = zoomLimit.min || 0;
- var zoomMax = zoomLimit.max || Infinity;
- zoom = Math.max(Math.min(zoomMax, zoom), zoomMin);
- }
- return zoom;
- }
- export function calcCompensationScaleToPreserveNodeSize(viewCoordSys, model) {
- var nodeScaleRatio = model.getShallow('nodeScaleRatio', true) || 1;
- var viewInner = inner(viewCoordSys);
- // Scale node when zoom changes
- return ((viewInner.zoom - 1) * nodeScaleRatio + 1) / (viewInner.trans[VIEW_COORD_SYS_TRANS_OVERALL].scaleX || 1);
- }
- export default View;
|