Public
Edited
Sep 15, 2022
38 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// dataset organized by the TTT (Tribute to Tobler) project
data = d3.json("https://raw.githubusercontent.com/tributetotobler/ttt/main/data/dollars.json")
Insert cell
// compute the balance of dollar bills as the difference between
// the sum of the rows and the sum of the columns of the OD matrix
balance = d3
.zip(
d3.transpose(data.OD).map((out) => d3.sum(out)),
data.OD.map((out) => d3.sum(out))
)
.map(([p, m]) => m - p)
Insert cell
// The balance of each region is spread out uniformly on all the points that belong to the regions
// Select "charge" to display this vector of values on the map; NaN for points that don't participate.
values = {
const V = new Float64Array(points.length).fill(NaN);
for (let i = 0; i < points.length; i++) {
for (let p = 0; p < data.polygones.length; p++) {
const poly = data.polygones[p].geom.coordinates[0];
if (d3.polygonContains(poly, pts[i])) {
V[i] = p;
break;
}
}
}

d3.rollup(
d3.range(V.length),
(I) => I.forEach((i) => (V[i] = balance[V[i]] / I.length)),
(i) => V[i]
);

return V;
}
Insert cell
// see this notebook for a graph-based solution to the Poisson equation,
// which returns the potential and shows the map
import { chart, viewof blurRadius } with {
viewof display,
points,
values as C
} from "@fil/poisson-potential"
Insert cell
// This projection transforms Tobler's geojson to screen coordinates
projection = d3
.geoIdentity()
.reflectY(true)
.fitExtent(
[
[2, 32],
[width - 2, height - 2]
],
{
type: "GeometryCollection",
geometries: data.polygones.map((d) => d.geom)
}
)
Insert cell
import { pick2d } from "@fil/2d-point-distributions"
Insert cell
W = 72 // width of the original space
Insert cell
H = 46 // height of the original space
Insert cell
// a point distribution in Tobler’s original space
pts = [...pick2d(W, H, npoints, distributionType)]
Insert cell
points = pts.map(projection)
Insert cell
height = 550
Insert cell
topojson = require("topojson@3")
Insert cell
border = {
const topo = topojson.topology({
regions: {
type: "GeometryCollection",
geometries: data.polygones.map((d) => d.geom)
}
});
return topojson.merge(topo, topo.objects.regions.geometries);
}
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