Warren UI

BandChart

Time series inside an expected-range envelope with breach emphasis.

P99 LATENCY · EXPECTED 24±8MS1628400s120s240s
Source
"use client"

import { BandChart } from "@/registry/warren/band-chart/band-chart"

/** Deterministic latency samples (ms) with a ±8ms envelope around 24ms. */
const SAMPLES = [
  { t: 0, v: 26 },
  { t: 30, v: 21 },
  { t: 60, v: 35 },
  { t: 90, v: 24 },
  { t: 120, v: 18 },
  { t: 150, v: 33 },
  { t: 180, v: 27 },
  { t: 210, v: 40 },
  { t: 240, v: 23 },
]
const BAND = SAMPLES.map(() => ({ center: 24, spread: 8 }))

export default function BandChartDemo() {
  return (
    <div className="flex flex-col gap-2 border-2 border-border bg-panel p-2">
      <span className="font-mono text-[10px] uppercase tracking-wide text-muted-foreground">
        P99 LATENCY · EXPECTED 24±8MS
      </span>
      <BandChart points={SAMPLES} band={BAND} format={(n) => `${n}`} formatT={(t) => `${t}s`} />
    </div>
  )
}

Installation

npx shadcn@latest add https://warren.eduard3v.com/r/band-chart.json

Usage

import { BandChart } from "@/components/ui/band-chart"
<BandChart
  points={[{ t: 0, v: 4 }, { t: 1, v: 15 }, { t: 2, v: 5 }]}
  band={[{ center: 6, spread: 4 }, { center: 6, spread: 4 }, { center: 6, spread: 4 }]}
/>

Encoding

The series renders in tone (default primary) inside the expected-range envelope: one flat translucent tone wash (color-mix at 14% — the sanctioned wash) plus dashed ink hairline bounds. band accepts either { lower, upper } bounds or { center, spread } envelopes, aligned by index with points. Points outside their range flip the overlay stroke and a 5px square marker to breachTone (danger by default) — signal color = state.

Axes are mono tabular numerals on hairline gridlines: format renders y values, formatT renders t labels. variant="step" switches the series (and envelope bounds) to horizontal-then-vertical interpolation for discrete-rate metrics. The y domain covers every value and band edge unless yDomain pins it.

Interaction

THROUGHPUT RATE · SLO BAND 0.45–0.650.000.501.00m0m2.5m5
Source
"use client"

import { BandChart } from "@/registry/warren/band-chart/band-chart"

/** Discrete rate samples — step interpolation with pinned y domain and success tone. */
const RATES = [
  { t: 0, v: 0.42 },
  { t: 1, v: 0.55 },
  { t: 2, v: 0.51 },
  { t: 3, v: 0.68 },
  { t: 4, v: 0.6 },
  { t: 5, v: 0.47 },
]
const BAND = RATES.map(() => ({ lower: 0.45, upper: 0.65 }))

export default function BandChartBreaches() {
  return (
    <div className="flex flex-col gap-2 border-2 border-border bg-panel p-2">
      <span className="font-mono text-[10px] uppercase tracking-wide text-muted-foreground">
        THROUGHPUT RATE · SLO BAND 0.45–0.65
      </span>
      <BandChart
        points={RATES}
        band={BAND}
        variant="step"
        tone="success"
        yDomain={[0, 1]}
        format={(n) => n.toFixed(2)}
        formatT={(t) => `m${t}`}
      />
    </div>
  )
}

With onPointClick, each point gains a full-column transparent hit rect and the container flips from role="img" to role="group".

API Reference

Prop

Type

Prop

Type

Prop

Type

On this page