D3 Zoomable Treemap Resize

584 Views Asked by At

I'm having some issues trying to make my treemap resizable on window resize: I started from this example: https://secure.polisci.ohio-state.edu/faq/d3/zoomabletreemap_code.php

This is my resize() function, I do nothing more than remove the graph, redefine div#graph width and height and rerun the init code you can see in the link above. (drawGraph() do the d3 treemap work and json is a global var containing the data):

function resize(){
    d3.select("#graph svg")
   .remove();

    margin = {top: 50, right: 0, bottom: 0, left: 0},
    width = $('#graph').innerWidth(),
    height = $('#graph').height() - margin.top - margin.bottom

    x = d3.scale.linear()
    .domain([0, width])
    .range([0, width]);

    y = d3.scale.linear()
    .domain([0, height])
    .range([0, height]);


    treemap = d3.layout.treemap()
    .children(function(d, depth) { return depth ? null : d._children; })
    .sort(function(a, b) { return a.value - b.value; })
    .ratio(height / width * 0.5 * (1 + Math.sqrt(5)))
    .round(false)
    .value(function(d) {  return d.size; })

    svg = d3.select("#graph").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.bottom + margin.top)
    .style("margin-left", -margin.left + "px")
    .style("margin.right", -margin.right + "px")
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .style("shape-rendering", "crispEdges");

    grandparent = svg.append("g")
    .attr("class", "grandparent");

    grandparent.append("rect")
    .attr("y", -margin.top)
    .attr("width", width)
    .attr("height", margin.top)

    grandparent.append("text")
    .attr("x", 6)
    .attr("y", 6 - margin.top)
    .attr("dy", "30px")


drawGraph(json)

}

Here the problem: the graph is redrawn correctly, but without any children! My treemap have height 3, after the resize it's like all the nodes become leafs.

SOLUTION I edited the accumulate function:

    function accumulate(d) {      
    if (d._children === undefined) {
       return (d._children = d.children)
        ? d.value = d.children.reduce(function(p, v) { return p + accumulate(v); }, 0)
        : d.value;
    } else {
        return d.value;
    }

  }

And on window resize event I update width and height of the svg element and re-execute: initialize(), accumulate(), layout(), display()

0

There are 0 best solutions below