Region Map
A static data map of US states or countries, shaded by a value, with labelled pins.
≈ 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:
regionsfor a value per state or country,pinsfor individual sites (up to 12),highlightfor a set of regions without values, such as a service territory. - Keep pin labels to the value (
"$10M") and put the name intitle. It shows on hover and in the list. - Set
scale.formatandcurrencyso values read correctly. Percent values are percentages:12.5means 12.5%. - Only set
selectablewhen the user's choice changes what you do next.
Regions and ids
| Geography | Preferred id | Also accepted |
|---|---|---|
us-states | 2-letter code, "TX" | FIPS ("48"), "US-TX", the state name. The 50 states and DC |
world | ISO 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.
emphasispins 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
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
| Prop | Type | Notes |
|---|---|---|
title | string? | |
description | string? | 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 |
highlight | string[] | Data-bound. Region ids to tint without a value |
highlightLabel | string? | Legend text for highlighted regions. Default "Highlighted" |
selectable | "none" | "region" | "pin" | Default none |
Host props: status (streaming, ready, submitted), onResult, result and className.