title: D3 Tree Layout - Distance between child nodes that have children
body: <p>Trying to get the tree layout in D3 to render the child nodes with children closer together. Here is the code:</p>
  
  <pre><code>var margin = {
              top: 20,
              right: 120,
              bottom: 20,
              left: 120
      },
      width = 960 - margin.right - margin.left,
      height = 800 - margin.top - margin.bottom;
  
      var i = 0,
              duration = 750,
              rectW = 185,
              rectH = 45;
  
      var tree = d3.layout.tree()
          .nodeSize([200, 40]);
  
      var diagonal = d3.svg.diagonal()
          .projection(function (d) {
          return [d.x + rectW / 2, d.y + rectH / 2];
      });
  
      var svg = d3.select("#body").append("svg").attr("width", 1000).attr("height", 1000)
          .call(zm = d3.behavior.zoom().scaleExtent([0,1]).on("zoom", redraw))
          .append("g")
          .attr("transform", "translate(" + 30 + "," + 20 + ")");
  
      //necessary so that zoom knows where to zoom and unzoom from
      zm.translate([350, 20]);
  
      root.x0 = width / 2;
      root.y0 = 0;
  
      update(root);
  
      d3.select("#body").style("height", "800px");
  
      function update(source) {
  
          // Compute the new tree layout.
          var nodes = tree.nodes(root).reverse(),
              links = tree.links(nodes);
  
  
          // Normalize for fixed-depth.
          nodes.forEach(function (d) {
              d.y = (d.depth * 120);
          });
  
          // Update the nodes…
          var node = svg.selectAll("g.node")
              .data(nodes, function (d) {
              return d.id || (d.id = ++i);
          });
  
          // Enter any new nodes at the parent's previous position.
          var nodeEnter = node.enter().append("g")
              .attr("class", "node")
              .attr("transform", function (d) {
                  return "translate(" + source.x0 + "," + source.y0 + ")";
              })
              .on("click", click);
  
          // Add rectangles to nodes
          nodeEnter.append("rect")
              .attr("width", function (d) {                   
                  return rectW;
                  //return d._children ? "lightsteelblue" : "#fff";
              })
              .attr("height", rectH)
              .attr("class", function (d) {
                  return "rect-" + d.state;
              });
  
          // Add text to nodes
          nodeEnter.append("text")
              .attr("x", rectW / 2)
              .attr("y", rectH / 2)
              .attr("dy", ".35em")
              .attr("text-anchor", "middle")
              .text(function (d) {
                  return d.name;
              });
  
          // Transition nodes to their new position.
          var nodeUpdate = node.transition()
              .duration(duration)
              .attr("transform", function (d) {
                  return "translate(" + d.x + "," + d.y + ")";
              });
  
          nodeUpdate.select("rect")
              .attr("width", rectW)
              .attr("height", rectH)
              .attr("class", function (d) {
                  return "rect-" + d.state;
              });
  
          nodeUpdate.select("text")
              .style("fill-opacity", 1);
  
          // Update the links…
          var link = svg.selectAll("path.link")
              .data(links, function (d) {
                  return d.target.id;
              });
  
          // Enter any new links at the parent's previous position.
          link.enter().insert("path", "g")
              .attr("class", function (d) {
                  return "link " + d.target.dest;
              })
              .attr("x", rectW / 2)
              .attr("d", function (d) {
                  var o = {
                      x: source.x0,
                      y: source.y0
                  };
                  return diagonal({
                      source: o,
                      target: o
                  });
              });
  
          // Transition links to their new position.
          link.transition()
                  .duration(duration)
                  .attr("d", diagonal);
  
          // Transition exiting nodes to the parent's new position.
          link.exit().transition()
              .duration(duration)
              .attr("d", function (d) {
                  var o = {
                      x: source.x,
                      y: source.y
                  };
                  return diagonal({
                      source: o,
                      target: o
                  });
              }).remove();
  
  
          // Update the link labels…
          var linkLabel = svg.selectAll("text.link-label")
              .data(links, function (d) {
                  return d.target.id;
              });
  
          // Enter any new links at the parent's previous position.
          linkLabel.enter().insert("text", "path")
              .text(function (d) {
                  return (d.target.state !== "open") ? null : "If " + d.target.dest;
              })
              .attr("class", function (d) {
                  return "link-label " + d.target.dest;
              })
              .attr("x",  function (d) {
                  return d.target.x + rectW / 2;
              })
              .attr("y", function (d) {
                  return d.target.y + rectH * 2 - 30;
              })              
              .attr('text-anchor', 'middle')
              .style("fill-opacity", 0);;
  
          // Transition link labels
          linkLabel.transition()
              .delay(duration)
              .style("fill-opacity", 1);
  
  
          // Stash the old positions for transition.
          nodes.forEach(function (d) {
              d.x0 = d.x;
              d.y0 = d.y;
          });
      }
  
      // Toggle children on click.
      function click(d) {
          return false;
          if (d.children) {
              d._children = d.children;
              d.children = null;
          } else {
              d.children = d._children;
              d._children = null;
          }
          update(d);
      }
  
      //Redraw for zoom
      function redraw() {
          //console.log("here", d3.event.translate, d3.event.scale);
          svg.attr("transform",
              "translate(" + d3.event.translate + ")"
              + " scale(" + d3.event.scale + ")");
      }
  </code></pre>
  
  <p><a href="http://jsbin.com/AxuCazu/4/edit" rel="nofollow">Here is a jsbin</a> of the above code. What I would like to see is the navy-colored "Node 1" and "Node 2" be closer together while preserving the distance between the nodes without children (grey nodes). </p>
  
  <p>Is this possible and how would I do so?</p>