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/11/01 09:39:05 UTC

[incubator-echarts] branch decal-custom created (now 23d617a)

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

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


      at 23d617a  Merge branch 'release' into decal-custom

This branch includes the following new commits:

     new 4e1e8fc  fix: [decal] (1) move option.decals to option.area.decal.decals. (2) disable series.decals (3) fix decals default option merge.
     new affc391  fix: fix decal visual assignment
     new fd3f74b  fix: [decal] (1) fix sankey decal and enable itemStyle.decal in sankey. (2) add test case for sankey, treemap, sunburst.
     new 59e0ad3  feature: [decal] support decal to custom series.
     new 23d617a  Merge branch 'release' into decal-custom

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



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


[incubator-echarts] 01/05: fix: [decal] (1) move option.decals to option.area.decal.decals. (2) disable series.decals (3) fix decals default option merge.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4e1e8fce2c9d0cb57d5441b7cf3fd1f800d1923c
Author: 100pah <su...@gmail.com>
AuthorDate: Thu Oct 29 02:24:15 2020 +0800

    fix: [decal] (1) move option.decals to option.area.decal.decals. (2) disable series.decals (3) fix decals default option merge.
---
 src/chart/helper/enableAriaDecalForTree.ts |  4 +-
 src/chart/sankey/SankeySeries.ts           |  3 +-
 src/component/aria.ts                      |  4 +-
 src/model/Global.ts                        |  7 +++
 src/model/Series.ts                        |  9 ----
 src/model/globalDefault.ts                 | 72 ++++++++++++++++--------------
 src/model/mixin/palette.ts                 | 28 +++++-------
 src/util/types.ts                          |  6 +--
 src/visual/aria.ts                         | 20 +++++----
 9 files changed, 75 insertions(+), 78 deletions(-)

diff --git a/src/chart/helper/enableAriaDecalForTree.ts b/src/chart/helper/enableAriaDecalForTree.ts
index b76aa84..fca0cf9 100644
--- a/src/chart/helper/enableAriaDecalForTree.ts
+++ b/src/chart/helper/enableAriaDecalForTree.ts
@@ -1,5 +1,6 @@
 import SeriesModel from '../../model/Series';
 import {Dictionary, DecalObject} from '../../util/types';
+import { getDecalFromPalette } from '../../model/mixin/palette';
 
 export default function (seriesModel: SeriesModel) {
     const data = seriesModel.getData();
@@ -13,7 +14,8 @@ export default function (seriesModel: SeriesModel) {
             current = current.parentNode;
         }
 
-        const decal = seriesModel.getDecalFromPalette(
+        const decal = getDecalFromPalette(
+            seriesModel.ecModel,
             current.name || current.dataIndex + '',
             decalPaletteScope
         );
diff --git a/src/chart/sankey/SankeySeries.ts b/src/chart/sankey/SankeySeries.ts
index d57b1ef..eb09f18 100644
--- a/src/chart/sankey/SankeySeries.ts
+++ b/src/chart/sankey/SankeySeries.ts
@@ -39,6 +39,7 @@ import GlobalModel from '../../model/Global';
 import List from '../../data/List';
 import { LayoutRect } from '../../util/layout';
 import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
+import { getDecalFromPalette } from '../../model/mixin/palette';
 
 
 type FocusNodeAdjacency = boolean | 'inEdges' | 'outEdges' | 'allEdges';
@@ -282,7 +283,7 @@ class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {
         const nodes = graph.nodes;
         zrUtil.each(nodes, node => {
             const name = this.getDataParams(node.dataIndex, 'node').name;
-            const paletteDecal = this.getDecalFromPalette(name, null, nodes.length);
+            const paletteDecal = getDecalFromPalette(this.ecModel, name, null, nodes.length);
             const decal = zrUtil.defaults(node.getVisual('style').decal || {}, paletteDecal);
             node.hostGraph.data.setItemVisual(node.dataIndex, 'decal', decal);
         });
diff --git a/src/component/aria.ts b/src/component/aria.ts
index 092236f..baa1252 100644
--- a/src/component/aria.ts
+++ b/src/component/aria.ts
@@ -20,6 +20,7 @@
 import * as echarts from '../echarts';
 import ariaVisual from '../visual/aria';
 import ariaPreprocessor from './aria/preprocessor';
+import { DecalObject } from '../util/types';
 
 const PRIORITY_VISUAL_ARIA = echarts.PRIORITY.VISUAL.ARIA;
 
@@ -66,7 +67,8 @@ export interface AriaOption extends AriaLabelOption {
     label?: AriaLabelOption;
     decal?: {
         show?: boolean;
-    }
+        decals?: DecalObject | DecalObject[];
+    };
 }
 
 echarts.registerPreprocessor(ariaPreprocessor);
diff --git a/src/model/Global.ts b/src/model/Global.ts
index 48fefab..a5ba207 100644
--- a/src/model/Global.ts
+++ b/src/model/Global.ts
@@ -813,6 +813,13 @@ class GlobalModel extends Model<ECUnitOption> {
             ecModel._componentsMap = createHashMap({series: []});
             ecModel._componentsCount = createHashMap();
 
+            // If user spefied `option.aria`, aria will be enable. This detection should be
+            // performed before theme and globalDefault merge.
+            const airaOption = baseOption.aria;
+            if (isObject(airaOption) && airaOption.enabled == null) {
+                airaOption.enabled = true;
+            }
+
             mergeTheme(baseOption, ecModel._theme.option);
 
             // TODO Needs clone when merging to the unexisted property
diff --git a/src/model/Series.ts b/src/model/Series.ts
index 655cf44..47b9782 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -460,15 +460,6 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
         return color;
     }
 
-    getDecalFromPalette(name: string, scope: any, requestColorNum?: number): DecalObject {
-        const ecModel = this.ecModel;
-        let decal = PaletteMixin.prototype.getDecalFromPalette.call(this, name, scope, requestColorNum);
-        if (!decal) {
-            decal = ecModel.getDecalFromPalette(name, scope, requestColorNum);
-        }
-        return decal;
-    }
-
     /**
      * Use `data.mapDimensionsAll(coordDim)` instead.
      * @deprecated
diff --git a/src/model/globalDefault.ts b/src/model/globalDefault.ts
index b7cd6c5..d25eab1 100644
--- a/src/model/globalDefault.ts
+++ b/src/model/globalDefault.ts
@@ -56,40 +56,44 @@ export default {
 
     gradientColor: ['#f6efa6', '#d88273', '#bf444c'],
 
-    decals: [{
-        color: decalColor,
-        dashArrayX: [1, 0],
-        dashArrayY: [2, 5],
-        symbolSize: 1,
-        rotation: Math.PI / 6
-    }, {
-        color: decalColor,
-        symbol: 'circle',
-        dashArrayX: [[8, 8], [0, 8, 8, 0]],
-        dashArrayY: [6, 0],
-        symbolSize: 0.8
-    }, {
-        color: decalColor,
-        dashArrayX: [1, 0],
-        dashArrayY: [4, 3],
-        dashLineOffset: 0,
-        rotation: -Math.PI / 4
-    }, {
-        color: decalColor,
-        dashArrayX: [[6, 6], [0, 6, 6, 0]],
-        dashArrayY: [6, 0]
-    }, {
-        color: decalColor,
-        dashArrayX: [[1, 0], [1, 6]],
-        dashArrayY: [1, 0, 6, 0],
-        rotation: Math.PI / 4
-    }, {
-        color: decalColor,
-        symbol: 'triangle',
-        dashArrayX: [[9, 9], [0, 9, 9, 0]],
-        dashArrayY: [7, 2],
-        symbolSize: 0.75
-    }],
+    aria: {
+        decal: {
+            decals: [{
+                color: decalColor,
+                dashArrayX: [1, 0],
+                dashArrayY: [2, 5],
+                symbolSize: 1,
+                rotation: Math.PI / 6
+            }, {
+                color: decalColor,
+                symbol: 'circle',
+                dashArrayX: [[8, 8], [0, 8, 8, 0]],
+                dashArrayY: [6, 0],
+                symbolSize: 0.8
+            }, {
+                color: decalColor,
+                dashArrayX: [1, 0],
+                dashArrayY: [4, 3],
+                dashLineOffset: 0,
+                rotation: -Math.PI / 4
+            }, {
+                color: decalColor,
+                dashArrayX: [[6, 6], [0, 6, 6, 0]],
+                dashArrayY: [6, 0]
+            }, {
+                color: decalColor,
+                dashArrayX: [[1, 0], [1, 6]],
+                dashArrayY: [1, 0, 6, 0],
+                rotation: Math.PI / 4
+            }, {
+                color: decalColor,
+                symbol: 'triangle',
+                dashArrayX: [[9, 9], [0, 9, 9, 0]],
+                dashArrayY: [7, 2],
+                symbolSize: 0.75
+            }]
+        }
+    },
 
     // If xAxis and yAxis declared, grid is created by default.
     // grid: {},
diff --git a/src/model/mixin/palette.ts b/src/model/mixin/palette.ts
index c0b6c85..0f74d7d 100644
--- a/src/model/mixin/palette.ts
+++ b/src/model/mixin/palette.ts
@@ -22,6 +22,7 @@ import {isArray} from 'zrender/src/core/util';
 import {makeInner, normalizeToArray} from '../../util/model';
 import Model from '../Model';
 import {ZRColor, PaletteOptionMixin, DecalObject} from '../../util/types';
+import GlobalModel from '../Global';
 
 type Inner<T> = (hostObj: PaletteMixin<PaletteOptionMixin>) => {
     paletteIdx: number;
@@ -58,26 +59,17 @@ class PaletteMixin<T extends PaletteOptionMixin = PaletteOptionMixin> {
     clearColorPalette(this: PaletteMixin<T>) {
         clearPalette<ZRColor>(this, innerColor);
     }
-
-    getDecalFromPalette(
-        this: PaletteMixin<T>,
-        name: string,
-        scope?: any,
-        requestNum?: number
-    ): DecalObject {
-        let decals = this.get('decals');
-        if (!isArray(decals)) {
-            decals = [decals as DecalObject];
-        }
-        const defaultDecals = decals as DecalObject[];
-        return getFromPalette<DecalObject>(this, innerDecal, defaultDecals, [defaultDecals], name, scope, requestNum);
-    }
-
-    clearDecalPalette(this: PaletteMixin<T>) {
-        clearPalette<DecalObject>(this, innerDecal);
-    }
 }
 
+export function getDecalFromPalette(
+    ecModel: GlobalModel,
+    name: string,
+    scope?: any,
+    requestNum?: number
+): DecalObject {
+    const defaultDecals = normalizeToArray(ecModel.get(['aria', 'decal', 'decals']));
+    return getFromPalette<DecalObject>(ecModel, innerDecal, defaultDecals, null, name, scope, requestNum);
+}
 
 
 function getNearestPalette<T>(
diff --git a/src/util/types.ts b/src/util/types.ts
index c2411d8..0be5a4c 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -711,11 +711,7 @@ export type ComponentLayoutMode = {
     ignoreSize?: boolean | boolean[]
 };
 /******************* Mixins for Common Option Properties   ********************** */
-export interface PaletteOptionMixin {
-    color?: ZRColor | ZRColor[]
-    colorLayer?: ZRColor[][],
-    decals?: DecalObject | DecalObject[]
-}
+export type PaletteOptionMixin = ColorPaletteOptionMixin;
 
 export interface ColorPaletteOptionMixin {
     color?: ZRColor | ZRColor[]
diff --git a/src/visual/aria.ts b/src/visual/aria.ts
index 21c8b37..41011f1 100644
--- a/src/visual/aria.ts
+++ b/src/visual/aria.ts
@@ -28,9 +28,9 @@ import {TitleOption} from '../component/title';
 import {makeInner} from '../util/model';
 import {Dictionary, DecalObject, InnerDecalObject} from '../util/types';
 import {LocaleOption} from '../locale';
+import { getDecalFromPalette } from '../model/mixin/palette';
 
-const defaultOption: AriaOption = {
-    enabled: true,
+const DEFAULT_OPTION: AriaOption = {
     label: {
         enabled: true
     },
@@ -48,15 +48,15 @@ type SeriesTypes = keyof LocaleOption['series']['typeNames'];
 export default function (ecModel: GlobalModel, api: ExtensionAPI) {
     const ariaModel: Model<AriaOption> = ecModel.getModel('aria');
 
-    if (ariaModel.option) {
-        const labelLocale = ecModel.getLocaleModel().get('aria');
-        defaultOption.label = zrUtil.defaults(labelLocale, defaultOption.label);
-        ariaModel.option = zrUtil.defaults(ariaModel.option, defaultOption);
-    }
+    // See "area enabled" detection code in `GlobalModel.ts`.
     if (!ariaModel.get('enabled')) {
         return;
     }
 
+    const defaultOption = zrUtil.clone(DEFAULT_OPTION);
+    zrUtil.merge(defaultOption.label, ecModel.getLocaleModel().get('aria'), false);
+    zrUtil.merge(ariaModel.option, defaultOption, false);
+
     setDecal();
     setLabel();
 
@@ -107,7 +107,8 @@ export default function (ecModel: GlobalModel, api: ExtensionAPI) {
                         const idx = idxMap[rawIdx];
                         const itemStyle = data.ensureUniqueItemVisual(idx, 'style');
                         const name = dataAll.getName(rawIdx) || (rawIdx + '');
-                        const paletteDecal = seriesModel.getDecalFromPalette(
+                        const paletteDecal = getDecalFromPalette(
+                            seriesModel.ecModel,
                             name,
                             decalScope,
                             dataCount
@@ -121,7 +122,8 @@ export default function (ecModel: GlobalModel, api: ExtensionAPI) {
                 }
                 else {
                     const style = data.getVisual('style');
-                    const paletteDecal = seriesModel.getDecalFromPalette(
+                    const paletteDecal = getDecalFromPalette(
+                        seriesModel.ecModel,
                         seriesModel.name,
                         decalPaletteScope,
                         ecModel.getSeriesCount()


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


[incubator-echarts] 03/05: fix: [decal] (1) fix sankey decal and enable itemStyle.decal in sankey. (2) add test case for sankey, treemap, sunburst.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit fd3f74bc0170d314aee209152ee5e8ba6c9efc2f
Author: 100pah <su...@gmail.com>
AuthorDate: Sun Nov 1 17:26:59 2020 +0800

    fix: [decal] (1) fix sankey decal and enable itemStyle.decal in sankey. (2) add test case for sankey, treemap, sunburst.
---
 src/chart/sankey/SankeySeries.ts |  11 -
 test/decal.html                  | 446 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 445 insertions(+), 12 deletions(-)

diff --git a/src/chart/sankey/SankeySeries.ts b/src/chart/sankey/SankeySeries.ts
index eb09f18..17cbd62 100644
--- a/src/chart/sankey/SankeySeries.ts
+++ b/src/chart/sankey/SankeySeries.ts
@@ -278,17 +278,6 @@ class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {
         return params;
     }
 
-    enableAriaDecal() {
-        const graph = this.getGraph();
-        const nodes = graph.nodes;
-        zrUtil.each(nodes, node => {
-            const name = this.getDataParams(node.dataIndex, 'node').name;
-            const paletteDecal = getDecalFromPalette(this.ecModel, name, null, nodes.length);
-            const decal = zrUtil.defaults(node.getVisual('style').decal || {}, paletteDecal);
-            node.hostGraph.data.setItemVisual(node.dataIndex, 'decal', decal);
-        });
-    }
-
     static defaultOption: SankeySeriesOption = {
         zlevel: 0,
         z: 2,
diff --git a/test/decal.html b/test/decal.html
index bb449a2..e8420ef 100644
--- a/test/decal.html
+++ b/test/decal.html
@@ -45,7 +45,6 @@ under the License.
 
         <div id="main0"></div>
         <div id="main1"></div>
-
         <div id="main2"></div>
 
         <table>
@@ -107,6 +106,12 @@ under the License.
         </table>
 
 
+        <div id="main-sankey"></div>
+        <div id="main-sunburst"></div>
+        <div id="main-treemap"></div>
+        <div id="main-custom-series"></div>
+
+
 
         <script>
         require(['echarts'/*, 'map/js/china' */], function (echarts) {
@@ -205,6 +210,13 @@ under the License.
                 };
                 if (i === 0) {
                     s.itemStyle = itemStyle;
+                    s.emphasis = {
+                        itemStyle: {
+                            decal: {
+                                color: 'red'
+                            }
+                        }
+                    }
                 }
                 series.push(s);
 
@@ -214,6 +226,13 @@ under the License.
                 };
                 if (i === 0) {
                     p.itemStyle = itemStyle;
+                    p.emphasis = {
+                        itemStyle: {
+                            decal: {
+                                color: 'red'
+                            }
+                        }
+                    }
                 }
                 pieData.push(p);
             }
@@ -254,6 +273,9 @@ under the License.
         </script>
 
 
+
+
+
         <script>
         var option;
         var decal = {
@@ -382,6 +404,428 @@ under the License.
             rand('rotation', 0, 3.14);
         }
         </script>
+
+
+
+
+
+
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+
+
+            var testData =  {
+                nodes: [
+                    {
+                        name: 'a',
+                        itemStyle: {
+                            decal: {
+                                color: 'yellow'
+                            }
+                        }
+                    },
+                    {
+                        name: 'b',
+                        depth: 2
+                    },
+                    {
+                        name: 'a1',
+                        depth: 4
+                    },
+                    {
+                        name: 'b1'
+                    },
+                    {
+                        name: 'c',
+                        depth: 3
+                    },
+                    {
+                        name: 'e',
+                        depth: 1
+                    }
+                ],
+                links: [
+                    {
+                        source: 'a',
+                        target: 'a1',
+                        value: 5
+                    },
+                    {
+                        source: 'e',
+                        target: 'b',
+                        value: 3
+                    },
+                    {
+                        source: 'a',
+                        target: 'b1',
+                        value: 0
+                    },
+                    {
+                        source: 'b1',
+                        target: 'a1',
+                        value: 1
+                    },
+                    {
+                        source: 'b1',
+                        target: 'c',
+                        value: 3
+                    },
+                    {
+                        source: 'b',
+                        target: 'c',
+                        value: 3
+                    }
+                ]
+            };
+
+            var option = {
+                aria: {
+                    decal: { show: true }
+                },
+                tooltip: {
+                    trigger: 'item',
+                    triggerOn: 'mousemove'
+                },
+                animation: false,
+                series: [
+                    {
+                        type: 'sankey',
+                        bottom: '10%',
+                        focusNodeAdjacency: true,
+                        itemStyle: {
+                            decal: {
+                                color: 'blue'
+                            }
+                        },
+                        data: testData.nodes,
+                        links: testData.links
+                    }
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main-sankey', {
+                title: [
+                    'All sankey nodes should have decal (they are from palette)',
+                    'decal color of all except "a" is **blue** (they are from series.itemStyle)',
+                    'decal color of "a" is **yellow** (it is from dataItem.itemStyle)'
+                ],
+                option: option
+            });
+        });
+        </script>
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var data = [{
+                children: [{
+                    value: 5,
+                    children: [{
+                        value: 1
+                    }, {
+                        value: 2,
+                        children: [{
+                            value: 1
+                        }]
+                    }, {
+                        children: [{
+                            value: 1
+                        }]
+                    }]
+                }, {
+                    value: 10,
+                    children: [{
+                        value: 6,
+                        children: [{
+                            value: 1
+                        }, {
+                            value: 1
+                        }, {
+                            value: 1
+                        }, {
+                            value: 1
+                        }]
+                    }, {
+                        value: 2,
+                        children: [{
+                            value: 1
+                        }]
+                    }, {
+                        children: [{
+                            value: 1
+                        }]
+                    }]
+                }]
+            }, {
+                value: 9,
+                children: [{
+                    value: 4,
+                    children: [{
+                        value: 2
+                    }, {
+                        children: [{
+                            value: 1
+                        }]
+                    }]
+                }, {
+                    children: [{
+                        value: 3,
+                        children: [{
+                            value: 1
+                        }, {
+                            value: 1
+                        }]
+                    }]
+                }]
+            }, {
+                value: 7,
+                children: [{
+                    children: [{
+                        value: 1
+                    }, {
+                        value: 3,
+                        children: [{
+                            value: 1
+                        }, {
+                            value: 1
+                        }]
+                    }, {
+                        value: 2,
+                        children: [{
+                            value: 1
+                        }, {
+                            value: 1
+                        }]
+                    }]
+                }]
+            }, {
+                children: [{
+                    value: 6,
+                    children: [{
+                        value: 1
+                    }, {
+                        value: 2,
+                        children: [{
+                            value: 2
+                        }]
+                    }, {
+                        value: 1
+                    }]
+                }, {
+                    value: 3,
+                    children: [{
+                        value: 1,
+                    }, {
+                        children: [{
+                            value: 1
+                        }]
+                    }, {
+                        value: 1
+                    }]
+                }]
+            }];
+
+            var option = {
+                aria: {
+                    decal: { show: true }
+                },
+                series: {
+                    type: 'sunburst',
+                    data: data
+                }
+            };
+
+            var chart = testHelper.create(echarts, 'main-sunburst', {
+                title: [
+                    'All sunburst nodes should have decal (by 1st level) (they are from palette)'
+                ],
+                option: option
+            });
+        });
+        </script>
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option = {
+                aria: {
+                    decal: { show: true }
+                },
+                series: [{
+                    name: 'tm',
+                    type: 'treemap',
+                    roam: false,
+                    label: {
+                        position: 'insideRight',
+                        emphasis: {
+                            show: true
+                        }
+                    },
+                    leafDepth: 1,
+                    levels: [{
+                        itemStyle: {
+                            borderColor: '#333',
+                            borderWidth: 4,
+                            gapWidth: 2
+                        }
+                    }, {
+                        itemStyle: {
+                            borderColor: '#aaa',
+                            gapWidth: 2,
+                            borderWidth: 2
+                        },
+                        colorSaturation: [0.2, 0.7]
+                    }],
+                    data: [{
+                        name: 'a',
+                        value: 10,
+                        children: [{
+                            name: 'a1',
+                            value: 11,
+                            children: [{
+                                name: 'a11',
+                                value: 111,
+                            }, {
+                                name: 'a111',
+                                value: 1111
+                            }, {
+                                name: 'a112',
+                                value: 1111
+                            }, {
+                                name: 'a113',
+                                value: 111
+                            }, {
+                                name: 'a114',
+                                value: 111
+                            }, {
+                                name: 'a115',
+                                value: 1100
+                            }]
+                        }]
+                    }, {
+                        name: 'b',
+                        value: 6,
+                        children: [{
+                            name: 'b1',
+                            value: 15,
+                            children: [{
+                                name: 'b11',
+                                value: 120
+                            }]
+                        }]
+                    }]
+                }]
+            };
+
+            var chart = testHelper.create(echarts, 'main-treemap', {
+                title: [
+                    'All treemap nodes should have decal (by 1st level) (they are from palette)'
+                ],
+                option: option
+            });
+        });
+        </script>
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+
+            function renderItem(params, api) {
+                var pos = api.coord([api.value(0), api.value(1)]);
+                var paletteColor = api.visual('color');
+                var paletteDecal = api.visual('decal');
+                if (params.dataIndex === 0) {
+                    return {
+                        type: 'group',
+                        x: pos[0],
+                        y: pos[1],
+                        children: [{
+                            type: 'circle',
+                            shape: { cx: 0, cy: 0, r: 30 },
+                            style: {
+                                fill: 'orange',
+                                decal: {
+                                    color: 'blue',
+                                    dashArrayX: [1, 0],
+                                    dashArrayY: [4, 3],
+                                    dashLineOffset: 0,
+                                    rotation: -Math.PI / 4
+                                }
+                            }
+                        }, {
+                            type: 'circle',
+                            shape: { cx: 60, cy: 0, r: 30 },
+                            style: { fill: 'orange' }
+                        }]
+                    }
+                }
+                else {
+                    return {
+                        type: 'group',
+                        x: pos[0],
+                        y: pos[1],
+                        children: [{
+                            type: 'rect',
+                            shape: { x: -20, y: -20, width: 40, height: 40 },
+                            style: { fill: paletteColor, decal: paletteDecal },
+                        }, {
+                            type: 'rect',
+                            shape: { x: 60 - 20, y: -20, width: 40, height: 40 },
+                            style: { fill: paletteColor, decal: paletteDecal },
+                        }]
+                    }
+                }
+            }
+
+            var option = {
+                xAxis: {
+                },
+                yAxis: {
+                },
+                series: [{
+                    type: 'custom',
+                    renderItem: renderItem,
+                    data: [ [11, 22], [55, 22] ]
+                }, {
+                    type: 'custom',
+                    renderItem: renderItem,
+                    data: [ [11, 55], [55, 55] ]
+                }, {
+                    type: 'custom',
+                    renderItem: renderItem,
+                    data: [ [11, 88], [55, 88] ]
+                }],
+                aria: {
+                    decal: {
+                        show: true
+                    }
+                }
+            };
+
+            var chart = testHelper.create(echarts, 'main-custom-series', {
+                title: [
+                    'All circle/rect should show decals.',
+                    'Circel should be in specified decal (in **blue**) and specified color (in **orange**).',
+                    'Rect should be in palette decal and palette color'
+                ],
+                option: option
+                // height: 300,
+                // buttons: [{text: 'btn-txt', onclick: function () {}}],
+                // recordCanvas: true,
+            });
+        });
+        </script>
+
+
+
     </body>
 </html>
 


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


[incubator-echarts] 05/05: Merge branch 'release' into decal-custom

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 23d617a9d4affdabe2425f1556884a8183898a31
Merge: 59e0ad3 a172154
Author: 100pah <su...@gmail.com>
AuthorDate: Sun Nov 1 17:36:50 2020 +0800

    Merge branch 'release' into decal-custom
    
    # Conflicts:
    #	test/decal.html

 src/chart/line/LineView.ts                    |  5 ++---
 src/component/dataZoom/DataZoomModel.ts       | 11 +++++------
 src/component/timeline/SliderTimelineView.ts  |  2 +-
 src/scale/Interval.ts                         |  4 ++--
 src/scale/Ordinal.ts                          | 25 +++++++++++++++----------
 src/scale/Scale.ts                            | 10 +++++-----
 src/scale/Time.ts                             | 17 ++++++++++-------
 src/util/decal.ts                             | 10 +++++++---
 src/util/states.ts                            |  5 ++++-
 src/util/types.ts                             |  3 ++-
 test/browser-esm.html                         |  2 +-
 test/custom-hexbin.html                       |  8 ++++----
 test/decal.html                               | 19 +++++++++++++++----
 test/graph.html                               | 12 ++++++++----
 test/hoverStyle.html                          |  4 ++--
 test/runTest/actions/__meta__.json            | 27 +++++++++++++++++----------
 test/runTest/actions/appendData.json          |  2 +-
 test/runTest/actions/axis-interval2.json      |  2 +-
 test/runTest/actions/brush.json               |  2 +-
 test/runTest/actions/calendar-month.json      |  2 +-
 test/runTest/actions/clip.json                |  2 +-
 test/runTest/actions/color-mix-aqi.json       |  2 +-
 test/runTest/actions/connect-dynamic.json     |  2 +-
 test/runTest/actions/connect.json             |  2 +-
 test/runTest/actions/connect2.json            |  2 +-
 test/runTest/actions/custom-hexbin.json       |  2 +-
 test/runTest/actions/dataSelect.json          |  1 +
 test/runTest/actions/dataZoom-action.json     |  2 +-
 test/runTest/actions/dataZoom-axes.json       |  2 +-
 test/runTest/actions/dataZoom-rainfall.json   |  2 +-
 test/runTest/actions/dataZoom-scatter-hv.json |  2 +-
 test/runTest/actions/dataZoom-toolbox.json    |  2 +-
 test/runTest/actions/decal.json               |  1 +
 test/runTest/actions/funnel.json              |  2 +-
 test/runTest/actions/geo-map.json             |  2 +-
 test/runTest/actions/getOption.json           |  2 +-
 test/runTest/actions/heatmap.json             |  2 +-
 test/runTest/actions/homepage3.json           |  2 +-
 test/runTest/actions/hoverFocus.json          |  1 +
 test/runTest/actions/hoverFocus2.json         |  1 +
 test/runTest/actions/hoverStyle.json          |  2 +-
 test/runTest/actions/label-layout.json        |  1 +
 test/runTest/actions/legend.json              |  2 +-
 test/runTest/actions/line-boldWhenHover.json  |  1 +
 test/runTest/actions/mapWorld.json            |  2 +-
 test/runTest/actions/markArea.json            |  2 +-
 test/runTest/actions/pie-calculable.json      |  2 +-
 test/runTest/actions/pie-label-extreme.json   |  1 +
 test/runTest/actions/scatter-single-axis.json |  2 +-
 test/runTest/client/client.js                 |  4 +---
 test/runTest/recorder/recorder.js             | 12 +++++++-----
 test/runTest/server.js                        |  4 ++--
 test/visualMap-continuous.html                |  7 +++----
 53 files changed, 146 insertions(+), 104 deletions(-)

diff --cc test/decal.html
index e8420ef,ab7bbf9..efa248a
--- a/test/decal.html
+++ b/test/decal.html
@@@ -180,7 -185,8 +190,8 @@@ under the License
                  title: [
                      'It should use decal when aria.show is true',
                      '(1) Each bar and pie piece should have different decal',
-                     '(2) The first bar and pie piece decal should be **blue**'
 -                    '(2) The first bar decal should be blue',
++                    '(2) The first bar and pie piece decal should be **blue**',
+                     '(3) The second and third bar should not have decal'
                  ],
                  option: option
                  // height: 300,


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


[incubator-echarts] 04/05: feature: [decal] support decal to custom series.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 59e0ad35a53d6e6b31dfcf53d32c13c1811997b0
Author: 100pah <su...@gmail.com>
AuthorDate: Sun Nov 1 17:33:30 2020 +0800

    feature: [decal] support decal to custom series.
---
 src/chart/custom.ts                              | 111 +++++++++++++++++------
 test/ut/jest.config.js                           |   4 +-
 test/ut/spec/component/graphic/setOption.test.ts |   1 -
 test/ut/spec/series/custom.test.ts               |  72 +++++++++++++++
 4 files changed, 156 insertions(+), 32 deletions(-)

diff --git a/src/chart/custom.ts b/src/chart/custom.ts
index 4d4a1a6..8db0f0f 100644
--- a/src/chart/custom.ts
+++ b/src/chart/custom.ts
@@ -53,7 +53,9 @@ import {
     BlurScope,
     SeriesDataType,
     OrdinalRawValue,
-    PayloadAnimationPart
+    PayloadAnimationPart,
+    DecalObject,
+    InnerDecalObject
 } from '../util/types';
 import Element, { ElementProps, ElementTextConfig } from 'zrender/src/Element';
 import prepareCartesian2d from '../coord/cartesian/prepareCustom';
@@ -69,7 +71,7 @@ import ExtensionAPI from '../ExtensionAPI';
 import Displayable from 'zrender/src/graphic/Displayable';
 import Axis2D from '../coord/cartesian/Axis2D';
 import { RectLike } from 'zrender/src/core/BoundingRect';
-import { PathProps } from 'zrender/src/graphic/Path';
+import { PathProps, PathStyleProps } from 'zrender/src/graphic/Path';
 import { ImageStyleProps } from 'zrender/src/graphic/Image';
 import { CoordinateSystem } from '../coord/CoordinateSystem';
 import { TextStyleProps } from 'zrender/src/graphic/Text';
@@ -89,6 +91,8 @@ import {
 } from 'zrender/src/tool/morphPath';
 import { AnimationEasing } from 'zrender/src/animation/easing';
 import * as matrix from 'zrender/src/core/matrix';
+import { PatternObject } from 'zrender/src/graphic/Pattern';
+import { createOrUpdatePatternFromDecal } from '../util/decal';
 
 
 const inner = makeInner<{
@@ -187,6 +191,11 @@ interface CustomGroupOption extends CustomBaseElementOption {
 }
 interface CustomZRPathOption extends CustomDisplayableOption, ShapeMorphingOption {
     shape?: PathProps['shape'] & TransitionAnyOption;
+    style?: CustomDisplayableOption['style'] & {
+        decal?: DecalObject;
+        // Only internal usage. Any user specified value will be overwritten.
+        __decalPattern?: PatternObject;
+    };
 }
 interface CustomSVGPathOption extends CustomDisplayableOption, ShapeMorphingOption {
     type: 'path';
@@ -219,14 +228,19 @@ type CustomElementOption = CustomZRPathOption | CustomSVGPathOption | CustomImag
 type CustomElementOptionOnState = CustomDisplayableOptionOnState | CustomImageOptionOnState;
 
 
-interface CustomSeriesRenderItemAPI extends
+export interface CustomSeriesRenderItemAPI extends
         CustomSeriesRenderItemCoordinateSystemAPI,
         Pick<ExtensionAPI, 'getWidth' | 'getHeight' | 'getZr' | 'getDevicePixelRatio'> {
     value(dim: DimensionLoose, dataIndexInside?: number): ParsedValue;
     ordinalRawValue(dim: DimensionLoose, dataIndexInside?: number): ParsedValue | OrdinalRawValue;
     style(userProps?: ZRStyleProps, dataIndexInside?: number): ZRStyleProps;
     styleEmphasis(userProps?: ZRStyleProps, dataIndexInside?: number): ZRStyleProps;
-    visual(visualType: string, dataIndexInside?: number): ReturnType<List['getItemVisual']>;
+    visual<VT extends NonStyleVisualProps | StyleVisualProps>(
+        visualType: VT,
+        dataIndexInside?: number
+    ): VT extends NonStyleVisualProps ? DefaultDataVisual[VT]
+        : VT extends StyleVisualProps ? PathStyleProps[typeof STYLE_VISUAL_TYPE[VT]]
+        : void;
     barLayout(opt: Omit<Parameters<typeof getLayoutOnAxis>[0], 'axis'>): ReturnType<typeof getLayoutOnAxis>;
     currentSeriesIndices(): ReturnType<GlobalModel['getCurrentSeriesIndices']>;
     font(opt: Parameters<typeof labelStyleHelper.getFont>[0]): ReturnType<typeof labelStyleHelper.getFont>;
@@ -245,7 +259,7 @@ interface CustomSeriesRenderItemCoordinateSystemAPI {
         dataItem: OptionDataValue | OptionDataValue[]
     ): number | number[];
 }
-interface CustomSeriesRenderItemParams {
+export interface CustomSeriesRenderItemParams {
     context: Dictionary<unknown>;
     seriesId: string;
     seriesName: string;
@@ -301,15 +315,18 @@ const STYLE_VISUAL_TYPE = {
     color: 'fill',
     borderColor: 'stroke'
 } as const;
+type StyleVisualProps = keyof typeof STYLE_VISUAL_TYPE;
 
-const VISUAL_PROPS = {
+const NON_STYLE_VISUAL_PROPS = {
     symbol: 1,
     symbolSize: 1,
     symbolKeepAspect: 1,
     legendSymbol: 1,
     visualMeta: 1,
-    liftZ: 1
+    liftZ: 1,
+    decal: 1
 } as const;
+type NonStyleVisualProps = keyof typeof NON_STYLE_VISUAL_PROPS;
 
 const EMPHASIS = 'emphasis' as const;
 const NORMAL = 'normal' as const;
@@ -482,7 +499,7 @@ class CustomSeriesView extends ChartView {
             });
             data.each(function (newIdx) {
                 createOrUpdateItem(
-                    null, newIdx, renderItem(newIdx, payload), customSeries, group, data, null
+                    api, null, newIdx, renderItem(newIdx, payload), customSeries, group, data, null
                 );
             });
         }
@@ -500,7 +517,7 @@ class CustomSeriesView extends ChartView {
             ))
             .add(function (newIdx) {
                 createOrUpdateItem(
-                    null, newIdx, renderItem(newIdx, payload), customSeries, group,
+                    api, null, newIdx, renderItem(newIdx, payload), customSeries, group,
                     data, null
                 );
             })
@@ -523,7 +540,7 @@ class CustomSeriesView extends ChartView {
                     oldEl = null;
                 }
                 createOrUpdateItem(
-                    oldEl, newIdx, renderItem(newIdx, payload), customSeries, group,
+                    api, oldEl, newIdx, renderItem(newIdx, payload), customSeries, group,
                     data, morphPreparation
                 );
                 morphPreparation.applyMorphing();
@@ -536,7 +553,7 @@ class CustomSeriesView extends ChartView {
                     removeElementDirectly(oldEl, group);
                 }
                 createOrUpdateItem(
-                    null, newIdx, renderItem(newIdx, payload), customSeries, group,
+                    api, null, newIdx, renderItem(newIdx, payload), customSeries, group,
                     data, morphPreparation
                 );
                 morphPreparation.applyMorphing();
@@ -550,7 +567,7 @@ class CustomSeriesView extends ChartView {
 
                 for (let i = 0; i < newLen; i++) {
                     createOrUpdateItem(
-                        null, newIndices[i], renderItem(newIndices[i], payload), customSeries, group,
+                        api, null, newIndices[i], renderItem(newIndices[i], payload), customSeries, group,
                         data, morphPreparation
                     );
                 }
@@ -599,7 +616,7 @@ class CustomSeriesView extends ChartView {
         }
         for (let idx = params.start; idx < params.end; idx++) {
             const el = createOrUpdateItem(
-                null, idx, renderItem(idx, payload), customSeries, this.group, data, null
+                null, null, idx, renderItem(idx, payload), customSeries, this.group, data, null
             );
             el.traverse(setIncrementalAndHoverLayer);
         }
@@ -779,6 +796,8 @@ function createEl(elOption: CustomElementOption): Element {
  * @return if `isMorphTo`, return `allPropsFinal`.
  */
 function updateElNormal(
+    // Can be null/undefined
+    api: ExtensionAPI,
     el: Element,
     // Whether be a morph target.
     isMorphTo: boolean,
@@ -823,6 +842,17 @@ function updateElNormal(
         );
     }
 
+    if (styleOpt) {
+        let decalPattern;
+        const decalObj = isPath(el) ? (styleOpt as CustomZRPathOption['style']).decal : null;
+        if (api && decalObj) {
+            (decalObj as InnerDecalObject).dirty = true;
+            decalPattern = createOrUpdatePatternFromDecal(decalObj, api);
+        }
+        // Always overwrite in case user specify this prop.
+        (styleOpt as CustomZRPathOption['style']).__decalPattern = decalPattern;
+    }
+
     !isMorphTo && prepareStyleTransitionFrom(el, null, elOption, styleOpt, transFromProps, isInit);
 
     if (elDisplayable) {
@@ -861,10 +891,22 @@ function applyPropsFinal(
     const elDisplayable = el.isGroup ? null : el as Displayable;
 
     if (elDisplayable && styleOpt) {
+
+        const decalPattern = (styleOpt as CustomZRPathOption['style']).__decalPattern;
+        let originalDecalObj;
+        if (decalPattern) {
+            originalDecalObj = (styleOpt as CustomZRPathOption['style']).decal;
+            (styleOpt as any).decal = decalPattern;
+        }
+
         // PENDING: here the input style object is used directly.
         // Good for performance but bad for compatibility control.
         elDisplayable.useStyle(styleOpt);
 
+        if (decalPattern) {
+            (styleOpt as CustomZRPathOption['style']).decal = originalDecalObj;
+        }
+
         // When style object changed, how to trade the existing animation?
         // It is probably conplicated and not needed to cover all the cases.
         // But still need consider the case:
@@ -1794,22 +1836,25 @@ function makeRenderItem(
      * @public
      * @param dataIndexInside by default `currDataIndexInside`.
      */
-    function visual(
-        visualType: keyof DefaultDataVisual,
+    function visual<VT extends NonStyleVisualProps | StyleVisualProps>(
+        visualType: VT,
         dataIndexInside?: number
-    ): ReturnType<List['getItemVisual']> {
+    ): VT extends NonStyleVisualProps ? DefaultDataVisual[VT]
+            : VT extends StyleVisualProps ? PathStyleProps[typeof STYLE_VISUAL_TYPE[VT]]
+            : never {
+
         dataIndexInside == null && (dataIndexInside = currDataIndexInside);
 
         if (hasOwn(STYLE_VISUAL_TYPE, visualType)) {
             const style = data.getItemVisual(dataIndexInside, 'style');
             return style
-                ? style[STYLE_VISUAL_TYPE[visualType as keyof typeof STYLE_VISUAL_TYPE]] as any
+                ? style[STYLE_VISUAL_TYPE[visualType as StyleVisualProps]] as any
                 : null;
         }
         // Only support these visuals. Other visual might be inner tricky
         // for performance (like `style`), do not expose to users.
-        if (hasOwn(VISUAL_PROPS, visualType)) {
-            return data.getItemVisual(dataIndexInside, visualType);
+        if (hasOwn(NON_STYLE_VISUAL_PROPS, visualType)) {
+            return data.getItemVisual(dataIndexInside, visualType as NonStyleVisualProps) as any;
         }
     }
 
@@ -1858,6 +1903,7 @@ function wrapEncodeDef(data: List<CustomSeriesModel>): Dictionary<number[]> {
 }
 
 function createOrUpdateItem(
+    api: ExtensionAPI,
     el: Element,
     dataIndex: number,
     elOption: CustomElementOption,
@@ -1878,7 +1924,7 @@ function createOrUpdateItem(
         removeElementDirectly(el, group);
         return;
     }
-    el = doCreateOrUpdateEl(el, dataIndex, elOption, seriesModel, group, true, morphPreparation);
+    el = doCreateOrUpdateEl(api, el, dataIndex, elOption, seriesModel, group, true, morphPreparation);
     el && data.setItemGraphicEl(dataIndex, el);
 
     enableHoverEmphasis(el, elOption.focus, elOption.blurScope);
@@ -1887,6 +1933,7 @@ function createOrUpdateItem(
 }
 
 function doCreateOrUpdateEl(
+    api: ExtensionAPI,
     el: Element,
     dataIndex: number,
     elOption: CustomElementOption,
@@ -1951,6 +1998,7 @@ function doCreateOrUpdateEl(
     );
 
     const pendingAllPropsFinal = updateElNormal(
+        api,
         el,
         thisElIsMorphTo,
         dataIndex,
@@ -1979,7 +2027,7 @@ function doCreateOrUpdateEl(
 
     if (elOption.type === 'group') {
         mergeChildren(
-            el as graphicUtil.Group, dataIndex, elOption as CustomGroupOption, seriesModel, morphPreparation
+            api, el as graphicUtil.Group, dataIndex, elOption as CustomGroupOption, seriesModel, morphPreparation
         );
     }
 
@@ -2052,7 +2100,7 @@ function doCreateOrUpdateClipPath(
             el.setClipPath(clipPath);
         }
         updateElNormal(
-            clipPath, null, dataIndex, clipPathOpt, null, null, seriesModel, isInit, false
+            null, clipPath, null, dataIndex, clipPathOpt, null, null, seriesModel, isInit, false
         );
     }
     // If not define `clipPath` in option, do nothing unnecessary.
@@ -2105,7 +2153,7 @@ function doCreateOrUpdateAttachedTx(
             const txConStlOptNormal = txConOptNormal && txConOptNormal.style;
 
             updateElNormal(
-                textContent, null, dataIndex, txConOptNormal, txConStlOptNormal, null, seriesModel, isInit, true
+                null, textContent, null, dataIndex, txConOptNormal, txConStlOptNormal, null, seriesModel, isInit, true
             );
             for (let i = 0; i < STATES.length; i++) {
                 const stateName = STATES[i];
@@ -2212,6 +2260,7 @@ function retrieveStyleOptionOnState(
 // child (otherwise the total indicies of the children array have to be modified).
 // User can remove a single child by set its `ignore` as `true`.
 function mergeChildren(
+    api: ExtensionAPI,
     el: graphicUtil.Group,
     dataIndex: number,
     elOption: CustomGroupOption,
@@ -2233,6 +2282,7 @@ function mergeChildren(
 
     if (byName) {
         diffGroupChildren({
+            api: api,
             oldChildren: el.children() || [],
             newChildren: newChildren || [],
             dataIndex: dataIndex,
@@ -2250,6 +2300,7 @@ function mergeChildren(
     let index = 0;
     for (; index < newLen; index++) {
         newChildren[index] && doCreateOrUpdateEl(
+            api,
             el.childAt(index),
             dataIndex,
             newChildren[index],
@@ -2268,12 +2319,13 @@ function mergeChildren(
 }
 
 type DiffGroupContext = {
-    oldChildren: Element[],
-    newChildren: CustomElementOption[],
-    dataIndex: number,
-    seriesModel: CustomSeriesModel,
-    group: graphicUtil.Group,
-    morphPreparation: MorphPreparation
+    api: ExtensionAPI;
+    oldChildren: Element[];
+    newChildren: CustomElementOption[];
+    dataIndex: number;
+    seriesModel: CustomSeriesModel;
+    group: graphicUtil.Group;
+    morphPreparation: MorphPreparation;
 };
 function diffGroupChildren(context: DiffGroupContext) {
     (new DataDiffer(
@@ -2304,6 +2356,7 @@ function processAddUpdate(
     const child = oldIndex != null ? context.oldChildren[oldIndex] : null;
 
     doCreateOrUpdateEl(
+        context.api,
         child,
         context.dataIndex,
         childOption,
diff --git a/test/ut/jest.config.js b/test/ut/jest.config.js
index ef57ca0..bc09902 100644
--- a/test/ut/jest.config.js
+++ b/test/ut/jest.config.js
@@ -35,10 +35,10 @@ module.exports = {
     testMatch: [
         '**/spec/api/*.test.ts',
         '**/spec/component/**/*.test.ts',
+        '**/spec/series/**/*.test.ts',
         '**/spec/data/*.test.ts',
         '**/spec/model/*.test.ts',
         '**/spec/scale/*.test.ts',
-        '**/spec/util/*.test.ts',
-        '**/spec/component/graphic/setOption.test.ts'
+        '**/spec/util/*.test.ts'
     ]
 };
diff --git a/test/ut/spec/component/graphic/setOption.test.ts b/test/ut/spec/component/graphic/setOption.test.ts
index b56f8b8..6dddca2 100755
--- a/test/ut/spec/component/graphic/setOption.test.ts
+++ b/test/ut/spec/component/graphic/setOption.test.ts
@@ -1,4 +1,3 @@
-
 /*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
diff --git a/test/ut/spec/series/custom.test.ts b/test/ut/spec/series/custom.test.ts
new file mode 100644
index 0000000..ec4565e
--- /dev/null
+++ b/test/ut/spec/series/custom.test.ts
@@ -0,0 +1,72 @@
+/*
+* 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 { EChartsType } from '../../../../src/echarts';
+import { createChart } from '../../core/utHelper';
+import { ZRColor } from '../../../../src/util/types';
+import { CustomSeriesRenderItemAPI, CustomSeriesRenderItemParams } from '../../../../src/chart/custom';
+
+
+describe('custom_series', function () {
+
+    let chart: EChartsType;
+    beforeEach(function () {
+        chart = createChart();
+    });
+
+    afterEach(function () {
+        chart.dispose();
+    });
+
+
+    it('visual_palette', function () {
+        const colors = ['#111111', '#222222', '#333333'];
+        const resultPaletteColors: ZRColor[] = [];
+
+        function renderItem(params: CustomSeriesRenderItemParams, api: CustomSeriesRenderItemAPI) {
+            const color = api.visual('color');
+            resultPaletteColors.push(color);
+            return {
+                type: 'circle'
+            };
+        }
+
+        chart.setOption({
+            color: colors,
+            xAxis: { data: ['a'] },
+            yAxis: {},
+            series: [{
+                type: 'custom',
+                renderItem: renderItem,
+                data: [11]
+            }, {
+                type: 'custom',
+                renderItem: renderItem,
+                data: [22]
+            }, {
+                type: 'custom',
+                renderItem: renderItem,
+                data: [33]
+            }]
+        }, true);
+
+        expect(resultPaletteColors).toEqual(colors);
+    });
+
+});


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


[incubator-echarts] 02/05: fix: fix decal visual assignment

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit affc3917c79433719e8277269ae807548be27bdc
Author: 100pah <su...@gmail.com>
AuthorDate: Thu Oct 29 23:55:57 2020 +0800

    fix: fix decal visual assignment
---
 src/chart/treemap/TreemapView.ts |  5 +++--
 src/coord/parallel/AxisModel.ts  |  5 +++--
 src/data/List.ts                 |  3 +--
 src/model/mixin/areaStyle.ts     |  5 +++--
 src/model/mixin/itemStyle.ts     |  5 +++--
 src/model/mixin/lineStyle.ts     |  5 +++--
 src/util/types.ts                |  3 ++-
 src/visual/aria.ts               | 24 +++++++++++++-----------
 src/visual/style.ts              |  3 +++
 test/decal.html                  |  4 ++--
 10 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/src/chart/treemap/TreemapView.ts b/src/chart/treemap/TreemapView.ts
index 4779b5b..93eb244 100644
--- a/src/chart/treemap/TreemapView.ts
+++ b/src/chart/treemap/TreemapView.ts
@@ -77,8 +77,9 @@ const getStateItemStyle = makeStyleMapper([
     ['shadowBlur'],
     ['shadowOffsetX'],
     ['shadowOffsetY'],
-    ['shadowColor'],
-    ['decal']
+    ['shadowColor']
+    // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
+    // So do not transfer decal directly.
 ]);
 const getItemStyleNormal = function (model: Model<TreemapSeriesNodeItemOption['itemStyle']>): PathStyleProps {
     // Normal style props should include emphasis style props.
diff --git a/src/coord/parallel/AxisModel.ts b/src/coord/parallel/AxisModel.ts
index fa8efba..7c5e4be 100644
--- a/src/coord/parallel/AxisModel.ts
+++ b/src/coord/parallel/AxisModel.ts
@@ -79,8 +79,9 @@ class ParallelAxisModel extends ComponentModel<ParallelAxisOption> {
                 ['lineWidth', 'borderWidth'],
                 ['stroke', 'borderColor'],
                 ['width', 'width'],
-                ['opacity', 'opacity'],
-                ['decal']
+                ['opacity', 'opacity']
+                // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
+                // So do not transfer decal directly.
             ]
         )(this.getModel('areaSelectStyle')) as ParallelAreaSelectStyleProps;
     }
diff --git a/src/data/List.ts b/src/data/List.ts
index eae8bbb..e960680 100644
--- a/src/data/List.ts
+++ b/src/data/List.ts
@@ -1787,7 +1787,6 @@ class List<
      * Make sure itemVisual property is unique
      */
     // TODO: use key to save visual to reduce memory.
-    // eslint-disable-next-line
     ensureUniqueItemVisual<K extends keyof Visual>(idx: number, key: K): Visual[K] {
         const itemVisuals = this._itemVisuals;
         let itemVisual = itemVisuals[idx] as Visual;
@@ -1795,7 +1794,7 @@ class List<
             itemVisual = itemVisuals[idx] = {} as Visual;
         }
         let val = itemVisual[key];
-        if (!val) {
+        if (val == null) {
             val = this.getVisual(key);
 
             // TODO Performance?
diff --git a/src/model/mixin/areaStyle.ts b/src/model/mixin/areaStyle.ts
index e0f37ff..5efd4e6 100644
--- a/src/model/mixin/areaStyle.ts
+++ b/src/model/mixin/areaStyle.ts
@@ -28,8 +28,9 @@ export const AREA_STYLE_KEY_MAP = [
     ['shadowOffsetX'],
     ['shadowOffsetY'],
     ['opacity'],
-    ['shadowColor'],
-    ['decal']
+    ['shadowColor']
+    // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
+    // So do not transfer decal directly.
 ];
 const getAreaStyle = makeStyleMapper(AREA_STYLE_KEY_MAP);
 
diff --git a/src/model/mixin/itemStyle.ts b/src/model/mixin/itemStyle.ts
index 3e38aac..950bf39 100644
--- a/src/model/mixin/itemStyle.ts
+++ b/src/model/mixin/itemStyle.ts
@@ -35,8 +35,9 @@ export const ITEM_STYLE_KEY_MAP = [
     ['lineDashOffset', 'borderDashOffset'],
     ['lineCap', 'borderCap'],
     ['lineJoin', 'borderJoin'],
-    ['miterLimit', 'borderMiterLimit'],
-    ['decal']
+    ['miterLimit', 'borderMiterLimit']
+    // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
+    // So do not transfer decal directly.
 ];
 
 const getItemStyle = makeStyleMapper(ITEM_STYLE_KEY_MAP);
diff --git a/src/model/mixin/lineStyle.ts b/src/model/mixin/lineStyle.ts
index dac90db..168102e 100644
--- a/src/model/mixin/lineStyle.ts
+++ b/src/model/mixin/lineStyle.ts
@@ -34,8 +34,9 @@ export const LINE_STYLE_KEY_MAP = [
     ['lineDashOffset', 'dashOffset'],
     ['lineCap', 'cap'],
     ['lineJoin', 'join'],
-    ['miterLimit'],
-    ['decal']
+    ['miterLimit']
+    // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
+    // So do not transfer decal directly.
 ];
 
 const getLineStyle = makeStyleMapper(LINE_STYLE_KEY_MAP);
diff --git a/src/util/types.ts b/src/util/types.ts
index 0be5a4c..1d7a605 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -688,7 +688,8 @@ export interface DecalObject {
 };
 
 export interface InnerDecalObject extends DecalObject {
-    // If option has changed
+    // Mark dirty when object may be changed.
+    // The record in WeakMap will be deleted.
     dirty?: boolean
 }
 
diff --git a/src/visual/aria.ts b/src/visual/aria.ts
index 41011f1..2a14d2f 100644
--- a/src/visual/aria.ts
+++ b/src/visual/aria.ts
@@ -105,7 +105,6 @@ export default function (ecModel: GlobalModel, api: ExtensionAPI) {
                     const dataCount = dataAll.count();
                     dataAll.each(rawIdx => {
                         const idx = idxMap[rawIdx];
-                        const itemStyle = data.ensureUniqueItemVisual(idx, 'style');
                         const name = dataAll.getName(rawIdx) || (rawIdx + '');
                         const paletteDecal = getDecalFromPalette(
                             seriesModel.ecModel,
@@ -113,26 +112,29 @@ export default function (ecModel: GlobalModel, api: ExtensionAPI) {
                             decalScope,
                             dataCount
                         );
-                        const decal = zrUtil.defaults(
-                            itemStyle.decal || {},
-                            paletteDecal
-                        );
-                        data.setItemVisual(idx, 'decal', decal);
+                        const specifiedDecal = data.getItemVisual(idx, 'decal');
+                        data.setItemVisual(idx, 'decal', mergeDecal(specifiedDecal, paletteDecal));
                     });
                 }
                 else {
-                    const style = data.getVisual('style');
                     const paletteDecal = getDecalFromPalette(
                         seriesModel.ecModel,
                         seriesModel.name,
                         decalPaletteScope,
                         ecModel.getSeriesCount()
                     );
-                    const decal = style.decal
-                        ? zrUtil.defaults(style.decal, paletteDecal)
+                    const specifiedDecal = data.getVisual('decal');
+                    data.setVisual('decal', mergeDecal(specifiedDecal, paletteDecal));
+                }
+
+                function mergeDecal(specifiedDecal: DecalObject, paletteDecal: DecalObject): DecalObject {
+                    // Merge decal from palette to decal from itemStyle.
+                    // User do not need to specify all of the decal props.
+                    const resultDecal = specifiedDecal
+                        ? zrUtil.extend(zrUtil.extend({}, paletteDecal), specifiedDecal)
                         : paletteDecal;
-                    (decal as InnerDecalObject).dirty = true;
-                    data.setVisual('decal', decal);
+                    (resultDecal as InnerDecalObject).dirty = true;
+                    return resultDecal;
                 }
             });
         }
diff --git a/src/visual/style.ts b/src/visual/style.ts
index aaa866d..e8c6832 100644
--- a/src/visual/style.ts
+++ b/src/visual/style.ts
@@ -90,6 +90,9 @@ const seriesStyleTask: StageHandler = {
         const colorCallback = isFunction(color) ? color as unknown as ColorCallback : null;
         // Get from color palette by default.
         if (!globalStyle[colorKey] || colorCallback) {
+            // Note: if some series has color specified (e.g., by itemStyle.color), we DO NOT
+            // make it effect palette. Bacause some scenarios users need to make some series
+            // transparent or as background, which should better not effect the palette.
             globalStyle[colorKey] = seriesModel.getColorFromPalette(
                 // TODO series count changed.
                 seriesModel.name, null, ecModel.getSeriesCount()
diff --git a/test/decal.html b/test/decal.html
index da1d9b6..bb449a2 100644
--- a/test/decal.html
+++ b/test/decal.html
@@ -175,7 +175,7 @@ under the License.
                 title: [
                     'It should use decal when aria.show is true',
                     '(1) Each bar and pie piece should have different decal',
-                    '(2) The first bar and pie piece decal should be blue'
+                    '(2) The first bar and pie piece decal should be **blue**'
                 ],
                 option: option
                 // height: 300,
@@ -245,7 +245,7 @@ under the License.
             var chart = testHelper.create(echarts, 'main1', {
                 title: [
                     'If aria is not enabled, decal can also be enabled',
-                    '(1) Only the first bar and pie piece should use decal',
+                    '(1) Only the first bar and pie piece should use decal (be **blue**)',
                     '(2) `aria.label` should be in the HTML'
                 ],
                 option: option


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