title: d3.js force-collapsible with labels
body: <p>I am having some trouble trying to re-create</p>
  
  <p>I've attempted to add the features of <a href="http://bl.ocks.org/950642" rel="nofollow noreferrer">http://bl.ocks.org/950642</a> to <a href="http://mbostock.github.com/d3/talk/20111116/force-collapsible.html" rel="nofollow noreferrer">http://mbostock.github.com/d3/talk/20111116/force-collapsible.html</a></p>
  
  <p>and tried to do:</p>
  
  <pre><code>node.enter().append("text")
        .attr("dx", 12)
        .attr("dy", ".35em")
        .text(function(d) { return d.name });
  </code></pre>
  
  <p>However that results in the circles disappearing and all the text is clumped in the top left corner.</p>
  
  <p>Any ideas what I might be doing wrong? Here is my JS:</p>
  
  <p>here is a jsfiddle: for some reason it isn't working though here because of the .json file I think...</p>
  
  <p><a href="http://jsfiddle.net/vMw2N/5/" rel="nofollow noreferrer">http://jsfiddle.net/vMw2N/5/</a></p>
  
  <pre><code>var width = 960,
      height = 500,
      node,
      link,
      root;
  
  var force = d3.layout.force()
      .on("tick", tick)
      .charge(function(d) { return d._children ? -d.size / 100 : -30; })
      .linkDistance(function(d) { return d.target._children ? 80 : 30; })
      .size([width, height]);
  
  var vis = d3.select("#chart").append("svg")
      .attr("width", width)
      .attr("height", height);
  
  d3.json("../data/flare.json", function(json) {
    root = json;
    root.fixed = true;
    root.x = width / 2;
    root.y = height / 2;
    update();
  });
  
  function update() {
    var nodes = flatten(root),
        links = d3.layout.tree().links(nodes);
  
    // Restart the force layout.
    force
        .nodes(nodes)
        .links(links)
        .start();
  
    // Update the links…
    link = vis.selectAll("line.link")
        .data(links, function(d) { return d.target.id; });
  
    // Enter any new links.
    link.enter().insert("line", ".node")
        .attr("class", "link")
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });
  
    // Exit any old links.
    link.exit().remove();
  
    // Update the nodes…
    node = vis.selectAll("circle.node")
        .data(nodes, function(d) { return d.id; })
        .style("fill", color);
  
    node.transition()
        .attr("r", function(d) { return d.children ? 4.5 : Math.sqrt(d.size) / 10; });
  
    // Enter any new nodes.
    node.enter().append("circle")
        .attr("class", "node")
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .attr("r", function(d) { return d.children ? 4.5 : Math.sqrt(d.size) / 10; })
        .style("fill", color)
        .on("click", click)
        .call(force.drag);
  
  
      node.enter().append("text")
              .attr("class","node")
              .attr("cx", function(d) { return d.x; })
              .attr("cy", function(d) { return d.y; })
              .on("click",click)
              .text(function(d){return d.name})
              .call(force.drag);
  
    // Exit any old nodes.
    node.exit().remove();
  }
  
  function tick() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });
  
    node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  }
  
  // Color leaf nodes orange, and packages white or blue.
  function color(d) {
    return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
  }
  
  // Toggle children on click.
  function click(d) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    update();
  }
  
  // Returns a list of all nodes under the root.
  function flatten(root) {
    var nodes = [], i = 0;
  
    function recurse(node) {
      if (node.children) node.size = node.children.reduce(function(p, v) { return p + recurse(v); }, 0);
      if (!node.id) node.id = ++i;
      nodes.push(node);
      return node.size;
    }
  
    root.size = recurse(root);
    return nodes;
  }
  </code></pre>