You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by de...@apache.org on 2018/05/02 11:39:47 UTC

[incubator-echarts] 04/05: add focus node adjacency for sankey view

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

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

commit 54947c80e694ec36d398f8da29515f3d62699c38
Author: deqingli <an...@gmail.com>
AuthorDate: Wed May 2 17:25:09 2018 +0800

    add focus node adjacency for sankey view
---
 src/chart/graph/GraphView.js             |   2 +-
 src/chart/graph/graphAction.js           |   2 +-
 src/chart/sankey/SankeySeries.js         |   2 +
 src/chart/sankey/SankeyView.js           | 162 +++++++++++++++++++++++++++++--
 src/chart/sankey/sankeyAction.js         |   6 ++
 src/chart/themeRiver/themeRiverVisual.js |   2 +-
 src/chart/tree/TreeSeries.js             |   1 +
 src/chart/tree/TreeView.js               |   1 +
 test/sankey-test.html                    |   3 +
 9 files changed, 169 insertions(+), 12 deletions(-)

diff --git a/src/chart/graph/GraphView.js b/src/chart/graph/GraphView.js
index c0a7a59..ceb64a5 100644
--- a/src/chart/graph/GraphView.js
+++ b/src/chart/graph/GraphView.js
@@ -132,7 +132,7 @@ export default echarts.extendChartView({
             var itemModel = data.getItemModel(idx);
             // Update draggable
             el.off('drag').off('dragend');
-            var draggable = data.getItemModel(idx).get('draggable');
+            var draggable = itemModel.get('draggable');
             if (draggable) {
                 el.on('drag', function () {
                     if (forceLayout) {
diff --git a/src/chart/graph/graphAction.js b/src/chart/graph/graphAction.js
index ee62c2e..6f7bc13 100644
--- a/src/chart/graph/graphAction.js
+++ b/src/chart/graph/graphAction.js
@@ -19,7 +19,7 @@
 
 import * as echarts from '../../echarts';
 import {updateCenterAndZoom} from '../../action/roamHelper';
-import '../focusNodeAdjacencyAction';
+import '../helper/focusNodeAdjacencyAction';
 
 var actionInfo = {
     type: 'graphRoam',
diff --git a/src/chart/sankey/SankeySeries.js b/src/chart/sankey/SankeySeries.js
index 1835c09..f1f0339 100644
--- a/src/chart/sankey/SankeySeries.js
+++ b/src/chart/sankey/SankeySeries.js
@@ -112,6 +112,8 @@ var SankeySeries = SeriesModel.extend({
         // control if the node can move or not
         draggable: true,
 
+        focusNodeAdjacency: 'outEdges',
+
         // the number of iterations to change the position of the node
         layoutIterations: 32,
 
diff --git a/src/chart/sankey/SankeyView.js b/src/chart/sankey/SankeyView.js
index 180f491..5068f31 100644
--- a/src/chart/sankey/SankeyView.js
+++ b/src/chart/sankey/SankeyView.js
@@ -24,6 +24,43 @@
 
 import * as graphic from '../../util/graphic';
 import * as echarts from '../../echarts';
+import * as zrUtil from 'zrender/src/core/util';
+
+var nodeOpacityPath = ['itemStyle', 'opacity'];
+var lineOpacityPath = ['lineStyle', 'opacity'];
+
+function getItemOpacity(item, opacityPath) {
+    return item.getVisual('opacity') || item.getModel().get(opacityPath);
+}
+
+function fadeOutItem(item, opacityPath, opacityRatio) {
+    var el = item.getGraphicEl();
+
+    var opacity = getItemOpacity(item, opacityPath);
+    if (opacityRatio != null) {
+        opacity == null && (opacity = 1);
+        opacity *= opacityRatio;
+    }
+
+    el.downplay && el.downplay();
+    el.traverse(function (child) {
+        if (child.type !== 'group') {
+            child.setStyle('opacity', opacity);
+        }
+    });
+}
+
+function fadeInItem(item, opacityPath) {
+    var opacity = getItemOpacity(item, opacityPath);
+    var el = item.getGraphicEl();
+
+    el.highlight && el.highlight();
+    el.traverse(function (child) {
+        if (child.type !== 'group') {
+            child.setStyle('opacity', opacity);
+        }
+    });
+}
 
 var SankeyShape = graphic.extendShape({
     shape: {
@@ -180,10 +217,11 @@ export default echarts.extendChartView({
 
             rect.dataType = 'node';
         });
-
-        var draggable = seriesModel.get('draggable');
-        if (draggable) {
-            nodeData.eachItemGraphicEl(function (el, dataIndex) {
+       
+        nodeData.eachItemGraphicEl(function (el, dataIndex) {
+            var itemModel = nodeData.getItemModel(dataIndex);
+            // var draggable = seriesModel.get('draggable');
+            if (itemModel.get('draggable')) {
                 el.drift = function (dx, dy) {
                     this.shape.x += dx;
                     this.shape.y += dy;
@@ -199,9 +237,45 @@ export default echarts.extendChartView({
         
                 el.draggable = true;
                 el.cursor = 'move';
-            });
-        }
-        
+
+            }
+            
+            if (itemModel.get('focusNodeAdjacency')) {
+                el.off('mouseover').on('mouseover', function () {
+                    api.dispatchAction({
+                        type: 'focusNodeAdjacency',
+                        seriesId: seriesModel.id,
+                        dataIndex: el.dataIndex
+                    });
+                });
+                el.off('mouseout').on('mouseout', function () {
+                    api.dispatchAction({
+                        type: 'unfocusNodeAdjacency',
+                        seriesId: seriesModel.id
+                    })
+                });
+            }
+        });
+
+        edgeData.eachItemGraphicEl(function (el, dataIndex) {
+            var edgeModel = edgeData.getItemModel(dataIndex);
+            if (edgeModel.get('focusNodeAdjacency')) {
+                el.off('mouseover').on('mouseover', function () {
+                    api.dispatchAction({
+                        type: 'focusNodeAdjacency',
+                        seriesId: seriesModel.id,
+                        edgeDataIndex: el.dataIndex
+                    });
+                });
+                el.off('mouseout').on('mouseout', function () {
+                    api.dispatchAction({
+                        type: 'unfocusNodeAdjacency',
+                        seriesId: seriesModel.id,
+                    });
+                })
+            }
+        });
+
         if (!this._data && seriesModel.get('animation')) {
             group.setClipPath(createGridClipShape(group.getBoundingRect(), seriesModel, function () {
                 group.removeClipPath();
@@ -211,7 +285,77 @@ export default echarts.extendChartView({
         this._data = seriesModel.getData();
     },
 
-    dispose: function () {}
+    dispose: function () {},
+
+    focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
+        var data = this._model.getData();
+        var graph = data.graph;
+        var dataIndex = payload.dataIndex;
+        var itemModel = data.getItemModel(dataIndex);
+        var edgeDataIndex = payload.edgeDataIndex;
+        
+        if (!dataIndex && !edgeDataIndex) {
+            return;
+        }
+        var node = graph.getNodeByIndex(dataIndex);
+        var edge = graph.getEdgeByIndex(edgeDataIndex);
+
+        graph.eachNode(function (node) {
+            fadeOutItem(node, nodeOpacityPath, 0.1);
+        });
+        graph.eachEdge(function (edge) {
+            fadeOutItem(edge, lineOpacityPath, 0.1);
+        });
+
+        if (node) {
+            fadeInItem(node, nodeOpacityPath);
+            var focusNodeAdjacency = itemModel.get('focusNodeAdjacency');
+            if (focusNodeAdjacency === 'outEdges') {
+                zrUtil.each(node.outEdges, function (edge) {
+                    if (edge.dataIndex < 0) {
+                        return;
+                    }
+                    fadeInItem(edge, lineOpacityPath);
+                    fadeInItem(edge.node2, nodeOpacityPath);
+                });
+            }
+            else if (focusNodeAdjacency === 'inEdges') {
+                zrUtil.each(node.inEdges, function (edge) {
+                    if (edge.dataIndex < 0) {
+                        return;
+                    }
+                    fadeInItem(edge, lineOpacityPath);
+                    fadeInItem(edge.node1, nodeOpacityPath);
+                });
+            }
+            else if (focusNodeAdjacency === 'allEdges') {
+                zrUtil.each(node.edges, function (edge) {
+                    if (edge.dataIndex < 0) {
+                        return;
+                    }
+                    fadeInItem(edge, lineOpacityPath);
+                    fadeInItem(edge.node1, nodeOpacityPath);
+                    fadeInItem(edge.node2, nodeOpacityPath);
+                });
+            }
+        }
+        if (edge) {
+            fadeInItem(edge, lineOpacityPath);
+            fadeInItem(edge.node1, nodeOpacityPath);
+            fadeInItem(edge.node2, nodeOpacityPath);
+        }
+    },
+
+    unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
+        var graph = this._model.getGraph();
+
+        graph.eachNode(function (node) {
+            fadeOutItem(node, nodeOpacityPath);
+        });
+        graph.eachEdge(function (edge) {
+            fadeOutItem(edge, lineOpacityPath);
+        });
+    }
 });
 
 // add animation to the view
@@ -232,4 +376,4 @@ function createGridClipShape(rect, seriesModel, cb) {
     }, seriesModel, cb);
 
     return rectEl;
-}
\ No newline at end of file
+}
diff --git a/src/chart/sankey/sankeyAction.js b/src/chart/sankey/sankeyAction.js
index 8683eec..5a0ad64 100644
--- a/src/chart/sankey/sankeyAction.js
+++ b/src/chart/sankey/sankeyAction.js
@@ -17,7 +17,13 @@
 * under the License.
 */
 
+/**
+ * @file The interactive action of sankey view
+ * @author Deqing Li(annong035@gmail.com)
+ */
+
 import * as echarts from '../../echarts';
+import '../helper/focusNodeAdjacencyAction';
 
 echarts.registerAction({
     type: 'dragNode',
diff --git a/src/chart/themeRiver/themeRiverVisual.js b/src/chart/themeRiver/themeRiverVisual.js
index 13da281..78d8394 100644
--- a/src/chart/themeRiver/themeRiverVisual.js
+++ b/src/chart/themeRiver/themeRiverVisual.js
@@ -19,7 +19,7 @@
 
 /**
  * @file Visual encoding for themeRiver view
- * @author  Deqing Li(annong035@gmail.com)
+ * @author Deqing Li(annong035@gmail.com)
  */
 
 import {createHashMap} from 'zrender/src/core/util';
diff --git a/src/chart/tree/TreeSeries.js b/src/chart/tree/TreeSeries.js
index 635a7b0..8d632a1 100644
--- a/src/chart/tree/TreeSeries.js
+++ b/src/chart/tree/TreeSeries.js
@@ -19,6 +19,7 @@
 
 /**
  * @file Create data struct and define tree view's series model
+ * @author Deqing Li(annong035@gmail.com)
  */
 
 import SeriesModel from '../../model/Series';
diff --git a/src/chart/tree/TreeView.js b/src/chart/tree/TreeView.js
index 483e41b..247813a 100644
--- a/src/chart/tree/TreeView.js
+++ b/src/chart/tree/TreeView.js
@@ -19,6 +19,7 @@
 
 /**
  * @file  This file used to draw tree view
+ * @author Deqing Li(annong035@gmail.com)
  */
 
 import * as zrUtil from 'zrender/src/core/util';
diff --git a/test/sankey-test.html b/test/sankey-test.html
index a609d96..f7df01c 100644
--- a/test/sankey-test.html
+++ b/test/sankey-test.html
@@ -172,6 +172,9 @@
                                 bottom: '10%',
                                 data: testData.nodes,
                                 links: testData.links,
+                                label: {
+                                    position: 'left'
+                                },
                                 // Used to test when the data is null whether it is work well. 
                                 // data: [],
                                 // links: [],

-- 
To stop receiving notification emails like this one, please contact
deqingli@apache.org.

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