RadarChart

Several comparable measures as one closed polygon per profile, for comparing shapes across five to eight axes. Every axis shares one radial scale, so the measures have to be normalized to a common range first.

html
<UiRadarChart :data="..." :categoryKey="..." :series="..." :ariaLabel="..." />

Needs the charts module

This component ships in @jgastager/bundy-ui/charts, a separate module so projects that never draw a chart don't carry the paint classes these need. Nothing extra to install — just add the module entry. See Charts.


Data

required

data is one object per axis with one field per profile. Every axis shares a single radial scale, so the fields have to be commensurable — scores out of 100, percentages, ratings. Mixing a count with a percentage on the same radar produces a shape that means nothing.

  • Alice
  • Bob

Every axis shares one radial scale, so the fields have to be comparable quantities. Normalize to a common range first if they aren't, or the shape is meaningless.

There's no animate prop. The marks are plain SVG elements Vue patches directly, so a data change re-renders rather than tweening; what motion there is comes from CSS transitions on hover, which this chart doesn't have.

Category key

required

categoryKey sets which field on each row names its axis.

Series

required

series are the profiles to draw, as field names or { key, label, color } objects. Order assigns the palette slots.

  • Alice
  • Bob
  • Chris

Colors are the library's own semantic ones — primary, secondary, success, warning, error, info, pending, neutral — and any shade of them, primary-400 through primary-950, exactly as the bg-* utilities spell them. Set color per series (or per item) to pin one; leave it unset to take the next slot of the default sequence. neutral and secondary are never handed out automatically, so an unlabelled series never lands on them.

The enclosed area is not a total — it depends on the order the axes happen to sit in. Don't rank profiles by how big they look.

ARIA label

required

ariaLabel is required. A radar is a shape, and without a sentence naming what it plots there's nothing to read.

  • Alice
  • Bob

ARIA description

ariaDescription is the detail the label shouldn't carry — which profile leads where.

Alice leads on speed and recovery; Bob on accuracy, endurance and consistency.
  • Alice
  • Bob

Domain

domain defaults to [0, max]. Radar polygons are only comparable when the scale starts at zero, so pin it explicitly whenever the axes have a known full range — a 0–100 score shouldn't rescale itself because today's best value happens to be 90.

  • Alice
  • Bob
  • Alice
  • Bob

Five to eight axes is the readable range. Below five, a BarChart compares the values more precisely; above eight, the polygon turns to mush and the axis labels collide.

Fill

fill shades each polygon's interior, which reads as an area — right for one or two profiles. Turn it off past two or three, where overlapping translucent shapes stop resolving into anything.

  • Alice
  • Bob
  • Chris
  • Alice
  • Bob
  • Chris

Turn fill off past two or three profiles, where the overlapping fills stop resolving and the outlines carry the comparison better.

Fill opacity

fillOpacity sets how solid each filled polygon is. Lower it when two profiles overlap heavily.

Stroke width

strokeWidth is the polygon outline, in pixels. Worth raising once the fill is off and the outline is all there is.

  • Alice
  • Bob
  • Chris
  • Alice
  • Bob
  • Chris

Rings

rings sets how many rings the grid draws — the radar's equivalent of tick density.

Polygon grid

polygonGrid draws the rings as polygons rather than circles, matching the shape the data traces. Circles read cleaner; polygons make it easier to judge a value against its own spoke.

  • Alice
  • Bob
  • Alice
  • Bob

Guides

guides are the rings, spokes and axis labels. Off, the polygons float on their own — a decorative shape rather than a chart.

  • Alice
  • Bob

guides="false" drops the rings, spokes and axis labels, leaving the profile outlines alone. The polygon keeps its radius either way — a radar reserves no axis margins to reclaim, unlike the cartesian charts.

Legend

legend is on by default from two profiles up, and off for one — a single polygon needs no key.

Legend position

legendPosition sets where the legend sits relative to the plot.

  • Alice
  • Bob

Legend align

legendAlign places the key horizontally. Centre suits a radar, which is itself a centred shape.

  • Alice
  • Bob
  • Alice
  • Bob
  • Alice
  • Bob

Legend orientation

legendOrientation flows the entries in a row or a column. vertical gives each profile its own line.

  • Alice
  • Bob
  • Chris

Height

height is the plot's height in pixels; the radar is sized to fit inside it. It's ignored once aspectRatio is set.

Aspect ratio

aspectRatio sizes the chart from its container's width instead of a fixed height.

  • Alice
  • Bob

Loading

loading is a skeleton at the chart's exact height; an empty data array gets the empty state instead.

  • Alice
  • Bob
No data to display
  • Alice
  • Bob

API Reference

Generated from the component's source — props, slots and emits as the component actually declares them.

Props

Prop
Type
Default
Description
datarequired
Record<string, unknown>[]
One object per axis, with one field per profile. Every axis shares one radial scale, so the fields have to be comparable quantities — normalize to a common range first if they aren't, or the shape means nothing. Five to eight axes is the readable range; below that a bar chart compares them more precisely, above it the polygon turns to mush.
categoryKeyrequired
string
Field holding each row's axis name.
seriesrequired
ChartSeriesInput[]
The profiles to draw.
ariaLabelrequired
string
What the chart shows, for screen readers. Required.
string
A longer accessible description, for detail the label shouldn't carry.
[number, number]
Radial domain. Defaults to `[0, max]`. Radar polygons are only comparable when the scale starts at zero, so the lower bound stays there unless you deliberately override it.
boolean
true
Fills each polygon. Turn it off past two or three profiles.
number
0.18
Fill opacity for each polygon.
number
2
Stroke width in pixels.
number
4
How many rings the grid draws.
boolean
true
Draws the rings as polygons rather than circles, matching the shape the data traces.
boolean
true
Draws the rings, spokes and axis labels.
boolean
Shows the legend. Defaults to on for two or more profiles.
"top" | "bottom"
'bottom'
Where the legend sits relative to the plot.
"start" | "center" | "end"
'center'
Horizontal placement of the legend.
"horizontal" | "vertical"
'horizontal'
How the legend entries flow.
number
340
Height of the plot in pixels. Ignored when `aspectRatio` is set.
number
Width-to-height ratio, sizing the chart from its container's width.
boolean
false
Replaces the plot with a skeleton of the same height.

Types

ts
interface ChartPlot {
    x: number;
    y: number;
    width: number;
    height: number;
    /** Right edge, since marks need it more often than the width. */
    right: number;
    /** Bottom edge, which is also the x axis' baseline. */
    bottom: number;
}
ts
type ChartSeriesInput = string | ChartSeries;