Skip to content

Chart

Chart

A single component, two engines, one data shape.

EngineCanvas / SVGBundleStrengths
chartjs (default)Canvas (chart.js/auto)~70 KB gzBattle-tested. Good for dense data. Mobile-friendly tooltips.
rechartsSVG~110 KB gzPure React. Easy to compose with helixui surfaces (e.g. cards).
Terminal window
# Chart.js
pnpm add chart.js
# Recharts
pnpm add recharts

The base @helixui/core bundle does not pull either until a <Chart> mounts.

Unified data shape

const data: ChartData = {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
datasets: [
{ label: 'Sessions', data: [120, 200, 150, 280, 240], color: 'brand' },
{ label: 'Conversions', data: [12, 24, 18, 36, 30], color: 'success' },
],
};

Per-dataset color accepts:

  • a helixui scale ref — 'brand' | 'success' | 'warning' | 'danger' | 'neutral'
  • a CSS variable — '--helixui-color-bg-action-brand-default'
  • a CSS color — '#ff6680', 'oklch(0.62 0.18 264)'

If no color is given, the dataset gets a slot from helixui’s categorical scale.

Examples

<Chart type="line" data={data} />
<Chart type="area" data={data} smooth />
<Chart type="bar" data={data} />
<Chart type="stackedBar" data={data} />
<Chart type="doughnut" data={{ labels: ['A','B','C'], datasets: [{ label: 'mix', data: [3, 5, 2] }] }} cutout={0.65} />
<Chart type="radar" data={data} />
<Chart type="scatter" data={data} />

Switch engines with the engine prop:

<Chart engine="recharts" type="area" data={data} />

Theming

theme="auto" watches document.documentElement.dataset.theme. Tick / grid / legend colors swap on the next render — no remount.

Compact widgets

Combine with <StatCard> for KPI tiles:

<StatCard label="Revenue" value="$24,580" delta="+8.2%">
<Chart type="area" data={trend} hideAxes legend={false} grid={false} height={64} />
</StatCard>

For tiny inline trends, prefer <Sparkline> — it is dependency-free SVG.

Escape hatches

<Chart
engine="chartjs"
type="line"
data={data}
chartjsOptions={{
scales: { y: { suggestedMin: 0, suggestedMax: 100 } },
plugins: { tooltip: { intersect: false, mode: 'index' } },
}}
/>

Install: @helixui/core

import { Chart } from '@helixui/core'

status: stable · since: 0.7.0

Tags: data-viz, graph, plot, analytics

Anatomy

┌──────────────────────────────┐
│ Title │
│ ▁▂▃▅▆▇█▇▆▅▃▂▁ legend │
│ └──────────────axis──────── │
│ Caption │
└──────────────────────────────┘

Layout

  • displayblock
  • widthfill
  • heightfixed:320px
  • intrinsicSizefills available width, default 320px tall
  • stackabletrue
  • fullBleedfalse

Visual

A surface with optional title, legend, and caption. The plot area uses brand / success / warning / danger token colors for series. Tooltips appear on hover/touch; axis labels use muted text. Animations respect prefers-reduced-motion.

Props

NameTypeDefaultDescription
type'line' | 'area' | 'bar' | 'stackedBar' | 'horizontalBar' | 'pie' | 'doughnut' | 'radar' | 'scatter'Chart type. Same set across both engines.
dataChartDataUnified { labels, datasets } shape. Adapters translate it.
engine'chartjs' | 'recharts'chartjsWhich engine to use. Chart.js draws to canvas; Recharts to SVG.
theme'light' | 'dark' | 'auto'autoauto follows document.documentElement.dataset.theme.
legendbooleantrueShow / hide the legend.
gridbooleantrueShow / hide axis grid lines.
tooltipbooleantrueShow / hide tooltips on hover/touch.
animatebooleanautoAnimate on mount and on data change. Defaults follow prefers-reduced-motion.
hideAxesbooleanfalseUseful for compact widgets — drops both x and y tick labels.
smoothbooleantrueSmoothed curves for line/area.
compactNumbersbooleantruePretty-format the y-axis as 1.2K / 3.4M.
cutoutnumber0.6Doughnut cutout (0–1). Ignored for non-doughnut types.
heightnumber | string320Numbers are treated as px.
titleReactNodeOptional title rendered above the chart.
captionReactNodeOptional caption rendered below the chart.
chartjsOptionsRecord<string, unknown>{}Spread last into Chart.js options. Escape hatch.
rechartsOptionsRecord<string, unknown>{}Reserved for the recharts adapter.
onMount(info: { engine, instance }) => voidFires once mounted. Receives the underlying engine instance.

Tokens used

color.bg.surface.default, color.bg.surface.subtle, color.bg.action.brand.default, color.bg.action.success.default, color.bg.action.warning.default, color.bg.action.danger.default, color.bg.action.danger.subtle, color.border.default, color.text.primary, color.text.muted, color.text.action.danger, radius.md, font.family.sans, motion.duration.fast, motion.easing.standard

Accessibility

Notes

  • Canvas-based engines (Chart.js) get a role='img' on the canvas with the chart title as aria-label.
  • Tooltips honor pointer + touch.
  • Animations turn off when prefers-reduced-motion: reduce unless animate is explicitly set.

Composes with

ComponentRelationNote
CardparentOften wrapped in a Card on dashboards.
StatCardsiblingKPI tiles next to a chart.
SparklinealternativeUse Sparkline for tiny inline trends.

Prompt examples

These are the AI prompt → JSX mappings used by the helixui prompt DSL and integrations like Cursor / Claude Code.

monthly revenue line chart

“show a line chart of revenue”

<Chart type="line" data={{ labels, datasets: [{ label: 'Revenue', data }] }} />

bar chart with engine override

“use recharts for a bar chart”

<Chart engine="recharts" type="bar" data={data} />