Public
Edited
Apr 4, 2022
4 forks
Insert cell
Insert cell
<svg width="1000" height="500">
<g id="countries"></g>
<g id="gdpcircles"></g>
</svg>
Insert cell
viewof year = Inputs.range([1961, 2011], {label: "Year", step:1, value:1994})
Insert cell
map = d3.select(mapContainer)
Insert cell
import {getMapData, drawMapLayer} with {projection} from "@emfielduva/dvlib_maps"
Insert cell
world = getMapData("world110m")
Insert cell
mapLayers = {
let mapLayers = [];
mapLayers["countries"] = drawMapLayer(map,"countries",world.features,world.idField);
return mapLayers;
}
Insert cell
<style>
#countries path {fill: #eeeeee; stroke: #ccc}
#gdpcircles circle {stroke: #ccc; opacity: 0.75;}
</style>
Insert cell
Insert cell
Insert cell
gdp = FileAttachment("world-gdp-growth.csv").csv()
Insert cell
Insert cell
import {rFromArea, toNum} from "@emfielduva/dvlib"
Insert cell
Insert cell
//year = "1994" // this is commented out to use the range slider at the top to define year
Insert cell
Insert cell
First we need to get the **centroid points** of the countries to put the circles on.
Insert cell
projection = d3.geoMercator()
Insert cell
import {geoCentroids} with {projection} from "@emfielduva/dvlib_maps"
Insert cell
countryCentroids = {
let centroids = geoCentroids(world.features, "id");
return d3.index(centroids, d => d["name"]); // return it as an indexed map by country "name". It's just easier to access this way.
}
Insert cell
Insert cell
Insert cell
Insert cell
getCoord = (countryCode) => {
let coord = "";
// in matching across datasets, they may not all have a match. This will test first and return only when it does
if (typeof(countryCentroids.get(countryCode)) !== "undefined") {
coord = countryCentroids.get(countryCode).coord;
}
return coord;
}
Insert cell
gdpCircles = {
let gdpCircles = map.select("#gdpcircles").selectAll("circle")
.data(gdp)
.join("circle")
.transition().duration(500)
.attr("cx", d => projection(getCoord(d["Country Code"]))[0])
.attr("cy", d => projection(getCoord(d["Country Code"]))[1])
.attr("r", d => rFromArea(Math.abs(d[year])) * dotScaleFactor)
.style("fill", d => colorScale(toNum(d[year])));

return gdpCircles;
}
Insert cell
Insert cell
dotScaleFactor = 5
Insert cell
colorScale = d3.scaleLinear().domain([-25,0,25]).range(["red","gray","green"])
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more