D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
jadiehm
Full window
Github gist
Scatter plot with detailed labels
<!doctype html> <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