Skip to content

Instantly share code, notes, and snippets.

@bradoyler
Last active March 16, 2020 15:03
Show Gist options
  • Save bradoyler/12b0895665ffa6e6b79652e7c48769b8 to your computer and use it in GitHub Desktop.
Save bradoyler/12b0895665ffa6e6b79652e7c48769b8 to your computer and use it in GitHub Desktop.
Flu Illness Cartogram

CDC ILI map

license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="//cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.18.1/babel.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js"></script>
<style>
#cartogram {
max-width: 600px;
margin: auto;
}
.week-label {
font-family: Helvetica;
font-size: 1em;
color: #fff;
}
body {
background-color:#000; margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<div id="cartogram"></div>
<script type="text/babel" src="index.js"></script>
</body>
const statesJson = {"AL":{"name":"Alabama","pop_2014":4849377,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":2,"W41":2,"W42":2,"W43":3,"W44":4,"W45":4,"W46":5,"W47":5,"W48":5,"W49":7,"W50":10,"W51":10,"W52":10},"AK":{"name":"Alaska","pop_2014":736732,"W1":6,"W2":6,"W3":6,"W4":8,"W5":10,"W6":10,"W40":1,"W41":2,"W42":4,"W43":3,"W44":2,"W45":2,"W46":4,"W47":4,"W48":5,"W49":6,"W50":5,"W51":6,"W52":7},"AZ":{"name":"Arizona","pop_2014":6731484,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":2,"W41":2,"W42":1,"W43":2,"W44":3,"W45":3,"W46":3,"W47":3,"W48":3,"W49":6,"W50":10,"W51":10,"W52":10},"AR":{"name":"Arkansas","pop_2014":2966369,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":3,"W47":1,"W48":4,"W49":8,"W50":10,"W51":10,"W52":10},"CA":{"name":"California","pop_2014":38802500,"W1":10,"W2":10,"W3":8,"W4":8,"W5":9,"W6":8,"W40":2,"W41":1,"W42":1,"W43":1,"W44":2,"W45":2,"W46":2,"W47":3,"W48":2,"W49":4,"W50":7,"W51":10,"W52":10},"CO":{"name":"Colorado","pop_2014":5355866,"W1":8,"W2":7,"W3":7,"W4":8,"W5":10,"W6":9,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":2,"W46":2,"W47":3,"W48":3,"W49":4,"W50":5,"W51":6,"W52":7},"CT":{"name":"Connecticut","pop_2014":3596677,"W1":4,"W2":5,"W3":9,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":2,"W49":2,"W50":3,"W51":2,"W52":3},"DC":{"name":"District of Columbia","pop_2014":658893,"W1":5,"W2":5,"W3":7,"W4":10,"W5":10,"W6":10,"W40":2,"W41":2,"W42":2,"W43":2,"W44":2,"W45":3,"W46":3,"W47":3,"W48":4,"W49":4,"W50":4,"W51":3,"W52":5},"DE":{"name":"Delaware","pop_2014":935614,"W1":1,"W2":1,"W3":2,"W4":5,"W5":8,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":1,"W52":1},"FL":{"name":"Florida","pop_2014":19893297,"W1":5,"W2":9,"W3":10,"W4":10,"W5":10,"W6":9,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":2,"W46":2,"W47":1,"W48":1,"W49":1,"W50":2,"W51":4,"W52":5},"GA":{"name":"Georgia","pop_2014":10097343,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":2,"W41":3,"W42":3,"W43":4,"W44":4,"W45":5,"W46":6,"W47":7,"W48":6,"W49":7,"W50":7,"W51":10,"W52":10},"HI":{"name":"Hawaii","pop_2014":1419561,"W1":5,"W2":8,"W3":7,"W4":8,"W5":6,"W6":5,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":3,"W46":3,"W47":3,"W48":5,"W49":5,"W50":3,"W51":6,"W52":7},"ID":{"name":"Idaho","pop_2014":1634464,"W1":5,"W2":7,"W3":6,"W4":5,"W5":6,"W6":4,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":2,"W49":1,"W50":1,"W51":3,"W52":1},"IL":{"name":"Illinois","pop_2014":12880580,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":2,"W49":3,"W50":6,"W51":10,"W52":10},"IN":{"name":"Indiana","pop_2014":6596855,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":1,"W46":1,"W47":1,"W48":3,"W49":4,"W50":3,"W51":9,"W52":10},"IA":{"name":"Iowa","pop_2014":3107126,"W1":5,"W2":8,"W3":9,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":2,"W50":2,"W51":3,"W52":8},"KS":{"name":"Kansas","pop_2014":2904021,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":2,"W48":1,"W49":3,"W50":7,"W51":10,"W52":10},"KY":{"name":"Kentucky","pop_2014":4413457,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":3,"W47":2,"W48":3,"W49":6,"W50":10,"W51":10,"W52":10},"LA":{"name":"Louisiana","pop_2014":4649676,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":3,"W41":3,"W42":4,"W43":5,"W44":7,"W45":7,"W46":8,"W47":10,"W48":10,"W49":10,"W50":10,"W51":10,"W52":10},"ME":{"name":"Maine","pop_2014":1330089,"W1":1,"W2":1,"W3":1,"W4":1,"W5":1,"W6":3,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":1,"W52":1},"MD":{"name":"Maryland","pop_2014":5976407,"W1":4,"W2":6,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":2,"W52":7},"MA":{"name":"Massachusetts","pop_2014":6745408,"W1":7,"W2":5,"W3":8,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":2,"W46":2,"W47":3,"W48":3,"W49":3,"W50":4,"W51":5,"W52":8},"MI":{"name":"Michigan","pop_2014":9909877,"W1":5,"W2":8,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":2,"W46":1,"W47":2,"W48":2,"W49":3,"W50":3,"W51":5,"W52":6},"MN":{"name":"Minnesota","pop_2014":5457173,"W1":7,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":2,"W50":2,"W51":4,"W52":5},"MS":{"name":"Mississippi","pop_2014":2994079,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":2,"W41":1,"W42":1,"W43":3,"W44":4,"W45":8,"W46":10,"W47":10,"W48":10,"W49":10,"W50":10,"W51":10,"W52":10},"MO":{"name":"Missouri","pop_2014":6063589,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":3,"W50":5,"W51":10,"W52":10},"MT":{"name":"Montana","pop_2014":1023579,"W1":1,"W2":2,"W3":2,"W4":1,"W5":2,"W6":1,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":1,"W52":1},"NE":{"name":"Nebraska","pop_2014":1881503,"W1":10,"W2":6,"W3":9,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":2,"W43":2,"W44":2,"W45":3,"W46":3,"W47":5,"W48":3,"W49":3,"W50":6,"W51":8,"W52":10},"NV":{"name":"Nevada","pop_2014":2839099,"W1":9,"W2":7,"W3":6,"W4":6,"W5":8,"W6":8,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":2,"W46":2,"W47":2,"W48":2,"W49":3,"W50":5,"W51":6,"W52":9},"NH":{"name":"New Hampshire","pop_2014":1326813,"W1":4,"W2":4,"W3":8,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":1,"W52":1},"NJ":{"name":"New Jersey","pop_2014":8938175,"W1":9,"W2":8,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":2,"W46":2,"W47":3,"W48":3,"W49":3,"W50":4,"W51":5,"W52":8},"NM":{"name":"New Mexico","pop_2014":2085572,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":2,"W46":3,"W47":3,"W48":1,"W49":3,"W50":5,"W51":7,"W52":10},"NY":{"name":"New York","pop_2014":19746227,"W1":7,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":2,"W51":5,"W52":4},"NC":{"name":"North Carolina","pop_2014":9943964,"W1":5,"W2":9,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":2,"W47":3,"W48":1,"W49":2,"W50":1,"W51":1,"W52":6},"ND":{"name":"North Dakota","pop_2014":739482,"W1":2,"W2":6,"W3":4,"W4":4,"W5":5,"W6":7,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":5,"W52":2},"OH":{"name":"Ohio","pop_2014":11594163,"W1":5,"W2":6,"W3":8,"W4":8,"W5":9,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":2,"W52":6},"OK":{"name":"Oklahoma","pop_2014":3878051,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":3,"W46":3,"W47":4,"W48":4,"W49":4,"W50":10,"W51":10,"W52":10},"OR":{"name":"Oregon","pop_2014":3970239,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":9,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":2,"W46":2,"W47":3,"W48":3,"W49":4,"W50":5,"W51":9,"W52":10},"PA":{"name":"Pennsylvania","pop_2014":12787209,"W1":6,"W2":7,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":2,"W45":2,"W46":2,"W47":2,"W48":2,"W49":2,"W50":3,"W51":3,"W52":6},"RI":{"name":"Rhode Island","pop_2014":1055173,"W1":5,"W2":7,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":3,"W50":2,"W51":3,"W52":2},"SC":{"name":"South Carolina","pop_2014":4832482,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":2,"W41":1,"W42":2,"W43":5,"W44":6,"W45":6,"W46":6,"W47":10,"W48":10,"W49":10,"W50":10,"W51":10,"W52":10},"SD":{"name":"South Dakota","pop_2014":853175,"W1":6,"W2":7,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":2,"W42":2,"W43":3,"W44":3,"W45":4,"W46":6,"W47":4,"W48":4,"W49":4,"W50":4,"W51":5,"W52":8},"TN":{"name":"Tennessee","pop_2014":6549352,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":2,"W51":9,"W52":7},"TX":{"name":"Texas","pop_2014":26956958,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":3,"W45":3,"W46":5,"W47":5,"W48":7,"W49":9,"W50":10,"W51":10,"W52":10},"UT":{"name":"Utah","pop_2014":2942902,"W1":3,"W2":4,"W3":5,"W4":3,"W5":4,"W6":6,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":1,"W52":4},"VT":{"name":"Vermont","pop_2014":626562,"W1":4,"W2":5,"W3":7,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":1,"W52":3},"VA":{"name":"Virginia","pop_2014":8326289,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":2,"W43":2,"W44":2,"W45":3,"W46":3,"W47":4,"W48":4,"W49":4,"W50":5,"W51":6,"W52":9},"WA":{"name":"Washington","pop_2014":7061530,"W1":10,"W2":10,"W3":8,"W4":9,"W5":7,"W6":5,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":1,"W50":1,"W51":1,"W52":10},"WV":{"name":"West Virginia","pop_2014":1850326,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":3,"W48":1,"W49":1,"W50":5,"W51":9,"W52":10},"WI":{"name":"Wisconsin","pop_2014":5757564,"W1":7,"W2":8,"W3":7,"W4":9,"W5":10,"W6":9,"W40":1,"W41":1,"W42":1,"W43":1,"W44":1,"W45":1,"W46":1,"W47":1,"W48":1,"W49":2,"W50":1,"W51":4,"W52":5},"WY":{"name":"Wyoming","pop_2014":584153,"W1":10,"W2":10,"W3":10,"W4":10,"W5":10,"W6":10,"W40":1,"W41":3,"W42":1,"W43":3,"W44":3,"W45":2,"W46":1,"W47":1,"W48":2,"W49":3,"W50":3,"W51":5,"W52":10}}
const width = 600
const height = 400
const scale = 0.64
const colorScale = d3.scaleLinear().domain([0, 10]).range(['#feebe2', '#c51b8a'])
function interpolateEachNode (node) {
const circle = pseudocircle(node)
const closestPoints = node.rings.slice(1).map(function (ring) {
const i = d3.scan(circle.map(point => distance(point, ring.centroid)))
return ring.map(() => circle[i])
})
const interpolator = d3.interpolateArray(node.rings, [circle, ...closestPoints])
node.interpolator = function (t) {
const str = pathString(interpolator(t))
// Prevent some fill-rule flickering for MultiPolygons
if (t > 0.99) {
return str.split('Z')[0] + 'Z'
}
return str
}
}
function displayTextNodes (g, show) {
return () => {
const display = show ? 'block' : 'none'
g.selectAll('text').style('display', display)
}
}
function pseudocircle (node) {
return node.rings[0].map(point => {
var angle = node.startingAngle - 2 * Math.PI * (point.along / node.perimeter)
return [
Math.cos(angle) * node.r + node.x,
Math.sin(angle) * node.r + node.y
]
})
}
function cleanUpGeometry (node) {
node.rings = (node.geometry.type === 'Polygon' ? [node.geometry.coordinates] : node.geometry.coordinates)
node.rings = node.rings.map(polygon => {
polygon[0].area = d3.polygonArea(polygon[0])
polygon[0].centroid = d3.polygonCentroid(polygon[0])
return polygon[0]
})
node.rings.sort((a, b) => b.area - a.area)
node.perimeter = d3.polygonLength(node.rings[0])
// Optional step, but makes for more circular circles
bisect(node.rings[0], node.perimeter / 72)
node.rings[0].reduce(function (prev, point) {
point.along = prev ? prev.along + distance(point, prev) : 0
node.perimeter = point.along
return point
}, null)
node.startingAngle = Math.atan2(node.rings[0][0][1] - node.y0, node.rings[0][0][0] - node.x0)
}
function bisect (ring, maxSegmentLength) {
for (var i = 0; i < ring.length; i++) {
const a = ring[i]
let b = i === ring.length - 1 ? ring[0] : ring[i + 1]
while (distance(a, b) > maxSegmentLength) {
b = midpoint(a, b)
ring.splice(i + 1, 0, b)
}
}
}
function distance (a, b) {
return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]))
}
function midpoint (a, b) {
return [a[0] + (b[0] - a[0]) * 0.5, a[1] + (b[1] - a[1]) * 0.5]
}
function pathString (d) {
return (d.rings || d).map(ring => 'M' + ring.join('L') + 'Z').join(' ')
}
function applyLabelToNodes (g, nodes) {
// apply state labels
g.selectAll('g')
.data(nodes)
.enter()
.append('text')
.text(d => {
if (d.r > 14) {
return d.id
}
})
.attr('text-anchor', 'middle')
.attr('y', d => d.y + 5)
.attr('x', d => d.x)
.attr('class', 'state-label')
.style('display', 'none')
}
function updateNodesForWeek (val) {
return (d, i) => {
const state = statesJson[d.id]
const colorNum = state[`W${val}`]
return colorScale(colorNum)
}
}
function createSimulation (nodes, links, width, height) {
return d3.forceSimulation(nodes)
.force('cx', d3.forceX().x(d => width / 2).strength(0.02))
.force('cy', d3.forceY().y(d => height / 2).strength(0.02))
.force('link', d3.forceLink(links).distance(d => d.distance))
.force('x', d3.forceX().x(d => d.x).strength(0.1))
.force('y', d3.forceY().y(d => d.y).strength(0.1))
.force('collide', d3.forceCollide().strength(0.8).radius(d => d.r + 1))
.stop()
}
function setupNodeData (node, i) {
const centroid = d3.geoPath().centroid(node)
const radius = d3.scaleSqrt().range([0, 75]).clamp(true)
node.x0 = centroid[0]
node.y0 = centroid[1]
const state = statesJson[node.id] || {}
node.stateName = state.name
node.r = radius(state.pop_2014 / 35000000)
cleanUpGeometry(node)
}
function updateWeekLabel (text) {
return () => {
d3.select('.week-label').text(text)
}
}
function initMap(selector = '#cartogram') {
d3.select(selector)
.append('p')
.attr('class', 'week-label')
const svg = d3.select(selector).append('svg')
.attr('width', width)
.attr('height', height)
.attr('id', 'map-svg')
.attr('viewBox', `0 0 ${width} ${height}`)
d3.json('us-topo.json', (err, us) => {
if (err) { throw Error(err) }
const neighbors = topojson.neighbors(us.objects.states.geometries)
const nodes = topojson.feature(us, us.objects.states).features
nodes.forEach(setupNodeData)
const g = svg.append('g')
.attr('transform', `scale(${scale}) translate(0, 0)`)
.attr('id', 'states')
const states = g.selectAll('g')
.data(nodes)
.enter()
.append('path')
.attr('d', pathString)
.attr('fill', '#eee')
d3.select(selector)
.append('p')
.text('Source: CDC')
.attr('class', 'credit')
simulate()
function simulate () {
nodes.forEach(node => {
node.x = node.x0
node.y = node.y0
})
const links = d3.merge(neighbors.map(function (neighborSet, i) {
return neighborSet.filter(j => nodes[j]).map(function (j) {
return {source: i, target: j, distance: nodes[i].r + nodes[j].r + 3}
})
}))
const simulation = createSimulation(nodes, links, width, height)
while (simulation.alpha() > 0.1) {
simulation.tick()
}
nodes.forEach(interpolateEachNode)
applyLabelToNodes(g, nodes)
const transDelay = 600
const transDuration = 900
states.sort((a, b) => b.r - a.r)
.transition().on('start', updateWeekLabel('Oct 7th, 2017'))
.attr('fill', '#eee')
.delay(transDelay).duration(transDuration) // change to circles
.attrTween('d', node => node.interpolator)
.on('end', displayTextNodes(g, true))
.transition()
.delay(transDelay)
.duration(transDuration)
.attr('fill', updateNodesForWeek(40))
.transition().on('start', updateWeekLabel('Nov 4th, 2017'))
.delay(transDelay)
.duration(transDuration)
.attr('fill', updateNodesForWeek(44))
.transition().on('start', updateWeekLabel('Dec 2nd, 2017'))
.delay(transDelay)
.duration(transDuration)
.attr('fill', updateNodesForWeek(48))
.transition().on('start', updateWeekLabel('Dec 30th 2017'))
.delay(transDelay)
.duration(transDuration)
.attr('fill', updateNodesForWeek(52))
.transition().on('start', updateWeekLabel('Jan 13, 2018'))
.delay(transDelay)
.duration(transDuration)
.attr('fill', updateNodesForWeek(2))
.transition().on('start', updateWeekLabel('Feb 10, 2018'))
.delay(transDelay)
.duration(transDuration)
.attr('fill', updateNodesForWeek(6))
.transition()
.on('start', displayTextNodes(g, false))
.delay(transDelay) // back to states
.attrTween('d', node => t => node.interpolator(1 - t))
.on('end', (d, i) => i || simulate())
}
})
}
initMap()
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