Public
Edited
Apr 14, 2023
Insert cell
Insert cell
{
replay;

const context = DOM.context2d(n, n, 1);
const canvas = context.canvas;
const image = context.createImageData(n, n);
const {data} = image;
const array = new Uint32Array(n2);

canvas.style.maxWidth = "100%";
canvas.style.imageRendering = "pixelated";

function render(i) {
const xy = d2xy(i);
const [x, y] = xy;
const j = (y * n + x);
const {r, g, b} = color(array[i]);
data[(j << 2) + 0] = r;
data[(j << 2) + 1] = g;
data[(j << 2) + 2] = b;
data[(j << 2) + 3] = 255;
return xy;
}

for (let i = 0; i < n2; ++i) {
render(array[i] = i);
}

context.putImageData(image, 0, 0);

{
let i, j = array.length, t, x, y;
while (j) {
i = Math.random() * j-- | 0;
t = array[j], array[j] = array[i], array[i] = t;
([x, y] = render(i)), context.putImageData(image, 0, 0, x, y, 1, 1);
([x, y] = render(j)), context.putImageData(image, 0, 0, x, y, 1, 1);
if (j % 10 === 0) yield context.canvas;
}
}

return context.canvas;
}
Insert cell
Insert cell
color = i => d3.rgb(d3.interpolateRainbow(i / (n * n)))
Insert cell
function d2xy(d) {
let rx, ry, s, t = d;
let x = 0, y = 0;
for (s = 1; s < n; s <<= 1) {
rx = 1 & (t >> 1);
ry = 1 & (t ^ rx);
[x, y] = rot(s, x, y, rx, ry);
x += s * rx;
y += s * ry;
t >>= 2;
}
return [x, y];
}
Insert cell
function rot(n, x, y, rx, ry) {
if (!ry) {
if (rx) {
x = n - 1 - x;
y = n - 1 - y;
}
return [y, x];
}
return [x, y];
}
Insert cell
z = 9
Insert cell
n = Math.pow(2, z)
Insert cell
n2 = Math.pow(2, z * 2)
Insert cell
d3 = require("d3-color@1", "d3-scale-chromatic@1")
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