This employs D3's ability to make line charts with D3's ability to parse HTML tables.
Last active
March 12, 2016 05:20
-
-
Save ndobie/436327fa73730ecb02db to your computer and use it in GitHub Desktop.
D3 Table with Chart and Data Download
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
license: mit | |
border: no | |
height: 600 | |
scrolling: no |
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
periodyear | period | cpi | |
---|---|---|---|
2007 | 1 | 202.416 | |
2007 | 2 | 203.499 | |
2007 | 3 | 205.352 | |
2007 | 4 | 206.686 | |
2007 | 5 | 207.949 | |
2007 | 6 | 208.352 | |
2007 | 7 | 208.299 | |
2007 | 8 | 207.917 | |
2007 | 9 | 208.49 | |
2007 | 10 | 208.936 | |
2007 | 11 | 210.177 | |
2007 | 12 | 210.036 | |
2008 | 1 | 211.08 | |
2008 | 2 | 211.693 | |
2008 | 3 | 213.528 | |
2008 | 4 | 214.823 | |
2008 | 5 | 216.632 | |
2008 | 6 | 218.815 | |
2008 | 7 | 219.964 | |
2008 | 8 | 219.086 | |
2008 | 9 | 218.783 | |
2008 | 10 | 216.573 | |
2008 | 11 | 212.425 | |
2008 | 12 | 210.228 | |
2009 | 1 | 211.143 | |
2009 | 2 | 212.193 | |
2009 | 3 | 212.709 | |
2009 | 4 | 213.24 | |
2009 | 5 | 213.856 | |
2009 | 6 | 215.693 | |
2009 | 7 | 215.351 | |
2009 | 8 | 215.834 | |
2009 | 9 | 215.969 | |
2009 | 10 | 216.177 | |
2009 | 11 | 216.33 | |
2009 | 12 | 215.949 | |
2010 | 1 | 216.687 | |
2010 | 2 | 216.741 | |
2010 | 3 | 217.631 | |
2010 | 4 | 218.009 | |
2010 | 5 | 218.178 | |
2010 | 6 | 217.965 | |
2010 | 7 | 218.011 | |
2010 | 8 | 218.312 | |
2010 | 9 | 218.439 | |
2010 | 10 | 218.711 | |
2010 | 11 | 218.803 | |
2010 | 12 | 219.179 | |
2011 | 1 | 220.223 | |
2011 | 2 | 221.309 | |
2011 | 3 | 223.467 | |
2011 | 4 | 224.906 | |
2011 | 5 | 225.964 | |
2011 | 6 | 225.722 | |
2011 | 7 | 225.922 | |
2011 | 8 | 226.545 | |
2011 | 9 | 226.889 | |
2011 | 10 | 226.421 | |
2011 | 11 | 226.23 | |
2011 | 12 | 225.672 | |
2012 | 1 | 226.665 | |
2012 | 2 | 227.663 | |
2012 | 3 | 229.392 | |
2012 | 4 | 230.085 | |
2012 | 5 | 229.815 | |
2012 | 6 | 229.478 | |
2012 | 7 | 229.104 | |
2012 | 8 | 230.379 | |
2012 | 9 | 231.407 | |
2012 | 10 | 231.317 | |
2012 | 11 | 230.221 | |
2012 | 12 | 229.601 | |
2013 | 1 | 230.28 | |
2013 | 2 | 232.166 | |
2013 | 3 | 232.773 | |
2013 | 4 | 232.531 | |
2013 | 5 | 232.945 | |
2013 | 6 | 233.504 | |
2013 | 7 | 233.596 | |
2013 | 8 | 233.877 | |
2013 | 9 | 234.149 | |
2013 | 10 | 233.546 | |
2013 | 11 | 233.069 | |
2013 | 12 | 233.049 | |
2014 | 1 | 233.916 | |
2014 | 2 | 234.781 | |
2014 | 3 | 236.293 | |
2014 | 4 | 237.072 | |
2014 | 5 | 237.9 | |
2014 | 6 | 238.343 | |
2014 | 7 | 238.25 | |
2014 | 8 | 237.852 | |
2014 | 9 | 238.031 | |
2014 | 10 | 237.433 | |
2014 | 11 | 236.151 | |
2014 | 12 | 234.812 | |
2015 | 1 | 233.707 | |
2015 | 2 | 234.722 | |
2015 | 3 | 236.119 | |
2015 | 4 | 236.599 | |
2015 | 5 | 237.805 | |
2015 | 6 | 238.638 | |
2015 | 7 | 238.654 | |
2015 | 8 | 238.316 | |
2015 | 9 | 237.945 | |
2015 | 10 | 237.838 | |
2015 | 11 | 237.336 | |
2015 | 12 | 236.525 | |
2016 | 1 | 236.916 |
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
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
<b>January</b> | 202.416 | 211.080 | 211.143 | 216.687 | 220.223 | 226.665 | 230.280 | 233.916 | 233.707 | 236.916 | 0.2 | |
<b>February</b> | 203.499 | 211.693 | 212.193 | 216.741 | 221.309 | 227.663 | 232.166 | 234.781 | 234.722 | |||
<b>March</b> | 205.352 | 213.528 | 212.709 | 217.631 | 223.467 | 229.392 | 232.773 | 236.293 | 236.119 | |||
<b>April</b> | 206.686 | 214.823 | 213.240 | 218.009 | 224.906 | 230.085 | 232.531 | 237.072 | 236.599 | |||
<b>May</b> | 207.949 | 216.632 | 213.856 | 218.178 | 225.964 | 229.815 | 232.945 | 237.900 | 237.805 | |||
<b>June</b> | 208.352 | 218.815 | 215.693 | 217.965 | 225.722 | 229.478 | 233.504 | 238.343 | 238.638 | |||
<b>July</b> | 208.299 | 219.964 | 215.351 | 218.011 | 225.922 | 229.104 | 233.596 | 238.250 | 238.654 | |||
<b>August</b> | 207.917 | 219.086 | 215.834 | 218.312 | 226.545 | 230.379 | 233.877 | 237.852 | 238.316 | |||
<b>September</b> | 208.490 | 218.783 | 215.969 | 218.439 | 226.889 | 231.407 | 234.149 | 238.031 | 237.945 | |||
<b>October</b> | 208.936 | 216.573 | 216.177 | 218.711 | 226.421 | 231.317 | 233.546 | 237.433 | 237.838 | |||
<b>November</b> | 210.177 | 212.425 | 216.330 | 218.803 | 226.230 | 230.221 | 233.069 | 236.151 | 237.336 | |||
<b>December</b> | 210.036 | 210.228 | 215.949 | 219.179 | 225.672 | 229.601 | 233.049 | 234.812 | 236.525 | |||
| ||||||||||||
<b>Annual Avg.</b> | 207.342 | 215.303 | 214.537 | 218.056 | 224.939 | 229.594 | 232.957 | 236.736 | 237.017 | |||
| ||||||||||||
<b>Y/Y % Chg.</b> | 2.8 | 3.8 | -0.4 | 1.6 | 3.2 | 2.1 | 1.5 | 1.6 | 0.1 |
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> | |
<meta charset="utf-8" /> | |
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> | |
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> | |
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> | |
<style type="text/css"> | |
h3 { | |
text-align: center; | |
padding-top: 0; | |
} | |
h4 { | |
text-align: center; | |
padding-top: 0; | |
} | |
svg { | |
font-family: sans-serif; | |
font-size: 0.75em; | |
position: relative; | |
} | |
path { | |
stroke: steelblue; | |
stroke-width: 2px; | |
fill: none; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: black; | |
stroke-width: 1; | |
shape-rendering: crispEdges; | |
} | |
@import url('//fonts.googleapis.com/css?family=Lato:400,400italic,700,700italic'); | |
body { | |
font-family: 'Lato', Arial, Helvetica, sans-serif; | |
font-size: 16px; | |
} | |
.source { | |
font-size: 0.625em; | |
color: grey; | |
line-height: 80%; | |
} | |
.prepaired { | |
font-size: 0.625em; | |
color: grey; | |
line-height: 80%; | |
} | |
.update { | |
font-size: 0.625em; | |
color: grey; | |
line-height: 80%; | |
} | |
.notes { | |
font-size: 0.625em; | |
color: grey; | |
line-height: 80%; | |
} | |
a { | |
color: dimgray; | |
} | |
th { | |
text-align: right; | |
font-weight: bold; | |
} | |
#cpi { | |
text-align: right; | |
padding-right: 2px; | |
margin-right: 3px; | |
width: 100%; | |
font-size: .8em; | |
} | |
h2 { | |
margin-top: 0; | |
} | |
td:nth-child(6) { | |
margin-right: 5px; | |
} | |
td:nth-child(1) { | |
width: 85px; | |
} | |
td:nth-child(12) { | |
width:95px; | |
} | |
@media print { | |
.noprint { | |
display: none !important; | |
} | |
a:link:after, a:visited:after { | |
display: none; | |
content: ""; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div style="align-items:flex-start; width:100%;" class="container"> | |
<ul class="nav nav-tabs"> | |
<li class="active"><a data-toggle="tab" href="#home">Consumer Price Index</a></li> | |
<li><a data-toggle="tab" href="#menu1">Chart</a></li> | |
<li><a href="http://data.bls.gov/cgi-bin/surveymost?bls" target="_blank">Download</a></li> | |
</ul> | |
<div class="tab-content" style="background-color:lightgrey; stroke-width:1px; stroke:dimgray; border-radius: 0 0 0.625em 0.625em; padding:4px;"> | |
<div id="home" style="margin-right:5px;" class="tab-pane fade in active"> | |
<h3>All items, U.S. city average (base period: 1982-1984=100)</h3> | |
<table id="cpi"></table> | |
<br /><span class="source">Source: U.S. Dept. of Labor, Bureau of Labor Statistics.</span> | |
<br /><span class="prepaired">Table prepared by UNM Bureau of Business and Economic Research</span> | |
<br /><span class="update">Last Revised: 01/20/2016, Next update: 03/08/2016</span> | |
</div> | |
<div id="menu1" style="margin-right:5px;" class="tab-pane fade"> | |
<span id="ieString"></span> | |
<div id="chart" style="background:white"></div> | |
<br /><span class="source">Source: U.S. Dept. of Labor, Bureau of Labor Statistics.</span> | |
<br /><span class="prepaired">Table prepared by UNM Bureau of Business and Economic Research</span> | |
<br /><span class="update">Last Revised: 01/20/2016, Next update: 03/08/2016</span> | |
</div> | |
</div> | |
</div> | |
<script> | |
// Set the dimensions of the canvas / graph | |
var margin = { top: 10, right: 60, bottom: 30, left: 50 } | |
, width = 910 | |
, width = width - margin.left - margin.right | |
, height = 400 - margin.top - margin.bottom; | |
// Parse the date / time | |
var parseDate = d3.time.format( "%m/%d/%Y" ).parse; | |
bisectDate = d3.bisector( function ( d ) { return d.date; } ).left; | |
// Set the ranges | |
var x = d3.time.scale().range( [0, width] ); | |
var y = d3.scale.linear().range( [height, 0] ); | |
// Define the axes | |
var xAxis = d3.svg.axis().scale( x ) | |
.orient( "bottom" ) | |
.ticks( d3.time.year, 1 ); | |
var yAxis = d3.svg.axis().scale( y ) | |
.orient( "left" ).ticks( 10 ); | |
// Adds the svg canvas | |
var svg = d3.select( "#chart" ) | |
.append( "svg" ) | |
.attr( "width", width + margin.left + margin.right ) | |
.attr( "height", height + margin.top + margin.bottom ) | |
.append( "g" ) | |
.attr( "transform", | |
"translate(" + margin.left + "," + margin.top + ")" ); | |
var rSvg = svg.append( "g" ); | |
var lineSvg = svg.append( "g" ); | |
var focus = svg.append( "g" ) | |
.style( "display", "none" ); | |
d3.csv( "cpi.csv", function ( error, data ) { | |
data.forEach( function ( d ) { | |
d.dateP = d.period + "/01/" + d.periodyear | |
d.date = parseDate( d.dateP ); | |
return d; | |
} ); | |
valueline = d3.svg.line() | |
.x( function ( d ) { return x( d.date ); } ) | |
.y( function ( d ) { return y( d.cpi ); } ); | |
// Scale the range of the data | |
x.domain( d3.extent( data, function ( d ) { return d.date; } ) ); | |
y.domain( [180, 250] ); | |
//Makes the shaded recession rectangle | |
rSvg.append( 'rect' ) | |
.attr( "class", "recessionRect" ) | |
.attr( "x", x( parseDate( "12/01/2007" ) ) ) | |
.attr( "width", x( parseDate( "06/01/2009" ) ) - x( parseDate( "12/01/2007" ) ) ) | |
.attr( "y", y( 250 ) ) | |
.attr( "height", y( 180 ) - y( 250 ) ) | |
.style( "fill", "lightgrey" ) | |
.style( "fill-opacity", 0.7 ); | |
// draw the lines | |
var lines = lineSvg.selectAll( ".line" ).data( data ).attr( "class", "line" ) | |
// transition from previous paths to new paths | |
lines.transition().duration( 1500 ) | |
.attr( "d", valueline( data ) ); | |
// exit | |
lines.exit().remove(); | |
// append the rectangle to capture mouse | |
svg.append( "rect" ) | |
.attr( "width", width ) | |
.attr( "height", height ) | |
.attr( "class", "mouseEventRect" ) | |
.style( "fill", "none" ) | |
.style( "pointer-events", "all" ) | |
.on( "mouseover", function () { | |
focus.style( "display", null ); | |
} ) | |
.on( "mouseout", function () { | |
focus.style( "display", "none" ); | |
} ) | |
.on( "mousemove", mousemove ); | |
if ( svg.selectAll( ".y.axis" )[0].length < 1 ) {//checks if an axis exists yet so the below only fires on page load or resize | |
// Add the valueline path for inital page | |
lineSvg.append( "path" ) | |
.attr( "class", "line" ) | |
.attr( "d", valueline( data ) ); | |
// Add the X Axis | |
svg.append( "g" ) | |
.attr( "class", "x axis" ) | |
.attr( "transform", "translate(0," + height + ")" ) | |
.call( xAxis ); | |
// Add the Y Axis | |
svg.append( "g" ) | |
.attr( "class", "y axis" ) | |
.call( yAxis ) | |
.append( "text" ) | |
.attr( "class", "label" ) | |
.attr( "transform", "rotate(-90)" ) | |
.attr( "y", 5 )//-30 | |
.attr( "x", -5 )//-350 | |
.attr( "dy", ".71em" ) | |
.style( "text-anchor", "end" ) | |
.text( "Consumer Price Index (100 = 1982-84)" ); | |
// append the circle at the intersection | |
focus.append( "circle" ) | |
.attr( "class", "y" ) | |
.style( "fill", "none" ) | |
.style( "stroke", "red" ) | |
.attr( "r", 5 ); | |
// place the value at the intersection | |
focus.append( "text" ) | |
.attr( "class", "y1" ) | |
.style( "stroke", "white" ) | |
.style( "stroke-width", "3.5px" ) | |
.style( "opacity", 0.8 ) | |
.attr( "dx", 8 ) | |
.attr( "dy", "-.3em" ); | |
focus.append( "text" ) | |
.attr( "class", "y2" ) | |
.attr( "dx", 8 ) | |
.attr( "dy", "-.3em" ); | |
}; | |
function mousemove() { | |
ms_ie = false, | |
ua = window.navigator.userAgent, | |
old_ie = ua.indexOf( 'MSIE ' ), | |
new_ie = ua.indexOf( 'Trident/' ); | |
if ( ( old_ie > -1 ) || ( new_ie > -1 ) ) { | |
ms_ie = true; | |
} | |
if ( ms_ie ) { | |
//IE specific code goes here | |
var x0 = x.invert( d3.mouse( this )[0] ), | |
i = bisectDate( data, x0, 1 ), | |
d0 = data[i - 1], | |
d1 = data[i], | |
d = x0 - d0.date > d1.date - x0 ? d1 : d0; | |
document.getElementById( 'ieString' ).innerHTML = ( '(' + d.period + '/' + d.periodyear + ', ' + ( d.cpi ) + ")" ); | |
focus.select( "circle.y" ) | |
.attr( "transform", | |
"translate(" + x( d.date ) + "," + y( d.cpi ) + ")" ); | |
} else { | |
var x0 = x.invert( d3.mouse( this )[0] ), | |
i = bisectDate( data, x0, 1 ), | |
d0 = data[i - 1], | |
d1 = data[i], | |
d = x0 - d0.date > d1.date - x0 ? d1 : d0; | |
focus.select( "text.y1" ) | |
.html( '(' + d.period + '/' + d.periodyear + ', ' + ( d.cpi ) + ")" ) | |
.attr( "transform", "translate(" + ( x( d.date ) - 55 ) + "," + ( y( d.cpi ) - 8 ) + ")" ); | |
focus.select( "text.y2" ) | |
.html( '(' + d.period + '/' + d.periodyear + ', ' + ( d.cpi ) + ")" ) | |
.attr( "transform", "translate(" + ( x( d.date ) - 55 ) + "," + ( y( d.cpi ) - 8 ) + ")" ); | |
focus.select( "circle.y" ) | |
.attr( "transform", | |
"translate(" + x( d.date ) + "," + y( d.cpi ) + ")" ); | |
}; | |
}; | |
} ); | |
function formatMoney( num ) { | |
return num.toString().replace( /(\d)(?=(\d{3})+(?!\d))/g, "$1," ) | |
}; | |
window.addEventListener( 'resize', function () { | |
"use strict"; | |
window.location.reload(); | |
} ); | |
d3.csv( "cpi_tab.csv", function ( data ) { | |
function tabulate( data, columns ) { | |
var table = d3.select( "#cpi" ), | |
columnNames = ["Month", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015","2016", "% Chg. from year prev."], | |
thead = table.append( "thead" ), | |
tbody = table.append( "tbody" ); | |
// append the header row | |
thead.append( "tr" ) | |
.selectAll( "th" ) | |
.data( columnNames ) | |
.enter() | |
.append( "th" ) | |
.text( function ( columnNames ) { return columnNames; } ); | |
// create a row for each object in the data | |
var rows = tbody.selectAll( "tr" ) | |
.data( data ) | |
.enter() | |
.append( "tr" ); | |
// create a cell in each row for each column | |
var cells = rows.selectAll( "td" ) | |
.data( function ( row ) { | |
return columns.map( function ( column ) { | |
return { column: column, value: row[column] }; | |
} ); | |
} ) | |
.enter() | |
.append( "td" ) | |
.attr( "style", "font-family: 'Lato'" ) | |
.attr("style", "padding: 2px;") | |
.html( function ( d ) { | |
return d.value; | |
} ); | |
return table; | |
}; | |
var peopleTable = tabulate( data, ["c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12"] ) | |
function formatMoney( num ) { | |
return num.toString().replace( /(\d)(?=(\d{3})+(?!\d))/g, "$1," ) | |
}; | |
} ); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment