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:
1 parent
a64b78b673
commit
a4ca1f04d4
14 files changed
+612
-35
No files matched your search
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)),
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user