David
David

Reputation: 345

Parenting D3.js-Nodes for dragging

I have a network of nodes and links. One of them has a fixed position in the center but is draggable, the others are in a force field around the centered one. If the user drags any node, the others will be draged behind him, because the are linked. Is there a possibility to drag the others with the centered node, but keeping the drag-event of the other nodes single?

thanks for thinking about it, David

edit: if someone knew a possibility to set a dragg-listener for all the other nodes to the centered one, the problem would be solved. I'd be grateful if you had an idea! Please leave me a comment which parts of th ecode could help you solve this issue, and I'll post it asap!

edit: with the help of nrabinowitz I can now move the nodes just as I wanted! But the new code-parts somehow crashed my coordinate-restrictions. For the nodes not to drop out of the svg, I put a cx/cy-attr to all nodes, preventing them from crossing the border of svg. This still works in the beginning, but after the first drag of the center-node (and therefore the 'g'-element) the restrictions seem to shift. Is there anything dragged except the svg?

The part of the script providing the restriction is

force.on("tick", function() {

   node.attr("cx", function(d) { return d.x = Math.max(15, Math.min(width - 15, d.x)); })
       .attr("cy", function(d) { return d.y = Math.max(15, Math.min(height - 15, d.y)); });
   node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

   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; });
});

Upvotes: 0

Views: 1628

Answers (1)

nrabinowitz
nrabinowitz

Reputation: 55688

See working fiddle: http://jsfiddle.net/nrabinowitz/4Rj4z/

This encloses the nodes in a g element, and uses the transform attribute to move them around.

In order to get this to work, you can't use force.drag for the node you want to have pull the group - you need a custom d3.behavior.drag. Unfortunately, per this answer, you can't put the drag handler on the node itself - it needs to be on the group. This works, but it means that other elements without a separate drag handler - e.g. links - will also drag the group. You might be able to fix this with pointer-events on the group.

Upvotes: 2

Related Questions