You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2021/06/18 11:06:20 UTC

[echarts] 01/03: feat(ut): handle setOption transition in ut module.

This is an automated email from the ASF dual-hosted git repository.

shenyi pushed a commit to branch enhance-morph
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 8dd75b29337ec786d3ee9f8d4cb31cd0f5d84b5d
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Jun 18 11:35:09 2021 +0800

    feat(ut): handle setOption transition in ut module.
    
    custom always create new but keep animation when niversalTransition is enabled.
---
 src/animation/universalTransition.ts | 37 +++++++++++++++++++++-
 src/chart/custom/CustomView.ts       | 59 +++++++++++++++---------------------
 src/core/echarts.ts                  | 22 +-------------
 3 files changed, 61 insertions(+), 57 deletions(-)

diff --git a/src/animation/universalTransition.ts b/src/animation/universalTransition.ts
index fa96d2f..de67444 100644
--- a/src/animation/universalTransition.ts
+++ b/src/animation/universalTransition.ts
@@ -19,7 +19,7 @@
 
 // Universal transitions that can animate between any shapes(series) and any properties in any amounts.
 
-import SeriesModel from '../model/Series';
+import SeriesModel, { SERIES_UNIVERSAL_TRANSITION_PROP } from '../model/Series';
 import {createHashMap, each, map, filter, isArray, find} from 'zrender/src/core/util';
 import Element, { ElementAnimateConfig } from 'zrender/src/Element';
 import { applyMorphAnimation, getPathList } from './morphTransitionHelper';
@@ -35,6 +35,7 @@ import {
     UpdateLifecycleTransitionSeriesFinder
 } from '../core/lifecycle';
 import { normalizeToArray } from '../util/model';
+import { warn } from '../util/log';
 
 interface DiffItem {
     data: List
@@ -361,6 +362,12 @@ function findTransitionSeriesBatches(params: UpdateLifecycleParams) {
             });
         }
     });
+
+    function checkTransitionSeriesKeyDuplicated(transitionKeyStr: string) {
+        if (updateBatches.get(transitionKeyStr)) {
+            warn(`Duplicated seriesKey in universalTransition ${transitionKeyStr}`);
+        }
+    }
     each(params.updatedSeries, series => {
         if (series.get(['universalTransition', 'enabled'])) {
             const newData = series.getData();
@@ -370,6 +377,9 @@ function findTransitionSeriesBatches(params: UpdateLifecycleParams) {
             const oldData = oldDataMap.get(transitionKeyStr);
             // string transition key is the best match.
             if (oldData) {
+                if (__DEV__) {
+                    checkTransitionSeriesKeyDuplicated(transitionKeyStr);
+                }
                 // TODO check if data is same?
                 updateBatches.set(transitionKeyStr, {
                     oldSeries: [{
@@ -383,6 +393,9 @@ function findTransitionSeriesBatches(params: UpdateLifecycleParams) {
             if (!oldData) {
                 // Transition from multiple series.
                 if (isArray(transitionKey)) {
+                    if (__DEV__) {
+                        checkTransitionSeriesKeyDuplicated(transitionKeyStr);
+                    }
                     const oldSeries: TransitionSeries[] = [];
                     each(transitionKey, key => {
                         const oldData = oldDataMap.get(key);
@@ -460,6 +473,20 @@ function transitionSeriesFromOpt(transitionOpt: UpdateLifecycleTransitionItem, p
 }
 
 export function installUniversalTransition(registers: EChartsExtensionInstallRegisters) {
+
+    registers.registerUpdateLifecycle('series:beforeupdate', (ecMOdel, api, params) => {
+        each(normalizeToArray(params.seriesTransition), transOpt => {
+            each(normalizeToArray(transOpt.to), (finder) => {
+                const series = params.updatedSeries;
+                for (let 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', (ecModel, api, params) => {
         // TODO multiple to multiple series.
         if (params.oldSeries && params.updatedSeries) {
@@ -477,6 +504,14 @@ export function installUniversalTransition(registers: EChartsExtensionInstallReg
                     transitionBetween(batch.oldSeries, batch.newSeries);
                 });
             }
+
+            // Reset
+            each(params.updatedSeries, series => {
+                // Reset;
+                if (series[SERIES_UNIVERSAL_TRANSITION_PROP]) {
+                    series[SERIES_UNIVERSAL_TRANSITION_PROP] = false;
+                }
+            });
         }
     });
 }
\ No newline at end of file
diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts
index 79004ed..b264d80 100644
--- a/src/chart/custom/CustomView.ts
+++ b/src/chart/custom/CustomView.ts
@@ -100,6 +100,7 @@ import {
     prepareTransformAllPropsFinal,
     prepareTransformTransitionFrom
 } from './prepare';
+import { SeriesModel } from '../../export/api';
 
 const transformPropNamesStr = keys(TRANSFORM_PROPS).join(', ');
 
@@ -216,40 +217,25 @@ export default class CustomChartView extends ChartView {
             group.removeAll();
         }
 
-        if (customSeries.isUniversalTransitionEnabled()) {
-            // Always create new if universalTransition is enabled.
-            // So the old will not be replaced and can be transition later.
-            // TODO check if UniversalTransition feature is installed.
-            oldData && oldData.each(function (oldIdx) {
+        data.diff(oldData)
+            .add(function (newIdx) {
+                createOrUpdateItem(
+                    api, null, newIdx, renderItem(newIdx, payload), customSeries, group,
+                    data
+                );
+            })
+            .remove(function (oldIdx) {
                 doRemoveEl(oldData.getItemGraphicEl(oldIdx), customSeries, group);
-            });
-            data.each(function (newIdx) {
+            })
+            .update(function (newIdx, oldIdx) {
+                const oldEl = oldData.getItemGraphicEl(oldIdx);
+
                 createOrUpdateItem(
-                    api, null, newIdx, renderItem(newIdx, payload), customSeries, group, data
+                    api, oldEl, newIdx, renderItem(newIdx, payload), customSeries, group,
+                    data
                 );
-            });
-        }
-        else {
-            data.diff(oldData)
-                .add(function (newIdx) {
-                    createOrUpdateItem(
-                        api, null, newIdx, renderItem(newIdx, payload), customSeries, group,
-                        data
-                    );
-                })
-                .remove(function (oldIdx) {
-                    doRemoveEl(oldData.getItemGraphicEl(oldIdx), customSeries, group);
-                })
-                .update(function (newIdx, oldIdx) {
-                    const oldEl = oldData.getItemGraphicEl(oldIdx);
-
-                    createOrUpdateItem(
-                        api, oldEl, newIdx, renderItem(newIdx, payload), customSeries, group,
-                        data
-                    );
-                })
-                .execute();
-        }
+            })
+            .execute();
 
         // Do clipping
         const clipPath = customSeries.get('clip', true)
@@ -1191,7 +1177,7 @@ function doCreateOrUpdateEl(
     const oldEl = existsEl;
     if (
         existsEl && (
-            doesElNeedRecreate(existsEl, elOption)
+            doesElNeedRecreate(existsEl, elOption, seriesModel)
             // || (
             //     // PENDING: even in one-to-one mapping case, if el is marked as morph,
             //     // do not sure whether the el will be mapped to another el with different
@@ -1283,14 +1269,17 @@ function doCreateOrUpdateEl(
 }
 
 // `el` must not be null/undefined.
-function doesElNeedRecreate(el: Element, elOption: CustomElementOption): boolean {
+function doesElNeedRecreate(el: Element, elOption: CustomElementOption, seriesModel: SeriesModel): boolean {
     const elInner = customInnerStore(el);
     const elOptionType = elOption.type;
     const elOptionShape = (elOption as CustomZRPathOption).shape;
     const elOptionStyle = elOption.style;
     return (
+        // Always create new if universal transition is enabled.
+        // Because we do transition after render. It needs to know what old element is. Replacement will loose it.
+        seriesModel.isUniversalTransitionEnabled()
         // If `elOptionType` is `null`, follow the merge principle.
-        (elOptionType != null
+        || (elOptionType != null
             && elOptionType !== elInner.customGraphicType
         )
         || (elOptionType === 'path'
@@ -1327,7 +1316,7 @@ function doCreateOrUpdateClipPath(
     }
     else if (clipPathOpt) {
         let clipPath = el.getClipPath();
-        if (clipPath && doesElNeedRecreate(clipPath, clipPathOpt)) {
+        if (clipPath && doesElNeedRecreate(clipPath, clipPathOpt, seriesModel)) {
             clipPath = null;
         }
         if (!clipPath) {
diff --git a/src/core/echarts.ts b/src/core/echarts.ts
index cf00d17..35fee84 100644
--- a/src/core/echarts.ts
+++ b/src/core/echarts.ts
@@ -49,7 +49,7 @@ import OptionManager from '../model/OptionManager';
 import backwardCompat from '../preprocessor/backwardCompat';
 import dataStack from '../processor/dataStack';
 import ComponentModel from '../model/Component';
-import SeriesModel, { SERIES_UNIVERSAL_TRANSITION_PROP } from '../model/Series';
+import SeriesModel from '../model/Series';
 import ComponentView, {ComponentViewConstructor} from '../view/Component';
 import ChartView, {ChartViewConstructor} from '../view/Chart';
 import * as graphic from '../util/graphic';
@@ -105,7 +105,6 @@ import {
     ComponentSubType,
     ColorString,
     SelectChangedPayload,
-    DimensionLoose,
     ScaleDataValue,
     ZRElementEventName,
     ECElementEvent,
@@ -618,20 +617,6 @@ class ECharts extends Eventful<ECEventDefinition> {
 
         this._model.setOption(option as ECBasicOption, { replaceMerge }, optionPreprocessorFuncs);
 
-        if (transitionOpt) {
-            each(modelUtil.normalizeToArray(transitionOpt), transOpt => {
-                each(modelUtil.normalizeToArray(transOpt.to), (finder) => {
-                    const series = this._model.getSeries();
-                    for (let 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;
-                        }
-                    }
-                });
-            });
-        }
-
         const updateParams = {
             oldSeries: oldSeriesModels,
             oldData: oldSeriesData,
@@ -2078,11 +2063,6 @@ class ECharts extends Eventful<ECEventDefinition> {
                     unfinished = true;
                 }
 
-                // Reset;
-                if (seriesModel[SERIES_UNIVERSAL_TRANSITION_PROP]) {
-                    seriesModel[SERIES_UNIVERSAL_TRANSITION_PROP] = false;
-                }
-
                 chartView.group.silent = !!seriesModel.get('silent');
                 // Should not call markRedraw on group, because it will disable zrender
                 // increamental render (alway render from the __startIndex each frame)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org