Public
Edited
Jan 9, 2023
5 stars
Insert cell
Insert cell
Insert cell
ch_topo = await d3.json("https://unpkg.com/swiss-maps/2021-07/ch-combined.json")
Insert cell
Insert cell
Insert cell
Insert cell
map_width = Math.min(700, width)
Insert cell
height = (5 * map_width) / 7
Insert cell
Insert cell
Insert cell
Insert cell
Object.keys(ch_topo.objects)
Insert cell
Insert cell
Insert cell
arms_info = async (q_id) => {
const json = await d3.json(
`https://www.wikidata.org/wiki/Special:EntityData/${q_id}.json`
);
const wikimedia_url = (snak) => {
// The URL is based on the MD5 of the *filename* where spaces are underscores
const filename = snak.datavalue.value.replace(/ /g, "_");
const hash = md5(unescape(encodeURIComponent(filename)));
const root = "https://upload.wikimedia.org/wikipedia/commons/";
return root + `${hash[0]}/${hash.slice(0, 2)}/${filename}`;
};
const entity = json.entities[q_id];
return {
short: entity.claims.P395[0].mainsnak.datavalue.value,
arms: wikimedia_url(entity.claims.P94[0].mainsnak)
};
}
Insert cell
wikiCantons = {
// Wikidata for Switzerland
const q39 = await d3.json(
"https://www.wikidata.org/wiki/Special:EntityData/Q39.json"
);
// comes back to synchronous world
return Promise.all(
q39.entities.Q39.claims.P150.map((elt) =>
arms_info(elt.mainsnak.datavalue.value.id)
)
);
}
Insert cell
cantonArms = (elt) =>
wikiCantons.filter((x) => x.short === elt.properties.short)[0].arms
Insert cell
Insert cell
neighbors = topojson.neighbors(ch_topo.objects.cantons.geometries)
Insert cell
neighbors_indices_sorted = {
const neighbors_indices = neighbors.map((d, i) => ({ fid: i, v: d }));
return d3.sort(neighbors_indices, d => d.v.length);
}
Insert cell
Insert cell
Insert cell
display_label = (canton) =>
d3.geoArea(canton.geometry) > 2e-5 ||
d3.min(
cantons.map((elt, j) =>
canton.id !== elt.id && d3.geoCentroid(canton)[1] > d3.geoCentroid(elt)[1]
? d3.geoDistance(d3.geoCentroid(canton), d3.geoCentroid(elt))
: undefined
)
) > 4e-3
Insert cell
Insert cell
country = topojson.merge(ch_topo, ch_topo.objects.cantons.geometries)
Insert cell
Insert cell
orientation = (polygon_coords) => {
const algebraic_area = d3.sum(
polygon_coords.map(
(elt, i, array) =>
(elt[0] - array[(i > 0 ? i : array.length) - 1][0]) *
(elt[1] + array[(i > 0 ? i : array.length) - 1][1])
)
);
return Math.sign(algebraic_area);
}
Insert cell
country.coordinates[0].map(orientation)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Cantons in several components (exclaves)
topo_exclaves = ch_topo.objects.cantons.geometries
.filter((elt) => elt.type === "MultiPolygon")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
enclaves = ch_topo.objects.cantons.geometries
.filter((elt) => elt.type === "MultiPolygon")
.map((piece) =>
piece.arcs
.filter((elt) => elt.length > 1)
.flat()
.filter((elt, i) => i > 0)
.map(
(chunk) =>
new Object({
arc: chunk[0],
enclave: cantons[piece.id - 1]
})
)
)
.flat()
.map(
(elt) =>
ch_topo.objects.cantons.geometries
.map((piece, i) =>
piece.arcs.flat(2).includes(elt.arc > 0 ? -elt.arc - 1 : -elt.arc + 1)
? new Object({ ...elt, exclave: cantons[i] })
: undefined
)
.filter((elt) => elt)[0]
)
.map(
(elt) =>
ch_topo.objects.municipalities.geometries
.map((piece, i) =>
/*piece.arcs.flat(2).includes(elt.arc) ||*/
piece.arcs.flat(2).includes(elt.arc > 0 ? -elt.arc - 1 : -elt.arc + 1)
? new Object({ ...elt, municipality: municipalities[i] })
: undefined
)
.filter((elt) => elt)[0]
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { md5 } from "@elmisback/zero-import-md5-hash"
Insert cell
import { toc } from "@nebrius/indented-toc"
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