逐步完成前后端服务器
This commit is contained in:
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