Skip to content

Instantly share code, notes, and snippets.

@alecrajeev
Last active April 27, 2017 17:54
Show Gist options
  • Save alecrajeev/ec120ec7493c2cad0da1dcb8216d4b48 to your computer and use it in GitHub Desktop.
Save alecrajeev/ec120ec7493c2cad0da1dcb8216d4b48 to your computer and use it in GitHub Desktop.
House 2018 Election
// 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 eleven_domain = [-1.0,-0.3,-0.2,-0.1,-0.05,0.0,0.05,0.1,0.2,0.3,1.0];
var color1;
var stateColor = ["#A94588","#D76940","#D13F46","#23A5C5", "#F0A851", "#F0A851", "#726198", "#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(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 1: // black
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 2: // latinx
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: // native american
color.range(['rgb(255,245,235)','rgb(254,230,206)','rgb(253,208,162)','rgb(253,174,107)','rgb(253,141,60)','rgb(241,105,19)','rgb(217,72,1)','rgb(166,54,3)','rgb(127,39,4)']);
break;
case 5: // multiracial
color.range(['rgb(247,244,249)','rgb(231,225,239)','rgb(212,185,218)','rgb(201,148,199)','rgb(223,101,176)','rgb(231,41,138)','rgb(206,18,86)','rgb(152,0,67)','rgb(103,0,31)']);
break;
default: // election
color.range(['#ae000c','#fff','#010a79']);
//color.range(['#ae000c','#8185BC','#ffffff','#D78287','#010a79']);
//color.range(['#AE000C','#BA3035','#C56365','#D09697','#DBC8C8','#C8C8D5','#9697BD','#6465A5','#32358E', '#010a79']);
break;
}
}
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.Latinx; });
extentData[3] = d3.extent(demoData, function(d) {return d.Asian; });
extentData[4] = d3.extent(demoData, function(d) {return d.NativeAmerican; });
extentData[5] = d3.extent(demoData, function(d) {return d.Multiracial; });
}
function buildColorDomain(i, extent) {
var colorDomain = [];
if (i < 5) { // demographics
var j = 0;
for (k = extent[0]; k <= (extent[1]+.01); k += ((extent[1]+.01) - extent[0])/8.0) {
colorDomain[j++] = k;
}
} else {
if (i == 5) { // multiracial
// colorDomain = [.005, .01, .015, .02, .025, .03, .035, .04, .1, .25];
colorDomain = [.025, .05, .075, .1, .125, .15, .175, .2, .25];
}
else
if (i == 12) // Pres 2016 Change
colorDomain = [-35.0, 0.0, 35.0];
else
if (i == 17) // House Map selector
colorDomain = [-1.0, 0.0, 1.0];
else // All other elections
colorDomain = [-100.0, 0.0, 100.0];
}
return colorDomain;
}
function grabLegendColor(i) {
if (i < 6) {
return color;
}
else {
color1 = new colorFunction();
color1.domainValues = getCopyDomain(i);
color1.rangeValues = ['#ae000c','#fff','#010a79'];
return color1;
}
}
function colorFunction(domainValues, rangeValues) {
// this replicates the function color aka d3.scale.linear
// necessary to properly get the legend color to work
this.domainValues = domainValues;
this.rangeValues = rangeValues;
this.domain = function() {
return this.domainValues;
}
this.range = function() {
return this.rangeValues;
}
this.value = function(v) {
return color(v);
}
}
function getCopyDomain(i) {
if (i == 12) // 12 to 16 Change
return [-35.0, -25.0, -10.0, -5.0, 0.0, 5.0, 10.0, 25.0, 35.0];
else // all other elections
return [-100.0, -50.0, -25.0, -10.0, 0.0, 10.0, 25.0, 50.0, 100.0];
}
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 (i == 17) {
}
if (districtID != -1)
return color(dataByDistrictID[districtID][i]);
}
function getStateColor(stateID) {
if (stateID != -1)
return stateColor[stateID];
}
function updateVoteHexagonColor() {
hexagons
.transition()
.delay(500)
.style({fill: function(d) {return getVoteDistrictColor(d.properties.districtID); },
stroke: function(d) {return getVoteDistrictColor(d.properties.districtID); }});
}
function updateHexagonColorFast(i) { // fills in the hexagons with the correct color according to the scale quickly
hexagons
.transition()
.style({fill: function(d) {return getDistrictColor(d.properties.districtID,i); },
stroke: function(d) {return getDistrictColor(d.properties.districtID,i); }});
}
var width = 1250;
var height = 730;
var radius = 6.5;
var hexagons;
var demoData;
var presData;
var dataByDistrictID = {};
var extentData = {};
var specificDistrictID = -2;
var toolTipSelector = 0;
var houseSelector = true;
var legendRectSize = 15;
var legendSpacing = 7;
var dataSets = ["White", "Black", "Latinx", "Asian", "NativeAmerican", "Multiracial", "Clinton 2016", "Trump 2016", "Obama 2012", "Romney 2012", "2016 Presidential Election", "2012 Presidential Election", "2012 to 2016 Change", "House Dem", "Hosue GOP", "2016 House Races", "2016 Pres vs House Margins"];
var dataSetSelector = 17; // used to figure out which data set is being shown
var legendRectSize = 15,
legendSpacing = 7;
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");
queue()
.defer(d3.json, "https://raw.githubusercontent.com/alecrajeev/UnitedStatesHex/Democratic-Primary/ushex.json")
.defer(d3.csv, "https://raw.githubusercontent.com/alecrajeev/UnitedStatesHex/2016-Presidential-Election/Demographics.csv")
.defer(d3.csv, "https://raw.githubusercontent.com/alecrajeev/UnitedStatesHex/2016-Presidential-Election/ElectionResults.csv")
.await(makeMyMap);
function makeMyMap(error, ushex, demographicData, electionData) {
if (error)
return console.warn(error);
demographicData.forEach(function (d) {
d.districtID = +d.districtID;
d.White = +d.White;
d.Black = +d.Black;
d.Latinx = +d.Latinx;
d.Asian = +d.Asian;
d.NativeAmerican = +d.NativeAmerican;
d.Multiracial = +d.Multiracial;
dataByDistrictID[d.districtID] = [d.White, d.Black, d.Latinx, d.Asian, d.NativeAmerican, d.Multiracial];
});
demoData = demographicData;
electionData.forEach(function (d) {
dataByDistrictID[d.districtID].push(+d.Clinton2016, +d.Trump2016, +d.Obama2012, +d.Romney2012, +d.Margin2016, +d.Margin2012, +d.MarginChange, +d.HouseDem, +d.HouseRep, +d.HouseMargin, +d.HousePresMargin);
// this if/else statement below will be used to select House districts
if (dataByDistrictID[d.districtID][15] > 0) // if Dem district
dataByDistrictID[d.districtID].push(1);
else
dataByDistrictID[d.districtID].push(-1);
if (checkCompetitive(d.districtID)) // checks if a ditrict is competitive
dataByDistrictID[d.districtID][17] = 0;
});
presData = electionData;
buildExtentData();
if (dataSetSelector == 17) {
buildColorRange(dataSetSelector);
color.domain(buildColorDomain(dataSetSelector, [-1.0, 1.0]));
}
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 getDistrictColor(d.properties.districtID, dataSetSelector); },
stroke: function(d) {return getDistrictColor(d.properties.districtID, dataSetSelector); }})
.on("mouseover", hoverOnDistrict)
.on("mousedown", selectDistrict);
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);
function hoverOnDistrict(d) {
coordinates = d3.mouse(this);
showTooltip(d, coordinates);
specificDistrictID = d.properties.districtID;
specificDistrict.call(drawSpecificDistrict);
changeInfo(d);
}
function selectDistrict(d) {
if (houseSelector && d.properties.state != "Ocean") { // you are using the function that chooses House seats
houseSeatFlip(d.properties.districtID);
updateHexagonColorFast(17);
d3.select(".houseBar").text("Dem: " + getDemSeats() + " \tRep: " + getRepSeats() + "\t Tossup: " + getTossupSeats());
}
}
function showTooltip(d, coordinates) {
if (d.properties.state != "Ocean"){
d3.select(".g-tooltip")
.style({display: "block",
top: function (e) {return (coordinates[1] + 75).toString() + "px"; },
left: function(e) {return (coordinates[0] + 175).toString() + "px"; }
});
d3.select(".tooltip-district").text(d.properties.state + "-" + d.properties.district);
if (dataSetSelector != -1) {
if (dataSetSelector < 6) {
d3.select(".tooltip-data-a").text("");
d3.select(".tooltip-data-b").text("");
d3.select(".tooltip-data").text(dataSets[dataSetSelector] + ": " + getShortened(dataByDistrictID[d.properties.districtID][dataSetSelector]));
}
else {
switch(dataSetSelector) {
case 10: // 2016 election
d3.select(".tooltip-data").text("");
d3.select(".tooltip-data-a").text("Clinton: " + getShortened(dataByDistrictID[d.properties.districtID][6]));
d3.select(".tooltip-data-b").text("Trump: " + " " + getShortened(dataByDistrictID[d.properties.districtID][7]));
break;
case 11: // 2012 election
d3.select(".tooltip-data").text("");
d3.select(".tooltip-data-a").text("Obama: " + " " + getShortened(dataByDistrictID[d.properties.districtID][8]));
d3.select(".tooltip-data-b").text("Romney: " + getShortened(dataByDistrictID[d.properties.districtID][9]));
break;
case 12: // 2012 -> 2016 change
d3.select(".tooltip-data").text("");
d3.select(".tooltip-data-a").text("2016: " + getShortened(dataByDistrictID[d.properties.districtID][10]));
d3.select(".tooltip-data-b").text("2012: " + getShortened(dataByDistrictID[d.properties.districtID][11]));
break;
case 15: // 2016 House
d3.select(".tooltip-data").text("");
d3.select(".tooltip-data-a").text("Dem: " + getShortened(dataByDistrictID[d.properties.districtID][13]));
d3.select(".tooltip-data-b").text("Rep: " + getShortened(dataByDistrictID[d.properties.districtID][14]));
break;
}
}
}
}
else {
d3.select(".g-tooltip").style("display", "none");
}
function getShortened(v) {
if (dataSetSelector < 6)
return d3.round(100.0*v,1).toString() + "%";
if (dataSetSelector == 12)
if (v < 0) // republican
return d3.round(-1.0*v,1).toString() + "% (R)";
else
return d3.round(v,1).toString() + "% (D)";
return d3.round(v,1).toString() + "%";
}
}
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 checkSpecificDistrict(hex1, hex2) {
if (specificDistrictID < 0) // if there is no specific district to be highlighted
return false;
if (hex1.properties.districtID != specificDistrictID &&
hex2.properties.districtID != specificDistrictID)
// if when traversing the hexmesh you are not near the specific district
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(); }
};
}
};
}
if (dataSetSelector == 17) {
showHouseSeatSelector();
}
}
function showRollCallVote() {
buildVoteColor();
updateVoteHexagonColor();
showVoteLegend();
d3.select(".voteLegend").style("display", "block");
d3.select(".legend").style("display", "none");
// d3.select(".districtBorder").style("stroke-opacity", ".5");
}
function showLegend(i) {
var demo = (i < 6 ? true : false);
d3.select(".legTitle").text(dataSets[i] + (demo ? " Demo" : ""));
var LegendColor = grabLegendColor(i);
var LegendContent = svgLegend.selectAll(".LegendContent")
.data(LegendColor.domain())
var LegendEnter = LegendContent.enter()
.append("g")
.attr("class", "LegendContent")
.attr("transform", function(d,j) {
var rectHeight = j*(legendRectSize + legendSpacing);
var rectWidth = legendRectSize;
return "translate(" + rectWidth + ", " + rectHeight + ")";
})
LegendEnter.append("rect")
.attr("width", legendRectSize-2)
.attr("height", legendRectSize)
.style("fill", function(d) {
if (demo)
return color(d)
else
return LegendColor.value(d);
})
.style("stroke", "black")
LegendEnter.append("text")
.attr("x", legendRectSize + legendSpacing*1.3)
.attr("y", legendRectSize-1)
.text(function(d) {
if (demo)
return d3.round(d*100,1).toString() + "%";
return (d < 1 ? (-1.0*d).toString() + "% (R)" : d.toString() + "% (D)");
});
var updateSelection = svgLegend.selectAll(".LegendContent")
.transition()
.duration(1000)
.style("opacity", "1")
.attr("transform", function(d,j) {
var rectHeight = j*(legendRectSize + legendSpacing);
var rectWidth = legendRectSize;
return "translate(" + rectWidth + ", " + rectHeight + ")";
})
updateSelection.select("rect")
.style("fill", function(d) {
if (demo)
return color(d)
else
return LegendColor.value(d);
});
updateSelection.select("text")
.text(function(d) {
if (demo)
return d3.round(d*100,1).toString() + "%";
return (d < 1 ? (-1.0*d).toString() + "% (R)" : d.toString() + "% (D)");
});
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 < 6; 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) + "%");
if (i == dataSetSelector)
d3.select("." + dataSets[i] + ".Info").style("font-weight", "bold");
}
else {// data set names that are two words
d3.select("." + classNameSplit[0] + "." + classNameSplit[1] + ".Info").text("Native American" + ": " + d3.round(dataByDistrictID[d.properties.districtID][i]*100, 1) + "%");
}
}
d3.select("." + "Pres2016" + ".Info").text("2016 Margin: " + getMarginString(dataByDistrictID[d.properties.districtID][10],0));
d3.select("." + "Pres2012" + ".Info").text("2012 Margin: " + getMarginString(dataByDistrictID[d.properties.districtID][11],1));
d3.select("." + "PresChange" + ".Info").text("'12 to '16 Change: " + getMarginString(dataByDistrictID[d.properties.districtID][12],2));
d3.select("." + "HouseMargin" + ".Info").text("House Margin: " + getMarginString(d3.round(dataByDistrictID[d.properties.districtID][15],1),3));
if (dataSetSelector > 6) {
switch(dataSetSelector) {
case 10:
d3.select("." + "Pres2016" + ".Info").style("font-weight", "bold");
break;
case 11:
d3.select("." + "Pres2012" + ".Info").style("font-weight", "bold");
break;
case 12:
d3.select("." + "PresChange" + ".Info").style("font-weight", "bold");
break;
case 15:
d3.select("." + "HouseMargin" + ".Info").style("font-weight", "bold");
break;
}
}
}
else { // if you are NOT on a district
d3.select(".whichState").text("");
d3.select(".whichDistrict").text("");
for (i = 0; i < 6; 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.select("." + dataSets[i] + ".Info").style("font-weight", "normal");
}
else// data set names that are two words
d3.select("." + classNameSplit[0] + "." + classNameSplit[1] + ".Info").text("Native American" + ": ");
}
d3.select("." + "Pres2016" + ".Info").text("2016 Margin: ");
d3.select("." + "Pres2012" + ".Info").text("2012 Margin: ");
d3.select("." + "PresChange" + ".Info").text("'12 to '16 Change: ");
d3.select("." + "HouseMargin" + ".Info").text("House Margin: ");
d3.select("." + "Pres2016" + ".Info").style("font-weight", "normal");
d3.select("." + "Pres2012" + ".Info").style("font-weight", "normal");
d3.select("." + "PresChange" + ".Info").style("font-weight", "normal");
d3.select("." + "HouseMargin" + ".Info").style("font-weight", "normal");
}
}
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;
}
function getMarginString(m, p) {
// gets the string displayed in the informational box to the left
switch(p) {
case 0:
if (m < 0)
return Math.abs(m).toString() + "% Trump";
else
return m.toString() + "% Clinton";
break;
case 1:
if (m < 0)
return Math.abs(m).toString() + "% Romney";
else
return m.toString() + "% Obama";
default:
if (m < 0)
return Math.abs(m).toString() + "% (R)";
else
return m.toString() + "% (D)";
}
}
function showStates() {
dataSetSelector = -1;
houseSelector = false;
shrinkTooltip(true)
d3.select(".header").text("States");
hexagons
.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(".houseBar").style("display", "none");
toolTipSelector = 0;
}
function showDataSet(i) {
dataSetSelector = i;
houseSelector = false;
shrinkTooltip(false);
if (i < 6)
if (i != 4)
d3.select(".header").text(dataSets[i] + " Demographics by Congressional District");
else
d3.select(".header").text("Native American" + " Demographics by Congressional District");
else
d3.select(".header").text(dataSets[i] + " by Congressional District");
buildColorRange(i);
color.domain(buildColorDomain(i,extentData[i]));
updateHexagonColor(i);
showLegend(i);
d3.select(".legend").style("display", "block");
d3.select(".houseBar").style("display", "none");
}
function showHouseSeatSelector() {
dataSetSelector = 17;
houseSelector = true;
shrinkTooltip(true);
d3.select(".header").text("House 2018 Election Map");
d3.select(".houseBar").style("display", "block");
buildColorRange(dataSetSelector);
color.domain(buildColorDomain(dataSetSelector, [-1.0, 1.0]));
updateHexagonColor(17);
d3.select(".legend").style("display", "none");
d3.select(".houseBar").text("Dem: " + getDemSeats() + " \tRep: " + getRepSeats() + "\t Tossup: " + getTossupSeats());
}
function shrinkTooltip(b) {
if (b) { // Tooltip is tiny
d3.select(".tooltip-data").text("");
d3.select(".tooltip-data-a").text("");
d3.select(".tooltip-data-b").text("");
d3.select(".g-tooltip").style({height: "25px"});
}
else {
d3.select(".g-tooltip").style({height: "50px"})
}
}
function showPrimaryDistrictVote() {
d3.select(".header").text("Democratic Primary Vote by Congressional District");
hexagons
.style({fill: function(d) {return getPrimaryVote(d.properties.districtID); },
stroke: function(d) {return getPrimaryVote(d.properties.districtID); }});
d3.select(".legend").style("display", "none");
toolTipSelector = 4;
d3.select(".legend").style("display", "");
showLegend(0)
}
function grabDistrictInfo(districtID, i) {
if (primaryByDistrictID[districtID][9])
return "";
return primaryByDistrictID[districtID][i];
}
function grabStateInfo(stateID, districtID, i) {
if (primaryByDistrictID[districtID][9])
return "";
if (i >= 4)
return d3.round(primaryByStateID[stateID][i]*100.0, 2) + "%";
if (i < 4)
return primaryByStateID[stateID][i];
}
function getRealDistrict(i, state) { // returns "at large" if the district number is 0, like Montana
if (i > 0)
return i;
return "At-Large";
}
function houseSeatFlip(districtID) {
switch (dataByDistrictID[districtID][17]) {
case 1: // Dem district
dataByDistrictID[districtID][17] = 0;
break;
case 0: // tossup district
dataByDistrictID[districtID][17] = -1;
break;
case -1: // Gop district
dataByDistrictID[districtID][17] = 1;
break;
}
}
function getDemSeats() {
var demSeats = 0;
for (var i = 0; i < 435; i++)
if (dataByDistrictID[i][17] == 1)
demSeats += 1;
return demSeats;
}
function getRepSeats() {
var repSeats = 0;
for (var i = 0; i < 435; i++)
if (dataByDistrictID[i][17] == -1)
repSeats += 1;
return repSeats;
}
function getTossupSeats() {
var tossupSeats = 0;
for (var i = 0; i < 435; i++)
if (dataByDistrictID[i][17] == 0)
tossupSeats +=1;
return tossupSeats;
}
function checkCompetitive(districtID) {
var competitive = false;
if (districtID == 68)
competitive = true;
if (districtID == 69)
competitive = true;
if (districtID == 119)
competitive = true;
if (districtID == 240)
competitive = true;
if (districtID == 383)
competitive = true;
return competitive;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="favicon.ico" />
<link rel="stylesheet", type="text/css", href="style.css">
<title>2016 Presidential Election</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>
</head>
<body>
<div class="top">
<div class="pageTitle">
<h3 class="header">House 2018 Election Map</h3>
</div>
<div class="houseBar">
<!-- <svg height="100" width="100"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /></svg> -->
</div>
</div>
<div class="left">
<div class="sidebar">
<text>Data Set</text>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showStates()">States
</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)">Latinx 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)">Native American Demo
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(5)">Multiracial Demo
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(10)">2016 Presidential
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(11)">2012 Presidential
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(12)">2016 Change
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" onclick="showDataSet(15)">House Margin
</div>
<div class="typeToggle">
<input type="radio" name="data-selector" checked onclick="showHouseSeatSelector()">House 2018 Selector
</div>
</div>
<div class="information">
<div>State: <span class="whichState"></span></div>
<div>District: <span class="whichDistrict"></span></div>
<div class="White Info">White: </div>
<div class="Black Info">Black: </div>
<div class="Latinx Info">Latinx: </div>
<div class="Asian Info">Asian: </div>
<div class="NativeAmerican Info">NativeAmerican: </div>
<div class="Multiracial Info">Multiracial: </div>
<div class="Pres2016 Info">2016 Margin: </div>
<div class="Pres2012 Info">2012 Margin: </div>
<div class="PresChange Info">'12 to '16 Change: </div>
<div class="HouseMargin Info">House Margin: </div>
</div>
<div class="legend">
<div class="legTitle">Margin of Victory</div>
<div class="legendChart"></div>
</div>
</div>
<div class="main">
<div class="map"></div>
<div class="sampleImage"> <img src="http://i.imgur.com/ATb2T5P.jpg" /></div>
</div>
<div class="g-tooltip">
<div class="tooltip-district"></div>
<div class="tooltip-data"></div>
<div class="tooltip-data-a"></div>
<div class="tooltip-data-b"></div>
</div>
</body>
<script type="text/javascript" src="hexscript.js"></script>
<script type="text/javascript" src="colorBuilder.js"></script>
</html>
.top {
position: absolute;
left:0px; right: 0px;
height: 92px;
margin-left: 15px;
font-family: 'Helvetica Neue';
font-weight: bold;
}
.left {
position: absolute;
left:0; top:80px; bottom: 0;
width: 250px;
margin-left: 15px;
}
.main {
position: relative;
left:252px; top:92px; right:0; bottom:0;
}
.right {
position: relative;
background: #fff;
top: -656px;
left: 1200px;
width: 178px;
}
.map {
position: relative;
top: -60px;
}
.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;
}
.houseBar {
position: relative;
left: 300px;
top: -50px;
height: 70px;
width: 300px;
margin-left: 15px;
display: block;
}
.buttonDiv {
padding: 5px 5px 5px 5px;
font-family: "Helvetica Neue";
}
.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;
line-height: 1.3;
}
.legTitle {
text-align: center;
font-weight: bold;
}
.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;
}
.g-tooltip {
position: absolute;
background-color: #fff;
padding: 5px 8px 5px 6px;
font-family: "Helvetica Neue";
top: 800px;
width: 100px;
height: 25px;
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;
}
.tooltip-data-a {
font-size: 80%;
text-align: left;
}
.tooltip-data-b {
font-size: 80%;
text-align: left;
}
.sampleImage {
display: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment