Skip to content

Instantly share code, notes, and snippets.

@MTClass
Created April 23, 2017 23:54
Show Gist options
  • Save MTClass/8b1ae5ecde517426d0cab1cf474387ce to your computer and use it in GitHub Desktop.
Save MTClass/8b1ae5ecde517426d0cab1cf474387ce to your computer and use it in GitHub Desktop.
Choropleth with Animated Stripes
license: mit

Block-a-Day #5. Experiment with using patterns and animation to show the margin of error on a choropleth. Stripes periodically pulse to the extremes of the margin of error to show uncertainty. This is one where the only way to see if it works is to build it; unfortunately, the idea worked better in my imagination.

Data Sources: 2014 ACS

What I Learned: I might have used an SVG mask before in a visualization project, but I had certainly never used the combination of pattern and mask. Drew heavily upon John Schulz's block demonstrating this technique. This is also my first time using Mike Bostock's pattern for chained transitions.

What I'd Do With More Time: Not sure. This isn't as effective as I'd hoped. Might be a dead end.

Block-a-Day

Just what it sounds like. For fifteen days, I will make a D3.js v4 block every single day. Rules:

  1. Ideas over implementation. Do something novel, don't sweat the details.
  2. No more than two hours can be spent on coding (give or take).
  3. Every. Single. Day.

Previously

forked from cmgiven's block: Choropleth with Animated Stripes

acs GEO.id GEO.id2 GEO.display-label HC01_EST_VC02 HC01_MOE_VC02 HC02_EST_VC02 HC02_MOE_VC02
one-year 0500000US24001 24001 Allegany County, Maryland 7148 811 19.2 6.3
one-year 0500000US24003 24003 Anne Arundel County, Maryland 62621 3121 6.3 1.8
one-year 0500000US24005 24005 Baltimore County, Maryland 97708 3700 10.4 1.9
one-year 0500000US24009 24009 Calvert County, Maryland 10552 1294 5.4 3.3
one-year 0500000US24011 24011 Caroline County, Maryland
one-year 0500000US24013 24013 Carroll County, Maryland 21737 1394 5.3 2.1
one-year 0500000US24015 24015 Cecil County, Maryland 10806 1168 9.4 4
one-year 0500000US24017 24017 Charles County, Maryland 22027 1579 7.7 2.9
one-year 0500000US24019 24019 Dorchester County, Maryland
one-year 0500000US24021 24021 Frederick County, Maryland 30524 1699 6.1 2.3
one-year 0500000US24023 24023 Garrett County, Maryland
one-year 0500000US24025 24025 Harford County, Maryland 29637 2010 10.2 2.8
one-year 0500000US24027 24027 Howard County, Maryland 41361 2341 6.1 2
one-year 0500000US24029 24029 Kent County, Maryland
one-year 0500000US24031 24031 Montgomery County, Maryland 129628 4169 7 1.3
one-year 0500000US24033 24033 Prince George's County, Maryland 100730 3600 11.2 1.7
one-year 0500000US24035 24035 Queen Anne's County, Maryland
one-year 0500000US24037 24037 St. Mary's County, Maryland 13170 1449 8.4 4.5
one-year 0500000US24039 24039 Somerset County, Maryland
one-year 0500000US24041 24041 Talbot County, Maryland
one-year 0500000US24043 24043 Washington County, Maryland 17702 1548 16.8 4.5
one-year 0500000US24045 24045 Wicomico County, Maryland 11716 1283 17.8 6.4
one-year 0500000US24047 24047 Worcester County, Maryland
one-year 0500000US24510 24510 Baltimore city, Maryland 62633 3419 27.2 2.9
five-year 0500000US24001 24001 Allegany County, Maryland 7211 354 19 3.3
five-year 0500000US24003 24003 Anne Arundel County, Maryland 67364 1334 5.8 0.9
five-year 0500000US24005 24005 Baltimore County, Maryland 96739 1439 9.9 0.7
five-year 0500000US24009 24009 Calvert County, Maryland 11793 468 6 1.4
five-year 0500000US24011 24011 Caroline County, Maryland 4190 282 18.7 4
five-year 0500000US24013 24013 Carroll County, Maryland 21166 505 5.7 1
five-year 0500000US24015 24015 Cecil County, Maryland 12357 539 11.6 1.9
five-year 0500000US24017 24017 Charles County, Maryland 20494 627 8.4 1.3
five-year 0500000US24019 24019 Dorchester County, Maryland 3834 273 23.4 4
five-year 0500000US24021 24021 Frederick County, Maryland 31040 811 6.2 1
five-year 0500000US24023 24023 Garrett County, Maryland 3306 206 19.7 4.8
five-year 0500000US24025 24025 Harford County, Maryland 31520 844 9.5 1.3
five-year 0500000US24027 24027 Howard County, Maryland 42290 975 5.3 0.8
five-year 0500000US24029 24029 Kent County, Maryland 1624 213 12.3 4.7
five-year 0500000US24031 24031 Montgomery County, Maryland 129447 1720 6.8 0.4
five-year 0500000US24033 24033 Prince George's County, Maryland 107174 1238 10.3 0.7
five-year 0500000US24035 24035 Queen Anne's County, Maryland 5590 348 8.9 2.7
five-year 0500000US24037 24037 St. Mary's County, Maryland 14293 461 7.5 1.7
five-year 0500000US24039 24039 Somerset County, Maryland 2080 283 31.5 6.9
five-year 0500000US24041 24041 Talbot County, Maryland 4097 242 13.1 3.5
five-year 0500000US24043 24043 Washington County, Maryland 17988 541 15.8 1.8
five-year 0500000US24045 24045 Wicomico County, Maryland 12053 545 19.2 3.1
five-year 0500000US24047 24047 Worcester County, Maryland 4729 365 12.1 3.4
five-year 0500000US24510 24510 Baltimore city, Maryland 64647 1121 28.7 1.2
<!DOCTYPE html>
<meta charset="utf-8">
<style>
#controls {
top: 240px;
left: 60px;
position: absolute;
font-family: sans-serif;
}
</style>
<body>
<form id="controls">
<strong>Poverty Rate of Families with Children Under 18</strong><br>
<input type="radio" name="survey" value="five-year" checked> ACS 5-Year<br>
<input type="radio" name="survey" value="one-year"> ACS 1-Year
</form>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var speed = 900
var width = 960
var height = 500
var color = d3.scaleLinear()
.range(['#ffd', '#c35'])
var projection = d3.geoMercator()
.center([-77.223, 38.85])
.scale(width * 12)
var path = d3.geoPath().projection(projection)
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
var defs = svg.append('defs')
defs.append('pattern')
.attr('id', 'stripe-pattern')
.attr('width', 20)
.attr('height', 20)
.attr('patternUnits', 'userSpaceOnUse')
.attr('patternTransform', 'rotate(45)')
.append('rect')
.attr('width', 12)
.attr('height', 20)
.attr('fill', '#fff')
defs.append('mask')
.attr('id', 'stripe-mask')
.append('rect')
.attr('width', '100%')
.attr('height', '100%')
.attr('fill', 'url(#stripe-pattern)')
var layers = svg.selectAll('.layer')
.data(['fill', 'stripe'])
.enter().append('g')
.attr('class', function (d) { return 'layer ' + d })
var stripeLayer = layers.filter(function (d) { return d === 'stripe' })
.attr('mask', 'url(#stripe-mask)')
d3.queue()
.defer(d3.csv, 'data.csv', function (d) {
return {
acs: d.acs,
id: d['GEO.id2'],
name: d['GEO.display-label'],
rate: d.HC02_EST_VC02 !== '' ? +d.HC02_EST_VC02 / 100 : undefined,
moe: d.HC02_MOE_VC02 !== '' ? +d.HC02_MOE_VC02 / 100 : undefined
}
})
.defer(d3.json, 'md-counties.json')
.awaitAll(initialize)
function initialize(error, results) {
if (error) { throw error }
var data = results[0]
var geoData = results[1]
color.domain([
d3.min(data, function (d) { return d.rate - d.moe }),
d3.max(data, function (d) { return d.rate + d.moe })
])
var counties = layers.selectAll('path')
.data(topojson.feature(geoData, geoData.objects.md).features)
.enter().append('path')
.attr('d', path)
.style('stroke', '#fff')
.style('stroke-width', 1)
update('five-year')
d3.select('#controls').on('change', function () {
update(d3.select('input:checked').attr('value'))
})
function update(acs) {
counties.interrupt()
.data(data.filter(function (d) { return d.acs === acs }),
function (d) { return d.id })
.style('fill', function (d) { return d.rate ? color(d.rate) : '#eee' })
var tIn = d3.transition().duration(speed).ease(d3.easeSinIn)
var tOut = d3.transition().duration(speed).ease(d3.easeSinOut)
stripeLayer.selectAll('path')
.filter(function (d) { return d.rate })
.transition(tIn).delay(function (d, i) { return Math.random() * speed })
.on('start', function repeat() {
d3.active(this)
.style('fill', function (d) { return color(d.rate + d.moe) })
.transition(tOut)
.style('fill', function (d) { return color(d.rate) })
.transition(tIn).delay(speed / 2)
.style('fill', function (d) { return color(d.rate - d.moe) })
.transition(tOut)
.style('fill', function (d) { return color(d.rate) })
.transition(tIn).delay(speed / 2)
.on('start', repeat)
})
}
}
</script>
</body>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment