Skip to content
microcharts
ReferenceExpressiveOrbitStatus

OrbitStatus

OrbitStatus carries a dependency's latency as orbit radius and its call rate as dash density, in one square glyph.

encodes
orbit radius = latency, dash density / speed = rate
precision
low
nodes
3
collection
Expressive
Source

OrbitStatus encodes two numbers in one glyph. The orbit radius is latency, so a wider orbit is a slower service, and the orbit's dash density is the call rate, so denser dashes mean more calls. In the interactive entry the satellite orbits at a speed that mirrors the rate. Both channels are low-precision ambient reads; for exact numbers use a Sparkline for latency and a Delta or MiniBar for rate.

Each channel reads against a stated reference. The radius spans 0–1000 ms, or 0–2× threshold when you set one, which lands the alert edge on the halfway orbit. Dash density steps by decade: under 1 call/s, then 1, 10, 100, and 1000 or more. Pass domain and rateDomain when you know the range you care about, because a service that answers in 40–90 ms reads better on its own frame than on the second-wide default.

OrbitStatus
interactive · 4.52 kB · static · 2.49 kB

Install

Import & usereact/orbit-status
import { OrbitStatus } from "@microcharts/react/orbit-status";<OrbitStatus  latency={240}  rate={12}  latencyDomain={[0, 500]}  rateDomain={[0, 20]}  title="Payments API"/>
Needs package + stylesheetSet up with AI

Try it

Live playground
onSelect
idle
  1. hover · click · Enter…

A live dependency table. Each orbit's radius is its latency, its dash density is its call rate, and the satellite's speed mirrors that rate — busier services spin faster. Cross 300ms and the satellite doubles and the row flags. Reduced-motion readers read the same dash density without the spin.

latency (ms) · 240
rate (calls/s) · 12
threshold 300ms
readout chip
import { OrbitStatus } from "@microcharts/react/orbit-status/interactive";<OrbitStatus  latency={240}  rate={12}  latencyDomain={[0, 500]}  rateDomain={[0, 20]}/>

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. Rate lives in the dashes as well as the spin, which is what lets a paused satellite still carry both variables. 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. Read the satellite's speed, not its angular position; the position encodes nothing.

When to use it

Use it for a live dependency health dot in a service table, for latency and rate together in one small mark, or for an infra status read. For exact latency or a trend over time use Sparkline; for exact rate use Delta or MiniBar.

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

an SLO threshold, and an idle service
locale — the ms gutter numeral and the summary both follow it

Edge cases

unknown latency — gray, no satellite, no spin
idle service — zero rate draws a solid, dash-free orbit

An unknown latency or rate renders gray, drops the satellite, and stops the spin, so an unreachable dependency never looks healthy. A rate of 0 draws a solid, dash-free orbit. At threshold the satellite doubles in size. The rate is quantized to five ordinal steps in both renderings (five dash counts and five angular periods), and radius and speed read from the same domains in the static and interactive frames.

Four homes

In a sentence

Payments API health — 240 ms latency, 12 req/s, orbit stable.

In a table cell
payments240ms
auth48ms
search420ms
In a KPI card
Payments
240ms· 12 rps
In a tab header
paymentsauthsearch

Preview uses the public chart API only. When an interactive twin exists, it swaps in with the same props and no entrance motion - code samples stay on the static import. Placement recipes: Composition, Sizing.

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 satellite's size and the summary carry the threshold state, 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. Hover or focus also reveals the reading itself in a floating chip, for the sizes and label modes where the mark does not print it; readout={false} drops the chip and keeps everything else.

Props

PropTypeNotes
latency*numberOrbit radius, on the latency reference below.
rate*numberDash density / satellite speed.
domain[number, number]Latency extent (default [0, 2·threshold], else [0, 1000] ms).
latencyDomain[number, number]The same extent under its older name.
rateDomain[number, number]Rate extent (default: one dash step per decade).
thresholdnumberLatency threshold: at/above it the satellite doubles + the summary flags it.
sizenumberOrbit box edge in viewBox units (default 20).
fontSizenumberType size of the gutter label, in viewBox units. Defaults from `size`.

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.

Related charts