D3.js Dynamic connector between objects

babyjet picture babyjet · Sep 7, 2013 · Viewed 16.9k times · Source

I'm very new to both JS and D3, and I've googled this a tonne but only found examples that are a bit too advanced.

I'm making a simple decision graph implementation, and I'm stuck trying to connect 2 nodes with a line / path. The objects can be moved around with the mouse, and the path should always update to reflect the positions of the objects.

This is my base source of knowledge: https://github.com/mbostock/d3/wiki/SVG-Shapes, but I don't quite understand how to do something smart with it.

Here is what I have so far: http://jsbin.com/AXEFERo/5/edit

Don't need the fancy stuff, just need to understand how to create connectors and have them update dynamically when the objects are being dragged around. Big thanks!

Answer

Lars Kotthoff picture Lars Kotthoff · Sep 7, 2013

To draw a line between the circles, you don't need anything special -- just the line element.

var line = svg.append("line")
        .style("stroke", "black")
        .attr("x1", 150)
        .attr("y1", 100)
        .attr("x2", 250)
        .attr("y2", 300);

Updating the position dynamically is a bit more difficult. At the moment, you have no means of distinguishing which of the circles is being dragged. One way of doing this is to add a distinguishing class to the g elements.

var g1 = svg.append("g")
        .attr("transform", "translate(" + 150 + "," + 100 + ")")
        .attr("class", "first")
        ...

and similarly for the other one. Now you can switch on the class in your dragmove function and update either the start or the end coordinates of the line.

if(d3.select(this).attr("class") == "first") {
            line.attr("x1", x);
            line.attr("y1", y);
} else {
            line.attr("x2", x);
            line.attr("y2", y);
}

Complete example here. There are other, more elegant ways of achieving this. In a real application, you would have data bound to the elements and could use that to distinguish between the different circles.