active-geo
Maps for React - areas, point symbols and context geometry over geometry you supply, with a legend, a table, a menu and export, and an optional world collection.
@workspace/active-geo 0.4.0Developmentunreleased, in development in Foundationbaseline ce081dc3
@workspace/active-geo draws one component, GeoMap: typed layers of areas, point symbols (in
SVG or on a canvas) and context geometry, over geometry your application supplies, in a
projection you name. The default is a quiet map: the title, the map and its source line; navigation
appears on demand, a legend only when something needs explaining, and the family menu (right click,
long press, Shift+F10) carries copy, the table, navigation and export.
Countries coloured by a measureClient
Loading the map…
// apps/docs/examples/geo/world-map.tsx'use client';
import {useEffect, useState} from 'react';
import { englishGeoTranslator, GeoMap, type GeoAreaFeature,} from '@workspace/active-geo';import { loadWorld50m, world50m,} from '@workspace/active-geo/collections/world-50m';
// Invented values per country, joined by the collection's key (ADM0_A3).const SHARE: Record<string, number> = { NLD: 82, BEL: 64, DEU: 71, FRA: 55, GBR: 48, ESP: 39, ITA: 44, POL: 31, SWE: 77, NOR: 69, USA: 58, CAN: 62, BRA: 27, IND: 19, JPN: 66, AUS: 52,};
/** * The optional world collection (Natural Earth, 1:50m), loaded on demand, * coloured by a measure with a threshold scale. Hover or focus a country * for its value; the menu (right click, Shift+F10) holds the table and export. */export default function WorldMap() { const [features, setFeatures] = useState<GeoAreaFeature[] | null>(null); useEffect(() => { let current = true; void loadWorld50m().then((loaded) => { if (current) setFeatures([...loaded]); }); return () => { current = false; }; }, []); if (!features) { return <p className="text-muted-foreground text-sm">Loading the map…</p>; } return ( // The map takes the width of its container (a ResizeObserver); // in a centring layout the host gives it one. <div className="w-full"> <GeoMap title="Share of online orders" projection="equal-earth" locale="en-GB" t={englishGeoTranslator} attribution={world50m.attribution} layers={[ { type: 'area', id: 'countries', title: 'Countries', features, measures: [ { id: 'share', label: 'Online share', semantics: { kind: 'percent', source: 'percentage-points', preset: 'integer', }, }, ], data: Object.entries(SHARE).map(([key, share]) => ({ key, values: {share}, })), fill: { measure: 'share', scale: {type: 'threshold', thresholds: [30, 50, 70]}, }, }, ]} /> </div> );}The package is at version 0.4.0 with the P1 interface, still in development: workable, not yet stable, and not accepted as version 1. Later phases (symbols and shapes, line layers, continuous colour, clusters) are not available and are refused at run time with a clear error.
What it does#
- Layers: areas (
featureswith a key, a name and a polygon), points (latitude,longitude) and context geometry (outlines, rivers) that is drawn but never interactive. - Measures and encodings: values per object, a fill by a classed scale (threshold, quantize, category, diverging), a circle size by area; missing and withheld values have their own states.
- Around the map: header, legend, tooltip, labels, zoom and pan, selection, the accessible table, the menu, and export to PNG, SVG and CSV.
- Host composition: outlets for the legend and the table,
GeoMapScope, the host's own buttons.
What it does not do#
- No geography by default. The runtime entry carries no map data; the optional world collection is a separate entry that loads on demand.
- No tiles, no network. Nothing leaves your host: you pass the geometry.
- No language of its own. Words go through your translator (
t);englishGeoTranslatoris the package's English.
What your application provides#
- The geometry and the data, joined by key; the projection.
- A presentation (
locale) and a translator (t), per map or on<GeoDefaults>. - Optionally the
--geo-*colour tokens (the package reads your semantic tokens too, so on this site a map matches active-ui without a mapping), your ownButton,ToggleandInput. - The attribution of your geometry: for the world collection, Natural Earth's suggested credit.
Dependencies#
@workspace/active-format, @workspace/active-helpers and @workspace/active-virtual (owners that
come along), d3-geo, d3-scale, @base-ui/react, date-fns and @date-fns/tz. react and
react-dom 19 are peers.