# RadarChart
Values on radial axes, one polygon per series, over a polygon or circle grid.
```ehtml Example
import { RadarChart } from "@elements/ui/chart-radar";
import type { ChartConfig } from "@elements/ui/chart";
```
## Parts
| Part | What it is |
|---|---|
| `RadarChart` | The template. One spoke per row, one polygon per series. |
| `.chart-radar-shape` | One series polygon; --series is its color. |
| `.chart-radar-ring, .chart-radar-spoke` | The grid; .chart-radar-grid.is-filled with grid fill. |
| `.chart-angle-tick, .chart-angle-detail` | A category label and its optional first line. |
| `.chart-radius-tick` | A value tick on the radius axis. |
| `.chart` | The figure. Declares `--color-` for each config entry; keeps a 16:9 box unless sized by class. |
| `.chart-plot` | The focusable plot area holding the SVG; one tab stop. |
| `.chart-tooltip` | The tooltip: heading, one row per item with swatch, name and value, optional footer. |
| `.chart-legend` | The legend row; .chart-legend-item per series, a button with legend toggle. |
| `.chart-table` | The data as a table, visually hidden unless showTable. |
## Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| `data` | `Row[]` | (required) | One row per spoke. |
| `config` | `ChartConfig` | (required) | The chart config: per data key a label, a color (any CSS color, usually var(--chart-N)) or a theme { light, dark }, and an optional icon; legendType and tooltipType; strokeDasharray and strokeOpacity dash and fade a line or an area's edge. Each key becomes `--color-` on the chart. |
| `x` | `string` | (required) | The category field (PolarAngleAxis dataKey). |
| `series` | `string[]` | `[]` | One polygon per value field; empty draws every numeric config key. |
| `outerRadius` | `number \| string` | `"80%"` | px, or a percent of the largest radius that fits. |
| `startAngle` | `number` | `90` | Where the first spoke points, in degrees counter-clockwise from three o'clock. Spokes run clockwise. |
| `innerRadius` | `number \| string` | `0` | Where the value scale and the rings start, px or a percent. |
| `grid` | `boolean \| { type?: "polygon" \| "circle"; radialLines?: boolean; radii?: number[]; fill?: boolean; polarAngles?: number[]; innerRadius?: number \| string; radiusAxis?: number; angleAxis?: number; stroke?: string; strokeDasharray?: string \| number; strokeWidth?: number }` | `true` | The grid: polygon or circle rings at the radius ticks (or at radii px), spokes (at polarAngles if given), and an optional wash of the first series' color; radiusAxis and angleAxis pick the axis it follows; stroke, strokeDasharray and strokeWidth restyle the rings and spokes. |
| `angleAxis` | `boolean \| { tickFormatter?: (value, index) => string; detail?: (row, index) => string; tickMargin?: number; reversed?: boolean; key?: string; series?: string[]; hide?: boolean; axisLine?: boolean; axisLineType?: "polygon" \| "circle"; tickLine?: boolean; tickSize?: number; label?: string; angle?: number } \| AngleAxisOptions[]` | `true` | The category labels; detail adds a first line from the row; an axis line, tick marks and a title; angle turns each label about its point. A list gives the series it names their own spoke order. |
| `radiusAxis` | `boolean \| { angle?: number; tickCount?: number; tickFormatter?: (value) => string; domain?: [number \| "auto" \| "dataMin" \| "dataMax", ...]; ticks?: number[]; allowDecimals?: boolean; reversed?: boolean; series?: string[]; hide?: boolean; axisLine?: boolean; tickLine?: boolean; tickSize?: number; label?: string; orientation?: "right" \| "left" \| "middle"; unit?: string; allowDataOverflow?: boolean; includeHidden?: boolean; niceTicks?: "auto" \| "none"; scale?: "linear" \| "sqrt" \| "log"; type?: "number" \| "category"; range?: [number, number] } \| RadiusAxisOptions[]` | `false` | Value ticks along one spoke, turned across it and set beside it by orientation, with an axis line, tick marks and a title; unit follows the values in the tooltip; allowDataOverflow, includeHidden, niceTicks, scale, type and range shape the scale. A list gives the series it names their own scale. |
| `layout` | `"centric" \| "radial"` | `"centric"` | radial puts each category on a ring from the center out and each value round the turn. |
| `fillOpacity` | `number` | `-1` | 0 to 1. -1 follows the theme. |
| `lines` | `boolean` | `false` | Stroke each polygon in its color. |
| `strokeWidth` | `number` | `0` | Outline width in px; 0 follows the theme. |
| `dots` | `boolean \| { r?: number }` | `false` | A dot on every vertex. |
| `activeDot` | `boolean \| { r?: number }` | `true` | The dots at the active spoke. |
| `connectNulls` | `boolean` | `false` | A missing value closes the polygon over its spoke instead of breaking it. |
| `labels` | `boolean \| LabelOptions \| LabelOptions[]` | `false` | The value (or another field) just outside each vertex. A [low, high] value draws a band. |
| `tooltip` | `boolean \| { indicator?: "dot" \| "line" \| "dashed"; hideLabel?: boolean; hideIndicator?: boolean; color?: string; labelKey?: string; nameKey?: string; labelFormatter?: (label, row) => string; formatter?: (value, key, row) => string; footer?: (row) => string; footerLabel?: string; unit?: string; defaultIndex?: number; cursor?: boolean; filterNull?: boolean; trigger?: "hover" \| "click"; active?: boolean; position?: { x?, y? }; reverseDirection?: { x?, y? }; itemSorter?: "name" \| "value" \| "key" \| (item) => number \| string; includeHidden?: boolean; animationDuration?: number; animationEasing?: string \| (t) => number; isAnimationActive?: boolean }` | `true` | The tooltip: false turns it off; an object sets the indicator, hides the heading or swatches, takes names and headings from other keys, formats them, adds a footer line, or turns off the hover cursor. More options: trigger click (a click shows it and it stays), active (always or never shown), position (a fixed spot), reverseDirection, itemSorter and includeHidden. |
| `legend` | `boolean \| { position?: "top" \| "bottom" \| "left" \| "right" \| "center" \| "insideTop" \| "insideBottom" \| "insideLeft" \| "insideRight" \| "insideTopLeft" \| "insideTopRight" \| "insideBottomLeft" \| "insideBottomRight" \| { x, y }; offset?: number; iconSize?: number; verticalAlign?: "top" \| "middle" \| "bottom"; align?: "left" \| "center" \| "right"; layout?: "horizontal" \| "vertical"; iconType?: "square" \| "rect" \| "circle" \| "line" \| "plainline" \| "diamond" \| "triangle" \| "cross" \| "star" \| "wye" \| "none"; formatter?: (name, key) => string; itemSorter?: "name" \| "key" \| (item) => number \| string; hideIcon?: boolean; nameKey?: string; toggle?: boolean }` | `false` | The legend: above or below the plot, or beside it with verticalAlign middle; position puts it beside the plot, over it at an inside spot or the center, or at a point, offset moves it, iconSize sizes the swatch; align, a vertical layout, the swatch shape (iconType), a name formatter and an itemSorter; names from another key; toggle makes each item a button that hides its series. |
| `margin` | `{ top?, right?, bottom?, left? }` | `{}` | Space around the plot in px; each side defaults to 5. |
| `cx, cy` | `number \| string, number \| string` | `"50%", "50%"` | The center of the chart: px from the left and top edges, or a percentage of the plot. |
| `active` | `number` (two-way) | `-1` | The active item index. Hover and the arrow keys move it; when the pointer leaves it returns to the value it had. |
| `hidden` | `string[]` (two-way) | `[]` | Series keys not drawn. They stay in the legend, where a toggle legend shows them again. |
| `label` | `string` | `"Radar chart"` | The chart's accessible name and its table's caption. |
| `animate` | `boolean` | `true` | Marks enter with motion and move to new values. Off under prefers-reduced-motion. |
| `animation` | `{ begin?: number; duration?: number; easing?: string \| (t) => number; matchBy?: "index" \| "append" \| (item, index) => key; interpolate?: (items, t) => items; newValues?: boolean }` | `{}` | Times the entry and the move to new data. matchBy pairs old and new items by position or by a key, matchByDataKey(field) from the chart package; interpolate draws every frame of a change from the paired items and the eased time; newValues false shows an unpaired new point at once. |
| `showTable` | `boolean` | `false` | Show the chart's data table under the plot. The table is always in the accessibility tree. |
| `class` | `string` | `""` | Classes on the figure. Size the chart here: it keeps a 16:9 box unless given a height or aspect-ratio. |
| `attrs` | `Record` | `{}` | Any other attributes for the figure: id, data-testid, aria-\*. |
| `syncId` | `string` | `""` | Charts with the same syncId share the active item and its tooltip. |
| `syncMethod` | `"index" \| "value"` | `"index"` | Match the shared item by position, or by its category or name. |
| `onActiveChange` | `(index: number) => void` | `() => {}` | The user moved the active item (hover, leave or keys). |
| `onItemClick` | `(index: number) => void` | `() => {}` | A click or tap on an item, with its index. |
| `onHiddenChange` | `(hidden: string[]) => void` | `() => {}` | A legend toggle changed hidden. |
## Keyboard
| Keys | Action |
|---|---|
| `Tab` | Focuses the chart (one tab stop) and shows the tooltip for the item the keys last reached, else the active item, else the first. |
| `ArrowRight / ArrowDown` | Next item. The same under dir=rtl: the plot is not mirrored, so keys follow the screen. |
| `ArrowLeft / ArrowUp` | Previous item. |
| `Home / End` | First and last item. |
| `Escape` | Hides the tooltip. In a dialog, the dialog stays open until the next Escape. |
## Data attributes
| Attribute | Values | On |
|---|---|---|
| `data-chart` | `"bar" \| "line" \| "area" \| "pie" \| "radar" \| "radial"` | figure |
| `data-state` | `"open" \| "closed"` | .chart-tooltip |
| `data-index` | the item index | .chart-hit and pie, radial marks |
| `data-series` | the series key | marks |
| `data-resizing` | present while the chart redraws for a new size | figure |
| `data-entered` | present once the entry motion is over | figure |
| `aria-pressed` | true \| false | .chart-legend-item (toggle) |
## Accessibility
- The plot is one tab stop: role=group, aria-roledescription=chart, named by label, described by the data table.
- The SVG is aria-hidden; a screen reader gets the data from the table, which every chart renders.
- Arrow keys move through the items and each move is announced in a polite live region, for example "February: Desktop 305, Mobile 200".
- Identity is never color alone: a legend for two or more series and labels on the tooltip rows.
- Legend toggles are buttons with aria-pressed.
## See also
- [Chart](chart): What every chart shares: the config and its colors, the tooltip, the legend, the palette and the data table.
- [BarChart](chart-bar): Vertical, horizontal, stacked and grouped bars with tooltip, legend and labels.
- [LineChart](chart-line): Lines over categories with dots, curves, labels and a crosshair tooltip.
- [AreaChart](chart-area): Filled areas, stacked or expanded, solid or gradient, with a crosshair tooltip.
- [PieChart](chart-pie): Pie and donut charts with labels, a center value, an active slice and stacked rings.
- [RadialChart](chart-radial): Radial bars and gauges, with tracks, labels along the arc and a center value.