Created
January 16, 2013 05:54
-
-
Save nsonnad/4544985 to your computer and use it in GitHub Desktop.
Area + donut: History of energy use in the US
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> | |
<title>US Historical Energy Consumption</title> | |
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> | |
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script> | |
<!--<script src="http://code.jquery.com/jquery-1.8.3.min.js" type="text/javascript" charset="utf-8"></script> | |
<script src="jquery.tipsy.js" type="text/javascript" charset="utf-8"></script> | |
<link rel="stylesheet" href="http://onehackoranother.com/projects/jquery/tipsy/stylesheets/tipsy.css" type="text/css" title="no title" charset="utf-8"/> --> | |
<style type="text/css"> | |
body { font-size: 11px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; } | |
.axis path, line { stroke: #000; fill:none; shape-rendering: crispEdges;} | |
line.tick { stroke: #cccccc; opacity:.4; } | |
.arc path { | |
stroke: #fff; | |
} | |
div#stack { width: 550px; float:left; } | |
div#pie { width: 350px; float:left; } | |
.yLabels { stroke: none; font-size: 1em; fill:#191919; } | |
.donutLabels { font-size:12px; font-weight: bold; stroke: none; fill:white; } | |
.underlay { visibility: hidden; pointer-events:all; } | |
.underlay rect { fill:gray; opacity:.3; } | |
.tooltip { position:absoulte; } | |
</style> | |
</head> | |
<body> | |
<div id="stack"> | |
</div> | |
<div id="pie"> | |
</div> | |
<script type="text/javascript"> | |
// global variables | |
var margin = {t:20, r:20, b:20, l:30 }, | |
w1 = 550 - margin.l - margin.r, | |
w2 = 300 - margin.r, | |
h = 350 - margin.t - margin.b, | |
x = d3.time.scale().range([0, w1]).clamp(true), | |
y = d3.scale.linear().range([h, 0]).domain([0, 110]), | |
color = d3.scale.ordinal().range(["#37A36A", "#3A5A64", "#DABD49", "#C78739", "#8AB8D9", "#A81F5E"]), | |
formatTime = d3.time.format("%Y").parse; | |
var dataChange, | |
latest, | |
data; | |
// settings for stacked area chart | |
var stacked = d3.select("#stack").append("svg") | |
.attr("width", w1 + margin.l + margin.r) | |
.attr("height", h + margin.t + margin.b) | |
.append("g") | |
.attr("class", "stackWrapper") | |
.attr("transform", "translate(" + margin.l + "," + margin.t + ")"); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.tickSubdivide(true) | |
.orient("bottom"); | |
stacked.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + h + ")") | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.tickSubdivide(true) | |
.tickSize(-w1, 0, 0) | |
.orient("left"); | |
var stack = d3.layout.stack() | |
.values(function(d) { return d.values; }); | |
var area = d3.svg.area().interpolate("cardinal") | |
.x(function(d) { return x(d.year); }) | |
.y0(function(d) { return y(d.y0); }) | |
.y1(function(d) { return y(d.y + d.y0); }) | |
stacked.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
// settings for donut chart | |
var radius = Math.min((w2), h) / 2, | |
labelRadius = radius - 20; | |
var krispy = d3.select("#pie").append("svg") | |
.attr("width", w2 + margin.r + margin.l) | |
.attr("height", h + margin.t + margin.b) | |
.append("g") | |
.attr("transform", "translate(150," + (h/2 + margin.t) + ")"); | |
var arc = d3.svg.arc() | |
.outerRadius(radius - 15) | |
.innerRadius(radius - 55); | |
var pie = d3.layout.pie() | |
.sort(null) | |
.value(function(d) { return d.values; }); | |
// bring in the data | |
d3.csv("us-historical-energy.csv", function(csv) { | |
// data variable that will be used throughout | |
data = csv; | |
// format dates | |
data.forEach(function(d) { | |
d.Year = formatTime(d.Year); | |
}); | |
// function for adding data points one at a time | |
var latest = 1; | |
function update() { | |
// create array that will update with each new data point | |
dataChange = data.slice(0, latest) | |
latest++; | |
if (latest < csv.length) { | |
// redraw function draws the meat of the charts | |
redraw(); | |
}; | |
}; | |
// update data every 500ms | |
var interval = setInterval(update, 500); | |
// create list energy sources to be used as keys | |
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Year" && key !== "sourcesPie"; })) | |
// create legend | |
var legend = stacked.append("g") | |
.attr("class", "legendBox") | |
var legends = legend.selectAll(".legend") | |
.data(color.domain()) | |
.enter().append("g") | |
.attr("class", "legend") | |
.attr("transform", function(d, i) { return "translate(10," + (5 + (i * 20)) + ")"; }); | |
legends.append("rect") | |
.attr("width", 15) | |
.attr("height", 15) | |
.style("fill", color) | |
legends.append("text") | |
.attr("x", 20) | |
.attr("y", 8) | |
.attr("dy", ".35em") | |
.text(function(d) { return d; }); | |
// draw the charts | |
function redraw() { | |
// map vales to d3.layout.stack() for the area chart | |
var sourcesStack = stack(color.domain().map(function(name) { | |
return { | |
name: name, | |
values: data.map(function(d) { | |
return { year: d.Year, y: +d[name] }; | |
}) | |
}; | |
})); | |
// set x domain to extend to the most recently added data point | |
x.domain([d3.min(dataChange, function(d) { | |
return d.Year; }), | |
d3.max(dataChange, function(d) { | |
return d.Year; })]); | |
// set data for energy sources stacked areas | |
var stacks = stacked.selectAll(".sources") | |
.data(sourcesStack); | |
// call enter() for stacked areas | |
var stacksEnter = stacks.enter().append("g") | |
.attr("class", "sources"); | |
// draw paths and areas | |
stacksEnter.append("path") | |
.attr("class", "area") | |
.attr("d", function(d) { return area(d.values); }) | |
.style("fill", function(d) { return color(d.name); }); | |
// update and transition area values | |
var stacksUpdate = d3.transition(stacks) | |
stacksUpdate.transition().select("path").duration(500) | |
.attr("d", function(d) { return area(d.values); }); | |
// update x axis | |
d3.selectAll(".x.axis").transition(stacked).duration(500).call(xAxis) | |
// create rect underlays that will be used for mouseovers | |
var underlay = stacks.selectAll(".underlay").data(data), | |
underlayWidth = w1/dataChange.length; | |
// enter() underlay g and append rects | |
var underlayEnter = underlay.enter().append("g") | |
.attr("class", "underlay"); | |
underlayEnter.append("rect") | |
.attr("x", function(d, i) { return x(d.Year); }) | |
.attr("width", underlayWidth) | |
.attr("y", 0) | |
.attr("height", h); | |
// update and move underlays; reduce width to svgwidth/data.length | |
var underlayUpdate = d3.transition(underlay); | |
underlayUpdate.transition().selectAll("rect").duration(500) | |
.attr("x", function(d, i) { return x(d.Year); }) | |
.attr("width", underlayWidth); | |
// what to do when we mouse on or off a rect | |
underlay.on("mouseover", rectOn) | |
underlay.on("mouseout", rectOff) | |
// now for the donut | |
// map values to color.domain key | |
data.forEach(function(d) { | |
d.sourcesPie = color.domain().map(function(name) { | |
return {name: name, values: +d[name]}; | |
}); | |
}); | |
// set data for the donut | |
var donut = krispy.selectAll(".arc") | |
.data(pie(dataChange[dataChange.length - 1].sourcesPie)) | |
// enter() the donut "g" | |
var donutEnter = donut.enter().append("g") | |
.attr("class", "arc") | |
// things we will use to compute percentages | |
var total = d3.sum(dataChange[dataChange.length - 1].sourcesPie, function(d) { return d.values; }) | |
var formatPercent = d3.format("%") | |
// draw donut arcs | |
donutEnter.append("path") | |
.attr("class", "donutPath") | |
.attr("d", arc) | |
.each(function(d) { this._current = d; }) | |
.style("fill", function(d) { return color(d.data.name); }) | |
// draw percentage labels inside arcs | |
donutEnter.append("text") | |
.attr("class", "donutLabels") | |
.attr("transform", function(d) { | |
return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; }) | |
.attr("dy", ".35em") | |
.attr("text-anchor", "middle") | |
.style("fill-opacity", function(d) {return d.value==0 ? 1e-6 : 1;}) | |
.text(function(d) { | |
return formatPercent(d.data.values/total) }); | |
// angle function used for rotating labels | |
function angle(d) { | |
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90; | |
return a > 90 ? a - 180 : a; | |
} | |
// update and transition arcs and labels | |
var donutUpdate = d3.transition(donut); | |
donutUpdate.transition().select("text").duration(500) | |
.attr("transform", function(d) { | |
return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; }) | |
.style("fill-opacity", function(d) {return d.value==0 ? 1e-6 : 1;}) | |
.text(function(d) { | |
return formatPercent(d.data.values/total) }); | |
donutUpdate.transition().select("path").duration(500) | |
.attrTween("d", arcTween) | |
function arcTween(a) { | |
var i = d3.interpolate(this._current, a); | |
this._current = i(0); | |
return function(t) { | |
return arc(i(t)); | |
}; | |
} | |
}; | |
// helper functions | |
// what happens when we go on or off of a rect | |
var rectOn = function() { | |
var hoverRect = d3.select(this) | |
hoverRect.style("visibility", "visible") | |
} | |
var rectOff = function() { | |
var hoverRect = d3.select(this) | |
hoverRect.style("visibility", "hidden") | |
} | |
// stop animation when we roll over stacked area, restart when leaving | |
$('#stack').hover(function() { | |
clearInterval(interval); | |
}, | |
function() { | |
interval = setInterval(update, 500); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
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
Year | Biomass | Coal | Petroleum | Natural Gas | Captured Energy | Nuclear | |
---|---|---|---|---|---|---|---|
1775 | 0.249 | 0 | 0 | 0 | 0 | 0 | |
1785 | 0.31 | 0 | 0 | 0 | 0 | 0 | |
1795 | 0.402 | 0 | 0 | 0 | 0 | 0 | |
1805 | 0.537 | 0 | 0 | 0 | 0 | 0 | |
1815 | 0.714 | 0 | 0 | 0 | 0 | 0 | |
1825 | 0.96 | 0 | 0 | 0 | 0 | 0 | |
1835 | 1.305 | 0 | 0 | 0 | 0 | 0 | |
1845 | 1.757 | 0 | 0 | 0 | 0 | 0 | |
1850 | 2.138 | 0.219 | 0 | 0 | 0 | 0 | |
1855 | 2.389 | 0.421 | 0 | 0 | 0 | 0 | |
1860 | 2.641 | 0.518 | 0.003 | 0 | 0 | 0 | |
1865 | 2.767 | 0.632 | 0.01 | 0 | 0 | 0 | |
1870 | 2.893 | 1.048 | 0.011 | 0 | 0 | 0 | |
1875 | 2.872 | 1.44 | 0.011 | 0 | 0 | 0 | |
1880 | 2.851 | 2.054 | 0.096 | 0 | 0 | 0 | |
1885 | 2.683 | 2.84 | 0.04 | 0.082 | 0 | 0 | |
1890 | 2.515 | 4.062 | 0.156 | 0.257 | 0.022 | 0 | |
1895 | 2.306 | 4.95 | 0.168 | 0.147 | 0.09 | 0 | |
1900 | 2.015 | 6.841 | 0.229 | 0.252 | 0.25 | 0 | |
1905 | 1.843 | 10.001 | 0.61 | 0.372 | 0.386 | 0 | |
1910 | 1.765 | 12.714 | 1.007 | 0.54 | 0.539 | 0 | |
1915 | 1.688 | 13.294 | 1.418 | 0.673 | 0.659 | 0 | |
1920 | 1.61 | 15.504 | 2.676 | 0.813 | 0.738 | 0 | |
1925 | 1.533 | 14.706 | 4.28 | 1.191 | 0.668 | 0 | |
1930 | 1.455 | 13.639 | 5.897 | 1.932 | 0.752 | 0 | |
1935 | 1.397 | 10.634 | 5.675 | 1.919 | 0.806 | 0 | |
1940 | 1.358 | 12.535 | 7.76 | 2.665 | 0.88 | 0 | |
1945 | 1.261 | 15.972 | 10.11 | 3.871 | 1.442 | 0 | |
1949 | 1.549262 | 11.980905 | 11.882722 | 5.145142 | 1.424722 | 0 | |
1950 | 1.562307 | 12.347109 | 13.315484 | 5.968371 | 1.415411 | 0 | |
1951 | 1.534669 | 12.552996 | 14.428043 | 7.048518 | 1.423795 | 0 | |
1952 | 1.474369 | 11.306479 | 14.955682 | 7.549621 | 1.465812 | 0 | |
1953 | 1.418601 | 11.372684 | 15.555829 | 7.906645 | 1.412859 | 0 | |
1954 | 1.394327 | 9.714667 | 15.839176 | 8.330202 | 1.359772 | 0 | |
1955 | 1.424143 | 11.167259 | 17.254955 | 8.997935 | 1.359844 | 0 | |
1956 | 1.415871 | 11.349723 | 17.937473 | 9.613975 | 1.434711 | 0 | |
1957 | 1.333581 | 10.820631 | 17.931667 | 10.190753 | 1.515613 | 0.000112 | |
1958 | 1.323123 | 9.533287 | 18.526937 | 10.663199 | 1.591967 | 0.001915 | |
1959 | 1.352874 | 9.518353 | 19.32265 | 11.717422 | 1.548465 | 0.002187 | |
1960 | 1.31987 | 9.837785 | 19.91923 | 12.385366 | 1.608334 | 0.006026 | |
1961 | 1.294762 | 9.623351 | 20.216387 | 12.926392 | 1.657464 | 0.019678 | |
1962 | 1.300242 | 9.906454 | 21.048981 | 13.730841 | 1.817202 | 0.026394 | |
1963 | 1.323316 | 10.412538 | 21.700828 | 14.403306 | 1.773115 | 0.038147 | |
1964 | 1.336802 | 10.964385 | 22.301257 | 15.28785 | 1.888446 | 0.039819 | |
1965 | 1.334761 | 11.580608 | 23.24568 | 15.768667 | 2.061055 | 0.043164 | |
1966 | 1.368985 | 12.14308 | 24.400523 | 16.995332 | 2.063477 | 0.064158 | |
1967 | 1.340249 | 11.91375 | 25.283661 | 17.944788 | 2.349964 | 0.088456 | |
1968 | 1.419495 | 12.330677 | 26.979447 | 19.209656 | 2.353161 | 0.141534 | |
1969 | 1.440487 | 12.38154 | 28.338336 | 20.677984 | 2.654405 | 0.153722 | |
1970 | 1.430962 | 12.264528 | 29.520695 | 21.794707 | 2.639059 | 0.239347 | |
1971 | 1.432323 | 11.598411 | 30.56129 | 22.469052 | 2.82989 | 0.412939 | |
1972 | 1.503065 | 12.076917 | 32.946738 | 22.69819 | 2.878944 | 0.583752 | |
1973 | 1.529068 | 12.97149 | 34.837435 | 22.512399 | 2.88187 | 0.910177 | |
1974 | 1.539657 | 12.662878 | 33.45366 | 21.732488 | 3.20219 | 1.272083 | |
1975 | 1.498734 | 12.662786 | 32.732323 | 19.947883 | 3.188386 | 1.899798 | |
1976 | 1.713373 | 13.584067 | 35.177782 | 20.345426 | 3.013778 | 2.111121 | |
1977 | 1.838332 | 13.922103 | 37.12398 | 19.930513 | 2.370634 | 2.701762 | |
1978 | 2.037605 | 13.765575 | 37.962821 | 20.0004 | 2.967834 | 3.024126 | |
1979 | 2.151906 | 15.039586 | 37.122274 | 20.665817 | 2.970948 | 2.775827 | |
1980 | 2.4755 | 15.422809 | 34.20452 | 20.235459 | 2.952843 | 2.739169 | |
1981 | 2.596283 | 15.907526 | 31.932206 | 19.747309 | 2.817406 | 3.007589 | |
1982 | 2.663452 | 15.321581 | 30.232226 | 18.356222 | 3.316185 | 3.131148 | |
1983 | 2.904414 | 15.894442 | 30.052216 | 17.220836 | 3.591198 | 3.202549 | |
1984 | 2.971119 | 17.070622 | 31.053237 | 18.393613 | 3.466744 | 3.552531 | |
1985 | 3.016233 | 17.478428 | 30.924732 | 17.703482 | 3.067784 | 4.075563 | |
1986 | 2.932094 | 17.260405 | 32.19826 | 16.591364 | 3.179046 | 4.380109 | |
1987 | 2.874884 | 18.008451 | 32.863733 | 17.639801 | 2.746923 | 4.753933 | |
1988 | 3.016049 | 18.846312 | 34.222795 | 18.448393 | 2.440706 | 5.586968 | |
1989 | 3.159358 | 19.069762 | 34.209296 | 19.601689 | 3.075876 | 5.602161 | |
1990 | 2.73511 | 19.172635 | 33.551623 | 19.603168 | 3.305565 | 6.10435 | |
1991 | 2.781798 | 18.99167 | 32.846032 | 20.032957 | 3.286719 | 6.422132 | |
1992 | 2.931678 | 19.122471 | 33.524957 | 20.713632 | 2.889674 | 6.479206 | |
1993 | 2.908172 | 19.835148 | 33.744546 | 21.228902 | 3.174333 | 6.410499 | |
1994 | 3.027535 | 19.909463 | 34.560541 | 21.728065 | 2.960583 | 6.693877 | |
1995 | 3.101142 | 20.088727 | 34.43837 | 22.671138 | 3.459341 | 7.075436 | |
1996 | 3.156806 | 21.001914 | 35.67535 | 23.084647 | 3.856872 | 7.086674 | |
1997 | 3.10522 | 21.445411 | 36.158897 | 23.222717 | 3.910322 | 6.596992 | |
1998 | 2.927489 | 21.655744 | 36.815915 | 22.830226 | 3.565409 | 7.067809 | |
1999 | 2.963291 | 21.622544 | 37.837705 | 22.909227 | 3.552327 | 7.610256 | |
2000 | 3.008228 | 22.579528 | 38.261705 | 23.823978 | 3.098124 | 7.862349 | |
2001 | 2.622347 | 21.914268 | 38.18551 | 22.772558 | 2.540203 | 8.028853 | |
2002 | 2.700598 | 21.903989 | 38.224147 | 23.510081 | 3.028521 | 8.145429 | |
2003 | 2.807132 | 22.320928 | 38.811443 | 22.830642 | 3.176232 | 7.958858 | |
2004 | 3.009666 | 22.466195 | 40.29178 | 22.923061 | 3.072751 | 8.221985 | |
2005 | 3.116765 | 22.796543 | 40.388116 | 22.565364 | 3.125178 | 8.16081 | |
2006 | 3.266757 | 22.44716 | 39.955351 | 22.238738 | 3.382414 | 8.215414 | |
2007 | 3.474262 | 22.749466 | 39.773964 | 23.662759 | 3.048323 | 8.455364 | |
2008 | 3.848548 | 22.385196 | 37.279917 | 23.842954 | 3.337857 | 8.427297 | |
2009 | 3.9117 | 19.692203 | 35.403266 | 23.41594 | 3.687903 | 8.356019 | |
2010 | 4.294066 | 20.84952 | 36.009541 | 24.256183 | 3.795848 | 8.434433 | |
2011 | 4.411164 | 19.643039 | 35.282604 | 24.842548 | 4.724236 | 8.259432 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment