Skip to content

Commit 154c418

Browse files
committed
added node dragging
1 parent 7032a93 commit 154c418

File tree

2 files changed

+94
-19
lines changed

2 files changed

+94
-19
lines changed

src/charts/topology-map/examples/topology-map-view.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@
1111
<example module="patternfly.charts">
1212
<file name="index.html">
1313
<div ng-controller="TopologyMapCtrl" class="container-topology">
14-
<pf-topology-map nodes="nodes" edges="edges"></pf-topology-map>
14+
<pf-topology-map nodes="nodes" edges="edges" selected-node="selected"></pf-topology-map>
15+
{{selected}}
1516
</div>
1617
</file>
1718
<file name="script.js">
1819
angular.module( 'patternfly.charts' ).controller( 'TopologyMapCtrl', function( $scope, $rootScope ) {
20+
$scope.selected = {};
1921
$scope.nodes = [
2022
{
2123
id: 1,
2224
title: 'testNode',
2325
icon: '\uF044',
2426
usage: 50,
27+
opacity: 0.5,
2528
},
2629
{
2730
id: 2,
@@ -34,7 +37,19 @@
3437
$scope.edges = [{
3538
source: 0,
3639
target: 1,
37-
}];
40+
},{
41+
source: 5,
42+
target: 1,
43+
},{
44+
source: 3,
45+
target: 1,
46+
},{
47+
source: 3,
48+
target: 5,
49+
},{
50+
source: 3,
51+
target: 2,
52+
},];
3853
});
3954
</file>
4055
</example>

src/charts/topology-map/topologyMap.component.js

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ angular.module('patternfly.charts').component('pfTopologyMap', {
44
edges: '<',
55
force: '<?',
66
radius: '<?',
7+
selectedNode: '<?'
78
},
89
templateUrl: 'charts/topology-map.html',
910
controller: function ($element) {
@@ -19,18 +20,31 @@ angular.module('patternfly.charts').component('pfTopologyMap', {
1920
var transform;
2021
var options;
2122
var radius = ctrl.radius || 17;
22-
23-
ctrl.scale = 1;
23+
var draggedNode;
2424
ctrl.canvas;
2525
ctrl.showLabels = false;
2626

2727
this.$onInit = function () {
2828
setUpCanvas();
2929
setUpForce();
3030
setUpZoom();
31-
setUpClick();
31+
setUpDrag();
32+
setUpSelection();
3233
};
3334

35+
function setUpSelection () {
36+
var canvas = d3.select(ctrl.canvas);
37+
canvas.on('click', click);
38+
39+
function click () {
40+
if (d3.event.defaultPrevented) {
41+
return;
42+
}
43+
console.log('event: ', d3.event);
44+
ctrl.selectedNode = findNode((d3.event.offsetX - ctrl.translate[0]) / ctrl.scale, (d3.event.offsetY - ctrl.translate[1]) / ctrl.scale);
45+
}
46+
}
47+
3448
function setUpCanvas () {
3549
var coords;
3650
options = {force: ctrl.force, radius: ctrl.radius};
@@ -49,10 +63,46 @@ angular.module('patternfly.charts').component('pfTopologyMap', {
4963
ctrl.context.font = '17px FontAwesome';
5064
}
5165

52-
function setUpClick () {
53-
d3.select(ctrl.canvas).on('click', function () {
54-
console.log('click: ', d3.select(this));
66+
function findNode (x, y) {
67+
var result = undefined;
68+
ctrl.force.nodes().forEach(function (node) {
69+
if (Math.pow((x - node.x), 2) + Math.pow((y - node.y), 2) < Math.pow(node.size, 2)) {
70+
result = node;
71+
ctrl.draggedNode = node;
72+
}
5573
});
74+
return result;
75+
}
76+
77+
function setUpDrag () {
78+
var drag = d3.behavior.drag();
79+
var canvas = d3.select(ctrl.canvas);
80+
canvas.call(drag.on('dragstart', onDragStart).on('drag', onDrag).on('dragend', onDragEnd));
81+
function onDragStart () {
82+
d3.event.sourceEvent.stopPropagation();
83+
ctrl.draggedNode = findNode((d3.event.sourceEvent.offsetX - ctrl.translate[0]) / ctrl.scale, (d3.event.sourceEvent.offsetY - ctrl.translate[1]) / ctrl.scale);
84+
}
85+
function onDrag () {
86+
var newX = (d3.event.sourceEvent.offsetX - ctrl.translate[0]) / ctrl.scale;
87+
var newY = (d3.event.sourceEvent.offsetY - ctrl.translate[1]) / ctrl.scale;
88+
if (ctrl.draggedNode) {
89+
ctrl.draggedNode.x = newX;
90+
ctrl.draggedNode.y = newY;
91+
ctrl.draggedNode.px = newX;
92+
ctrl.draggedNode.py = newY;
93+
ctrl.draggedNode.fixed = true;
94+
ctrl.force.nodes()[ctrl.draggedNode.index] = ctrl.draggedNode;
95+
ctrl.force.start();
96+
}
97+
}
98+
function onDragEnd () {
99+
if (ctrl.draggedNode) {
100+
ctrl.force.nodes()[ctrl.draggedNode.index] = ctrl.draggedNode;
101+
ctrl.draggedNode = undefined;
102+
ctrl.force.on('tick')();
103+
//ctrl.force.start();
104+
}
105+
}
56106
}
57107

58108
function setUpZoom () {
@@ -68,15 +118,22 @@ angular.module('patternfly.charts').component('pfTopologyMap', {
68118
function zoomed () {
69119
var t = zoom.translate();
70120
var s = zoom.scale();
71-
ctrl.scale = s;
72-
121+
if (ctrl.draggedNode) {
122+
return;
123+
}
73124
ctrl.context.clearRect(0, 0, ctrl.canvasW, ctrl.canvasH);
74-
125+
ctrl.translate = t;
126+
ctrl.scale = s;
127+
ctrl.force.stop();
75128
ctrl.context.save();
76129
ctrl.context.translate(t[0], t[1]);
77-
ctrl.context.scale(s, s);
78130
ctrl.force.on('tick')();
79131
ctrl.context.restore();
132+
if (ctrl.scale === 1) {
133+
ctrl.context.translate(0, 0);
134+
ctrl.translate = [0, 0];
135+
ctrl.force.start();
136+
}
80137
}
81138
}
82139

@@ -93,23 +150,27 @@ angular.module('patternfly.charts').component('pfTopologyMap', {
93150
.links(ctrl.edges)
94151
.on('tick', tick)
95152
.start();
153+
96154
function tick () {
97155
ctrl.context.clearRect(0, 0, ctrl.canvasW, ctrl.canvasH);
98156
drawEdges();
99157
drawNodes();
158+
ctrl.context.save();
159+
ctrl.context.translate(ctrl.translate[0], ctrl.translate[1]);
160+
ctrl.context.restore();
100161
if (ctrl.scale !== 1) {
101162
drawMiniMap();
102163
}
103164
}
104165
}
105166

106167
function drawEdges () {
107-
ctrl.context.strokeStyle = "#ccc";
168+
ctrl.context.strokeStyle = 'rgba(150, 150, 150, 0.6)';
108169
ctrl.context.beginPath();
109170
ctrl.edges.forEach(function (d) {
110171
ctrl.context.lineWidth = 1;
111-
ctrl.context.moveTo(d.source.x, d.source.y);
112-
ctrl.context.lineTo(d.target.x, d.target.y);
172+
ctrl.context.moveTo(ctrl.scale * d.source.x, ctrl.scale * d.source.y);
173+
ctrl.context.lineTo(ctrl.scale * d.target.x, ctrl.scale * d.target.y);
113174
});
114175
ctrl.context.stroke();
115176
}
@@ -121,19 +182,18 @@ angular.module('patternfly.charts').component('pfTopologyMap', {
121182
}
122183

123184
function drawNodes () {
124-
// draw circle
125185
ctrl.nodes.forEach(function (node) {
126186
normalizeNode(node);
127187
ctrl.context.beginPath();
128188
ctrl.context.fillStyle = node.fill || "steelblue";
129189
ctrl.context.moveTo(node.x, node.y);
130-
ctrl.context.arc(node.x, node.y, 17, 0, 2 * Math.PI);
190+
ctrl.context.arc(ctrl.scale * node.x, ctrl.scale * node.y, 17, 0, 2 * Math.PI);
131191
ctrl.context.fill();
132192

133193
if (node.usage) {
134194
ctrl.context.beginPath();
135195
ctrl.context.lineWidth = 5;
136-
ctrl.context.arc(node.x, node.y, node.size, 0, ((node.usage / 100) * 2) * Math.PI);
196+
ctrl.context.arc(ctrl.scale * node.x, ctrl.scale * node.y, node.size, 0, ((node.usage / 100) * 2) * Math.PI);
137197
ctrl.context.strokeStyle = '#003300';
138198
ctrl.context.stroke();
139199
}
@@ -143,7 +203,7 @@ angular.module('patternfly.charts').component('pfTopologyMap', {
143203
ctrl.context.fillStyle = 'white';
144204
ctrl.context.textAlign = 'center';
145205
ctrl.context.textBaseline = 'middle';
146-
ctrl.context.fillText(node.icon || '\uF049', node.x, node.y);
206+
ctrl.context.fillText(node.icon || '\uF049', ctrl.scale * node.x, ctrl.scale * node.y);
147207
ctrl.context.fill();
148208
});
149209
}

0 commit comments

Comments
 (0)