Skip to content
Protocore Design Systemv1.6.9

/// Charts

ChartContainer

The bordered, theme-aware frame that hosts a chart and exposes the --pds-chart-1..5 ramp.

import { ChartContainer } from "@protocore/pds";
View as Markdown

Basics

Wrap any chart in a ChartContainer to get the family frame: a bordered surface, a mono-UPPERCASE label header, and a fixed-height body. Match height on the container and the chart so the body doesn't clip or leave a gap.

RPC throughput / req·s⁻¹

Legend and actions

The actions slot pins controls (a menu, a range toggle) to the right of the header; the legend slot sits below it — typically a ChartLegend. Both are plain ReactNodes, so compose them from any pds control.

Ledger settlement / txns
InboundSettled

Pinning the ramp theme

theme="dark" or theme="light" writes the --pds-chart-* custom properties inline, pinning the ramp regardless of the page theme — use it when a chart always lives on a dark panel. theme="auto" (the default) inherits the page's theme.

Ramp · light
Ramp · dark

The chart color doctrine — monochrome + signal

The categorical ramp is five ranked slots, not five equal colors:

  • `--pds-chart-1` — ink. The near-fg tone (#fafafa dark / #0a0a0a light). The lead series.
  • `--pds-chart-2`, `--pds-chart-3` — progressively muted greys. Secondary and structural series.
  • `--pds-chart-4` — signal green (#3fcf8e / #0e9e6e).
  • `--pds-chart-5` — signal amber (#d29922 / #9a6c00).

The rule: rank your series and let the ink slot lead; keep supporting series greyscale; spend the two signal hues only where color carries meaning — the live metric, the threshold breach, the healthy-vs-degraded split. A chart where every series is a different bright color says nothing about which one matters. This is the charts-family expression of the system-wide differentiation contract, where --pds-accent and the status hues are reserved signals, never decoration.

The ramp flips per theme so contrast holds on either background, and the values are hardcoded identically in tokens/index.ts (for recharts, via JS) and ChartContainer.css (for CSS) so the two never drift. ChartContainer is what exposes them: the recharts wrappers resolve each series to var(--pds-chart-N) by position, so they inherit whatever the nearest container pins.

When to use it

Use ChartContainer as the shell for every LineChart, AreaChart, and BarChart on a dashboard — it standardizes the header, legend placement, and (critically) the ramp so charts read as one family. It is server-safe and ships in the main @protocore/pds entry.

You don't need it for a bare Sparkline (which is frameless by design), and you can render a recharts wrapper without it — but then you must supply the --pds-chart-* ramp yourself. Prefer the container.

Usage

Do

  • Keep `height` on the container and the chart in sync.
  • Write `label` as a short mono-UPPERCASE metric with its unit (e.g. "RPC throughput / req·s⁻¹").
  • Rank series and let --pds-chart-1 (ink) lead; keep supporting series greyscale.
  • Pin `theme` only when a chart lives on a fixed-theme surface; otherwise leave it auto.

Don't

  • Don't give five equally-important series five bright colors — the ramp is a rank, not a palette.
  • Don't spend the signal hues (chart-4/5) on decorative series; reserve them for meaning.
  • Don't override `--pds-chart-*` with raw hex — pin a `theme` or adjust the tokens.
  • Don't wrap a Sparkline in it; sparklines are intentionally frameless.

Accessibility

  • ChartContainer is a presentational frame; the accessible meaning comes from the chart inside it and its `label`.
  • The ramp keeps a monochrome luminance spread, so series stay distinguishable in grayscale and for color-vision deficiencies — pair with a legend rather than relying on hue.
  • The `actions` slot must contain real controls (e.g. an IconButton with an `aria-label`); it is not announced on its own.

ChartContainer props

PropTypeDefaultDescription
actionsReactNodeActions slot pinned to the right of the header row (e.g. a menu button).
childrenReactNodeChart body — typically one of the recharts wrappers.
classNamestring
heightnumber240Fixed body height in px. Defaults to `240`.
labelReactNodeMono UPPERCASE label rendered at the left of the header row.
legendReactNodeLegend slot rendered below the label row (e.g. a `ChartLegend`).
styleCSSProperties
themeenumautoPin the `--pds-chart-*` ramp to a theme, or defer to CSS defaults (`auto`).

Related

  • LineChartA monochrome-plus-signal line chart over the shared --pds-chart-N ramp, recharts-backed.
  • AreaChartA monochrome-plus-signal area chart with a soft 0.10→0 gradient fill, recharts-backed.
  • BarChartA monochrome-plus-signal bar chart with sharp (radius 0) bars capped at 24px, recharts-backed.
  • ChartLegendA compact swatch-and-label legend row: 8px squares with mono-UPPERCASE muted labels.