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