I have the following graph built with d3.

Here's the code I'm using: https://jsfiddle.net/eb2L618g/1/

I'm having trouble with the D3.js API, in particular, how to set the x position of each node based on dynamic data. In particular, when I change the x position of the nodes, the path.links that connect source and target nodes aren't updated correctly and are no longer touching source and target nodes. First, I offset the node x positions:

I added this within the update function:

// Enter any new nodes at the parent's previous position. nodeEnter.append("rect") .attr("y", -barHeight / 2) // added this function to try to offset the x position .attr("x", function(d){ return d.x +20 // hardcode offset for now }) .attr("height", barHeight) .attr("width", barWidth) .style("fill", color) .on("click", click);

The above addition offsets each node from it's parent's x position, so far so good but it broke the alignment of the text inside it, so I added this:

nodeEnter.append("text") .attr("x", function(d){ return d.x +20 }) .attr("dy", 3.5) .attr("dx", 5.5) .text(function(d) { return d.name; });

But now the path.links aren't aligned:

...so I've been playing around with this part of the code:

// Enter any new links at the parent's previous position. link.enter().insert("path", "g") .attr("class", "link") .attr("d", function(d) { var o = {x: source.x0, y: source.y0}; return diagonal({source: o, target: o}); }) .transition() .duration(duration) .attr("d", diagonal); // Transition links to their new position. link.transition() .duration(duration) .attr("d", diagonal);

I've tried changing the diagonal function's source and target values but it seems to not do anything. I'm missing something about how path.links are aligned with their source and target nodes. I'm looking through the D3.js docs but would like to see if anyone can point me in the right direction or notice any flaws or missing functions in the aforementioned code.

Using D3.js version 3.