function svgMap() {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]),
path = d3.geoPath(projection);
projection.fitExtent([[2, 2], [width - 2, height - 2]], { type: "Sphere" });
function render() {
svg
.append("g")
.attr("id", "sphere")
.append("path")
.attr("fill", "none")
.attr("stroke", "#000")
.attr("stroke-width", 0.125)
.datum({ type: "Sphere" })
.attr("d", path);
svg
.append("g")
.attr("id", "world")
.append("path")
.attr("fill", "#fff")
.attr("stroke", "#000")
.attr("stroke-width", 0.125)
.datum(world)
.attr("d", path);
const contrast = .7,
max = d3.max(points, d => d[2]),
mmax = 1 + Math.floor(contrast * Math.log(max));
const groups = d3
.groups(dots, d => 1 + Math.floor(contrast * Math.log(value(...d))))
.sort((a, b) => d3.ascending(a[0], b[0]));
const g = svg.append("g").attr("id", "population");
for (const [b, pts] of groups) {
path.pointRadius(Math.pow((1.2 / mmax) * b, exp));
g.append("g")
.attr("id", `points${b}`)
.append("path")
.attr("fill", "#000")
.datum({ type: "MultiPoint", coordinates: pts })
.attr("d", path);
}
}
return svg.call(render).node();
}