Zetta v1.6

Components · Data display & feedback

Chart

Zetta does not ship a charting component — it ships the palette a chart should use: a five-colour categorical ramp plus a gridline colour. Bring your own chart library and map its series to these tokens so visualisations stay on-brand and reskin with the theme.

Preview

chart-1
chart-2
chart-3
chart-4
chart-5

Build with the skill

No package to install — hand this to your AI to generate or migrate the component in your stack.

Prompt for your AI
Apply the Zetta "Chart" component to this project using the zetta-design-md skill.

WHEN TO USE
- Migrating or fixing existing code (the common case): audit the current implementation against the `chart` spec (variants: chart-1, chart-2, chart-3, chart-4, chart-5) and CORRECT every deviation — replace off-spec values, don't only add new ones.
- New component: build it to the `chart` spec in this project's stack.

AUDIT & FIX (when the component already exists)
Compare it to the skill's spec and fix, don't just append: hardcoded colors/hex, off-scale radius, wrong fonts, dark/navy fills, shadows used in place of borders (or missing borders), brand lime used as a CTA or interaction (must be primary indigo), and any missing or wrong hover / focus / active / disabled / invalid state or missing 2px focus ring. Replace each with the correct Zetta token.

ALWAYS
- Pull the authoritative spec and tokens from the skill — never guess or hardcode values.
- Use this project's own component conventions and framework idioms.
- Honor the Zetta guardrails (brand = identity only, primary = interaction, shadows for overlays) and verify in Light, Dark, and Accessibility.

Anatomy & rules

  ╭─ chart canvas ──────────────────────────────╮
  │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─  ← gridline (chart-gridline)
  │  ────────────────────────────  ← series 1 (chart-1)
  │  ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌  ← series 2 (chart-2)
  │  ·····························  ← series 3 (chart-3)
  ╰─────────────────────────────────────────────╯
  ■ Series 1  ■ Series 2  ■ Series 3   ← legend (product-defined)

Parts:

  • Canvas — product-level container; chart tokens apply within it
  • Gridlines — always {colors.hairline}; do not use series colors for gridlines
  • Series strokes / fillschart-1 through chart-5 in assignment order
  • Legend — product-defined; must not rely on color alone
State Visual
Default Data rendered with series colors
Loading Skeleton fills chart area (same dimensions)
Empty Empty state illustration + message inside chart bounds
Error Error message with retry action inside chart bounds
Series hover Hovered series highlights; others dim to 30% opacity
Tooltip visible Floating tooltip shows data point values

When to use

  • Any multi-series data visualization within the product.
  • Assign series colors in order (chart-1 first, then chart-2, etc.) to maintain consistency across chart instances.
  • Skip to a non-adjacent token if two series are visually similar (e.g., skip chart-2 when using chart-1 for better hue contrast).

When not to use

  • Single-metric charts that use a semantic color (error rate → use {colors.danger} directly, not a chart token).
  • Status/state color coding — use semantic tokens (success, warning, danger, info).

Do

  • Pair color with a secondary differentiator (line style, shape, direct label) so charts remain readable in the accessibility theme.
  • Limit active series to 5 — the palette has exactly 5 tokens by design.

Don't

  • Don't use chart tokens for non-chart UI — they are data-visualization-only.
  • Don't hardcode hex values; always reference the token so themes switch correctly.
  • Legend labels: noun or short noun phrase. Sentence case. Match exactly the series name used in axis labels.
  • Axis labels: concise, unit-annotated where necessary (e.g., "Revenue (USD)", "Latency (ms)"). Left-align Y-axis labels.
  • Tooltips: show the series name, value, and unit. Format numbers with locale-aware separators.
  • Empty chart message: "No data available" centered in the chart canvas in {colors.muted}.

Keyboard

Chart is primarily visual. Interactive chart variants (hover tooltips, selectable series) follow the keyboard patterns of the underlying interactive elements. Data tables should be provided as an accessible alternative. When interactive: Tab moves focus between interactive chart elements (points, legend items), Arrow keys navigate between data points within a series, and Enter activates the tooltip / drill-down on the focused data point.

Accessibility

  • Color independence (WCAG 1.4.1): the accessibility theme collapses all five series to a grayscale range. Always pair color with a pattern, line style, or data-point shape.
  • Alt text / ARIA: provide aria-label on the chart container with a summary ("Line chart showing monthly revenue for Q1 2025"). For complex charts, link to a data table fallback.
  • Gridlines: {colors.hairline} meets 3:1 contrast against {colors.canvas} in all themes.

Spec

Values and token references resolved straight from the Zetta spec.

chart-1
value
{colors.chart-1}
chart-2
value
{colors.chart-2}
chart-3
value
{colors.chart-3}
chart-4
value
{colors.chart-4}
chart-5
value
{colors.chart-5}
chart-gridline
value
{colors.hairline}
chart-axis-label
fontFamily
Geist
fontSize
11px
fontWeight
400
textColor
{colors.muted}
lineHeight
1.4
chart-axis-tick
strokeColor
{colors.hairline}
strokeWidth
1px
chart-data-label
fontFamily
Geist
fontSize
11px
fontWeight
500
textColor
{colors.ink}
backgroundColor
{colors.surface-card}
borderRadius
{rounded.sm}
paddingX
4px
paddingY
2px
chart-legend-item
fontFamily
Geist
fontSize
12px
fontWeight
400
textColor
{colors.body}
gap
{spacing.xs}
swatchSize
10px
swatchBorderRadius
{rounded.sm}
chart-tooltip-container
backgroundColor
{colors.surface-card}
textColor
{colors.ink}
borderColor
{colors.hairline}
borderWidth
1px
borderRadius
{rounded.base}
shadow
{elevation.shadow.overlay}
paddingX
{spacing.sm}
paddingY
{spacing.xs}
fontFamily
Geist
fontSize
12px
chart-tooltip-label
fontWeight
500
textColor
{colors.ink}
chart-tooltip-value
fontWeight
400
textColor
{colors.muted}
chart-loading
backgroundColor
{colors.skeleton-bg}
shimmerColor
{colors.skeleton-shimmer}
borderRadius
{rounded.base}
animationDuration
1.5s
chart-bar
fillColor
{colors.chart-1}
borderRadius
{rounded.sm}
gap
4px
groupGap
16px
minBarWidth
8px
hoverOpacity
0.85
chart-line
strokeColor
{colors.chart-1}
strokeWidth
2px
dotRadius
4px
dotFill
{colors.canvas}
dotStroke
{colors.chart-1}
dotStrokeWidth
2px
hoverDotRadius
6px
chart-area
strokeColor
{colors.chart-1}
strokeWidth
2px
fillOpacity
0.15
fill
{colors.chart-1}
chart-pie
strokeColor
{colors.canvas}
strokeWidth
2px
hoverScale
1.03
chart-donut
innerRadiusRatio
0.60
centerLabel
[object Object]
centerSublabel
[object Object]

Known gaps

  • Color scale for sequential/diverging data (heat maps, choropleth) — not in scope for v1.1; tracked for v1.2.
  • Sparkline / micro-chart variant — not yet specified.
  • Real-time / streaming chart update behavior — not yet specified.