Published
Edited
Sep 27, 2019
12 stars
Hello, A5Chandrupatla’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.js
Lloyd’s relaxation on a graph
Manhattan 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 shoreWorkerngraph: pagerank, louvain…t-SNE VoronoiCloud ContoursCircular function drawingKruskal MazeMyceliumTravelling salesperson approximation on the globe, with t-SNEtsne.jstsne.js & worker
Also listed in…
Voronoi
Graphs
Insert cell
Insert cell
Insert cell
Insert cell
origins = {
const n = nodes.length,
origins = Array.from({ length }, () => (Math.random() * n) | 0);

yield origins;

// forbid backtracking: a point cannot go back to any of its previous two positions
const prev0 = origins.slice(),
prev1 = origins.slice();

// check if we repeat ourselves
let last = origins.slice();

for (let t = 0; t < 1000; t++) {
const tree = shortest_tree({ graph, origins }).next().value;
const weights = Uint32Array.from(tree.predecessor).fill(0);

function branch_length(i) {
if (weights[i]) return weights[i];
const j = tree.predecessor[i];
if (j > -1) {
return (weights[i] = branch_length(j) + 1);
}
return 0;
}

for (let j = 0; j < n; j++) {
if (tree.origin[j] == -1) continue;
branch_length(j);
}

for (let k = 0; k < origins.length; k++) {
const i = origins[k];
let best = -1,
value = 0;
for (let j = 0; j < n; j++) {
if (tree.origin[j] === i && weights[j] > value) {
value = weights[j];
best = j;
}
}
if (best > -1) {
while (
tree.predecessor[best] !== -1 &&
tree.predecessor[tree.predecessor[best]] !== -1
)
best = tree.predecessor[best];
if (best !== prev0[k] && best !== prev1[k]) {
prev1[k] = prev0[k];
prev0[k] = origins[k];
origins[k] = best;
}
}
}

if (last.toString() == origins.toString()) break;
last = origins.slice();

yield origins;
}
}
Insert cell
function map(anchor) {
const context = DOM.context2d(width, height),
path = d3.geoPath().context(context);

// underlying graph
context.beginPath();
for (let k = 0; k < graph.sources.length; k++) {
const i = graph.sources[k],
j = graph.targets[k];
if (i < j) {
context.moveTo(...pts[i]);
context.lineTo(...pts[j]);
}
}
context.strokeStyle = "#ccc";
context.lineWidth = 1;
context.stroke();

// the trees
context.lineWidth = 2;
for (const k of origins) {
context.beginPath();
context.strokeStyle = color(origins.indexOf(k));
for (let i = 0; i < pts.length; i++) {
const j = tree.predecessor[i];
if (j > -1 && tree.origin[j] === k) {
context.moveTo(...pts[i]);
context.lineTo(...pts[j]);
}
}
context.stroke();
}

path.pointRadius(6);
for (const k of origins.filter(i => i < pts.length)) {
context.beginPath();
path({
type: "Point",
coordinates: pts[k]
});
context.fillStyle = color(origins.indexOf(k));
context.strokeStyle = "white";
context.fill();
context.stroke();
}

return context.canvas;
}
Insert cell
Insert cell
Insert cell
Insert cell
src = "https://gist.githubusercontent.com/Fil/450db51a15fdc8bd34a12cb8a9961976/raw/680961da57d2b11a0e3e6993e5f79bd035729831"
Insert cell
nodes = d3.csv(`${src}/node_list.csv`, d3.autoType)
Insert cell
edges = d3.csv(`${src}/edge_list.csv`, d3.autoType)
Insert cell
Insert cell
nodesIndex = new Map(nodes.map((d, i) => [d.osmid, i]))
Insert cell
function createGraph(nodesIndex, edges) {
const graph = { sources: [], targets: [], costs: [] };
edges.forEach(({ u, v, length }) => {
const i = nodesIndex.get(u),
j = nodesIndex.get(v),
cost = length;
graph.sources.push(i);
graph.targets.push(j);
graph.costs.push(cost);

graph.sources.push(j);
graph.targets.push(i);
graph.costs.push(cost);
});

return graph;
}
Insert cell
graph = createGraph(nodesIndex, edges)
Insert cell
import { shortest_tree } from "@fil/dijkstra"
Insert cell
tree = shortest_tree({ graph, origins })
Insert cell
Insert cell
pts = nodes.map(d => projection([d.x, d.y]))
Insert cell
projection = d3.geoMercator().fitExtent([[10, 10], [width - 10, height - 10]], {
type: "MultiPoint",
coordinates: nodes.map(d => [d.x, d.y])
})
Insert cell
Insert cell
color = d3.scaleOrdinal(d3.schemeCategory10)
Insert cell
Insert cell
d3 = require("d3@5", "d3-tricontour@0.1", "d3-hexbin@0.2")
Insert cell
import { checkbox, slider } from "@jashkenas/inputs"
Insert cell
height = width * 0.9
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