Region traffic
Traffic between regions as dotted curves whose rows and particle rate follow throughput; selecting a region isolates its flows and rolls its totals.
Your data
Pass your regions as regions and your traffic as flows. Without either the component shows 12 demo cloud regions and 14 demo flows with invented throughput that drifts every 3 s; regions alone shows an empty map. See Your data.
Playground
Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.
<GeoFlows projection="equalEarth" live maxParticles={400} unit="Gbps" />Installation
pnpm dlx shadcn@latest add @lumesec/geo-flowsFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/geo-flows.jsonUsage
"use client";
import * as React from "react";
import { GeoFlows, type FlowRegion, type RegionFlow } from "@/components/lumesec/geo-flows";
const regions: FlowRegion[] = [
{ id: "fra", label: "Frankfurt", lat: 50.11, lon: 8.68 },
{ id: "iad", label: "Ashburn", lat: 39.04, lon: -77.49 },
{ id: "sin", label: "Singapore", lat: 1.35, lon: 103.82 },
];
export function Example({ flows }: { flows: RegionFlow[] }) {
const [region, setRegion] = React.useState<string | null>(null);
return <GeoFlows regions={regions} flows={flows} value={region} onValueChange={setRegion} unit="Gbps" />;
}Behaviour
Traffic between regions as dotted curves whose width and particle rate follow throughput. Downstream runs in the accent colour and upstream in the info colour, each bending to its own side of the line.
Select a region and its flows stay lit while all others collapse to hairlines and drain; the inbound and outbound totals roll to that region's numbers.
API reference
Props
Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.
regionsTypereadonly FlowRegion[]Default12 demo regionsThe regions on the map: { id, label, lat, lon }. Regions with a repeated id or a non-finite coordinate are skipped.
flowsTypereadonly RegionFlow[]Default14 demo flowsTraffic between regions: { from, to, down, up } with region ids and throughput in unit. down runs from from to to, up the other way. Flows that name an unknown region or carry no traffic are skipped; an empty array shows an empty map.
valueTypestring | nullSelected region id (controlled), or null for none. Use with onValueChange.
defaultValueTypestring | nullDefaultnullSelected region when uncontrolled.
onValueChangeType(value: string | null) => voidCalled with the region id when a region is selected, and with null when the selection is cleared.
unitTypestringDefault"Gbps"Unit of down and up, shown after the totals and used in the accessible names.
formatType(value: number) => stringDefaultone decimalFormats the totals and the throughput in the map's accessible name. The default gives one decimal with grouping, for example 1,204.5.
maxParticlesTypenumberDefault400Most particles in flight at once. When the cap is reached the oldest particle is dropped. 0 turns particles off.
projectionType"equalEarth" | "equirectangular"Default"equalEarth"Map projection. The map is cropped to 50° S to 72° N with its central meridian at 10° E.
liveTypebooleanDefaulttrueLets the demo flows drift by up to 12 % every 3 s while the map is on screen. Has no effect when flows or regions is given.
Ref
ref points at the root HTMLDivElement.
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves to the region markers, which share one tab stop, then to the clear button of the selection chip. |
| ArrowLeft / ArrowRight / ArrowUp / ArrowDown | Moves focus to the nearest marker in that direction on the map. |
| Enter / Space | Selects the focused region, or clears the selection when it is already selected. |
| Escape | Clears the selection. |
Accessibility
- Each region marker is a
buttonwitharia-pressed, named by the region'slabel. The markers form one roving tab stop. - The map has
role="img"and anaria-labelthat gives the number of regions and the three largest flows with their downstream and upstream throughput. - The totals are DOM text. A polite live region announces the selected region's inbound and outbound totals when the selection changes, not when the data changes.
- The chip's clear button is named "Clear selection: " plus the label. After clearing, focus moves to that region's marker.
- Where markers overlap on small maps, a tap on a dot goes to the marker whose centre is nearest; a tap on a label goes to its own region.
- The canvases are
aria-hidden. - Reduced motion: there are no particles, ping or halo: the number of dot rows carries the throughput, selection and data changes apply at once, and the totals swap without rolling.
Theming
Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --lumesec, --lumesec-shine, --lumesec-info, --foreground, --muted-foreground, --card and --border.
Notes
- Downstream curves use
--lumesecand bend to the left of their direction of travel; upstream curves use--lumesec-infoand bend to the other side, so the two directions of a flow separate. - A curve has 1 + round(2 × √(throughput / largest throughput)) rows of dots, so 1 to 3. Particles start at random along a Poisson process of 1.2 + 10 × throughput / largest particles per second and travel at constant speed.
- With nothing selected, In is the sum of every
downand Out the sum of everyup. With a region selected, In is the traffic arriving there (downof flows to it plusupof flows from it) and Out the traffic leaving it. - Selecting a region lights its flows from the region outward behind an uneven front, collapses every other flow to a hairline and stops its particles, pings the land around the region and lights the land under it as its traffic arrives.
- When
flowschanges, rows and particle rates spring to the new values; added flows grow out of their origin and removed ones retract into it. - Flows that cross the map's edge at 170° W continue from the other edge.
- The map's height follows from its width, so set only the width. Below 480 px only the selected region's label shows and the selection chip moves to its own row. Labels that do not fit are hidden; the markers keep their names.
- The animation runs only while the map is on screen. Colours follow the theme and are re-read when it changes.
Related
Was this page helpful?