Public
Edited
Oct 4, 2023
Fork of Random Grid
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Hat tip to https://georgefrancis.dev/writing/crafting-organic-patterns-with-voronoi-tessellations/
getRandomGrid = (
width,
height,
step = 10,
amount = Math.round((width * height) / step ** 2),
rndseed = 1984,
pct
) => {
amount = amount >= 0 ? amount : Math.round((width * height) / step ** 2);
const rnd = almostRandom(rndseed);
const start = new Array(amount)
.fill(0)
.map(() => [rnd() * width, rnd() * height]);
const delaunay = Delaunay.from(start);
const voronoi = delaunay.voronoi([0, 0, width, height]);
const points = [];

for (let k = 0; k < relax; k++) {
for (let i = 0; i < delaunay.points.length; i += 2) {
const cell = voronoi.cellPolygon(i >> 1);

if (cell === null) continue;

const x0 = delaunay.points[i];
const y0 = delaunay.points[i + 1];

const [x1, y1] = polygonCentroid(cell);

delaunay.points[i] = x1;
delaunay.points[i + 1] = y1;
}

voronoi.update();
}
const count = (amount * pct * 2) / 100
const perc = ((amount * perceived * 2) / 100)
for (let i = 0; i < delaunay.points.length; i += 2) {
const fill = i < count ? c[0].green : c[0].yellow ;
const stroke = i > count && i < perc ? 'black' : 'none';
let classed;
switch(true) {
case (i < count):
classed = 'highlight'
break;
case (i >= count && i < perc):
classed = 'diff'
break;
default:
classed = 'other';
}
points.push([delaunay.points[i], delaunay.points[i + 1], fill, stroke, classed]);
}
return points;
}
Insert cell
c = [{
yellow: '#ebe46e',
lightyellow: '#f1ec9b',
ruby: '#ab354b',
green: '#00cdb1'
}]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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