# Dot world map
URL: /diagrammatic/docs/charts/dot-world-map

The world as a halftone field of dots. Countries color by named group, and flows draw as trails between countries.

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

```tsx
"use client";

import { Legend } from "diagrammatic";
import { Root, Tooltip } from "diagrammatic/interactive";
import { DotWorldMap, WORLD } from "diagrammatic/world";

const NAMES = new Map(WORLD.map((country) => [country.iso, country.name]));
const REGIONS = {
  "us-east": ["US", "CA", "MX", "BR", "AR", "CO", "CL"],
  "eu-west": ["GB", "IE", "FR", "DE", "NL", "ES", "IT", "PL", "SE", "NO"],
  "ap-south": ["IN", "SG", "ID", "AU", "JP", "KR", "TH", "VN"],
};
const REGION_OF = new Map(
  Object.entries(REGIONS).flatMap(([region, list]) =>
    list.map((iso) => [iso, region]),
  ),
);

export default function InferenceRegionsMap() {
  return (
    <div data-dg-motion="">
      <Legend names={Object.keys(REGIONS)} className="mb-3 text-xs" />
      <Root highlightOnHover="series">
        <DotWorldMap
          title="Inference regions and the countries they serve"
          groups={REGIONS}
          flows={[
            { from: "BR", to: "US" },
            { from: "GB", to: "US" },
            { from: "IN", to: "DE" },
            { from: "AU", to: "SG" },
            { from: "JP", to: "US" },
            { from: "DE", to: "SG" },
          ]}
        />
        <Tooltip side="top">
          {({ datum }) => {
            if (!datum.series) return null;
            const text = datum.series2
              ? `${NAMES.get(datum.series)} to ${NAMES.get(datum.series2)}`
              : `${NAMES.get(datum.series) ?? datum.series}, ${REGION_OF.get(datum.series) ?? "not served"}`;
            return (
              <div className="bg-popover text-popover-foreground w-max rounded-lg border px-2.5 py-1.5 text-xs shadow-md">
                {text}
              </div>
            );
          }}
        </Tooltip>
      </Root>
    </div>
  );
}
```

## Usage

```
import { DotWorldMap } from "diagrammatic/world";

<DotWorldMap
  groups={{ "us-east": ["US", "CA"], "eu-west": ["GB", "DE"] }}
  flows={[{ from: "US", to: "GB" }]}
/>;
```

Use it when the question is where, not how much: a footprint, a coverage map, a replication topology. For a value per country, use the [World map](/diagrammatic/docs/charts/world-map).

## Examples

### A footprint

One group lights up a set of countries; every other country stays a faint dot.

```tsx
import { DotWorldMap } from "diagrammatic/world";

export default function FootprintMap() {
  return (
    <DotWorldMap
      title="Where we ship"
      groups={{ shipping: ["US", "CA", "GB", "DE", "FR", "JP", "AU"] }}
    />
  );
}
```

### Groups

`groups` maps a name to a list of country codes. Groups take the categorical palette in their key order. The map draws no legend of its own; put the DOM `Legend` above it with the same names, as the figure at the top does.

```tsx
import { DotWorldMap } from "diagrammatic/world";

export default function TimezoneTeamsMap() {
  return (
    <DotWorldMap
      title="Support coverage by team"
      groups={{
        Americas: ["US", "CA", "MX", "BR", "AR", "CO", "CL", "PE"],
        EMEA: [
          "GB",
          "IE",
          "FR",
          "DE",
          "ES",
          "IT",
          "NL",
          "SE",
          "PL",
          "ZA",
          "NG",
          "EG",
          "AE",
          "SA",
        ],
        APAC: ["IN", "CN", "JP", "KR", "SG", "ID", "AU", "NZ", "PH", "VN"],
      }}
    />
  );
}
```

### Flows

`flows` draws a lifted trail from one country to another, blending from the source group's color to the target's.

```tsx
import { DotWorldMap } from "diagrammatic/world";

export default function ReplicationMap() {
  return (
    <DotWorldMap
      title="Database replication from the primary in Virginia"
      groups={{
        primary: ["US"],
        replicas: ["GB", "DE", "JP", "SG", "BR", "AU"],
      }}
      flows={["GB", "DE", "JP", "SG", "BR", "AU"].map((to) => ({
        from: "US",
        to,
      }))}
    />
  );
}
```

### Animated flows

Put `data-dg-motion` on the map or any ancestor and each trail runs from source to target, so the direction reads without arrows. See [Motion](/diagrammatic/docs/motion).

```tsx
import { DotWorldMap } from "diagrammatic/world";

export default function LiveTrafficMap() {
  return (
    <div data-dg-motion="">
      <DotWorldMap
        title="Traffic failing over between regions, live"
        groups={{
          "us-east": ["US", "CA", "MX", "BR"],
          "eu-west": ["GB", "FR", "DE", "ES", "IT"],
          "ap-south": ["IN", "SG", "JP", "AU"],
        }}
        flows={[
          { from: "BR", to: "US" },
          { from: "GB", to: "US" },
          { from: "IN", to: "DE" },
          { from: "AU", to: "SG" },
          { from: "JP", to: "US" },
          { from: "DE", to: "SG" },
        ]}
      />
    </div>
  );
}
```

## Interaction

Each country is a mark with `data-series` set to its code, and each flow carries its source in `series` and its target in `series2`, so one tooltip can describe both, as the figure at the top does.

### Zoom

```tsx
"use client";

import { Zoom } from "diagrammatic/interactive";
import { DotWorldMap } from "diagrammatic/world";

export default function ZoomableDotMap() {
  return (
    <Zoom max={6} className="overflow-hidden rounded-md">
      {(view) => (
        <DotWorldMap
          title="Edge locations in Europe"
          groups={{
            edge: [
              "GB",
              "IE",
              "FR",
              "DE",
              "NL",
              "ES",
              "IT",
              "SE",
              "PL",
              "CH",
              "AT",
            ],
          }}
          view={view}
        />
      )}
    </Zoom>
  );
}
```

## Props

- `groups?`: `Record<string, string[]>` — Named sets of ISO 3166-1 alpha-2 codes, colored in key order.
- `flows?`: `{ from: string; to: string }[]` — Trails between two countries, by code.
- `title?`: `string` — Names the map for assistive technology.
- `summary?`: `string` — A sentence read after the title.
- `width`: `number` (default `640`) — Rendered width in CSS pixels.
- `height?`: `number` — Rendered height in CSS pixels.
- `aspect?`: `number` — Width over height when \`height\` is not given.
- `view?`: `{ x: number; y: number; w: number; h: number }` — A window onto the map, from \`Zoom\`.