Last active
April 26, 2016 15:26
-
-
Save SteveBate/1476137306f499b1840c38708a82edbf to your computer and use it in GitHub Desktop.
Example D3 bubble chart based on the one in 'Facts Are Sacred' book on page 52
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var dataset = { | |
"dispatched": { | |
"CCE018 - Acme Glass Division": "42", | |
"CCE033 - Cold Shopper Marketing": "730", | |
"CCE034 - Home Shopper Marketing": "31", | |
"CCE035 - T C C C Portfolio": "10", | |
"CCE036 - Portfolio X Franchise": "21", | |
"CCE037 - Cold Operations Trading": "500", | |
"CCE038 - Home Operations Trading": "9", | |
"CCE039 - Field Sales Operations": "2702", | |
"All Divisions": "4045" | |
} | |
}; | |
function processData(data, col) { | |
var obj = data[col]; | |
var newDataSet = []; | |
for(var prop in obj) { | |
newDataSet.push({name: prop, className: prop.toUpperCase(), size: obj[prop]}); | |
} | |
return {children: newDataSet}; | |
} | |
function renderBubble(target, diameter){ | |
var svg = d3.select(target).append('svg').attr('width', diameter).attr('height', diameter); | |
// prepare an area that can pack circle together | |
var bubble = d3.layout.pack() | |
.sort(function(a, b) {return -(a.value - b.value);}) | |
.size([diameter, diameter]) | |
.padding(30) // padding between adjacent circles | |
.value(function(d) {return d.size;}); // new data will be loaded to bubble layout | |
var node = svg.selectAll(".node") | |
.data(bubble.nodes(processData(dataset, "dispatched")) | |
.filter(function(d) { return !d.children; })) | |
.enter() | |
.append("g") | |
.attr("class", "node") | |
.attr("data-x", function(d){return d.x;}) | |
.attr("data-y", function(d){return d.y;}) | |
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
node.append("circle") | |
.attr("r", function(d) { return d.r; }) | |
.style("fill", function(d, i) { return "rgb(138, " + i*10 + ", 175)"; }) | |
.on("click", function(d){console.log(d);}) | |
.on("mouseenter", function(d) { | |
// scale the circle | |
d3.select(this) | |
.transition() | |
.ease('cubic-in-out') | |
.duration(200) | |
.attr('r', d.r+5); | |
// scale the text | |
var text = d3.select(this.parentNode.lastChild); | |
text | |
.transition() | |
.ease('cubic-in-out') | |
.duration(200) | |
.style('font-size', text.attr('font-size')/0.8); | |
}) | |
.on("mouseout", function(d) { | |
// scale the circle | |
d3.select(this) | |
.transition() | |
.ease('cubic-in-out') | |
.duration(200) | |
.attr('r', d.r); | |
// scale the text | |
var text = d3.select(this.parentNode.lastChild); | |
text | |
.transition() | |
.ease('cubic-in-out') | |
.duration(200) | |
.style('font-size', text.attr('font-size')); | |
}); | |
// find the circle representing the total value of all circles combined | |
var index = node[0].length-1; | |
var totalCircle = node[0][index].childNodes[0]; | |
// draw lines from the center of the current circle to the center of the target circle | |
node.append("line") | |
.attr("x1", function(d){return 0;}) | |
.attr("x2", function(d, i){return totalCircle.parentNode.getAttribute("data-x")-d.x;}) | |
.attr("y1", function(d){return 0;}) | |
.attr("y2", function(d, i){return (totalCircle.parentNode.getAttribute("data-y")-d.y);}) | |
.attr("stroke", function(d,i) { return "rgb(138, " + i*10 + ", 175)"; }) | |
.attr("stroke-width", 5); | |
// add text displaying the total number of orders dispatched. Set the font size according to the circle size. | |
node.append("text") | |
.attr("dy", ".3em") | |
.attr("font-family", "sans-serif") | |
.attr("font-size", function(d, i){ | |
var val = node[0][i].childNodes[0].r.baseVal.value; | |
return val < 45 ? val*0.6 : val*0.5; | |
}) | |
.attr("fill", "#FFF") | |
.attr("font-weight", "bold") | |
.attr("text-anchor", "middle") | |
.text(function(d) { return d.value.toLocaleString(); }); | |
} | |
renderBubble("#chart1", 550); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<div id="chart1" /> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment