-
-
Save norrs/2883411 to your computer and use it in GitHub Desktop.
<!DOCTYPE html> | |
<html> | |
<head> | |
<script type="text/javascript" src="http://d3js.org/d3.v2.js"></script> | |
<style type="text/css"> | |
.link { stroke: #ccc; } | |
.nodetext { pointer-events: none; font: 10px sans-serif; } | |
</style> | |
</head> | |
<body> | |
<h3><a href="http://stackoverflow.com/questions/10899725/d3-js-force-directed-graph-with-support-for-drag-and-drop-to-make-selected-node">http://stackoverflow.com/questions/10899725/d3-js-force-directed-graph-with-support-for-drag-and-drop-to-make-selected-node</a></h3> | |
<script type="text/javascript"> | |
var w = 960, | |
h = 500 | |
var vis = d3.select("body").append("svg:svg") | |
.attr("width", w) | |
.attr("height", h); | |
d3.json("graph.json", function(json) { | |
var force = self.force = d3.layout.force() | |
.nodes(json.nodes) | |
.links(json.links) | |
.gravity(.05) | |
.distance(100) | |
.charge(-100) | |
.size([w, h]) | |
.start(); | |
var link = vis.selectAll("line.link") | |
.data(json.links) | |
.enter().append("svg:line") | |
.attr("class", "link") | |
.attr("x1", function(d) { return d.source.x; }) | |
.attr("y1", function(d) { return d.source.y; }) | |
.attr("x2", function(d) { return d.target.x; }) | |
.attr("y2", function(d) { return d.target.y; }); | |
var node_drag = d3.behaviour.drag() | |
.on("dragstart", dragstart) | |
.on("drag", dragmove) | |
.on("dragend", dragend); | |
function dragstart(d, i) { | |
force.stop() // stops the force auto positioning before you start dragging | |
} | |
function dragmove(d, i) { | |
d.px += d3.event.dx; | |
d.py += d3.event.dy; | |
d.x += d3.event.dx; | |
d.y += d3.event.dy; | |
tick(); // this is the key to make it work together with updating both px,py,x,y on d ! | |
} | |
function dragend(d, i) { | |
d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff | |
tick(); | |
force.resume(); | |
} | |
var node = vis.selectAll("g.node") | |
.data(json.nodes) | |
.enter().append("svg:g") | |
.attr("class", "node") | |
.call(node_drag); | |
node.append("svg:image") | |
.attr("class", "circle") | |
.attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png") | |
.attr("x", "-8px") | |
.attr("y", "-8px") | |
.attr("width", "16px") | |
.attr("height", "16px"); | |
node.append("svg:text") | |
.attr("class", "nodetext") | |
.attr("dx", 12) | |
.attr("dy", ".35em") | |
.text(function(d) { return d.name }); | |
force.on("tick", function() { | |
link.attr("x1", function(d) { return d.source.x; }) | |
.attr("y1", function(d) { return d.source.y; }) | |
.attr("x2", function(d) { return d.target.x; }) | |
.attr("y2", function(d) { return d.target.y; }); | |
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
@ducksmanager :
Working as intended, node will not be positioned by the force simulation if the fixed value is set to true. As this example simple sets the dropped node fixed value to true, it get's excluded in the force layout simulation.
I guess you could easily write some code that sets neighbors 'fixed' value to false for the node you drop. So if you drop B, check neighbors for B and set it's neighbors to false.
http://jsfiddle.net/xReHA/2/ I guess would help you to determine which nodes are linked to the one your selected/dropping :-)
If I have some free time, I can probably hack together another demo which does what you want.
That would be great ! Keep me in touch : I'm not sure I would succeed in hacking the script myself ^^
Hey I am new to the data visualization world and really like your solution to a problem I am having with the force directed graph. I am not sure I understand the .json file. I would like to create one with some live data I have but do not understand the source target linking with the names can you explain how the numbers match up with the names?
Hi,
There seems to be a small bug : when you have drag'n'dropped a node A, its position gets fixed : if you drag'n'drop another node (B) linked to A, A won't move anymore. Is this a normal behaviour ?