d3.js - Dynamically Updating A D3 Treemap Datasource -


i think i'm missing obvious here. trying create treemap on button click go server , retrieve next level treemap...this necessary because treemap structure large , takes long calculate jumping 1 level @ time option have.

[note ie users, in example treemap node names don't appear working. try using chrome]

http://plnkr.co/edit/simvgu

this code taken

http://bost.ocks.org/mike/treemap/

i'm using vizdata1.json "first" level , on mouse click i'm using vizdata2.json "second" level. can see 2 end overlapping. i've tried svg.exit() svg.clear() without luck.

i should note have tried sticky(false) suggestion post

does d3 treemap layout cached when root node passed it?

update: continue hunt have found example adds new nodes existing treemap. having trouble adapting logic treemap attempting fit logic has been heavily customized michael bostock - @mbostock allow nice breadcrumb trail bar @ top.

code snippet proves appending existing treemap nodes possible: http://jsfiddle.net/wb5jh/3/

also, stackoverflow forcing me post code because i'm linking plnkr have dumped script.js here rather not interact plunker

$(function() { var margin = { top: 20, right: 0, bottom: 0, left: 0 },     width = 960,     height = 500,     formatnumber = d3.format(",d"),     transitioning;  var x = d3.scale.linear()     .domain([0, width])     .range([0, width]);  var y = d3.scale.linear()     .domain([0, height])     .range([0, height]);  var 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)     .sticky(false);  var svg = d3.select("#treemap")     .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");  var 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", ".75em");  d3.json("vizdata1.json", function (root) {     initialize(root);     accumulate(root);     layout(root);     display(root); });  function initialize(root) {     root.x = root.y = 0;     root.dx = width;     root.dy = height;     root.depth = 0; }  // aggregate values internal nodes. done // treemap layout, not here because of our custom implementation. // take snapshot of original children (_children) avoid // children being overwritten when when layout computed. function accumulate(d) {     return (d._children = d.children)         ? d.value = d.children.reduce(function (p, v) { return p + accumulate(v); }, 0)         : d.value; }  // compute treemap layout recursively such each group of siblings // uses same size (1×1) rather dimensions of parent cell. // optimizes layout current zoom state. note wrapper // object created parent node each group of siblings // parent’s dimensions not discarded recurse. since each group // of sibling laid out in 1×1, must rescale fit using absolute // coordinates. lets use viewport zoom. function layout(d) {     if (d._children) {         treemap.nodes({ _children: d._children });         d._children.foreach(function (c) {             c.x = d.x + c.x * d.dx;             c.y = d.y + c.y * d.dy;             c.dx *= d.dx;             c.dy *= d.dy;             c.parent = d;             layout(c);         });     } }  function display(d) {     console.log(d);     grandparent         .datum(d.parent)         .on("click", transition)       .select("text")         .text(name(d));      var g1 = svg.insert("g", ".grandparent")         .datum(d)         .attr("class", "depth");      var g = g1.selectall("g")         .data(d._children)       .enter().append("g");      g.filter(function (d) { return d._children; })         .classed("children", true)         .on("click", transition);      g.selectall(".child")         .data(function (d) { return d._children || [d]; })       .enter().append("rect")         .attr("class", "child")         .call(rect);      g.append("rect")         .attr("class", "parent")         .call(rect)       .append("title")         .text(function (d) { return formatnumber(d.value); });      g.append("foreignobject")         .call(rect)         .attr("class", "foreignobj")         .append("xhtml:div")         .attr("dy", ".75em")         .html(function (d) { return d.name; })         .attr("class", "textdiv");      function transition(d) {         if (transitioning || !d) return;         transitioning = true;          d3.json("vizdata2.json", function (root) {             initialize(root);             accumulate(root);             layout(root);             display(root);         });          var g2 = display(d),             t1 = g1.transition().duration(750),             t2 = g2.transition().duration(750);          // update domain after entering new elements.         x.domain([d.x, d.x + d.dx]);         y.domain([d.y, d.y + d.dy]);          // enable anti-aliasing during transition.         svg.style("shape-rendering", null);          // draw child nodes on top of parent nodes.         svg.selectall(".depth").sort(function (a, b) { return a.depth - b.depth; });          // fade-in entering text.         g2.selectall("text").style("fill-opacity", 0);         g2.selectall("foreignobject div").style("display", "none"); /*added*/          // transition new view.         t1.selectall("text").call(text).style("fill-opacity", 0);         t2.selectall("text").call(text).style("fill-opacity", 1);         t1.selectall("rect").call(rect);         t2.selectall("rect").call(rect);          t1.selectall(".textdiv").style("display", "none"); /* added */         t1.selectall(".foreignobj").call(foreign);         t2.selectall(".textdiv").style("display", "block"); /* added */         t2.selectall(".foreignobj").call(foreign); /* added */          // remove old node when transition finished.         t1.remove().each("end", function () {             svg.style("shape-rendering", "crispedges");             transitioning = false;         });     }      return g; }  function text(text) {     text.attr("x", function (d) { return x(d.x) + 6; })         .attr("y", function (d) { return y(d.y) + 6; }); }  function rect(rect) {     rect.attr("x", function (d) { return x(d.x); })         .attr("y", function (d) { return y(d.y); })         .attr("width", function (d) { return x(d.x + d.dx) - x(d.x); })         .attr("height", function (d) { return y(d.y + d.dy) - y(d.y); }); }  function foreign(foreign) {  /* added */     foreign.attr("x", function (d) { return x(d.x); })       .attr("y", function (d) { return y(d.y); })       .attr("width", function (d) { return x(d.x + d.dx) - x(d.x); })       .attr("height", function (d) { return y(d.y + d.dy) - y(d.y); }); }  function name(d) {     return d.parent         ? name(d.parent) + "." + d.name         : d.name; } }); 


Popular posts from this blog