score:4

Accepted answer

The following changes are necessary to make this work. First, you need to select the existing SVG element (and its descendant g) as vis in the update function:

var vis = d3.select("svg > g");

Then, you need to compute and handle enter, update and exit selections for circles and text separately:

var newG = vis.selectAll("circle").data(nodes);

newG.enter().append("svg:circle");
newG.exit().remove();
newG.attr("class", function(d) {
    return d.children ? "parent" : "child";
  }).attr("cx", function(d) {
    return d.x;
  }).attr("cy", function(d) {
    return d.y;
  }).attr("r", function(d) {
    return d.r;
  }).on("click", function(d) {
    return zoom(node == d ? root : d);
  });

var texts = vis.selectAll("text").data(nodes);

texts.enter().append("svg:text");
texts.exit().remove();
texts.append("svg:text")
  .attr("class", function(d) {
    return d.children ? "parent" : "child";
  }).attr("x", function(d) {
    return d.x;
  }).attr("y", function(d) {
    return d.y;
  }).attr("dy", ".35em")
  .attr("text-anchor", "middle")
  .style("opacity", function(d) {
    return d.r > 20 ? 1 : 0;
  }).text(function(d) {
    return d.name;
  }); 

You could also merge your functions as they both do almost the same thing and there's a lot of redundant code. But the above should be sufficient to make it work.


Related Query