You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2019/11/28 16:10:51 UTC

[incubator-echarts] 01/01: fix(legend): legend of pie/funnel can pick from visualMap encoded color #10766

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

shenyi pushed a commit to branch pie-visual-color
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git

commit ae4beb5961c932bf1850805fedb12e6d5749dc88
Author: pissang <bm...@gmail.com>
AuthorDate: Thu Nov 28 23:56:18 2019 +0800

    fix(legend): legend of pie/funnel can pick from visualMap encoded color #10766
---
 src/chart/funnel/FunnelSeries.js         |   8 +-
 src/chart/graph/GraphSeries.js           |  11 ++-
 src/chart/pie/PieSeries.js               |   7 +-
 src/chart/radar/RadarSeries.js           |   8 +-
 src/chart/themeRiver/ThemeRiverSeries.js |   7 +-
 src/component/legend/LegendModel.js      |   6 +-
 src/component/legend/LegendView.js       |  18 +++--
 src/model/Series.js                      |   4 +-
 src/visual/LegendVisualProvider.js       |  55 +++++++++++++
 src/visual/dataColor.js                  |  13 ----
 test/legend-visualMapColor.html          | 130 +++++++++++++++++++++++++++++++
 11 files changed, 226 insertions(+), 41 deletions(-)

diff --git a/src/chart/funnel/FunnelSeries.js b/src/chart/funnel/FunnelSeries.js
index d241cf8..9c4d614 100644
--- a/src/chart/funnel/FunnelSeries.js
+++ b/src/chart/funnel/FunnelSeries.js
@@ -20,6 +20,8 @@
 import * as echarts from '../../echarts';
 import createListSimply from '../helper/createListSimply';
 import {defaultEmphasis} from '../../util/model';
+import LegendVisualProvider from '../../visual/LegendVisualProvider';
+import {bind} from 'zrender/src/core/util';
 
 var FunnelSeries = echarts.extendSeriesModel({
 
@@ -30,9 +32,9 @@ var FunnelSeries = echarts.extendSeriesModel({
 
         // Enable legend selection for each data item
         // Use a function instead of direct access because data reference may changed
-        this.legendDataProvider = function () {
-            return this.getRawData();
-        };
+        this.legendVisualProvider = new LegendVisualProvider(
+            bind(this.getData, this), bind(this.getRawData, this)
+        );
         // Extend labelLine emphasis
         this._defaultLabelLine(option);
     },
diff --git a/src/chart/graph/GraphSeries.js b/src/chart/graph/GraphSeries.js
index 2ea09b2..47d9fd9 100644
--- a/src/chart/graph/GraphSeries.js
+++ b/src/chart/graph/GraphSeries.js
@@ -24,6 +24,7 @@ import {defaultEmphasis} from '../../util/model';
 import Model from '../../model/Model';
 import {encodeHTML} from '../../util/format';
 import createGraphFromNodeEdge from '../helper/createGraphFromNodeEdge';
+import LegendVisualProvider from '../../visual/LegendVisualProvider';
 
 var GraphSeries = echarts.extendSeriesModel({
 
@@ -32,10 +33,14 @@ var GraphSeries = echarts.extendSeriesModel({
     init: function (option) {
         GraphSeries.superApply(this, 'init', arguments);
 
+        var self = this;
+        function getCategoriesData() {
+            return self._categoriesData;
+        }
         // Provide data for legend select
-        this.legendDataProvider = function () {
-            return this._categoriesData;
-        };
+        this.legendVisualProvider = new LegendVisualProvider(
+            getCategoriesData, getCategoriesData
+        );
 
         this.fillDataTextStyle(option.edges || option.links);
 
diff --git a/src/chart/pie/PieSeries.js b/src/chart/pie/PieSeries.js
index 42a44e6..a4abb3a 100644
--- a/src/chart/pie/PieSeries.js
+++ b/src/chart/pie/PieSeries.js
@@ -24,6 +24,7 @@ import * as modelUtil from '../../util/model';
 import {getPercentWithPrecision} from '../../util/number';
 import dataSelectableMixin from '../../component/helper/selectableMixin';
 import {retrieveRawAttr} from '../../data/helper/dataProvider';
+import LegendVisualProvider from '../../visual/LegendVisualProvider';
 
 
 var PieSeries = echarts.extendSeriesModel({
@@ -36,9 +37,9 @@ var PieSeries = echarts.extendSeriesModel({
 
         // Enable legend selection for each data item
         // Use a function instead of direct access because data reference may changed
-        this.legendDataProvider = function () {
-            return this.getRawData();
-        };
+        this.legendVisualProvider = new LegendVisualProvider(
+            zrUtil.bind(this.getData, this), zrUtil.bind(this.getRawData, this)
+        );
 
         this.updateSelectedMap(this._createSelectableList());
 
diff --git a/src/chart/radar/RadarSeries.js b/src/chart/radar/RadarSeries.js
index ef9e60b..8d6d7b4 100644
--- a/src/chart/radar/RadarSeries.js
+++ b/src/chart/radar/RadarSeries.js
@@ -21,6 +21,7 @@ import SeriesModel from '../../model/Series';
 import createListSimply from '../helper/createListSimply';
 import * as zrUtil from 'zrender/src/core/util';
 import {encodeHTML} from '../../util/format';
+import LegendVisualProvider from '../../visual/LegendVisualProvider';
 
 var RadarSeries = SeriesModel.extend({
 
@@ -35,9 +36,10 @@ var RadarSeries = SeriesModel.extend({
 
         // Enable legend selection for each data item
         // Use a function instead of direct access because data reference may changed
-        this.legendDataProvider = function () {
-            return this.getRawData();
-        };
+        this.legendVisualProvider = new LegendVisualProvider(
+            zrUtil.bind(this.getData, this), zrUtil.bind(this.getRawData, this)
+        );
+
     },
 
     getInitialData: function (option, ecModel) {
diff --git a/src/chart/themeRiver/ThemeRiverSeries.js b/src/chart/themeRiver/ThemeRiverSeries.js
index 5a49a3a..2552a7a 100644
--- a/src/chart/themeRiver/ThemeRiverSeries.js
+++ b/src/chart/themeRiver/ThemeRiverSeries.js
@@ -24,6 +24,7 @@ import List from '../../data/List';
 import * as zrUtil from 'zrender/src/core/util';
 import {groupData} from '../../util/model';
 import {encodeHTML} from '../../util/format';
+import LegendVisualProvider from '../../visual/LegendVisualProvider';
 
 var DATA_NAME_INDEX = 2;
 
@@ -49,9 +50,9 @@ var ThemeRiverSeries = SeriesModel.extend({
         // Put this function here is for the sake of consistency of code style.
         // Enable legend selection for each data item
         // Use a function instead of direct access because data reference may changed
-        this.legendDataProvider = function () {
-            return this.getRawData();
-        };
+        this.legendVisualProvider = new LegendVisualProvider(
+            zrUtil.bind(this.getData, this), zrUtil.bind(this.getRawData, this)
+        );
     },
 
     /**
diff --git a/src/component/legend/LegendModel.js b/src/component/legend/LegendModel.js
index bdb189b..f49cb55 100644
--- a/src/component/legend/LegendModel.js
+++ b/src/component/legend/LegendModel.js
@@ -111,9 +111,9 @@ var LegendModel = echarts.extendComponentModel({
             availableNames.push(seriesName);
             var isPotential;
 
-            if (seriesModel.legendDataProvider) {
-                var data = seriesModel.legendDataProvider();
-                var names = data.mapArray(data.getName);
+            if (seriesModel.legendVisualProvider) {
+                var provider = seriesModel.legendVisualProvider;
+                var names = provider.getAllNames();
 
                 if (!ecModel.isSeriesFiltered(seriesModel)) {
                     availableNames = availableNames.concat(names);
diff --git a/src/component/legend/LegendView.js b/src/component/legend/LegendView.js
index ecb379e..e63bf78 100644
--- a/src/component/legend/LegendView.js
+++ b/src/component/legend/LegendView.js
@@ -175,7 +175,7 @@ export default echarts.extendComponentView({
                 return;
             }
 
-            // Series legend
+            // Legend to control series.
             if (seriesModel) {
                 var data = seriesModel.getData();
                 var color = data.getVisual('color');
@@ -211,22 +211,24 @@ export default echarts.extendComponentView({
                 legendDrawnMap.set(name, true);
             }
             else {
-                // Data legend of pie, funnel
+                // Legend to control data. In pie and funnel.
                 ecModel.eachRawSeries(function (seriesModel) {
+
                     // In case multiple series has same data name
                     if (legendDrawnMap.get(name)) {
                         return;
                     }
 
-                    if (seriesModel.legendDataProvider) {
-                        var data = seriesModel.legendDataProvider();
-                        var idx = data.indexOfName(name);
-                        if (idx < 0) {
+                    if (seriesModel.legendVisualProvider) {
+                        var provider = seriesModel.legendVisualProvider;
+                        if (!provider.containName(name)) {
                             return;
                         }
 
-                        var color = data.getItemVisual(idx, 'color');
-                        var borderColor = data.getItemVisual(idx, 'borderColor');
+                        var idx = provider.indexOfName(name);
+
+                        var color = provider.getItemVisual(idx, 'color');
+                        var borderColor = provider.getItemVisual(idx, 'borderColor');
 
                         var legendSymbolType = 'roundRect';
 
diff --git a/src/model/Series.js b/src/model/Series.js
index 8b090e6..75dee39 100644
--- a/src/model/Series.js
+++ b/src/model/Series.js
@@ -62,11 +62,11 @@ var SeriesModel = ComponentModel.extend({
     defaultOption: null,
 
     /**
-     * Data provided for legend
+     * legend visual provider to the legend component
      * @type {Function}
      */
     // PENDING
-    legendDataProvider: null,
+    legendVisualProvider: null,
 
     /**
      * Access path of color for visual
diff --git a/src/visual/LegendVisualProvider.js b/src/visual/LegendVisualProvider.js
new file mode 100644
index 0000000..a0be73b
--- /dev/null
+++ b/src/visual/LegendVisualProvider.js
@@ -0,0 +1,55 @@
+/*
+* 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.
+*/
+
+
+/**
+ * LegendVisualProvider is an bridge that pick encoded color from data and
+ * provide to the legend component.
+ * @param {Function} getDataWithEncodedVisual Function to get data after filtered. It stores all the encoding info
+ * @param {Function} getRawData Function to get raw data before filtered.
+ */
+function LegendVisualProvider(getDataWithEncodedVisual, getRawData) {
+    this.getAllNames = function () {
+        var rawData = getRawData();
+        // We find the name from the raw data. In case it's filtered by the legend component.
+        // Normally, the name can be found in rawData, but can't be found in filtered data will display as gray.
+        return rawData.mapArray(rawData.getName);
+    };
+
+    this.containName = function (name) {
+        var rawData = getRawData();
+        return rawData.indexOfName(name) >= 0;
+    };
+
+    this.indexOfName = function (name) {
+        // Only get data when necessary.
+        // Because LegendVisualProvider constructor may be new in the stage that data is not prepared yet.
+        // Invoking Series#getData immediately will throw an error.
+        var dataWithEncodedVisual = getDataWithEncodedVisual();
+        return dataWithEncodedVisual.indexOfName(name);
+    };
+
+    this.getItemVisual = function (dataIndex, key) {
+        // Get encoded visual properties from final filtered data.
+        var dataWithEncodedVisual = getDataWithEncodedVisual();
+        return dataWithEncodedVisual.getItemVisual(dataIndex, key);
+    };
+}
+
+export default LegendVisualProvider;
\ No newline at end of file
diff --git a/src/visual/dataColor.js b/src/visual/dataColor.js
index 63c2b84..c32419d 100644
--- a/src/visual/dataColor.js
+++ b/src/visual/dataColor.js
@@ -68,33 +68,20 @@ export default function (seriesType) {
                             dataAll.getName(rawIdx) || (rawIdx + ''), seriesModel.__paletteScope,
                             dataAll.count()
                         );
-                    // Legend may use the visual info in data before processed
-                    dataAll.setItemVisual(rawIdx, 'color', color);
-
                     // Data is not filtered
                     if (filteredIdx != null) {
                         data.setItemVisual(filteredIdx, 'color', color);
                     }
                 }
-                else {
-                    // Set data all color for legend
-                    dataAll.setItemVisual(rawIdx, 'color', singleDataColor);
-                }
 
                 if (!singleDataBorderColor) {
                     var borderColor = itemModel.get('itemStyle.borderColor');
-                    // Legend may use the visual info in data before processed
-                    dataAll.setItemVisual(rawIdx, 'borderColor', borderColor);
 
                     // Data is not filtered
                     if (filteredIdx != null) {
                         data.setItemVisual(filteredIdx, 'borderColor', borderColor);
                     }
                 }
-                else {
-                    // Set data all borderColor for legend
-                    dataAll.setItemVisual(rawIdx, 'borderColor', singleDataBorderColor);
-                }
             });
         }
     };
diff --git a/test/legend-visualMapColor.html b/test/legend-visualMapColor.html
new file mode 100644
index 0000000..6eebe09
--- /dev/null
+++ b/test/legend-visualMapColor.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/esl.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+
+
+        <div id="main0"></div>
+        <div id="main1"></div>
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option;
+            option = {
+                "dataset": [
+                    {
+                    "source": [
+                        [
+                            "Mark3",
+                            "Mark3_desc",
+                            "Role4",
+                            "Role4_desc"
+                        ],
+                        [
+                            "01",
+                            "高档",
+                            61278,
+                            "61278.00"
+                        ],
+                        [
+                            "03",
+                            "中档",
+                            108814,
+                            "108814.00"
+                        ],
+                        [
+                            "04",
+                            "低档",
+                            242664,
+                            "242664.00"
+                        ]
+                    ]
+                    }
+                ],
+                "series": [
+                    {
+                        "type": "pie",
+                        "datasetIndex": 0,
+                        "name": "销售数量",
+                        "encode": {
+                            "value": "Role4",
+                            "itemName": "Mark3_desc"
+                        }
+                    }
+                ],
+                "visualMap": [
+                    {
+                        "show": false,
+                        "inRange": {
+                            "color": [
+                                "#6EB9FF",
+                                "#99DFA2",
+                                "#FDAD29"
+                            ]
+                        },
+                        "dataDefIndex": 0,
+                        "field": "FA_XS_MONTH.JGDC",
+                        "type": "piecewise",
+                        "categories": [
+                            "高档",
+                            "中档",
+                            "低档"
+                        ],
+                        "dimension": "Mark3_desc",
+                        "seriesIndex": 0
+                    }
+                ],
+                "legend": {
+                    "show": true
+                }
+            };
+
+            var chart = testHelper.create(echarts, 'main0', {
+                title: [
+                    'Legend use color from visualMap',
+                    'Test case from #10766'
+                ],
+                option: option
+            });
+        });
+        </script>
+
+    </body>
+</html>
+


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