Skip to content

Add a Geo/map chart with Choropleth, points, pie, arc and path layers - #271

Open
IPWright83 wants to merge 1 commit into
masterfrom
claude/choropleth-map-viz-35mar4
Open

IPWright83 wants to merge 1 commit into
masterfrom
claude/choropleth-map-viz-35mar4

Conversation

@IPWright83

Copy link
Copy Markdown
Owner

Summary

Adds <Geo>, a map/choropleth chart family. It's a composition root like <XYChart> - self-contained, but rather than a single fixed plot it composes any combination of new layers as children, all sharing one d3-geo projection fitted to the plot area:

  • <Choropleth> - shades each region of a GeoJSON/TopoJSON geography by a quantized color scale, joined against the chart's data by a region key (e.g. population by country/continent).
  • <GeoPoints> - plots a marker per row at its lat/lon, optionally sized by a value and colored by category.
  • <GeoPie> - plots a small Pie/Donut glyph per location, summarizing that location's rows by category (e.g. energy mix per city).
  • <GeoArcs> - draws a great-circle flow line between a source/target lat/lon pair per row (e.g. migration or trade between regions).
  • <GeoPaths> - connects each group's rows into a single ordered route across the map (e.g. a tracked animal's migration path).

Any combination of layers can be composed onto one <Geo> - see the Composed story/Composing layers doc section.

Supports both GeoJSON and TopoJSON (via the new topojson-client dependency) for features, any standard d3-geo projection (equalEarth/mercator/naturalEarth1/orthographic/albersUsa/albers/azimuthalEqualArea) or a custom projection factory, and Canvas rendering via useCanvas.

Implementation notes

  • New renderGeoPath Canvas primitive in @chart-io/core (registered under the "geo" path type in renderElements), shared by every layer that draws an arbitrary projected shape (regions, arcs, routes). It replays the SVG d string's M/L/Z commands directly rather than depending on the Path2D global, which isn't available in every Canvas host environment (e.g. jsdom's canvas polyfill).
  • New normalizeGeoFeatures core util converts either a plain GeoJSON Feature/FeatureCollection or a TopoJSON Topology into one consistent FeatureCollection.
  • New <ShapesPlot> generic React primitive (alongside the existing NodesPlot/RectsPlot/LinksPlot/LabelsPlot) renders arbitrary filled/stroked shapes from a d accessor - powers <Choropleth>'s regions, <GeoArcs>'s flow lines and <GeoPaths>'s routes.
  • The shared projection is threaded through a GeoContext provided by an internal GeoLayer (the real direct child of <Chart>, carrying the isPlot/requiresVirtualCanvas flags <VirtualCanvas> looks for) - not the Redux store, to keep this contained to the react package.
  • New world_map_dataset.js Storybook dataset - deliberately low-resolution, hand-authored continent bounding regions (not real coastlines), so the Storybook/Chromatic build has no external basemap dependency.

Test plan

  • pnpm --filter @chart-io/core test / lint / types / build
  • pnpm --filter @chart-io/react test / lint / types / build
  • New unit tests for every layer plus a Canvas-mode image snapshot test (packages/react/src/lib/components/Plots/Geo/Geo.unit.tsx)
  • New unit tests for normalizeGeoFeatures (packages/core/src/utils/geo/normalizeGeoFeatures.unit.ts)
  • Built Storybook and visually verified each new story (Choropleth, GeoPoints, GeoPie, GeoArcs, GeoPaths, composed layers) in a headless browser
  • Added a changeset

🤖 Generated with Claude Code

https://claude.ai/code/session_01SHs98Edsbh6eZLEKKhJMS3


Generated by Claude Code

Adds <Geo>, a composition root (like <XYChart>) for map charts. Rather
than a single fixed plot, it composes any combination of new layers as
children, all sharing one d3-geo projection fitted to the plot area:

- <Choropleth> shades each region of a GeoJSON/TopoJSON geography by a
  quantized color scale, joined against the chart's data by a region key.
- <GeoPoints> plots a marker per row at its lat/lon, optionally sized by
  a value field.
- <GeoPie> plots a small Pie/Donut glyph per location, summarizing that
  location's rows by category (e.g. energy mix per country).
- <GeoArcs> draws a great-circle flow line between a source/target
  lat/lon pair per row (e.g. migration or trade between regions).
- <GeoPaths> connects each group's rows into a single ordered route
  across the map (e.g. a tracked animal's migration path).

Any combination of layers can be composed onto one <Geo>. Supports both
GeoJSON and TopoJSON (via the new topojson-client dependency) for
`features`, any standard d3-geo projection or a custom factory, and
Canvas rendering via useCanvas alongside a new renderGeoPath Canvas
primitive (registered under the "geo" path type) shared by every layer
that draws an arbitrary projected shape.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SHs98Edsbh6eZLEKKhJMS3
@changeset-bot

changeset-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 15c0009

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@chart-io/core Minor
@chart-io/react Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@IPWright83
IPWright83 marked this pull request as ready for review August 26, 2026 19:41

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants