Tree Map

Tree Map

by Graham Dixon

HTML

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="graph" class="thisOne"></div>

CSS

body {
    font: 10px sans-serif;
}

.link {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
}

.sibling {
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
}

.border {
    fill: none;
    shape-rendering: crispEdges;
    stroke: #aaa;
}

.node {
    stroke: red;
    fill: white;
}

#graph svg {
    margin-top: -80px;
    padding-left: 560px;
}

JavaScript

(function() {

// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm,
// as improved by A.J. van der Ploeg, 2013, "Drawing Non-layered Tidy
// Trees in Linear Time".
d3.layout.flextree = function() {
  var hierarchy = d3.layout.hierarchy().sort(null).value(null);

  // The spacing between nodes can be specified in one of two ways:
  // - separation - returns center-to-center distance
  //   in units of root-node-x-size
  // - spacing - returns edge-to-edge distance in the same units as
  //   node sizes
  var separation = d3_layout_treeSeparation,
      spacing = null,
      size = [1, 1],    // x_size, y_size
      nodeSize = null,
      setNodeSizes = false;

  // This stores the x_size of the root node, for use with the spacing 
  // function
  var wroot = null;

  // The main layout function:
  function tree(d, i) {
    var nodes = hierarchy.call(this, d, i),
        t = nodes[0],
        wt = wrapTree(t);

    wroot = wt;
    zerothWalk(wt, 0);
    firstWalk(wt);
    secondWalk(wt, 0);
    renormalize(wt);

    return nodes;
  }

  // Every node in the tree is wrapped in an object that holds data
  // used during the algorithm
  function wrapTree(t) {
    var wt = {
      t: t,
      prelim: 0,
      mod: 0, 
      shift: 0, 
      change: 0,
      msel: 0,
      mser: 0,
    };
    t.x = 0;
    t.y = 0;
    if (size) {
      wt.x_size = 1;
      wt.y_size = 1;
    }
    else if (typeof nodeSize == "object") {  // fixed array
      wt.x_size = nodeSize[0];
      wt.y_size = nodeSize[1];
    }
    else {  // use nodeSize function
      var ns = nodeSize(t);
      wt.x_size = ns[0];
      wt.y_size = ns[1];
    }
    if (setNodeSizes) {
      t.x_size = wt.x_size;
      t.y_size = wt.y_size;
    }

    var children = [];
    var num_children = t.children ? t.children.length : 0;
    for (var i = 0; i < num_children; ++i) {
      children.push(wrapTree(t.children[i]));
    }
    wt.children = children;
    wt.num_children = num_children;

   ...