title: d3 pack layout circles overlapping after movement/size transitions
body: <p>I have circles arranged with the pack layout, from a dataset which periodically updates the radii.</p>
  
  <p>The code I started out with is this standard example for a bubble chart: <a href="http://bl.ocks.org/mbostock/4063269" rel="nofollow noreferrer">http://bl.ocks.org/mbostock/4063269</a></p>
  
  <p><img src="https://i.stack.imgur.com/8CEgT.png" alt="enter image description here"></p>
  
  <p>Whenever the circle sizes change, they transition.  Often when circles grow, they move to overlap other circles. I don't want them to overlap each other.</p>
  
  <p>I'm still pretty new to d3, have moved the code around a lot and tried everything I can think of, but no luck.</p>
  
  <p>The function <code>makeBubbles</code> is passed raw Json (see below).</p>
  
  <pre><code>function makeBubbles(root){
    var diameter = $(window).width(),
        diameterh = $(window).height(),
        format = d3.format(",d"),
        color = d3.scale.category20();
  
    var bubble = d3.layout.pack()
        .sort(null)
        .size([diameter, diameterh])
        .value(function(d){return d.value; })
        .padding(1.5);
  
    var svg = d3.select("svg")
        .attr("width", diameter)
        .attr("height", diameterh)
        .attr("class", "bubble");
  
    var node = svg.selectAll(".node")
        .data(bubble.nodes(classes(root)).filter(function(d) { return !d.children; }),     function(d){  console.log(d); return d.className; });
  
  
    node.append("title")
        .text(function(d) { return d.className + ": " + format(d.value); });
  
    node.append("circle")
        .style("fill", function(d) { return color(d.packageName); })
        .on("click", function(d) { window.location = d.url; })
        .attr("r", 0)
        .transition()
        .duration(1000)
        .attr("r", function(d) { return d.r; });
  
    node.transition().duration(1000).attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
  
    node.enter().append("g")
        .attr("class", "node")
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
  
    node.exit().transition().duration(200).attr("transform", "scale(0.001)").remove();
  
    node.append("text")
        .attr("dy", ".3em")
        .style("text-anchor", "middle")
        .text(function(d) { return d.className.substring(0, d.r / 6); })
        .attr("opacity",0)
        .transition().duration(1000)
        .attr("opacity",1);
  
  // Returns a flattened hierarchy containing all leaf nodes under the root.
    function classes(root) {
      var classes = [];
  
      function recurse(name, node) {
        if (node.children) node.children.forEach(function(child) { recurse(node.name, child);     });
        else classes.push({packageName: name, className: node.name, value: node.size, url: node.url});
      }
  
      recurse(null, root);
      return {children: classes};
    }
  
    d3.select(self.frameElement).style("height", diameterh + "px");
  }
  </code></pre>
  
  <p>Data passed looks something like this (varying as the dataset is updated):</p>
  
  <pre><code>{"name":"bubbles","children":[{"name":"tourism","children":[{"name":"tourism","children":[{"name":"practical","children":[{"name":"ACCOMM","size":13,"url":"#"},{"name":"HIRE","size":2,"url":"#"}]},{"name":"activity","children":[{"name":"EVENT","size":6,"url":"#"},{"name":"TOUR","size":3,"url":"#"}]},{"name":"leisure","children":[{"name":"RESTAURANT","size":168,"url":"#"},{"name":"ATTRACTION","size":8,"url":"#"}]}]}]}]} 
  </code></pre>