Skip to content

Radar Chart

The Radar Chart gives each category its own spoke radiating from a shared center and joins one series' values into a filled polygon, so a series is read as a shape. Reach for it to compare a handful of subjects across the same fixed set of measures — skill profiles, product scorecards, survey dimensions. categories fixes the spokes, levels sets the grid rings, max pins the outer ring, and each series takes its own value accessor and fillOpacity. Markers animate in step with the polygon, and labels, legend and format handle the annotation. It works against any Ripl rendering target: Canvas, SVG or a terminal.

NOTE

For the full API, see the Charts API Reference.

Example

Usage

ts
import {
    createRadarChart,
} from '@ripl/charts';

const chart = createRadarChart('#container', {
    data: [/* ... */],
    categories: ['Speed', 'Strength', 'Defense', 'Magic', 'Luck', 'Agility'],
    series: [
        { id: 'player1', value: 'player1', label: 'Player 1' },
    ],
});

Data Format

Each item represents one axis and contains the axis label plus one or more numeric series values:

ts
const data = [
    {
        axis: 'Speed',
        player1: 80,
        player2: 65,
    },
    {
        axis: 'Strength',
        player1: 55,
        player2: 90,
    },
    {
        axis: 'Defense',
        player1: 70,
        player2: 45,
    },
];

The categories option lists axis labels, and each series references a numeric field via value.

Variants

Single series

ts
createRadarChart('#container', {
    data,
    categories: ['Speed', 'Strength', 'Defense', 'Magic', 'Luck'],
    series: [
        {
            id: 'player1',
            value: 'player1',
            label: 'Player 1',
        },
    ],
});

Custom levels and max value

ts
createRadarChart('#container', {
    data,
    categories: ['Speed', 'Strength', 'Defense', 'Magic', 'Luck'],
    levels: 10,
    max: 100,
    series: [
        {
            id: 'player1',
            value: 'player1',
            label: 'Player 1',
            fillOpacity: 0.3,
        },
        {
            id: 'player2',
            value: 'player2',
            label: 'Player 2',
            fillOpacity: 0.3,
        },
    ],
});

Options

A full configuration for this chart. The options every chart shares — padding, title, animation, theme and the rest — behave the same everywhere and are documented on Shared Options.

ts
createRadarChart('#container', {
    data,
    categories: ['Speed', 'Power', 'Range', 'Accuracy', 'Defence'],
    max: 100,
    // Concentric grid rings.
    levels: 5,
    labels: true,
    legend: { position: 'bottom' },
    format: 'number',
    series: [
        {
            id: 'player-1',
            label: 'Player 1',
            value: 'playerOne',
            color: '#7cacf8',
            fillOpacity: 0.3,
        },
    ],
});

Events

Subscribe with chart.on(...). A handler receives an Event object, not the payload directly — the payload is on event.data, and carries the interacted datum plus its { x, y } anchor in chart pixels. event.target and event.stopPropagation() are also available.

ts
// Emitted when a point marker is clicked.
chart.on('markerclick', event => console.log(event.data)); // event.data: RadarChartMarkerEvent
// Emitted when the pointer enters a point marker.
chart.on('markerenter', event => console.log(event.data)); // event.data: RadarChartMarkerEvent
// Emitted when the pointer leaves a point marker.
chart.on('markerleave', event => console.log(event.data)); // event.data: RadarChartMarkerEvent