One <svg> per series, tinted through style.color. Axis, labels, legend and
the hover readout are text and boxes beside the plot, so every chart inherits the
surface it sits on. The paint is window-verified by chart-surface-lifecycle.
import {
AreaChart ,
BarChart ,
ChartLegend ,
ComposedChart ,
DonutChart ,
LineChart ,
PieChart ,
RadarChart ,
RadialChart ,
Sparkline ,
StackedBar ,
} from " @gpuixui/data " ;
< BarChart
aria-label = " Revenue against cost by quarter "
labels = {[ " Q1 " , " Q2 " , " Q3 " , " Q4 " ]}
series = {[
{ key : " revenue " , label : " Revenue " , values : [ 32 , 48 , 41 , 60 ] },
{ key : " cost " , label : " Cost " , values : [ 18 , 22 , 26 , 24 ] },
]}
width = { 320 }
height = { 140 }
/>;
Every cartesian chart shares the frame's options: grid, tooltip, colors,
legend, axis, xLabels, ticks and valueFormat. Hovering a column shows
each series' value; tooltip={false} turns it off.
< BarChart
aria-label = " Signups by month "
labels = { MONTHS }
series = {[{ key : " signups " , label : " Signups " , values : SIGNUPS }]}
orientation = " horizontal " // vertical by default
radius = { 4 }
valueLabels
valueLabelFormat = {(value, series) => `${ series . label } ${ value }` }
/>;
Negative values stand below the axis; a zero paints no bar but keeps its slot.
Prop Type Default Consequence orientation"vertical" | "horizontal""vertical"bars grow up, or right from the axis radiusnumber3the bar's corner, clamped to half its width and height valueLabelsbooleanfalseeach bar's value prints above it valueLabelFormat(value, series, category) => stringvalueFormat, then the valuewhat a bar's label says
< StackedBar
aria-label = " Revenue and cost "
labels = { QUARTERS }
series = {[ revenue , cost ]}
percent // each category reads as 100%
/>;
Prop Type Default Consequence radiusnumber3the segment's corner, clamped to the bar percentbooleanfalsevalues become shares of each category's total, on a 0–100 axis
< LineChart
aria-label = " Churn "
labels = { QUARTERS }
series = {[ churn ]}
curve = " smooth " // linear, smooth or step
dots
showLabels
dotIcons = {[ " check " , " info " , " bell " , " circle " ]}
lineWidth = { 2 }
/>;
Prop Type Default Consequence curve"linear" | "smooth" | "step""linear"a spline through every point, or a held step dotsbooleanfalsea dot paints on every point dashedbooleanfalsethe line paints dashes lineWidthnumber2the stroke's weight, in pixels showLabelsbooleanfalseeach point's value paints above it dotIconsIconName[]none an icon per category paints on each point pointTooltipbooleanfalsea hit zone on every point shows that datum dotIconsIconName[]none an icon per category paints on each point
< ComposedChart
aria-label = " Installs and conversion "
labels = { MONTHS }
series = {[ installs , conversion ]}
lineKeys = {[ " conversion " ]}
/>;
Prop Type Default Consequence lineKeysstring[][]those series paint as lines; the rest paint as bars radiusnumber3the bar's corner, clamped to the bar
< AreaChart
aria-label = " Revenue by quarter "
labels = { QUARTERS }
series = {[ revenue , cost ]}
stacked
gradient
/>;
Prop Type Default Consequence curve"linear" | "smooth" | "step""smooth"how the area's edge joins its points stackedbooleanfalseeach series stands on the one before it gradientbooleantruethe fill fades toward the axis in nested bands fillOpacitynumber0.35the fill's top opacity dotsbooleanfalsea dot paints on every point lineWidthnumber2the edge's stroke weight showLabelsbooleanfalseeach point's value paints above it pointTooltipbooleanfalsea hit zone on every point shows that datum dotIconsIconName[]none an icon per category paints on each point
< PieChart
aria-label = " Traffic by source "
data = { sources }
size = { 160 }
padAngle = { 0.03 }
showLabels
stacked
labelPosition = " outside "
labelFormat = {(datum, share) => `${ datum . label } ${ Math . round ( share * 100 ) } % ` }
activeIndex = { active } // controlled: set it from a press
onSliceActivate = {(datum, index) => setActive ( index )}
/>;
Prop Type Default Consequence dataChartDatum[]— { key, label, value } per slicesizenumber160the ring's square box innerRadiusnumber0 (0.62 for DonutChart)the hole's share of the radius padAnglenumber0.02the gap between slices, in radians legendbooleantruepaints the legend under the ring legendValuesbooleantrueeach legend row prints its value colorsstring[]the theme scale the palette override valueFormat(value: number) => stringone decimal how a value prints centerLabelstringnone words in the ring's centre showLabelsbooleanfalseeach slice's label paints on its arc labelPosition"inside" | "outside""inside"a label inside the arc, or outside with a leader line labelFormat(datum, share) => stringthe datum's label what a slice's label says activeIndexnumbernone that slice stands proud of the ring stackedbooleanfalseeach datum owns a concentric band instead of a slice onSliceActivate(datum, index) => voidnone a press on a slice reports the datum animatebooleanfalsea data change tweens the ring's values animationDurationnumber320how long that tween takes, in ms classNamestring— joined after the recipe testIdstring— the ring's locator; a slice is -layer-<key>
< RadarChart
aria-label = " Coverage by discipline "
labels = {[ " Ship " , " Review " , " Test " , " Design " , " Docs " ]}
series = {[ team ]}
levels = { 4 }
gridShape = " circle "
gridFill
gridAt = {[ 0.25 , 0.5 , 0.75 , 1 ]}
radius = { 80 }
dots
dotIcons = {[ " check " , " circle " , " info " , " bell " , " eye " ]}
axisLabelFormat = {(label) => label . toUpperCase ()}
/>;
Prop Type Default Consequence levelsnumber4the number of webs the grid draws dotsbooleanfalsea dot paints on every corner fillOpacitynumber0.25the series polygon's opacity websbooleantruethe webs and spokes paint gridShape"polygon" | "circle""polygon"the web follows the axes, or rings at each level gridFillbooleanfalsethe webs fill at a low opacity fillbooleantruethe series polygon fills; false draws lines only radiusnumberthe box's half, less padding the outer radius in pixels gridAtnumber[]even levels the webs' radii, as fractions of the outer radius dotIconsIconName[]none an icon per axis paints on every corner axisLabelFormat(label, index) => stringthe label as given how an axis label prints pointTooltipbooleanfalsea hit zone on every corner shows that axis' datum
< RadialChart
aria-label = " Storage by service "
data = { storage }
max = { 100 }
centerLabel = " 62% "
thickness = { 10 }
track
grid
rounded
showLabels
/>;
Prop Type Default Consequence dataChartDatum[]— one concentric ring per datum sizenumber160the plot's square box maxnumberthe largest datum the value a full ring stands for thicknessnumber10one ring's thickness gapnumber4the space between rings trackbooleanfalsea muted ring behind each value gridbooleanfalseguide rings at each quarter of the radius roundedbooleanfalseeach arc's ends round off with a cap showLabelsbooleanfalseeach ring's value prints at the end of its arc animatebooleanfalsea data change tweens the rings' values animationDurationnumber320how long that tween takes, in ms legendbooleantruepaints the legend under the rings colorsstring[]the theme scale the palette override valueFormat(value: number) => stringone decimal how a value prints centerLabelstringnone words at the rings' centre classNamestring— joined after the recipe testIdstring— the chart's locator; a ring is -layer-<key>
< Sparkline aria-label = " Revenue trend " values = { revenue . values } width = { 120 } height = { 32 } />;
Prop Type Default Consequence valuesnumber[]— one point each, in paint order widthnumber120the plot's width heightnumber32the plot's height colorstringthe first categorical swatch the line's colour; a blank one is the default curve"linear" | "smooth" | "step""smooth"how the line joins its points filledbooleanfalsethe line fills down to the floor animatebooleanfalsea data change tweens the line animationDurationnumber320how long that tween takes, in ms classNamestring— joined after the recipe testIdstring— the plot's locator
< ChartLegend
items = {[
{ key : " revenue " , label : " Revenue " , color : series1 },
{ key : " cost " , label : " Cost " , color : series2 },
]}
/>;
Prop Type Default Consequence itemsChartLegendItem[]— { key, label, color, value? } per seriesshape"square" | "dot" | "line""square"the mark beside each row testIdstring— the legend's locator; a swatch is -swatch-<key>
Prop Type Default Consequence seriesChartSeries[]— { key, label, values, color? } per series; a blank label reads as keylabelsstring[]— one label per category widthnumber320the plot's width heightnumber160the plot's height legendboolean | "top" | "bottom"2+ series, bottom where the legend paints legendShape"square" | "dot" | "line""square"the mark beside each legend row axisbooleantruethe y-axis tick column gridbooleantruethe horizontal grid lines xLabelsbooleantruethe category labels ticksnumber4the steps the axis divides its range into colorsstring[]the theme scale the palette override tooltipbooleantruethe hovered column's readout tooltipIndicator"dot" | "line" | "none" | "icon""dot"the mark beside each readout row tooltipIconsIconName[]none an icon per series, when the indicator is "icon" labelFormat(label: string) => stringthe label as given how the hovered category's name prints activeBandbooleanfalsea wash behind the hovered column domain[number, number]all categories the category window a brush leaves, as [start, end) indexes view[number, number]every category the continuous window a zoom shows, in category units zoombooleanfalsea navigation strip that pans on drag and zooms on the wheel onViewChange(view) => voidnone reports each pan or zoom step brushbooleanfalsea brush strip under the plot reports a dragged window onDomainChange(domain) => voidnone reports each drag step as [start, end) animatebooleanfalsea data change tweens its values animationDurationnumber320how long that tween takes, in ms valueFormat(value: number) => stringone decimal how a value prints in the readout classNamestring— joined after the recipe testIdstring— the chart's locator; a series layer is -layer-<key>
< BarChart
aria-label = " Revenue "
labels = { QUARTERS }
series = {[ revenue , cost ]}
tooltipIndicator = " line "
labelFormat = {(label) => ` Quarter ${ label }` }
valueFormat = {(value) => `${ value } k ` }
activeBand
/>;
The readout follows the pointer inside a column. tooltipIndicator marks each
row with a dot, a line or nothing; labelFormat
rewrites the category's name and valueFormat rewrites every value.
< BarChart
aria-label = " Revenue "
labels = { QUARTERS }
series = {[ revenue , cost ]}
legend = " top "
legendShape = " line "
/>;
< ChartLegend
shape = " dot "
items = {[
{ key : " revenue " , label : " Revenue " , color : series1 , value : " 181k " },
{ key : " cost " , label : " Cost " , color : series2 , value : " 90k " },
]}
/>;
legendShape draws a square, a dot or a line before each row; a row with a
value prints it after its label.
< BarChart
aria-label = " Revenue "
labels = { QUARTERS }
series = {[ revenue ]}
view = { view } // controlled: drag the strip to pan, wheel to zoom
zoom
onViewChange = { setView }
/>;
view is a continuous window in category units: an edge of 1.5 puts
category 1 half off the plot's left edge, and a span of two shows two
categories. zoom paints the navigation strip; dragging it pans and the wheel
zooms around the window's centre. Its Reset control returns [0, labels].
< BarChart
aria-label = " Revenue "
labels = { QUARTERS }
series = {[ revenue ]}
domain = { window } // controlled: the drag reports into it
brush
onDomainChange = { setWindow }
/>;
brush paints a strip under the plot; dragging across it reports
onDomainChange for the categories it covers, and the controlled domain is
what the plot paints. domain is the same window as [start, end) indexes;
the chart paints only those categories and measures its axis over them. A stored window that is
reversed, fractional or past the end is normalized to whole indexes inside the
list, and a window that leaves nothing paints the whole chart.
< BarChart
aria-label = " Revenue "
labels = { QUARTERS }
series = {[ revenue , cost ]}
animate
animationDuration = { 320 }
/>;
animate tweens a data change from the values on screen to the new ones;
animationDuration is that run in milliseconds. A chart with a
MotionProvider preference="reduced" above it paints the new values at once —
the resting frame is the same one the tween lands on.
Every example shadcn's charts app ships, and the native chart that answers it.
Every row is now native : a shipped component paints it. The status column
stays so a future gap can be named honestly. Live mounts that row's chart
through the real GPUix web build (/live?scene=parity&only=<id>).
Reference Native Option Status Live chart-area-axesAreaChart axisnative live chart-area-defaultAreaChart gradientnative live chart-area-gradientAreaChart gradientnative live chart-area-iconsAreaChart dotIconsnative — icons paint as a native overlay on each point live chart-area-interactiveAreaChart tooltipnative live chart-area-legendAreaChart legendnative live chart-area-linearAreaChart curvenative live chart-area-stackedAreaChart stackednative live chart-area-stacked-expandAreaChart stackednative live chart-area-stepAreaChart curvenative live chart-bar-activeBarChart activeBandnative live chart-bar-defaultBarChart radiusnative live chart-bar-horizontalBarChart orientationnative live chart-bar-interactiveBarChart tooltipnative live chart-bar-labelBarChart valueLabelsnative live chart-bar-label-customBarChart valueLabelFormatnative live chart-bar-mixedComposedChart lineKeysnative live chart-bar-multipleBarChart seriesnative live chart-bar-negativeBarChart seriesnative live chart-bar-stackedStackedBar percentnative live chart-line-defaultLineChart lineWidthnative live chart-line-dotsLineChart dotsnative live chart-line-dots-colorsLineChart colorsnative live chart-line-dots-customLineChart dotIconsnative live chart-line-interactiveLineChart tooltipnative live chart-line-labelLineChart showLabelsnative live chart-line-label-customLineChart valueFormatnative live chart-line-linearLineChart curvenative live chart-line-multipleLineChart seriesnative live chart-line-stepLineChart curvenative live chart-pie-donutDonutChart innerRadiusnative live chart-pie-donut-activeDonutChart activeIndexnative live chart-pie-donut-textDonutChart centerLabelnative live chart-pie-interactivePieChart onSliceActivatenative live chart-pie-labelPieChart showLabelsnative live chart-pie-label-customPieChart labelFormatnative live chart-pie-label-listPieChart labelPositionnative live chart-pie-legendPieChart legendValuesnative live chart-pie-separator-nonePieChart padAnglenative live chart-pie-simplePieChart datanative live chart-pie-stackedPieChart stackednative — each datum owns a concentric band live chart-radar-defaultRadarChart fillnative live chart-radar-dotsRadarChart dotsnative live chart-radar-grid-circleRadarChart gridShapenative live chart-radar-grid-circle-fillRadarChart gridFillnative live chart-radar-grid-circle-no-linesRadarChart websnative live chart-radar-grid-customRadarChart gridAtnative live chart-radar-grid-fillRadarChart gridFillnative live chart-radar-grid-noneRadarChart websnative live chart-radar-iconsRadarChart dotIconsnative live chart-radar-label-customRadarChart axisLabelFormatnative live chart-radar-legendRadarChart legendnative live chart-radar-lines-onlyRadarChart fillnative live chart-radar-multipleRadarChart seriesnative live chart-radar-radiusRadarChart radiusnative live chart-radial-gridRadialChart gridnative live chart-radial-labelRadialChart showLabelsnative live chart-radial-shapeRadialChart roundednative live chart-radial-simpleRadialChart datanative live chart-radial-stackedRadialChart datanative live chart-radial-textRadialChart centerLabelnative live chart-tooltip-advancedBarChart tooltipnative live chart-tooltip-defaultBarChart tooltipnative live chart-tooltip-formatterBarChart valueFormatnative live chart-tooltip-iconsBarChart tooltipIconsnative — each readout row paints its series' icon live chart-tooltip-indicator-lineBarChart tooltipIndicatornative live chart-tooltip-indicator-noneBarChart tooltipIndicatornative live chart-tooltip-label-customBarChart labelFormatnative live chart-tooltip-label-formatterBarChart labelFormatnative live chart-legend-defaultChartLegend itemsnative live chart-legend-shapesChartLegend shapenative live
One tint per layer: two colours inside one series need two layers.
A category label wider than its slot is clipped at the slot's edge, so two
neighbouring categories never paint over each other.
No zoom, pan or animation between data sets.
A hover readout is per category, not per mark: it names every series' value at
that column rather than the one shape under the pointer.
Edit this page on GitHub packages/data/docs/charts.mdx