Skip to content

Instantly share code, notes, and snippets.

@alecrajeev
Last active March 26, 2016 08:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alecrajeev/5d9cc533088d2f22844c to your computer and use it in GitHub Desktop.
Save alecrajeev/5d9cc533088d2f22844c to your computer and use it in GitHub Desktop.
United States Congressional Districts Hexagons

U.S. Congressional Districts as Hexagons.

Background

The purpose of this map as detailed on Daily Kos is to represent the congressional districts in the United States accurately. Currently it is difficult to show the districts because some such as those in New York City are very small, while others like Montana are the size of an entire state. Previosly the maps needed to be zoomable to see the districts containing cities. Other represntations such as cartograms warped the country's shape. This map attempts to fix that by giving each congressional district equal area i.e. five regular hexagons.

According to the original Daily Kos article, the map was built by Daniel Donner.

Porting the Map

I did not design the map. This project's purpose is to port the map to a more useable format. I ported the map to a topoJSON file using node. Then it is displayed in the browser using D3. The orignal hexagonal mesh comes from Mike Bostock, the creator of the javascript library D3. I changed the hexagonal mesh to be a larger size that will contain the entire United States map. Then I set every hexagon to the district that it was supposed to represent.

The file congress.csv is a list of every district, and the id number for all 5 hexagons for each district. This is then converted to a json file using the python program convertCSVtoJSON.py. Then a Node script is used to build the topoJSON file. Every hexagon has an id number. It sets each hexagon to a specific district. If it is not part of a district then it is set to ocean. It gets the information on which district to assign it to using the coverted json file districtList.json. The actual code for the hexagonal mesh comes the aforemetioned program by Mike Bostock. I adapted it to my needs. The node script that does this is called buildtopoJSON.js. This exports a topoJSON file called ushex.json.

Displaying the Map on Browser

Now it is ready to launched in a browser. The file index.html imports the various javascript libraries used such as D3, topoJSON, and Queue. It creates dividers for the main map, and buttons to select which demographics you want to be displayed. The javascript source with D3 is called hexscript.js. This displays the hexagon mesh and assigns each district an id. This is done alphabetically, so Alabama-1 is 1, and Wyoming-1 is 435. Then it connects this information with demographic data from the 2010 U.S. census. This data was taken from Dave Wasserman's google sheets file on it. The hexscript file imports this and assigns colors based on demographics. The darker the color is, the more people of that demographic live there. The data on votes comes from The New York Times Congress API. The New York Times does not endorse or promote my idea or whatever.

 "Congressional Map"

// this is the javascript file that has all the functions that regarding color
var color = d3.scale.linear() // initial color scale for the demographic data
.range(['rgb(247,252,245)','rgb(229,245,224)','rgb(199,233,192)','rgb(161,217,155)','rgb(116,196,118)','rgb(65,171,93)','rgb(35,139,69)','rgb(0,109,44)','rgb(0,68,27)']);
var voteColor = d3.scale.ordinal() // color scale for a specifc vote
.range(["#7A9CC7","#DA9285","#a9a9a9","#405695","#B43030"])
.domain([0, 1, 2, 3, 4]);
var bernieColor = d3.scale.ordinal() // color scale for bernie event data
.range(['rgb(255,247,243)','rgb(253,224,221)','rgb(252,197,192)','rgb(250,159,181)','rgb(247,104,161)','rgb(221,52,151)','rgb(174,1,126)','rgb(122,1,119)','rgb(73,0,106)'])
.domain([0,1,2,3,4,5,6,7,8]);
var stateColor = ["#A94588","#D76940","#D13F46","#23A5C5", "#F0A851", "#F0A851", "#A94588", "#23A5C5", "#228947", "#2B6AA1", "#D13F46", "#A94588", "#A94588",
"#2B6AA1", "#F0A851", "#D76940", "#D13F46", "#D13F46", "#6EAE51", "#A94588", "#A94588", "#D76940", "#D13F46", "#F0A851", "#228947", "#D76940", "#23A5C5",
"#23A5C5", "#D13F46", "#6EAE51", "#A94588", "#2B6AA1", "#23A5C5", "#2B6AA1", "#6EAE51", "#2B6AA1", "#2B6AA1", "#D13F46", "#23A5C5", "#6EAE51", "#6EAE51",
"#D76940", "#6EAE51", "#228947", "#F0A851", "#F0A851", "#D13F46", "#726198", "#726198", "#726198"];
function buildColorRange(i) { // builds the color range
switch(i) {
case 0: // white
color.range(['rgb(247,252,245)','rgb(229,245,224)','rgb(199,233,192)','rgb(161,217,155)','rgb(116,196,118)','rgb(65,171,93)','rgb(35,139,69)','rgb(0,109,44)','rgb(0,68,27)']);
break;
case 1: // black
color.range(['rgb(252,251,253)','rgb(239,237,245)','rgb(218,218,235)','rgb(188,189,220)','rgb(158,154,200)','rgb(128,125,186)','rgb(106,81,163)','rgb(84,39,143)','rgb(63,0,125)']);
break;
case 2: // latino
color.range(['rgb(247,251,255)','rgb(222,235,247)','rgb(198,219,239)','rgb(158,202,225)','rgb(107,174,214)','rgb(66,146,198)','rgb(33,113,181)','rgb(8,81,156)','rgb(8,48,107)']);
break;
case 3: // asian
color.range(['rgb(255,245,240)','rgb(254,224,210)','rgb(252,187,161)','rgb(252,146,114)','rgb(251,106,74)','rgb(239,59,44)','rgb(203,24,29)','rgb(165,15,21)','rgb(103,0,13)']);
break;
case 4: // multiracial
color.range(['rgb(255,247,251)','rgb(236,226,240)','rgb(208,209,230)','rgb(166,189,219)','rgb(103,169,207)','rgb(54,144,192)','rgb(2,129,138)','rgb(1,108,89)','rgb(1,70,54)']);
break;
case 5: // bernie event data
color.range(['rgb(255,247,251)','#e4fff9','rgb(208,209,230)','rgb(166,189,219)','rgb(103,169,207)','rgb(54,144,192)','rgb(2,129,138)','rgb(1,108,89)']);
break;
default: // presidential
color.range(['#AE000C','#BA3035','#C56365','#D09697','#DBC8C8','#C8C8D5','#9697BD','#6465A5','#32358E', '#010a79']);
break;
}
}
function buildVoteColor() {
voteColor = d3.scale.ordinal() // color scale for a specifc vote
.range(["#7A9CC7","#DA9285","#a9a9a9","#405695","#B43030"])
.domain([0, 1, 2, 3, 4]);
}
function buildBernieColor() {
bernieColor = d3.scale.ordinal() // color scale for bernie event data
.range(['rgb(255,247,243)','rgb(253,224,221)','rgb(252,197,192)','rgb(250,159,181)','rgb(247,104,161)','rgb(221,52,151)','rgb(174,1,126)','rgb(122,1,119)','rgb(73,0,106)'])
.domain([0,1,2,3,4,5,6,7,8]);
}
function showBernieLegend() {
var LegendContent = svgBernieLegend.selectAll(".LegendContent")
.data(bernieColor.domain())
var LegendEnter = LegendContent.enter()
.append("g")
.attr("class", "LegendContent")
.attr("transform", function(d,i) {
var rectHeight = i*(legendRectSize + legendSpacing);
var rectWidth = legendRectSize;
return "translate(" + rectWidth + ", " + rectHeight + ")";
})
.on("mouseover", function(d) {showBernieSelection(d); })
.on("mouseout", function(d) {hideBernieSelection(); })
LegendEnter.append("rect")
.attr("width", legendRectSize-2)
.attr("height", legendRectSize)
.style("fill", function(d) {return bernieColor(d)})
.style("stroke", "black")
LegendEnter.append("text")
.attr("x", legendRectSize + legendSpacing*1.3)
.attr("y", legendRectSize-1)
.text(function(d) {return interpretBin(d); });
var updateSelection = svgBernieLegend.selectAll(".LegendContent")
.transition()
.duration(500)
.style("opacity", "1")
.attr("transform", function(d,i) {
var rectHeight = i*(legendRectSize + legendSpacing);
var rectWidth = legendRectSize;
return "translate(" + rectWidth + ", " + rectHeight + ")";
})
updateSelection.select("rect")
.style("fill", function(d) {return bernieColor(d); });
updateSelection.select("text")
.text(function(d) {return "< " + interpretBin(d); });
LegendContent.exit()
.transition()
.duration(500)
.style("opacity", "0")
.remove();
}
function interpretBin(d) {
var bernieBin = -1;
switch(d) {
case 0:
bernieBin = 0;
break;
case 1:
bernieBin = 236;
break;
case 2:
bernieBin = 472;
break;
case 3:
bernieBin = 708;
break;
case 4:
bernieBin = 944;
break;
case 5:
bernieBin = 1179;
break;
case 6:
bernieBin = 1415;
break;
case 7:
bernieBin = 1651;
break;
default:
bernieBin = 1887;
break;
}
if (bernieBin == 0)
return "Less than 1";
return "<" + (bernieBin+1) + " attendees" ;
}
function buildColorDomain(i, extent) {
var colorDomain = [];
if (i < 6) {
var j = 0;
for (i = extent[0]; i <= (extent[1]+.01); i += ((extent[1]+.01) - extent[0])/8.0)
colorDomain[j++] = i;
} else
colorDomain = [.18, .3, .35, .4, .45, .55, .6, .65, .7, .97];
return colorDomain;
}
function buildExtentData() { // builds the mininum and maximum value array, extent, for each dataset
extentData[0] = d3.extent(demoData, function(d) {return d.White; });
extentData[1] = d3.extent(demoData, function(d) {return d.Black; });
extentData[2] = d3.extent(demoData, function(d) {return d.Latino; });
extentData[3] = d3.extent(demoData, function(d) {return d.Asian; });
extentData[4] = d3.extent(demoData, function(d) {return d.Multiracial; });
extentData[5] = d3.extent(demoData, function(d) {return d.bernieAttendance; })
}
function updateHexagonColor(i) { // fills in the hexagons with the correct color according to the scale
hexagons
.transition()
.delay(500)
.style({fill: function(d) {return getDistrictColor(d.properties.districtID,i); },
stroke: function(d) {return getDistrictColor(d.properties.districtID,i); }});
}
function getDistrictColor(districtID,i) {
if (districtID != -1)
return color(dataByDistrictID[districtID][i])
}
function getStateColor(stateID) {
if (stateID != -1)
return stateColor[stateID];
}
function getVoteDistrictColor(districtID) {
if (districtID != -1) {
return voteColor(voteByDistrictID[districtID]);
}
}
function getBernieDistrictColor(bernieBin) {
if (bernieBin != -1) {
return bernieColor(bernieBin);
}
}
function updateVoteHexagonColor() {
hexagons
.transition()
.delay(1000)
.style({fill: function(d) {return getVoteDistrictColor(d.properties.districtID); },
stroke: function(d) {return getVoteDistrictColor(d.properties.districtID); }});
}
function updateBernieHexagonColor() {
hexagons
.transition()
.delay(1000)
.style({fill: function(d) {return getBernieDistrictColor(d.properties.bernieBin); },
stroke: function(d) {return getBernieDistrictColor(d.properties.bernieBin); }});
}
var width = 1250,
height = 730,
radius = 6.5;
var hexagons, demoData;
var districtList = {},
voteByDistrictID = {},
dataByDistrictID = {},
extentData = {};
specificDistrictID = -2
var dataSets = ["White", "Black", "Latino", "Asian", "Multiracial", "Bernie Event", "Obama 2012", "Obama 2008"];
var legendRectSize = 15,
legendSpacing = 7;
var bernieBorder;
var binSelector = -1; // used to figure out which of the bernie bins is selected
var dataSetSelector = -1; // used to figure out which data set is being shown
var coordinates = [0,0];
var svg = d3.select(".map").append("svg")
.attr("width", width)
.attr("height", height);
var svgLegend = d3.select(".legend").append("svg")
.attr("height", "220px")
.attr("width", "162px");
var svgBernieLegend = d3.select(".bernieLegend").append("svg")
.attr("height", "220px")
.attr("width", "162px");
queue()
.defer(d3.tsv, "https://raw.githubusercontent.com/alecrajeev/UnitedStatesHex/master/districtList.tsv")
.defer(d3.json, "https://raw.githubusercontent.com/alecrajeev/UnitedStatesHex/master/ushex.json")
.defer(d3.tsv, "https://raw.githubusercontent.com/alecrajeev/UnitedStatesHex/master/demographics.tsv")
.defer(d3.tsv, "https://raw.githubusercontent.com/alecrajeev/UnitedStatesHex/master/presidential_results.tsv")
.await(makeMyMap);
function makeMyMap(error, districtListData, ushex, ddata, presidentialData) {
if (error)
return console.warn(error);
districtListData.forEach(function(d) { // will use import the nyt member list here
d.districtID = +d.districtID;
districtList[d.districtID] = [d.statecd, d.nytID, d.party]; // eventually make this tree or a hashtable, preprocess in node
});
ddata.forEach(function(d) {
d.Asian = +d.Asian;
d.Black = +d.Black;
d.districtID = +d.districtID;
d.Latino = +d.Latino;
d.Multiracial = +d.Multiracial;
d.Party = +d.Party;
d.White = +d.White;
d.bernieAttendance = +d.bernieAttendance;
dataByDistrictID[d.districtID] = [d.White, d.Black, d.Latino, d.Asian, d.Multiracial, d.bernieAttendance];
});
demoData = ddata;
presidentialData.forEach(function(d) {
d.Obama2012 = +d.Obama2012;
d.Obama2008 = +d.Obama2008;
d.districtID = +d.districtID;
dataByDistrictID[d.districtID].push(d.Obama2012,d.Obama2008);
});
buildExtentData();
var projection = hexProjection(radius);
var path = d3.geo.path()
.projection(projection)
var hexFeatures = topojson.feature(ushex, ushex.objects.states).features;
hexagons = svg.append("g").attr("class", "hexagon").selectAll("hexagon")
.data(hexFeatures)
.enter()
.append("path")
.attr("d", path)
.style({fill: function(d) {return getStateColor(d.properties.stateID); },
stroke: function(d) {return getStateColor(d.properties.stateID); }})
.on("mouseover", hoverOnDistrict)
var stateBorder = svg.append("path")
.attr("class", "stateBorder")
.call(drawStateBorder);
var districtBorder = svg.append("path")
.attr("class", "districtBorder")
.call(drawDistrctBorder);
var specificDistrict = svg.append("path")
.attr("class", "specificBorder")
.call(drawSpecificDistrict);
drawBernieBorder = function (border) {
border.attr("d", path(topojson.mesh(ushex, ushex.objects.states, checkBorderByBernie)));
}
bernieBorder = svg.append("path")
.attr("class", "bernieBorder")
.call(drawBernieBorder);
function hoverOnDistrict(d) {
coordinates = d3.mouse(this);
showTooltip(d, coordinates);
specificDistrictID = d.properties.districtID;
specificDistrict.call(drawSpecificDistrict);
changeInfo(d);
}
function showTooltip(d, coordinates) {
if (d.properties.state != "Ocean"){
d3.select(".g-tooltip")
.style({display: "block",
top: function (e) {return (coordinates[1] - 35).toString() + "px"; },
left: function(e) {return (coordinates[0] - 100).toString() + "px"; }
});
d3.select(".tooltip-district")
.text(d.properties.state + "-" + d.properties.district);
if (dataSetSelector >= 0)
if (dataSetSelector == 5)
d3.select(".tooltip-data").text(dataByDistrictID[d.properties.districtID][dataSetSelector] + " attendees");
else
d3.select(".tooltip-data").text(getShortened(dataSets[dataSetSelector]) + ": " + d3.round(dataByDistrictID[d.properties.districtID][dataSetSelector]*100, 1) + "%");
else
if (dataSetSelector == -2)
d3.select(".tooltip-data").text(interpretVote(voteByDistrictID[d.properties.districtID]));
else
d3.select(".tooltip-data").text("");
}
else
d3.select(".g-tooltip").style("display", "none");
function getShortened(title) {
var split = title.split(" ");
if (split.length < 2)
return title;
else
return split[1];
}
}
function drawSpecificDistrict(border) {
border.attr("d", path(topojson.mesh(ushex, ushex.objects.states, checkSpecificDistrict)));
}
function drawDistrctBorder(border) {
border.attr("d", path(topojson.mesh(ushex, ushex.objects.states, checkBorderByDistrict)));
}
function drawStateBorder(border) {
border.attr("d", path(topojson.mesh(ushex, ushex.objects.states, checkBorderByState)));
}
function checkBorderByBernie(hex1, hex2) {
hex1 = hex1.properties.bernieBin;
hex2 = hex2.properties.bernieBin;
hex1 = (hex1 == binSelector ? true : false);
hex2 = (hex2 == binSelector ? true : false);
return hex1 != hex2;
}
function checkSpecificDistrict(hex1, hex2) {
if (specificDistrictID < 0) // if there is no specific district to be highlighted
return false;
// if when traversing the hexmesh you are not near the specific district
if (hex1.properties.districtID != specificDistrictID &&
hex2.properties.districtID != specificDistrictID)
return false;
if (hex1.properties.state == hex2.properties.state)
return hex1.properties.district != hex2.properties.district;
else
return true;
}
function checkBorderByDistrict(hex1, hex2) {
if (hex1.properties.state == hex2.properties.state)
return hex1.properties.district != hex2.properties.district;
else
return true;
}
function checkBorderByState(hex1, hex2) {
return hex1.properties.state != hex2.properties.state;
}
function hexProjection(radius) { // comes from Mike Bostock's hexagon mesh source code
var dx = radius * 2 * Math.sin(Math.PI / 3),
dy = radius * 1.5;
return {
stream: function(stream) {
return {
point: function(x, y) { stream.point(x * dx / 2, (y - (2 - (y & 1)) / 3) * dy / 2); },
lineStart: function() { stream.lineStart(); },
lineEnd: function() { stream.lineEnd(); },
polygonStart: function() { stream.polygonStart(); },
polygonEnd: function() { stream.polygonEnd(); }
};
}
};
}
}
function showStates() {
d3.select(".header").text("States");
hexagons
.transition()
.delay(750)
.style({fill: function(d) {return getStateColor(d.properties.stateID); },
stroke: function(d) {return getStateColor(d.properties.stateID); }});
d3.select(".legend").style("display", "none");
d3.select(".voteLegend").style("display", "none");
d3.select(".bernieLegend").style("display", "none");
dataSetSelector = -1;
// d3.select(".districtBorder").style("stroke-opacity", ".2");
}
function showRollCallVote() {
buildVoteColor();
updateVoteHexagonColor();
showVoteLegend();
d3.select(".voteLegend").style("display", "block");
d3.select(".legend").style("display", "none");
dataSetSelector = -2;
// d3.select(".districtBorder").style("stroke-opacity", ".5");
}
function showDataSet(i) {
d3.select(".header").text(dataSets[i] + " Demographics by Congressional District");
buildColorRange(i);
color.domain(buildColorDomain(i,extentData[i]));
updateHexagonColor(i);
showLegend(i);
d3.select(".bernieLegend").style("display", "none");
d3.select(".legend").style("display", "block");
d3.select(".voteLegend").style("display", "none");
dataSetSelector = i;
// d3.select(".districtBorder").style("stroke-opacity", ".5");
}
function showBernie() {
d3.select(".header").text(dataSets[5] + " Data by Congressional District");
buildBernieColor();
updateBernieHexagonColor();
showBernieLegend();
d3.select(".legend").style("display", "none");
d3.select(".bernieLegend").style("display", "block");
d3.select(".voteLegend").style("display", "none");
dataSetSelector = 5;
}
function showBernieSelection(i) {
binSelector = i;
bernieBorder.call(drawBernieBorder);
d3.select(".bernieBorder").style("stroke-opacity" , "1");
}
function hideBernieSelection(d) {
d3.select(".bernieBorder").style("stroke-opacity" , "0");
}
function showLegend(i) {
var LegendContent = svgLegend.selectAll(".LegendContent")
.data(color.domain())
var LegendEnter = LegendContent.enter()
.append("g")
.attr("class", "LegendContent")
.attr("transform", function(d,i) {
var rectHeight = i*(legendRectSize + legendSpacing);
var rectWidth = legendRectSize;
return "translate(" + rectWidth + ", " + rectHeight + ")";
})
LegendEnter.append("rect")
.attr("width", legendRectSize-2)
.attr("height", legendRectSize)
.style("fill", function(d) {return color(d)})
.style("stroke", "black")
LegendEnter.append("text")
.attr("x", legendRectSize + legendSpacing*1.3)
.attr("y", legendRectSize-1)
.text(function(d) {
if (i != 5)
return d3.round(d*100,1).toString() + "%";
else // bernie
return d3.round(d).toString() + " attendees";
});
var updateSelection = svgLegend.selectAll(".LegendContent")
.transition()
.duration(1000)
.style("opacity", "1")
.attr("transform", function(d,i) {
var rectHeight = i*(legendRectSize + legendSpacing);
var rectWidth = legendRectSize;
return "translate(" + rectWidth + ", " + rectHeight + ")";
})
updateSelection.select("rect")
.style("fill", function(d) {return color(d); });
updateSelection.select("text")
.text(function(d) {
if (i != 5)
return d3.round(d*100,1).toString() + "%";
else // bernie
return d3.round(d).toString() + " attendees";
});
LegendContent.exit()
.transition()
.duration(1000)
.style("opacity", "0")
.remove();
}
function getRealDistrict(i, state) { // returns "at large" if the district number is 0, like Montana
if (i > 0)
return i;
return "At-Large";
}
function changeInfo(d) {
if (d.properties.state != "Ocean") { // if you ARE on a district
d3.select(".whichState").text(d.properties.state);
d3.select(".whichDistrict").text(getRealDistrict(d.properties.district, d.properties.state));
for (i = 0; i < 8; i++) {
var classNameSplit = dataSets[i].split(" ");
if (classNameSplit.length < 2) // data set names that are one word (Asian)
d3.select("." + dataSets[i] + ".Info").text(dataSets[i] + ": " + d3.round(dataByDistrictID[d.properties.districtID][i]*100, 1) + "%");
else { // data set names that are two words (Obama 2012)
if (i > 5) // obama 2012
d3.select("." + classNameSplit[0] + classNameSplit[1] + ".Info").text(dataSets[i] + ": " + d3.round(dataByDistrictID[d.properties.districtID][i]*100, 1) + "%");
else // bernie
d3.select("." + classNameSplit[0] + classNameSplit[1] + ".Info").text(dataSets[i] + ": " + d3.round(dataByDistrictID[d.properties.districtID][i]));
}
}
}
else { // if you are NOT on a district
d3.select(".whichState").text("");
d3.select(".whichDistrict").text("");
for (i = 0; i < 8; i++) {
var classNameSplit = dataSets[i].split(" ");
if (classNameSplit.length < 2)
d3.select("." + dataSets[i] + ".Info").text(dataSets[i] + ": ");
else
d3.select("." + classNameSplit[0] + classNameSplit[1] + ".Info").text(dataSets[i] + ": ");
}
}
}
function getdistrictID(statecd) { // give the id for the specific congressional district
// determined by the name of the state and district number
// will eventually preprocess a hashtable in node
for (i = 0; i < 435; i++) {
if (districtList[i][0] === statecd) {
return i;
}
}
return -1;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="favicon.ico" />
<link rel="stylesheet", type="text/css", href="style.css">
<title>United States Congressional Districts as Hexagons</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js">
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js">
</script>
<script type="text/javascript" src="colorBuilder.js"></script>
</head>
<body>
<div class="top">
<h3 class="header">Bernie Event Data by Congressional District</h3>
</div>
<div class="left">
<div class="sidebar">
<text>Data Set</text>
<div class="typeToggle">
<input type="radio" name="data-selector" checked onclick="showStates()">States
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(6)">Presidential Results 2012
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(7)">Presidential Results 2008
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(0)">White Demographics
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(1)">Black Demographics
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(2)">Latino Demographics
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(3)">Asian Demographics
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(4)">MultiRacial Demographics
</div>
</div>
<div class="information">
<div>State: <span class="whichState"></span></div>
<div>District: <span class="whichDistrict"></span></div>
<div class="Obama2012 Info"> Obama 2012: </div>
<div class="Obama2008 Info"> Obama 2008: </div>
<div class="White Info">White: </div>
<div class="Black Info">Black: </div>
<div class="Latino Info">Latino: </div>
<div class="Asian Info">Asian: </div>
<div class="Multiracial Info">Multiracial: </div>
<div class="BernieEvent Info">Bernie Event: </div>
</div>
<div class="legend"></div>
<div class="bernieLegend"></div>
</div>
<div class="main">
<div class="map"></div>
<div class="g-tooltip">
<div class="tooltip-district"></div>
<div class="tooltip-data"></div>
</div>
</div>
<div class="right">
<div class="voteSelector">
<text>Congressional Votes</text>
</div>
<div class="voteLegend"></div>
<div class="nytimesLogo">
<a href="http://developer.nytimes.com"><img src="poweredby_nytimes_178c.png"></a>
</div>
</div>
</body>
<script type="text/javascript" src="hexscript.js"></script>
<script type="text/javascript" src="votescript.js"></script>
</html>
.top {
position: absolute;
left:0; right:0;
height: 92px;
margin-left: 15px;
font-family: 'Helvetica Neue';
font-weight: bold;
}
.left {
position: absolute;
left:0; top:80px; bottom: 0;
width: 178px;
margin-left: 15px;
}
.main {
position: relative;
left:180px; top:92px; right:0; bottom:0;
}
.right {
position: relative;
background: #fff;
top: -656px;
left: 1200px;
width: 178px;
}
.map {
position: relative;
top: -60px;
}
.g-tooltip {
position: absolute;
background-color: #fff;
padding: 5px 8px 5px 6px;
font-family: "Helvetica Neue";
top: 800px;
width: 100px;
height: 30px;
overflow: hidden;
border: 1px solid #ccc;
box-shadow: 2px 2px 7px rgba(0,0,0,0.3);
/* font-size: 62.5%;
*/}
.tooltip-district {
font-weight: bold;
text-align: center;
}
.tooltip-data {
font-size: 80%;
text-align: center;
}
.legend {
position: relative;
top: -6px;
height: 220px;
border: solid black;
padding: 5px;
padding-top: 10px;
display: block;
font-family: "Helvetica Neue";
stroke-width: 2px;
display: none;
}
.bernieLegend {
position: relative;
top: -6px;
height: 220px;
border: solid black;
padding: 5px;
padding-top: 10px;
display: block;
font-family: "Helvetica Neue";
stroke-width: 2px;
display: none;
}
.voteSelector {
position: relative;
height: 302px;
border: solid black;
padding: 5px;
display: block;
font-family: "Helvetica Neue";
stroke-width: 2px;
background: #fff;
overflow: scroll;
display: block;
}
.voteSelector text {
position: relative;
text-align: center;
display: block;
border-bottom: thin solid black;
padding: 10px 30px 10px 30px;
font-weight: bold;
font-family: 'Helvetica Neue';
}
.buttonDiv {
padding: 5px 5px 5px 5px;
font-family: "Helvetica Neue";
}
.voteLegend {
position: relative;
top: -3px;
height: 120px;
border: solid black;
padding: 5px;
padding-top: 10px;
display: block;
font-family: "Helvetica Neue";
stroke-width: 2px;
display: none;
}
.nytimesLogo {
position: relative;
top: -3px;
}
.passage {
width: 130px;
height: 40px;
}
.sidebar {
border: solid black;
padding: 5px;
font-family: 'Helvetica Neue';
}
.sidebar text{
position: relative;
text-align: center;
display: block;
border-bottom: thin solid black;
padding: 10px 30px 10px 30px;
font-weight: bold;
font-family: 'Helvetica Neue';
}
.whichState {
font-weight: bold;
}
.whichDistrict {
font-weight: bold;
}
.typeToggle {
font-family: 'Helvetica Neue';
padding: 3px;
font-size: 14px;
font-style: normal;
font-variant: normal;
font-weight: 400;
line-height: 20px;
}
.information {
position: relative;
top: -3px;
border: solid black;
padding: 5px;
font-family: 'Helvetica Neue';
display: block;
}
.toggleSideBar {
position: relative;
top: -3px;
border: solid black;
padding: 5px;
font-family: 'Helvetica Neue';
display: block;
}
.hexagon {
fill: none;
pointer-events: all;
stroke: 0px;
z-index: 1;
}
.specificBorder {
fill: none;
stroke-width: 2.5px;
stroke-opacity: 1;
stroke: #fff;
pointer-events: none;
}
.districtBorder {
fill: none;
stroke: #000;
stroke-width: 1px;
stroke-opacity: .2;
pointer-events: none;
}
.stateBorder {
fill: none;
stroke: #000;
stroke-width: 2px;
pointer-events: none;
}
.bernieBorder {
fill: none;
stroke: #7fff00;
stroke-width: 2.5px;
stroke-opacity: 0;
pointer-events: none;
}
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment