Skip to content

Instantly share code, notes, and snippets.

@jasondavies
Created October 19, 2011 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasondavies/1299353 to your computer and use it in GitHub Desktop.
Save jasondavies/1299353 to your computer and use it in GitHub Desktop.
button {
font: 14px Helvetica Neue;
background-color: #222;
background-image: -moz-linear-gradient(top, rgba(255,255,255,.25), rgba(255,255,255,.11));
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, rgba(255,255,255,.25)),color-stop(1, rgba(255,255,255,.11)));
background-image: -webkit-linear-gradient(rgba(255,255,255,.25), rgba(255,255,255,.11));
color: #fff;
text-rendering: optimizeLegibility;
text-shadow: 0 -1px 1px #222;
padding: 6px 10px 6px 10px;
border: 0;
border-radius: 0;
border-bottom: 1px solid #222;
margin: 0;
-moz-box-shadow: 0 1px 3px #999;
-webkit-box-shadow: 0 1px 3px #999;
}
button.first {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
button.last {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
button.active {
background-color: rgb(65,102,133);
}
button:hover {
background-color: steelblue;
}
{
"name": "Flash/Lighting", "qty": 332, "revs": 988,
"children": [
{
"name": "Flash & Lighting Accessories", "qty": 98, "revs": 289,
"children": [
{"name": "Bounce + Diffusers for Small Flash", "qty": 58, "revs": 162 },
{"name": "Camera Flash Brackets", "qty": 11, "revs": 30},
{"name": "TTL Connecting Accessories", "qty": 10, "revs": 29},
{"name": "Replacement + Misc Accessory Items", "qty": 7, "revs": 23 }
]
},
{
"name": "Universal Light Controls", "qty": 56, "revs": 177,
"children": [
{"name": "Reflectors", "qty": 16, "revs": 47},
{"name": "Umbrellas", "qty": 15, "revs": 43},
{"name": "Soft Boxes + Accessories", "qty": 9, "revs": 36},
{"name": "Lighting Filters", "qty": 6, "revs": 19},
{"name": "Speedrings/Adaptors", "qty": 5, "revs": 20}
]
},
{
"name": "On-Camera + Slave Flashes", "qty": 53, "revs": 134,
"children": [
{"name": "Shoe Mount Flashes", "qty": 48, "revs": 119},
{"name": "Macro & Ringflash Units", "qty": 3, "revs": 9},
{"name": "Slave Flashes", "qty": 2, "revs": 5},
{"name": "Handle-Mount Flashes", "qty": 0.1, "revs": 0.7}
]
},
{ "name": "Light Stands + Grips", "qty": 33, "revs": 110 },
{ "name": "Backgrounds + Supports", "qty": 28, "revs": 76 },
{ "name": "Monolights", "qty": 20, "revs": 53 },
{ "name": "Slaves", "qty": 17, "revs": 66 },
{ "name": "Continuous Output Lighting", "qty": 12, "revs": 32 },
{ "name": "Studio/Still Life + Copy Equipment", "qty": 6, "revs": 17 },
{ "name": "AC Packs + Heads", "qty": 5, "revs": 20 },
{ "name": "DC Packs + Heads", "qty": 4, "revs": 13 }
]
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Node-Link Tree</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js"></script>
<link href='button.css' rel='stylesheet' type='text/css' />
<link href='tree.css' rel='stylesheet' type='text/css' />
</head>
<body>
<div id="chart">
<h1 align="left">Flash/Lighting Categories</h1>
<p>Sized by quantity sold (000's)</p>
</div>
<div id="chart2">
<p>Sized by revenues sold ($millions)</p>
</div>
<script type="text/javascript" src="qty-tree.js"></script>
<script type="text/javascript" src="rev-tree.js"></script>
</body>
</html>
(function() {
var m = [20, 120, 20, 120],
w = 880 - m[1] - m[3],
h = 300 - 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:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
d3.json("data/flash-categories.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(source).reverse();
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 250; });
// 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("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
nodeEnter.append("svg:circle")
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeEnter.append("svg:text")
.attr("x", function(d) { return d.children || d._children ? -25 : 40; })
.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)
.style("font-size", 12 );
nodeEnter.append("svg:text")
.text(function(d) { return d.qty } )
.style("font-size", 15 )
.attr("x", function(d) { return d.children || d._children ? -10 : 15; })
.attr("dy", ".35em");
// 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", function(d) { return d.qty/5 })
// .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("svg:path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
})
.transition()
.duration(duration)
.attr("d", diagonal);
// 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);
}
})();
(function() {
var m = [20, 120, 20, 120],
w = 880 - m[1] - m[3],
h = 300 - m[0] - m[2],
j = 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("#chart2").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
d3.json("data/flash-categories.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(source).reverse();
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 250; });
// Update the nodesÉ
var node = vis.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++j); });
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
nodeEnter.append("svg:circle")
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeEnter.append("svg:text")
.attr("x", function(d) { return d.children || d._children ? -25 : 50; })
.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)
.style("font-size", 12 );
nodeEnter.append("svg:text")
.text(function(d) { return d.revs } )
.style("font-size", 15 )
.attr("x", function(d) { return d.children || d._children ? -10 : 15; })
.attr("dy", ".35em");
// 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", function(d) { return d.revs/15 })
// .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("svg:path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
})
.transition()
.duration(duration)
.attr("d", diagonal);
// 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);
}
})();
.node circle {
cursor: pointer;
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
}
h1 {
font: 25px sans-serif;
}
p {
font-family: sans-serif;
font-size: 12px;
font-style: italic;
}
path.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
@tomdong
Copy link

tomdong commented Sep 29, 2014

I just met a issue: how to set a background color (or image) to the text element in the node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment