Component

RadarChart

Polygon-based profile chart for scouting and editorial workflows. Use it when the story is the overall shape of a profile across ordered axes.

525507595GoalsxGxGOTShotsShots on targetxABig chances createdBox touches
Attacking
Possession
Stories

Canonical behaviors.

Category Legend

Multiple categories tint the axis labels and emit a grouped legend.

525507595GoalsxGxGOTShotsShots on targetxABig chances createdBox touches
Attacking
Possession
Banded Rings

Editorial ring treatment instead of plain ring lines.

102030405060708090GoalsxGxAShotsShots on targetBig chancescreatedBox touchesPossessionPass completion
Attacking
Possession
Banded Rings Inside Polygon

Bands render only inside the profile polygon — the classic StatsBomb scouting radar look. Optional outerRingColors adds a full-circle alternating-grey background; spoke-tick labels inside the polygon auto-invert to white bold for contrast.

102030405060708090GoalsxGxAShotsShots on targetBig chancescreatedBox touchesPossessionPass completion
Attacking
Possession
Multi-Profile Comparison

Pass `series` to overlay two (or more) players. Hover any slot to see all values at once. `showVertexValues` labels every vertex with a coloured pill — useful when scouts want values visible without hovering.

5255075951.00.2620.7123.02.00.1061.09.04.02.2119101.073.036GoalsxGxGOTShotsShots on targetxABig chances createdBox touches
M. Salah
Liverpool (team avg.)
Attacking
Possession
Series "Liverpool (team avg.)" has a different metric set from the primary series; missing metrics render at 0.
Raw-Value Mode

Per-axis min/max normalization with raw values rather than percentiles.

0.150.30.450.571.1252.253.3754.27512.87525.7538.62548.92521.2542.563.7580.750.10.20.30.380.751.52.252.850.16250.3250.48750.61751.1252.253.3754.2751.510.50.10.6251.251.8752.3755.62511.2516.87521.375Non-PenaltyGoalsShotsShooting %Passing %AssistsKey PassesThroughballsInt+TacklesDispossessedSuccessfulDribblesGoalConversion %
Dense Ticks

Finer ring steps for pages that want a more explicit scale.

0.120.180.240.30.360.420.480.540.60.91.351.82.252.73.153.64.054.510.315.4520.625.7530.936.0541.246.3551.51725.53442.55159.56876.5850.080.120.160.20.240.280.320.360.40.60.91.21.51.82.12.42.730.130.1950.260.3250.390.4550.520.5850.650.91.351.82.252.73.153.64.054.51.61.41.210.80.60.40.200.50.7511.251.51.7522.252.54.56.75911.2513.515.751820.2522.5Non-PenaltyGoalsShotsShooting %Passing %AssistsKey PassesThroughballsInt+TacklesDispossessedSuccessfulDribblesGoalConversion %
Dark Theme

ThemeProvider restyles the chart without changing the row model.

102030405060708090GoalsxGxAShotsShots on targetBig chancescreatedBox touchesPossessionPass completion
Attacking
Possession
Sparse Profile

Few metrics still render, but the radial read is much weaker.

525507595GoalsAssistsTacklesPressures
Empty State

No rows means no polygon.

No profile data
Static Export

RadarChart is part of the stable export union through the bounded export prop surface.

525507595GoalsxGxGOTShotsShots on targetxABig chances createdBox touchesAttackingPossession
Recipes

Composition patterns.

Methodology Notes

Use the shared chart-frame note seam for sample and role context instead of rebuilding prose around the card.

Percentiles vs Premier League forwards, minimum 900 minutes
5255075951.00.2620.7123.02.00.1061.09.0GoalsxGxGOTShotsShots on targetxABig chances createdBox touches
Attacking
Possession
Keep overlay radars to two or three profiles before the polygon read stops being honest
Cross-cutting

Shared concerns.

Choose RadarChart

Use RadarChart when axis order and overall profile shape matter more than exact bar-to-bar comparisons.

Ordering Matters

Metric order is part of the visual meaning. Reordering axes changes the shape the reader perceives.

Percentile Vs Range

Percentiles are the default scouting read. Range mode is useful only when you have defensible per-metric min/max bounds.

Composition

RadarChart is best as a standalone profile card. Use surrounding text to explain role, sample, and comparison context.

Export / Static

RadarChart is part of the stable export union, but only through the bounded export prop surface. Shared methodology notes stay in the live React path.

Responsive Behavior

Circular charts fail at the labels first. On narrower widths the polygon and ring read should survive before dense outer text does. Use radarChartRecipes.smallMultiples when the surrounding layout already names the metrics.

Responsive

Width pressure.

Compact Container

At smaller widths the polygon and ring structure should survive before dense outer labels do.

525507595
Wide Profile Card

Wider layouts preserve more label separation and category-legibility around the ring.

525507595GoalsxGxGOTShotsShots on targetxABig chances createdBox touches
Attacking
Possession
Usage

Best-practice examples.

Minimal usage

Pass rows with percentile values and categories. The component handles the polar layout and category legend.

                    import { RadarChart } from "@withqwerty/campos-react";

export function PlayerRadar({ rows }) {
  return <RadarChart rows={rows} />;
}
                  
Recipe-driven comparison

Use named radar recipes for benchmark looks and comparison chrome instead of rebuilding the same prop combinations per card.

                    import {
  mergeChartRecipeProps,
  RadarChart,
  radarChartRecipes,
} from "@withqwerty/campos-react";

export function PlayerRadarComparison({ series }) {
  return (
    <RadarChart
      series={series}
      {...mergeChartRecipeProps(
        radarChartRecipes.statsbomb,
        radarChartRecipes.comparison,
      )}
    />
  );
}
                  
API

Public surface.

Prop Type Default Description
rows RadarChartRow[] Single-profile shorthand. Equivalent to series: [{ id: 'default', rows }]. Pass this OR `series`, not both.
series { id, label?, rows, color? }[] Multi-profile overlay. One polygon per series; default colours come from a blue/red/green palette. Each series can override via color.
seriesColors string[] ['#3b82f6','#ef4444','#22c55e', …] Palette used to auto-assign colours across series.
showVertexValues boolean false Render a coloured pill at each vertex showing the row's displayValue. Typical for scouting comparison radars where values should be readable without hovering.
metricOrder string[] undefined Explicit metric order starting at 12 o'clock, clockwise.
categoryOrder string[] undefined Explicit category grouping order for the legend and axis tinting.
valueMode "percentile" | "range" "percentile" Normalization mode.
showLegend boolean auto Show the category legend.
showVertexMarkers boolean true Show dot markers at polygon vertices.
showAxisLabels boolean true Show metric labels around the outer ring.
ringStyle "line" | "banded" | "banded-inside-polygon" "line" Concentric ring style. 'banded-inside-polygon' clips the bands to the profile polygon for the classic StatsBomb radar look; polygon fill defaults to transparent.
ringSteps number[] [0.05, 0.25, 0.5, 0.75, 0.95] Normalized positions for ring lines and ticks.
bandSteps number[] same as ringSteps Normalized positions for banded fills.
ringColors string[] subtle alternating greys Per-ring fill colors for banded radar styles.
outerRingColors string[] undefined Full-circle background band palette. Only active when ringStyle='banded-inside-polygon'. Pairs with ringColors (used inside the polygon) for the classic StatsBomb grey-background, coloured-polygon look.
areas RadarChartAreasStyle First-class styling surface for the profile polygon and vertex markers.
categoryColors string[] football scouting palette Per-category palette for axis tinting and legend entries.
guides RadarChartGuidesStyle First-class styling surface for rings and spokes.
text RadarChartTextStyle First-class styling surface for outer metric labels.
methodologyNotes ChartMethodologyNotes Shared chart-frame note regions for sample and role context.

`methodologyNotes` are supported in the live React surface, but they stay outside the stable `ExportFrameSpec` contract.

Use with AI
LLM Prompt
Create a React component using Campos RadarChart. Import RadarChart and radarChartRecipes from @withqwerty/campos-react, keep row shaping outside the component, show the smallest good usage first, then one recipe-driven comparison or benchmark-look variant.