forked from cool-Blue's block: canvas-based-wind-with-d3
xxxxxxxxxx
<html lang="en">
<head>
<title>Obama’s Diverse Base of Support - Interactive Feature - NYTimes.com</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css"
href="https://graphics8.nytimes.com/css/0.1/screen/build/interactive/us/politics/styles.css?v=20121001">
<link rel="stylesheet" type="text/css" media="print" href="https://graphics8.nytimes.com/css/0.1/print/styles.css">
<style type="text/css">
body {
margin: 10px;
padding: 0;
width: 750px;
height: 540px;
}
.g-header, .g-gfx-hed, .g-block-hed {
text-align: center;
}
.g-header h4 {
font-size: 30px;
font-weight: normal;
line-height: 1.4em;
}
.g-header .g-summary {
color: #999;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
height: 30px;
line-height: 1.4em;
margin: 8px auto;
width: 420px;
}
.g-chart {
padding: 0px;
position: relative;
width: 750px;
height: 453px;
}
.g-chart canvas,
.g-chart svg {
position: absolute;
}
.g-state {
fill: #000;
stroke: #eee;
stroke-width: .5px;
stroke-opacity: 0.5;
}
.g-footer {
position: relative;
font-family: Arial, Helvetica, sans-serif;
font-size: 11px;
line-height: 28px;
color: #999;
margin: 0 10px;
}
.g-footer span {
padding-left: 13px;
margin-left: 4px;
}
.g-footer span.g-dem {
background: url(https://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/dem-swatch.png) no-repeat left center;
}
.g-footer span.g-rep {
background: url(https://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/rep-swatch.png) no-repeat left center;
}
.g-footer a {
display: block;
margin: 0 10px;
}
.g-footer .g-refer {
padding: 0 0 0 26px;
position: absolute;
right: 0px;
top: 0px;
background: url(https://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/zoom.svg) no-repeat left center;
}
.g-button {
background: #fff;
border-bottom-color: #ccc;
border-radius: 3px;
border: solid 1px #ddd;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
color: #888;
cursor: pointer;
font: inherit;
font-size: 11px;
line-height: 17px;
margin: 0 -1px 0 0;
padding: 4px 0;
text-align: center;
transition-duration: 0.2s;
transition-property: box-shadow, border-color;
-moz-transition-duration: 0.2s;
-moz-transition-property: box-shadow, border-color;
-ms-transition-duration: 0.2s;
-ms-transition-property: box-shadow, border-color;
-o-transition-duration: 0.2s;
-o-transition-property: box-shadow, border-color;
-webkit-transition-duration: 0.2s;
-webkit-transition-property: box-shadow, border-color;
}
.g-button:hover {
border-bottom-color: #bbb;
border-color: #ccc;
box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
color: #666;
}
.g-button.g-active,
.g-button:active {
background-color: #f0f0f0;
border-color: #ccc;
border-top-color: #bbb;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
color: #333;
}
.g-buttons .g-button {
border-radius: 0;
font-family: Arial, Helvetica, sans-serif;
font-size: 11px;
line-height: 1.3em;
margin: 4px -1px 4px 0;
padding: 7px 0;
position: relative;
width: 96px;
}
.g-button:first-child {
border-radius: 3px 0 0 3px;
}
.g-button:last-child {
border-radius: 0 3px 3px 0;
}
.g-buttons .g-button.g-active {
box-shadow: inset 0 1px 4px rgba(0, 0, 0, .15);
}
.g-buttons .g-button:focus {
z-index: 3;
}
.g-buttons .g-button.g-active {
z-index: 2;
}
</style>
</head>
<body id="interactiveABC" class="interactiveABC">
<div id="interactiveFreeFormMain">
<div id="g-gfx">
<div id="g-gfx-header" class="g-gfx-block">
<h2 class="g-gfx-hed">How Obama Won Re-election</h2>
</div>
<!--block -->
<div id="g-gfx-main" class="g-gfx-block">
<h3 class="g-block-hed g-block-middle">Romney’s Shift Wasn’t Enough</h3>
<div id="g-gfx-shift">
<div class="g-container">
<div class="g-header">
<div class="g-buttons"></div>
<div class="g-summary"></div>
</div>
<div class="g-chart"></div>
<div class="g-footer">
<div class="g-legend">
Became more:
<span class="g-dem">Democratic</span>
<span class="g-rep">Republican</span>
</div>
</div>
</div>
<!--<script src="https://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/d3.js"></script>-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.js"></script>
<!--<script src="d3 CB.js"></script>-->
<script>
var dispatch = d3.dispatch("data");
(function() {
var synchronousMode = false;
var width = 750, height = 500;
var steps = [{
summary : "In 2008, Barack Obama drew increased support from nearly every demographic category, and most of the nation shifted to the left.",
velocity: function(d) {
return d['08'] - d['04'];
},
color : function(d) {
return d['08'] - d['04'];
},
label : "2008",
click: function(){yearClick.apply(this, arguments)}
}, {
summary : "Most of the nation shifted to the right in Tuesday's vote,<br>but not far enough to secure a win for Mitt Romney.",
velocity: function(d) {
return d['12'] - d['08'];
},
color : function(d) {
return d['12'] - d['08'];
},
label : "2012",
click: function(){yearClick.apply(this, arguments)}
},{
mode: true,
label: "synchronous",
value: synchronousMode, //initial value
click: function(d) {
d3.select(this)
.classed("g-active", (synchronousMode = (d.value = (+d.value + 1) % 2)))
}
}], yearClick;
d3.select(self.frameElement).style("height", "620px");
var svg = d3.select(".g-chart").append("svg").attr("width", width).attr("height", height);
var canvas = d3.select(".g-chart").append("canvas").node(),
offscreenCanvas = d3.select(document.createElement("canvas")).node(),
context = canvas.getContext("2d"),
offscreenContext = offscreenCanvas.getContext("2d"),
ratio = (window.devicePixelRatio / context.webkitBackingStorePixelRatio) || 1;
d3.selectAll([canvas, offscreenCanvas])
.attr("width", width * ratio).attr("height", height * ratio)
.style("width", width + "px").style("height", height + "px");
context.scale(ratio, ratio);
offscreenContext.scale(ratio, ratio);
offscreenContext.globalAlpha = .9;
var color = d3.scale.threshold()
.domain([0])
.range(["#2280c3", "#da0b2e"].map(function(d) {
return d3.rgb(d);
}));
var projection = albersUsa().translate([width / 2 - 10, height / 2 - 40]).scale(920);
var path = d3.geo.path().projection(projection);
var duration = 750, paused = true, then, now;
var summary = d3.select(".g-summary"),
buttons = d3.select(".g-buttons");
var button = buttons.selectAll(".g-button").data(steps)
.enter().append("button")
.attr("class", "g-button")
.text(function(d) {return d.label;})
.classed("modeButton", function(d){return d.mode});
var modeButton = buttons.select(".modeButton");
dispatch.on("data", function(counties, collection) {
var stateById = {};
collection.features.forEach(function(d) {
stateById[d.id] = d;
});
counties.forEach(function(d) {
d.centroid = projection([d.x, d.y]);
d.state = stateById[Math.floor(d.id / 1e3)];
});
svg.append("path").datum(collection).attr("d", path).attr("class", "g-state");
d3.select(".g-container").on("mouseover", mouseover).on("mouseout", mouseout);
var particles = counties.map(particle), pauseTimeout = setTimeout(mouseout, 30e3);
yearClick = function(d){
button.classed("g-active", function(p) {
return d === p;
});
summary.html(d.summary);
particles.forEach(function(p) {
var c = color(d.color(p.d));
p.v = Math.max(-.25, Math.min(.25, d.velocity(p.d))) * 100;
p.r = c.r, p.g = c.g, p.b = c.b;
});
mouseover();
}
function click(d) {
return d.click.apply(this, arguments)
};
button.on("click", click);
var started = click(steps[1]);
function mouseover() {
clearTimeout(pauseTimeout);
if(paused) run();
}
function mouseout() {
// clearTimeout(pauseTimeout);
// pauseTimeout = setTimeout(pause, duration);
}
function pause() {
paused = true;
}
function run() {
paused = false;
then = Date.now();
now = then;
particles.forEach(function(p) {
p.t = now + (Math.random() - 1) * duration;
});
d3.timer(function(elapsed) {
var i = -1, n = particles.length;
var f = format(" >8.1f"), f3 = format(" >8.4f");
if(!synchronousMode) {
// clear the shadow context and copy the current context to it
offscreenContext.clearRect(0, 0, width, height);
offscreenContext.drawImage(canvas, 0, 0, width, height)
//clear the current context and try to jam the previous version
//back on top of the drawing activities
//lovely chaos ensues
context.clearRect(0, 0, width, height);
context.drawImage(offscreenCanvas, 0, 0, width, height);
}
else {
//allow the
context.clearRect(0, 0, width, height);
context.drawImage(offscreenCanvas, 0, 0, width, height);
offscreenContext.clearRect(0, 0, width, height);
}
now = elapsed + then;
//iterate the transition for each county
while(++i < n) {
var p = particles[i], t = (now - p.t) / duration;
if(t > 1) {
p.t += duration * Math.floor(t);
p.y = p.d.centroid[1] + (true ? (Math.random() - .5) * 2 : 0);
}
else if(t > 0) {
if(synchronousMode){
offscreenContext.fillStyle = "rgba(" + p.r + "," + p.g + "," + p.b + "," + mirror(1 - t) + ")";
offscreenContext.fillRect(p.x + (t - .5) * p.v * 2 - .75, p.y - .75, 2.5, 2.5);
} else {
context.fillStyle = "rgba(" + p.r + "," + p.g + "," + p.b + "," + mirror(1 - t) + ")";
context.fillRect(p.x + (t - .5) * p.v * 2 - .75, p.y - .75, 1.5, 1.5);
}
}
}
function format(_fmt) {
return function(x) {
return Array.isArray(x) ? x.map(f) : d3.format(_fmt)(x);
};
};
return paused;
}, 0, now);
}
});
function mirror(t) {
return t < .5 ? 2 * t : 2 - 2 * t;
}
function particle(d) {
return {
d: d, x: d.centroid[0], y: d.centroid[1], t: now
};
}
function albersUsa() {
var lower48 = d3.geo.albers(), alaska = d3.geo.albers().rotate([160, 0]).center([0, 60]).parallels([55, 65]), hawaii = d3.geo.albers().rotate([160, 0]).center([0, 20]).parallels([8, 18]);
function albersUsa(coordinates) {
return projection(coordinates)(coordinates);
}
function projection(point) {
var lon = point[0], lat = point[1];
return lat > 50 ? alaska : lon < -140 ? hawaii : lower48;
}
albersUsa.polygon = function(coordinates, context) {
return projection(coordinates[0][0]).polygon(coordinates, context);
};
albersUsa.scale = function(x) {
if(!arguments.length) return lower48.scale();
lower48.scale(x);
alaska.scale(x * .38);
hawaii.scale(x);
return albersUsa.translate(lower48.translate());
};
albersUsa.translate = function(x) {
if(!arguments.length) return lower48.translate();
var dz = lower48.scale(), dx = x[0], dy = x[1];
lower48.translate(x);
alaska.translate([dx - .30 * dz, dy + .17 * dz]);
hawaii.translate([dx - .16 * dz, dy + .20 * dz]);
return albersUsa;
};
return albersUsa.scale(lower48.scale());
}
})();
</script>
<!--<script src="https://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/data.js"></script>-->
<script src="data.js"></script>
<!--<![endif]-->
</div>
</div>
</div>
</div>
</body>
</html>
Modified http://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/d3.js to a secure url
Modified http://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/data.js to a secure url
https://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/d3.js
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.js
https://graphics8.nytimes.com/newsgraphics/2012/11/05/election-county-shift/1269d0aadb7a9c5e3e694033d24af804d28235aa/data.js