Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the d3 treemap layout get cached when a root node is passed to it?

I was trying to get a d3 treemap to animate, and had something like

App.svg = d3.select("#medals-tree-map").append("svg:svg")
    .style("width", App.canvasWidth)
    .style("height", App.canvasHeight)
  .append("svg:g")
    .attr("transform", "translate(-.5,-.5)")
    .attr("id", "container");

App.treemap = d3.layout.treemap()
    .size([App.canvasWidth + 1, App.canvasHeight + 1])
    .value(function(d) { return d.number; })
    .sticky(true);

function drawGraphFromJson(data) {
  // Draw the graph
  var leaves = App.treemap(data);

  var cell = App.svg.selectAll("g.cell")
    .data(leaves);

  // More rendering code
}

Based on this answer: https://stackoverflow.com/a/9650825/111884

However, the tree map doesn't change at all when I call drawGraphFromJson with new data.

I fixed the problem by defining App.treemap inside the drawGraphFromJson ie,

function drawGraphFromJson(data) {
  App.treemap = d3.layout.treemap()
    .size([App.canvasWidth + 1, App.canvasHeight + 1])
    .value(function(d) { return d.number; })
    .sticky(true);

  // Draw the graph
  var leaves = App.treemap(data);

  var cell = App.svg.selectAll("g.cell")
    .data(leaves);

  // More rendering code
}

Why do I need to do this? Does treemap become cached when you pass in a root node?

like image 834
zlog Avatar asked Dec 21 '22 22:12

zlog


1 Answers

Yes, the layout is partially cached if you set treemap.sticky(true). See the documentation for treemap.sticky.

The expectation with treemap.sticky is that you use the same root node as input to the layout but you change the value function to alter how the child nodes are sized. See the treemap visualization on the D3 website for an example of changing the value function with a sticky treemap layout. The reason for this constraint is that with a sticky layout, the topology of the tree can't change—you must have the same number of nodes in the same hierarchy. The only thing that changes is the value.

So, if you are calling drawGraphFromJson with two different sets of data, then you either need to set treemap.sticky(false), or you need to merge your two datasets into a single hierarchy and then change the value function to animate between the two.

Also: you haven't included your rendering code, so it's possible there's an error in your data join. However, I think the sticky explanation is more likely. See Thinking with Joins for an explanation.

like image 66
mbostock Avatar answered Apr 30 '23 06:04

mbostock