Public
Edited
Apr 22
Paused
3 forks
Importers
36 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
width,
height: useProjection ? width : width * 0.7,
inset: useProjection ? 0 : 20,
projection: useProjection ? { type: "mercator" } : undefined,
marks: [
useProjection ? Plot.sphere() : Plot.frame(),
showVoronoi
? Plot.voronoiMesh(airports, { x: "longitude", y: "latitude" })
: null,
Plot.arrow(
airports,
maybeVoronoiCentroids({
x1: "longitude",
y1: "latitude",
x2: "longitude",
y2: "latitude",
stroke: "black",
strokeWidth: 0.7,
bend: true,
headLength: 0
})
),
Plot.dot(airports, {
x: "longitude",
y: "latitude",
r: 1.5,
fill: "black"
}),
Plot.text(
airports,
maybeVoronoiCentroids({
x: "longitude",
y: "latitude",
text: (d) => d.name.split(/ /)[0],
stroke: "white",
strokeWidth: 7,
fill: "black"
})
)
]
})
Insert cell
Insert cell
voronoiCentroids = (options) =>
Plot.initializer(
options,
function (
data,
facets,
{ x: X0, y: Y0, x2: X = X0, y2: Y = Y0 },
{ x, y },
{ width, height, marginLeft, marginRight, marginTop, marginBottom },
{ projection }
) {
const n = X.value.length;
const P = new Float64Array(2 * n).fill(NaN);
let i;
if (projection) {
const stream = projection.stream({
point(x, y) {
P[2 * i] = x;
P[2 * i + 1] = y;
}
});
for (i = 0; i < n; ++i) stream.point(X.value[i], Y.value[i]);
} else {
for (i = 0; i < n; ++i) P[2 * i] = x ? x(X.value[i]) : X.value[i];
for (i = 0; i < n; ++i) P[2 * i + 1] = y ? y(Y.value[i]) : Y.value[i];
}

for (const I of facets) {
const v = new d3.Delaunay(P).voronoi([
marginLeft,
marginTop,
width - marginRight,
height - marginBottom
]);
for (const [i, k] of I.entries())
[X.value[i], Y.value[i]] = d3.polygonCentroid(v.cellPolygon(k) ?? []);
}
delete X.scale;
delete Y.scale;
return { data, facets };
}
)
Insert cell
maybeVoronoiCentroids = activate ? voronoiCentroids : (options) => options
Insert cell
Insert cell
airports = FileAttachment("airports.csv")
.csv({ typed: true })
.then((data) => data.filter((d, i) => i % 20 === 0))
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