My submission for a d3.unconf 2016 ticket... Data from somewhere? Something about Trump and Hillary shouting at each other. Shoulda/coulda/woulda put noises of them doing that. Oh well.
Last active
September 16, 2016 06:40
-
-
Save jcnesci/abdda0bcf5206b3be3e6853e677eb0a8 to your computer and use it in GitHub Desktop.
Upcoming shouting match at d3.unconf
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
license: gpl-3.0 | |
height: 600 |
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
State | Clinton | Trump | Unsure | Margin of Error | Electoral College Votes | |
---|---|---|---|---|---|---|
AK | 31.5% | 52.5% | 16% | 4.3% | 3 | |
AL | 33.3% | 52.3% | 14.4% | 2.3% | 9 | |
AR | 36.6% | 46.7% | 16.7% | 2.6% | 6 | |
AZ | 37.9% | 45.8% | 16.3% | 2.1% | 11 | |
CA | 52.1% | 32.3% | 15.7% | 1.3% | 55 | |
CO | 45.3% | 37% | 17.7% | 2.2% | 9 | |
CT | 44.6% | 39.6% | 15.8% | 3% | 7 | |
DC | 65.7% | 20.2% | 14.1% | 2.7% | 3 | |
DE | 44.5% | 39.4% | 16.1% | 2.9% | 3 | |
FL | 42.6% | 42.1% | 15.4% | 1.4% | 29 | |
GA | 42.8% | 41.8% | 15.5% | 1.7% | 16 | |
HI | 49.6% | 30.5% | 19.9% | 3.1% | 4 | |
IA | 40.1% | 40.1% | 19.9% | 2.3% | 6 | |
ID | 33.8% | 44.8% | 21.4% | 2.9% | 4 | |
IL | 48.2% | 35.2% | 16.7% | 1.8% | 20 | |
IN | 36.7% | 45% | 18.3% | 2.1% | 11 | |
KS | 35% | 45.6% | 19.4% | 2.5% | 6 | |
KY | 34.7% | 49.1% | 16.3% | 2.1% | 8 | |
LA | 32.9% | 50.7% | 16.4% | 2.5% | 8 | |
MA | 49.8% | 33.3% | 16.9% | 2.2% | 11 | |
MD | 51.1% | 32.8% | 16.1% | 2.5% | 10 | |
ME | 38.8% | 40.8% | 20.4% | 3.4% | 4 | |
MI | 41.9% | 39.3% | 18.8% | 2.1% | 16 | |
MN | 45% | 35.2% | 19.8% | 2.6% | 10 | |
MO | 36.6% | 45.2% | 18.2% | 2.3% | 10 | |
MS | 33.2% | 51.1% | 15.8% | 2.5% | 6 | |
MT | 35.8% | 45.3% | 18.9% | 2.6% | 3 | |
NC | 40.2% | 43.2% | 16.6% | 1.8% | 15 | |
ND | 35.6% | 44.2% | 20.2% | 2.5% | 3 | |
NE | 35.3% | 47.7% | 17% | 2.7% | 5 | |
NH | 41.3% | 40.5% | 18.2% | 3% | 4 | |
NJ | 46.3% | 36.6% | 17.1% | 2% | 14 | |
NM | 42.7% | 39.8% | 17.4% | 3.2% | 5 | |
NV | 43.5% | 39.6% | 16.9% | 2.7% | 6 | |
NY | 50.9% | 33.7% | 15.4% | 1.3% | 29 | |
OH | 40.9% | 41.7% | 17.4% | 1.6% | 18 | |
OK | 33.9% | 47.9% | 18.2% | 3% | 7 | |
OR | 45.1% | 36.3% | 18.7% | 2.2% | 7 | |
PA | 42.5% | 42.1% | 15.3% | 1.5% | 20 | |
RI | 47.3% | 35.7% | 17% | 3% | 4 | |
SC | 36.6% | 46.2% | 17.1% | 2.4% | 9 | |
SD | 32.4% | 46.7% | 20.9% | 3.4% | 3 | |
TN | 33.4% | 49% | 17.6% | 1.9% | 11 | |
TX | 38.2% | 43.5% | 18.3% | 1.3% | 38 | |
UT | 33.3% | 44.8% | 21.9% | 3.5% | 6 | |
VA | 43.6% | 38.9% | 17.5% | 1.9% | 13 | |
VT | 48.5% | 32.1% | 19.4% | 3.8% | 3 | |
WA | 47.6% | 33.8% | 18.5% | 2.1% | 12 | |
WI | 41.4% | 39.4% | 19.1% | 2.3% | 10 | |
WV | 27.9% | 55.7% | 16.4% | 2.6% | 5 | |
WY | 24.5% | 58.5% | 16.9% | 3.4% | 3 |
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"> | |
<style> | |
.bubble { | |
stroke-width: 10px; | |
} | |
.bar { | |
fill: silver; | |
} | |
.bar:hover { | |
fill: rgb(90,90,90); | |
} | |
.axis { | |
font: 10px sans-serif; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.x.axis path { | |
display: none; | |
} | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script> | |
var margin = {top: 20, right: 20, bottom: 30, left: 40}, | |
width = 960 - margin.left - margin.right, | |
height = 600 - margin.top - margin.bottom, | |
heightBubble = height * 0.6, | |
heightBarchart = height * 0.4; | |
var svgParent = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom); | |
var svgBubble = svgParent.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var svgBarchart = svgParent.append("g") | |
.attr("transform", "translate(" + margin.left + "," + (margin.top + heightBubble) + ")"); | |
var fontSize = 92; | |
// | |
svgBubble.append("text") | |
.attr("id", "votes-clinton") | |
.attr("x", 0) | |
.attr("y", heightBubble/2) | |
.style("fill", "blue") | |
.style("font-size", fontSize +"px") | |
.style("font-weight", "bold") | |
.style("font-family", "sans-serif") | |
.text("Clinton"); | |
svgBubble.append("text") | |
.attr("id", "votes-trump") | |
.attr("x", width) | |
.attr("y", heightBubble/2) | |
.style("fill", "red") | |
.style("font-size", fontSize +"px") | |
.style("font-weight", "bold") | |
.style("font-family", "sans-serif") | |
.style("text-anchor", "end") | |
.text("Trump"); | |
var nodes = [ | |
{ | |
candidate: 'clinton', | |
radius: 40, | |
img1: 'clinton-1.jpg', | |
img2: 'clinton-2.jpg', | |
color: "blue" | |
}, | |
{ | |
candidate: 'trump', | |
radius: 40, | |
img1: 'trump-1.jpg', | |
img2: 'trump-2.jpg', | |
color: "red" | |
}]; | |
var defs = svgBubble.append("svg:defs"); | |
var images = []; | |
nodes.forEach(function(d){ | |
images.push( {candidate: d.candidate, img: d.img1, type: 'not-yelling'} ); | |
images.push( {candidate: d.candidate, img: d.img2, type: 'yelling'} ); | |
}); | |
defs.selectAll("pattern") | |
.data(images) | |
.enter().append("pattern") | |
.attr("id", function(d){ return "img-"+ d.candidate +"-"+ d.type; }) | |
.attr("width", 1) | |
.attr("height", 1) | |
.attr("viewBox", "0 0 100 100") | |
.attr("preserveAspectRatio", "none") | |
.append("image") | |
.attr("width", 100) | |
.attr("height", 100) | |
.attr("xlink:href", function(d){ return d.img; }) | |
.attr("preserveAspectRatio", "none"); | |
var force = d3.layout.force() | |
.gravity(5) | |
.charge(10) | |
.linkDistance(-2000) | |
.nodes(nodes) | |
.size([width, heightBubble]) | |
.start(); | |
var bubbles = svgBubble.selectAll("circle") | |
.data(nodes) | |
.enter().append("circle") | |
.attr("id", function(d){ return d.candidate; }) | |
.attr("class", "bubble") | |
.attr("r", function(d) { return d.radius; }) | |
.style("stroke", function(d){ return d.color; }) | |
.style("fill", function(d){ return "url(#img-"+ d.candidate +"-not-yelling)"; }); | |
force.on("tick", function(e) { | |
var q = d3.geom.quadtree(nodes), | |
i = 0, | |
n = nodes.length; | |
while (++i < n) q.visit(collide(nodes[i])); | |
svgBubble.selectAll("circle") | |
.attr("cx", function(d) { return d.x; }) | |
.attr("cy", function(d) { return d.y; }); | |
}); | |
function collide(node) { | |
var r = node.radius + 16, | |
nx1 = node.x - r, | |
nx2 = node.x + r, | |
ny1 = node.y - r, | |
ny2 = node.y + r; | |
return function(quad, x1, y1, x2, y2) { | |
if (quad.point && (quad.point !== node)) { | |
var x = node.x - quad.point.x, | |
y = node.y - quad.point.y, | |
l = Math.sqrt(x * x + y * y), | |
r = node.radius + quad.point.radius; | |
if (l < r) { | |
l = (l - r) / l * .5; | |
node.x -= x *= l; | |
node.y -= y *= l; | |
quad.point.x += x; | |
quad.point.y += y; | |
} | |
} | |
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; | |
}; | |
} | |
// | |
d3.tsv('elections.tsv', function(error, data) { | |
if (error) throw error; | |
data.forEach(function(d){ | |
d['Electoral College Votes'] = +d['Electoral College Votes']; | |
d.Clinton = +(d.Clinton.replace('%','')); | |
d.Trump = +(d.Trump.replace('%','')); | |
d.Unsure = +(d.Unsure.replace('%','')); | |
d['Margin of Error'] = +(d['Margin of Error'].replace('%','')); | |
}); | |
var x = d3.scale.ordinal() | |
.rangeRoundBands([0, width], .1); | |
var y = d3.scale.linear() | |
.range([heightBarchart, 0]); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom"); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left") | |
.tickValues(function(){ return y.domain(); }); | |
x.domain(data.map(function(d) { return d.State; })); | |
y.domain([0, d3.max(data, function(d) { return d['Electoral College Votes']; })]); | |
svgBarchart.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + heightBarchart + ")") | |
.call(xAxis); | |
svgBarchart.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("Electoral College Votes"); | |
d3.selectAll('.y.axis path').remove(); | |
svgBarchart.selectAll(".bar") | |
.data(data) | |
.enter().append("rect") | |
.attr("class", "bar") | |
.attr("x", function(d) { return x(d.State); }) | |
.attr("width", x.rangeBand()) | |
.attr("y", function(d) { return y(d['Electoral College Votes']); }) | |
.attr("height", function(d) { return heightBarchart - y(d['Electoral College Votes']); }) | |
.on('mouseover', function(d){ | |
nodes[0].radius = d.Clinton; | |
nodes[0].radius += (nodes[0].radius * nodes[0].radius)/30; | |
nodes[1].radius = d.Trump; | |
nodes[1].radius += (nodes[1].radius * nodes[1].radius)/30; | |
// | |
var bubbleInFront, bubbleInBack; | |
if (d.Clinton >= d.Trump) { | |
bubbleInFront = "trump"; | |
bubbleInBack = "clinton"; | |
} else { | |
bubbleInFront = "clinton"; | |
bubbleInBack = "trump"; | |
} | |
d3.select( ".bubble#"+bubbleInFront ).moveToFront(); | |
d3.select( ".bubble#"+bubbleInFront ).style("fill", function(d){ return "url(#img-"+ d.candidate +"-not-yelling)"; }); | |
d3.select( ".bubble#"+bubbleInBack ).style("fill", function(d){ return "url(#img-"+ d.candidate +"-yelling)"; }); | |
// | |
bubbles | |
.transition() | |
.duration(100) | |
// .attr("r", function(d) { return d.radius + (d.radius * d.radius)/30; }) | |
.attr("r", function(d) { return d.radius; }) | |
.attr("cx", function(d) { | |
return d.x + ((Math.random() - .5) * 50); | |
}) | |
.attr("cy", function(d) { | |
return d.y + ((Math.random() - .5) * 50); | |
}); | |
// | |
d3.select("#votes-clinton").text(d.Clinton +"%"); | |
d3.select("#votes-trump").text(d.Trump +"%"); | |
d3.select("#votes-"+bubbleInFront).style("font-size", fontSize/2 +"px"); | |
d3.select("#votes-"+bubbleInBack).style("font-size", fontSize +"px"); | |
}); | |
}); | |
d3.selection.prototype.moveToFront = function() { | |
return this.each(function(){ | |
this.parentNode.appendChild(this); | |
}); | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment