Public
Edited
Nov 12, 2023
Insert cell
Insert cell
drawGraph([...generateOrthoDirected2(20000)], 1)
Insert cell
function drawGraph(points, cellSize = 1) {
const xmin = _.min(points.map((p) => p[0]));
const xmax = _.max(points.map((p) => p[0]));
const ymin = _.min(points.map((p) => p[1]));
const ymax = _.max(points.map((p) => p[1]));
const width = xmax - xmin + 1;
const height = ymax - ymin + 1;
// return [xmin, xmax, ymin, ymax, width, height];

const canvas = html`<canvas width="${width * cellSize}" height="${
height * cellSize
}"/>`;
const ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
for (const cell of points) {
ctx.fillRect(
cellSize * (-xmin + cell[0]),
cellSize * (height - (-ymin + cell[1])),
cellSize,
cellSize
);
}
return canvas;
}
Insert cell
function generateOrthoDirected2(limit) {
const base = [0, 0];
const included = new PointSet();
const choices = new PointSet();
choices.add(base);
for (let i = 0; i < limit; i++) {
const choice = randChoice([...choices]);
choices.remove(choice);
included.add(choice);
for (const nbr of getNeighbors(choice)) {
if (!included.has(nbr)) {
if (Math.random() > 0.3) {
choices.add(nbr);
}
}
}
}
return included;
}
Insert cell
function generateOrthoDirected(limit) {
const base = [0, 0];
const included = new PointSet();
included.add(base);
const choices = new PointSet();
choices.addAll(getNeighbors(base));
for (let i = 0; i < limit; i++) {
const choice = randChoice([...choices]);
choices.remove(choice);
included.add(choice);
for (const nbr of getNeighbors(choice)) {
if (!included.has(nbr)) {
choices.add(nbr);
}
}
}
return included;
}
Insert cell
function getNeighbors([x, y]) {
return [
[x + 1, y],
// [x - 1, y],
[x, y + 1]
// [x, y - 1]
];
}
Insert cell
class PointSet {
data;
size;

constructor() {
this.data = [];
this.size = 0;
}

add(p) {
if (!this.data[p[0]]) {
this.data[p[0]] = [];
}
this.data[p[0]][p[1]] = true;
this.size++;
}

remove(p) {
if (this.has(p)) {
delete this.data[p[0]][p[1]];
this.size--;
}
}

addAll(ps) {
for (const p of ps) {
this.add(p);
}
}

has(p) {
return !!this.data[p[0]]?.[p[1]];
}

*[Symbol.iterator]() {
for (let [x, ys] of Object.entries(this.data)) {
for (let y of Object.keys(ys)) {
yield [+x, +y];
}
}
}
}
Insert cell
function randChoice(items) {
return items[randRange(0, items.length)]
}
Insert cell
function randRange(min, max) {
return Math.floor(Math.random() * (max - min) + min)
}
Insert cell
_ = require('lodash')
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