Data from Table 1-1 of Vital Statistics on Congress. Interactive treatment inspired by Nathan Yau.
Last active
May 15, 2019 18:20
-
-
Save cingraham/7424289 to your computer and use it in GitHub Desktop.
Table 1-1: Congressional Seats by Region and State
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
date | Alabama | Arkansas | Florida | Georgia | Louisiana | Mississippi | North Carolina | South Carolina | Tennessee | Texas | Virginia | Kentucky | Maryland | Missouri | Oklahoma | West Virginia | Connecticut | Maine | Massachusetts | New Hampshire | Rhode Island | Vermont | Delaware | New Jersey | New York | Pennsylvania | Illinois | Indiana | Michigan | Ohio | Wisconsin | Iowa | Kansas | Minnesota | Nebraska | North Dakota | South Dakota | Arizona | Colorado | Idaho | Montana | Nevada | New Mexico | Utah | Wyoming | Alaska | California | Hawaii | Oregon | Washington | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
region | South | South | South | South | South | South | South | South | South | South | South | Border | Border | Border | Border | Border | NewEngland | NewEngland | NewEngland | NewEngland | NewEngland | NewEngland | MidAtlantic | MidAtlantic | MidAtlantic | MidAtlantic | Midwest | Midwest | Midwest | Midwest | Midwest | Plains | Plains | Plains | Plains | Plains | Plains | RockyMountains | RockyMountains | RockyMountains | RockyMountains | RockyMountains | RockyMountains | RockyMountains | RockyMountains | PacificCoast | PacificCoast | PacificCoast | PacificCoast | PacificCoast | |
1910 | 10 | 7 | 4 | 12 | 8 | 8 | 10 | 7 | 10 | 18 | 10 | 11 | 6 | 16 | 8 | 6 | 5 | 4 | 16 | 2 | 3 | 2 | 1 | 12 | 43 | 36 | 27 | 13 | 13 | 22 | 11 | 11 | 8 | 10 | 6 | 3 | 3 | 1 | 4 | 2 | 2 | 1 | 1 | 2 | 1 | 0 | 11 | 0 | 3 | 5 | |
1930 | 9 | 7 | 5 | 10 | 8 | 7 | 11 | 6 | 9 | 21 | 9 | 9 | 6 | 13 | 9 | 6 | 6 | 3 | 15 | 2 | 2 | 1 | 1 | 14 | 45 | 34 | 27 | 12 | 17 | 24 | 10 | 9 | 7 | 9 | 5 | 2 | 2 | 1 | 4 | 2 | 2 | 1 | 1 | 2 | 1 | 0 | 20 | 0 | 3 | 6 | |
1940 | 9 | 7 | 6 | 10 | 8 | 7 | 12 | 6 | 10 | 21 | 9 | 9 | 6 | 13 | 8 | 6 | 6 | 3 | 14 | 2 | 2 | 1 | 1 | 14 | 45 | 33 | 26 | 11 | 17 | 23 | 10 | 8 | 6 | 9 | 4 | 2 | 2 | 2 | 4 | 2 | 2 | 1 | 2 | 2 | 1 | 0 | 23 | 0 | 4 | 6 | |
1950 | 9 | 6 | 8 | 10 | 8 | 6 | 12 | 6 | 9 | 22 | 10 | 8 | 7 | 11 | 6 | 6 | 6 | 3 | 14 | 2 | 2 | 1 | 1 | 14 | 43 | 30 | 25 | 11 | 18 | 23 | 10 | 8 | 6 | 9 | 4 | 2 | 2 | 2 | 4 | 2 | 2 | 1 | 2 | 2 | 1 | 1 | 30 | 1 | 4 | 7 | |
1960 | 8 | 4 | 12 | 10 | 8 | 5 | 11 | 6 | 9 | 23 | 10 | 7 | 8 | 10 | 6 | 5 | 6 | 2 | 12 | 2 | 2 | 1 | 1 | 15 | 41 | 27 | 24 | 11 | 19 | 24 | 10 | 7 | 5 | 8 | 3 | 2 | 2 | 3 | 4 | 2 | 2 | 1 | 2 | 2 | 1 | 1 | 38 | 2 | 4 | 7 | |
1970 | 7 | 4 | 15 | 10 | 8 | 5 | 11 | 6 | 8 | 24 | 10 | 7 | 8 | 10 | 6 | 4 | 6 | 2 | 12 | 2 | 2 | 1 | 1 | 15 | 39 | 25 | 24 | 11 | 19 | 23 | 9 | 6 | 5 | 8 | 3 | 1 | 2 | 4 | 5 | 2 | 2 | 1 | 2 | 2 | 1 | 1 | 43 | 2 | 4 | 7 | |
1980 | 7 | 4 | 19 | 10 | 8 | 5 | 11 | 6 | 9 | 27 | 10 | 7 | 8 | 9 | 6 | 4 | 6 | 2 | 11 | 2 | 2 | 1 | 1 | 14 | 34 | 23 | 22 | 10 | 18 | 21 | 9 | 6 | 5 | 8 | 3 | 1 | 1 | 5 | 6 | 2 | 2 | 2 | 3 | 3 | 1 | 1 | 45 | 2 | 5 | 8 | |
1990 | 7 | 4 | 23 | 11 | 7 | 5 | 12 | 6 | 9 | 30 | 11 | 6 | 8 | 9 | 6 | 3 | 6 | 2 | 10 | 2 | 2 | 1 | 1 | 13 | 31 | 21 | 20 | 10 | 16 | 19 | 9 | 5 | 4 | 8 | 3 | 1 | 1 | 6 | 6 | 2 | 1 | 2 | 3 | 3 | 1 | 1 | 52 | 2 | 5 | 9 | |
2000 | 7 | 4 | 25 | 13 | 7 | 4 | 13 | 6 | 9 | 32 | 11 | 6 | 8 | 9 | 5 | 3 | 5 | 2 | 10 | 2 | 2 | 1 | 1 | 13 | 29 | 19 | 19 | 9 | 15 | 18 | 8 | 5 | 4 | 8 | 3 | 1 | 1 | 8 | 7 | 2 | 1 | 3 | 3 | 3 | 1 | 1 | 53 | 2 | 5 | 9 | |
2010 | 7 | 4 | 27 | 14 | 6 | 4 | 13 | 7 | 9 | 36 | 11 | 6 | 8 | 8 | 5 | 3 | 5 | 2 | 9 | 2 | 2 | 1 | 1 | 12 | 27 | 18 | 18 | 9 | 14 | 16 | 8 | 4 | 4 | 8 | 3 | 1 | 1 | 9 | 7 | 2 | 1 | 4 | 3 | 4 | 1 | 1 | 53 | 2 | 5 | 10 |
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> | |
<meta charset="utf-8"> | |
<html> | |
<head> | |
<title>Table 1-1: Apportionment of Congressional Seats, by Region and State, 1910-2010</title> | |
<link rel = "stylesheet" type = "text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> | |
<style type="text/css"> | |
body { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
margin: auto; | |
padding-top: 10px; | |
padding-left: 10px; | |
position: relative; | |
width: 960px; | |
} | |
.line { | |
fill: none; | |
stroke: steelblue; | |
stroke-width: 2.5px; | |
} | |
h3 { | |
color: #333; | |
} | |
svg { background:rgb(255,255,255);position:relative;} | |
svg:not(:root) { overflow: hidden; } | |
.y.axis line { | |
stroke: #ccc; | |
stroke-dasharray: 1,3; | |
} | |
.x.axis line { | |
stroke: #666; | |
stroke-dasharray: 3,1; | |
} | |
.y.axis path { | |
display: none; | |
} | |
.y.axis .zero line { | |
stroke: #333; | |
} | |
.axis text { | |
font: 10px sans-serif; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.x.axis path { | |
display: none; | |
} | |
.y.axis line { | |
stroke-dasharray: 5,5; | |
} | |
</style> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script> | |
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js" type="text/javascript"></script> | |
</head> | |
<body> | |
<h3><b>Apportionment of Congressional Seats, by Region and State, 1910-2010</b></h3> | |
<h4 id= "location">United States</h4> | |
<p id = "detailtext">Select a region or mouse over a line for more detail.</p> | |
<div class="btn-group" id="select"> | |
<button type="button" class="btn btn-default active" value = "None">None</button> | |
<button type="button" class="btn btn-default" value = "South">South</button> | |
<button type="button" class="btn btn-default" value = "Border">Border</button> | |
<button type="button" class="btn btn-default" value = "NewEngland">New England</button> | |
<button type="button" class="btn btn-default" value = "MidAtlantic">Mid-Atlantic</button> | |
<button type="button" class="btn btn-default" value = "Midwest">Midwest</button> | |
<button type="button" class="btn btn-default" value = "Plains">Plains</button> | |
<button type="button" class="btn btn-default" value = "RockyMountains">Rocky Mountains</button> | |
<button type="button" class="btn btn-default" value = "PacificCoast">Pacific Coast</button> | |
</div> | |
<div id = "#container"></div> | |
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> | |
<script type="text/javascript"> | |
//set margins, height, and width | |
var margin = {top: 5, right: 20, bottom: 20, left: 40}, | |
w = 960 - margin.left - margin.right, | |
h = 500 - margin.top - margin.bottom; | |
//set up formatting for dates(x-axis) and percentages (data labels) | |
var parseDate = d3.time.format("%Y").parse; | |
var formatpct = d3.format("+.1%"); | |
//variables indicating which region is selected, and placeholders in order to revert the caption text | |
var selectedRegion = "none;" | |
var prevText = "", prevRegion = ""; | |
//x and y-axis scales. I hard-coded the y-max because I'm lazy; you could also dig this up with d3.max | |
var x = d3.time.scale() | |
.range([0, w]); | |
var y = d3.scale.linear() | |
.range([h, 0]) | |
.domain([0, 53]); | |
//total seats by region in 1910 | |
var totals1910 = { | |
South: 104, | |
Border: 47, | |
NewEngland: 32, | |
MidAtlantic: 92, | |
Midwest: 86, | |
Plains: 41, | |
RockyMountains: 14, | |
PacificCoast:19 | |
}; | |
//total seats by region in 2010 | |
var totals2010 = { | |
South: 138, | |
Border: 30, | |
NewEngland: 21, | |
MidAtlantic: 58, | |
Midwest: 65, | |
Plains: 21, | |
RockyMountains: 31, | |
PacificCoast: 71 | |
}; | |
//color scale -- d3's prebuilt 10-category ordinal scale | |
var color = d3.scale.category10(); | |
//set up the line generator | |
var line = d3.svg.line() | |
.x(function(d) { return x(d.date); }) | |
.y(function(d) { return y(d.value); }); | |
//set up your axes | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.tickSize(5) | |
.orient("bottom"); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left"); | |
//add svg to the document | |
var svg = d3.select("body").append("svg") | |
.attr("width", w + margin.left + margin.right) | |
.attr("height", h + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
//read the data file | |
d3.csv("apportionment.csv", function(error, data) { | |
//use date formatting function ensure D3 is reading dates properly | |
data.forEach(function(d,i) { | |
d.date = parseDate(d.date); | |
}); | |
//set x-axis domain using d3.extent (same as calling both min and max) | |
x.domain(d3.extent(data, function(d) { return d.date; })); | |
//set color domain - basically return all columns that aren't the date column | |
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); | |
//create an array to store the region data, currently held in the second header row of our data file | |
var regions = data[0]; | |
//now that we've stored the regions in a separate array, we can trim that row from the data file | |
data = data.filter(function(d, i) { return i > 0; }); | |
//formatting the data so that the line generator reads it properly | |
var states = color.domain().map(function(name, i) { | |
return { | |
name: name, | |
region: regions[name], | |
values: data.map(function(d) { | |
return {date: d.date, value: +d[name]}; | |
}) | |
}; | |
}); | |
//append axes | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + h + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis) | |
.append("text") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 6) | |
.attr("dy", ".71em") | |
.style("text-anchor", "end") | |
.text("Number of seats"); | |
//append a group for each state | |
var state = svg.selectAll(".state") | |
.data(states) | |
.enter().append("g") | |
.attr("class", "state"); | |
//draw the lines, and call functions on mouseover and mouseout | |
state.append("path") | |
.attr("class", function(d) { return "line " + d.region; }) | |
.attr("d", function(d) { return line(d.values); }) | |
.attr("id", function(d) { return d.name; }) | |
.style("stroke", function(d) { return color(d.region); }) | |
.style("opacity", "0.1") | |
.on("mouseover", function(d) { showDetail(d); }) | |
.on("mouseout", function(d) { removeDetail(d); }); | |
//tell it what to do when you click one of the filter buttons at top | |
d3.selectAll(".btn") | |
.on("click", function() { | |
var reg = this.value; | |
var display = this.innerHTML; | |
getHighlight(reg, display); | |
}); | |
}); | |
//this function highlights the selected line and updates the caption at the top of the page | |
function showDetail(line) { | |
prevText = d3.selectAll("#detailtext").html(); | |
prevRegion = d3.selectAll("#location").html(); | |
var total1910 = line.values[0].value; | |
var total2010 = line.values[9].value; | |
var pctChange = formatpct((total2010 - total1910)/total1910); | |
if(total1910 == 0) { | |
pctChange = "N/A%"; | |
}; | |
var highlighted = svg.selectAll("path").filter(function(g) {return g.name == line.name; }); | |
highlighted.transition().duration(250).style({"opacity":"1"}); | |
d3.selectAll("#location") | |
.html(line.name); | |
d3.selectAll("#detailtext") | |
.html("<p>" + line.name + " had <b>" + total1910 + " seats</b> in 1910" + " and <b>" + total2010 + " seats</b> in 2010, a change of <b>" + pctChange + "</b>"); | |
} | |
//basically the reverse of the previous - note that we use prevRegion and prevText to revert back to the prior header/caption. This is because this text will differ depending on whether a region is selected | |
function removeDetail(line) { | |
var highlighted = svg.selectAll("path").filter(function(g) {return g.name ==line.name; }); | |
highlighted.transition().duration(250).style("opacity", function() { | |
if(selectedRegion == line.region) { | |
return 0.8; | |
} else { | |
return 0.1; | |
} | |
}); | |
d3.selectAll("#location") | |
.html(prevRegion); | |
d3.selectAll("#detailtext") | |
.html(prevText); | |
} | |
//update lines and captions when you select a region | |
function getHighlight (region, displaytext) { | |
d3.selectAll("#location") | |
.html(displaytext); | |
var total1910 = totals1910[region]; | |
var total2010 = totals2010[region]; | |
var pctChange = formatpct((total2010 - total1910)/total1910); | |
selectedRegion = region; | |
if(region == "None") { | |
d3.selectAll("#location") | |
.html("United States"); | |
d3.selectAll("#detailtext") | |
.html("<p>Select a region or mouse over a line for more detail.</p>"); | |
} else { | |
d3.selectAll("#location") | |
.html(displaytext); | |
d3.selectAll("#detailtext") | |
.html("<p>States in the " + displaytext + " region had <b>" + total1910 + " seats</b> in 1910" + " and <b>" + total2010 + " seats</b> in 2010, a change of <b>" + pctChange + "</b>"); | |
} | |
d3.selectAll(".line") | |
.transition() | |
.duration(500) | |
.style({"opacity":"0.1","stroke-width":"2.5"}); | |
if(region != "none") { | |
d3.selectAll("." + region) | |
.transition() | |
.duration(500) | |
.style({"opacity":"0.8","stroke-width":"5"}) | |
} | |
} | |
d3.select(self.frameElement).style("height", "700px"); | |
</script> | |
<script type="text/javascript"> | |
// allow buttons to indicate whether they're selected | |
$("#select button").click(function() { | |
$("#select button").removeClass("active"); | |
$(this).addClass("active"); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment