Public
Edited
Mar 31, 2024
1 fork
Importers
57 stars
Chandrupatla’s root-finding methodSidi’s root-finding methodRegular numbersDruidJS workerNatural breaksDistance to a segmentRay out of a convex hullWord Tour: 40k words and their friendsHello, @thi.ng/grid-iteratorsHead/tail breaksPseudo-blue noise shaderHow fast does walk-on-spheres converge?AoC 12: shortest path under constraintsKDE estimationPlot: Correlation heatmapPoisson Finish 2Poisson disk sampling functionsWoS with transportSimple and surprising sortLocal medianTime series topological subsamplingUnion-FindLevel set experiment 1Mean value coordinatesPoisson potentialMiddle-squareWorld of squares (spherical)World of squaresLargest Inscribed SquareHello, PyWaveletsGeothmetic meandianHello, Reorder.jsGeometric MedianImage FFTTransport to a mapDisc TransportTP3: Power Diagram and Semi-Discrete Optimal TransportThe blue waveHello, genetic-jsSliced Optimal TransportDruidJSSelf-Organizing Maps meet DelaunayHello, polygon-clippingseedrandom, minimalWalk on Spheres 2Walk on SpheresHello, AutoencoderKaprekar’s numberVoronoiMap2DHello, ccwt.jsPolygon TriangulationQuantile.invert?Linear congruential generatorHue blurNeedle in a haystackMoving average blurApollo 11 implementation of trigonometric functions, by Margaret H. Hamilton (march 1969)2D curves intersectionThe 2D approximate Newton-Raphson methodInverting Lee’s Tetrahedral projectionLinde–Buzo–Gray stipplingMean shift clustering with kd-tree2D point distributionsShortest pathKahan SummationHello, delatinDijkstra’s algorithm in gpu.jsLloyd’s relaxation on a graphManhattan DiameterManhattan VoronoiMobility landscapes — an introductionDijkstra’s shortest-path treeH3 odditiesProtein MatrixConvex Spectral WeightsSort stuff by similarityKrigingDelaunay.findTrianglen-dimensions binning?Travelling with a self-organizing mapUMAP-o-MaticMNIST & UMAP-jsHello UMAP-jsMean shift clusteringLevenshtein transitionRd quasi-random sequencesAutomated label placement (countries)Phyllotaxis explainedMotionrugsPlanar hull (Andrew’s monotone chain algorithm)South Africa’s medial axisTravelling salesperson approximation with t-SNEDistance to shore
Worker
ngraph: pagerank, louvain…t-SNE VoronoiCloud ContoursCircular function drawingKruskal MazeMyceliumTravelling salesperson approximation on the globe, with t-SNEtsne.jstsne.js & worker
Also listed in…
Meta
Hello
Insert cell
Insert cell
// read results as they are arriving
Generators.queue(worker(blah, 100))
Insert cell
// don't pause between yields
Generators.observe(worker(blah, 100000))
Insert cell
// pass several named arguments
Generators.queue(worker(who, { n: 100, k: 21 }))
Insert cell
// retrieve a simple result
Generators.queue(worker(meh))
Insert cell
// anonymous function
Generators.queue(worker(() => "foo"))
Insert cell
// async function
observeWorker`return await fetch("https://d3js.org/").then(d => d.text()).then(text => text.length);`
Insert cell
webWorker = (method) =>
function (f, ...vars) {
let t = f[0];
const args = {};
for (let i = 0; i < vars.length; i++) {
t = `${t}${
typeof vars[i] === "function"
? function_stringify(vars[i])
: ((args[`a${i}`] = vars[i]), `data.a${i}`)
}${f[i + 1]}`;
}
// auto-detect async functions
const _async = t.match(/\b(await|async)\b/) ? "async " : "";

return Generators[method](
worker(
{
toString: () => `${_async}function main(data) {\n${t}\n;;;\n}`,
name: "main"
},
args
)
);
}
Insert cell
queueWorker = webWorker("queue")
Insert cell
observeWorker = webWorker("observe")
Insert cell
worker = function (f, e, preamble, transferList) {
const b = new Blob([workertext(f, preamble)], { type: "text/javascript" });
return function (notify) {
const url = URL.createObjectURL(b);
const worker = new Worker(url); // TODO: add an option for { type: "module" } if we want to import modules; but then importScript does not work
worker.addEventListener("message", (r) => notify(r.data));
worker.postMessage(e, transferList);
return () => {
worker.terminate();
URL.revokeObjectURL(url);
};
};
}
Insert cell
// just like Observable, we don't want to iterate on arrays
// so we check if our iterator has a method .next()
function workertext(f, preamble = "") {
return `
${preamble}

function isIterable(obj) {
return (
typeof obj[Symbol.iterator] === "function" &&
typeof obj["next"] == "function"
);
}

const __run__ = ${typeof f === "function" ? function_stringify(f) : f};

self.onmessage = async function(e) {
const t0 = performance.now();
let result = await __run__(e.data);
if (typeof result !== "undefined") {
if (!isIterable(result)) result = [result];
for (const p of result) {
postMessage(typeof p !== "object" ? p : Object.assign(p, {_time: performance.now() - t0}));
}
close();
}

}`;
}
Insert cell
// On iOS, [generator].toString() doesn't give "function*" but "function". Fix this.
function function_stringify(f) {
let g = f.toString();
if (f.prototype && f.prototype.toString() === "[object Generator]")
g = g.replace(/function\*?/, "function*");
return g;
}
Insert cell
function* blah(n) {
let sum = 0;
while (n-- > 0) yield (sum += n);
}
Insert cell
function* who({ n, k }) {
let sum = 0;
while (n-- > 0) yield k * (sum += n);
}
Insert cell
function meh() {
let sum = 0,
n = 100;
while (n-- > 0) {
sum += n;
}
return sum;
}
Insert cell
Insert cell
Generators.queue(worker(d => d ** 2, 10))
Insert cell
Insert cell
Generators.queue(
worker(
delaunay,
[0, 0, 1, 2.1, 4, 3],
`
importScripts("https://unpkg.com/d3-delaunay");
const de = d3;
`
)
)
Insert cell
function delaunay(data) {
return new de.Delaunay(Float32Array.from(data));
}
Insert cell
// a fake `de` that we don't use in the main thread, but avoids a runtime error with the function
de = "🤯"
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more