Skip to content

Instantly share code, notes, and snippets.

@martgnz
Last active March 23, 2021 02:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save martgnz/1b7ba8ebd60a1567e855 to your computer and use it in GitHub Desktop.
Save martgnz/1b7ba8ebd60a1567e855 to your computer and use it in GitHub Desktop.
Choropleth map
license: mit

A simple choropleth map with the foreign population of El Maresme extracted from IDESCAT. It uses d3-tip for the tooltip.

Generating the GeoJSON

  1. Download the Base Municipal 1:50 000 SHP from the Institut Cartogràfic de Catalunya website. You need to register first.
  2. Extract it and note the bm50mv33sh1fpm1r170.shp shapefile. These are the municipalities that we need.
  3. Open a terminal in the extracted folder and convert the shapefile it to GeoJSON using the following ogr2ogr2 snippet:
ogr2ogr \
  -f GeoJSON \
  -where "NOM_MUNI IN ( 'Alella', 'Arenys de Mar', 'Arenys de Munt', 'Argentona', 'Cabrera de Mar', 'Cabrils', 'Caldes d''Estrac', 'Calella', 'Canet de Mar', 'Dosrius', 'Malgrat de Mar', 'El Masnou', 'Mataró', 'Montgat', 'Palafolls', 'Pineda de Mar', 'Premià de Dalt', 'Premià de Mar', 'Sant Andreu de Llavaneres', 'Sant Cebrià de Vallalta', 'Sant Iscle de Vallalta', 'Sant Pol de Mar', 'Sant Vicenç de Montalt', 'Santa Susanna', 'Teià', 'Tiana', 'Tordera', 'Vilassar de Dalt', 'Vilassar de Mar', 'Òrrius')" \
  -t_srs 'EPSG:4326' \
  maresme.json \
  bm50mv33sh1fpm1r170.shp

Possible improvements: insert the scale of the choropleth buckets like this example and use TopoJSON for a smaller footprint.

municipi percentatge
Alella 08.63
Arenys de Mar 10.77
Arenys de Munt 05.59
Argentona 04.58
Cabrera de Mar 05.64
Cabrils 09.14
Caldes d'Estrac 13.95
Calella 18.81
Canet de Mar 08.23
Dosrius 03.83
Malgrat de Mar 11.53
el Masnou 08.4
Mataró 16.1
Montgat 05.74
Palafolls 04.95
Pineda de Mar 14.56
Premià de Dalt 08.59
Premià de Mar 12.7
Sant Andreu de Llavaneres 09.85
Sant Cebrià de Vallalta 07.33
Sant Iscle de Vallalta 06.6
Sant Pol de Mar 09.43
Sant Vicenç de Montalt 08.62
Santa Susanna 11.66
Teià 04.93
Tiana 03.3
Tordera 08.1
Vilassar de Dalt 05.1
Vilassar de Mar 07.77
Òrrius 03.4
<!DOCTYPE html>
<meta charset="utf-8" />
<style type="text/css">
.municipis {
stroke: black;
stroke-width: 0.5px;
stroke-opacity: 0.2;
}
.municipis:hover {
fill-opacity: 0.7;
}
.d3-tip {
font-weight: bold;
font-size: 12px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
padding: 10px;
background: rgba(0, 0, 0, 0.7);
color: #fff;
border-radius: 2px;
}
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/d3-tip@0.7.1/index.js"></script>
<script type="text/javascript">
var margin = { top: 40, right: 10, bottom: 10, left: 10 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var projection = d3
.geoMercator()
.center([2.5, 41.6])
.scale(64000);
var path = d3.geoPath().projection(projection);
var color = d3
.scaleQuantize()
.range([
"rgb(239,243,255)",
"rgb(189,215,231)",
"rgb(107,174,214)",
"rgb(49,130,189)",
"rgb(8,81,156)"
]);
var tip = d3
.tip()
.attr("class", "d3-tip")
.offset([-5, 0])
.html(function(d) {
return (
"<strong>" +
d.properties.NOM_MUNI +
"</strong>" +
"<br />" +
"<span>Foreign population: <span>" +
"<span style='color: rgb(189,215,231)'>" +
d.properties.percentatge +
"%</span>"
);
});
var svg = d3
.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.call(tip);
d3.csv("dades.csv", function(data) {
color.domain([
d3.min(data, function(d) {
return d.percentatge;
}),
d3.max(data, function(d) {
return d.percentatge;
})
]);
d3.json("maresme.json", function(json) {
for (var i = 0; i < data.length; i++) {
var dataState = data[i].municipi;
var dataValue = parseFloat(data[i].percentatge);
for (var j = 0; j < json.features.length; j++) {
var jsonState = json.features[j].properties.NOM_MUNI;
if (dataState == jsonState) {
json.features[j].properties.percentatge = dataValue;
break;
}
}
}
svg
.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.attr("class", "municipis")
.on("mouseover", tip.show)
.on("mouseout", tip.hide)
.attr("fill", function(d) {
var value = d.properties.percentatge;
if (value) {
return color(value);
} else {
return "#ccc";
}
});
});
});
</script>
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