# OrbitStatus (/docs/charts/orbit-status)

OrbitStatus answers "how slow and how busy is this dependency right now?" in one small mark. The orbit radius is latency
— a wider orbit is a slower service — and the orbit's dash density is the call rate, denser dashes meaning more calls.
In the interactive entry the satellite orbits at a speed that mirrors that rate, so a busy service visibly spins faster.
Both channels are deliberately low-precision ambient reads; for exact numbers, use a `Sparkline` for latency and a
`Delta` or `MiniBar` for rate.

```tsx
<OrbitStatus latency={240} rate={12} latencyDomain={[0, 500]} rateDomain={[0, 20]} title="Payments API" size={40} />
```

## Install

```tsx
import { OrbitStatus } from "@microcharts/react/orbit-status";

<OrbitStatus
  latency={240}
  rate={12}
  latencyDomain={[0, 500]}
  rateDomain={[0, 20]}
  title="Payments API"
/>
```

Setup (package + stylesheet): [Quickstart](/docs/quickstart#set-up-with-an-ai-agent) or paste [`/agent-setup.md`](/agent-setup.md) into your agent.


## Motion, and reduced motion

The satellite's angular speed is quantized to the same five steps as the static dash density, so the motion and the
still frame decode identically — you learn nothing extra from watching, you just feel the rate. This is the deliberate
idle-loop exception, allowed because the loop rate is the datum. It pauses off-screen and, under
`prefers-reduced-motion`, does not spin at all: the dash density already carries the rate. The satellite's angular
_position_ never means anything — only its speed does — so the docs say plainly not to read the angle.

## When to use it

- **Good for** — a live dependency health dot in a service table, latency and rate together in one small mark, or an
  infra status glance.
- **Avoid for** — exact latency (`Sparkline`), exact rate (`Delta`, `MiniBar`), or a trend over time (`Sparkline`).

## Sizing

One `size` prop, in viewBox units, sets the orbit box — it defaults to `20`. There is no separate `width`/`height`: the
glyph is square, and the rendered box widens only by the gutter a `label` reserves. `fontSize` follows `size` unless you
set it.

## Variants

```tsx
<OrbitStatus latency={340} rate={8} threshold={300} latencyDomain={[0, 500]} rateDomain={[0, 20]} />
<OrbitStatus latency={100} rate={0} latencyDomain={[0, 500]} rateDomain={[0, 20]} />
```

```tsx
<OrbitStatus
  latency={1240}
  rate={12}
  latencyDomain={[0, 2000]}
  rateDomain={[0, 20]}
  label="latency"
  locale="de-DE"
/>
```

## Edge cases

```tsx
<OrbitStatus latency={NaN} rate={5} title="Unreachable" />
```

```tsx
<OrbitStatus latency={90} rate={0} latencyDomain={[0, 500]} rateDomain={[0, 20]} />
```


## Why this default

The dash-density static encoding exists because a paused satellite says nothing — the still frame had to carry both
variables or the chart would fail the survivor test, so rate lives in the dashes as well as the spin. The rate is
quantized to five ordinal steps in both renderings — five dash counts and five angular periods — and radius and speed
always come from the same domains in the static and interactive frames, so nothing drifts. A lone orbit radius is
meaningless, so the docs insist on explicit `latencyDomain` and `rateDomain` — the same steer as `FatDigits`. At
`threshold`, the satellite doubles and flags the summary, never relying on color alone. Unknown latency or rate goes
gray and stops the spin: an unknown dependency must not look healthy.

## Accessibility

The accessible name is both variables with units — **"240ms latency at 12 calls/s."** — plus "— above threshold" when
the latency crosses `threshold`, or **"Latency unknown."** when a value is missing. The threshold state is carried by
the satellite's size and the summary, never color alone; motion is gated on `prefers-reduced-motion`; and the live
region announces threshold crossings only.

This chart is a single unit, so there is nothing to rove between: a click, tap, `Enter` or `Space` selects it
and fires `onSelect`, and no selection stays pinned. That is the scalar half of the shared
[interaction contract](/docs/accessibility#one-interaction-contract).

## Props

| Prop | Type | Description |
| --- | --- | --- |
| `latency` (required) | `number` | Orbit radius (weak — pass a domain). |
| `rate` (required) | `number` | Dash density / satellite speed. |
| `latencyDomain` | `[number, number]` | Latency extent (insist on it — a lone radius is meaningless). |
| `rateDomain` | `[number, number]` | Rate extent (default [0, 2·rate]). |
| `threshold` | `number` | Latency threshold: at/above it the satellite doubles + the summary flags it. |

Plus the shared grammar — `data`, `domain`, `color`, `title`, `summary`, `format` — and the layout props (`width`, `height`, `className`, `style`) that every chart accepts. Interactive entries also share `animate` and `live`, and — wherever a chart has more than one navigable unit — `onActive`, `onSelect`, `selectedIndex` and `defaultSelectedIndex`; and — wherever the chart shows a hover value — `readout`. See [the shared grammar](/docs/quickstart#the-shared-grammar).
