DocumentationComponentsTheme Creator
Theme CreatorGitHubIntroduction
InstallationUsageThemingMotion
Components
ChartArea ChartBar ChartLine ChartLive Line ChartComposed ChartPie ChartFunnel ChartRadar ChartRadial ChartSankey ChartScatter ChartCandlestick ChartSunburst ChartChoropleth ChartActivity Heatmap
AI agentsContributing
  1. Components
  2. Radar Chart

Radar Chart

Token-driven radar (spider) chart built on Recharts v3 for comparing multiple metrics across one or more series, with full light/dark theming.

$ pnpm add @tessinaui/ui

When to use

  • Comparing profiles. A radar is good at shape: a profile you can recognise and compare at a glance, such as scores or ratings across the same measures for a few options.
  • A handful of axes. Three at minimum, eight is a comfortable maximum. Below three the polygon degenerates; the largest we found in the wild is a product that caps itself at twelve.
  • Metrics on one scale. All axes share one scale. If your metrics are not comparable, normalise them before plotting and say so in the description.
  • An order that means something. The same numbers make a different shape when reordered, so choose an order (a workflow, a ranking, a fixed template) and keep it stable across charts.
  • Up to three series. Use series to plot only the keys you want, or fillOpacity={0} to read the shapes as outlines.

When not to use

  • For exact magnitudes. Readers judge radial length less accurately than aligned length, and a filled area grows with the square of its values, so a series twice as high looks four times as big. If the question is "which is larger, and by how much", use a Bar Chart.
  • For change over time. Use a Line Chart or an Area Chart.
  • For parts of a whole. Use a Pie Chart.
  • With more than about three series. Past that, filled areas hide one another. Use fillOpacity={0} for outlines, or split into small multiples.
  • With long axis names. A name past 80px wraps at its word breaks, and the plot shrinks until every name sits inside the chart, so a long single word in a narrow card leaves little room for the shape. A custom tick wraps only if you wrap it.
  • For metrics on different scales that you have not normalised.

Installation

Terminal
pnpm add @tessinaui/ui recharts

Usage

example.tsx
import { RadarChart } from "@tessinaui/ui";
import type { ChartConfig } from "@tessinaui/ui";

const config: ChartConfig = {
  productA: { label: "Product A", color: "var(--chart-1)" },
  productB: { label: "Product B", color: "var(--chart-3)" },
};

const data = [
  { metric: "Speed", productA: 120, productB: 90 },
  { metric: "Reliability", productA: 98, productB: 130 },
  { metric: "Comfort", productA: 86, productB: 130 },
];

<RadarChart data={data} config={config} categoryKey="metric" />

Examples

Default

A single-series radar comparing one product across six metrics.

Multiple series

Two radars overlaid in distinct brand tones, with a legend.

Sizes

Three square size caps — sm, md, and lg.

Lines only

Outline-only radar with fillOpacity={0} so the shape reads as a stroke.

Grid types

Four grids: concentric polygons (default) or circles via gridType, rings without spokes via radialLines={false}, and no grid at all.

Radius axis and a pinned scale

showRadiusAxis puts the value scale on the chart, and maxValue pins the outer ring. Without it the outer ring is the largest value in your data, so a dataset topping out at 72 paints a full-radius polygon and reads as a perfect score.

Values on the axis labels

Pass a PolarAngleAxis through children to take over the axis labels — Recharts keys polar axes by id, so yours replaces the chart's own rather than drawing a second one on top.

Icon labels

The same seam, with a decorative glyph above each axis name. Keep the name as text: an icon alone is not readable to assistive tech or at 200% zoom.

Filtering series

series is the filter — pass the keys you want plotted and the chart draws exactly those. No extra API is needed for a rater or category picker.

On a coloured plate

Inside a coloured Surface the chart's chrome takes the plate's ink with no prop: axis labels, the value scale, grid lines and spokes, the legend and the focus ring. Series colours are yours. The --chart-N tokens are measured against the page, not a plate, so give a series the plate's ink (hsl(var(--surface-ink))). One series reads best: a second can drop to 80% of the ink and no further, and two fills in one ink merge, so plot two as outlines (fillOpacity={0}). The tooltip is a page panel, so it keeps the page's look.

States

The loading skeleton alongside the empty state.

API Reference

PropTypeDefaultDescription
dataRecord<string, string | number | null>[]—One row per axis (spoke).
configChartConfig—Series metadata (label, color).
categoryKeystring—Datum key for the angular axis.
seriesstring[]all config keysWhich series to plot.
fillOpacitynumber0.1Per-series fill opacity.
showDotsbooleantrueVertex markers.
size"sm" | "md" | "lg""md"Square size cap.
radialLinesbooleantrueDraw the spokes running out to each axis.
showRadiusAxisbooleanfalseShow the radial value scale.
maxValuenumberdata maxPin the radial scale to [0, maxValue].
categoryFormatter(value: string) => string—Format the axis (spoke) labels.
valueFormatter(value, index) => string—Format radial tick text, e.g. "70%".
showGrid / showLegend / showTooltipboolean—Toggle chart chrome.
labelstring—Accessible name — renders role="figure". State the insight.
descriptionstring—Visually hidden summary read after the label.
childrenReactNode—Recharts children rendered inside the chart.
loadingbooleanfalseRender the skeleton.
errorReactNode—Render an error message instead of the chart.
emptyStateReactNode"No data to display"Shown when data is empty.

Accessibility

  • Give every chart a label. It names the figure to assistive tech; description carries the numbers a sighted reader gets from the shape.
  • Never let colour be the only channel. Series are named in the legend and in the tooltip.

VoiceOver + Safari: passed 2026-09-14. A static read gives "Product A scores highest on speed and lowest on design, figure" and the axis labels. Tab lands on the plot, which VoiceOver reads after the figure name as "web application", and the arrow keys read each point through the tooltip ("Reliability, Product A, 98"). NVDA and JAWS are untested.

Recharts' accessibilityLayer is on: the chart takes focus and the arrow keys step between points, announcing each through the tooltip's polite live region. VoiceOver users need QuickNav off for the arrow keys to reach the chart.

Funnel ChartRadial Chart

On this page

When to useWhen not to useInstallationUsageExamplesDefaultMultiple seriesSizesLines onlyGrid typesRadius axis and a pinned scaleValues on the axis labelsIcon labelsFiltering seriesOn a coloured plateStatesAPI ReferenceAccessibility