Status Board Zoom- USE THIS!!!

with AmeliaBR improvements - see http://stackoverflow.com/questions/22391074/adjusting-scale-of-a-group-to-ensure-shapes-inside-are-as-big-as-possible-in-d3

by Nivaldo

HTML

<script src="http://d3js.org/d3.v3.min.js"></script>
    <body>
        <h1>Status Board</h1>
        <div id="Search"><input id="SearchBox" type="text" placeholder="Search"></div>
        <div id="tree-container"></div>
    </body>
        
<!--
The method of determining the appropriate scale to fit a collection of points is fairly straightforward, although it took me quite a while to figure out why it wasn't working for me -- I hadn't clued in to the fact that (since you were drawing the tree horizontally) "x" from the tree layout represented vertical position, and "y" represented horizontal position, so I was getting apparently arbitrary results.
-->

CSS

body, html{
    overflow:hidden;
    margin: 0;
    padding: 0;
    background-color:#eee;
}
  
.node { 
	cursor: pointer; 
	padding: 5px 0;
}

.overlay{ background-color: #eee; }

.doesntHaveKids {
    display: none;
}

.node circle.nodeCircle {
    fill: #ddd;
    stroke: #bbb;
    stroke-width: 1px;
}

.node circle.ping {
    fill: rgba(255,0,0,0);
    stroke: rgba(255,0,0,1);
    stroke-width: 1px;
}

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

.node.selected text { 
	font-weight: bold; 

 	background-color: transparent;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.15)), to(transparent));
	background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.15), transparent);
	background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.15), transparent);
}

/*.node.selected circle { stroke-width: 3px; }*/
  
.node circle.Deliver {
    stroke: #003086;
    fill: #4b84ea;
}

.node circle.Engage.Promote {
    stroke: #0048c8;
    fill: #7da8f5;
}

.node circle.Play.Experience {
    stroke: #4386fe;
    fill: #99bbfa;
} 

.node circle.Support {
    stroke: #76a7ff;
    fill: #c0d6ff;
}

.node circle.Deliver.closed, 
.node circle.Engage.Promote.closed, 
.node circle.Play.Experience.closed,
.node circle.Support.closed {
    stroke: #494949;
    fill: #aaa;
}            
   
.link {
    fill: none;
    stroke: #ccc;
    stroke-width: 1.5px;
}

.templink {
    fill: none;
    stroke: red;
    stroke-width: 3px;
}

.ghostCircle.show{ display:block; }

.ghostCircle, .activeDrag .ghostCircle{ display: none; }

.tooltip {   
    position: absolute;      
    bottom: 50%;
    right: 0px;
    text-align: left;
    min-width: 250px;
	min-height: 100px;
    font: 12px sans-serif;           
    pointer-events: none;  

 	background-color: transparent;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.15)), to(transparent));
	background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.15),...

JavaScript

// Get JSON data
var nodeEnter;
var node;
var toolTip;
var radiusSizeNormal = 4.5;
var radiusSizeBig = 6.5;
var pingStartSize = 50;
treeJSON = d3.json("fake.json", function(error, treeData) {
var treeData = {"mainBranch":null,"name":"GrandParent","children":[{"mainBranch":true,"name":"Parent 1","children":[{"mainBranch":null,"name":"1Child A","children":[]},{"mainBranch":null,"name":"1Child B","children":[]}]},{"mainBranch":true,"name":"Parent 2","children":[{"mainBranch":null,"name":"2Child A","children":[]},{"mainBranch":null,"name":"2Child B","children":[]}]}]};
    
    // Calculate total nodes, max label length
    var totalNodes = 0;
    var maxLabelLength = 0;
    // variables for drag/drop
    var selectedNode = null;
    var draggingNode = null;
    // panning variables
    var panSpeed = 200;
    var panBoundary = 20; // Within 20px from edges will pan when dragging.
    // Misc. variables
    var i = 0;
    var duration = 750;
    var root;
    var flatTreeData = [];



    // size of the diagram
    var viewerWidth = $(document).width();
    var viewerHeight = $(document).height();

    var tree = d3.layout.tree()
        .size([viewerHeight, viewerWidth]);

    toolTip = d3.select("body").append("div")
        .attr("class", "tooltip")
        .style("opacity", 0);

    // define a d3 diagonal projection for use by the node paths later on.
    var diagonal = d3.svg.diagonal()
        .projection(function(d) {
            return [d.y, d.x];
        });

    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }

    // A recursive helper function for performing some setup by walking through all nodes
    function visit(parent, visitFn, childrenFn) {
        parent.radius = radiusSizeNormal;
        parent.isSelected = false; //to know if its selected
        if (!parent) return;

        visitFn(parent);

        var children = childrenFn(parent);
        if (children) {
            var count =...