Skip to content

Commit 125ea93

Browse files
committed
Make force-directed graphs draggable.
1 parent 32c0620 commit 125ea93

3 files changed

Lines changed: 41 additions & 31 deletions

File tree

examples/force/cluster.html

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -157,34 +157,6 @@
157157
return curve(d.path); // 0.8
158158
}
159159

160-
function drag(n) {
161-
var active = null;
162-
n.on("mouseover", function(d) { if (d != active) d.fixed = true; })
163-
.on("mouseout", function(d) { if (d != active) d.fixed = false; })
164-
.on("mousedown", function(d) {
165-
if (d3.event.preventDefault) { d3.event.preventDefault(); }
166-
active = d;
167-
168-
// unregister drag listeners
169-
body.on("mouseup", function(d) {
170-
active = null;
171-
body.on("mouseup", noop)
172-
.on("mousemove", noop);
173-
});
174-
175-
// update node position on drag
176-
body.on("mousemove", function() {
177-
if (active == null) return false;
178-
var m = d3.svg.mouse(vis[0][0]);
179-
active.x = m[0];
180-
active.y = m[1];
181-
force.resume(); // restart annealing
182-
});
183-
184-
return false;
185-
});
186-
}
187-
188160
// --------------------------------------------------------
189161

190162
var body = d3.select("body");
@@ -251,11 +223,12 @@
251223
.attr("r", function(d) { return d.size ? d.size + dr : dr+1; })
252224
.attr("cx", function(d) { return d.x; })
253225
.attr("cy", function(d) { return d.y; })
254-
.call(drag)
255226
.on("dblclick", function(d) {
256227
if (d.size) { expand[d.group] = true; init(); }
257228
});
258-
node = nodeg.selectAll("circle.node");
229+
230+
node = nodeg.selectAll("circle.node")
231+
.call(force.drag);
259232

260233
force.on("tick", function() {
261234
if (!hull.empty()) {

examples/force/force.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ d3.json("miserables.json", function(json) {
3030
.attr("cx", function(d) { return d.x; })
3131
.attr("cy", function(d) { return d.y; })
3232
.attr("r", 5)
33-
.style("fill", function(d) { return fill(d.group); });
33+
.style("fill", function(d) { return fill(d.group); })
34+
.call(force.drag);
3435

3536
vis.attr("opacity", 0)
3637
.transition()

examples/force/layout.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,5 +153,41 @@ function layout_force() {
153153
return force;
154154
};
155155

156+
// use `node.call(force.drag)` to make nodes draggable
157+
force.drag = function() {
158+
var node, element;
159+
160+
this
161+
.on("mouseover", function(d) { d.fixed = true; })
162+
.on("mouseout", function(d) { if (d != node) d.fixed = false; })
163+
.on("mousedown", mousedown);
164+
165+
d3.select(window)
166+
.on("mousemove", mousemove)
167+
.on("mouseup", mouseup);
168+
169+
function mousedown(d) {
170+
(node = d).fixed = true;
171+
element = this;
172+
d3.event.preventDefault();
173+
}
174+
175+
function mousemove() {
176+
if (!node) return;
177+
var m = d3.svg.mouse(element);
178+
node.x = m[0];
179+
node.y = m[1];
180+
force.resume(); // restart annealing
181+
}
182+
183+
function mouseup() {
184+
if (!node) return;
185+
mousemove();
186+
node = element = null;
187+
}
188+
189+
return force;
190+
};
191+
156192
return force;
157193
}

0 commit comments

Comments
 (0)