Skip to content

Instantly share code, notes, and snippets.

@rgdonohue
Last active July 3, 2020 01:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rgdonohue/895d82f8dc9d6f87401e1075d4334fe5 to your computer and use it in GitHub Desktop.
Save rgdonohue/895d82f8dc9d6f87401e1075d4334fe5 to your computer and use it in GitHub Desktop.
Sequencing choropleth map with D3 v4
id 2010 2011 2012 2013 2014 2015 2016
1 5.0989242 5.1071601 5.1251884 5.1423388 5.1451654 5.146771 5.1470571
2 4.9367247 4.9445963 4.9618983 4.978291 4.9809551 4.9825864 4.9827614
3 5.0192266 5.0273027 5.0450058 5.0618234 5.0645833 5.0661912 5.0664377
4 5.4870582 5.4958878 5.5151806 5.5335665 5.5366168 5.53829 5.5386457
5 4.7672024 4.7748523 4.791666 4.8075972 4.8101869 4.8117704 4.8119426
6 4.8474455 4.8552446 4.8723626 4.8886042 4.8912573 4.8928399 4.8930478
7 4.856298 4.86413 4.8813052 4.897615 4.9002881 4.9018579 4.9020863
8 5.1594591 5.1678715 5.186233 5.2037487 5.206665 5.2082362 5.2085986
9 5.0730085 5.0812154 5.0991807 5.1162705 5.1190867 5.120688 5.1209717
10 4.9116721 4.9195366 4.9368153 4.9531932 4.9558587 4.9574776 4.9576635
11 5.0580745 5.0663204 5.0843325 5.1015019 5.1043539 5.1059117 5.1062493
12 4.8068585 4.8144374 4.831162 4.8469458 4.8494754 4.8511348 4.851213
13 4.9077721 4.9156227 4.9328814 4.9492307 4.9518857 4.9535146 4.9536872
14 4.921865 4.9298401 4.9473066 4.9639139 4.9666467 4.968214 4.9684782
15 5.0372849 5.045403 5.0631924 5.0800977 5.0828743 5.0844827 5.0847387
16 5.1141939 5.122551 5.1407981 5.1581998 5.1610932 5.1626606 5.1630139
17 4.2812109 4.2879834 4.3029666 4.3170729 4.3193126 4.3208456 4.3208642
18 4.2709394 4.2777634 4.292841 4.307055 4.3093233 4.310842 4.3108873
19 5.1829953 5.1915421 5.2101483 5.2279429 5.2309327 5.2324619 5.2328987
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sequenced choropleth map</title>
<style>
#map {
width: 960px;
height: 480px;
margin: 18px auto 0;
background: whitesmoke;
position: relative;
}
#ui {
position: absolute;
left: 8px;
bottom: 8px;
}
#ui output {
padding: 3px 6px;
margin: 0 0 8px 0;
width: 40px;
border: 1px solid gray;
display: block;
text-align: center;
}
#ui input {
width: 280px;
}
.region {
stroke: #fff;
}
</style>
</head>
<body>
<div id="map">
<div id="ui">
<output id="output">2010</output>
<input id="sequence" type='range' min="2010", max="2016", value="2010", step="1" >
</div>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/simple-statistics@4.1.0/dist/simple-statistics.min.js"></script>
<script>
(function(){
var width = 960,
height = 480;
var svg = d3.select("#map")
.append("svg")
.attr("width", width)
.attr("height", height);
var projection = d3.geoConicEqualArea()
.center([0, -29])
.rotate([-24,0])
.scale(2000)
.translate([width / 2, height / 2]);
var path = d3.geoPath()
.projection(projection);
// colors from https://github.com/CartoDB/CartoColor/blob/master/cartocolor.js
var colors = ["#f9ddda", "#eda8bd", "#ce78b3", "#9955a8", "#573b88"];
// function to take a number and output a color
var colorize = d3.scaleThreshold()
.range(colors);
d3.queue()
.defer(d3.json, 'sa.json')
.defer(d3.csv, 'data.csv')
.await(processData);
function processData(err, geoms, dataSet){
// empty array for holding all values for later
// classifying data
var dataValues = [];
// loop through your geometry features
geoms.features.forEach(function(geom){
// loop through CSV data
dataSet.forEach(function(data){
// if they match
if(geom.properties.WMA_DWAF_I === +data.id){
// loop through all years
for(var datum in data){
// if isn't id code
if (datum != "id") {
// add CSV data to geom properties
geom.properties[datum] = +data[datum]; // convert from string to number
// push value to our array
dataValues.push(+data[datum]);
}
}
}
})
});
// determine cluster arrays from data values
var clusters = ss.ckmeans(dataValues, 5);
var breaks = clusters.map(function(cluster){
// return the last element of the cluster array
return cluster.pop();
});
// remove last array item for colorize domain
breaks.splice(-1,1);
// update colorize function with domain values
colorize.domain(breaks);
// send updated geoms to be drawn
drawMap(geoms);
}
function drawMap(geoms) {
// append a g to the svg, use data from geoms
// and path generator to draw map
svg.append("g")
.selectAll("path")
.data(geoms.features)
.enter()
.append("path")
.attr("d", path)
.attr("class", "region");
// call to color map with initial/min value
updateMap(d3.select("#sequence").attr("min"));
}
function updateMap(year) {
// select all the regions
d3.selectAll('.region')
.attr("fill", function(d){
if(d.properties[year] != undefined) {
return colorize(d.properties[year]);
} else {
// something wrong with data
return 'lightgray'
}
});
}
// IIFE to attach listeners to range UI
(function() {
// select the output
var output = d3.select("#output");
// select range
d3.select('#sequence')
.on('input', function(d) { // when it changes
updateMap(+this.value); // update the map
output.html(+this.value) // update the output
});
})();
})();
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
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