
Description
Choose an honest visualization from a user story, metric, comparison, projection, target, or explanatory goal before selecting TanStack Charts marks. Load whenever a user asks to graph, chart, visualize, compare, forecast, project, explain, or communicate data.
SKILL.md
Design a Chart From a User Goal
Use this scenario loop: trigger → inspect → decide → build → verify. Do not begin with a chart type, even when the request names one.
Setup
Turn the request into this brief before writing chart code:
interface ChartBrief {
question: string
decision: string
observation: string
metric: { value: string; unit: string; denominator?: string }
comparison:
'time' | 'category' | 'distribution' | 'relationship' | 'composition'
evidence: readonly string[]
}
export const brief: ChartBrief = {
question:
'Which acquisition channel improved conversion without losing volume?',
decision: 'Choose where to increase next-month spend',
observation: 'one row per channel and month',
metric: { value: 'conversionRate', unit: '%', denominator: 'sessions' },
comparison: 'time',
evidence: ['conversion rate', 'sessions', 'month', 'channel'],
}
If the question, observation, unit, denominator, or decision is unknown, inspect the data and surrounding product before choosing marks.
Core Patterns
Match the form to the reader's comparison
- Change over ordered time → line; discrete periods → bars.
- Named-category magnitude → sorted horizontal bars or dots.
- Distribution → histogram, ECDF, box, violin, or faceted histograms.
- Relationship → scatterplot; add size only for a meaningful third quantity.
- Composition → stack for totals, normalized stack for proportions, mosaic for two categorical dimensions.
- Flow, hierarchy, network, or spatial questions → use their first-party layouts only when topology is the question.
Read the visual-task matrix for the full routing table.
Separate observed, target, and projected values
import { areaY, defineChart, lineY, ruleY } from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts/scales/linear'
import { scalePoint } from '@tanstack/charts/scales/point'
const rows = [
{ month: 'Jan', actual: 82, forecast: null, low: null, high: null },
{ month: 'Feb', actual: 91, forecast: null, low: null, high: null },
{ month: 'Mar', actual: null, forecast: 96, low: 88, high: 106 },
{ month: 'Apr', actual: null, forecast: 103, low: 90, high: 119 },
]
export const chart = defineChart({
marks: [
areaY(rows, { x: 'month', y1: 'low', y2: 'high', fillOpacity: 0.15 }),
lineY(rows, { x: 'month', y: 'actual', strokeWidth: 2.5 }),
lineY(rows, { x: 'month', y: 'forecast', strokeDasharray: '5 4' }),
ruleY([100], { strokeDasharray: '2 3' }),
],
x: { scale: scalePoint },
y: { scale: scaleLinear, axis: { label: 'Indexed revenue' } },
})
Use different channels for status and uncertainty. A continuous unqualified line implies equal epistemic status.
Define proof before polish
For every chart, verify:
- the visual answers the stated question;
- axes, legend, title, or adjacent copy identify units and comparison;
- ordering, aggregation, missing-value policy, and baseline are deliberate;
- exact-value tasks have a table or textual equivalent;
- the smallest supported container preserves the important comparison;
- pointer, keyboard, updates, and empty states tell the same story.
Common Mistakes
CRITICAL Starting with the requested chart type
Wrong: implement “make this a pie chart” before identifying the comparison.
Correct: restate the decision and recommend the form that makes that comparison perceptually direct. If the user retains a weaker form, state its analytical limitation and preserve the underlying semantics.
A familiar chart can answer a different question than the user needs.
Source: docs/guides/choosing-a-chart.md
HIGH Showing a rate without its denominator
Wrong: show conversion rate alone.
Correct: keep sessions or eligible population in the prepared row and expose it beside the rate or in the tooltip.
Normalized values can reverse interpretation when volume changes.
Source: API-FRICTION.md F-217; docs/reference/transforms.md
CRITICAL Rendering projections as observed history
Wrong: connect actuals and forecasts with one undifferentiated line.
Correct: encode the forecast boundary, projected segment, and uncertainty explicitly.
Continuous treatment implies equal certainty.
Source: docs/examples/lines-and-areas.md; docs/reference/marks/difference.md
HIGH Choosing area or angle for precise ranking
Wrong: rank close values with wedges, bubbles, or interior stack layers.
Correct: use aligned position or length when exact ordering is the reader's task.
Area and angle emphasize shape or part-to-whole relationships, not precise rank.
Source: docs/guides/choosing-a-chart.md; docs/examples/bars-and-rankings.md
HIGH Tension: analytical honesty versus visual simplicity
Simplifying aggregation can hide denominators, lineage, uncertainty, or missing-value policy. Preserve the evidence needed to interpret the result before reducing visual detail.
See also: prepare-chart-data/SKILL.md § Common Mistakes
References
See also: prepare-chart-data/SKILL.md and compose-marks-and-views/SKILL.md — the analytical task determines both the transform and mark composition.
More skills from the charts repository
View all 12 skillsbuild-chart-interactions
build chart interactions with TanStack Charts
Aug 15ChartsFrontendInteractionTanStackcompose-marks-and-views
compose marks and views in TanStack Charts
Aug 15ChartsFrontendTanStackUI Componentsconfigure-scales-guides-color
configure scales and guides for TanStack Charts
Aug 15ChartsData VisualizationFrontendTanStackcoordinate-charts-with-tanstack
coordinate TanStack Charts with data sources
Aug 15ChartsData AnalysisData EngineeringFrontend +1debug-and-verify-charts
debug and verify TanStack Charts
Aug 15ChartsDebuggingFrontendTanStackdesign-responsive-charts
design responsive TanStack Charts
Aug 15ChartsData VisualizationFrontendSSR +1
More from TanStack
View publisheraggregation
perform data aggregation in TanStack Table
table
Aug 11Data AnalysisFrontendTanStackapi-not-found
diagnose TanStack Table API errors
table
Aug 11DebuggingFrontendTanStackcell-selection
select rectangular cell ranges in tables
table
Aug 11Data AnalysisTanStackUI Componentscell-spanning
configure cell spanning in TanStack Table
table
Aug 11Data VisualizationFrontendTanStackUI Componentsclient-vs-server
manage TanStack Table data pipelines
table
Aug 11Data PipelineFrontendPerformanceTanStackcolumn-faceting
build faceted filter UIs
table
Aug 11Data VisualizationFrontendTanStack