{
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height])
.style("background", "lightblue");
const projection = d3
.geoAzimuthalEquidistant()
.rotate([0, 90, -30])
.scale(width * 0.6)
.translate([width * 0.5, height * 0.54]);
const path = d3.geoPath(projection);
svg
.append("path")
.datum(d3.geoGraticule10())
.attr("d", path)
.attr("fill", "none")
.attr("stroke-width", 0.25)
.attr("stroke", "white");
const tpath = DOM.uid("tpath");
svg
.append("path")
.datum(pf.filter((d, i) => i % 10 === 0).map(projection))
.attr("id", tpath.id)
.attr("d", d3.line().curve(d3.curveBasisClosed))
.attr("fill", "none")
.attr("stroke-width", 2)
.attr("stroke-dasharray", [7, 3])
.attr("stroke", "white");
svg
.append("text")
.attr("fill", "#fff")
.style("font-family", "sans-serif")
.style("font-size", `${(10 * width) / 928}px`)
.style("font-weight", "bold")
.style("letter-spacing", (3 * width) / 928)
.attr("text-anchor", "middle")
.attr("dy", -8)
.append("textPath")
.attr("xlink:href", tpath.href)
.text("ANTARCTIC CONVERGENCE")
.attr("startOffset", "50.5%");
svg
.append("path")
.datum(topojson.feature(world, world.objects.land))
.attr("d", path)
.attr("fill", "white");
const nodes = Array.from(data, (d, i) => ({
...d,
x: projection(bases.get(d.sitio))[0] + i / 100,
y: projection(bases.get(d.sitio))[1] - (i * i) / 1000
}));
d3.forceSimulation(nodes)
.force(
"x",
d3.forceX((d) => d.x)
)
.force(
"y",
d3.forceY((d) => d.y)
)
.force("collide", d3.forceCollide().radius(4))
.tick(10)
.stop();
svg
.append("g")
.selectAll()
.data(nodes)
.join("circle")
.attr("r", 4)
.attr("transform", (d) => `translate(${d.x},${d.y})`)
.attr("fill", (d) => color(d.nacionalidad))
.attr("d", path)
.append("title")
.text(
(d) => `${d["nombre y appellido"]}
${d["fecha"].toLocaleString("en-GB", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
timeZone: "UTC"
})}
${d.sitio}`
);
return svg.node();
}