Public
Edited
Dec 22, 2022
Insert cell
Insert cell
Insert cell
<div id="plot" style="min-width:${width}px;min-height:${width * .75}px"></div>
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
Insert cell
preserved = ["nationality", "gender", "CNTR_CODE", "immigrant"]
Insert cell
nuts_geojson = {
const nuts_geojson = await FileAttachment(
"NUTS_RG_20M_2006_4326.geojson"
).json();

for (let feature of nuts_geojson.features) {
if (feature.properties.LEVL_CODE != "3") {
continue;
}
if (lookup.get(feature.properties.NUTS_ID)) {
feature.properties = {
...feature.properties,
...lookup.get(feature.properties.NUTS_ID)
};
}
}
return nuts_geojson;
}
Insert cell
random_points_ = tf.randomPoints(
triangulated,
gender_cols,
500,
preserved,
["gender", "nationality", "immigrant"],
"_"
)
Insert cell
gender_cols = triangulated.t.schema.fields
.map((d) => d.name)
.filter((d) => d.match(/^[MF]_/))
Insert cell
random_points.numRows
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(),
...Object.fromEntries(
preserved.map((d) => [d, random_points_.getChild(d).toArray()])
),
gender: random_points_.getChild("gender").toArray(),
nationality: random_points_.getChild("nationality").toArray(),
ix: new Float32Array(d3.range(random_points_.numRows))
})
Insert cell
random_points_.getChild("nationality")
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
plot.plotAPI({
duration: 10,
point_size
})
Insert cell
plot.plotAPI({
duration: 750,
encoding: {
jitter_radius: {
method: "time",
constant: 1
},
jitter_speed: {
constant: 13
},
color: {
field: colorize,
domain: [-2047, 2047],
range: "dark2"
}
}
})
Insert cell
plot = {
const plot = new Deepscatter("#plot", 900, 600);
await plot.plotAPI({
arrow_table: chunked,
point_size: 2,
max_points: 1e6,
zoom_balance: 0.55,
alpha: 70,
background_color: "#FFFAF2",
encoding: {
x: {
field: "x",
transform: "literal"
},
y: {
field: "y",
transform: "literal"
}
}
});

invalidation.then(() => plot.destroy());
return plot;
}
Insert cell
nuts_geojson.features
.filter(
(d) => d.properties.CNTR_CODE == "DE" && d.properties.LEVL_CODE == "3"
)
.map((d) => d.id)
Insert cell
triangulated = tf.TriFeather.from_feature_collection(nuts_geojson, projection)
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
2010, 2020, and Change-Table 1.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
projection = d3.geoMercator().fitSize([width * 0.8, width * 0.5], nuts_geojson)
Insert cell
geo = require("d3-geo-projection")
Insert cell
lookup = {
// These are general terms that will also be represented more specifically.
const blocklist = new Set([
"AME",
"EU",
"EU-FOR",
"TOTAL",
"EUR",
"AFR",
"ASI"
]);
const rolled = d3.rollup(
await FileAttachment("estat_cens_01rsctz_en.csv").csv(),
(vs) => collapse(vs),
(k) => k.geo
);

function collapse(vs) {
const output = {};
for (let [k, v] of Object.entries(vs)) {
if (v.sex === "T" || blocklist.has(v.citizen)) {
continue;
}
// Actually use the name of the country.
const country = v.geo.slice(0, 2);
if (v.citizen === "NAT") {
if (country == "NL") {
// Netherlands is double-counted for some reason.
continue;
} else {
v.citizen = country;
}
}
const immigrant = v.citizen === country ? "local" : "immigrant";
const m = `${v.sex}_${v.citizen.replaceAll("_", "-")}_${immigrant}`;
output[m] = +v.OBS_VALUE;
}

return output;
}
return rolled;
}
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
estat_cens_01rsctz_en.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

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