Joel
Joel

Reputation: 4593

D3.js customize collapsible indented tree. Setting positions of nodes based on data

I have the following graph built with d3. enter image description here

enter image description here

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:

enter image description here

...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.

Upvotes: 3

Views: 1197

Answers (1)

manuBriot
manuBriot

Reputation: 2715

Seems to me like you want to change the transform applied to the <g> for each node, rather than the x and y for the <rect>. That way all nodes are described the same (a group offset at the right position, and within the group all elements rect and text are always indented the same. But perhaps I misunderstood your intend.

Upvotes: 1

Related Questions