Region Map

A static data map of US states or countries, shaded by a value, with labelled pins.

Pattern

≈ 1,400 tokens per use (tool 957 · guidance 296 · typical payload 147)How token costs are estimated

Example: Region Map

Where are our clean-energy projects and how big are they?

Clean-energy projects

Committed capital

  • Service territory

Service territory: California, Nevada, Utah, Arizona, New Mexico, Colorado, Wyoming, Texas, Oklahoma, Kansas, Nebraska, Iowa

When to use

  • The answer is a number per state or country, and where it happens matters: sales by state, users by country.
  • A few sites with a value each, where their location tells the story: projects and their size, deals and their value.
  • The user should pick a state, country or site from data you show.

When not to use

  • The user needs to find, compare or route between places, or drop a pin. Use the Map.
  • Exact comparison matters more than geography. Use a Chart or a Data Table.
  • There are only one or two regions. Say it in a sentence.
  • The data isn't by US state or country, such as cities in one region or sales territories.

How the agent should use it

  • Take every value, id and coordinate from a tool result. Never guess coordinates.
  • Pick the layer for the data: regions for a value per state or country, pins for individual sites (up to 12), highlight for a set of regions without values, such as a service territory.
  • Keep pin labels to the value ("$10M") and put the name in title. It shows on hover and in the list.
  • Set scale.format and currency so values read correctly. Percent values are percentages: 12.5 means 12.5%.
  • Only set selectable when the user's choice changes what you do next.

Regions and ids

GeographyPreferred idAlso accepted
us-states2-letter code, "TX"FIPS ("48"), "US-TX", the state name. The 50 states and DC
worldISO 3166-1 alpha-3, "PRT"ISO numeric ("620"), the country name. The ~175 countries in Natural Earth 1:110m

Ids that aren't on the map are listed under it ("Not on this map: …") instead of being dropped silently, and so are pins outside the map's area (for example, Puerto Rico on the US map).

Reading the map

  • Shading: values fall into 3–7 equal-width buckets (default 5) on round bounds, such as "$0–$10M", "$10M–$20M". Buckets are steps of one neutral ink, light to strong, so they read without color vision. Regions without a value stay in the neutral base and appear as "No data" in the legend.
  • Highlight: a soft tint when nothing else is shaded; with values on the map, highlighted regions get an outline instead, so the two never look alike.
  • Pins: a dot with a halo and a dashed leader up to a label. Labels are laid out so they don't overlap each other, cover another pin's dot or leave the map: each tries the spot above its dot first, then further up, sideways, then below. emphasis pins are placed first and drawn inverted.

Accessibility

The map drawing is hidden from assistive tech. A visually hidden table lists every region with its full value, sorted from highest, and the figure's label summarizes it, such as "Sales by state, Q3: highest Texas $50M, lowest Vermont $200K (30 states)". Highlighted regions and pins are listed too. With pins and no region values, the visible list under the map is the accessible list.

Hovering or tapping a region shows its name and value. Regions aren't tab stops unless selectable is "region"; then each region with a value has a button in the hidden table, and focusing it outlines the region and shows its tooltip. Pins with a title, or all pins when selectable is "pin", are buttons.

Bundle size

The atlas geometry (us-atlas ~80 KB, world-atlas ~105 KB) and d3-geo load with a dynamic import() after the component mounts, so they never block the page. A skeleton shows until they arrive, and each geography loads once per page.

Installation

npx shadcn@latest add https://your-site.com/r/region-map.json

Usage

app/api/chat/route.ts
import { tool } from "ai"
import { regionMapTool } from "@/components/genui/region-map.schema"

const tools = {
  [regionMapTool.name]: tool({
    description: regionMapTool.description,
    inputSchema: regionMapTool.inputSchema,
  }),
}

With selectable: "none" (the default) the map is the whole answer, so give the tool an execute that returns immediately. Otherwise the agent receives the id it sent:

{ action: "select-region", id: "TX" }
{ action: "select-pin", id: "kanab" }

With LangGraph

Push it from a graph node with ui.push({ name: "show_region_map", props: { toolCallId, ...args } }, { message }), and render the thread's UI messages with the Renderer.

Restoring from history

Pass the stored tool output as result. The map restores the selected region or pin, locks, and never calls onResult again:

<RegionMap
  {...part.input}
  result={part.state === "output-available" ? part.output : undefined}
/>

Schema

PropTypeNotes
titlestring?
descriptionstring?The period or source
geography"us-states" | "world"
regions{ id, value, label? }[]Data-bound. label replaces the formatted value
scale{ format, currency?, steps?, legendLabel? }format: currency, number (default) or percent. steps 3–7, default 5. legendLabel names the legend and the hidden data table for screen readers; it isn't shown
pins{ id, lat, lng, label, title?, icon?, emphasis? }[]Up to 12. Data-bound. icon: wind, solar, building, factory, store, users, dollar, pin
highlightstring[]Data-bound. Region ids to tint without a value
highlightLabelstring?Legend text for highlighted regions. Default "Highlighted"
selectable"none" | "region" | "pin"Default none

Host props: status (streaming, ready, submitted), onResult, result and className.

Source

On this page