Public
Edited
Dec 27, 2022
2 forks
1 star
Insert cell
Insert cell
Insert cell
viewof year = Inputs.radio(["10", "20"], { value: "20" })
Insert cell
<div id="plot" style="min-width:${width}px;min-height:${width * .75}px"></div>
Insert cell
random_points_ = tf.randomPoints(
triangulated,
["Hsp_20", "WNH_20", "BNH_20", "ANH_20", "ONH_20", "NH2pl_20"]
.map((p) => [p.replace("20", "10"), p])
.flat(),
100,
["BoroName"],
["category", "year"],
"_"
)
Insert cell
chunked = {
const ts = [];
const step = 65000;
for (let i = 0; i < random_points.numRows; i += step) {
ts.push(...random_points.slice(i, i + step).batches);
}
return new arrow.Table(ts);
}
Insert cell
random_points = new arrow.tableFromArrays({
x: random_points_.getChild("x").toArray(),
y: random_points_.getChild("y").toArray(),
boro: random_points_.getChild("BoroName").toArray(),
category: random_points_.getChild("category").toArray(),
year: random_points_.getChild("year").toArray(),
ix: new Float32Array(d3.range(random_points_.numRows))
})
Insert cell
random_points_.getChild("category")
Insert cell
//nuts_rg_60m_2021_4326 = FileAttachment("NUTS_RG_60M_2021_4326.geojson").json()
Insert cell
Deepscatter = import("https://benschmidt.org/deepscatter@2.6.2.js").then(
(d) => d.default
)
Insert cell
arrow = require("apache-arrow@10.0.1")
Insert cell
{
year;
console.log("replotting");
return plot.plotAPI({
encoding: {
color: {
field: colorize,
domain: [-2047, 2047],
range: "dark2"
},
filter: { field: "year", lambda: `d => d === '${year}'` }
}
});
}
Insert cell
plot = {
console.log("Creating deepscatter");
const plot = new Deepscatter("#plot", 900, 600);
await plot.plotAPI({
arrow_table: chunked,
point_size: 3,
max_points: 1e6,
zoom_balance: 0.75,
alpha: 70,
background_color: "#FFFAF2",
encoding: {
x: {
field: "x",
transform: "literal"
},
y: {
field: "y",
transform: "literal"
}
}
});

invalidation.then(() => plot.destroy());
return plot;
}
Insert cell
triangulated = tf.TriFeather.from_feature_collection(tracts, projection)
Insert cell
tracts
Insert cell
tf = import("https://benschmidt.org/trifeather@1.3.0.js")
Insert cell
/*delaunay = {
const points = [...random_points].map((d) => [d.x, d.y]).flat();
const delaunay = new d3.Delaunay(points);
return delaunay;
}*/
Insert cell
NYC = fetch(
"https://services5.arcgis.com/GfwWNkhOj9bNBqoJ/arcgis/rest/services/NYC_Census_Tracts_for_2020_US_Census/FeatureServer/0/query?where=1=1&outFields=*&outSR=4326&f=pgeojson"
).then((d) => d.json())
Insert cell
tracts = {
const lookups = d3.group(andChangeTable1, (d) => "" + d.GeoID);
const supplemented = [];
for (let feature of NYC.features) {
const { properties } = feature;
const matched = lookups.get(properties.GEOID);
if (matched !== undefined) {
let census_data = matched[0];
census_data = Object.fromEntries(
Object.entries(census_data).map(([k, v]) => [
k,
// Strip out commas. Ugh
k == "GeoID" ? "" + v : v && v.replace ? +v.replace(",", "") : v
])
);
feature.properties = { ...feature.properties, ...census_data };
supplemented.push(feature);
}
// return properties.GEOID;
}
return {
type: "FeatureCollection",
features: supplemented
};
}
Insert cell
2010, 2020, and Change-Table 1.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
tree = {
// https://observablehq.com/@mbostock/minimum-spanning-tree minus the visualization

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);

// 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
function renderEdges(edges, context, points) {
for (const [i, j] of edges) {
context.moveTo(points[i * 2], points[i * 2 + 1]);
context.lineTo(points[j * 2], points[j * 2 + 1]);
}
}
Insert cell
Insert cell
import { dot_density } from "@bmschmidt/dot-density"
Insert cell
import { usStateFeatures } from "@karimdouieb/us-house-election-2022"
Insert cell
projection = d3.geoMercator().fitSize([width * 0.8, width * 0.5], tracts)
Insert cell
import { distance2, FlatQueue } from "@mbostock/minimum-spanning-tree"
Insert cell
geo = require("d3-geo-projection")
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

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