Public
Edited
Oct 26, 2023
1 fork
Insert cell
Insert cell
world = {
const topo = await FileAttachment("ne_110m_admin_0_countries_lakes.json").json();
const geo = topojson.feature(topo, topo.objects.ne_110m_admin_0_countries_lakes);
geo.features.forEach(feature => {
feature.centroid = centroid(feature);
return feature;
});
return geo;
}
Insert cell
simulation = d3.forceSimulation(world.features)
.force("x", d3.forceX(d => projection(d.centroid)[0]))
.force("y", d3.forceY(d => projection(d.centroid)[1]))
.force("collide", d3.forceCollide(d => 1 + r(d.properties.POP_EST)))
.stop();
Insert cell
height = width * .49;
Insert cell
path = d3.geoPath(projection);
Insert cell
projection = d3.geoEqualEarth()
.rotate([-10, 0, 0])
.fitSize([width, height], { type: "Sphere" });
Insert cell
import { toc } from "@harrystevens/toc";
Insert cell
r = d3.scaleSqrt()
.domain([0, d3.max(world.features, d => d.properties.POP_EST)])
.range([0, Math.sqrt(width * height) / 10])
Insert cell
// Find the centroid of the largest polygon
centroid = (feature) => {
const geometry = feature.geometry;
if (geometry.type === "Polygon"){
return d3.geoCentroid(feature);
}
else {
let largestPolygon = {}, largestArea = 0;
geometry.coordinates.forEach(coordinates => {
const polygon = { type: "Polygon", coordinates },
area = d3.geoArea(polygon);
if (area > largestArea) {
largestPolygon = polygon;
largestArea = area;
}
});
return d3.geoCentroid(largestPolygon);
}
}
Insert cell
{
for (let i = 0; i < 200; i++){
simulation.tick();
}
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("overflow", "visible");
svg.selectAll(".country")
.data(world.features)
.enter().append("path")
.attr("class", "country")
.attr("d", path)
.attr("fill", "#f5f5f5")
.attr("stroke", "#e0e0e0")
.style("display", "block");

svg.selectAll("circle")
.data(world.features)
.enter().append("circle")
.attr("r", d => r(d.properties.POP_EST))
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("fill", "steelblue")
.attr("fill-opacity", 0.3)
.attr("stroke", "steelblue");

return svg.node();
}
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