Information Technology
Information Technology

Reputation: 2333

Transitioning Node Circle Colors in D3 Tree Visualization

I have a problem where, when I collapse nodes, the colors of the stroke for other nodes also change (when they shouldn't). The hint seems to be that the colors of the Tree branch being collapsed shift "down" to nodes in lower branches.

You can see the problem by clicking on "Node 1". The result is that the colors of nodes 2 and 3 shift down to 4 and 5. 4 and 5 shift to 6 and 7, etc.

The interesting thing is that you reselect "Node 1" to expand the branch, all colors go back to their original and correct state.

NOTE: The tree visualization and source can be seen at: http://bl.ocks.org/Guerino1/raw/ed80661daf8e5fa89b85/

I have node related "circle" elements that I deal with in three blocks of code:

BLOCK #1:

      nodeEnter.append("svg:circle")
          .attr("cx", horizontalTreeOffset)
          .attr("r", 1e-6)
          .style("fill", function(d) { return d._children ? "lightsteelblue"
                                       : "#fff"; });

BLOCK #2:

      nodeUpdate.select("circle")
          .attr("r", 5.5)
          .style("stroke", function(d) { return color_hash[d.type]; })
          .style("stroke-width", 3)
          .style("fill", function(d) { 
            if(d._children)
              { return color_hash[d.type]; }
            else
              { return "white"; }
            }
          )
          .attr("type_value", function(d, i) { return d.type; })
          .attr("color_value", function(d, i) { return color_hash[d.type]; });

BLOCK #3:

      nodeExit.select("circle")
          .attr("r", 1e-6);

Any help you can offer is greatly appreciated.

Upvotes: 1

Views: 599

Answers (1)

Information Technology
Information Technology

Reputation: 2333

Found it...

The tree.nodes() method traverses the links and comes up with its own set of nodes. This is totally different than the list of nodes passed into the program by the user, which contains all the traits for each node. As a result, the original traits must be taken from the original node set and merged into the D3 generated nodes (that lack the traits).

When the code enters the update() method for every transition, the old code was iterating through the nodes and merging based on their index. However, the index is now "shifted" due to the number of total nodes being less (because of collapsed nodes). AND, the transitioned nodes have already gone through the process of having their traits assigned to them, so there's no reason to do so, again.

The new code to merge looks as follows...

      // Normalize for fixed-depth.
      //nodes.forEach(function(d) { d.y = d.depth * 180; });
      if(!nodes[0].name){
        nodes.forEach(function(d, i){
          d.y = d.depth * 180;
          d.name = nodeSet[i].name
          d.type = nodeSet[i].type
          d.hlink = nodeSet[i].hlink
          d.rSize = nodeSet[i].rSize
        })
      }
      else{
        nodes.forEach(function(d, i){
          d.y = d.depth * 180;
        })
      };

Upvotes: 2

Related Questions