Skip to content

Instantly share code, notes, and snippets.

@robherley
Last active March 2, 2019 05:25
Show Gist options
  • Save robherley/9ee0d5e3fc84fd830393b76de5d369fc to your computer and use it in GitHub Desktop.
Save robherley/9ee0d5e3fc84fd830393b76de5d369fc to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Compulsory Sterilizations</title>
</head>
<body>
<style>
* {
padding: 0;
margin: 0;
}
body {
background: #37474f;
}
#map {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
#svg_map {
width: 80vw;
height: 80vh;
box-sizing: border-box;
padding: 1rem;
}
</style>
<div id="map"></div>
<script src="//d3js.org/d3.v5.min.js"></script>
<script src="//unpkg.com/topojson@3"></script>
<script>
// Created By Robert Herley
// Inspiration from: https://observablehq.com/@likes2weave/d3-choropleth/4
let svg, path;
// Simple function to map over keys (with optional function)
const mK = data => (key, fn) =>
data.map(({ [key]: k }) => (fn ? fn(k) : k));
// D3.js's parsing function will split the csv into keys of a json,
// but I want to quickly grab all the n columns of data
const parse_sterile = async () => {
// topojson uses ansi mapping for states
const ansi = await d3.csv('./data/state_ansi.csv');
const ansi_map = {};
for (let { state, ab } of ansi) {
ansi_map[ab] = state;
}
const raw_csv = await (await fetch('/data/sterile.csv')).text();
const rows = raw_csv.split('\n').splice(1);
const obj = {};
for (let row of rows) {
const [ab, name, total, region, ...rest] = row.split(',');
obj[ansi_map[ab]] = {
ab,
name,
total,
region,
rest
};
}
return obj;
};
const draw = () => {
const { width, height } = svg_map.getBoundingClientRect();
svg.attr('width', width).attr('height', height);
};
const init = async () => {
const us = await d3.json('https://unpkg.com/us-atlas@1/us/10m.json');
const data = await parse_sterile();
window.data = data;
const max = d3.max(mK(Object.values(data))('total', parseInt));
// const color = d3
// .scaleQuantile()
// .domain([0, max])
// .range(d3.schemeBlues[9].splice(2));
svg = d3
.select('#map')
.append('svg')
.attr('id', 'svg_map');
path = d3.geoPath();
svg
.attr('viewBox', '20 0 950 600')
.attr('preserveAspectRatio', 'xMidYMid');
svg
.append('g')
.selectAll('path')
.data(topojson.feature(us, us.objects.states).features)
.enter()
.append('path')
.attr('fill', d =>
data[d.id] ? d3.interpolateOranges(data[d.id].total / max) : 'white'
)
.attr('d', path);
svg
.append('path')
.datum(topojson.mesh(us, us.objects.states, (a, b) => a !== b))
.attr('fill', 'none')
.attr('stroke', 'white')
.attr('stroke-linejoin', 'round')
.attr('d', path);
svg
.append('path')
.datum(topojson.mesh(us, us.objects.nation))
.attr('fill', 'none')
.attr('stroke', 'white')
.attr('stroke-linejoin', 'round')
.attr('d', path);
draw();
};
window.onload = init;
window.onresize = draw;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment