# Dot map

A flat world map in dithered dots with pulsing markers and dotted arcs, for customers-worldwide sections.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available by appending `.md` to any URL or sending an `Accept: text/markdown` header. The dithercn agent skill, for building any dither on the engine, is at [/.well-known/agent-skills/dithercn/SKILL.md](/.well-known/agent-skills/dithercn/SKILL.md).

<ComponentPreview src="examples/dot-map-demo.tsx" size="full" align="stretch" controls="dotMapControls">
  <DotMapDemo />
</ComponentPreview>

## Installation [#installation]

<InstallBlock name="dot-map" />

## Usage [#usage]

```tsx
import { DotMap } from "@/components/dithercn/dot-map";

const OFFICES = [
  { at: [51.51, -0.13], label: "London" },
  { at: [35.68, 139.69], label: "Tokyo" },
] as const;

export function Offices() {
  return (
    <DotMap
      markers={OFFICES}
      arcs={[{ from: OFFICES[0].at, to: OFFICES[1].at }]}
      accent="blue"
    />
  );
}
```

The map is an SVG that scales to its container's width and keeps its aspect ratio. Land comes from a 3.8 KB mask of Natural Earth's public-domain land polygons that installs with it as `world-land`, so nothing is fetched at runtime.

Each marker pulses and casts a dithered halo on the land around it: dense at the marker, thinning through the Bayer levels. Arcs are dotted curves with a stretch of light running along them.

## Examples [#examples]

### Customers worldwide [#customers-worldwide]

Many small markers, round dots and a tight halo, between a headline and a row of stats.

<ComponentPreview src="examples/dot-map-customers.tsx" size="lg">
  <DotMapCustomers />
</ComponentPreview>

### Region map in a card [#region-map-in-a-card]

`bounds` crops the map to a region. Here, Europe, with labelled edge regions in a dashboard card.

<ComponentPreview src="examples/dot-map-regions.tsx">
  <DotMapRegions />
</ComponentPreview>

### Routes, held still [#routes-held-still]

Arcs only, with faint sea dots and `animate={false}`.

<ComponentPreview src="examples/dot-map-routes.tsx" size="lg">
  <DotMapRoutes />
</ComponentPreview>

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `markers` | `{ at: [lat, lon]; label?: string; color?: DitherColor }[]` | `[]` | Locations to mark. Labels show beside the marker and are read by screen readers. |
| `arcs` | `{ from: [lat, lon]; to: [lat, lon]; color?: DitherColor }[]` | `[]` | Dotted curves between places. |
| `color` | `DitherColor` | `"grey"` | Colour of the land dots. |
| `accent` | `DitherColor` | `"ink"` | Colour of markers, halos and arcs that don't set their own. |
| `columns` | `number` | `160` | Dots across the full width. |
| `shape` | `"square" \| "round"` | `"square"` | Dot shape. |
| `halo` | `number` | `14` | Radius in degrees of each marker's dithered glow on the land. 0 turns it off. |
| `ocean` | `number` | `0` | Share of sea cells with a faint dot, 0 to 1. |
| `bounds` | `{ north; south; west; east }` | `78°N to 56°S, all longitudes` | The region to draw, in degrees. |
| `animate` | `boolean` | `true` | Pulse the markers and run light along the arcs. |
| `title` | `string` | `"World map"` | Accessible name. Marker labels are appended to it. |

## Notes [#notes]

* The map is one image to assistive technology, named by `title` plus the marker labels.
* Pulses and running arcs are CSS animations. With reduced motion they are hidden and the map is still.
* Pass `markers` and `arcs` as constants or memoised arrays: the dot paths are rebuilt when they change. Land cells are cached per grid size.
* Land data: [Natural Earth](https://www.naturalearthdata.com/) 1:50m land, public domain, rasterised to 0.75° cells.