Skip to content

Instantly share code, notes, and snippets.

/data.json Secret

Created February 26, 2015 22:42
D3.js Tree
{
"name":"Do cash transfer improve access to education?",
"children":[
{
"name":"Should transfers be conditional?",
"url":"https://www.bing.com",
"children":[
{
"name":"Yes",
"children":[
{
"name":"What conditions?",
"size":3938,
"url":"https://www.google.com"
},
{
"name":"How to communicate conditions?",
"size":3812
},
{
"name":"How to monitor conditions?",
"size":6714
}
]
},
{
"name":"No"
}
]
},
{
"name":"What design options can enhance the CTs?"
},
{
"name":"What complementary interventions can maximize the productivity of CTs?"
}
]
}
<!doctype html>
<html lang=en dir=ltr>
<meta charset=utf-8>
<title>Node-Link Tree</title>
<style>
.node { cursor: pointer; }
.node text { font: 12px sans-serif; }
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
</style>
<header>
<button onclick="click(tree)">Expand All</button>
<button onclick="">Collapse All</button>
</header>
<div id="chart"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var m = [20, 300, 20, 300],
w = 1280 - m[1] - m[3],
h = 800 - m[0] - m[2],
i = 0,
duration = 500,
root;
var tree = d3.layout.tree().size([h, w]);
var diagonal = d3.svg.diagonal().projection(function(d) {
return [d.y, d.x];
});
var vis = d3.select("#chart").append("svg").attr("width", w + m[1] + m[3]).attr("height", h + m[0] + m[2]).append("g").attr("transform", "translate(" + m[3] + "," + m[0] + ")");
d3.json("data.json", function(json) {
root = json;
root.x0 = h / 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);
});
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse();
// Normalize for fixed-depth.
nodes.forEach(function(d) {
d.y = d.depth * 180;
});
// Update the nodes…
var node = vis.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("svg:a")
//.attr("xlink:href", function(d){return d.url;});
nodeEnter.append("circle").attr("r", 1e-6).style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
//Dilip added this ....
// window.open(d.url);
nodeEnter.append("svg:a").attr("target", "E2B").attr("xlink:href", function(d) {
return d.url;
}).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 = vis.selectAll("path.link").data(tree.links(nodes), 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);
}
//Returns a list of all nodes under the root.
function expandAll(root) {
var nodes = [],
i = 0;
function recurse(node) {
if(node.children) node.children.forEach(recurse);
if(!node.id) node.id = ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment