Maps · World: choropleths and the world's countries

ChoroplethLayer washes each area by its value, keyed by its id or a
property's text or number, on one hue's scale from its faintest at the
least value to its strongest at the most; an area without a value reads
as no data. ChoroplethMap lays it on the owner's map, with or without
tiles, and puts a legend of the scale and of no data in the corner; a
value that matches no area is logged once. WorldMap washes Natural
Earth's 110m countries, bundled trimmed by scripts/countries.py, by ISO
3166 alpha-2 code, and fails on a key that is no code. A shape now
paints as one fill and one edge path per world in view.
This commit is contained in:
ZacharyZhang-NY committed 2026-09-27 23:12:27 -04:00
1 parent a64b78b673
commit a4ca1f04d4
14 files changed
+612 -35

No files matched your search

+1 -1
View File
@@ -214,7 +214,7 @@ pub fn stream(_: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
),
];
section(
"EventStream · LogStream → terminal::LogViewer · TraceWaterfall → debug::TimelineProfiler · SystemMonitor → devtools::ResourceMonitor · ProcessTable → terminal::ProcessList · NetworkGraph (throughput) → charts::RealtimeChart · MapView / GeoHeatmap → maps::MapView, maps::GeoHeatmap · WorldMap → maps (T41c)",
"EventStream · LogStream → terminal::LogViewer · TraceWaterfall → debug::TimelineProfiler · SystemMonitor → devtools::ResourceMonitor · ProcessTable → terminal::ProcessList · NetworkGraph (throughput) → charts::RealtimeChart · MapView / GeoHeatmap → maps::MapView, maps::GeoHeatmap · WorldMap → maps::WorldMap",
"Events as they come, newest first, kept by kind, with Pause to hold the list while new ones count up. Logs, traces, a machine's readings, its processes and live throughput have their homes in the terminal, agent, dev tools and charts chapters; the maps live in the maps chapter.",
cx,
)
+3 -1
View File
@@ -12,6 +12,7 @@ use gpui::{
};
mod layers;
mod world;
use super::Page;
use crate::probe::probe;
@@ -22,7 +23,7 @@ pub const PAGE: Page = Page {
number: 41,
slug: "maps",
title: "Maps",
summary: "Tiles the host supplies, pins with a popup, a picker's crosshair, routes, GeoJSON, heat and clusters. The land is Natural Earth's.",
summary: "Tiles the host supplies, pins with a popup, a picker's crosshair, routes, GeoJSON, heat, clusters and choropleths. The land is Natural Earth's.",
render,
script: &[
Step::Click("world-map"),
@@ -72,6 +73,7 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement {
.child(layers::routes(cx))
.child(layers::heat(cx))
.child(layers::clusters(cx))
.child(world::world(cx))
.into_any_element()
}
+76
View File
@@ -0,0 +1,76 @@
use ely_gpui_component::maps::{
ChoroplethLayer, ChoroplethMap, LatLon, MapView, MapViewport, WorldMap, read_geojson,
};
use gpui::{App, IntoElement, ParentElement, Styled, div, px};
use super::{ATTRIBUTION, tile};
use crate::ui::section;
const VISITORS: [(&str, f64); 20] = [
("US", 120_400.0),
("IN", 51_300.0),
("GB", 45_100.0),
("DE", 38_200.0),
("JP", 30_800.0),
("FR", 26_400.0),
("BR", 22_100.0),
("CA", 18_300.0),
("AU", 14_700.0),
("ES", 13_200.0),
("CN", 12_600.0),
("IT", 12_100.0),
("KR", 11_400.0),
("MX", 9_100.0),
("SG", 8_300.0),
("RU", 7_200.0),
("AR", 6_300.0),
("ZA", 5_400.0),
("EG", 4_100.0),
("NG", 3_200.0),
];
const REGIONS: &str = r#"{"type": "FeatureCollection", "features": [
{"type": "Feature", "properties": {"region": "west"},
"geometry": {"type": "Polygon", "coordinates": [[[-9, 36], [3, 36], [3, 43.5], [-9, 43.5], [-9, 36]]]}},
{"type": "Feature", "properties": {"region": "middle"},
"geometry": {"type": "Polygon", "coordinates": [[[-4, 43.5], [8, 43.5], [8, 51], [-4, 51], [-4, 43.5]]]}},
{"type": "Feature", "properties": {"region": "south"},
"geometry": {"type": "Polygon", "coordinates": [[[7, 37], [18, 37], [18, 46], [7, 46], [7, 37]]]}},
{"type": "Feature", "properties": {"region": "north"},
"geometry": {"type": "Polygon", "coordinates": [[[5, 55], [15, 55], [15, 60], [5, 60], [5, 55]]]}}
]}"#;
pub fn world(cx: &App) -> impl IntoElement + use<> {
let regions = read_geojson(REGIONS).expect("the demo's regions read");
let rainfall = ChoroplethLayer::new(
regions,
[("west", 540.0), ("middle", 810.0), ("south", 700.0)],
)
.key_by("region")
.hue(1);
let over = MapView::new("rain-map", MapViewport::new(LatLon::new(46.0, 5.0), 3.2))
.tiles(tile)
.tile_zooms(0, 3)
.attribution(ATTRIBUTION);
let visits = MapView::new(
"world-visits",
MapViewport::new(LatLon::new(25.0, 10.0), 1.4),
);
section(
"ChoroplethMap · WorldMap",
"Areas washed by value on one hue's scale, with a legend; an area without a value reads as no data. WorldMap washes Natural Earth's countries by ISO code: Singapore, too small at this scale, draws nowhere and is logged once.",
cx,
)
.child(
div()
.w(px(720.0))
.h(px(360.0))
.child(WorldMap::new("world-visits", visits, VISITORS).hue(0)),
)
.child(
div()
.w(px(480.0))
.h(px(320.0))
.child(ChoroplethMap::new("rain", over, rainfall)),
)
}