D3.js Force layout with collapsible node (3)rd demo

with font icons

by bizamajig

HTML

<script src="http://d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.no-icons.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.css">
<div id="chart"></div>
<input type="button" name="loadImage" value="Load" onClick="loadImage();" />

CSS

circle.node {
    cursor: pointer;
    stroke: #3182bd;
    stroke-width: 1.5px;
}
path.link {
    fill: none;
    stroke: #666;
    stroke-width: 1.5px;
}
.simpleDiv {
    position: absolute;
    overflow: visible;
}
.simpleDiv .mainDiv {
    overflow: visible;
    width: 100%;
}
.simpleDiv .mainDiv .userImage {
    width: 36px;
    height: 36px;
    border: 2px solid;
    border-radius:30px;
    overflow: hidden;
}
.simpleDiv .mainDiv .docIcon {
    width: 36px;
}
.simpleDiv .mainDiv .content {
    margin-left: 45px;
    margin-top: -30px;
}
#hiddenText {
    visibility: hidden;
    padding: 0;
}

JavaScript

var w = 960,
    h = 500,
    node,
    path,
    root, nodes, links;

var force, vis;
var LoadData = true;

function update() {
    if (force) force.stop();
    nodes = flatten(root);
    links = d3.layout.tree().links(nodes);

    force.nodes(nodes)
        .links(links)
        .linkDistance(120)
        .charge(-500)
        .start();

    path = vis.selectAll("path.link");
    path = path.data(force.links());
    path.exit().remove();
    path.enter().append("svg:path")
        .attr("class", "link")
        .attr("marker-end", "url(#end)");
    vis.selectAll(".node .simpleDiv").remove();

    node = vis.selectAll(".node");
    node = node.data(force.nodes());
    node.exit().remove();
    node.enter().append("g")
        .attr("class", "node")
        .on("click", click)
        .call(force.drag);

    node.append("foreignObject")
        .attr("class", "simpleDiv")
        .attr("width", function (d) {
        var f = document.createElement("span");
        f.id = "hiddenText";
        f.style.display = 'hidden';
        f.style.padding = '0px';
        f.innerHTML = d.name;
        document.body.appendChild(f);
        textWidth = f.offsetWidth;
        var f1 = document.getElementById('hiddenText');
        f1.parentNode.removeChild(f1);
        return textWidth + 50;
    })
        .attr("overflow", "visible")
        .attr("height", 50)
        .append("xhtml:div").attr("class", "mainDiv").style("cursor", hoverStyle)
        .html(function (d) {
        var htmlString = "";


        var userImage = "http://t2.gstatic.com/images?q=tbn:ANd9GcT6fN48PEP2-z-JbutdhqfypsYdciYTAZEziHpBJZLAfM6rxqYX";
        if (d.type == 'user') {
            htmlString += "<div class='userImage' style='border-color:" + color(d) + "'><image src='" + userImage + "' width='36' height='36'></image></div>";
            htmlString += "<div class='content' style='color:" + color(d) + ";'>" + d.name + "</div>";
            htmlString += "<div style='clear:both;'></div>";
        }...