<!DOCTYPE html>
        <html>
          <meta charset="utf-8">
          <head>
            <style>
              .node {
                cursor: pointer;
              }

              .node circle {
                fill: #fff;
                stroke: steelblue;
                stroke-width: 1.5px;
              }

              .node text {
                font: 10px sans-serif;
              }

              .link {
                fill: none;
                stroke: #ccc;
                stroke-width: 1.5px;
              }
            </style>
          </head>
          <body>
            <div id="container">
              <div id="divCollapsibleTree"></div>
            </div>
            <script src="http://d3js.org/d3.v3.min.js"></script>
            <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
            <script>
              $(document).ready(function() {
                var margin = {top: 20, right: 120, bottom: 20, left: 120},
                  width = $(window).width() - margin.right - margin.left,
                  height = $(window).height() - margin.top - margin.bottom;

                var i = 0,
                  duration = 750,
                  root;

                var tree = d3.layout.tree()
                  .size([height, width]);

                var diagonal = d3.svg.diagonal()
                  .projection(function (d) {
                    return [d.y, d.x];
                  });

                var svg = d3.select("#divCollapsibleTree").append("svg")
                  .attr("width", width + margin.right + margin.left)
                  .attr("height", height + margin.top + margin.bottom)
                  .append("g")
                  .attr("class", "drawarea")
                  .append("g")
                  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                d3.json('/json/university-structure.json', function (error, flare) {
                  if (error) throw error;

                  root = flare;
                  root.x0 = height / 2;
                  root.y0 = 0;

                  function collapse(d) {
                    if (d.children) {
                      d._children = d.children;
                      d._children.forEach(collapse);
                      d.children = null;
                    }
                  }

                  root.children.forEach(collapse);
                  update(root);
                });

                d3.select(self.frameElement).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 * 360;
                  });

                  // 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.y0 + "," + source.x0 + ")";
                    })
                    .on("click", click);

                  nodeEnter.append("circle")
                    .attr("r", 1e-6)
                    .style("fill", function (d) {
                      return d._children ? "lightsteelblue" : "#fff";
                    });

                  nodeEnter.append("text")
                    .attr("x", function (d) {
                      return d.children || d._children ? -10 : 10;
                    })
                    .attr("dy", ".35em")
                    .attr("text-anchor", function (d) {
                      return d.children || d._children ? "end" : "start";
                    })
                    .text(function (d) {
                      return d.name;
                    })
                    .style("fill-opacity", 1e-6);

                  // Transition nodes to their new position.
                  var nodeUpdate = node.transition()
                    .duration(duration)
                    .attr("transform", function (d) {
                      return "translate(" + d.y + "," + d.x + ")";
                    });

                  nodeUpdate.select("circle")
                    .attr("r", 4.5)
                    .style("fill", function (d) {
                      return d._children ? "lightsteelblue" : "#fff";
                    });

                  nodeUpdate.select("text")
                    .style("fill-opacity", 1);

                  // Transition exiting nodes to the parent's new position.
                  var nodeExit = node.exit().transition()
                    .duration(duration)
                    .attr("transform", function (d) {
                      return "translate(" + source.y + "," + source.x + ")";
                    })
                    .remove();

                  nodeExit.select("circle")
                    .attr("r", 1e-6);

                  nodeExit.select("text")
                    .style("fill-opacity", 1e-6);

                  // 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", "link")
                    .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();

                  // 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) {
                  if (d.children) {
                    d._children = d.children;
                    d.children = null;
                  } else {
                    d.children = d._children;
                    d._children = null;
                  }
                  update(d);
                }

                //Add zoom extension
                d3.select("svg")
                  .call(d3.behavior.zoom()
                    .scaleExtent([0.5, 5])
                    .on("zoom", zoom));

                function zoom() {
                  var scale = d3.event.scale,
                    translation = d3.event.translate,
                    drawAreaWidth = d3.select(".drawarea").node().getBBox().width,
                    tBound = -height * scale + 50 * scale,
                    bBound = height - 50 * scale,
                    lBound = (-drawAreaWidth) * scale + 50 * scale,
                    rBound = width - 50 * scale,
                  // limit translation to thresholds
                    translation = [
                      Math.max(Math.min(translation[0], rBound), lBound),
                      Math.max(Math.min(translation[1], bBound), tBound)
                    ];

                  d3.select(".drawarea")
                    .attr("transform", "translate(" + translation + ")" +
                    " scale(" + scale + ")");
                }
              });
            </script>
          </body>
        </html>