Public
Edited
Sep 14, 2022
1 fork
6 stars
Insert cell
Insert cell
Insert cell
{
const svg = DOM.svg(width, 400);

const path = d3.geoPath();

d3.select(svg)
.selectAll()
.data(contours)
.join("path")
.attr("stroke", "#333")
.attr("fill", (d) => color(d.value))
.attr("d", (d) => path(project(d)));

return svg;
}
Insert cell
n = 100
Insert cell
m = 50
Insert cell
grid = {
const X = [];
const Y = [];
const Z = [];
for (let j = 0; j < m; ++j) {
const y = (j / (m - 1) - 0.5) * 3;
for (let i = 0; i < n; ++i) {
const x = (i / (n - 1) - 0.5) * 3;
X.push(2 + Math.cos(y) - Math.cos(x));
Y.push(2 + Math.sin(y) + Math.sin(x));
Z.push(Math.hypot(x, y));
}
}
return { X, Y, Z };
}
Insert cell
contours = d3.contours().size([n, m])(grid.Z)
Insert cell
Insert cell
projection = ([x, y]) => {
const x0 = clamp(Math.floor(x), 0, n - 1),
dx = x - x0;
const x1 = clamp(Math.ceil(x), 0, n - 1),
rx = dx / (x1 - x);
const y0 = clamp(Math.floor(y), 0, m - 1),
dy = y - y0;
const y1 = clamp(Math.ceil(y), 0, m - 1),
ry = dy / (y1 - y);

// bilinear interpolation
const qx = i(
i(grid.X[x0 + n * y0], grid.X[x1 + n * y0], rx),
i(grid.X[x0 + n * y1], grid.X[x1 + n * y1], rx),
ry
);
const qy = i(
i(grid.Y[x0 + n * y0], grid.Y[x0 + n * y1], ry),
i(grid.Y[x1 + n * y0], grid.Y[x1 + n * y1], ry),
rx
);

return [qx, qy];

// linear interpolation
function i(a, b, r) {
return a === b ? a : (a + b * r) / (r + 1);
}

function clamp(x, lo, hi) {
return x < lo ? lo : x > hi ? hi : x;
}
}
Insert cell
color = d3
.scaleSequential(d3.interpolateSpectral)
.domain(d3.extent(contours, (d) => d.value))
Insert cell
function project(d) {
d = {
...d,
coordinates: d.coordinates.map((poly) =>
poly.map((ring) =>
ring.map((d) => {
const e = projection(d);
const f = [(4 * d[0]) / n, (4 * d[1]) / m];
const i = d3.interpolate(f, e);
return i(alpha).map((d) => d * 100);
})
)
)
};
return d;
}
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