- Overview
- shadcn/ui Charts
- Lines and Areas
- Bars and Rankings
- Scatterplots and Relationships
- Distributions
- Heatmaps and Densities
- Intervals and Financial Charts
- Stacked and Composed Charts
- Facets and Multiple Views
- Networks and Hierarchies
- Maps and Spatial Charts
- Polar and Radar Charts
- Annotations and Overlays
- Interactive Charts
- Themes and Motion
Individual Charts
- Apple stock line with seasonal gaps
- Industry unemployment with end labels
- San Francisco temperature range band
- Industry unemployment stacked area
- Sorted vertical bars
- Horizontal ranking with long labels
- Grouped bars
- Stacked bars
- Bubble scatterplot
- Histogram
- Labeled ordinal heatmap
- Anscombe quartet small multiples
- Open-to-close price intervals
- Point estimates with error bars
- Grouped boxplot
- Ranked lollipop chart
- Dumbbell comparison
- Cumulative histogram
- San Francisco temperature moving averages
- Industry share of unemployment
- Streamgraph
- Bollinger band
- Quantitative binned heatmap
- Precipitation calendar heatmap
- Diverging Likert responses
- Parallel coordinates
- Candlestick chart
- Annual gasoline-price waterfall
- Two-period slopegraph
- Scatterplot with linear regression
- Metro inequality change arrows
- Apple close versus moving average
- Pointer-selected tooltip
- Grouped X tooltip
- Tidy hierarchy tree
- Delaunay spatial network
- Filled wind-speed contours
- Point density contours
- Westport House floor plan
- Les Misérables character network
- English letter frequency waffle
- Two-dimensional vector field
- Hexagonally binned density
- Framed guide-free scatterplot
- Empirical cumulative distribution
- Faceted distributions
- Beeswarm distribution
- Log-scale Flare class sizes
- Industry unemployment bump chart
- Indexed industry unemployment
- Directed connected scatterplot
- Scatterplot with marginal histograms
- Annotated AAPL extrema
- Mean penguin mass reducer bars
- AAPL lag-one autocorrelation
- Industry unemployment percentile ribbon
- Ridgeline density comparison
- Violin distribution comparison
- Marimekko survey composition
- Voronoi nearest-point interaction
- Seattle weather with three y axes
- Palmer penguins by species and sex
- Stacked and adjacent Seattle weather bars
- Automobile specifications scatter
- Flare analytics treemap
- Simple radar chart
- English letter frequency pie
- English letter frequency donut
- Survey agreement share gauge
- Snapped axis pointer with grouped tooltip
- Interactive series legend
- Linked chart and data table selection
- Focus and context time window
- Expanding pinned energy tooltip
- Scrollable resource timeline lanes
- Streaming window preservation
- Synchronized cursors across views
- Free cursor over car measurements
- Observed monthly AAPL brush selection
- Wheel zoom and pan over AAPL closes
- AAPL close playback scrubber
- Editable event range
- Letter frequency pie with labels
- Letter frequency donut with total
- Rounded letter frequency donut
- Nested Flare package sizes
- English letter frequency rose
- County unemployment gauge
- Comparative radar chart
- Concentric letter frequency bars
- Flare analytics sunburst
- World learning-poverty choropleth
- World population bubble map
- Orthographic globe with graticule
- HMS Beagle voyage
- Seattle daily high-temperature polar line
- Surface wind polar scatter
- World population-density choropleth
- United States county unemployment choropleth
- Standard world projection gallery
- Basic Sankey
- Sankey
- Staggered entrance motion
- Interrupted spring updates
- Spring line updates
- Definition-owned motion
- Cross-chart geometry morph
- Focus and crosshair motion
- Token use calendar heatmap
- Stacked bars with band and rule cursors
- Themed interactive area card
- Active bar dashboard
- Premium KPI sparklines
- Active donut metric
- Theme palette matrix
- Sales conversion funnel
- Drillable Flare sunburst
- shadcn dashboard
- shadcn Bar Chart - Multiple
- shadcn Pie Chart - Donut with Text
- shadcn Radar Chart - Multiple
- shadcn Radial Chart - Text
- shadcn Tooltip - Advanced
- shadcn Area Chart - Axes
- shadcn Area Chart
- shadcn Area Chart - Gradient
- shadcn Area Chart - Icons
- shadcn Area Chart - Interactive
- shadcn Area Chart - Legend
- shadcn Area Chart - Linear
- shadcn Area Chart - Stacked Expanded
- shadcn Area Chart - Stacked
- shadcn Area Chart - Step
- shadcn Bar Chart - Active
- shadcn Bar Chart
- shadcn Bar Chart - Horizontal
- shadcn Bar Chart - Interactive
- shadcn Bar Chart - Custom Label
- shadcn Bar Chart - Label
- shadcn Bar Chart - Mixed
- shadcn Bar Chart - Negative
- shadcn Bar Chart - Stacked + Legend
- shadcn Line Chart
- shadcn Line Chart - Dots Colors
- shadcn Line Chart - Custom Dots
- shadcn Line Chart - Dots
- shadcn Line Chart - Interactive
- shadcn Line Chart - Custom Label
- shadcn Line Chart - Label
- shadcn Line Chart - Linear
- shadcn Line Chart - Multiple
- shadcn Line Chart - Step
- shadcn Pie Chart - Donut Active
- shadcn Pie Chart - Donut
- shadcn Pie Chart - Interactive
- shadcn Pie Chart - Custom Label
- shadcn Pie Chart - Label List
- shadcn Pie Chart - Label
- shadcn Pie Chart - Legend
- shadcn Pie Chart - Separator None
- shadcn Pie Chart
- shadcn Pie Chart - Stacked
- shadcn Radar Chart
- shadcn Radar Chart - Dots
- shadcn Radar Chart - Grid Circle Filled
- shadcn Radar Chart - Grid Circle - No lines
- shadcn Radar Chart - Grid Circle
- shadcn Radar Chart - Grid Custom
- shadcn Radar Chart - Grid Filled
- shadcn Radar Chart - Grid None
- shadcn Radar Chart - Icons
- shadcn Radar Chart - Custom Label
- shadcn Radar Chart - Legend
- shadcn Radar Chart - Lines Only
- shadcn Radar Chart - Radius Axis
- shadcn Radial Chart - Grid
- shadcn Radial Chart - Label
- shadcn Radial Chart - Shape
- shadcn Radial Chart
- shadcn Radial Chart - Stacked
- shadcn Tooltip - Default
- shadcn Tooltip - Formatter
- shadcn Tooltip - Icons
- shadcn Tooltip - Line Indicator
- shadcn Tooltip - No Indicator
- shadcn Tooltip - Custom label
- shadcn Tooltip - Label Formatter
- shadcn Tooltip - No Label
Stacked and Composed Charts
Stacked charts answer how a total divides into contributions. They work best when the total and a small number of stable components both matter. Interior layers do not share a baseline, so their individual values are harder to compare than the first layer or the total.
Use a normalized stack when proportion matters more than magnitude. Use a mosaic when both column width and internal height carry part-to-whole meaning. Use a streamgraph only when changing shape is the primary story and exact values remain available elsewhere.
Choose the composition#
| Reader question | Start with |
|---|---|
| How do several series contribute to a changing total? | Stacked area |
| How does proportional mix change independently of the total? | Normalized 100% stack |
| How does the overall shape of many positive series evolve? | Streamgraph |
| How do two categorical part-to-whole dimensions interact? | Marimekko or mosaic |
| How much volume remains at each ordered conversion stage? | Funnel |
| Which subgroup values must be compared precisely across groups? | Grouped bars or aligned small multiples |
| Do contributions extend in positive and negative directions? | Diverging stack around an explicit zero |
Single-value bar and area channels stack implicitly. Use layout: stack() when the order or offset must be explicit; supply interval endpoints when the application has already computed them.
Preserve totals with a stacked area#
A stacked area combines a shared ordered x domain with one length per series. The top boundary carries the total; the thickness of each layer carries its contribution.
import { areaY, colorLegend, defineChart, ruleY, stack } from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts/scales/linear'
import { scalePoint } from '@tanstack/charts/scales/point'
import { rows } from './data'
export default defineChart({
marks: [
areaY(rows, {
x: 'quarter',
y: 'revenue',
color: 'business',
layout: stack({ order: ['Core', 'Services'] }),
fillOpacity: 0.8,
}),
ruleY([0]),
],
scales: {
x: { scale: () => scalePoint<string>().padding(0.15) },
y: {
scale: scaleLinear,
grid: true,
axis: { label: 'Revenue (USD thousands)' },
},
},
color: {
domain: ['Core', 'Services'],
range: ['#2563eb', '#14b8a6'],
legend: colorLegend({ label: 'Business' }),
},
})Support files
export const rows = [
{ quarter: 'Q1', business: 'Core', revenue: 42 },
{ quarter: 'Q1', business: 'Services', revenue: 18 },
{ quarter: 'Q2', business: 'Core', revenue: 48 },
{ quarter: 'Q2', business: 'Services', revenue: 24 },
{ quarter: 'Q3', business: 'Core', revenue: 53 },
{ quarter: 'Q3', business: 'Services', revenue: 31 },
{ quarter: 'Q4', business: 'Core', revenue: 59 },
{ quarter: 'Q4', business: 'Services', revenue: 38 },
]Open the full unemployment-by-industry catalog example.
Keep series order stable across updates. Reordering layers can make unchanged values appear to move substantially and breaks the reader's spatial memory. When one series needs precise comparison, place it on the shared baseline or give it a separate aligned view.
The original value remains available to tooltips and selection while the mark derives its stack endpoints.
Center an ordered response scale#
Survey counts are nonnegative, but an ordered response scale often reads as diverging. Group the observations into counts, then anchor the stack on the neutral category:
const counts = groupBy(responses, {
by: { question: 'question', response: 'response' },
outputs: { count: { reduce: 'count' } },
})
barX(counts, {
x: 'count',
y: 'question',
z: 'response',
color: 'response',
layout: stack({
order: ['Strongly Disagree', 'Disagree', 'Neutral', 'Agree'],
anchor: { series: 'Neutral', fraction: 0.5 },
}),
})The grouping transform owns counts and lineage. The stack owns ordered endpoints and the per-question zero translation. Response order, neutral choice, and anchor fraction remain explicit chart meaning.
Compare proportional mix#
A normalized stack gives every x position the same total height. It answers which series gained or lost share, but deliberately removes the original total magnitude.
Format the quantitative guide as a percentage and state the denominator. Keep raw totals available in a tooltip, table, or companion view when the reader may otherwise mistake stable share for stable volume.
Use layout: stack({ offset: 'normalize' }). Normalization is resolved independently at each x position.
Emphasize changing shape#
A streamgraph offsets and orders layers to reduce visible oscillation around a central baseline. It is effective for the broad shape of many positive series, but the displaced baseline makes precise values and totals difficult to read.
The source can stay in tidy form; stacking belongs to the area definition:
areaY(industries, {
x: 'date',
y: 'unemployed',
z: 'industry',
color: 'industry',
layout: stack({ offset: 'wiggle', order: 'inside-out' }),
})Keep the offset and order stable across revisions, preserve series colors, and provide exact values through Tooltips and Focus.
Use an ordinary stacked area when totals or baselines are part of the question.
Show stage attrition#
A funnel encodes the remaining volume at each ordered stage. Use it when the sequence is fixed and values decrease toward one outcome. Use bars when stages can grow, reorder, or need precise comparison on a shared baseline.
The example derives centered left and right endpoints from each raw stage value, then uses one areaX trapezoid per stage. Keep the raw value available to the tooltip and label; the narrowing shape alone is not precise enough for lookup.
Show shares as fixed units#
A waffle chart trades precise length comparison for countable, equal units. Use it when one tile has a clear meaning, such as one percentage point.
waffleY(alphabet, {
y: 'frequency',
color: 'letter',
unit: 0.01,
round: true,
gap: 2,
radius: 2,
})waffleY expands source values internally and preserves each source row for tooltips and selection. unit defines one complete cell; round: true rounds cumulative boundaries so category rounding does not change the overall total. Leave columns unset for responsive square-cell packing, or set it when the grid dimensions are part of the encoding.
Encode two part-to-whole dimensions#
A Marimekko chart uses column width for one categorical total and vertical composition for a second. Each cell is an explicit rectangle with both horizontal and vertical interval endpoints.
The two dimensions have independent denominators: response totals determine each question's column width, while response-category shares determine height within that question. Use groupBy to state the count or sum, then mosaicY to allocate both normalized interval dimensions. Ordinary rect and text marks render the result. Small cells may need a tooltip or adjacent table rather than unreadable direct text.
The transform contract is defined in Data Transforms, and rectangle endpoint semantics are defined in Bar and Rect Marks.
Production checks#
- State whether the chart preserves totals or normalizes every group.
- Keep series order, category order, colors, and keys stable.
- Include zero for ordinary positive stacks and an explicit zero rule for diverging stacks.
- Preserve raw values alongside derived endpoints and proportions.
- Avoid too many layers; group minor categories only when the aggregation is defensible and disclosed.
- Use a legend or direct labels that remain meaningful in light and dark themes. See Legends and Color.
- Verify keyboard focus and exact-value access with Accessibility.
Marks and Layering explains how the interval areas, rules, labels, and highlights compose into one chart.