Radar Chart
Compare séries entre múltiplos eixos que compartilham um único domínio radial.
Visão geral
RadarChart é o wrapper estilizado sobre o RadarChart do recharts, composto sobre o primitive chart do shadcn (ChartContainer). Cada linha de dados (xKey) se torna um raio no grid polar; cada entrada em config se torna um polígono fechado que compartilha um único máximo radial. Use quando você tem três a sete dimensões que devem ser avaliadas juntas - perfis de habilidade, scores de satisfação, análise de gap de capacidade.
Use RadarChart quando nenhuma dimensão única é o destaque e a forma do polígono carrega significado por todo o conjunto. Para comparar uma dimensão ordenada, LineChart lê mais rápido. Para ranquear categorias em uma única métrica, BarChart é mais legível.
A edição React (@gremorie/rx-data) renderiza com recharts dentro do primitive chart do shadcn; a edição Angular (@gremorie/ng-data) renderiza geometria d3 headless dentro de um SVG estilizado. O motor de renderização difere; a superfície pública é idêntica input-por-input.
Anatomia
<radar-chart>
└─ figure (role="img") card surface, aspect-square
├─ svg
│ ├─ polar grid (gridType: polygon | circle)
│ ├─ angle axis (spokes from xKey)
│ └─ radar polygons, one per config key
├─ tooltip overlay (optional via tooltip)
├─ legend (when config has >1 series)
└─ sr-only data tableA edição React compõe esta superfície através do primitive chart do shadcn:
RadarChart
└─ ChartContainer responsive square frame + injects --color-<key>
└─ RadarChart (recharts) polar plot area over the angular axis (xKey)
├─ ChartTooltip hover card (ChartTooltipContent)
├─ PolarAngleAxis spoke labels (xKey)
├─ PolarGrid polygon or circular grid (gridType)
└─ Radar one polygon per seriesPreview
- Desktop
- Mobile
| month | Desktop | Mobile |
|---|---|---|
| Jan | 186 | 80 |
| Feb | 305 | 200 |
| Mar | 237 | 120 |
| Apr | 173 | 190 |
| May | 209 | 130 |
| Jun | 214 | 140 |
'use client';import { RadarChart, type ChartConfig, type ChartDatum,} from '@gremorie/rx-data';const monthlyData: ChartDatum[] = [ { month: 'Jan', desktop: 186, mobile: 80 }, { month: 'Feb', desktop: 305, mobile: 200 }, { month: 'Mar', desktop: 237, mobile: 120 }, { month: 'Apr', desktop: 173, mobile: 190 }, { month: 'May', desktop: 209, mobile: 130 }, { month: 'Jun', desktop: 214, mobile: 140 },];const monthlyConfig: ChartConfig = { desktop: { label: 'Desktop', color: 'var(--chart-1)' }, mobile: { label: 'Mobile', color: 'var(--chart-2)' },};export function RadarChartPreview() { return <RadarChart data={monthlyData} config={monthlyConfig} xKey="month" />;}Instalação
bash npx gremorie@latest add rx-radar-chart bash pnpm dlx gremorie@latest add rx-radar-chart
bash yarn dlx gremorie@latest add rx-radar-chart
bash bunx --bun gremorie@latest add rx-radar-chart
Uso
import { RadarChart } from "@gremorie/rx-data";
import type { ChartConfig, ChartDatum } from "@gremorie/rx-data";
const data: ChartDatum[] = [
{ skill: "Speed", a: 90, b: 60 },
{ skill: "Power", a: 70, b: 80 },
{ skill: "Stamina", a: 85, b: 70 },
{ skill: "Agility", a: 75, b: 90 },
{ skill: "Skill", a: 95, b: 65 },
];
const config: ChartConfig = {
a: { label: "Player A", color: "var(--chart-1)" },
b: { label: "Player B", color: "var(--chart-2)" },
};
export function PlayerComparison() {
return <RadarChart data={data} config={config} xKey="skill" />;
}import { Component } from '@angular/core';
import { RadarChart } from '@gremorie/ng-data';
import type { ChartConfig, ChartDatum } from '@gremorie/ng-data';
@Component({
selector: 'app-player-comparison',
imports: [RadarChart],
template: `<radar-chart [data]="data" [config]="config" xKey="skill" />`,
})
export class PlayerComparisonComponent {
readonly data: ChartDatum[] = [
{ skill: 'Speed', a: 90, b: 60 },
{ skill: 'Power', a: 70, b: 80 },
{ skill: 'Stamina', a: 85, b: 70 },
{ skill: 'Agility', a: 75, b: 90 },
{ skill: 'Skill', a: 95, b: 65 },
];
readonly config: ChartConfig = {
a: { label: 'Player A', color: 'var(--chart-1)' },
b: { label: 'Player B', color: 'var(--chart-2)' },
};
}
API
<RadarChart>
O wrapper estilizado sobre o RadarChart do recharts, composto sobre ChartContainer. Renderiza o frame responsivo, um PolarGrid, o PolarAngleAxis (labels dos raios), um tooltip opcional e um <Radar> por chave de config colorido com var(--color-<key>).
| Prop | Type | Default | Descrição |
|---|---|---|---|
data | ChartDatum[] | - | Dados tabulares. Uma linha por raio. Cada linha carrega o label do raio em xKey mais um valor numérico por chave de config. |
config | ChartConfig | - | Mapeia cada chave de série para { label, color }. A color é qualquer cor CSS ou token, tipicamente "var(--chart-1)" até "var(--chart-5)". ChartContainer injeta cada uma como uma CSS variable var(--color-<key>). |
xKey | string | - | Nome do campo do raio (ângulo) em cada linha. Determina os labels do PolarAngleAxis ao redor do perímetro. |
gridType | "polygon" | "circle" | "polygon" | Forma dos anéis do PolarGrid - polígono de bordas retas (padrão) ou círculos concêntricos. |
tooltip | boolean | true | Alterna o tooltip de hover. |
className | string | - | Mesclado no ChartContainer. O estilo empacotado centraliza o gráfico com um aspect quadrado. |
Compondo com o primitive chart
Para controle total, componha recharts diretamente dentro de ChartContainer usando os primitives exportados. Isso espelha o bloco de radar oficial do shadcn.
| Export | Papel |
|---|---|
ChartContainer | Frame responsivo; injeta as vars --color-<key> por série a partir do config. |
ChartTooltip | Reexport do Tooltip do recharts; combine com ChartTooltipContent. |
ChartTooltipContent | Corpo de tooltip estilizado. |
ChartLegend | Reexport do Legend do recharts; combine com ChartLegendContent. |
ChartLegendContent | Corpo de legenda estilizado. |
useChart | Hook para ler o config ativo dentro de um child customizado. |
Types
| Type | Shape |
|---|---|
ChartDatum | Record<string, string | number> & { fill?: string } - uma linha de dados do chart. |
ChartConfig | Record<string, { label?: ReactNode; color?: string }> - mapa de label e cor por série. |
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
type ChartDatum,
} from '@gremorie/rx-data';
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts';
const config = {
a: { label: 'Player A', color: 'var(--chart-1)' },
b: { label: 'Player B', color: 'var(--chart-2)' },
} satisfies ChartConfig;
export function Example({ data }: { data: ChartDatum[] }) {
return (
<ChartContainer
config={config}
className="mx-auto aspect-square max-h-[250px]"
>
<RadarChart accessibilityLayer data={data}>
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<PolarAngleAxis dataKey="skill" />
<PolarGrid gridType="polygon" />
<Radar
dataKey="a"
fill="var(--color-a)"
fillOpacity={0}
stroke="var(--color-a)"
strokeWidth={2}
/>
<Radar
dataKey="b"
fill="var(--color-b)"
fillOpacity={0}
stroke="var(--color-b)"
strokeWidth={2}
/>
</RadarChart>
</ChartContainer>
);
}Desça a este nível para traços tracejados, preenchimentos de gradiente, dots marcadores nas interseções dos raios ou uma legenda customizada via ChartLegend + ChartLegendContent.
Composição
- Escolha o
xKey- o campo de label do raio. Três a sete raios é o ponto ideal; menos e você obtém um triângulo que esconde a forma, mais e os eixos se aglomeram. - Escreva o
configcom no máximo três séries. Os polígonos permanecem legíveis quando traçados; quatro ou mais ficam difíceis de ler. - Ordene os raios consistentemente entre gráficos na mesma superfície para que os usuários possam comparar formas por memória muscular.
- Escolha o
gridType-polygon(padrão) segue a geometria dos raios;circlelê como um alvo/dartboard quando o alinhamento exato dos raios importa menos.
O chart se auto-dimensiona ao pai através do frame responsivo do ChartContainer, com um aspect quadrado para que os polígonos permaneçam simétricos.
Variações
Comparação multi-série
- Desktop
- Mobile
| month | Desktop | Mobile |
|---|---|---|
| Jan | 186 | 80 |
| Feb | 305 | 200 |
| Mar | 237 | 120 |
| Apr | 173 | 190 |
| May | 209 | 130 |
| Jun | 214 | 140 |
'use client';import { RadarChart, type ChartConfig, type ChartDatum,} from '@gremorie/rx-data';const monthlyData: ChartDatum[] = [ { month: 'Jan', desktop: 186, mobile: 80 }, { month: 'Feb', desktop: 305, mobile: 200 }, { month: 'Mar', desktop: 237, mobile: 120 }, { month: 'Apr', desktop: 173, mobile: 190 }, { month: 'May', desktop: 209, mobile: 130 }, { month: 'Jun', desktop: 214, mobile: 140 },];const monthlyConfig: ChartConfig = { desktop: { label: 'Desktop', color: 'var(--chart-1)' }, mobile: { label: 'Mobile', color: 'var(--chart-2)' },};export function RadarChartPreview() { return <RadarChart data={monthlyData} config={monthlyConfig} xKey="month" />;}const config: ChartConfig = {
a: { label: 'Player A', color: 'var(--chart-1)' },
b: { label: 'Player B', color: 'var(--chart-2)' },
};
<RadarChart data={data} config={config} xKey="skill" />;<radar-chart [data]="data" [config]="config" xKey="skill" />A forma mais comum. Duas séries traçadas deixam o usuário comparar as pegadas dos polígonos num relance. Mantenha a contagem em duas ou três antes que os polígonos sobrepostos derrotem a comparação.
Perfil de série única
<RadarChart
data={data}
config={{ score: { label: 'Score', color: 'var(--chart-1)' } }}
xKey="dimension"
/><radar-chart [data]="data" [config]="config" xKey="dimension" />Para perfis de sujeito único - um jogador, um produto, um time. Um único polígono preenchido lê limpo mesmo com cinco ou seis raios.
Grid de polígono
O gridType padrão. Anéis de polígono de bordas retas seguem os raios, enfatizando a geometria por raio.
<RadarChart data={data} config={config} xKey="skill" gridType="polygon" /><radar-chart [data]="data" [config]="config" xKey="skill" gridType="polygon" />Grid de círculo
Defina gridType como "circle" para círculos concêntricos que leem como um alvo ou dartboard, mantendo os anéis como uma escala radial neutra quando o alinhamento exato dos raios importa menos.
<RadarChart data={data} config={config} xKey="skill" gridType="circle" /><radar-chart [data]="data" [config]="config" xKey="skill" gridType="circle" />Acessibilidade
- o
accessibilityLayerdo recharts adiciona navegação por teclado e anúncios de screen reader para as séries plotadas. - os tokens
--chart-1até--chart-5vêm com contraste WCAG AA contra o fundo do card em ambos os temas claro e escuro. - Labels dos raios: cada tick do
PolarAngleAxisé renderizado como<text>SVG ao redor do polígono, mantendo o mapeamento cor-para-série legível junto com o tooltip. - Limite as séries: mantenha a contagem em duas ou três. Quatro ou mais polígonos sobrepostos derrotam o objetivo visual de comparação de forma.
Relacionados
- LineChart - use uma linha quando uma dimensão ordenada é o destaque.
- BarChart - use barras quando ranquear categorias em uma única métrica.
- RadialChart - layout polar irmão quando as categorias devem ser mostradas como arcos concêntricos.