World countries colored by land area using the areakm2 property — an opt-in field computed from 10m Natural Earth geometry. A logarithmic color scale handles the range from Vatican City (0.44 km²) to Russia (17M km²). Hover to see each country's area. areakm2 is most useful as a denominator: divide any count by area to get a per-km² density.
https://api.mapjson.com/v1/geo?layer=countries&filter=world&detail=low&properties=name,areakm2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Country Area</title>
<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script>
<style>
body { margin: 0; background: #18303f; }
svg { width: 100%; height: 100vh; display: block; }
.country { stroke: #2e4a5a; stroke-width: 0.3; transition: opacity 0.1s; }
.country:hover { opacity: 0.8; }
.graticule { fill: none; stroke: #2e5870; stroke-width: 0.3; }
.sphere { fill: #22485e; }
.tooltip {
position: fixed;
background: #2c2317;
color: #f4efe8;
font-family: monospace;
font-size: 11px;
padding: 6px 10px;
pointer-events: none;
opacity: 0;
transition: opacity 0.1s;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="tooltip" id="tooltip"></div>
<svg id="map"></svg>
<script>
const url = "https://api.mapjson.com/v1/geo?layer=countries&filter=world&detail=low&properties=name,areakm2";
const width = 960, height = 500;
const tooltip = document.getElementById("tooltip");
const svg = d3.select("#map").attr("viewBox", `0 0 ${width} ${height}`);
const projection = d3.geoEqualEarth()
.scale(160).translate([width / 2, height / 2 + 20]);
const path = d3.geoPath(projection);
// Log scale — Russia (17M km²) is 40,000× larger than tiny island states
const color = d3.scaleSequentialLog(d3.interpolateYlOrBr)
.domain([500, 17000000]);
svg.append("path").datum({type:"Sphere"})
.attr("class", "sphere").attr("d", path);
svg.append("path").datum(d3.geoGraticule()())
.attr("class", "graticule").attr("d", path);
d3.json(url).then(topo => {
const geojson = topojson.feature(topo, topo.objects.geo);
svg.selectAll(".country")
.data(geojson.features)
.join("path")
.attr("class", "country")
.attr("d", path)
.attr("fill", d => d.properties.areakm2 ? color(d.properties.areakm2) : "#3a4a52")
.on("mousemove", function(event, d) {
const area = d.properties.areakm2;
tooltip.style.left = (event.clientX + 12) + "px";
tooltip.style.top = (event.clientY - 10) + "px";
tooltip.style.opacity = 1;
tooltip.innerHTML =
`<strong>${d.properties.name || d.properties.gid}</strong><br>` +
(area ? area.toLocaleString() + " km²" : "area unavailable");
})
.on("mouseleave", () => { tooltip.style.opacity = 0; });
});
</script>
</body>
</html>