Public
Edited
Oct 26, 2023
1 fork
Importers
15 stars
Insert cell
Insert cell
canvas = {
const context = DOM.context2d(width, height);
const path = d3.geoPath(projection, context);
projection.preclip(d3.geoClipAntimeridian);
context.beginPath(), path(land), context.fillStyle = "#ddd", context.fill();
context.beginPath(), path(viewport), context.strokeStyle = "#f00", context.stroke();
projection.preclip(clipPolygon);
context.beginPath(), path(land), context.strokeStyle = "#000", context.stroke();
return context.canvas;
}
Insert cell
clipPolygon = d3.geoClipPolygon({
type: "Polygon",
coordinates: [viewport.coordinates[0].map(d3.geoRotation(projection.rotate()))]
})
Insert cell
viewport = {
const n = 10; // precision
const p = 40; // padding
return {
type: "Polygon",
coordinates: [
[
...Array.from({length: n}, (_, t) => [p + (width - p * 2) * t / n, p]),
...Array.from({length: n}, (_, t) => [width - p, (height - p * 2) * t / n + p]),
...Array.from({length: n}, (_, t) => [p + (width - p * 2) * (n - t) / n, height - p]),
...Array.from({length: n}, (_, t) => [p, (height - p * 2) * (n - t) / n + p]),
[p, p]
].map(p => projection.invert(p))
]
};
}
Insert cell
projection = d3.geoBonne()
.parallel(52)
.rotate([-20, 0])
.center([0, 52])
.translate([width / 2, height / 2])
.scale(width)
Insert cell
height = Math.min(640, width)
Insert cell
land = topojson.feature(world, world.objects.land)
Insert cell
world = FileAttachment("land-50m.json").json()
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3-geo@3", "d3-geo-polygon@1", "d3-geo-projection@4")
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