Chart
Recharts on the six categorical tokens, in sequence. Grid and axes stay recessive on `border` / `muted-foreground`; the tooltip is the floating surface (`popover`, 12px, `shadow-sm`). A series is only a status colour when it *is* that status — never for "series 4".
const config = {
personalCare: { label: "Personal care", color: "var(--chart-1)" },
} satisfies ChartConfig;
<ChartContainer config={config}>
<BarChart data={data}>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="personalCare" fill="var(--color-personalCare)" />
</BarChart>
</ChartContainer>Bar chart — interactive
shadcn's interactive card: the series totals sit in the header as aria-pressed toggles and the chart shows one series at a time, so the number and its bars share a colour. Daily data for three months; the totals are derived from the rows.
Lots by category (bar)
One colour per category, chart-1 through chart-4 in order, with the value on every bar so colour is never the only channel. Legend entries are toggles (aria-pressed); an sr-only figcaption carries the numbers.
Orders per day (line)
Bids and buy-now orders on chart-1 and chart-2; the crosshair snaps to the nearest day and the tooltip lists both.
Order status (stacked bar, semantic)
Cancelled, pending and delivered are opt-in status colours because the series *is* that status — danger, warning, success, never chart-1…6. The stack carries its total on top; the exceptions sit on the baseline so they read against each other.
Recharts gallery
Every example from recharts.org/en-US/examples, ported onto the tokens through `ChartContainer`. Each keeps its Recharts structure and behaviour; where the original exists to show something the system forbids (a gradient, a decorative colour), the note says what it became.
LineChart
Simple Line Chart
Two series on chart-1 and chart-2, the baseline every other example varies. Grid drops its vertical rules and the axes lose their lines, per the house style.
Dashed Line Chart
Dash patterns separate the series without a second colour channel. Given to planned against actual lot views, where the dash already means 'not measured'.
Vertical Line Chart
layout="vertical" puts the categories on the y axis, so the grid flips to vertical rules and the container takes a fixed height instead of aspect-video.
Biaxial Line Chart
Two y axes for two units, listings left and euros right. Both active dots drop to r=4, the size the rest of the page uses.
Vertical Line Chart With Specified Domain
The value axis takes an explicit domain with dataMax + 1000 of headroom, so the widest seller never crosses into the edge.
Line Chart Connect Nulls
The same missing reading twice: broken above, bridged by connectNulls below. Each chart carries its own caption, because the difference is the whole point.
Line Chart With X Axis Padding
Axis padding holds the series 30px off the left and 100px off the right of the plot.
Line Chart With Reference Lines
Two reference lines, one vertical, one horizontal with a rotated label. The original's red became border-strong for the event marker and warning for the GMV ceiling — a threshold the series can breach is exactly what warning is for; labels read on muted-foreground.
Customized Dot Line Chart
A render function per dot, keyed on the value. The green and red emoji faces became a filled success dot above target and a hollow warning ring below, so shape carries the state alongside colour.
Customized Label Line Chart
A custom point label and a rotated custom axis tick. Both take muted-foreground at 11px rather than inheriting the series colour, which would not hold 4.5:1.
Synchronized Line Chart
Three charts share a syncId, so a cursor in one moves all three, and the brush on the middle chart ranges all three. Brush track on surface-2, handles and frame on border-strong.
Line that animates opacity
The line's shape prop swaps in a Curve that fades its stroke in. Recharts 3.8 gives a custom shape no animation progress, so the fade is a 320ms transition driven from React, with a button to replay it and another to swap datasets.
Highlight And Zoom Line Chart
Drag across the plot to zoom both value axes to that range; the selection draws as a ReferenceArea on surface-2 inside a border-strong edge. Zoom out is an outline Button, disabled while the chart is already full width.
Line Chart Has Multi Series
Three series with their own data arrays over overlapping weeks, joined by allowDuplicatedCategory={false}. The config is keyed by series name so legend and tooltip still resolve labels and colours.
Line Chart Axis Interval
The same 100-point series under five tick intervals. The interval is named in a line of text above each chart rather than a Label inside the plot, which had nothing to anchor to.
interval: preserveStart
interval: preserveEnd
interval: preserveStartEnd
interval: equidistantPreserveStart
interval: 1
Line Chart Negative Values With Reference Lines
Numeric axes on both sides of zero: each axis line is dropped where a zero reference line on border-strong already draws it, and the axis titles read on muted-foreground.
Compare Two Lines
Hovering reveals the comparison line, the ad cost base and the gap between the two at the cursor. The original dims everything past the cursor with a hard-stop gradient; here the gmv series splits into two flat keys at the cursor instead, full strength before and 0.25 after.
Dynamic Z-Index Line Chart
Hovering or focusing a legend entry raises that line's zIndex above the others. ChartLegendContent drops recharts' legend mouse handlers, so this one renders its own entries on the same tokens and dims the other series to 0.25 rather than the hovered one.
Tiny Line Chart
A sparkline: no axes, no grid, no tooltip, the container overridden to h-16 w-40. The figcaption still reads the six values.
Animated Time Series
A six-point window slides over a 30-point stream, each step animating in over 320ms. It plays on a timer, so it starts paused behind a Play button.
AreaChart
Simple Area Chart
Two series over the same weeks. The original fades each fill into a vertical gradient; gradients are off-system, so both areas take their series colour flat at 25% under a 2px stroke.
Stacked Area Chart
Three channels stacked into the weekly listings total, chart-1 to chart-3 in order. Stack totals are real: the caption reads the sum, not the top band.
Ranged Area Chart
A [low, high] tuple per point draws the band between the two instead of down to the baseline. The tooltip formats the tuple as a range so it never prints as a comma-joined pair.
Area Chart Connect Nulls
Six charts in three pairs: one series then a stack, each drawn with connectNulls off and on, over data with a missing reading and data with a missing day. Each pair is labelled, and the captions say what actually happens — a lone series is bridged, a stacked one counts as zero and pinches to the baseline.
One series, one missing day
connectNulls off
connectNulls on
Stacked, one missing day
connectNulls off
connectNulls on
Stacked, a whole day and a single series missing
connectNulls off
connectNulls on
Cardinal Area Chart
One dataset under two curve interpolations. d3's curveCardinal needs d3-shape, which this app does not depend on, so the second curve is Recharts' own natural spline — same comparison, no new package.
Percent Area Chart
stackOffset="expand" normalises the stack to 100% while the payload keeps the raw counts. The tooltip states both, which ChartTooltipContent has no shape for, so this one renders its own on bg-popover with the hairline and shadow-sm.
Synchronized Area Chart
One syncId across three charts: hovering any of them moves the cursor and tooltip in all three to the same day. The third series keeps the original's dashed stroke, thinned from 4px to 2px to match the other two.
Tiny Area Chart
No axes, grid or tooltip — the shape is the whole message. Overrides the container's aspect-video with a fixed 64 by 160.
Area Chart Fill By Value
The original splits one area with a gradient stop at zero. Gradients are off-system, so the series splits into two clamped at zero: surplus on --success, deficit on --danger, semantic because each series is that status. The break-even line is chrome on border-strong.
Custom Animation Example
Recharts 3.8 has no animationInterpolateFn or AreaRevealShape (both land after it), so the grow-from-bottom interpolation is not portable. What survives is user-controlled motion: Replay remounts the series, Swap repeats the update animation, both at the system's 320ms ease-out.
Range Area Custom Animation
Range data gives the area an inner baseline path to interpolate as well as an outer one. Same substitution as above — no animationInterpolateFn in 3.8 — and the contrived doubled top series becomes a second honest band, p75 to p99 above p25 to p75.
Area Chart With Custom Events
Every pointer handler on the chart root, typed with MouseHandlerDataParam and getRelativeCoordinate. The original logs to the console; here the last event lands in a polite live region, so it is readable without devtools and announced to a screen reader.
No chart event yet — hover, click or right-click the chart.
Prevent right click menu
onContextMenu calls preventDefault, so the browser menu never opens over the plot. Nothing replaces it, so no action becomes right-click-only.
BarChart
Simple Bar Chart
Two grouped series on chart-1 and chart-2, each bar carrying its value. The original's 10px corners drop to the system's 4px and bars cap at 24px wide.
Stacked Bar Chart
One stack per category with the total on top and the slot behind each bar on surface-2. Tops stay square so the segments read as one column.
Population Pyramid
Two mirrored distributions around zero via stackOffset="sign", the left side stored negative and the axis dropping the sign. Recoloured to chart-1 and chart-2: seller and buyer are categories, not statuses.
Timeline
Absolute [start, end] ranges on one stacked track, a Gantt row per order. The original colours each row from inside a custom shape; here the outcome is the series, so success, danger and running are earned and the legend explains them.
Candlestick
Body is a range bar from open to close, wick an asymmetric ErrorBar behind it. Up closes take success and down closes danger; the wick stays on muted-foreground because ErrorBar takes one colour for the whole series.
Box Plot
Interquartile range as a range bar, whiskers as an ErrorBar, median as a surface-coloured rule through the box, outliers as a Scatter on chart-5. Five sellers instead of 100 synthetic points.
Animated Bar Width
Bars rest at a fifth of their slot and grow to full width on hover, over 320ms ease-out instead of the original 200ms. A transparent hitbox keeps the pointer from falling into the gap, and the tooltip parks on the plot floor. The label inside the bar is dropped: nothing fits at a fifth width.
Waterfall
Each bar starts where the last ended, held as an absolute range. Contributions take success, deductions danger, and the closing total chart-1 because a subtotal is not a status. The figures close: 420 + 210 − 170 − 120 − 60 = 280.
Animated Bar series
A six-minute window sliding over thirty minutes of throughput. recharts 3.8 has no animationMatchBy or animationInterpolateFn, so the custom swipe interpolation is gone; the window still steps and a Play/Pause button owns the timer.
Mix Bar Chart
Two stacked series beside a third standalone bar. The original greys the unfocused series to #eee on legend hover; that reading falls under 3:1, so the legend becomes the house visibility toggle with aria-pressed.
Custom Shape Bar Chart
A bell path instead of a rectangle, with the active bar's outline easing in over 320ms. The decorative seven-colour cycle becomes chart-1 through chart-6, and the value labels stay on muted-foreground because the hues only clear 3:1.
Positive and Negative Bar Chart
Signed bars around a zero reference line, with the y-axis ticks coloured by sign — success above, danger below, neutral and bold at zero. Sign is the subject here, so the status tokens are earned.
Brush Bar Chart
Forty days behind a brush: track on surface-2, frame and travellers on border-strong, traveller labels forced up to muted-foreground because they otherwise inherit the frame's stroke.
Bar Chart With Customized Event
Click a bar to select it. The original logs to the console and carries the state on fill opacity alone; selection here is opacity plus an outline, and a polite live region names what is selected.
Click a bar to select a seller.
Bar Chart With Min Height
minPointSize keeps an 8 and an 18 visible beside values in the thousands. The original's filled label circle becomes the house LabelList so the value is not a second coloured shape.
Bar Chart Stacked By Sign
stackOffset="sign" splits each stack around zero. No stack total: a signed stack has two, one each side, and either label would land on the reference line.
Biaxial Bar Chart
Counts on the left axis, euros on the right, both axes recessive on the house tick style.
Bar Chart with background
The first series draws its full slot behind the bar on surface-2, so the fill reads as a share of capacity.
Bar Chart With Multi X Axis
A second x-axis brackets the months into quarters. The original's red separators become border hairlines and the quarter labels muted-foreground.
Ranged Stacked Bar Chart
Three contiguous latency bands per seller as absolute ranges under one BarStack. The 25px pill stack goes square: stacked bars keep square tops.
Ranged Bar Chart
One bar per day spanning that day's low and high concurrent lot views — a single series with no baseline at zero.
Tiny Bar Chart
No axes, no legend, no tooltip. The container drops aspect-video for a fixed 160×64 box and the caption carries the numbers the shape cannot.
Animate by Scroll
Scroll position is the clock: bars grow as the figure rises through the viewport and shrink if the reader scrolls back. recharts 3.8 has no AnimationControllerProvider, so the progress is measured here and the bars render with isAnimationActive={false}. Reduced motion draws them full height.
Stacked Bar Chart with Horizontal Line
Three cost centres stacked against a budget line. The threshold takes warning, not danger — overspend is recoverable — and the total loses its white pill for the house LabelList.
ComposedChart
Line Bar Area Composed Chart
Four marks on one axis — area, bar, line, scatter — on chart-1 to chart-4 in declaration order. The area fill drops to 20% so the bars in front of it stay legible.
Same Data Composed Chart
One measurement drawn twice, as bars and as a line. The value is duplicated into a field per mark because legend and tooltip identify a series by its dataKey, and two marks sharing a key collapse into one entry.
Vertical Composed Chart
layout="vertical" puts the categories on the y axis, so category names read straight. The grid flips with it (horizontal={false}) and the bars round on the trailing edge; the container takes a portrait ratio instead of aspect-video.
Composed Chart With Axis Labels
Both axes carry a title. Recharts draws the label object as its own text node, outside the tick selector ChartContainer restyles, so the class that matches the ticks goes on the label itself.
Scatter And Line Of Best Fit
Measurements as points, each fit as a two-endpoint line in the same colour. The fits carry legendType and tooltipType "none" so they stay out of both — the tokens' way of doing what the original does with hand-filtered payloads.
Banded Chart
A forecast band behind the actual line, both bridging a week with no forecast via connectNulls. The band is a backdrop rather than a series: surface-2, and legendType and tooltipType "none" instead of the original's custom legend and tooltip components.
Target Price Chart with active Label
Hovering pins the value of each series in the plot instead of gathering them in a tooltip, so the tooltip renders nothing and only its cursor remains. The band drops its own label, which would have printed a tuple.
ScatterChart
Simple Scatter Chart
Two sellers on chart-1 and chart-2, dot size from the z axis. Tooltip rows are named by the axis that produced them, so the axis keys carry the labels.
Three Dim Scatter Chart
The same three measures with a wider z range, star against triangle. Shape repeats what colour says so the two sellers survive a colour-blind reading.
Joint Line Scatter Chart
Points joined by a line, linear for one scheduler and monotone for the other. The line takes the series colour; the fixed z range keeps every dot the same size.
Bubble Chart
Seven single-row charts, one per weekday, bubble area by queue depth on a shared domain. Only the last row prints its hours; the rest keep zero-size ticks so the rows stay aligned.
Custom Animation
Recharts 3.8 has no animationInterpolateFn, so the staggered entrance is three interleaved Scatters offset by animationBegin, each still 320ms ease-out. Replay and the week swap are buttons, so the motion only runs when asked.
Scatter Chart With Labels
A LabelList inside each dot on chart-foreground. The original turned the hovered dot green; a second hue would read as a second series, so it takes an ink ring instead.
Multiple Y Axes Scatter Chart
Two cost scales, cents on the left and a ten-times-larger range on the right, each series bound to its own axis.
Scatter Chart With Cells
A custom Symbols shape per point. The original cycled four web colours plus red and pink; the cycle is now chart-1 to chart-6 in order, symbol and hue advancing together.
Scatter Chart with many points (performance test)
A runtime demo: a thousand points in a hundred series, kept at full count, drawn with isAnimationActive={false} and half-opacity fills. Delivered and cancelled are real statuses, so success and danger are the right tokens.
PieChart
Two Level Pie Chart
Stages inside, the categories that make them up outside, the two totals equal. Both rings run the six hues from the start; radius and the 2px surface stroke separate them, not colour.
Straight Angle Pie Chart
A half pie from 180 to 0 degrees, six stages on chart-1 to chart-6 in order, each slice labelled with its tokens. The legend sits above the arc, the only space a semicircle leaves.
Custom Active Shape Pie Chart
The hovered slice grows an outer arc and a leader line to its numbers. The callout text is ink and muted ink rather than the slice hue: the hues are tuned to 3:1 as fills, not to 4.5:1 as 12px type.
Pie Chart With Customized Label
Percentages drawn inside each slice on chart-foreground. The original dimmed the other slices to 50% on hover, which takes those percentages under 4.5:1, so the hovered slice takes an ink ring instead.
Pie Chart with gap and rounded corners
A ring where paddingAngle and a 50% corner radius turn the slices into separate pills. The gap already separates them, so the 2px surface stroke only shows where a pill meets the background. A legend names the stages the ring cannot label.
Pie Chart With Needle
A gauge: the bands are statuses, so danger, warning and success are the right tokens. The needle is muted-foreground because it points, it does not report a fourth state.
Pie Chart in Flexbox
Three of the same ring in a flex row, each box sized differently, all still square. The chart reads its size from ChartContainer, so the layout is plain Tailwind flex utilities.
Pie Chart in Grid
The same ring across a three-column grid, one chart spanning 2×2, two single cells and one full-width row.
Pie Chart with Gradient
The original filled each slice with a radial gradient. The system has no gradients in charts, so the slices are flat chart-1 to chart-4 and the shape carries the reading on its own.
RadarChart
Simple Radar Chart
One seller's listing readiness across six checks. The web is a 2px stroke with the fill at 0.2 so the grid stays readable through it; the grid itself is `border`, restyled by the container.
Specified Domain Radar Chart
The radius axis is pinned to 0–150 instead of fitted to the data, so two sellers compare on one scale. Both webs take chart-1 and chart-2 at 0.2 fill — the original's 0.6 muddies where they overlap.
Range Radar Custom Animation
Each point is a p50–p95 band rather than a value, and the web grows out of the centre on mount. recharts 3.8 has no `animationInterpolateFn`, so the band is interpolated in state over 320ms ease-out; Replay re-runs it and reduced motion skips straight to the end.
RadialBarChart
Simple Radial Bar Chart
Six shares of this month's GMV, one ring each on chart-1…6, with the rest of the turn as a `surface-2` background sector. The angle axis is pinned to 0–100 so a ring's sweep is its percentage, and the legend moves from the right edge to the bottom.
Radial Bar Chart with Click to Focus Legend
Clicking a legend entry or a ring focuses one seller and dims the rest to 0.25 fill; clicking it again clears. The original's random per-sector palette becomes chart-1…6 in order, and the legend entries are `aria-pressed` buttons so focus is reachable without a mouse.
Treemap
Bundle Size Treemap
Summary tiles over a treemap you drill into a level at a time. The recharts bundle manifest becomes this product's own monthly lot GMV, category → seller → lot, so the nesting still has three levels and fifteen leaves.
- Measured month
- September
- Total GMV
- €1,625
- Largest category
- Household, €450
Simple Treemap
One rectangle per lot, sized by GMV and coloured by the category it belongs to. recharts' default cell hardcodes a white stroke and black labels, so the port supplies content: chart-1…6 by branch, 2px `surface` gutters, and a label only where the cell is wide enough for it.
Custom Content Treemap
The custom cell keeps the branch block solid and its lots transparent, with the category's rank and name inside. Ink is `chart-foreground`, the token for text on a chart fill — `foreground` drops under 4.5:1 on all six hues.
Nested Treemap
`type="nest"`: selecting a category opens its sellers and a breadcrumb back. Depth carries the fill — a branch is the full hue, anything under it a 0.45 tint of the same one.
Treemap with Padding and Gaps
recharts 3.8 has no `nodeInset` / `nodeGap`, so the cell content insets itself — 7px for a category, 4px for a seller, 2px for a lot. The gutter between two siblings is twice their inset, and each category and seller shows as a frame around the GMV underneath it.
SunburstChart
Bundle Size Sunburst
The same GMV tree in polar coordinates: categories on the inner ring, then sellers, then lots. Rings do not overlap, so depth is 1 / 0.7 / 0.45 of the branch hue, mixed against `surface` because SunburstChart takes a colour per node and no opacity.
Sunburst Chart Example
The same hierarchy swept from `startAngle` 90 over `endAngle` 270 degrees, so the ring opens at the top right. recharts prints every arc's value whatever the arc is worth, so the labels are off and the numbers sit in the tooltip and the caption.
Tooltip
Custom Content Of Tooltip
The tooltip is written by hand rather than routed through `ChartTooltipContent`, so it can carry a sentence about the queue under the value. It stays on the system's floating surface: `popover` fill, hairline, 8px radius, `shadow-sm`, 12px text.
Tooltip Style
The original repaints the panel and every part of its text. Panel, edge and type are the container's job here, so what is left to vary is `ChartTooltipContent`'s indicator — dot, line and dashed, side by side, each pinned open with `active`.
indicator="dot"
indicator="line"
indicator="dashed"
Legend
Legend with Opacity
Pointing at or tabbing to a legend entry dims the other lines' strokes to 0.25; the labels never fade, so 12px text stays over 4.5:1. recharts only hands its pointer handlers to the default legend content, so the entries are buttons written here.
Legend Position
The original exposes thirteen `position` values and a pixel offset. The system has three places a legend belongs — over the plot, under it, beside it — set here as `verticalAlign` / `align` on `ChartLegend`.
Custom Legend Styles
The original's panel colour, 2px blue edge, 8px radius and bold 14px labels become `surface-2` in a hairline box at the system's radius, with the emphasis carried by ink rather than weight. Everything else the original sets by hand — type, icon size, inactive colour — is already the container's.
ResponsiveContainer
Area Responsive Container
`ChartContainer` already wraps `ResponsiveContainer`, so nothing is added: the same area chart is shown at `w-full`, `max-w-md` and `max-w-xs`, dropping ticks as it narrows. The original's green minimum and red maximum are not statuses, so both reference lines take `border-strong`.
w-full
max-w-md
max-w-xs
Composed Responsive Container
Area, bar and line on one plot at the same three widths. The bar keeps its 20px size, so at `max-w-xs` the gaps close rather than the bars stretching.
w-full
max-w-md
max-w-xs
Pie Responsive Container
A pie has no ticks to drop, so it scales with its box: `outerRadius` is a percentage and the leader labels follow it in. Slice colours come from `shape`, since recharts 3.8 deprecates `Cell`; the slices are named in the tooltip and the caption, as in the original.
w-full
max-w-md
max-w-xs
XAxis
Multiple X Axes
Once one axis has an `xAxisId`, every axis, every line and the tooltip needs one. Only the day axis carries tick labels; the three value axes are `mirror` rules inside the plot so four scales do not become four rows of numbers.
Automatic X Axis Height
Rotated labels longer than the axis' 30px default get cut off. The original fixes that with `height="auto"`, which recharts 3.8 implements for `YAxis width` only, so the second chart states the height the labels need — 84px, measured for six 18-character labels at 35 degrees.
height={30}
height={84}