Skip to content

Instantly share code, notes, and snippets.

@1wheel
Forked from mbostock/.block
Last active Dec 22, 2015
Embed
What would you like to do?
origin carrier count
ATL 9E 5
ATL AA 22
ATL CO 11
ATL DL 360
ATL EV 245
ATL F9 3
ATL FL 241
ATL MQ 2
ATL NW 14
ATL OH 12
ATL OO 11
ATL UA 8
ATL US 9
ATL XE 3
ATL YV 7
DFW 9E 2
DFW AA 448
DFW AS 3
DFW CO 10
DFW DL 10
DFW F9 4
DFW FL 7
DFW MQ 254
DFW NW 5
DFW OH 3
DFW OO 5
DFW UA 13
DFW US 18
DFW XE 4
ORD AA 203
ORD AS 4
ORD B6 7
ORD CO 14
ORD DL 10
ORD MQ 253
ORD NW 17
ORD OH 9
ORD OO 125
ORD UA 228
ORD US 19
ORD XE 3
ORD YV 60
SFO AA 34
SFO AS 14
SFO B6 5
SFO CO 14
SFO DL 12
SFO F9 4
SFO FL 2
SFO HA 1
SFO MQ 5
SFO NW 10
SFO OO 110
SFO UA 125
SFO US 20
SFO WN 24
SFO XE 5
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Pie Multiples with Nesting</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.4.5"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.csv.js?2.4.5"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?2.4.5"></script>
<style type="text/css">
body {
text-align: center;
}
svg {
font: 10px sans-serif;
}
</style>
</head>
<body>
<script type="text/javascript">
// Load the flight data asynchronously.
d3.csv("flights.csv", function(flights) {
// Define the margin, radius, and color scale. Colors are assigned lazily, so
// if you want deterministic behavior, define a domain for the color scale.
var m = 10,
r = 100,
z = d3.scale.category20c();
// Define a pie layout: the pie angle encodes the count of flights. Since our
// data is stored in CSV, the counts are strings which we coerce to numbers.
var pie = d3.layout.pie()
.value(function(d) { return +d.count; })
.sort(function(a, b) { return b.count - a.count; });
// Define an arc generator. Note the radius is specified here, not the layout.
var arc = d3.svg.arc()
.innerRadius(function(d){ return totalFlights[d.data.origin]/952 * r / 2; })
.outerRadius(function(d){ return totalFlights[d.data.origin]/952 * r; });
// Nest the flight data by originating airport. Our data has the counts per
// airport and carrier, but we want to group counts by aiport.
var airports = d3.nest()
.key(function(d) { return d.origin; })
.entries(flights);
//create an object w/ each origin's total flights
var totalFlights = {};
airports.forEach(function(d){
totalFlights[d.key] = d3.sum(d.values.map(function(d){ return +d.count; })); });
// Insert an svg element (with margin) for each airport in our dataset. A
// child g element translates the origin to the pie center.
var svg = d3.select("body").selectAll("div")
.data(airports)
.enter().append("div") // http://code.google.com/p/chromium/issues/detail?id=98951
.style("display", "inline-block")
.style("width", (r + m) * 2 + "px")
.style("height", (r + m) * 2 + "px")
.append("svg:svg")
.attr("width", (r + m) * 2)
.attr("height", (r + m) * 2)
.append("svg:g")
.attr("transform", "translate(" + (r + m) + "," + (r + m) + ")");
// Add a label for the airport. The `key` comes from the nest operator.
svg.append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.key; });
// Pass the nested per-airport values to the pie layout. The layout computes
// the angles for each arc. Another g element will hold the arc and its label.
var g = svg.selectAll("g")
.data(function(d) { return pie(d.values); })
.enter().append("svg:g");
// Add a colored arc path, with a mouseover title showing the count.
g.append("svg:path")
.attr("d", arc)
.style("fill", function(d) { return z(d.data.carrier); })
.append("svg:title")
.text(function(d) { return d.data.carrier + ": " + d.data.count; });
// Add a label to the larger arcs, translated to the arc centroid and rotated.
g.filter(function(d) { return d.endAngle - d.startAngle > .2; }).append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; })
.text(function(d) { return d.data.carrier; });
// Computes the label angle of an arc, converting from radians to degrees.
function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment