Components

Chart

Stacked bars and sparklines for figures beside their own numbers

Import
import { BarChart, Sparkline } from "@nyte-ai/ui/chart";
import type { ChartSeries, ChartBucket } from "@nyte-ai/ui/chart";

BarChart compares stacked values across buckets. Sparkline shows a row's trend without axes or labels, so keep the numbers in nearby text. Both are drawn by nivo, with each series painted inside its tint's scope so theme and display-mode changes repaint them.

Usage

  • Give each series and bucket a stable key. Put each bucket's values in series order, with one nonnegative, finite number per series. Missing entries render as zero.
  • BarChart stacks series bottom to top and scales every bar against the largest bucket total. It fills its container's width; height is the bars, and the labels sit in 20px below.
  • Pass format to format the readout's values and total. Pointing at any segment opens a readout of its whole bucket. The first and last labels hang inward so neither is cut at the edge.
  • ticks selects evenly spaced bucket labels below the bars. Use an integer of at least 2.
  • Sparkline scales against its own largest value. Use nonnegative, finite values and do not compare line heights across sparklines as absolute quantities.

Examples

Stacked bars

const series = [
  { key: "input", label: "Input", tint: "blue" },
  { key: "output", label: "Output", tint: "purple" },
] satisfies readonly ChartSeries[];

const buckets = [
  { key: "mon", label: "Mon", values: [1200, 400] },
  { key: "tue", label: "Tue", values: [1800, 600] },
  { key: "wed", label: "Wed", values: [900, 300] },
] satisfies readonly ChartBucket[];

<BarChart
  label="Daily token usage, Monday to Wednesday"
  series={series}
  buckets={buckets}
  format={(value) => `${value.toLocaleString()} tokens`}
  ticks={3}
/>;

A row's trend

<div>
  <span>Requests this week: 42</span>
  <Sparkline values={[2, 8, 4, 6, 10, 5, 7]} tint="blue" />
</div>

A named sparkline

<Sparkline
  values={[2, 8, 4, 6, 10, 5, 7]}
  label="Daily requests this week, peaking at 10"
  width={96}
  height={24}
/>

Props

BarChart

PropTypeDefaultDescription
labelstringRequiredAccessible name of the plot.
seriesreadonly ChartSeries[]RequiredLayers in bottom-to-top order.
bucketsreadonly ChartBucket[]RequiredBars in left-to-right order.
format(value: number) => stringRequiredFormats each readout value and the total.
heightnumber88Bar height in pixels, without the labels.
ticksnumber5Number of bucket labels below the plot, capped at the bucket count.
xstyleXStyleStyles the outer container.
classNamestringClass on the outer container.
styleReact.CSSPropertiesInline styles on the outer container.

ChartSeries

FieldTypeDescription
keystringStable series identity.
labelstringSeries name in the readout.
tintTintColor of the layer and its readout swatch.

ChartBucket

FieldTypeDescription
keystringStable bucket identity.
labelstringBucket name in the readout and below the plot.
valuesreadonly number[]One value per series, in series order.

Sparkline

PropTypeDefaultDescription
valuesreadonly number[]RequiredPoints in left-to-right order.
tintTintUses a tinted stroke instead of the secondary content color.
labelstringAccessible name. Without it, the line is decorative.
widthnumber72Width in pixels.
heightnumber20Height in pixels.
xstyleXStyleStyles the wrapper.
classNamestringClass on the wrapper.
styleReact.CSSPropertiesInline styles on the wrapper.

Tint accepts "gray", "brown", "orange", "yellow", "green", "blue", "purple", "pink", "red", "teal", and "custom". See Theming for xstyle, className, and style.

Accessibility

  • BarChart renders one SVG with role="img" and the supplied label. The readout follows the pointer only, so put the figures the chart shows in nearby text or a table as well.
  • Sparkline has no keyboard interaction. With label, it has role="img" and aria-label. Without label, it is aria-hidden.