0

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; });
});
David
  • 335
  • 3
  • 16
  • Do you mean drag non-connected nodes? Or drag connected nodes all at once, rather than according to force? Can you include some example code, or link to a JSFiddle? – nrabinowitz Nov 21 '12 at 18:07
  • they are all connected in one net. it's more like take any node to move it single, take the central node to drag the whole network as if the network itself was an object with a drag-event! – David Jan 11 '13 at 08:09
  • is there a possibility to place a second svg or some kind of container-element around the network that would respond to the drag-event of the central node? – David Jan 23 '13 at 14:45

1 Answers1

2

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.

Community
  • 1
  • 1
nrabinowitz
  • 55,314
  • 10
  • 149
  • 165
  • thank you very much, this looks exactly like the thing I was looking for! – David Jan 31 '13 at 07:12
  • it's working perfectly, only problem is that it conflicts with my bounding-box thing. to prevent elements from floating out of svg, I limit the coordinates of my nodes in a final force.on(starting at line 52 in your example). that is where I added a node.attr("cx")/cy. But now that I have included your idea with the g-element and the seperate handler, it's not woorking anymore. the restrictions seem to shift in unknown ways after dragging. if i find a solution, I'll post it :) – David Jan 31 '13 at 10:04