You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2020/09/28 05:13:15 UTC

[incubator-echarts] branch custom-morph2 updated: feature: custom series support transition: ['shape', 'style', 'extra']

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

sushuang pushed a commit to branch custom-morph2
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git


The following commit(s) were added to refs/heads/custom-morph2 by this push:
     new 0d0ecbf  feature: custom series support transition: ['shape', 'style', 'extra']
0d0ecbf is described below

commit 0d0ecbfda47cb95bf231efc8368cac82b0ee3eb9
Author: 100pah <su...@gmail.com>
AuthorDate: Mon Sep 28 03:09:31 2020 +0800

    feature: custom series support transition: ['shape', 'style', 'extra']
---
 src/chart/custom.ts              | 167 ++++++++++++++++++++++++++-------------
 test/custom-shape-morphing2.html |  37 +++++----
 2 files changed, 131 insertions(+), 73 deletions(-)

diff --git a/src/chart/custom.ts b/src/chart/custom.ts
index e37e1d7..58d2d8d 100644
--- a/src/chart/custom.ts
+++ b/src/chart/custom.ts
@@ -19,7 +19,7 @@
 
 import {
     hasOwn, assert, isString, retrieve2, retrieve3, defaults, each,
-    keys, isArrayLike, bind, isFunction, eqNaN
+    keys, isArrayLike, bind, isFunction, eqNaN, isArray, indexOf
 } from 'zrender/src/core/util';
 import * as graphicUtil from '../util/graphic';
 import { setDefaultStateProxy, enableHoverEmphasis } from '../util/states';
@@ -106,22 +106,22 @@ const TRANSFORM_PROPS = {
     originY: 1,
     rotation: 1
 } as const;
-type TransformProps = keyof typeof TRANSFORM_PROPS;
+type TransformProp = keyof typeof TRANSFORM_PROPS;
 const transformPropNamesStr = keys(TRANSFORM_PROPS).join(', ');
 
-type TransitionAnyProps = string | string[];
-type TransitionTransformProps = TransformProps | TransformProps[];
 // Do not declare "Dictionary" in TransitionAnyOption to restrict the type check.
 type TransitionAnyOption = {
     transition?: TransitionAnyProps;
     enterFrom?: Dictionary<unknown>;
     leaveTo?: Dictionary<unknown>;
 };
+type TransitionAnyProps = string | string[];
 type TransitionTransformOption = {
-    transition?: TransitionTransformProps;
+    transition?: ElementRootTransitionProp | ElementRootTransitionProp[];
     enterFrom?: Dictionary<unknown>;
     leaveTo?: Dictionary<unknown>;
 };
+type ElementRootTransitionProp = TransformProp | 'shape' | 'extra' | 'style';
 type ShapeMorphingOption = {
     /**
      * If do shape morphing animation when type is changed.
@@ -131,7 +131,7 @@ type ShapeMorphingOption = {
 };
 
 interface CustomBaseElementOption extends Partial<Pick<
-    Element, TransformProps | 'silent' | 'ignore' | 'textConfig'
+    Element, TransformProp | 'silent' | 'ignore' | 'textConfig'
 >>, TransitionTransformOption {
     // element type, mandatory.
     type: string;
@@ -162,7 +162,7 @@ interface CustomDisplayableOption extends CustomBaseElementOption, Partial<Pick<
     select?: CustomDisplayableOptionOnState;
 }
 interface CustomDisplayableOptionOnState extends Partial<Pick<
-    Displayable, TransformProps | 'textConfig' | 'z2'
+    Displayable, TransformProp | 'textConfig' | 'z2'
 >> {
     // `false` means remove emphasis trigger.
     style?: (ZRStyleProps & TransitionAnyOption) | false;
@@ -781,7 +781,7 @@ function updateElNormal(
         );
     }
 
-    prepareStyleUpdate(el, morphingFromEl, styleOpt, transFromProps, isInit);
+    prepareStyleUpdate(el, morphingFromEl, elOption, styleOpt, transFromProps, isInit);
 
     if (elDisplayable) {
         // PENDING: here the input style object is used directly.
@@ -885,19 +885,34 @@ function prepareShapeOrExtraUpdate(
         }
     }
 
-    if (!isInit && elPropsInAttr && attrOpt.transition
-        && !(morphingFromEl && mainAttr === 'shape')    // Just ignore shape animation in morphing.
+    if (!isInit
+        && elPropsInAttr
+        // Just ignore shape animation in morphing.
+        && !(morphingFromEl && mainAttr === 'shape')
     ) {
-        !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
-        const transitionKeys = normalizeToArray(attrOpt.transition);
-        for (let i = 0; i < transitionKeys.length; i++) {
-            const key = transitionKeys[i];
-            const elVal = elPropsInAttr[key];
-            if (__DEV__) {
-                checkTansitionRefer(key, (attrOpt as any)[key], elVal);
+        if (attrOpt.transition) {
+            !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
+            const transitionKeys = normalizeToArray(attrOpt.transition);
+            for (let i = 0; i < transitionKeys.length; i++) {
+                const key = transitionKeys[i];
+                const elVal = elPropsInAttr[key];
+                if (__DEV__) {
+                    checkNonStyleTansitionRefer(key, (attrOpt as any)[key], elVal);
+                }
+                // Do not clone, see `checkNonStyleTansitionRefer`.
+                transFromPropsInAttr[key] = elVal;
+            }
+        }
+        else if (indexOf(elOption.transition, mainAttr) >= 0) {
+            !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
+            const elPropsInAttrKeys = keys(elPropsInAttr);
+            for (let i = 0; i < elPropsInAttrKeys.length; i++) {
+                const key = elPropsInAttrKeys[i];
+                const elVal = elPropsInAttr[key];
+                if (isNonStyleTransitionEnabled((attrOpt as any)[key], elVal)) {
+                    transFromPropsInAttr[key] = elVal;
+                }
             }
-            // Do not clone, see `checkTansitionRefer`.
-            transFromPropsInAttr[key] = elVal;
         }
     }
 
@@ -936,7 +951,7 @@ function prepareTransformUpdate(
     if (isInit && enterFrom) {
         const enterFromKeys = keys(enterFrom);
         for (let i = 0; i < enterFromKeys.length; i++) {
-            const key = enterFromKeys[i] as TransformProps;
+            const key = enterFromKeys[i] as TransformProp;
             if (__DEV__) {
                 checkTransformPropRefer(key, 'el.enterFrom');
             }
@@ -950,12 +965,15 @@ function prepareTransformUpdate(
             const transitionKeys = normalizeToArray(elOption.transition);
             for (let i = 0; i < transitionKeys.length; i++) {
                 const key = transitionKeys[i];
+                if (key === 'style' || key === 'shape' || key === 'extra') {
+                    continue;
+                }
                 const elVal = fromEl[key];
                 if (__DEV__) {
                     checkTransformPropRefer(key, 'el.transition');
-                    checkTansitionRefer(key, elOption[key], elVal);
+                    checkNonStyleTansitionRefer(key, elOption[key], elVal);
                 }
-                // Do not clone, see `checkTansitionRefer`.
+                // Do not clone, see `checkNonStyleTansitionRefer`.
                 transFromProps[key] = elVal;
             }
         }
@@ -983,7 +1001,7 @@ function prepareTransformUpdate(
         const leaveToProps = getOrCreateLeaveToPropsFromEl(el);
         const leaveToKeys = keys(leaveTo);
         for (let i = 0; i < leaveToKeys.length; i++) {
-            const key = leaveToKeys[i] as TransformProps;
+            const key = leaveToKeys[i] as TransformProp;
             if (__DEV__) {
                 checkTransformPropRefer(key, 'el.leaveTo');
             }
@@ -996,6 +1014,7 @@ function prepareTransformUpdate(
 function prepareStyleUpdate(
     el: Element,
     morphingFromEl: graphicUtil.Path | graphicUtil.Path[],
+    elOption: CustomElementOption,
     styleOpt: CustomElementOption['style'],
     transFromProps: LooseElementProps,
     isInit: boolean
@@ -1004,7 +1023,9 @@ function prepareStyleUpdate(
         return;
     }
 
-    const fromEl = (morphingFromEl instanceof graphicUtil.Path) && morphingFromEl || el;
+    // At present in "many-to-one"/"one-to-many" case, to not support "many" have
+    // different styles and make style transitions. That might be a rare case.
+    const fromEl = (isArray(morphingFromEl) ? morphingFromEl[0] : morphingFromEl) || el;
 
     const fromElStyle = (fromEl as LooseElementProps).style as LooseElementProps['style'];
     let transFromStyleProps: LooseElementProps['style'];
@@ -1020,17 +1041,34 @@ function prepareStyleUpdate(
         }
     }
 
-    if (!isInit && fromElStyle && styleOpt.transition) {
-        const transitionKeys = normalizeToArray(styleOpt.transition);
-        !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});
-        for (let i = 0; i < transitionKeys.length; i++) {
-            const key = transitionKeys[i];
-            const elVal = (fromElStyle as any)[key];
-            if (__DEV__) {
-                checkTansitionRefer(key, (styleOpt as any)[key], elVal);
+    if (!isInit && fromElStyle) {
+        if (styleOpt.transition) {
+            const transitionKeys = normalizeToArray(styleOpt.transition);
+            !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});
+            for (let i = 0; i < transitionKeys.length; i++) {
+                const key = transitionKeys[i];
+                const elVal = (fromElStyle as any)[key];
+                // Do not clone, see `checkNonStyleTansitionRefer`.
+                (transFromStyleProps as any)[key] = elVal;
+            }
+        }
+        else if (
+            (el as Displayable).getAnimationStyleProps
+            && indexOf(elOption.transition, 'style') >= 0
+        ) {
+            const animationProps = (el as Displayable).getAnimationStyleProps();
+            const animationStyleProps = animationProps ? animationProps.style : null;
+            if (animationStyleProps) {
+                !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});
+                const styleKeys = keys(styleOpt);
+                for (let i = 0; i < styleKeys.length; i++) {
+                    const key = styleKeys[i];
+                    if ((animationStyleProps as Dictionary<unknown>)[key]) {
+                        const elVal = (fromElStyle as any)[key];
+                        (transFromStyleProps as any)[key] = elVal;
+                    }
+                }
             }
-            // Do not clone, see `checkTansitionRefer`.
-            (transFromStyleProps as any)[key] = elVal;
         }
     }
 
@@ -1046,26 +1084,41 @@ function prepareStyleUpdate(
     }
 }
 
-function checkTansitionRefer(propName: string, optVal: unknown, elVal: unknown): void {
-    const isArrLike = isArrayLike(optVal);
-    assert(
-        isArrLike || (optVal != null && isFinite(optVal as number)),
-        'Prop `' + propName + '` must refer to a finite number or ArrayLike for transition.'
-    );
-    // Try not to copy array for performance, but if user use the same object in different
-    // call of `renderItem`, it will casue animation transition fail.
-    assert(
-        !isArrLike || optVal !== elVal,
-        'Prop `' + propName + '` must use different Array object each time for transition.'
-    );
+let checkNonStyleTansitionRefer: (propName: string, optVal: unknown, elVal: unknown) => void;
+if (__DEV__) {
+    checkNonStyleTansitionRefer = function (propName: string, optVal: unknown, elVal: unknown): void {
+        if (!isArrayLike(optVal)) {
+            assert(
+                optVal != null && isFinite(optVal as number),
+                'Prop `' + propName + '` must refer to a finite number or ArrayLike for transition.'
+            );
+        }
+        else {
+            // Try not to copy array for performance, but if user use the same object in different
+            // call of `renderItem`, it will casue animation transition fail.
+            assert(
+                optVal !== elVal,
+                'Prop `' + propName + '` must use different Array object each time for transition.'
+            );
+        }
+    };
+}
+function isNonStyleTransitionEnabled(optVal: unknown, elVal: unknown): boolean {
+    // The same as `checkNonStyleTansitionRefer`.
+    return !isArrayLike(optVal)
+        ? (optVal != null && isFinite(optVal as number))
+        : optVal !== elVal;
 }
 
-function checkTransformPropRefer(key: string, usedIn: string): void {
-    assert(
-        hasOwn(TRANSFORM_PROPS, key),
-        'Prop `' + key + '` is not a permitted in `' + usedIn + '`. '
-            + 'Only `' + keys(TRANSFORM_PROPS).join('`, `') + '` are permitted.'
-    );
+let checkTransformPropRefer: (key: string, usedIn: string) => void;
+if (__DEV__) {
+    checkTransformPropRefer = function (key: string, usedIn: string): void {
+        assert(
+            hasOwn(TRANSFORM_PROPS, key),
+            'Prop `' + key + '` is not a permitted in `' + usedIn + '`. '
+                + 'Only `' + keys(TRANSFORM_PROPS).join('`, `') + '` are permitted.'
+        );
+    };
 }
 
 function getOrCreateLeaveToPropsFromEl(el: Element): LooseElementProps {
@@ -1081,14 +1134,14 @@ const tmpDuringScope = {} as {
 };
 const customDuringAPI = {
     // Usually other props do not need to be changed in animation during.
-    setTransform(key: TransformProps, val: unknown) {
+    setTransform(key: TransformProp, val: unknown) {
         if (__DEV__) {
             assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
         }
         tmpDuringScope.el[key] = val as number;
         return this;
     },
-    getTransform(key: TransformProps): unknown {
+    getTransform(key: TransformProp): unknown {
         if (__DEV__) {
             assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
         }
@@ -1302,7 +1355,7 @@ function updateZForEachState(
 
 function setLagecyProp(
     elOption: CustomElementOption,
-    targetProps: Partial<Pick<Transformable, TransformProps>>,
+    targetProps: Partial<Pick<Transformable, TransformProp>>,
     legacyName: LegacyTransformProp,
     fromEl?: Element // If provided, retrieve from the element.
 ): void {
@@ -1322,8 +1375,8 @@ function setLagecyProp(
 
 function setTransProp(
     elOption: CustomElementOption,
-    targetProps: Partial<Pick<Transformable, TransformProps>>,
-    name: TransformProps,
+    targetProps: Partial<Pick<Transformable, TransformProp>>,
+    name: TransformProp,
     fromEl?: Element // If provided, retrieve from the element.
 ): void {
     if (elOption[name] != null) {
diff --git a/test/custom-shape-morphing2.html b/test/custom-shape-morphing2.html
index 6d5b16d..5600088 100644
--- a/test/custom-shape-morphing2.html
+++ b/test/custom-shape-morphing2.html
@@ -82,8 +82,11 @@ under the License.
                 echarts.registerTransform(ecStat.transform.clustering);
 
 
-                const COLORS = [
-                    '#37A2DA', '#e06343', '#37a354', '#b55dba', '#b5bd48', '#8378EA', '#96BFFF'
+                const PIE_COLORS = [
+                    '#e06343', '#37a354', '#b55dba', '#b5bd48', '#8378EA', '#96BFFF'
+                ];
+                const CLUSTER_COLORS = [
+                    '#cc5664', '#9bd6ec', '#ea946e', '#8acaaa', '#f1ec64', '#ee8686', '#a48dc1', '#5da6bc', '#b9dcae'
                 ];
                 var COUNT = 50;
                 var CONTENT_COLOR = '#37A2DA';
@@ -203,16 +206,15 @@ under the License.
                                         shape: {
                                             cx: pos[0],
                                             cy: pos[1],
-                                            r: 10,
-                                            transition: ['cx', 'cy', 'r']
+                                            r: 10
                                         },
                                         style: {
-                                            transition: 'lineWidth',
                                             fill: CONTENT_COLOR,
-                                            // fill: COLORS[clusterIndex],
+                                            // fill: PIE_COLORS[clusterIndex],
                                             stroke: '#555',
                                             lineWidth: 1
-                                        }
+                                        },
+                                        transition: ['shape', 'style']
                                     };
                                 }
                             }
@@ -259,14 +261,13 @@ under the License.
                                             y: tarPos[1],
                                             height: zeroPos[1] - tarPos[1],
                                             width: width,
-                                            transition: ['x', 'y', 'width', 'height']
                                         },
                                         style: {
-                                            transition: 'lineWidth',
                                             fill: CONTENT_COLOR,
                                             stroke: '#555',
                                             lineWidth: 0
-                                        }
+                                        },
+                                        transition: ['shape', 'style']
                                     };
                                 }
                             }
@@ -294,13 +295,16 @@ under the License.
                                             totalValue += api.value('ATA', i);
                                         }
                                         var angles = [];
+                                        var colors = [];
                                         var currentAngle = -Math.PI / 2;
                                         for (var i = 0; i < params.dataInsideLength; i++) {
+                                            colors.push(PIE_COLORS[i]);
                                             var angle = api.value('ATA', i) / totalValue * Math.PI * 2;
                                             angles.push([currentAngle, angle + currentAngle - 0.01]);
                                             currentAngle += angle;
                                         }
                                         context.angles = angles;
+                                        context.colors = colors;
                                     }
 
                                     var width = chart.getWidth();
@@ -318,12 +322,13 @@ under the License.
                                             clockwise: true
                                         },
                                         style: {
-                                            transition: 'lineWidth',
-                                            fill: CONTENT_COLOR,
+                                            // fill: CONTENT_COLOR,
+                                            fill: context.colors[params.dataIndex],
                                             stroke: '#555',
                                             lineWidth: 0,
                                             strokeNoScale: true
                                         },
+                                        transition: ['shape', 'style']
                                     };
                                 }
                             }
@@ -379,14 +384,14 @@ under the License.
                                             cx: pos[0],
                                             cy: pos[1],
                                             r: radius,
-                                            transition: ['cx', 'cy', 'r']
                                         },
                                         style: {
-                                            transition: 'lineWidth',
-                                            fill: CONTENT_COLOR,
+                                            // fill: CONTENT_COLOR,
+                                            fill: CLUSTER_COLORS[params.dataIndex],
                                             stroke: '#555',
                                             lineWidth: 0
-                                        }
+                                        },
+                                        transition: ['shape', 'style']
                                     };
                                 }
                             }


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