逐步完成前后端服务器
This commit is contained in:
243
frontend/node_modules/echarts/lib/animation/basicTransition.js
generated
vendored
Normal file
243
frontend/node_modules/echarts/lib/animation/basicTransition.js
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
|
||||
/*
|
||||
* 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 { isFunction, isObject, retrieve2 } from 'zrender/lib/core/util.js';
|
||||
import { makeInner } from '../util/model.js';
|
||||
// Stored properties for further transition.
|
||||
export var transitionStore = makeInner();
|
||||
/**
|
||||
* Return null if animation is disabled.
|
||||
*/
|
||||
export function getAnimationConfig(animationType, animatableModel, dataIndex,
|
||||
// Extra opts can override the option in animatable model.
|
||||
extraOpts,
|
||||
// TODO It's only for pictorial bar now.
|
||||
extraDelayParams) {
|
||||
var animationPayload;
|
||||
// Check if there is global animation configuration from dataZoom/resize can override the config in option.
|
||||
// If animation is enabled. Will use this animation config in payload.
|
||||
// If animation is disabled. Just ignore it.
|
||||
if (animatableModel && animatableModel.ecModel) {
|
||||
var updatePayload = animatableModel.ecModel.getUpdatePayload();
|
||||
animationPayload = updatePayload && updatePayload.animation;
|
||||
}
|
||||
var animationEnabled = animatableModel && animatableModel.isAnimationEnabled();
|
||||
var isUpdate = animationType === 'update';
|
||||
if (animationEnabled) {
|
||||
var duration = void 0;
|
||||
var easing = void 0;
|
||||
var delay = void 0;
|
||||
if (extraOpts) {
|
||||
duration = retrieve2(extraOpts.duration, 200);
|
||||
easing = retrieve2(extraOpts.easing, 'cubicOut');
|
||||
delay = 0;
|
||||
} else {
|
||||
duration = animatableModel.getShallow(isUpdate ? 'animationDurationUpdate' : 'animationDuration');
|
||||
easing = animatableModel.getShallow(isUpdate ? 'animationEasingUpdate' : 'animationEasing');
|
||||
delay = animatableModel.getShallow(isUpdate ? 'animationDelayUpdate' : 'animationDelay');
|
||||
}
|
||||
// animation from payload has highest priority.
|
||||
if (animationPayload) {
|
||||
animationPayload.duration != null && (duration = animationPayload.duration);
|
||||
animationPayload.easing != null && (easing = animationPayload.easing);
|
||||
animationPayload.delay != null && (delay = animationPayload.delay);
|
||||
}
|
||||
if (isFunction(delay)) {
|
||||
delay = delay(dataIndex, extraDelayParams);
|
||||
}
|
||||
if (isFunction(duration)) {
|
||||
duration = duration(dataIndex);
|
||||
}
|
||||
var config = {
|
||||
duration: duration || 0,
|
||||
delay: delay,
|
||||
easing: easing
|
||||
};
|
||||
return config;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function animateOrSetProps(animationType, el, props, animatableModel, dataIndex, cb, during) {
|
||||
var isFrom = false;
|
||||
var removeOpt;
|
||||
if (isFunction(dataIndex)) {
|
||||
during = cb;
|
||||
cb = dataIndex;
|
||||
dataIndex = null;
|
||||
} else if (isObject(dataIndex)) {
|
||||
cb = dataIndex.cb;
|
||||
during = dataIndex.during;
|
||||
isFrom = dataIndex.isFrom;
|
||||
removeOpt = dataIndex.removeOpt;
|
||||
dataIndex = dataIndex.dataIndex;
|
||||
}
|
||||
var isRemove = animationType === 'leave';
|
||||
if (!isRemove) {
|
||||
// Must stop the remove animation.
|
||||
el.stopAnimation('leave');
|
||||
}
|
||||
var animationConfig = getAnimationConfig(animationType, animatableModel, dataIndex, isRemove ? removeOpt || {} : null, animatableModel && animatableModel.getAnimationDelayParams ? animatableModel.getAnimationDelayParams(el, dataIndex) : null);
|
||||
if (animationConfig && animationConfig.duration > 0) {
|
||||
var duration = animationConfig.duration;
|
||||
var animationDelay = animationConfig.delay;
|
||||
var animationEasing = animationConfig.easing;
|
||||
var animateConfig = {
|
||||
duration: duration,
|
||||
delay: animationDelay || 0,
|
||||
easing: animationEasing,
|
||||
done: cb,
|
||||
force: !!cb || !!during,
|
||||
// Set to final state in update/init animation.
|
||||
// So the post processing based on the path shape can be done correctly.
|
||||
setToFinal: !isRemove,
|
||||
scope: animationType,
|
||||
during: during
|
||||
};
|
||||
isFrom ? el.animateFrom(props, animateConfig) : el.animateTo(props, animateConfig);
|
||||
} else {
|
||||
el.stopAnimation();
|
||||
// If `isFrom`, the props is the "from" props.
|
||||
!isFrom && el.attr(props);
|
||||
// Call during at least once.
|
||||
during && during(1);
|
||||
cb && cb();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Update graphic element properties with or without animation according to the
|
||||
* configuration in series.
|
||||
*
|
||||
* Caution: this method will stop previous animation.
|
||||
* So do not use this method to one element twice before
|
||||
* animation starts, unless you know what you are doing.
|
||||
* @example
|
||||
* graphic.updateProps(el, {
|
||||
* position: [100, 100]
|
||||
* }, seriesModel, dataIndex, function () { console.log('Animation done!'); });
|
||||
* // Or
|
||||
* graphic.updateProps(el, {
|
||||
* position: [100, 100]
|
||||
* }, seriesModel, function () { console.log('Animation done!'); });
|
||||
*/
|
||||
function updateProps(el, props,
|
||||
// TODO: TYPE AnimatableModel
|
||||
animatableModel, dataIndex, cb, during) {
|
||||
animateOrSetProps('update', el, props, animatableModel, dataIndex, cb, during);
|
||||
}
|
||||
export { updateProps };
|
||||
/**
|
||||
* Init graphic element properties with or without animation according to the
|
||||
* configuration in series.
|
||||
*
|
||||
* Caution: this method will stop previous animation.
|
||||
* So do not use this method to one element twice before
|
||||
* animation starts, unless you know what you are doing.
|
||||
*/
|
||||
export function initProps(el, props, animatableModel, dataIndex, cb, during) {
|
||||
animateOrSetProps('enter', el, props, animatableModel, dataIndex, cb, during);
|
||||
}
|
||||
/**
|
||||
* If element is removed.
|
||||
* It can determine if element is having remove animation.
|
||||
*/
|
||||
export function isElementRemoved(el) {
|
||||
if (!el.__zr) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0; i < el.animators.length; i++) {
|
||||
var animator = el.animators[i];
|
||||
if (animator.scope === 'leave') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Remove graphic element
|
||||
*/
|
||||
export function removeElement(el, props, animatableModel, dataIndex, cb, during) {
|
||||
// Don't do remove animation twice.
|
||||
if (isElementRemoved(el)) {
|
||||
return;
|
||||
}
|
||||
animateOrSetProps('leave', el, props, animatableModel, dataIndex, cb, during);
|
||||
}
|
||||
function fadeOutDisplayable(el, animatableModel, dataIndex, done) {
|
||||
el.removeTextContent();
|
||||
el.removeTextGuideLine();
|
||||
removeElement(el, {
|
||||
style: {
|
||||
opacity: 0
|
||||
}
|
||||
}, animatableModel, dataIndex, done);
|
||||
}
|
||||
export function removeElementWithFadeOut(el, animatableModel, dataIndex) {
|
||||
function doRemove() {
|
||||
el.parent && el.parent.remove(el);
|
||||
}
|
||||
// Hide label and labelLine first
|
||||
// TODO Also use fade out animation?
|
||||
if (!el.isGroup) {
|
||||
fadeOutDisplayable(el, animatableModel, dataIndex, doRemove);
|
||||
} else {
|
||||
el.traverse(function (disp) {
|
||||
if (!disp.isGroup) {
|
||||
// Can invoke doRemove multiple times.
|
||||
fadeOutDisplayable(disp, animatableModel, dataIndex, doRemove);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Save old style for style transition in universalTransition module.
|
||||
* It's used when element will be reused in each render.
|
||||
* For chart like map, heatmap, which will always create new element.
|
||||
* We don't need to save this because universalTransition can get old style from the old element
|
||||
*/
|
||||
export function saveOldStyle(el) {
|
||||
transitionStore(el).oldStyle = el.style;
|
||||
}
|
||||
export function getOldStyle(el) {
|
||||
return transitionStore(el).oldStyle;
|
||||
}
|
143
frontend/node_modules/echarts/lib/animation/customGraphicKeyframeAnimation.js
generated
vendored
Normal file
143
frontend/node_modules/echarts/lib/animation/customGraphicKeyframeAnimation.js
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
|
||||
/*
|
||||
* 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 { keys, filter, each, isArray, indexOf } from 'zrender/lib/core/util.js';
|
||||
import { ELEMENT_ANIMATABLE_PROPS } from './customGraphicTransition.js';
|
||||
import { getAnimationConfig } from './basicTransition.js';
|
||||
import { warn } from '../util/log.js';
|
||||
import { makeInner } from '../util/model.js';
|
||||
var getStateToRestore = makeInner();
|
||||
var KEYFRAME_EXCLUDE_KEYS = ['percent', 'easing', 'shape', 'style', 'extra'];
|
||||
/**
|
||||
* Stop previous keyframe animation and restore the attributes.
|
||||
* Avoid new keyframe animation starts with wrong internal state when the percent: 0 is not set.
|
||||
*/
|
||||
export function stopPreviousKeyframeAnimationAndRestore(el) {
|
||||
// Stop previous keyframe animation.
|
||||
el.stopAnimation('keyframe');
|
||||
// Restore
|
||||
el.attr(getStateToRestore(el));
|
||||
}
|
||||
export function applyKeyframeAnimation(el, animationOpts, animatableModel) {
|
||||
if (!animatableModel.isAnimationEnabled() || !animationOpts) {
|
||||
return;
|
||||
}
|
||||
if (isArray(animationOpts)) {
|
||||
each(animationOpts, function (singleAnimationOpts) {
|
||||
applyKeyframeAnimation(el, singleAnimationOpts, animatableModel);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var keyframes = animationOpts.keyframes;
|
||||
var duration = animationOpts.duration;
|
||||
if (animatableModel && duration == null) {
|
||||
// Default to use duration of config.
|
||||
// NOTE: animation config from payload will be ignored because they are mainly for transitions.
|
||||
var config = getAnimationConfig('enter', animatableModel, 0);
|
||||
duration = config && config.duration;
|
||||
}
|
||||
if (!keyframes || !duration) {
|
||||
return;
|
||||
}
|
||||
var stateToRestore = getStateToRestore(el);
|
||||
each(ELEMENT_ANIMATABLE_PROPS, function (targetPropName) {
|
||||
if (targetPropName && !el[targetPropName]) {
|
||||
return;
|
||||
}
|
||||
var animator;
|
||||
var endFrameIsSet = false;
|
||||
// Sort keyframes by percent.
|
||||
keyframes.sort(function (a, b) {
|
||||
return a.percent - b.percent;
|
||||
});
|
||||
each(keyframes, function (kf) {
|
||||
// Stop current animation.
|
||||
var animators = el.animators;
|
||||
var kfValues = targetPropName ? kf[targetPropName] : kf;
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (kf.percent >= 1) {
|
||||
endFrameIsSet = true;
|
||||
}
|
||||
}
|
||||
if (!kfValues) {
|
||||
return;
|
||||
}
|
||||
var propKeys = keys(kfValues);
|
||||
if (!targetPropName) {
|
||||
// PENDING performance?
|
||||
propKeys = filter(propKeys, function (key) {
|
||||
return indexOf(KEYFRAME_EXCLUDE_KEYS, key) < 0;
|
||||
});
|
||||
}
|
||||
if (!propKeys.length) {
|
||||
return;
|
||||
}
|
||||
if (!animator) {
|
||||
animator = el.animate(targetPropName, animationOpts.loop, true);
|
||||
animator.scope = 'keyframe';
|
||||
}
|
||||
for (var i = 0; i < animators.length; i++) {
|
||||
// Stop all other animation that is not keyframe.
|
||||
if (animators[i] !== animator && animators[i].targetName === animator.targetName) {
|
||||
animators[i].stopTracks(propKeys);
|
||||
}
|
||||
}
|
||||
targetPropName && (stateToRestore[targetPropName] = stateToRestore[targetPropName] || {});
|
||||
var savedTarget = targetPropName ? stateToRestore[targetPropName] : stateToRestore;
|
||||
each(propKeys, function (key) {
|
||||
// Save original value.
|
||||
savedTarget[key] = ((targetPropName ? el[targetPropName] : el) || {})[key];
|
||||
});
|
||||
animator.whenWithKeys(duration * kf.percent, kfValues, propKeys, kf.easing);
|
||||
});
|
||||
if (!animator) {
|
||||
return;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!endFrameIsSet) {
|
||||
warn('End frame with percent: 1 is missing in the keyframeAnimation.', true);
|
||||
}
|
||||
}
|
||||
animator.delay(animationOpts.delay || 0).duration(duration).start(animationOpts.easing);
|
||||
});
|
||||
}
|
480
frontend/node_modules/echarts/lib/animation/customGraphicTransition.js
generated
vendored
Normal file
480
frontend/node_modules/echarts/lib/animation/customGraphicTransition.js
generated
vendored
Normal file
@ -0,0 +1,480 @@
|
||||
|
||||
/*
|
||||
* 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 { makeInner, normalizeToArray } from '../util/model.js';
|
||||
import { assert, bind, each, eqNaN, extend, hasOwn, indexOf, isArrayLike, keys, reduce } from 'zrender/lib/core/util.js';
|
||||
import { cloneValue } from 'zrender/lib/animation/Animator.js';
|
||||
import Displayable from 'zrender/lib/graphic/Displayable.js';
|
||||
import { getAnimationConfig } from './basicTransition.js';
|
||||
import { Path } from '../util/graphic.js';
|
||||
import { warn } from '../util/log.js';
|
||||
import { TRANSFORMABLE_PROPS } from 'zrender/lib/core/Transformable.js';
|
||||
var LEGACY_TRANSFORM_PROPS_MAP = {
|
||||
position: ['x', 'y'],
|
||||
scale: ['scaleX', 'scaleY'],
|
||||
origin: ['originX', 'originY']
|
||||
};
|
||||
var LEGACY_TRANSFORM_PROPS = keys(LEGACY_TRANSFORM_PROPS_MAP);
|
||||
var TRANSFORM_PROPS_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) {
|
||||
obj[key] = 1;
|
||||
return obj;
|
||||
}, {});
|
||||
var transformPropNamesStr = TRANSFORMABLE_PROPS.join(', ');
|
||||
// '' means root
|
||||
export var ELEMENT_ANIMATABLE_PROPS = ['', 'style', 'shape', 'extra'];
|
||||
;
|
||||
var transitionInnerStore = makeInner();
|
||||
;
|
||||
function getElementAnimationConfig(animationType, el, elOption, parentModel, dataIndex) {
|
||||
var animationProp = animationType + "Animation";
|
||||
var config = getAnimationConfig(animationType, parentModel, dataIndex) || {};
|
||||
var userDuring = transitionInnerStore(el).userDuring;
|
||||
// Only set when duration is > 0 and it's need to be animated.
|
||||
if (config.duration > 0) {
|
||||
// For simplicity, if during not specified, the previous during will not work any more.
|
||||
config.during = userDuring ? bind(duringCall, {
|
||||
el: el,
|
||||
userDuring: userDuring
|
||||
}) : null;
|
||||
config.setToFinal = true;
|
||||
config.scope = animationType;
|
||||
}
|
||||
extend(config, elOption[animationProp]);
|
||||
return config;
|
||||
}
|
||||
export function applyUpdateTransition(el, elOption, animatableModel, opts) {
|
||||
opts = opts || {};
|
||||
var dataIndex = opts.dataIndex,
|
||||
isInit = opts.isInit,
|
||||
clearStyle = opts.clearStyle;
|
||||
var hasAnimation = animatableModel.isAnimationEnabled();
|
||||
// Save the meta info for further morphing. Like apply on the sub morphing elements.
|
||||
var store = transitionInnerStore(el);
|
||||
var styleOpt = elOption.style;
|
||||
store.userDuring = elOption.during;
|
||||
var transFromProps = {};
|
||||
var propsToSet = {};
|
||||
prepareTransformAllPropsFinal(el, elOption, propsToSet);
|
||||
prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
|
||||
prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet);
|
||||
if (!isInit && hasAnimation) {
|
||||
prepareTransformTransitionFrom(el, elOption, transFromProps);
|
||||
prepareShapeOrExtraTransitionFrom('shape', el, elOption, transFromProps);
|
||||
prepareShapeOrExtraTransitionFrom('extra', el, elOption, transFromProps);
|
||||
prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps);
|
||||
}
|
||||
propsToSet.style = styleOpt;
|
||||
applyPropsDirectly(el, propsToSet, clearStyle);
|
||||
applyMiscProps(el, elOption);
|
||||
if (hasAnimation) {
|
||||
if (isInit) {
|
||||
var enterFromProps_1 = {};
|
||||
each(ELEMENT_ANIMATABLE_PROPS, function (propName) {
|
||||
var prop = propName ? elOption[propName] : elOption;
|
||||
if (prop && prop.enterFrom) {
|
||||
if (propName) {
|
||||
enterFromProps_1[propName] = enterFromProps_1[propName] || {};
|
||||
}
|
||||
extend(propName ? enterFromProps_1[propName] : enterFromProps_1, prop.enterFrom);
|
||||
}
|
||||
});
|
||||
var config = getElementAnimationConfig('enter', el, elOption, animatableModel, dataIndex);
|
||||
if (config.duration > 0) {
|
||||
el.animateFrom(enterFromProps_1, config);
|
||||
}
|
||||
} else {
|
||||
applyPropsTransition(el, elOption, dataIndex || 0, animatableModel, transFromProps);
|
||||
}
|
||||
}
|
||||
// Store leave to be used in leave transition.
|
||||
updateLeaveTo(el, elOption);
|
||||
styleOpt ? el.dirty() : el.markRedraw();
|
||||
}
|
||||
export function updateLeaveTo(el, elOption) {
|
||||
// Try merge to previous set leaveTo
|
||||
var leaveToProps = transitionInnerStore(el).leaveToProps;
|
||||
for (var i = 0; i < ELEMENT_ANIMATABLE_PROPS.length; i++) {
|
||||
var propName = ELEMENT_ANIMATABLE_PROPS[i];
|
||||
var prop = propName ? elOption[propName] : elOption;
|
||||
if (prop && prop.leaveTo) {
|
||||
if (!leaveToProps) {
|
||||
leaveToProps = transitionInnerStore(el).leaveToProps = {};
|
||||
}
|
||||
if (propName) {
|
||||
leaveToProps[propName] = leaveToProps[propName] || {};
|
||||
}
|
||||
extend(propName ? leaveToProps[propName] : leaveToProps, prop.leaveTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
export function applyLeaveTransition(el, elOption, animatableModel, onRemove) {
|
||||
if (el) {
|
||||
var parent_1 = el.parent;
|
||||
var leaveToProps = transitionInnerStore(el).leaveToProps;
|
||||
if (leaveToProps) {
|
||||
// TODO TODO use leave after leaveAnimation in series is introduced
|
||||
// TODO Data index?
|
||||
var config = getElementAnimationConfig('update', el, elOption, animatableModel, 0);
|
||||
config.done = function () {
|
||||
parent_1.remove(el);
|
||||
onRemove && onRemove();
|
||||
};
|
||||
el.animateTo(leaveToProps, config);
|
||||
} else {
|
||||
parent_1.remove(el);
|
||||
onRemove && onRemove();
|
||||
}
|
||||
}
|
||||
}
|
||||
export function isTransitionAll(transition) {
|
||||
return transition === 'all';
|
||||
}
|
||||
function applyPropsDirectly(el,
|
||||
// Can be null/undefined
|
||||
allPropsFinal, clearStyle) {
|
||||
var styleOpt = allPropsFinal.style;
|
||||
if (!el.isGroup && styleOpt) {
|
||||
if (clearStyle) {
|
||||
el.useStyle({});
|
||||
// When style object changed, how to trade the existing animation?
|
||||
// It is probably complicated and not needed to cover all the cases.
|
||||
// But still need consider the case:
|
||||
// (1) When using init animation on `style.opacity`, and before the animation
|
||||
// ended users triggers an update by mousewhel. At that time the init
|
||||
// animation should better be continued rather than terminated.
|
||||
// So after `useStyle` called, we should change the animation target manually
|
||||
// to continue the effect of the init animation.
|
||||
// (2) PENDING: If the previous animation targeted at a `val1`, and currently we need
|
||||
// to update the value to `val2` and no animation declared, should be terminate
|
||||
// the previous animation or just modify the target of the animation?
|
||||
// Therotically That will happen not only on `style` but also on `shape` and
|
||||
// `transfrom` props. But we haven't handle this case at present yet.
|
||||
// (3) PENDING: Is it proper to visit `animators` and `targetName`?
|
||||
var animators = el.animators;
|
||||
for (var i = 0; i < animators.length; i++) {
|
||||
var animator = animators[i];
|
||||
// targetName is the "topKey".
|
||||
if (animator.targetName === 'style') {
|
||||
animator.changeTarget(el.style);
|
||||
}
|
||||
}
|
||||
}
|
||||
el.setStyle(styleOpt);
|
||||
}
|
||||
if (allPropsFinal) {
|
||||
// Not set style here.
|
||||
allPropsFinal.style = null;
|
||||
// Set el to the final state firstly.
|
||||
allPropsFinal && el.attr(allPropsFinal);
|
||||
allPropsFinal.style = styleOpt;
|
||||
}
|
||||
}
|
||||
function applyPropsTransition(el, elOption, dataIndex, model,
|
||||
// Can be null/undefined
|
||||
transFromProps) {
|
||||
if (transFromProps) {
|
||||
var config = getElementAnimationConfig('update', el, elOption, model, dataIndex);
|
||||
if (config.duration > 0) {
|
||||
el.animateFrom(transFromProps, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
function applyMiscProps(el, elOption) {
|
||||
// Merge by default.
|
||||
hasOwn(elOption, 'silent') && (el.silent = elOption.silent);
|
||||
hasOwn(elOption, 'ignore') && (el.ignore = elOption.ignore);
|
||||
if (el instanceof Displayable) {
|
||||
hasOwn(elOption, 'invisible') && (el.invisible = elOption.invisible);
|
||||
}
|
||||
if (el instanceof Path) {
|
||||
hasOwn(elOption, 'autoBatch') && (el.autoBatch = elOption.autoBatch);
|
||||
}
|
||||
}
|
||||
// Use it to avoid it be exposed to user.
|
||||
var tmpDuringScope = {};
|
||||
var transitionDuringAPI = {
|
||||
// Usually other props do not need to be changed in animation during.
|
||||
setTransform: function (key, val) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
|
||||
}
|
||||
tmpDuringScope.el[key] = val;
|
||||
return this;
|
||||
},
|
||||
getTransform: function (key) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
|
||||
}
|
||||
return tmpDuringScope.el[key];
|
||||
},
|
||||
setShape: function (key, val) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertNotReserved(key);
|
||||
}
|
||||
var el = tmpDuringScope.el;
|
||||
var shape = el.shape || (el.shape = {});
|
||||
shape[key] = val;
|
||||
el.dirtyShape && el.dirtyShape();
|
||||
return this;
|
||||
},
|
||||
getShape: function (key) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertNotReserved(key);
|
||||
}
|
||||
var shape = tmpDuringScope.el.shape;
|
||||
if (shape) {
|
||||
return shape[key];
|
||||
}
|
||||
},
|
||||
setStyle: function (key, val) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertNotReserved(key);
|
||||
}
|
||||
var el = tmpDuringScope.el;
|
||||
var style = el.style;
|
||||
if (style) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (eqNaN(val)) {
|
||||
warn('style.' + key + ' must not be assigned with NaN.');
|
||||
}
|
||||
}
|
||||
style[key] = val;
|
||||
el.dirtyStyle && el.dirtyStyle();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
getStyle: function (key) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertNotReserved(key);
|
||||
}
|
||||
var style = tmpDuringScope.el.style;
|
||||
if (style) {
|
||||
return style[key];
|
||||
}
|
||||
},
|
||||
setExtra: function (key, val) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertNotReserved(key);
|
||||
}
|
||||
var extra = tmpDuringScope.el.extra || (tmpDuringScope.el.extra = {});
|
||||
extra[key] = val;
|
||||
return this;
|
||||
},
|
||||
getExtra: function (key) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertNotReserved(key);
|
||||
}
|
||||
var extra = tmpDuringScope.el.extra;
|
||||
if (extra) {
|
||||
return extra[key];
|
||||
}
|
||||
}
|
||||
};
|
||||
function assertNotReserved(key) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (key === 'transition' || key === 'enterFrom' || key === 'leaveTo') {
|
||||
throw new Error('key must not be "' + key + '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
function duringCall() {
|
||||
// Do not provide "percent" until some requirements come.
|
||||
// Because consider thies case:
|
||||
// enterFrom: {x: 100, y: 30}, transition: 'x'.
|
||||
// And enter duration is different from update duration.
|
||||
// Thus it might be confused about the meaning of "percent" in during callback.
|
||||
var scope = this;
|
||||
var el = scope.el;
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
// If el is remove from zr by reason like legend, during still need to called,
|
||||
// because el will be added back to zr and the prop value should not be incorrect.
|
||||
var latestUserDuring = transitionInnerStore(el).userDuring;
|
||||
var scopeUserDuring = scope.userDuring;
|
||||
// Ensured a during is only called once in each animation frame.
|
||||
// If a during is called multiple times in one frame, maybe some users' calculation logic
|
||||
// might be wrong (not sure whether this usage exists).
|
||||
// The case of a during might be called twice can be: by default there is a animator for
|
||||
// 'x', 'y' when init. Before the init animation finished, call `setOption` to start
|
||||
// another animators for 'style'/'shape'/'extra'.
|
||||
if (latestUserDuring !== scopeUserDuring) {
|
||||
// release
|
||||
scope.el = scope.userDuring = null;
|
||||
return;
|
||||
}
|
||||
tmpDuringScope.el = el;
|
||||
// Give no `this` to user in "during" calling.
|
||||
scopeUserDuring(transitionDuringAPI);
|
||||
// FIXME: if in future meet the case that some prop will be both modified in `during` and `state`,
|
||||
// consider the issue that the prop might be incorrect when return to "normal" state.
|
||||
}
|
||||
function prepareShapeOrExtraTransitionFrom(mainAttr, fromEl, elOption, transFromProps) {
|
||||
var attrOpt = elOption[mainAttr];
|
||||
if (!attrOpt) {
|
||||
return;
|
||||
}
|
||||
var elPropsInAttr = fromEl[mainAttr];
|
||||
var transFromPropsInAttr;
|
||||
if (elPropsInAttr) {
|
||||
var transition = elOption.transition;
|
||||
var attrTransition = attrOpt.transition;
|
||||
if (attrTransition) {
|
||||
!transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
|
||||
if (isTransitionAll(attrTransition)) {
|
||||
extend(transFromPropsInAttr, elPropsInAttr);
|
||||
} else {
|
||||
var transitionKeys = normalizeToArray(attrTransition);
|
||||
for (var i = 0; i < transitionKeys.length; i++) {
|
||||
var key = transitionKeys[i];
|
||||
var elVal = elPropsInAttr[key];
|
||||
transFromPropsInAttr[key] = elVal;
|
||||
}
|
||||
}
|
||||
} else if (isTransitionAll(transition) || indexOf(transition, mainAttr) >= 0) {
|
||||
!transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
|
||||
var elPropsInAttrKeys = keys(elPropsInAttr);
|
||||
for (var i = 0; i < elPropsInAttrKeys.length; i++) {
|
||||
var key = elPropsInAttrKeys[i];
|
||||
var elVal = elPropsInAttr[key];
|
||||
if (isNonStyleTransitionEnabled(attrOpt[key], elVal)) {
|
||||
transFromPropsInAttr[key] = elVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function prepareShapeOrExtraAllPropsFinal(mainAttr, elOption, allProps) {
|
||||
var attrOpt = elOption[mainAttr];
|
||||
if (!attrOpt) {
|
||||
return;
|
||||
}
|
||||
var allPropsInAttr = allProps[mainAttr] = {};
|
||||
var keysInAttr = keys(attrOpt);
|
||||
for (var i = 0; i < keysInAttr.length; i++) {
|
||||
var key = keysInAttr[i];
|
||||
// To avoid share one object with different element, and
|
||||
// to avoid user modify the object inexpectedly, have to clone.
|
||||
allPropsInAttr[key] = cloneValue(attrOpt[key]);
|
||||
}
|
||||
}
|
||||
function prepareTransformTransitionFrom(el, elOption, transFromProps) {
|
||||
var transition = elOption.transition;
|
||||
var transitionKeys = isTransitionAll(transition) ? TRANSFORMABLE_PROPS : normalizeToArray(transition || []);
|
||||
for (var i = 0; i < transitionKeys.length; i++) {
|
||||
var key = transitionKeys[i];
|
||||
if (key === 'style' || key === 'shape' || key === 'extra') {
|
||||
continue;
|
||||
}
|
||||
var elVal = el[key];
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkTransformPropRefer(key, 'el.transition');
|
||||
}
|
||||
// Do not clone, animator will perform that clone.
|
||||
transFromProps[key] = elVal;
|
||||
}
|
||||
}
|
||||
function prepareTransformAllPropsFinal(el, elOption, allProps) {
|
||||
for (var i = 0; i < LEGACY_TRANSFORM_PROPS.length; i++) {
|
||||
var legacyName = LEGACY_TRANSFORM_PROPS[i];
|
||||
var xyName = LEGACY_TRANSFORM_PROPS_MAP[legacyName];
|
||||
var legacyArr = elOption[legacyName];
|
||||
if (legacyArr) {
|
||||
allProps[xyName[0]] = legacyArr[0];
|
||||
allProps[xyName[1]] = legacyArr[1];
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) {
|
||||
var key = TRANSFORMABLE_PROPS[i];
|
||||
if (elOption[key] != null) {
|
||||
allProps[key] = elOption[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
function prepareStyleTransitionFrom(fromEl, elOption, styleOpt, transFromProps) {
|
||||
if (!styleOpt) {
|
||||
return;
|
||||
}
|
||||
var fromElStyle = fromEl.style;
|
||||
var transFromStyleProps;
|
||||
if (fromElStyle) {
|
||||
var styleTransition = styleOpt.transition;
|
||||
var elTransition = elOption.transition;
|
||||
if (styleTransition && !isTransitionAll(styleTransition)) {
|
||||
var transitionKeys = normalizeToArray(styleTransition);
|
||||
!transFromStyleProps && (transFromStyleProps = transFromProps.style = {});
|
||||
for (var i = 0; i < transitionKeys.length; i++) {
|
||||
var key = transitionKeys[i];
|
||||
var elVal = fromElStyle[key];
|
||||
// Do not clone, see `checkNonStyleTansitionRefer`.
|
||||
transFromStyleProps[key] = elVal;
|
||||
}
|
||||
} else if (fromEl.getAnimationStyleProps && (isTransitionAll(elTransition) || isTransitionAll(styleTransition) || indexOf(elTransition, 'style') >= 0)) {
|
||||
var animationProps = fromEl.getAnimationStyleProps();
|
||||
var animationStyleProps = animationProps ? animationProps.style : null;
|
||||
if (animationStyleProps) {
|
||||
!transFromStyleProps && (transFromStyleProps = transFromProps.style = {});
|
||||
var styleKeys = keys(styleOpt);
|
||||
for (var i = 0; i < styleKeys.length; i++) {
|
||||
var key = styleKeys[i];
|
||||
if (animationStyleProps[key]) {
|
||||
var elVal = fromElStyle[key];
|
||||
transFromStyleProps[key] = elVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function isNonStyleTransitionEnabled(optVal, elVal) {
|
||||
// The same as `checkNonStyleTansitionRefer`.
|
||||
return !isArrayLike(optVal) ? optVal != null && isFinite(optVal) : optVal !== elVal;
|
||||
}
|
||||
var checkTransformPropRefer;
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkTransformPropRefer = function (key, usedIn) {
|
||||
if (!hasOwn(TRANSFORM_PROPS_MAP, key)) {
|
||||
warn('Prop `' + key + '` is not a permitted in `' + usedIn + '`. ' + 'Only `' + keys(TRANSFORM_PROPS_MAP).join('`, `') + '` are permitted.');
|
||||
}
|
||||
};
|
||||
}
|
203
frontend/node_modules/echarts/lib/animation/morphTransitionHelper.js
generated
vendored
Normal file
203
frontend/node_modules/echarts/lib/animation/morphTransitionHelper.js
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
|
||||
/*
|
||||
* 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 { separateMorph, combineMorph, morphPath, isCombineMorphing } from 'zrender/lib/tool/morphPath.js';
|
||||
import { Path } from '../util/graphic.js';
|
||||
import { defaults, isArray } from 'zrender/lib/core/util.js';
|
||||
import { getAnimationConfig } from './basicTransition.js';
|
||||
import { clonePath } from 'zrender/lib/tool/path.js';
|
||||
function isMultiple(elements) {
|
||||
return isArray(elements[0]);
|
||||
}
|
||||
function prepareMorphBatches(one, many) {
|
||||
var batches = [];
|
||||
var batchCount = one.length;
|
||||
for (var i = 0; i < batchCount; i++) {
|
||||
batches.push({
|
||||
one: one[i],
|
||||
many: []
|
||||
});
|
||||
}
|
||||
for (var i = 0; i < many.length; i++) {
|
||||
var len = many[i].length;
|
||||
var k = void 0;
|
||||
for (k = 0; k < len; k++) {
|
||||
batches[k % batchCount].many.push(many[i][k]);
|
||||
}
|
||||
}
|
||||
var off = 0;
|
||||
// If one has more paths than each one of many. average them.
|
||||
for (var i = batchCount - 1; i >= 0; i--) {
|
||||
if (!batches[i].many.length) {
|
||||
var moveFrom = batches[off].many;
|
||||
if (moveFrom.length <= 1) {
|
||||
// Not enough
|
||||
// Start from the first one.
|
||||
if (off) {
|
||||
off = 0;
|
||||
} else {
|
||||
return batches;
|
||||
}
|
||||
}
|
||||
var len = moveFrom.length;
|
||||
var mid = Math.ceil(len / 2);
|
||||
batches[i].many = moveFrom.slice(mid, len);
|
||||
batches[off].many = moveFrom.slice(0, mid);
|
||||
off++;
|
||||
}
|
||||
}
|
||||
return batches;
|
||||
}
|
||||
var pathDividers = {
|
||||
clone: function (params) {
|
||||
var ret = [];
|
||||
// Fitting the alpha
|
||||
var approxOpacity = 1 - Math.pow(1 - params.path.style.opacity, 1 / params.count);
|
||||
for (var i = 0; i < params.count; i++) {
|
||||
var cloned = clonePath(params.path);
|
||||
cloned.setStyle('opacity', approxOpacity);
|
||||
ret.push(cloned);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
// Use the default divider
|
||||
split: null
|
||||
};
|
||||
export function applyMorphAnimation(from, to, divideShape, seriesModel, dataIndex, animateOtherProps) {
|
||||
if (!from.length || !to.length) {
|
||||
return;
|
||||
}
|
||||
var updateAnimationCfg = getAnimationConfig('update', seriesModel, dataIndex);
|
||||
if (!(updateAnimationCfg && updateAnimationCfg.duration > 0)) {
|
||||
return;
|
||||
}
|
||||
var animationDelay = seriesModel.getModel('universalTransition').get('delay');
|
||||
var animationCfg = Object.assign({
|
||||
// Need to setToFinal so the further calculation based on the style can be correct.
|
||||
// Like emphasis color.
|
||||
setToFinal: true
|
||||
}, updateAnimationCfg);
|
||||
var many;
|
||||
var one;
|
||||
if (isMultiple(from)) {
|
||||
// manyToOne
|
||||
many = from;
|
||||
one = to;
|
||||
}
|
||||
if (isMultiple(to)) {
|
||||
// oneToMany
|
||||
many = to;
|
||||
one = from;
|
||||
}
|
||||
function morphOneBatch(batch, fromIsMany, animateIndex, animateCount, forceManyOne) {
|
||||
var batchMany = batch.many;
|
||||
var batchOne = batch.one;
|
||||
if (batchMany.length === 1 && !forceManyOne) {
|
||||
// Is one to one
|
||||
var batchFrom = fromIsMany ? batchMany[0] : batchOne;
|
||||
var batchTo = fromIsMany ? batchOne : batchMany[0];
|
||||
if (isCombineMorphing(batchFrom)) {
|
||||
// Keep doing combine animation.
|
||||
morphOneBatch({
|
||||
many: [batchFrom],
|
||||
one: batchTo
|
||||
}, true, animateIndex, animateCount, true);
|
||||
} else {
|
||||
var individualAnimationCfg = animationDelay ? defaults({
|
||||
delay: animationDelay(animateIndex, animateCount)
|
||||
}, animationCfg) : animationCfg;
|
||||
morphPath(batchFrom, batchTo, individualAnimationCfg);
|
||||
animateOtherProps(batchFrom, batchTo, batchFrom, batchTo, individualAnimationCfg);
|
||||
}
|
||||
} else {
|
||||
var separateAnimationCfg = defaults({
|
||||
dividePath: pathDividers[divideShape],
|
||||
individualDelay: animationDelay && function (idx, count, fromPath, toPath) {
|
||||
return animationDelay(idx + animateIndex, animateCount);
|
||||
}
|
||||
}, animationCfg);
|
||||
var _a = fromIsMany ? combineMorph(batchMany, batchOne, separateAnimationCfg) : separateMorph(batchOne, batchMany, separateAnimationCfg),
|
||||
fromIndividuals = _a.fromIndividuals,
|
||||
toIndividuals = _a.toIndividuals;
|
||||
var count = fromIndividuals.length;
|
||||
for (var k = 0; k < count; k++) {
|
||||
var individualAnimationCfg = animationDelay ? defaults({
|
||||
delay: animationDelay(k, count)
|
||||
}, animationCfg) : animationCfg;
|
||||
animateOtherProps(fromIndividuals[k], toIndividuals[k], fromIsMany ? batchMany[k] : batch.one, fromIsMany ? batch.one : batchMany[k], individualAnimationCfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
var fromIsMany = many ? many === from
|
||||
// Is one to one. If the path number not match. also needs do merge and separate morphing.
|
||||
: from.length > to.length;
|
||||
var morphBatches = many ? prepareMorphBatches(one, many) : prepareMorphBatches(fromIsMany ? to : from, [fromIsMany ? from : to]);
|
||||
var animateCount = 0;
|
||||
for (var i = 0; i < morphBatches.length; i++) {
|
||||
animateCount += morphBatches[i].many.length;
|
||||
}
|
||||
var animateIndex = 0;
|
||||
for (var i = 0; i < morphBatches.length; i++) {
|
||||
morphOneBatch(morphBatches[i], fromIsMany, animateIndex, animateCount);
|
||||
animateIndex += morphBatches[i].many.length;
|
||||
}
|
||||
}
|
||||
export function getPathList(elements) {
|
||||
if (!elements) {
|
||||
return [];
|
||||
}
|
||||
if (isArray(elements)) {
|
||||
var pathList_1 = [];
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
pathList_1.push(getPathList(elements[i]));
|
||||
}
|
||||
return pathList_1;
|
||||
}
|
||||
var pathList = [];
|
||||
elements.traverse(function (el) {
|
||||
if (el instanceof Path && !el.disableMorphing && !el.invisible && !el.ignore) {
|
||||
pathList.push(el);
|
||||
}
|
||||
});
|
||||
return pathList;
|
||||
}
|
649
frontend/node_modules/echarts/lib/animation/universalTransition.js
generated
vendored
Normal file
649
frontend/node_modules/echarts/lib/animation/universalTransition.js
generated
vendored
Normal file
@ -0,0 +1,649 @@
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// Universal transitions that can animate between any shapes(series) and any properties in any amounts.
|
||||
import { SERIES_UNIVERSAL_TRANSITION_PROP } from '../model/Series.js';
|
||||
import { createHashMap, each, map, filter, isArray, extend } from 'zrender/lib/core/util.js';
|
||||
import { applyMorphAnimation, getPathList } from './morphTransitionHelper.js';
|
||||
import Path from 'zrender/lib/graphic/Path.js';
|
||||
import { initProps } from '../util/graphic.js';
|
||||
import DataDiffer from '../data/DataDiffer.js';
|
||||
import { makeInner, normalizeToArray } from '../util/model.js';
|
||||
import { warn } from '../util/log.js';
|
||||
import { getAnimationConfig, getOldStyle } from './basicTransition.js';
|
||||
import Displayable from 'zrender/lib/graphic/Displayable.js';
|
||||
var DATA_COUNT_THRESHOLD = 1e4;
|
||||
var TRANSITION_NONE = 0;
|
||||
var TRANSITION_P2C = 1;
|
||||
var TRANSITION_C2P = 2;
|
||||
;
|
||||
var getUniversalTransitionGlobalStore = makeInner();
|
||||
function getDimension(data, visualDimension) {
|
||||
var dimensions = data.dimensions;
|
||||
for (var i = 0; i < dimensions.length; i++) {
|
||||
var dimInfo = data.getDimensionInfo(dimensions[i]);
|
||||
if (dimInfo && dimInfo.otherDims[visualDimension] === 0) {
|
||||
return dimensions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// get value by dimension. (only get value of itemGroupId or childGroupId, so convert it to string)
|
||||
function getValueByDimension(data, dataIndex, dimension) {
|
||||
var dimInfo = data.getDimensionInfo(dimension);
|
||||
var dimOrdinalMeta = dimInfo && dimInfo.ordinalMeta;
|
||||
if (dimInfo) {
|
||||
var value = data.get(dimInfo.name, dataIndex);
|
||||
if (dimOrdinalMeta) {
|
||||
return dimOrdinalMeta.categories[value] || value + '';
|
||||
}
|
||||
return value + '';
|
||||
}
|
||||
}
|
||||
function getGroupId(data, dataIndex, dataGroupId, isChild) {
|
||||
// try to get groupId from encode
|
||||
var visualDimension = isChild ? 'itemChildGroupId' : 'itemGroupId';
|
||||
var groupIdDim = getDimension(data, visualDimension);
|
||||
if (groupIdDim) {
|
||||
var groupId = getValueByDimension(data, dataIndex, groupIdDim);
|
||||
return groupId;
|
||||
}
|
||||
// try to get groupId from raw data item
|
||||
var rawDataItem = data.getRawDataItem(dataIndex);
|
||||
var property = isChild ? 'childGroupId' : 'groupId';
|
||||
if (rawDataItem && rawDataItem[property]) {
|
||||
return rawDataItem[property] + '';
|
||||
}
|
||||
// fallback
|
||||
if (isChild) {
|
||||
return;
|
||||
}
|
||||
// try to use series.dataGroupId as groupId, otherwise use dataItem's id as groupId
|
||||
return dataGroupId || data.getId(dataIndex);
|
||||
}
|
||||
// flatten all data items from different serieses into one arrary
|
||||
function flattenDataDiffItems(list) {
|
||||
var items = [];
|
||||
each(list, function (seriesInfo) {
|
||||
var data = seriesInfo.data;
|
||||
var dataGroupId = seriesInfo.dataGroupId;
|
||||
if (data.count() > DATA_COUNT_THRESHOLD) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn('Universal transition is disabled on large data > 10k.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
var indices = data.getIndices();
|
||||
for (var dataIndex = 0; dataIndex < indices.length; dataIndex++) {
|
||||
items.push({
|
||||
data: data,
|
||||
groupId: getGroupId(data, dataIndex, dataGroupId, false),
|
||||
childGroupId: getGroupId(data, dataIndex, dataGroupId, true),
|
||||
divide: seriesInfo.divide,
|
||||
dataIndex: dataIndex
|
||||
});
|
||||
}
|
||||
});
|
||||
return items;
|
||||
}
|
||||
function fadeInElement(newEl, newSeries, newIndex) {
|
||||
newEl.traverse(function (el) {
|
||||
if (el instanceof Path) {
|
||||
// TODO use fade in animation for target element.
|
||||
initProps(el, {
|
||||
style: {
|
||||
opacity: 0
|
||||
}
|
||||
}, newSeries, {
|
||||
dataIndex: newIndex,
|
||||
isFrom: true
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function removeEl(el) {
|
||||
if (el.parent) {
|
||||
// Bake parent transform to element.
|
||||
// So it can still have proper transform to transition after it's removed.
|
||||
var computedTransform = el.getComputedTransform();
|
||||
el.setLocalTransform(computedTransform);
|
||||
el.parent.remove(el);
|
||||
}
|
||||
}
|
||||
function stopAnimation(el) {
|
||||
el.stopAnimation();
|
||||
if (el.isGroup) {
|
||||
el.traverse(function (child) {
|
||||
child.stopAnimation();
|
||||
});
|
||||
}
|
||||
}
|
||||
function animateElementStyles(el, dataIndex, seriesModel) {
|
||||
var animationConfig = getAnimationConfig('update', seriesModel, dataIndex);
|
||||
animationConfig && el.traverse(function (child) {
|
||||
if (child instanceof Displayable) {
|
||||
var oldStyle = getOldStyle(child);
|
||||
if (oldStyle) {
|
||||
child.animateFrom({
|
||||
style: oldStyle
|
||||
}, animationConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function isAllIdSame(oldDiffItems, newDiffItems) {
|
||||
var len = oldDiffItems.length;
|
||||
if (len !== newDiffItems.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < len; i++) {
|
||||
var oldItem = oldDiffItems[i];
|
||||
var newItem = newDiffItems[i];
|
||||
if (oldItem.data.getId(oldItem.dataIndex) !== newItem.data.getId(newItem.dataIndex)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function transitionBetween(oldList, newList, api) {
|
||||
var oldDiffItems = flattenDataDiffItems(oldList);
|
||||
var newDiffItems = flattenDataDiffItems(newList);
|
||||
function updateMorphingPathProps(from, to, rawFrom, rawTo, animationCfg) {
|
||||
if (rawFrom || from) {
|
||||
to.animateFrom({
|
||||
style: rawFrom && rawFrom !== from
|
||||
// dividingMethod like clone may override the style(opacity)
|
||||
// So extend it to raw style.
|
||||
? extend(extend({}, rawFrom.style), from.style) : from.style
|
||||
}, animationCfg);
|
||||
}
|
||||
}
|
||||
var hasMorphAnimation = false;
|
||||
/**
|
||||
* With groupId and childGroupId, we can build parent-child relationships between dataItems.
|
||||
* However, we should mind the parent-child "direction" between old and new options.
|
||||
*
|
||||
* For example, suppose we have two dataItems from two series.data:
|
||||
*
|
||||
* dataA: [ dataB: [
|
||||
* { {
|
||||
* value: 5, value: 3,
|
||||
* groupId: 'creatures', groupId: 'animals',
|
||||
* childGroupId: 'animals' childGroupId: 'dogs'
|
||||
* }, },
|
||||
* ... ...
|
||||
* ] ]
|
||||
*
|
||||
* where dataA is belong to optionA and dataB is belong to optionB.
|
||||
*
|
||||
* When we `setOption(optionB)` from optionA, we choose childGroupId of dataItemA and groupId of
|
||||
* dataItemB as keys so the two keys are matched (both are 'animals'), then universalTransition
|
||||
* will work. This derection is "parent -> child".
|
||||
*
|
||||
* If we `setOption(optionA)` from optionB, we also choose groupId of dataItemB and childGroupId
|
||||
* of dataItemA as keys and universalTransition will work. This derection is "child -> parent".
|
||||
*
|
||||
* If there is no childGroupId specified, which means no multiLevelDrillDown/Up is needed and no
|
||||
* parent-child relationship exists. This direction is "none".
|
||||
*
|
||||
* So we need to know whether to use groupId or childGroupId as the key when we call the keyGetter
|
||||
* functions. Thus, we need to decide the direction first.
|
||||
*
|
||||
* The rule is:
|
||||
*
|
||||
* if (all childGroupIds in oldDiffItems and all groupIds in newDiffItems have common value) {
|
||||
* direction = 'parent -> child';
|
||||
* } else if (all groupIds in oldDiffItems and all childGroupIds in newDiffItems have common value) {
|
||||
* direction = 'child -> parent';
|
||||
* } else {
|
||||
* direction = 'none';
|
||||
* }
|
||||
*/
|
||||
var direction = TRANSITION_NONE;
|
||||
// find all groupIds and childGroupIds from oldDiffItems
|
||||
var oldGroupIds = createHashMap();
|
||||
var oldChildGroupIds = createHashMap();
|
||||
oldDiffItems.forEach(function (item) {
|
||||
item.groupId && oldGroupIds.set(item.groupId, true);
|
||||
item.childGroupId && oldChildGroupIds.set(item.childGroupId, true);
|
||||
});
|
||||
// traverse newDiffItems and decide the direction according to the rule
|
||||
for (var i = 0; i < newDiffItems.length; i++) {
|
||||
var newGroupId = newDiffItems[i].groupId;
|
||||
if (oldChildGroupIds.get(newGroupId)) {
|
||||
direction = TRANSITION_P2C;
|
||||
break;
|
||||
}
|
||||
var newChildGroupId = newDiffItems[i].childGroupId;
|
||||
if (newChildGroupId && oldGroupIds.get(newChildGroupId)) {
|
||||
direction = TRANSITION_C2P;
|
||||
break;
|
||||
}
|
||||
}
|
||||
function createKeyGetter(isOld, onlyGetId) {
|
||||
return function (diffItem) {
|
||||
var data = diffItem.data;
|
||||
var dataIndex = diffItem.dataIndex;
|
||||
// TODO if specified dim
|
||||
if (onlyGetId) {
|
||||
return data.getId(dataIndex);
|
||||
}
|
||||
if (isOld) {
|
||||
return direction === TRANSITION_P2C ? diffItem.childGroupId : diffItem.groupId;
|
||||
} else {
|
||||
return direction === TRANSITION_C2P ? diffItem.childGroupId : diffItem.groupId;
|
||||
}
|
||||
};
|
||||
}
|
||||
// Use id if it's very likely to be an one to one animation
|
||||
// It's more robust than groupId
|
||||
// TODO Check if key dimension is specified.
|
||||
var useId = isAllIdSame(oldDiffItems, newDiffItems);
|
||||
var isElementStillInChart = {};
|
||||
if (!useId) {
|
||||
// We may have different diff strategy with basicTransition if we use other dimension as key.
|
||||
// If so, we can't simply check if oldEl is same with newEl. We need a map to check if oldEl is still being used in the new chart.
|
||||
// We can't use the elements that already being morphed. Let it keep it's original basic transition.
|
||||
for (var i = 0; i < newDiffItems.length; i++) {
|
||||
var newItem = newDiffItems[i];
|
||||
var el = newItem.data.getItemGraphicEl(newItem.dataIndex);
|
||||
if (el) {
|
||||
isElementStillInChart[el.id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
function updateOneToOne(newIndex, oldIndex) {
|
||||
var oldItem = oldDiffItems[oldIndex];
|
||||
var newItem = newDiffItems[newIndex];
|
||||
var newSeries = newItem.data.hostModel;
|
||||
// TODO Mark this elements is morphed and don't morph them anymore
|
||||
var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex);
|
||||
var newEl = newItem.data.getItemGraphicEl(newItem.dataIndex);
|
||||
// Can't handle same elements.
|
||||
if (oldEl === newEl) {
|
||||
newEl && animateElementStyles(newEl, newItem.dataIndex, newSeries);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
// We can't use the elements that already being morphed
|
||||
oldEl && isElementStillInChart[oldEl.id]) {
|
||||
return;
|
||||
}
|
||||
if (newEl) {
|
||||
// TODO: If keep animating the group in case
|
||||
// some of the elements don't want to be morphed.
|
||||
// TODO Label?
|
||||
stopAnimation(newEl);
|
||||
if (oldEl) {
|
||||
stopAnimation(oldEl);
|
||||
// If old element is doing leaving animation. stop it and remove it immediately.
|
||||
removeEl(oldEl);
|
||||
hasMorphAnimation = true;
|
||||
applyMorphAnimation(getPathList(oldEl), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
|
||||
} else {
|
||||
fadeInElement(newEl, newSeries, newIndex);
|
||||
}
|
||||
}
|
||||
// else keep oldEl leaving animation.
|
||||
}
|
||||
new DataDiffer(oldDiffItems, newDiffItems, createKeyGetter(true, useId), createKeyGetter(false, useId), null, 'multiple').update(updateOneToOne).updateManyToOne(function (newIndex, oldIndices) {
|
||||
var newItem = newDiffItems[newIndex];
|
||||
var newData = newItem.data;
|
||||
var newSeries = newData.hostModel;
|
||||
var newEl = newData.getItemGraphicEl(newItem.dataIndex);
|
||||
var oldElsList = filter(map(oldIndices, function (idx) {
|
||||
return oldDiffItems[idx].data.getItemGraphicEl(oldDiffItems[idx].dataIndex);
|
||||
}), function (oldEl) {
|
||||
return oldEl && oldEl !== newEl && !isElementStillInChart[oldEl.id];
|
||||
});
|
||||
if (newEl) {
|
||||
stopAnimation(newEl);
|
||||
if (oldElsList.length) {
|
||||
// If old element is doing leaving animation. stop it and remove it immediately.
|
||||
each(oldElsList, function (oldEl) {
|
||||
stopAnimation(oldEl);
|
||||
removeEl(oldEl);
|
||||
});
|
||||
hasMorphAnimation = true;
|
||||
applyMorphAnimation(getPathList(oldElsList), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
|
||||
} else {
|
||||
fadeInElement(newEl, newSeries, newItem.dataIndex);
|
||||
}
|
||||
}
|
||||
// else keep oldEl leaving animation.
|
||||
}).updateOneToMany(function (newIndices, oldIndex) {
|
||||
var oldItem = oldDiffItems[oldIndex];
|
||||
var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex);
|
||||
// We can't use the elements that already being morphed
|
||||
if (oldEl && isElementStillInChart[oldEl.id]) {
|
||||
return;
|
||||
}
|
||||
var newElsList = filter(map(newIndices, function (idx) {
|
||||
return newDiffItems[idx].data.getItemGraphicEl(newDiffItems[idx].dataIndex);
|
||||
}), function (el) {
|
||||
return el && el !== oldEl;
|
||||
});
|
||||
var newSeris = newDiffItems[newIndices[0]].data.hostModel;
|
||||
if (newElsList.length) {
|
||||
each(newElsList, function (newEl) {
|
||||
return stopAnimation(newEl);
|
||||
});
|
||||
if (oldEl) {
|
||||
stopAnimation(oldEl);
|
||||
// If old element is doing leaving animation. stop it and remove it immediately.
|
||||
removeEl(oldEl);
|
||||
hasMorphAnimation = true;
|
||||
applyMorphAnimation(getPathList(oldEl), getPathList(newElsList), oldItem.divide,
|
||||
// Use divide on old.
|
||||
newSeris, newIndices[0], updateMorphingPathProps);
|
||||
} else {
|
||||
each(newElsList, function (newEl) {
|
||||
return fadeInElement(newEl, newSeris, newIndices[0]);
|
||||
});
|
||||
}
|
||||
}
|
||||
// else keep oldEl leaving animation.
|
||||
}).updateManyToMany(function (newIndices, oldIndices) {
|
||||
// If two data are same and both have groupId.
|
||||
// Normally they should be diff by id.
|
||||
new DataDiffer(oldIndices, newIndices, function (rawIdx) {
|
||||
return oldDiffItems[rawIdx].data.getId(oldDiffItems[rawIdx].dataIndex);
|
||||
}, function (rawIdx) {
|
||||
return newDiffItems[rawIdx].data.getId(newDiffItems[rawIdx].dataIndex);
|
||||
}).update(function (newIndex, oldIndex) {
|
||||
// Use the original index
|
||||
updateOneToOne(newIndices[newIndex], oldIndices[oldIndex]);
|
||||
}).execute();
|
||||
}).execute();
|
||||
if (hasMorphAnimation) {
|
||||
each(newList, function (_a) {
|
||||
var data = _a.data;
|
||||
var seriesModel = data.hostModel;
|
||||
var view = seriesModel && api.getViewOfSeriesModel(seriesModel);
|
||||
var animationCfg = getAnimationConfig('update', seriesModel, 0); // use 0 index.
|
||||
if (view && seriesModel.isAnimationEnabled() && animationCfg && animationCfg.duration > 0) {
|
||||
view.group.traverse(function (el) {
|
||||
if (el instanceof Path && !el.animators.length) {
|
||||
// We can't accept there still exists element that has no animation
|
||||
// if universalTransition is enabled
|
||||
el.animateFrom({
|
||||
style: {
|
||||
opacity: 0
|
||||
}
|
||||
}, animationCfg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function getSeriesTransitionKey(series) {
|
||||
var seriesKey = series.getModel('universalTransition').get('seriesKey');
|
||||
if (!seriesKey) {
|
||||
// Use series id by default.
|
||||
return series.id;
|
||||
}
|
||||
return seriesKey;
|
||||
}
|
||||
function convertArraySeriesKeyToString(seriesKey) {
|
||||
if (isArray(seriesKey)) {
|
||||
// Order independent.
|
||||
return seriesKey.sort().join(',');
|
||||
}
|
||||
return seriesKey;
|
||||
}
|
||||
function getDivideShapeFromData(data) {
|
||||
if (data.hostModel) {
|
||||
return data.hostModel.getModel('universalTransition').get('divideShape');
|
||||
}
|
||||
}
|
||||
function findTransitionSeriesBatches(globalStore, params) {
|
||||
var updateBatches = createHashMap();
|
||||
var oldDataMap = createHashMap();
|
||||
// Map that only store key in array seriesKey.
|
||||
// Which is used to query the old data when transition from one to multiple series.
|
||||
var oldDataMapForSplit = createHashMap();
|
||||
each(globalStore.oldSeries, function (series, idx) {
|
||||
var oldDataGroupId = globalStore.oldDataGroupIds[idx];
|
||||
var oldData = globalStore.oldData[idx];
|
||||
var transitionKey = getSeriesTransitionKey(series);
|
||||
var transitionKeyStr = convertArraySeriesKeyToString(transitionKey);
|
||||
oldDataMap.set(transitionKeyStr, {
|
||||
dataGroupId: oldDataGroupId,
|
||||
data: oldData
|
||||
});
|
||||
if (isArray(transitionKey)) {
|
||||
// Same key can't in different array seriesKey.
|
||||
each(transitionKey, function (key) {
|
||||
oldDataMapForSplit.set(key, {
|
||||
key: transitionKeyStr,
|
||||
dataGroupId: oldDataGroupId,
|
||||
data: oldData
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
function checkTransitionSeriesKeyDuplicated(transitionKeyStr) {
|
||||
if (updateBatches.get(transitionKeyStr)) {
|
||||
warn("Duplicated seriesKey in universalTransition " + transitionKeyStr);
|
||||
}
|
||||
}
|
||||
each(params.updatedSeries, function (series) {
|
||||
if (series.isUniversalTransitionEnabled() && series.isAnimationEnabled()) {
|
||||
var newDataGroupId = series.get('dataGroupId');
|
||||
var newData = series.getData();
|
||||
var transitionKey = getSeriesTransitionKey(series);
|
||||
var transitionKeyStr = convertArraySeriesKeyToString(transitionKey);
|
||||
// Only transition between series with same id.
|
||||
var oldData = oldDataMap.get(transitionKeyStr);
|
||||
// string transition key is the best match.
|
||||
if (oldData) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkTransitionSeriesKeyDuplicated(transitionKeyStr);
|
||||
}
|
||||
// TODO check if data is same?
|
||||
updateBatches.set(transitionKeyStr, {
|
||||
oldSeries: [{
|
||||
dataGroupId: oldData.dataGroupId,
|
||||
divide: getDivideShapeFromData(oldData.data),
|
||||
data: oldData.data
|
||||
}],
|
||||
newSeries: [{
|
||||
dataGroupId: newDataGroupId,
|
||||
divide: getDivideShapeFromData(newData),
|
||||
data: newData
|
||||
}]
|
||||
});
|
||||
} else {
|
||||
// Transition from multiple series.
|
||||
// e.g. 'female', 'male' -> ['female', 'male']
|
||||
if (isArray(transitionKey)) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkTransitionSeriesKeyDuplicated(transitionKeyStr);
|
||||
}
|
||||
var oldSeries_1 = [];
|
||||
each(transitionKey, function (key) {
|
||||
var oldData = oldDataMap.get(key);
|
||||
if (oldData.data) {
|
||||
oldSeries_1.push({
|
||||
dataGroupId: oldData.dataGroupId,
|
||||
divide: getDivideShapeFromData(oldData.data),
|
||||
data: oldData.data
|
||||
});
|
||||
}
|
||||
});
|
||||
if (oldSeries_1.length) {
|
||||
updateBatches.set(transitionKeyStr, {
|
||||
oldSeries: oldSeries_1,
|
||||
newSeries: [{
|
||||
dataGroupId: newDataGroupId,
|
||||
data: newData,
|
||||
divide: getDivideShapeFromData(newData)
|
||||
}]
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Try transition to multiple series.
|
||||
// e.g. ['female', 'male'] -> 'female', 'male'
|
||||
var oldData_1 = oldDataMapForSplit.get(transitionKey);
|
||||
if (oldData_1) {
|
||||
var batch = updateBatches.get(oldData_1.key);
|
||||
if (!batch) {
|
||||
batch = {
|
||||
oldSeries: [{
|
||||
dataGroupId: oldData_1.dataGroupId,
|
||||
data: oldData_1.data,
|
||||
divide: getDivideShapeFromData(oldData_1.data)
|
||||
}],
|
||||
newSeries: []
|
||||
};
|
||||
updateBatches.set(oldData_1.key, batch);
|
||||
}
|
||||
batch.newSeries.push({
|
||||
dataGroupId: newDataGroupId,
|
||||
data: newData,
|
||||
divide: getDivideShapeFromData(newData)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return updateBatches;
|
||||
}
|
||||
function querySeries(series, finder) {
|
||||
for (var i = 0; i < series.length; i++) {
|
||||
var found = finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id;
|
||||
if (found) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
function transitionSeriesFromOpt(transitionOpt, globalStore, params, api) {
|
||||
var from = [];
|
||||
var to = [];
|
||||
each(normalizeToArray(transitionOpt.from), function (finder) {
|
||||
var idx = querySeries(globalStore.oldSeries, finder);
|
||||
if (idx >= 0) {
|
||||
from.push({
|
||||
dataGroupId: globalStore.oldDataGroupIds[idx],
|
||||
data: globalStore.oldData[idx],
|
||||
// TODO can specify divideShape in transition.
|
||||
divide: getDivideShapeFromData(globalStore.oldData[idx]),
|
||||
groupIdDim: finder.dimension
|
||||
});
|
||||
}
|
||||
});
|
||||
each(normalizeToArray(transitionOpt.to), function (finder) {
|
||||
var idx = querySeries(params.updatedSeries, finder);
|
||||
if (idx >= 0) {
|
||||
var data = params.updatedSeries[idx].getData();
|
||||
to.push({
|
||||
dataGroupId: globalStore.oldDataGroupIds[idx],
|
||||
data: data,
|
||||
divide: getDivideShapeFromData(data),
|
||||
groupIdDim: finder.dimension
|
||||
});
|
||||
}
|
||||
});
|
||||
if (from.length > 0 && to.length > 0) {
|
||||
transitionBetween(from, to, api);
|
||||
}
|
||||
}
|
||||
export function installUniversalTransition(registers) {
|
||||
registers.registerUpdateLifecycle('series:beforeupdate', function (ecMOdel, api, params) {
|
||||
each(normalizeToArray(params.seriesTransition), function (transOpt) {
|
||||
each(normalizeToArray(transOpt.to), function (finder) {
|
||||
var series = params.updatedSeries;
|
||||
for (var i = 0; i < series.length; i++) {
|
||||
if (finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id) {
|
||||
series[i][SERIES_UNIVERSAL_TRANSITION_PROP] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
registers.registerUpdateLifecycle('series:transition', function (ecModel, api, params) {
|
||||
// TODO api provide an namespace that can save stuff per instance
|
||||
var globalStore = getUniversalTransitionGlobalStore(api);
|
||||
// TODO multiple to multiple series.
|
||||
if (globalStore.oldSeries && params.updatedSeries && params.optionChanged) {
|
||||
// TODO transitionOpt was used in an old implementation and can be removed now
|
||||
// Use give transition config if its' give;
|
||||
var transitionOpt = params.seriesTransition;
|
||||
if (transitionOpt) {
|
||||
each(normalizeToArray(transitionOpt), function (opt) {
|
||||
transitionSeriesFromOpt(opt, globalStore, params, api);
|
||||
});
|
||||
} else {
|
||||
// Else guess from series based on transition series key.
|
||||
var updateBatches_1 = findTransitionSeriesBatches(globalStore, params);
|
||||
each(updateBatches_1.keys(), function (key) {
|
||||
var batch = updateBatches_1.get(key);
|
||||
transitionBetween(batch.oldSeries, batch.newSeries, api);
|
||||
});
|
||||
}
|
||||
// Reset
|
||||
each(params.updatedSeries, function (series) {
|
||||
// Reset;
|
||||
if (series[SERIES_UNIVERSAL_TRANSITION_PROP]) {
|
||||
series[SERIES_UNIVERSAL_TRANSITION_PROP] = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Save all series of current update. Not only the updated one.
|
||||
var allSeries = ecModel.getSeries();
|
||||
var savedSeries = globalStore.oldSeries = [];
|
||||
var savedDataGroupIds = globalStore.oldDataGroupIds = [];
|
||||
var savedData = globalStore.oldData = [];
|
||||
for (var i = 0; i < allSeries.length; i++) {
|
||||
var data = allSeries[i].getData();
|
||||
// Only save the data that can have transition.
|
||||
// Avoid large data costing too much extra memory
|
||||
if (data.count() < DATA_COUNT_THRESHOLD) {
|
||||
savedSeries.push(allSeries[i]);
|
||||
savedDataGroupIds.push(allSeries[i].get('dataGroupId'));
|
||||
savedData.push(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user