Sextant
← Catalog
Block · dashboard

Streamgraph

A flowing, centered streamgraph of composition over time, with smooth bands, a left-to-right reveal, and an auto-generated narrative naming the largest and fastest-growing streams.

State
Size
Mode

Revenue by contract type

5.6k

latest total · 4 streams

  • Enterprise
  • Mid-market
  • SMB
  • Self-serve

Total grew +51% to 5.6k across 4 streams — Enterprise is the largest, Mid-market the fastest-growing.

Revenue by contract type — value by category over time
PeriodEnterpriseMid-marketSMBSelf-serve
Jun1.7k920680420
Jul1.7k960710450
Aug1.7k1k750480
Sep1.7k1.1k800520
Oct1.7k1.1k860540
Nov1.7k1.2k920480
Dec1.7k1.3k980410
Jan1.8k1.3k1.1k480
Feb1.8k1.4k1.1k560
Mar1.8k1.5k1.2k640
Apr1.8k1.6k1.3k720
May1.8k1.6k1.4k800

Acme Analytics · updated monthly from CRM

Demo data is illustrative. Replace with your own typed data prop.

Use it with your data

Data contract

Passed via the data prop — an object: validated at runtime, so a bad shape degrades to the error state rather than crashing.

FieldTypeRequired
categoriesarrayyes
pointsarrayyes

Static props

import { ChartStreamgraph } from "@/components/blocks/chart-streamgraph/chart-streamgraph";

<ChartStreamgraph data={myData} />

Client fetch (SWR)

const { data, isLoading, error } = useSWR("/api/metric", fetcher);
// route isLoading/error through <ChartStates>, then:
<ChartStreamgraph data={data} />

Server component (RSC)

const data = await fetch(url, {
  next: { revalidate: 3600 },
}).then((r) => r.json());

<ChartStreamgraph data={data} />

Map arbitrary rows

import { mapRows } from "@/lib/sextant/column-map";

const out = mapRows(rows, { /* contractKey: "yourColumn" */ }, dataSchema);
if (out.ok) <ChartStreamgraph data={out.data} />;

Make it yours

Every customization below is an optional prop — omit them all and you get the defaults shown above. Recolor, reformat, restyle, or drop the card chrome without forking the component.

Recolor or rename a series (band)

<ChartStreamgraph
  series={{ band: { color: "var(--chart-3)", label: "…" } }}
/>

Format numbers (currency / locale)

const eur = new Intl.NumberFormat("de-DE", {
  style: "currency",
  currency: "EUR",
  notation: "compact",
});

<ChartStreamgraph valueFormatter={(n) => eur.format(n)} />

Replace or hide the narrative

<ChartStreamgraph narrative="Your own one-liner." />

// …or hide it entirely:
<ChartStreamgraph narrative={false} />

Restyle any region

<ChartStreamgraph
  className="max-w-xl"
  classNames={{ body: "bg-muted/20" }}
/>

Drop the card chrome (headless plot)

import { ChartStreamgraphPlot } from "@/components/blocks/chart-streamgraph/chart-streamgraph";

// Just the chart body — bring your own card/layout:
<ChartStreamgraphPlot data={data} config={config} />