Requests
1.84B
+12.4%last 24h
Choose your reading theme.
A dark overview of a project on an edge network: KPIs with bar sparklines, live traffic on a dotted world map, an alert you can act on, latency and deployments.
edge-overview/edge-overview.tsx1.84B
+12.4%last 24h
41ms
+9 msall regions
0.021%
+0.0065xx / requests
94.2%
−1.1 ptedge cache
sin1 p95 is 3.3x its baseline
Since deploy #4127 at 13:41. hkg1 has 41% headroom at 36 ms.
The live component, numbered part by part. Every measurement is read from it as it is drawn. Point at a row to outline its part, or at a part to find its row.
When to use
When not to use
You can add this component with the shadcn CLI or by hand:
Into components/edge-overview of any React project, with no setup:
npx shadcn@latest add https://brunodelorence.com/r/edge-overview.jsonCopy these files into one folder of your project, keeping their relative imports together, or download them as a ZIP:
As shown under Usage, below.
Either way it needs React 19 and a bundler that supports CSS Modules, such as Next.js or Vite. It has a dark colour scheme: it follows your page’s color-scheme, light unless the page sets one, or its colorScheme prop, with nothing to configure. Browsers without light-dark() show it light.
import { EdgeOverview } from './edge-overview';export function OverviewPage() { return ( <EdgeOverview defaultRange="24h" defaultRegion="all" onShift={(shifted) => console.log(shifted ? 'shifted' : 'undone')} onDeploy={(deployment) => console.log(deployment.id)} autoplay={false} /> );}Each state below is a live instance, locked so you can study it.
The pieces it is built from, each with its measurements read live.
The overview screen of a project served from ten regions. Requests travel the routes of a dotted world map while the regions’ traffic ticks; hover a region for its popover, or click it to filter the screen. One region runs slow since a deploy: shift 30% of its traffic to a neighbour and watch its dot, its row, the KPI and the chart come back down, then undo it, or open the slow request’s trace. Time ranges, a region menu, a line legend, search and Deploy all work.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultRange | '1h' | '24h' | '7d' | '30d' | '24h' | The time range at first: it sets the KPIs, their bars and the latency chart. |
defaultRegion | 'all' | 'iad1' | 'fra1' | 'sfo1' | 'lhr1' | 'hnd1' | 'sin1' | 'hkg1' | 'bom1' | 'gru1' | 'syd1' | 'all' | The region filter at first; the chart follows it and the other regions dim on the map. |
defaultPopover | RegionCode | null | 'sin1' | The region whose popover is open at first. The map comes back to the elevated region when the pointer leaves it; null keeps it closed. |
live | boolean | true | Whether traffic ticks and requests travel the routes (only on screen, never under reduced motion). |
onRangeChange | (range: RangeId) => void | — | Called with the range the reader picks. |
onRegionChange | (region: RegionCode | 'all') => void | — | Called with the region picked in the menu, on the map or in the list. |
onShift | (shifted: boolean) => void | — | Called when the alert’s action moves traffic (true) or undoes it (false). |
onDeploy | (deployment: Deployment) => void | — | Called with the new deployment when Deploy is pressed. |
autoplay | boolean | true | While on screen and untouched, a demo pointer hovers regions, switches the range, reads the chart, opens the trace and shifts traffic. Any real input stops it. |
colorScheme | 'light' | 'dark' | 'system' | — | Light or dark colours, or the reader’s; without it, the page’s color-scheme. |
defaultState | EdgeOverviewState | — | Opens in a state: { menu: "team" | "bell" | "region", trace, shifted, drawer, query, hidden: SeriesKey[], crosshair: 0–1, allRegions }. A menu opened this way leaves the focus alone; any of it turns the demo off. |
className | string | — | Classes for the root, the quiet field around the window. |
The complete source behind this demo. Open source under the MIT license, © 2026 Bruno Delorence: copy it, change it, ship it.
// Copyright (c) 2026 Bruno Delorence. MIT License.'use client';/* * Edge overview: the overview screen of a project on an edge network, dark first. An app window * with a sidebar (team switcher, sections, projects, the month's usage) and a main column: the * breadcrumbs, search and notifications; the project's title with its environment and address, * the time range, a region filter and Deploy; four KPIs with bar sparklines; traffic by region on * a dotted world map; the regions with an alert and their latency; the latency chart; and the * latest deployments. * * - Live: while the screen is on show, requests travel the map's routes, and every 1.6 s the * regions' traffic, the total and the newest request bar move a little. * - Map: hovering or focusing a region opens its popover (p95 over the last hours, p95, requests, * errors); clicking one filters the screen to it, as the region menu does. * - The alert: Shift 30% to hkg1 moves traffic over two seconds: sin1's latency, its dot on the * map, its row, the KPI and the chart come back down, and a route from sin1 to hkg1 appears. * Undo moves it back. Open trace shows the slow request's spans. * - 1h / 24h / 7d / 30d change the KPIs and the chart; the legend hides or shows each line; * deploy markers on the chart are buttons. Search filters the regions and deployments. * Deploy adds a deployment that builds, then goes live. * - Layout from its own width (container queries): the reference's two columns from 1400 px, * one column of cards below; the sidebar is an icon rail under 1100 px and a drawer under// Copyright (c) 2026 Bruno Delorence. MIT License.'use client';/* * The map of the Traffic by region card. Everything is laid out on a 749 × 315 board, which is * scaled to fit the card (never above its own size) and centred: * * - the land is a grid of dots on a canvas drawn at the device's pixel ratio. A dot's shade comes * from how close it is to a region (weighted by that region's traffic), with a little steady * noise, and dots around an elevated region turn red. It is drawn again only when the size or * the regions' states change. * - the routes are quadratic curves in an SVG, and the requests travelling them are small glowing * dots moved along the same paths by CSS offset-path, so the motion costs no script. They stop * when the root says the screen is paused (offscreen, hidden tab, reduced motion). * - each region is a button: a dot with its halo and a label with its code and traffic. Hovering * or focusing one opens the popover beside it, with its p95 over the last hours and its stats; * leaving the map brings back the pinned region (the elevated one), if there is one. */import { useEffect, useLayoutEffect, useRef, useState, type CSSProperties } from 'react';import { ARCS, MAP_H,// Copyright (c) 2026 Bruno Delorence. MIT License.'use client';/* * The latency chart: p50, p95 and p99 over the range, drawn in an SVG at the plot's own pixel size * (measured with a ResizeObserver), so strokes and dashes keep their weight at any width. The * y scale is fixed (150 ms at the top gridline), as the reference reads, and lines may run above * it. * * The span where p95 was elevated is a tinted band with its label; inside it, p95 turns red over * a red wash. Deploy markers stand on the baseline, the bad one in red. Hovering, or focusing the * plot and pressing Left / Right, moves a crosshair with the three values of that moment. */import { useId, useLayoutEffect, useRef, useState, type KeyboardEvent } from 'react';import type { Series } from './data';import styles from './edge-overview.module.css';export type SeriesKey = 'p95' | 'p50' | 'p99';/** Card px from the plot's left edge to the axis labels' column, as on the reference. */const LEFT = 17.5;const RIGHT = 57.5;// Copyright (c) 2026 Bruno Delorence. MIT License./* * The made-up project behind the edge overview: its regions with their place on the map, traffic * and latency, the deployments, the KPIs of each time range, and the latency series the chart and * the popover draw. Everything is computed from a seeded random generator, so the screen is the * same on every load and on the server. * * The world map is a grid of dots kept where a hand-drawn outline of the land says there is land. * The outlines are coarse polygons in degrees of longitude and latitude, drawn for this screen. */export type RangeId = '1h' | '24h' | '7d' | '30d';export const RANGES: RangeId[] = ['1h', '24h', '7d', '30d'];export type RegionCode = 'iad1' | 'fra1' | 'sfo1' | 'lhr1' | 'hnd1' | 'sin1' | 'hkg1' | 'bom1' | 'gru1' | 'syd1';export type Region = { code: RegionCode; city: string; /** Where its node sits on the 749 × 315 map. */ x: number; y: number;// Copyright (c) 2026 Bruno Delorence. MIT License./* * The screen's line icons, drawn on a 16-unit grid with a 1.25 stroke in the current colour. They * are decorative: every control that shows one also has a name. The stylesheet sets their size. */const PATHS = { overview: ( <> <rect x="2.2" y="2.2" width="4.6" height="4.6" rx="1" /> <rect x="9.2" y="2.2" width="4.6" height="4.6" rx="1" /> <rect x="2.2" y="9.2" width="4.6" height="4.6" rx="1" /> <rect x="9.2" y="9.2" width="4.6" height="4.6" rx="1" /> </> ), rocket: ( <> <path d="M6.3 9.7 4.1 7.5c1.6-2.9 4.6-5.4 9.6-5.4 0 5-2.5 8-5.4 9.6z" /> <path d="M6.2 6.1H3.6L2.4 7.7l1.7.6M9.9 9.8v2.6l-1.6 1.2-.6-1.7" /> <path d="M4.6 11.4c-1 .5-1.7 1.4-2 2.6 1.2-.3 2.1-1 2.6-2" /> <circle cx="10.1" cy="5.9" r="1.1" /> </> ),// Copyright (c) 2026 Bruno Delorence. MIT License.'use client';import type { CSSProperties, Ref } from 'react';/* * The demo's pointer, and the steps that move it. A demo is a script of awaited steps: wait, or * glide the pointer somewhere. Stopping the demo (the reader takes over, or it scrolls away) ends * the step in progress at once: its promise rejects, which ends the script right there, and the * pointer fades out. * * Each glide is a curved flight played by the Web Animations API, so nothing runs frame by frame. * The points of the flight are handed to whoever wants to move along with it. The arrow and the * hand are HTML boxes that swap by their visibility: a change of style inside an SVG would lay the * SVG out again. */export type Point = { x: number; y: number };/** A glide's path and timing, for an animation that plays along with it. */export type Flight = { points: Point[]; timing: KeyframeAnimationOptions };export type Demo = {// Copyright (c) 2026 Bruno Delorence. MIT License.'use client';import { useCallback, useEffect, useRef, useState } from 'react';/* * When a demo may play on its own: while part of it is on screen and the tab is visible, never * under reduced motion, and not while the reader is using it. `take()` hands it to the reader; it * takes back over `idle` ms after their last input (never, for an infinite `idle`). `visible` and * `reduced` are handed out too: the live stream runs while the screen is visible, whoever drives * it. */export function useAutoplay<T extends HTMLElement>(idle = 6000) { const ref = useRef<T>(null); const [visible, setVisible] = useState(false); const [reduced, setReduced] = useState(true); const [taken, setTaken] = useState(false); const timer = useRef(0); useEffect(() => { const element = ref.current; if (!element) return; let onScreen = false;/* Edge overview (edge-overview.tsx): an app window on a quiet field, with a sidebar and a main column of cards. Sizes are the screen's own px, measured on the reference at its true scale (the window is 1445 × 903 there). The layout follows the component's own width (container queries on the root): two columns of cards from 1400 px, one below; the sidebar is an icon rail under 1100 px and a drawer under 720 px. Colours are the tokens below, light-dark(light, dark) where the two differ: the component takes the color-scheme it inherits from the page (light unless the page says otherwise), or the one its colorScheme prop sets (data-color-scheme). Motion is transforms and opacity: the requests on the map ride an offset-path, the bars grow by scaleY, the meters by scaleX. All of it pauses with data-paused on the root (offscreen, hidden tab, reduced motion). */.root { --sans: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; --mono: JetBrains, 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace; --page: #ececee; --frame: #fbfbfc; --frame-edge: #dcdce0; --rule: #e6e6ea; --card-top: #ffffff;