subject-mapper
v0.1.0
Published
A generic choropleth map viewer for the browser
Maintainers
Readme
Subject Mapper
A lightweight choropleth map viewer for the browser. Accepts data from any source and renders an interactive map with a dimension selector, animation, zoom, and theming.
Installation
npm install subject-mapperPeer dependencies — install these alongside subject-mapper:
npm install d3 topojson-client @observablehq/plotUsage
import 'subject-mapper/style';
import { createMap } from 'subject-mapper';
import { fetchWorldBank, worldBankUrl } from 'subject-mapper/worldbank';
const INDICATOR = 'AG.LND.FRST.ZS';
const data = await fetchWorldBank(INDICATOR);
createMap(document.getElementById('app'), {
data,
topoUrl: '/topojson/world/countries.json',
topoObject: 'units',
title: 'Forest Area',
emoji: '🌳',
subtitle: `${INDICATOR} · % of land area`,
unit: '% of land area',
colorScheme: 'Greens',
sourceUrl: worldBankUrl(INDICATOR),
sourceLabel: `data.worldbank.org/indicator/${INDICATOR}`,
});Add this to your page CSS:
#app { width: 100%; height: 100dvh; }Data format
createMap accepts any data source as long as rows conform to:
{ id: string, value: number, dimension: string | null }id— matches the topojson feature idvalue— the numeric value to displaydimension— the value the selector steps through (year, category, etc.). Passnullfor a static map with no selector.
Data helpers
World Bank
import { fetchWorldBank, worldBankUrl } from 'subject-mapper/worldbank';
const data = await fetchWorldBank('AG.LND.FRST.ZS');CSV
import { fetchCSV } from 'subject-mapper/csv';
const data = await fetchCSV('/data/emissions.csv', {
id: 'country_code',
value: 'emissions',
dimension: 'year', // optional
});Options
Required
| Option | Type | Description |
|--------------|----------|------------------------------------------|
| data | Array | Pre-shaped data rows |
| topoUrl | string | URL of the topojson file |
| topoObject | string | Object name inside the topojson |
Display
| Option | Type | Default | Description |
|---------------|----------|--------------|----------------------------------------------|
| title | string | '' | Header display name |
| emoji | string | '' | Emoji shown before the title |
| subtitle | string | '' | Second line in the header |
| unit | string | '' | Unit label for legend and tooltips |
| sourceUrl | string | null | URL for the footer source link |
| sourceLabel | string | sourceUrl | Display text for the footer source link |
| dimLabel | string | 'YEAR' | Label shown above the dimension selector |
Map
| Option | Type | Default | Description |
|--------------|-----------|-----------------|----------------------------------------------------|
| projection | string | 'equal-earth' | Any Plot projection type |
| sphere | boolean | true | Show ocean sphere. Disable for non-global projections like albers-usa |
| ocean | string | theme default | Ocean fill color |
Color
| Option | Type | Default | Description |
|-------------------|------------|----------|----------------------------------------------------------|
| colorScheme | string | 'Blues'| Any d3 sequential scheme name |
| colorReverse | boolean | false | Reverse the color ramp |
| colorDomain | number[] | auto | Explicit [min, max]. Overrides automatic calculation |
| clampPercentile | number | 1 | Clips the top and bottom N% when computing auto domain |
Behaviour
| Option | Type | Default | Description |
|---------------------|----------|---------|------------------------------------------------------|
| initialDim | string | latest | Start on this dimension value instead of the most recent |
| animationInterval | number | 800 | ms per animation frame. Set to 0 to hide the play button |
Theming
Built-in themes are available for the following d3 color schemes: Greens, Blues, Oranges, Purples, Reds, YlOrRd. Any other scheme will use the Blues UI theme while still applying the correct color ramp to the map.
Custom themes can be added by importing SCHEME_THEMES from subject-mapper/theme and adding a new entry before calling createMap.
URL state
The selected dimension is reflected in the URL hash as #dim=2023, allowing direct links to a specific view. The hash is updated when the user manually selects a dimension but not during animation playback.
