Public
Edited
Nov 29
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = Plot.plot({
width: 960,
height: 600,
projection: {
type: "azimuthal-equal-area",
rotate: [-13, -59],
domain: {
type: "MultiPoint",
coordinates: focus
}
},
color: {
scheme: "burd", // Change color scheme
unknown: "#ddd", // Polygons with unknown broadband values are gray
type: "linear", // Linear scale for color progression
legend: false, // Add the legend
label: "% change, 2019-2023 period", // Update legend label
percent: true // Convert value to a percent (from a proportion)
// domain: [0, 100] // Update the value domain to span 0 to 100% access
},
// color: {
// domain: sources,
// range: colors
// },
marks: [
Plot.sphere({ fill: "white" }),
Plot.geo(land),
Plot.graticule(),
Plot.geo(countries, {
stroke: "#333",
strokeWidth: 0.2,
fill: "#e1e1e1",
title: (d) => d.id
}),
// Plot.geo(countrymesh, { stroke: "#999", strokeWidth: 0.5 }),
Plot.geo(upper_zones, {
stroke: "#aaa",
strokeWidth: 0.5,
fill: (d) => d.properties.percentage_change,
fillOpacity: 0.5,
title: (d) =>
`${d.properties.name}\nchange 2022 vs 2019: ${d3.format("+0.1%")(
d.properties.percentage_change
)}`
}),
Plot.text(
// -6.174316,68.015798
[{ longitude: -18, latitude: 67.85, label: "Upper airspace" }],
{
// Add text to the map using data from us_power_plants
x: "longitude", // Place text horizontally at plant longitude
y: "latitude", // Place text vertically at plant latitude
text: "label", // The text that appears is the value from the Plant_Name column,
fontSize: 22, // Increased font size
fontWeight: 400, // Increased font weight
stroke: "white", // Adds white outer stroke to text (for readability)
fill: "black", // Text fill color
textAnchor: "start", // Left align text with the x- and y-coordinates
dx: 0 // Shifts text to the right (starting from left alignment with coordinate)
}
),
Plot.text(
upper_zones.features.filter(
(d) => d.properties.percentage_change !== undefined
),
{
x: (d) => d.properties.label_position[0], // longitude
y: (d) => d.properties.label_position[1], // latitude
text: (d) => d3.format("+0.0%")(d.properties.percentage_change),
title: (d) =>
`${d.properties.name}\nchange 2022 vs 2019: ${d3.format("+0.1%")(
d.properties.percentage_change
)}`,
textAnchor: "middle",
fontSize: 16,
stroke: "white",
fill: "black"
}
),

lower_airspace_inset(),
Plot.sphere({ stroke: "#aaa" })
]
})
Insert cell
height = width / 1.618
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
upper_zones = {
const zones = upper;

const subs = new Map(
submissions.map(({ id, percentage }) => [
+id,
{ percentage }
])
);

const labs = new Map(
ansp_labels.map(({ id, position }) => [+id, { position }])
);

for (const zone of zones.features) {
const v = subs.get(+zone.properties.id);
const l = labs.get(+zone.properties.id);
zone.properties.label_position = l ? l.position : undefined;
zone.properties.percentage_change = v ? v.percentage : undefined;
}

// filter out excluded zones
zones.features = zones.features.filter(
(d) => !excluded_zones.includes(d.properties.id)
);
return zones;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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