Chart

Pro

A dependency-free plotting primitive for trends, funnels and pies. Compose the named parts into one measured SVG; the legend focuses and toggles series, and every hue re-themes.

Weekly signups by platform
weekWebiOSAndroid
Jul 71,8401,210760
Jul 141,9201,260790
Jul 211,8801,300780
Jul 282,0501,280820
Aug 42,0101,350850
Aug 112,1801,410840
Aug 182,1401,390880
Aug 252,4601,5801,010
Sep 12,5201,6201,040
Sep 82,4801,6501,020
Sep 152,6101,7001,080
Sep 222,6901,7601,110
Sep 291,120740470

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add chart

Usage#

Chart is composed from named parts, like Card. The root takes the data, an optional index key for category labels, and a config that names each series’ label and color. The parts (ChartGrid, ChartArea, ChartLine, ChartTooltip) read it from context and draw into one shared, pixel-measured SVG.

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Anatomy#

import {  Chart,  ChartLegend,  ChartGrid,  ChartXAxis,  ChartYAxis,  ChartArea,  ChartLine,  ChartReferenceLine,  ChartAnnotation,  ChartTooltip,} from "@/components/ui/chart"<Chart>  <ChartLegend />  <ChartGrid />  <ChartXAxis />  <ChartYAxis />  <ChartArea />  <ChartLine />  {/* or ChartBar, ChartBars, ChartAreas, ChartFunnel, ChartPie */}  <ChartReferenceLine />  <ChartAnnotation />  <ChartTooltip /></Chart>

Load animation#

Every chart plays a one-shot reveal the first time it mounts: the ChartLine self-draws left to right, the ChartArea fill rises from the baseline, and each ChartBar grows up from the zero line in a left-to-right cascade. It fires once, never on hover or re-sort, and honors prefers-reduced-motion (every layer simply appears drawn). Pass animate={false} on the Chart root to opt out. Press Replay to watch it again.

monthRevenue
Jan4,200
Feb3,800
Mar5,100
Apr4,600
May6,200
Jun5,400
Jul7,100
Aug6,500
monthOrders
Jan240
Feb198
Mar312
Apr277
May388
Jun305
Jul372
Aug410

Line#

Layer a ChartLine per series; each resolves its hue from config, or takes an explicit color. The shared ChartTooltip lists every series at the hovered category, and a crosshair tracks the active point.

Desktop vs. mobile visitors by month
monthDesktopMobile
Jan2,4001,800
Feb2,9002,100
Mar2,2002,600
Apr3,4002,300
May3,1003,200
Jun4,2002,900
Jul3,8003,600
Aug4,6004,100

Area#

ChartArea fills the space under the trend with a currentColor gradient that fades to the baseline, so the wash is just the series hue at low opacity: a blue line yields a soft blue-100/200 fill. Pair it with a ChartLine for a crisp edge.

Monthly revenue
monthRevenue
Jan4,200
Feb3,800
Mar5,100
Apr4,600
May6,200
Jun5,400
Jul7,100
Aug6,500

Smooth curves#

Pass curve="monotone" to ChartLine, ChartArea or ChartAreas to join the points with a monotone cubic instead of straight segments. It is smooth, yet it still passes through every point and never swings above a peak or below a trough the data does not have: a plateau stays flat and an extreme sits exactly on its point, so the curve never invents a value. Gaps, stacking, dashed, markEnd, the draw-in and the hover dot all follow the curve. Set the same curve on the area and the line drawn over it.

linear (default)

Sessions by month, linear curve
monthSessions
Jan420
Feb480
Mar480
Apr610
May440
Jun520
Jul520
Aug700

monotone

Sessions by month, monotone curve
monthSessions
Jan420
Feb480
Mar480
Apr610
May440
Jun520
Jul520
Aug700

Missing data#

A point with a non-numeric (or absent) value is a gap. By default the ChartLine and ChartArea break at the gap, so a dropout reads honestly. Pass connectNulls to bridge across it instead.

Default: line breaks at gaps

daySignal
Mon40
Tue52
Wed
Thu48
Fri61
Sat
Sun70

connectNulls: bridged

daySignal
Mon40
Tue52
Wed
Thu48
Fri61
Sat
Sun70

Bar#

ChartBar draws a bar per category from a 0-anchored baseline. Each bar stands square on the baseline and rounds only at its value end (the bottom, for a negative bar), and ChartGrid draws the zero line a step stronger, so the bars stand on a floor. Hovering a column brings it forward and dims the rest, so the active value reads at a glance.

Orders by month
monthOrders
Jan240
Feb198
Mar312
Apr277
May388
Jun305
Jul372
Aug410

Value labels & highlight#

Pass label to ChartBar to print each value just past its bar end. It returns inline content, so a figure can carry a glyph. To single one datum out, draw the series in neutral (the foreground at 10% on every theme) and pass its index to highlight, so that one bar takes full ink. Hovering a column also lifts its x-axis tick to the foreground.

Revenue by week
weekRevenue
Week 118,484
Week 221,489
Week 324,941
Week 419,994

Highlight & active bar#

highlight on ChartBar paints chosen bars in highlightColor (primary, full ink, by default) and leaves the rest in the series hue: an index for today, a list, a predicate over the row, or "active" for the bar under the pointer. The chart reports that bar through onActiveIndexChange (and takes a controlled activeIndex), so a legend or a headline can follow it. Here the latest month is lit until another is hovered. Swapping the highlight recolors the bars in place, so the grow-in never replays, and the tooltip swatch takes the hue the bar is wearing. While a column is hovered the others dim, except neutral bars: already faint, they hold their ink and the hovered one steps up instead, so no bar ever disappears.

Today in full ink

Orders this week
dayOrders
Mon42
Tue51
Wed47
Thu58
Fri63
Sat38
Sun45

Follows the pointer

Aug:$6,500
Revenue by month
monthRevenue
Jan4,200
Feb3,800
Mar5,100
Apr4,600
May6,200
Jun5,400
Jul7,100
Aug6,500

Grouped & stacked bars#

ChartBars draws several bar series in one band. By default they render grouped side by side; set stack on Chart to stack them, and the y-axis grows to the per-category total automatically. Grouped series rotate distinct hues; stacked ones take shades of one blue, since their order already tells them apart. A color in config always wins.

Grouped

Desktop vs. mobile visitors (grouped)
monthDesktopMobile
Jan2,4001,800
Feb2,9002,100
Mar2,2002,600
Apr3,4002,300
May3,1003,200
Jun4,2002,900
Jul3,8003,600
Aug4,6004,100

Stacked

Desktop vs. mobile visitors (stacked)
monthDesktopMobile
Jan2,4001,800
Feb2,9002,100
Mar2,2002,600
Apr3,4002,300
May3,1003,200
Jun4,2002,900
Jul3,8003,600
Aug4,6004,100

Stacked area#

ChartAreas stacks several area series into a band chart when stack is set on Chart: each series sits on the cumulative total below it as a translucent band under its own edge line. A stack reads by its order, so series that name no color take shades of the house blue, dark at the floor to light at the top (palette="tonal", the default whenever stack is set). Without stack the series overlap from the baseline.

Desktop vs. mobile visitors, stacked
monthDesktopMobile
Jan2,4001,800
Feb2,9002,100
Mar2,2002,600
Apr3,4002,300
May3,1003,200
Jun4,2002,900
Jul3,8003,600
Aug4,6004,100

Legend#

Put ChartLegend inside the Chart and it keys the chart’s own series, sits above the plot (or below it, with placement="bottom") and becomes the chart’s control surface, as in Mixpanel. Hover a key and its series comes forward while the rest recede; click it to hide or show the series, and the scale and the stack refit around what is left; Alt+click shows it alone. The last series showing never hides. Past max keys, the rest fold into a +N more menu with the same controls.

New revenue by channel
monthOrganicPaid searchSocialEmailReferralPartners
Mar4231181496
Apr45292115107
May51341917127
Jun48382416119
Jul563627191310
Aug614125211512
Sep674430221713

Outside a chart, ChartLegend is a plain key: feed it the same config (or explicit items) and each swatch resolves its hue exactly like the chart, palette fallback included.

DesktopMobile
Desktop vs. mobile visitors by month
monthDesktopMobile
Jan2,4001,800
Feb2,9002,100
Mar2,2002,600
Apr3,4002,300
May3,1003,200
Jun4,2002,900
Jul3,8003,600
Aug4,6004,100

Give an item a value and it prints after the label in the foreground, so the key doubles as a summary of each series. Inside a chart, value="sum", "average" or "last" summarises each series from the data, in its own format.

Travel:$456,478Health:$234,567Food:$123,456Technology:$789,012

Driving it from outside#

The series state is controllable, so a table under the chart can run it, the way Mixpanel pairs every insight with its breakdown. hiddenSeries with onHiddenSeriesChange takes the checkboxes, and focusedSeries with onFocusedSeriesChange lights the plan under the pointer. A series and the period it is compared against always stay lit together.

Monthly recurring revenue by plan
monthEnterpriseProBusinessStarter
Apr51,20042,10036,80018,400
May51,20044,60038,90019,100
Jun58,90047,30041,20018,800
Jul58,90049,80042,60020,300
Aug64,40053,90045,10021,200
Sep71,30057,40047,80021,900
ShownPlanSep MRRSince Apr
Enterprise$71,300+39.3%
Pro$57,400+36.3%
Business$47,800+29.9%
Starter$21,900+19.0%

Dual axis & per-series format#

Give a series axis: "right" in config to scale it against a secondary y-axis (so two metrics at different magnitudes share one chart), and render a second ChartYAxis with side="right". Each series can also carry its own format, so the tooltip shows, say, currency for revenue and a plain count for orders.

Revenue and orders by month
monthRevenueOrders
Jan4,200240
Feb3,800198
Mar5,100312
Apr4,600277
May6,200388
Jun5,400305
Jul7,100372
Aug6,500410

Forecast & end marker#

ChartLine takes dashed for projected data and markEnd to pin a filled dot on the last point (a “current value” marker). Split actuals and projection into two series that share the seam point, and the solid line meets its dashed continuation cleanly.

Revenue with projection
monthActualProjected
Jan4,200
Feb4,600
Mar5,100
Apr4,800
May5,600
Jun6,1006,100
Jul6,700
Aug7,200

Incomplete period#

Today’s count is still climbing, so drawn like a finished day it reads as a collapse. Pass partial on Chart (or a number, for several trailing periods) and the open period draws as provisional, Mixpanel’s treatment: a line dashes from the last complete point on the exact same curve, its area fades, a bar hatches, and the tooltip marks the period with partialLabel.

Daily active users
dayActive users
Sep 163,120
Sep 173,260
Sep 183,190
Sep 193,380
Sep 202,840
Sep 212,610
Sep 223,290
Sep 233,440
Sep 243,510
Sep 253,470
Sep 263,620
Sep 273,010
Sep 282,790
Sep 291,460
Orders per day
dayOrders
Sep 16212
Sep 17238
Sep 18224
Sep 19251
Sep 20188
Sep 21171
Sep 22243
Sep 23262
Sep 24259
Sep 25271
Sep 26284
Sep 27203
Sep 28186
Sep 2997

Compare to previous period#

Name the earlier period in a series’ config with compare and the pair reads as one story. The earlier series becomes a ghost: it borrows the hue, takes no palette slot, and its ChartLine draws thin, faint and dashed with no prop set. The tooltip prints the change beside the current value, green up and red down; give a down-is-good metric (churn, refunds, latency) inverted and the colors flip. In ChartBars the ghost stands beside its partner, faint.

Weekly revenue, this quarter against last
weekThis quarterLast quarter
W148,20041,800
W251,60044,100
W349,30045,600
W455,80043,900
W558,10047,200
W654,70049,800
W761,20048,600
W863,90051,300
W960,40053,700
W1066,80052,100
W1169,50055,400
W1272,30057,900

Reference lines#

ChartReferenceLine draws a horizontal threshold (y) or vertical marker (x) across the plot, with an optional label. Compose it after the data so it annotates on top, for a target, limit, or average. It defaults to a muted dashed line; pass a color to emphasize it.

Monthly revenue against target
monthRevenue
Jan4,200
Feb3,800
Mar5,100
Apr4,600
May6,200
Jun5,400
Jul7,100
Aug6,500

Annotations#

ChartAnnotation pins a note to a category: a launch, an outage, a release, so the jump in the line explains itself. Its marker sits in a lane above the plot (the plot steps down to make room on its own) with a faint rule down to the baseline, and hovering it opens the note. Mixpanel numbers its markers; pass any short label, or none for a dot, and a color for a note that is bad news. The text also reaches screen readers beside the data table.

Daily signups in September
daySignups
Sep 1420
Sep 2443
Sep 3462
Sep 4475
Sep 5481
Sep 6479
Sep 7471
Sep 8460
Sep 9450
Sep 10803
Sep 11613
Sep 12450
Sep 13464
Sep 14484
Sep 15507
Sep 16529
Sep 17408
Sep 18560
Sep 19564
Sep 20561
Sep 21552
Sep 22541
Sep 23601
Sep 24595
Sep 25596
Sep 26605
Sep 27620
Sep 28641
Sep 29664

Tooltip rows#

footer on ChartTooltip adds rows under the series, below a hairline, for a figure the chart does not draw: here the net of income and expenses. Build each row with ChartTooltipItem (a swatch, a label, a value) so it lines up with the rows above and its swatch keeps its hue in the portaled bubble. labelFormatter receives the whole row and its index after the label, so the heading can say more than the axis (a full month name).

Income against expenses by month
monthIncomeExpenses
Mar51,20038,400
Apr48,60041,200
May56,30039,800
Jun53,90044,100
Jul61,50042,700
Aug58,80045,300

Tooltip order & totals#

With several series, the tooltip reads best as a ranking. sort="desc" orders the rows by their value at the hovered category, so the leader comes first however the lines cross (a comparison row stays under its series). total adds the column’s sum below a hairline (a string names it), and maxItems folds the tail into a +N more line. While a legend key holds the focus, the other rows recede with their series.

Support tickets by region
weekNorth AmericaEMEAAPACLATAMOther
Aug 441235624118862
Aug 1143837125917658
Aug 1840139224820171
Aug 2546641827721466
Sep 145244129022974
Sep 848943731123669
Sep 1550346230524881
Sep 2252148833225977

Axis labels that fit#

interval="auto" on ChartXAxis measures its labels against the plot’s width and skips just enough of them that none collide, re-thinning as the chart resizes. It counts back from the last category, so the latest day or month always carries its name. minTickGap sets the clear space between labels (12px), and minInterval keeps a month of days reading by the week however wide the plot. A number still labels every Nth category from the first.

Wide

Visits per day, wide plot
dayVisits
Aug 291,200
Aug 301,297
Aug 311,385
Sep 11,455
Sep 21,501
Sep 31,519
Sep 41,508
Sep 51,472
Sep 61,415
Sep 71,345
Sep 81,270
Sep 91,202
Sep 101,147
Sep 111,114
Sep 121,108
Sep 131,131
Sep 141,181
Sep 151,254
Sep 161,343
Sep 171,441
Sep 181,537
Sep 191,623
Sep 201,690
Sep 211,731
Sep 221,745
Sep 231,731
Sep 241,691
Sep 251,631
Sep 261,560
Sep 271,486

Narrow

Visits per day, narrow plot
dayVisits
Aug 291,200
Aug 301,297
Aug 311,385
Sep 11,455
Sep 21,501
Sep 31,519
Sep 41,508
Sep 51,472
Sep 61,415
Sep 71,345
Sep 81,270
Sep 91,202
Sep 101,147
Sep 111,114
Sep 121,108
Sep 131,131
Sep 141,181
Sep 151,254
Sep 161,343
Sep 171,441
Sep 181,537
Sep 191,623
Sep 201,690
Sep 211,731
Sep 221,745
Sep 231,731
Sep 241,691
Sep 251,631
Sep 261,560
Sep 271,486

Axis titles & compact figures#

ChartYAxis prints compact figures by default (12K, 1.4M), the way Mixpanel and Attio label an axis; pass tickFormatter for currency or units. Both axes take a label: the y title turns to run along the outer edge, the x title centers under the ticks, as in Attio’s report builder. Give the chart the room for them in padding.

Companies by primary location
countryCompanies
United States128
United Kingdom64
Germany41
France33
Spain27
Netherlands19
Sweden12

Negative values#

The domain anchors to zero, and bars and areas grow from the value baseline (the y-zero line), so positive values rise above it and negative values drop below. No extra config: pass data that crosses zero and it reads correctly.

Net change by month
monthNet change
Jan12
Feb-8
Mar15
Apr-4
May22
Jun-11
Jul18
Aug9

Fitted domain#

A full chart starts its y-axis at zero, which is right for bars and totals. A balance or a rate moves in a band far from zero, and a zero floor flattens it into a line. Pass domain="fit" and the axis wraps the data’s own extent in nice rounded bounds, with ticks on a nice step, so the grid and the labels still land on round values. It never crosses zero when the data does not. A [min, max] pair still fixes the domain exactly.

auto (default): from zero

Balance at each week's close, auto domain
weekBalance
Jul 51,674,200
Jul 121,681,900
Jul 191,690,400
Jul 261,697,800
Aug 21,709,600
Aug 91,722,300
Aug 161,738,900
Aug 231,731,400
Aug 301,768,200
Sep 61,790,600
Sep 131,805,300
Sep 201,821,500
Sep 271,842,300

fit: around the data

Balance at each week's close, fit domain
weekBalance
Jul 51,674,200
Jul 121,681,900
Jul 191,690,400
Jul 261,697,800
Aug 21,709,600
Aug 91,722,300
Aug 161,738,900
Aug 231,731,400
Aug 301,768,200
Sep 61,790,600
Sep 131,805,300
Sep 201,821,500
Sep 271,842,300

Funnel#

ChartFunnel draws conversion through ordered steps, as Mixpanel and Attio do. Each step is a column, and above it a faint ghost rises to the step before, so what dropped off reads as the empty part of the column. Each step carries its conversion from the first, and ChartTooltip adds the conversion and drop-off rows by itself. Give the chart about 32px of padding.top for the first label.

Signup funnel, last 30 days
stepUsers
Visited pricing12,480
Started signup5,920
Verified email4,310
Created workspace3,180
Invited a teammate1,240

Pie & donut#

ChartPie draws each row as a slice, clockwise from twelve o’clock, with a clean gap between slices. innerRadius sets the hole (0.62 by default, a donut; 0 for a pie), and its children center in the hole. Hovering a slice lifts it out a step while the rest recede, with its value and share in the tooltip. A ChartLegend in the same chart keys the slices in their hues and lights them from the key.

Visits by source
sourceVisits
Organic search18,420
Direct9,310
Referral5,870
Social4,120
Email2,280
Open deals by stage
stageDeals
Lead42
Qualified27
Proposal16
Negotiation9
Won6

Category bar#

CategoryBar breaks one whole into its parts in a single line: credits by tool, storage by file type, time by project. It takes the same rows as a pie (each one a category, named by index, sized by dataKey), so where a donut spends a square, this sits under a figure or across a card. Each segment’s width is its share, with a clean gap between segments, and CategoryBarLegend keys them underneath with the share after each name. Hovering a segment or a key lights it and recedes the rest, with its amount and share in the tooltip. Give the long tail’s Other the gray hue.

size sets the thickness (6, 8 or 12px), palette="tonal" paints shades of the house blue instead of distinct hues, and the legend’s value prints the share, the amount (through valueFormatter), both, or nothing.

size="sm"

size="md"

size="lg", palette="tonal", value="both"

Sparkline#

Pass sparkline for a chromeless trend: zero padding (it bleeds to the edge), points spanning the full width, and currentColor so a single text-* utility sets the hue. This is exactly what StatSparkline renders under the hood.

Revenue

Sessions

Refunds

Sparkline bars#

A sparkline can draw bars too, for a week of orders beside a figure. Once a ChartBar is in it, the categories sit in bands (the first and last bars keep their full width) and the scale runs from zero, so the shortest bar still reads as a bar. Add ChartTooltip for a hover readout, and highlight to light today.

Orders

344

Refunds

9

Colors#

Every series takes a semantic hue: blue (the default), teal, purple, orange, pink, the status roles, or current to inherit the ambient color. Series without a color follow the chart’s palette: categorical rotates distinct hues led by blue, for lines that cross and must be told apart; tonal spreads the blue ramp (blue-800 to blue-200) as far apart as the count allows, and is the default for a stack.

blue

teal

purple

orange

pink

Loading & empty#

Pass loading to render a Skeleton in place of the plot (it also sets aria-busy). When data is empty, the chart shows a muted message; override it with the empty prop.

With data

monthRevenue
Jan4,200
Feb3,800
Mar5,100
Apr4,600
May6,200
Jun5,400
Jul7,100
Aug6,500

Loading

Empty

No data to display

Accessibility#

The SVG is decorative (aria-hidden): pixels do not read well to a screen reader. Instead, every full chart renders a visually-hidden data table as its accessible equivalent, so assistive tech gets the real numbers, row by row. Pass label to name the chart, it becomes the table’s caption. loading sets aria-busy. Sparklines stay decorative (no table), since they are labelled by their surrounding context, like a Stat’s value.

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

API reference#

Chart

The root: measures itself, builds the scales and shares them with every part, which draw into one SVG. Renders a visually hidden data table for screen readers. Forwards all native <div> props, ref included. Every part accepts className, merged last.

PropTypeDefaultDescription
data*ChartDatum[] | number[]-A row per category, or a bare number[] for a single value series. null marks a missing point.
indexstring-The key holding each row's category label, for the x-axis and tooltip heading.
configRecord<string, ChartSeriesConfig>-Per series: label, color, format, axis ("left" | "right"), compare (the key it is measured against) and inverted (down is good). A ChartColor is a semantic hue (blue, teal, purple, brand, gray, a status role, blue-200 to blue-800) or current.
domain"auto" | "fit" | [number, number]"auto"auto runs from zero to a nice top; fit wraps the data's own extent; a pair fixes it.
sparklinebooleanfalseChromeless: zero padding, points across the full width, painted in currentColor.
stackbooleanfalseStacks ChartBars and ChartAreas, and sizes the domain to the category total.
palette"categorical" | "tonal""categorical" ("tonal" with stack)How series without a color are painted: distinct hues, or shades of one blue.
paddingPartial<{ top: number; right: number; bottom: number; left: number }>-The plot insets, in px. Raise bottom and left to make room for axes.
animatebooleantrueThe one-shot load reveal. Held under reduced motion.
crosshairbooleantrue (false for sparklines)The hover tracking line, painted behind the data.
activeIndexnumber | null-The hovered category, controlled.
onActiveIndexChange(index: number | null) => void-Called as the pointer crosses categories, and with null when it leaves.
hiddenSeriesstring[]-The series switched off, controlled. They leave the scale, stacks and tooltip.
defaultHiddenSeriesstring[]-The series switched off at first, uncontrolled.
onHiddenSeriesChange(keys: string[]) => void-Called when a series is shown or hidden.
focusedSeriesstring | null-The series in focus, controlled; the rest recede.
onFocusedSeriesChange(key: string | null) => void-Called when the focused series changes.
partialboolean | number-Trailing categories still in progress (true is the last): lines dash, areas fade, bars hatch.
loadingbooleanfalseA Skeleton in place of the plot, with aria-busy.
emptyReact.ReactNode"No data"Shown when data is empty.
labelstring-The accessible name; it also captions the hidden data table. Strongly recommended.

ChartLine

A line series. Forwards SVG <path> props except d.

PropTypeDefaultDescription
dataKeystring"value"The series to plot.
colorChartColor-Overrides the hue from config.
curve"linear" | "monotone""linear"Straight segments, or a smooth curve that never overshoots. Match the area under it.
connectNullsbooleanfalseBridges missing points instead of breaking the line.
dashedbooleanfalseA dashed line for projected data; skips the draw-in.
markEndbooleanfalseA filled dot on the last point.
variant"default" | "comparison"-comparison is the faint dashed ghost of a previous period, the default for a series another one compares against.
hideActiveDotbooleanfalseHides the dot on the hovered point.
strokeWidthnumber-The stroke width.

ChartArea

An area series fading down from its edge; pair it with a ChartLine on top. Forwards SVG <path> props except d.

PropTypeDefaultDescription
dataKeystring"value"The series to fill.
colorChartColor-Overrides the hue from config.
curve"linear" | "monotone""linear"How the top edge joins its points.
connectNullsbooleanfalseBridges missing points instead of leaving a hole.

ChartAreas

Several area series at once, stacked into bands with stack on the root, each with its own edge line. Forwards SVG <g> props.

PropTypeDefaultDescription
keysstring[]-The series to draw, bottom of the stack first. Defaults to every series.
curve"linear" | "monotone""linear"How every band's edges join their points.
connectNullsbooleanfalseBridges missing points instead of leaving a hole.

ChartBar

A single bar series. Forwards SVG <path> props except d.

PropTypeDefaultDescription
dataKeystring"value"The series to draw.
colorChartColor-Overrides the hue from config.
barRationumber0.62Bar width as a fraction of the category band.
radiusnumber8Corner radius at the value end, in px.
label(value: number, index: number) => React.ReactNode-A value label past each bar's end. Give the Chart about 24px of padding.top.
highlightnumber | number[] | "active" | ((datum, index, active) => boolean)-Bars painted in highlightColor: an index, a list, the hovered bar, or a predicate.
highlightColorChartColor"primary"The hue of a highlighted bar.

ChartBars

Several bar series sharing each band: grouped, or stacked with stack on the root. Forwards SVG <path> props except d.

PropTypeDefaultDescription
keysstring[]-The series to draw, in order. Defaults to every series.
barRationumber0.7Group width as a fraction of the category band.
radiusnumber8Corner radius at each bar's value end; a stack rounds its outer segment only.

ChartGrid

Horizontal grid lines on the y ticks. Forwards SVG <g> props.

PropTypeDefaultDescription
rowsnumber4The number of horizontal bands.
showVerticalbooleanfalseAlso draws a line per category.
baselinebooleantrueDraws the zero line a step stronger, when zero is in the domain.

ChartXAxis

The category labels under the plot. Forwards SVG <g> props.

PropTypeDefaultDescription
tickFormatter(value: string | number, index: number) => string-Formats a category label.
intervalnumber | "auto"1Labels every Nth category, or auto: thins by measuring, counted back from the last category.
minTickGapnumber12With auto: the minimum space between labels, in px.
minIntervalnumber1With auto: never label more often than every Nth category.
labelstring-An axis title under the labels. Give the Chart about 24px more padding.bottom.

ChartYAxis

The value ticks, in compact figures (12K, 1.4M) by default. Forwards SVG <g> props.

PropTypeDefaultDescription
countnumber4The number of ticks.
tickFormatter(value: number) => string-Formats a tick, e.g. as currency.
side"left" | "right""left"right labels the secondary scale on the right edge.
labelstring-An axis title along the outer edge. Give the Chart about 20px more side padding.

ChartReferenceLine

A threshold (y) or marker (x) across the plot; compose it after the data. Forwards SVG <line> props except x and y.

PropTypeDefaultDescription
ynumber-Draws a horizontal line at this value.
xnumber-Draws a vertical line at this category index.
labelstring-A label at the line's end.
variant"dashed" | "solid""dashed"The stroke.
colorChartColor-The hue; a muted neutral by default.

ChartTooltip

The hover bands and the shared bubble, a row per series. Takes only the props below.

PropTypeDefaultDescription
valueFormatter(value: number) => string-Formats each value. A series' own format wins.
labelFormatter(value: string | number, datum: ChartDatum, index: number) => React.ReactNode-Formats the heading from the category, its row and index.
footer(datum: ChartDatum, index: number) => React.ReactNode-Extra rows under a hairline; build them with ChartTooltipItem.
sort"none" | "desc" | "asc""none"Orders the rows by value at the hovered category.
totalboolean | string-Adds a total row ("Total", or your label).
maxItemsnumber-Folds the rows past this count into "+N more".
partialLabelReact.ReactNode"In progress"The heading of a partial category.
classNamestring-Merged onto the bubble.

ChartTooltipItem

One tooltip row: swatch, label, right-aligned value. Works in footer and outside a Chart. Forwards native <span> props except children.

PropTypeDefaultDescription
label*React.ReactNode-What the row measures.
value*React.ReactNode-The figure.
colorChartColor-The swatch hue; omit for no swatch.
changenumber | null-A change printed before the value, as a fraction (0.12 is "+12%").
invertedbooleanfalseDown is good: a fall prints green.
ghostbooleanfalseA comparison row with a faint swatch.
dimmedbooleanfalseRecedes the row.

ChartLegend

The key. Inside a Chart it lists the series (or slices) above the plot and focuses, hides and isolates them; outside, a plain key. Forwards all native <div> props.

PropTypeDefaultDescription
configChartConfig-Outside a chart: entries from the same config the Chart takes.
items{ label: string; color?: ChartColor; value?: React.ReactNode; dataKey?: string }[]-Explicit entries; win over config and the chart's series.
align"start" | "center" | "end""start"The alignment of the row.
placement"top" | "bottom""top"Inside a chart: above or below the plot.
interactivebooleantrueHover focuses, click toggles, Alt+click isolates. false for a static key.
maxnumber-Folds the keys past this count into a "+N more" menu.
value"last" | "sum" | "average" | ((key: string) => React.ReactNode)-A figure after each label, summarised from the data.
Data attributeDescription
data-hiddenOn a key whose series is switched off (it also gets aria-pressed="false").

ChartAnnotation

A note pinned to a category: a marker in a lane above the plot that opens on hover. Forwards SVG <g> props except title.

PropTypeDefaultDescription
index*number-The category the note belongs to.
title*React.ReactNode-The headline of the note.
labelReact.ReactNode-What the marker shows (a number, a letter); omit for a dot.
descriptionReact.ReactNode-More detail under the title.
colorChartColor-The marker hue; the foreground by default.

ChartFunnel

Ordered steps as columns, each with a ghost of the drop-off and its conversion from the first. Forwards SVG <path> props except d.

PropTypeDefaultDescription
dataKeystring"value"The count at each step.
colorChartColor-The column hue.
barRationumber0.62Column width as a fraction of the band.
radiusnumber8Top corner radius, in px.
labelfalse | ((value: number, index: number, conversion: number) => React.ReactNode)-The label over each step; the conversion by default, false for none.

ChartPie

A pie or donut, one slice per row named by the Chart's index. Forwards SVG <g> props.

PropTypeDefaultDescription
dataKeystring"value"The value each slice is sized by.
innerRadiusnumber0.62The hole as a fraction of the radius; 0 draws a pie.
gapnumber2Space between slices, in px.
colorsChartColor[]-Slice hues in row order; the palette by default.
valueFormatter(value: number) => string-Formats the value in the slice tooltip.
tooltipbooleantrueA tooltip per slice with its value and share.
childrenReact.ReactNode-Content centered in a donut's hole.

CategoryBar

One whole split into segments in a single bar, standalone (no Chart). Forwards native <div> props except children.

PropTypeDefaultDescription
data*ChartDatum[]-One row per category.
indexstring"label"The key holding each category's name.
dataKeystring"value"The key holding each amount; shares come from the total.
colorsChartColor[]-Segment hues in row order. Give "Other" gray.
palette"categorical" | "tonal""categorical"The hues for categories colors leaves out.
size"sm" | "md" | "lg""md"The track height: 6, 8 or 12px.
valueFormatter(value: number) => string-Formats an amount in the tooltip and legend.
tooltipbooleantrueA tooltip per segment: name, amount and share.
animatebooleantrueSweeps the bar open on mount. Held under reduced motion.
labelstring-What the bar breaks down; leads its accessible name.
childrenReact.ReactNode-Parts under the bar: a CategoryBarLegend.

CategoryBarLegend

The key under a CategoryBar; hovering a key recedes the other segments. Forwards all native <ul> props.

PropTypeDefaultDescription
value"share" | "value" | "both" | "none""share"What follows each name.

FAQ#

Each series part takes a dataKey that names the field in your data rows, for example ChartLine dataKey="revenue". The part resolves its hue from the matching config entry, or you can pass an explicit color.