xxxxxxxxxx
<html lang='en-GB'>
<head></head>
<style>
body {
font-family: sans-serif;
font-size: 16px;
line-height: 1.4;
display: block;
margin: 0;
padding: 0;
color: #333;
-webkit-font-smoothing: antialiased;
}
p {
font-family: sans-serif;
font-size: 14px;
line-height: 22px;
margin-top: 5px;
}
/*template styles*/
.gia-chart-wrapper {
max-width: 620px;
margin: 0 auto;
}
/*chart styles*/
.axis line {
shape-rendering: crispEdges;
stroke: #dcdcdc;
stroke-dasharray: 1, 1;
}
.axis text {
font-family: sans-serif;
font-size: 12px;
pointer-events: none;
fill: #bdbdbd;
}
.domain {
display: none;
}
.g-baseline line {
stroke: #767676;
stroke-dasharray: 0;
stroke-width: 1px;
}
.Adamslabel, .Hayeslabel {
font-family: sans-serif;
font-size: 13px;
text-align: left;
font-weight: 700;
text-anchor: start;
}
.Trumplabel, .Harrisonlabel, .Bushlabel {
font-family: sans-serif;
font-size: 13px;
font-weight: 700;
text-align: right;
text-anchor: end;
}
.Wilsonlabel, .Clintonlabel, .Lincolnlabel, .Reaganlabel {
font-family: sans-serif;
font-size: 13px;
text-align: right;
text-anchor: end;
fill: #767676;
}
.FDRlabel {
font-family: sans-serif;
font-size: 13px;
text-align: left;
text-anchor: start;
fill: #767676;
}
.popvotelabel, .elecvotelabel {
font-family: sans-serif;
font-size: 13px;
text-align: center;
text-anchor: middle;
fill: #767676;
}
.failed-text, .disparity-text, .equality-text {
font-weight: 700;
}
.failed-text::before {
display: inline-block;
width:11px;
height:11px;
border-radius: 50%;
content: '';
background-color: #4bc6df;
margin: 0 4px;
}
.disparity-text::before {
display: inline-block;
width:11px;
height:11px;
border-radius: 50%;
content: '';
background-color: #dcdcdc;
margin: 0 4px;
}
.equality-text::before {
display: inline-block;
width:15px;
height:11px;
content: '';
border-top: 2px solid #ffbb00;
position: relative;
top: 8px;
margin: 0 4px;
}
@media(max-width: 500px) {
.Wilsonlabel, .Clintonlabel, .Lincolnlabel, .Reaganlabel, .FDRlabel {
display: none;
}
}
</style>
<body>
<main>
<div class='gia-chart-wrapper'>
<p>This graph shows the<span class='disparity-text'>disparity</span> between electoral college results in presidential elections as compared to popular vote. In five<span class='failed-text'>“failed”</span> elections, the winning candidate actually gained fewer votes than their opponent. In many others the winner got less than 50% of the votes but won by plurality. Almost all cases are above the <span class='equality-text'>line of equality</span> where the electoral college exaggerated the margin in favour of the victor.</p>
<div class='gia-chart'>
</div>
</div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script>
//Margin conventions
var margin = {top: 10, right: 20, bottom: 50, left: 50};
var widther = d3.select(".gia-chart").node().clientWidth;
var width = widther - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
//Appends the svg to the chart-container div
var svg = d3.select(".gia-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 + ")");
//Creates the xScale
var xScale = d3.scale.linear()
.range([0,width]);
//Creates the yScale
var yScale = d3.scale.linear()
.range([height, 0])
//Defines the y axis styles
var yAxis = d3.svg.axis()
.scale(yScale)
.tickSize(-width)
.tickPadding(7)
.orient("left");
//Defines the y axis styles
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickPadding(7)
//.tickFormat(function(d) {return d + "%"; })
.tickSize(height);
//Loads the data
d3.csv("electoral_college.csv", ready);
function ready(err, data) {
//Formats data
data.forEach(function(d) {
d.popvote_percent = +d.popvote_percent;
d.elecvote_percent = +d.elecvote_percent;
})
data.sort(function(a, b) {
return d3.descending(+a.perNonWhite, +b.perNonWhite);
});
//Sets the domains
xScale.domain([20, 65]);
yScale.domain([0, 100]);
//Appends the y axis
var yAxisGroup = svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.selectAll("g");
//Appends the x axis
var xAxisGroup = svg.append("g")
.attr("class", "x axis")
.call(xAxis)
.selectAll("g")
.classed("g-baseline", function(d) { return d == 50 });
//Equality line
var equalLine = svg.append("line")
.attr("x1", width/1.1)
.attr("x2", width/4.2)
.attr("class", "added line")
.attr("y1", height/2.6)
.attr("y2", height/1.45)
.attr("stroke-width", 1)
.attr("stroke", "#ffbb00");
//Styles the circles
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d){return xScale(d.popvote_percent);})
.attr("cy", function(d){return yScale(d.elecvote_percent);})
.attr("r", 5)
.attr("stroke", "white")
.attr("stroke-width", 1)
.attr("opacity", function(d) {
if(d.type === "failure") {
return "1"
}
else {
return "0.6"
}
})
.attr("fill", function(d) {
if(d.type === "failure") {
return "#4bc6df";
}
else {
return "#dcdcdc";
}
});
//Sorts the circles
circles
.sort(function(a, b){return d3.ascending(+a.perNonWhite, +b.perDem);})
//Append pres labels
var Adamslabel = svg.append("text")
.text("Adams, 1824")
.attr("class", "Adamslabel")
.attr("x", width/5)
.attr("y", height/1.35);
var Trumplabel = svg.append("text")
.text("Trump, 2016")
.attr("class", "Trumplabel")
.attr("x", width/1.75)
.attr("y", height/2.1);
var Bushlabel = svg.append("text")
.text("Bush, 2000")
.attr("class", "Bushlabel")
.attr("x", width/1.65)
.attr("y", height/1.85);
var Hayeslabel = svg.append("text")
.text("Hayes, 1876")
.attr("class", "Hayeslabel")
.attr("x", width/1.578)
.attr("y", height/1.8);
var Harrisonlabel = svg.append("text")
.text("Harrison, 1888")
.attr("class", "Harrisonlabel")
.attr("x", width/1.6)
.attr("y", height/2.6);
var Wilsonlabel = svg.append("text")
.text("Wilson, 1912")
.attr("class", "Wilsonlabel")
.attr("x", width/2.125)
.attr("y", height/5.5);
var Clintonlabel = svg.append("text")
.text("Clinton, 1992")
.attr("class", "Clintonlabel")
.attr("x", width/1.98)
.attr("y", height/3.5);
var Lincolnlabel = svg.append("text")
.text("Lincoln, 1860")
.attr("class", "Lincolnlabel")
.attr("x", width/2.35)
.attr("y", height/2.35);
var Reaganlabel = svg.append("text")
.text("Reagan, 1984")
.attr("class", "Reaganlabel")
.attr("x", width/1.175)
.attr("y", height/20);
var FDRlabel = svg.append("text")
.text("F. Roosevelt, 1932")
.attr("class", "FDRlabel")
.attr("x", width/1.3)
.attr("y", height/7);
//Appends axes lables
var popvoteLabel = svg.append("text")
.text("Popular vote percentage")
.attr("class", "popvotelabel")
.attr("x", width/2)
.attr("y", height/1)
.attr("transform", "translate(0,40)");
var elecvoteLabel = svg.append("text")
.text("Electoral college percentage")
.attr("class", "elecvotelabel")
.attr("x", -40)
.attr("y", -38)
.attr("transform", "translate(0,100)rotate(270)");
//RESPONSIVENESS
d3.select(window).on("resize", resized);
function resized() {
//new margin
var newMargin = {top: 10, right: 20, bottom: 100, left: 40};
var newWidther = d3.select(".gia-chart").node().clientWidth;
var newWidth = newWidther - newMargin.left - newMargin.right;
//Change the width of the svg
d3.select("svg")
.attr("width", newWidth + newMargin.left + newMargin.right);
//Change the xScale
xScale
.range([0, newWidth]);
//Update the bars
circles
.attr("cx", function(d){return xScale(d.popvote_percent);})
//Updates xAxis
d3.selectAll(".x.axis")
.call(xAxis);
//Updates ticks
xAxis
.scale(xScale);
//Updates yAxis
d3.selectAll(".y.axis")
.call(yAxis);
yAxis
.tickSize(-newWidth);
equalLine
.attr("x1", newWidth/1.1)
.attr("x2", newWidth/4.2)
//Labels
Adamslabel
.attr("x", newWidth/5);
Trumplabel
.attr("x", newWidth/1.75);
Bushlabel
.attr("x", newWidth/1.65);
Hayeslabel
.attr("x", newWidth/1.6);
Harrisonlabel
.attr("x", newWidth/1.6);
Wilsonlabel
.attr("x", newWidth/2.125);
Clintonlabel
.attr("x", newWidth/1.98);
Lincolnlabel
.attr("x",newWidth/2.35);
FDRlabel
.attr("x", newWidth/1.3);
Reaganlabel
.attr("x", newWidth/1.175);
popvoteLabel
.attr("x", newWidth/2);
};
}
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js