RadarChart

A headless wrapper for a chart plotting several axes from a shared centre as a polygon. Use it for comparing one item across several quantitative axes that share a scale, such as a skills profile.

Status: beta — implemented and unit-tested in the Svelte canonical; not yet exercised in composed flows.

The component renders a <figure> holding a <div class="radar-chart-graphic" role="img" aria-label> around an inline <svg> that the consumer draws, names the figure with aria-label (from label), and lets the consumer reference a longer description or a real data <table> through aria-describedby. The component draws nothing and ships no scales, colours or animation; it exists to give every chart in the catalog the same accessible, stylable shell.

Implementation Notes

  • Renders <figure class="radar-chart {class}> containing the children
  • The consumer supplies the <svg> (and any legend or caption markup)
  • restProps — including aria-describedby — spread onto the <figure>
  • No internal state, no drawing, no data handling

Props

Prop Type Default Description
class string "" Appended to the base class
label string (required) — Accessible name
children slot (required) — The consumer-drawn inline <svg>
...restProps HTML attributes — Spread onto the root <figure>, e.g. aria-describedby

Usage

<RadarChart label="Radar Chart of example data" aria-describedby="radar-chart-data">
  <svg viewBox="0 0 100 100">…</svg>
</RadarChart>
<table id="radar-chart-data">…</table>

Keyboard Interactions

  • None. The chart is a single image to assistive technology.
  • A referenced data table follows native table behaviour.

ARIA

  • role="img" exposes the chart as one image (its children are presentational)
  • aria-label provides the accessible name
  • aria-describedby (consumer-supplied) references the description or data table

When to Use

  • Comparing one item across several quantitative axes that share a scale, such as a skills profile
  • When the chart needs the catalog's standard accessible shell and a stable class hook
  • When a real data table accompanies the drawing as the accessible alternative

When Not to Use

  • Use BarChart or ColumnChart — easier to read when exact comparison matters
  • Use LineChart — values that change over a continuous axis
  • Use DataTable — precise values for many axes

Headless

This component decides semantics only: the figure element, the image role and the name. It decides no geometry, scale, colour, legend or motion.

Styles

Target .radar-chart for the figure and style the supplied <svg> from consumer CSS. No default styles are included.

Testing

  • Renders a <figure> with class radar-chart and a .radar-chart-graphic child with role="img"
  • label sets aria-label
  • aria-describedby and other rest props reach the figure
  • The consumer svg renders inside the figure

Advice

Pass the radial <svg> (axes, rings, polygon) as children. Describe the axes and values in text or a data table referenced by aria-describedby.

Because role="img" makes descendants presentational, never put interactive controls inside the figure; place legends and toggles next to it.

Data table alternative (added 2026-10-05)

The graphic is wrapped in <div class="radar-chart-graphic" role="img" aria-label>; role="img" is not on the <figure> any more. The optional dataTable (a snippet in Svelte, a prop in React, a named slot in Vue, a projected [dataTable] element in Angular, a DataTable render fragment in Blazor, params.dataTable in Nunjucks, a slot="data-table" child in Web Components) renders the accessible table in <div class="radar-chart-data-table">, a sibling of the graphic and never inside it: role="img" makes its descendants presentational, so a table inside would be invisible to assistive technology. Without a data table the wrapper is not rendered (except Angular, noted above).

Related components

  • bar-chart
  • column-chart
  • line-chart
  • data-table
  • graphic-block — chart wrapper with title and notes

References


Lily™ and Lily Design System™ are trademarks.

Example

Skill scores
Five axesScored from 0 to 10
Show demo markup
<figure class="radar-chart"><div class="radar-chart-graphic" role="img" aria-label="Skills radar across five axes"><svg viewBox="0 0 120 80" width="240" height="160" aria-hidden="true" focusable="false"><polygon points="60,10 105,40 88,70 32,70 15,40" fill="none" stroke="currentColor" stroke-opacity="0.25"/><polygon points="60,22 92,42 78,62 40,60 28,42" fill="currentColor" fill-opacity="0.3" stroke="currentColor"/></svg></div><div class="radar-chart-data-table"><table><caption>Skill scores</caption><tbody><tr><th scope="row">Five axes</th><td>Scored from 0 to 10</td></tr></tbody></table></div></figure>

Graphic only (no data table)

Show markup
<figure class="radar-chart"><div class="radar-chart-graphic" role="img" aria-label="Skills radar across five axes"><svg viewBox="0 0 120 80" width="240" height="160" aria-hidden="true" focusable="false"><polygon points="60,10 105,40 88,70 32,70 15,40" fill="none" stroke="currentColor" stroke-opacity="0.25"/><polygon points="60,22 92,42 78,62 40,60 28,42" fill="currentColor" fill-opacity="0.3" stroke="currentColor"/></svg></div></figure>
Usage example
<RadarChart label="Radar Chart of example data" aria-describedby="radar-chart-data">
  <svg viewBox="0 0 100 100">…</svg>
</RadarChart>
<table id="radar-chart-data">…</table>
Show Svelte source
// In your Svelte component:
import RadarChart from "lily-design-system-svelte-headless/components/RadarChart/RadarChart.svelte";

<RadarChart>
  <!-- content -->
</RadarChart>

Canonical contract

Generated from this component's canonical metadata — the machine-checked source the implementations are held to.

Metadata

  • Component: radar-chart
  • PascalCase: RadarChart
  • Description: a chart plotting several axes from a shared centre as a polygon
  • Status: beta — implemented and unit-tested in the Svelte canonical; not yet exercised in composed flows
  • HTML tag: <figure>
  • CSS class: .radar-chart
  • Interactive: no

ARIA

  • role="img" exposes the chart as a single image
  • aria-label and aria-describedby provide the accessible name and description

Keyboard

  • No keyboard interactions on the chart
  • A data table (when rendered) follows native table keyboard behaviour

Props

  • class: string (default: "") -- appended to the base class
  • label: string (required) -- accessible name
  • children: slot (required) -- the inline <svg>
  • ...restProps: HTML attributes -- spread onto the root <figure>