Public
Edited
Apr 4, 2023
1 star
Insert cell
Insert cell
{
const canvas = DOM.canvas(width, width);
const ctx = canvas.getContext("2d");
const x = d3.scaleLinear().domain(d3.extent(wider)).range([0, width]);
//return canvas;
let i = 0;
ctx.strokeStyle = "gray";
ctx.strokeWidth = 0.5;
for (const [a, b, d] of tree) {
ctx.beginPath();
ctx.moveTo(x(wider[a * 2]), x(wider[a * 2 + 1]));
ctx.lineTo(x(wider[b * 2]), x(wider[b * 2 + 1]));
ctx.stroke();
i++;
if (i % 100000 === 0) {
yield canvas;
}
}
function randcol() {
return Math.floor(Math.random() * 255);
}
ctx.globalAlpha = 1;
for (const cluster of clusters) {
if (Math.random() < 0.001) {
yield canvas;
}
ctx.fillStyle = `rgb(${randcol()},${randcol()},${randcol()})`;
// ctx.fillStyle = `red`;

for (const seed of cluster) {
const c = wider.slice(seed * 2, seed * 2 + 2).map((d) => x(d));
if (c.length === 2) {
ctx.fillRect(
...wider.slice(seed * 2, seed * 2 + 2).map((d) => x(d)),
1,
1
);
}
}
}

yield canvas;
}
Insert cell
clusters = {
const clusters = seeds.map((i) => [i]);
const is_set = new Array(wider.length / 2);
for (let seed of seeds) {
is_set[seed] = 1;
}
let thresh = 0.1;
for (let run of d3.range(350)) {
thresh += 0.005;
for (const cluster of clusters) {
const c = [...cluster];
for (const point of c) {
for (const [partner, dist] of edgelist[point]) {
if (dist < thresh && !is_set[partner]) {
cluster.push(partner);
is_set[partner] = 1;
}
}
}
}
// yield clusters;
}

yield clusters;
}
Insert cell
seeds = {
const seeds = [];
for (let i = 0; i < edgelist.length; i++) {
if (edgelist[i].length > 4) {
seeds.push(i);
}
if (Math.random() < 0.002) {
seeds.push(i);
}
// return edgelist.filter((d) => d.length > 3);
}
return seeds;
}
Insert cell
tree = {
const set = new Uint8Array(delaunay.points.length / 2);
const heap = new FlatQueue();
const tree = [];

// Initialize the heap with the outgoing edges of vertex zero.
set[0] = 1;
for (const i of delaunay.neighbors(0)) {
heap.push([0, i], distance2(0, i));
}

// For each remaining minimum edge in the heap…
let edge;
while ((edge = heap.pop())) {
const [i, j] = edge;

// If j is already connected, skip; otherwise add the new edge to point j.
if (set[j]) continue;
set[j] = 1;
tree.push([...edge, distance2(i, j)]);

// Add each unconnected neighbor k of point j to the heap.
for (const k of delaunay.neighbors(j)) {
if (set[k]) continue;
heap.push([j, k], distance2(j, k));
}
}
return tree;
}
Insert cell
edgelist = {
const edgelist = d3.range(wider.length / 2).map((d) => []);
for (let [a, b, dist] of tree) {
edgelist[a].push([b, dist]);
edgelist[b].push([a, dist]);
}
return edgelist;
}
Insert cell
function distance2(i, j) {
const dx = points[i * 2] - points[j * 2];
const dy = points[i * 2 + 1] - points[j * 2 + 1];
return dx * dx + dy * dy;
}
Insert cell
delaunay = new d3.Delaunay(wider)
Insert cell
wider = new Float32Array(rawpoints.map((d) => d.r))
Insert cell
points = wider
Insert cell
rawpoints = t.query("SELECT UNNEST([X_bert, Y_bert]) r FROM name LIMIT 800000")
Insert cell
t = DuckDBClient.of({ name: t1 })
Insert cell
ids = t.query("SELECT * FROM name LIMIT 2")
Insert cell
FlatQueue = require("flatqueue@1")
Insert cell
t1 = FileAttachment("t1.parquet")
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