/

Geo Chart

Render geographic data on interactive maps with choropleth coloring, multiple projections, and custom GeoJSON support. Perfect for regional data, election maps, and global metrics.

6.0K45.0KUsers

Quick Start

import { GeoChart } from "@chartts/react"
 
const data = [
  { region: "US", value: 331000000 },
  { region: "BR", value: 214000000 },
  { region: "IN", value: 1400000000 },
  { region: "CN", value: 1410000000 },
  { region: "ID", value: 274000000 },
  { region: "NG", value: 211000000 },
  { region: "DE", value: 83000000 },
  { region: "JP", value: 126000000 },
  { region: "GB", value: 67000000 },
  { region: "FR", value: 67000000 },
]
 
export function WorldPopulation() {
  return (
    <GeoChart
      data={data}
      region="region"
      value="value"
      projection="equalEarth"
      colorScale={["#eff6ff", "#1d4ed8"]}
      showTooltip
      className="h-[500px] w-full"
    />
  )
}

That renders a world map where each country is shaded according to its population value. Lighter colors represent lower values and darker colors represent higher values. Hover any region to see its name and exact value.

When to Use Geo Charts

Geo charts (choropleth maps) color geographic regions according to a data variable. They make geographic patterns instantly visible: where values are highest, where gaps exist, and how regions compare.

Use a geo chart when:

  • Data is tied to geographic regions (countries, states, counties)
  • Spatial patterns matter (clustering, regional trends, border effects)
  • The audience expects to see data on a map (elections, demographics, economics)
  • Comparing values across 5 or more distinct regions
  • The presentation benefits from the immediate recognition of geographic shapes

Don't use a geo chart when:

  • Regions vary drastically in size (small but important regions become invisible)
  • Precise value comparison matters more than spatial context (use a bar chart)
  • Data is not geographic or the regions are arbitrary
  • You have only 2 to 3 regions (a simple table or bar chart is clearer)

Props Reference

PropTypeDefaultDescription
dataT[]requiredArray of data objects with region identifiers and values
regionkeyof TrequiredKey for the region identifier (ISO code, name, or custom ID)
valuekeyof TrequiredKey for the numeric value to encode as color
geoJsonGeoJSON.FeatureCollectionworld mapCustom GeoJSON for region boundaries
projection'mercator' | 'equalEarth' | 'orthographic''equalEarth'Map projection type
colorScalestring[]['#eff6ff', '#1d4ed8']Array of colors for the value gradient
showLabelsbooleanfalseDisplay region name labels on the map
showTooltipbooleantrueShow value tooltip on hover
zoombooleanfalseEnable scroll-to-zoom and drag-to-pan
animatebooleantrueEnable color transition animation
classNamestring-Tailwind classes on root SVG
regionClassNamestring-Tailwind classes on region paths
labelClassNamestring-Tailwind classes on label text

Projection Types

Equal Earth (default)

A modern projection that shows all countries at their true relative size. No region is disproportionately enlarged. Best general-purpose choice.

<GeoChart
  data={data}
  region="region"
  value="value"
  projection="equalEarth"
/>

Mercator

The familiar web map projection. Preserves shapes and angles but distorts size at high latitudes (Greenland appears as large as Africa). Use when the audience expects the "standard" web map look.

<GeoChart
  data={data}
  region="region"
  value="value"
  projection="mercator"
/>

Orthographic

A globe view that shows one hemisphere at a time. Creates a dramatic, three-dimensional appearance. Combine with zoom to let users rotate the globe.

<GeoChart
  data={data}
  region="region"
  value="value"
  projection="orthographic"
  zoom
  className="h-[500px] w-[500px] mx-auto"
/>

Color Scales

The colorScale prop works the same way as in heatmaps: an array of colors that the chart interpolates between based on each region's value.

Sequential (low to high)

// Blue scale (default)
<GeoChart
  data={data}
  region="region"
  value="value"
  colorScale={["#eff6ff", "#1d4ed8"]}
/>
 
// Green scale
<GeoChart
  data={data}
  region="region"
  value="value"
  colorScale={["#f0fdf4", "#16a34a"]}
/>
 
// Heat scale
<GeoChart
  data={data}
  region="region"
  value="value"
  colorScale={["#fefce8", "#dc2626"]}
/>

Diverging (negative to positive)

Three colors for data that diverges from a midpoint (like GDP growth where negative is bad and positive is good).

<GeoChart
  data={growthData}
  region="country"
  value="gdpGrowth"
  colorScale={["#dc2626", "#f5f5f5", "#16a34a"]}
/>

Multi-stop

<GeoChart
  data={data}
  region="region"
  value="value"
  colorScale={["#1e3a5f", "#3b82f6", "#fbbf24", "#ef4444"]}
/>

Custom GeoJSON

Use your own GeoJSON to render any geographic boundaries: states, provinces, counties, districts, or custom regions.

import usStates from "./us-states.json"
 
<GeoChart
  data={stateData}
  region="state"
  value="population"
  geoJson={usStates}
  projection="mercator"
  colorScale={["#dbeafe", "#1e40af"]}
  showLabels
  className="h-[400px] w-full"
/>

The region key in your data must match a property in the GeoJSON features. By default, the chart matches against properties.id, properties.name, or properties.ISO_A2.

Custom region matching

When your GeoJSON uses a non-standard property for region identification:

<GeoChart
  data={data}
  region="zipCode"
  value="medianIncome"
  geoJson={zipCodeBoundaries}
  geoJsonKey="properties.ZCTA5CE10"
/>

Zoom and Pan

Enable zoom to let users scroll to zoom in and drag to pan across the map. This is essential for maps where small regions contain important data.

<GeoChart
  data={data}
  region="region"
  value="value"
  zoom
/>

Zoom works with all projections. On the orthographic projection, dragging rotates the globe instead of panning.

Zoom limits

The zoom range is automatically constrained to prevent users from zooming out beyond the full map or zooming in past the point where individual regions lose detail.


Accessibility

  • Each region announces its name, value, and rank relative to other regions
  • Keyboard navigation: Tab to enter the map, arrow keys to move between adjacent regions
  • Screen readers describe the overall pattern (for example, "highest values concentrated in South Asia")
  • Regions without data are announced as "no data available"
  • Color is never the only encoding: tooltips and labels provide text-based value access
  • High-contrast mode adds distinct borders between all regions

Real-World Examples

US election results

import usStates from "./us-states.json"
 
const electionData = [
  { state: "CA", margin: -29.2 },
  { state: "TX", margin: 5.6 },
  { state: "FL", margin: 3.4 },
  { state: "NY", margin: -23.1 },
  { state: "PA", margin: 1.2 },
  { state: "OH", margin: 8.0 },
  // ... all states
]
 
<GeoChart
  data={electionData}
  region="state"
  value="margin"
  geoJson={usStates}
  projection="mercator"
  colorScale={["#2563eb", "#f5f5f5", "#dc2626"]}
  showTooltip
  showLabels
  className="h-[450px] w-full"
  regionClassName="stroke-white stroke-1"
/>

Global GDP per capita

<GeoChart
  data={gdpData}
  region="countryCode"
  value="gdpPerCapita"
  projection="equalEarth"
  colorScale={["#fef3c7", "#b45309", "#78350f"]}
  showTooltip
  zoom
  className="h-[500px] w-full"
  regionClassName="stroke-zinc-300 dark:stroke-zinc-700 stroke-0.5"
/>

COVID case density

<GeoChart
  data={covidData}
  region="country"
  value="casesPerMillion"
  projection="equalEarth"
  colorScale={["#fef9c3", "#f59e0b", "#dc2626", "#7f1d1d"]}
  showTooltip
  animate
  className="h-[500px] w-full"
/>

Other Charts