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 d6cb3b4feb771c3a3bdf05289beff6ca62aa8eea
Author: pissang <bm2736...@gmail.com>
AuthorDate: Sun Jan 24 20:27:18 2021 +0800

    refact(custom): optimize morph transition
---
 src/chart/custom/CustomSeries.ts |   3 +-
 src/chart/custom/CustomView.ts   | 144 ++++++++++++++++++++++-----------------
 src/chart/custom/prepare.ts      |   6 +-
 src/util/graphic.ts              |   1 +
 4 files changed, 87 insertions(+), 67 deletions(-)

diff --git a/src/chart/custom/CustomSeries.ts b/src/chart/custom/CustomSeries.ts
index 58c0da8..c3b94f2 100644
--- a/src/chart/custom/CustomSeries.ts
+++ b/src/chart/custom/CustomSeries.ts
@@ -301,8 +301,7 @@ export const customInnerStore = makeInner<{
     leaveToProps: ElementProps;
     // Can morph: "morph" specified in option and el is Path.
     morph: boolean;
-    propsToSet: ElementProps;
-    propsToAnimate: ElementProps;
+    option: CustomElementOption;
     userDuring: CustomBaseElementOption['during'];
 }, Element>();
 
diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts
index 7958fa9..c6fc280 100644
--- a/src/chart/custom/CustomView.ts
+++ b/src/chart/custom/CustomView.ts
@@ -101,6 +101,8 @@ import {
     prepareTransformAllPropsFinal,
     prepareTransformTransitionFrom
 } from './prepare';
+import { SeriesModel } from '../../export/api';
+import { seriesStyleTask } from '../../visual/style';
 
 const transformPropNamesStr = keys(TRANSFORM_PROPS).join(', ');
 
@@ -203,11 +205,19 @@ export default class CustomChartView extends ChartView {
             from: graphicUtil.Path, to: graphicUtil.Path, rawFrom: 
graphicUtil.Path, rawTo: graphicUtil.Path
         ) {
             // element has been updated if rawTo is same with to.
-            if (to !== rawTo) {
-                applyPropsDirectly(to, customInnerStore(rawTo).propsToSet);
-                applyPropsTransition(
-                    to, dataIndex, customSeries, 
customInnerStore(rawTo).propsToAnimate, false
-                );
+            const elOption = customInnerStore(rawTo).option;
+            if (elOption) {
+                const transFromProps = {} as ElementProps;
+                const propsToSet = {} as ElementProps;
+                const styleOpt = elOption.style;
+                prepareShapeOrExtraTransitionFrom('extra', rawFrom, elOption, 
transFromProps, false);
+                prepareShapeOrExtraAllPropsFinal('extra', elOption, 
propsToSet);
+                prepareStyleTransitionFrom(rawFrom, elOption, styleOpt, 
transFromProps, false);
+                (propsToSet as DisplayableProps).style = styleOpt;
+
+                applyPropsDirectly(to, propsToSet);
+                applyPropsTransition(to, dataIndex, customSeries, 
transFromProps, false);
+                applyMiscProps(to, elOption, false);
             }
         }
 
@@ -219,7 +229,7 @@ export default class CustomChartView extends ChartView {
             });
             data.each(function (newIdx) {
                 createOrUpdateItem(
-                    api, null, newIdx, renderItem(newIdx, payload), 
customSeries, group, data
+                    api, null, false, newIdx, renderItem(newIdx, payload), 
customSeries, group, data
                 );
             });
         }
@@ -238,7 +248,7 @@ export default class CustomChartView extends ChartView {
             ))
             .add(function (newIdx) {
                 createOrUpdateItem(
-                    api, null, newIdx, renderItem(newIdx, payload), 
customSeries, group,
+                    api, null, false, newIdx, renderItem(newIdx, payload), 
customSeries, group,
                     data
                 );
             })
@@ -251,11 +261,11 @@ export default class CustomChartView extends ChartView {
                 const oldPathList = getPathList(oldEl);
 
                 const newEl = createOrUpdateItem(
-                    api, oldEl, newIdx, renderItem(newIdx, payload), 
customSeries, group,
+                    api, oldEl, oldPathList.length > 0, newIdx, 
renderItem(newIdx, payload), customSeries, group,
                     data
                 );
 
-                const newPathList = getPathList(newEl);
+                const newPathList = getPathList(newEl, true);
                 applyMorphAnimation(
                     oldPathList, newPathList, customSeries, newIdx, 
curry(updateMorphingPathProps, newIdx)
                 );
@@ -273,13 +283,13 @@ export default class CustomChartView extends ChartView {
                 const updateMorphingPathPropsWithIdx = 
curry(updateMorphingPathProps, newIdx);
 
                 const newEl = createOrUpdateItem(
-                    api, null, newIdx, renderItem(newIdx, payload), 
customSeries, group,
+                    api, null, oldElList.length > 0, newIdx, 
renderItem(newIdx, payload), customSeries, group,
                     data
                 );
 
-                const newPathLiat = getPathList(newEl);
+                const newPathList = getPathList(newEl, true);
                 applyMorphAnimation(
-                    oldPathList, newPathLiat, customSeries, newIdx, 
updateMorphingPathPropsWithIdx
+                    oldPathList, newPathList, customSeries, newIdx, 
updateMorphingPathPropsWithIdx
                 );
             })
             .updateOneToMany(function (newIndices, oldIdx) {
@@ -292,17 +302,18 @@ export default class CustomChartView extends ChartView {
                 const newElList = [];
                 for (let i = 0; i < newLen; i++) {
                     newElList.push(createOrUpdateItem(
-                        api, null, newIndices[i], renderItem(newIndices[i], 
payload), customSeries, group,
+                        api, null, oldPathList.length > 0,
+                        newIndices[i], renderItem(newIndices[i], payload), 
customSeries, group,
                         data
                     ));
                 }
 
-                const newPathLiat = getPathList(newElList);
+                const newPathList = getPathList(newElList, true);
 
                 // TODO Different animation config in different indices?
                 const updateMorphingPathPropsWithIdx = 
curry(updateMorphingPathProps, newIndices[0]);
                 applyMorphAnimation(
-                    oldPathList, newPathLiat, customSeries, newIndices[0], 
updateMorphingPathPropsWithIdx
+                    oldPathList, newPathList, customSeries, newIndices[0], 
updateMorphingPathPropsWithIdx
                 );
             })
             .execute();
@@ -348,7 +359,7 @@ export default class CustomChartView extends ChartView {
         }
         for (let idx = params.start; idx < params.end; idx++) {
             const el = createOrUpdateItem(
-                null, null, idx, renderItem(idx, payload), customSeries, 
this.group, data
+                null, null, false, idx, renderItem(idx, payload), 
customSeries, this.group, data
             );
             el.traverse(setIncrementalAndHoverLayer);
         }
@@ -531,29 +542,11 @@ function updateElNormal(
     el: Element,
     dataIndex: number,
     elOption: CustomElementOption,
-    styleOpt: CustomElementOption['style'],
     attachedTxInfo: AttachedTxInfo,
     seriesModel: CustomSeriesModel,
     isInit: boolean,
     isTextContent: boolean
 ): void {
-    const transFromProps = {} as ElementProps;
-    const propsToSet = {} as ElementProps;
-
-    // TODO el may can't be morphed
-    const willMorph = customInnerStore(el).morph;
-    if (willMorph) {
-        (el as graphicUtil.Path).attr('shape', (elOption as 
CustomZRPathOption).shape);
-    }
-    else {
-        prepareShapeOrExtraTransitionFrom('shape', el, elOption, 
transFromProps, isInit);
-        prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
-    }
-
-    prepareShapeOrExtraTransitionFrom('extra', el, elOption, transFromProps, 
isInit);
-    prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet);
-    prepareTransformTransitionFrom(el, elOption, transFromProps, isInit);
-    prepareTransformAllPropsFinal(el, elOption, propsToSet);
 
     const txCfgOpt = attachedTxInfo && attachedTxInfo.normal.cfg;
     if (txCfgOpt) {
@@ -562,18 +555,21 @@ function updateElNormal(
         el.setTextConfig(txCfgOpt);
     }
 
-    if (el.type === 'text' && styleOpt) {
-        const textOptionStyle = styleOpt as TextStyleProps;
-        // Compatible with ec4: if `textFill` or `textStroke` exists use them.
-        hasOwn(textOptionStyle, 'textFill') && (
-            textOptionStyle.fill = (textOptionStyle as any).textFill
-        );
-        hasOwn(textOptionStyle, 'textStroke') && (
-            textOptionStyle.stroke = (textOptionStyle as any).textStroke
-        );
-    }
+    // Do some normalization on style.
+    const styleOpt = elOption && elOption.style;
 
     if (styleOpt) {
+        if (el.type === 'text') {
+            const textOptionStyle = styleOpt as TextStyleProps;
+            // Compatible with ec4: if `textFill` or `textStroke` exists use 
them.
+            hasOwn(textOptionStyle, 'textFill') && (
+                textOptionStyle.fill = (textOptionStyle as any).textFill
+            );
+            hasOwn(textOptionStyle, 'textStroke') && (
+                textOptionStyle.stroke = (textOptionStyle as any).textStroke
+            );
+        }
+
         let decalPattern;
         const decalObj = isPath(el) ? (styleOpt as 
CustomZRPathOption['style']).decal : null;
         if (api && decalObj) {
@@ -584,18 +580,36 @@ function updateElNormal(
         (styleOpt as CustomZRPathOption['style']).__decalPattern = 
decalPattern;
     }
 
-    prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps, isInit);
-
     // Save the meta info for further morphing. Like apply on the sub morphing 
elements.
     const store = customInnerStore(el);
-    store.propsToSet = propsToSet;
-    store.propsToAnimate = transFromProps;
     store.userDuring = elOption.during;
 
-    (propsToSet as DisplayableProps).style = styleOpt;
-    applyPropsDirectly(el, propsToSet);
-    applyPropsTransition(el, dataIndex, seriesModel, transFromProps, isInit);
-    applyMiscProps(el, elOption, isTextContent);
+    // TODO el may can't be morphed
+    const willMorph = customInnerStore(el).morph;
+    const transFromProps = {} as ElementProps;
+    const propsToSet = {} as ElementProps;
+
+    if (!willMorph) {
+        prepareShapeOrExtraTransitionFrom('shape', el, elOption, 
transFromProps, isInit);
+        prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
+        prepareTransformTransitionFrom(el, elOption, transFromProps, isInit);
+        prepareTransformAllPropsFinal(el, elOption, propsToSet);
+        prepareShapeOrExtraTransitionFrom('extra', el, elOption, 
transFromProps, isInit);
+        prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet);
+        prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps, 
isInit);
+        (propsToSet as DisplayableProps).style = styleOpt;
+        applyPropsDirectly(el, propsToSet);
+        applyPropsTransition(el, dataIndex, seriesModel, transFromProps, 
isInit);
+        applyMiscProps(el, elOption, isTextContent);
+    }
+    else {
+        // Needs shape and transform info in morphing.
+        prepareTransformAllPropsFinal(el, elOption, propsToSet);
+        prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
+        applyPropsDirectly(el, propsToSet);
+
+        store.option = elOption;
+    }
 
     styleOpt ? el.dirty() : el.markRedraw();
 }
@@ -888,8 +902,7 @@ function updateElOnState(
 function updateZ(
     el: Element,
     elOption: CustomElementOption,
-    seriesModel: CustomSeriesModel,
-    attachedTxInfo: AttachedTxInfo
+    seriesModel: CustomSeriesModel
 ): void {
     // Group not support textContent and not support z yet.
     if (el.isGroup) {
@@ -1252,6 +1265,7 @@ function wrapEncodeDef(data: List<CustomSeriesModel>): 
WrapEncodeDefRet {
 function createOrUpdateItem(
     api: ExtensionAPI,
     existsEl: Element,
+    hasMorphFrom: boolean,
     dataIndex: number,
     elOption: CustomElementOption,
     seriesModel: CustomSeriesModel,
@@ -1270,7 +1284,7 @@ function createOrUpdateItem(
         group.remove(existsEl);
         return;
     }
-    const el = doCreateOrUpdateEl(api, existsEl, dataIndex, elOption, 
seriesModel, group, true);
+    const el = doCreateOrUpdateEl(api, existsEl, hasMorphFrom, dataIndex, 
elOption, seriesModel, group, true);
     el && data.setItemGraphicEl(dataIndex, el);
 
     enableHoverEmphasis(el, elOption.focus, elOption.blurScope);
@@ -1281,6 +1295,7 @@ function createOrUpdateItem(
 function doCreateOrUpdateEl(
     api: ExtensionAPI,
     existsEl: Element,
+    hasMorphFrom: boolean,
     dataIndex: number,
     elOption: CustomElementOption,
     seriesModel: CustomSeriesModel,
@@ -1325,7 +1340,8 @@ function doCreateOrUpdateEl(
         // do not clearState but update cached normal state directly.
         el.clearStates();
     }
-    const morph = customInnerStore(el).morph = isPath(el)
+    const morph = customInnerStore(el).morph =
+        hasMorphFrom && isPath(el)
         && (elOption as CustomZRPathOption).morph
         // Don't need morph if element type are same.
         // shaping transition is enough
@@ -1355,7 +1371,6 @@ function doCreateOrUpdateEl(
         el,
         dataIndex,
         elOption,
-        elOption.style,
         attachedTxInfoTmp,
         seriesModel,
         isInit,
@@ -1371,11 +1386,11 @@ function doCreateOrUpdateEl(
         }
     }
 
-    updateZ(el, elOption, seriesModel, attachedTxInfoTmp);
+    updateZ(el, elOption, seriesModel);
 
     if (elOption.type === 'group') {
         mergeChildren(
-            api, el as graphicUtil.Group, dataIndex, elOption as 
CustomGroupOption, seriesModel
+            api, el as graphicUtil.Group, hasMorphFrom, dataIndex, elOption as 
CustomGroupOption, seriesModel
         );
     }
 
@@ -1448,7 +1463,7 @@ function doCreateOrUpdateClipPath(
             el.setClipPath(clipPath);
         }
         updateElNormal(
-            null, clipPath, dataIndex, clipPathOpt, null, null, seriesModel, 
isInit, false
+            null, clipPath, dataIndex, clipPathOpt, null, seriesModel, isInit, 
false
         );
     }
     // If not define `clipPath` in option, do nothing unnecessary.
@@ -1498,11 +1513,11 @@ function doCreateOrUpdateAttachedTx(
                 // do not clearState but update cached normal state directly.
                 textContent.clearStates();
             }
-            const txConStlOptNormal = txConOptNormal && txConOptNormal.style;
 
             updateElNormal(
-                null, textContent, dataIndex, txConOptNormal, 
txConStlOptNormal, null, seriesModel, isInit, true
+                null, textContent, dataIndex, txConOptNormal, null, 
seriesModel, isInit, true
             );
+            const txConStlOptNormal = txConOptNormal && txConOptNormal.style;
             for (let i = 0; i < STATES.length; i++) {
                 const stateName = STATES[i];
                 if (stateName !== NORMAL) {
@@ -1610,6 +1625,7 @@ function retrieveStyleOptionOnState(
 function mergeChildren(
     api: ExtensionAPI,
     el: graphicUtil.Group,
+    hasMorphFrom: boolean,
     dataIndex: number,
     elOption: CustomGroupOption,
     seriesModel: CustomSeriesModel
@@ -1634,6 +1650,7 @@ function mergeChildren(
             newChildren: newChildren || [],
             dataIndex: dataIndex,
             seriesModel: seriesModel,
+            hasMorphFrom,
             group: el
         });
         return;
@@ -1648,6 +1665,7 @@ function mergeChildren(
         newChildren[index] && doCreateOrUpdateEl(
             api,
             el.childAt(index),
+            hasMorphFrom,
             dataIndex,
             newChildren[index],
             seriesModel,
@@ -1669,6 +1687,7 @@ type DiffGroupContext = {
     newChildren: CustomElementOption[];
     dataIndex: number;
     seriesModel: CustomSeriesModel;
+    hasMorphFrom: boolean
     group: graphicUtil.Group;
 };
 function diffGroupChildren(context: DiffGroupContext) {
@@ -1702,6 +1721,7 @@ function processAddUpdate(
     doCreateOrUpdateEl(
         context.api,
         child,
+        context.hasMorphFrom,
         context.dataIndex,
         childOption,
         context.seriesModel,
diff --git a/src/chart/custom/prepare.ts b/src/chart/custom/prepare.ts
index eb1af0d..2bb730b 100644
--- a/src/chart/custom/prepare.ts
+++ b/src/chart/custom/prepare.ts
@@ -83,7 +83,7 @@ function setTransformPropToTransitionFrom(
 // See [STRATEGY_TRANSITION]
 export function prepareShapeOrExtraTransitionFrom(
     mainAttr: 'shape' | 'extra',
-    el: Element,
+    fromEl: Element,
     elOption: CustomElementOption,
     transFromProps: LooseElementProps,
     isInit: boolean
@@ -94,7 +94,7 @@ export function prepareShapeOrExtraTransitionFrom(
         return;
     }
 
-    const elPropsInAttr = (el as LooseElementProps)[mainAttr];
+    const elPropsInAttr = (fromEl as LooseElementProps)[mainAttr];
     let transFromPropsInAttr: Dictionary<unknown>;
 
     const enterFrom = attrOpt.enterFrom;
@@ -139,7 +139,7 @@ export function prepareShapeOrExtraTransitionFrom(
 
     const leaveTo = attrOpt.leaveTo;
     if (leaveTo) {
-        const leaveToProps = getOrCreateLeaveToPropsFromEl(el);
+        const leaveToProps = getOrCreateLeaveToPropsFromEl(fromEl);
         const leaveToPropsInAttr: Dictionary<unknown> = leaveToProps[mainAttr] 
|| (leaveToProps[mainAttr] = {});
         const leaveToKeys = keys(leaveTo);
         for (let i = 0; i < leaveToKeys.length; i++) {
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 0b14435..5500497 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -388,6 +388,7 @@ function animateOrSetProps<Props>(
                         easing: animationEasing,
                         done: cb,
                         force: !!cb || !!during,
+                        setToFinal: true,
                         scope: animationType,
                         during: during
                     })


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

Reply via email to