Skip to main content
Gremorie

Radial Chart

Concentric radial bars - one ring per data row with sweep proportional to value.

Overview

RadialChart is a recharts chart built on the shadcn chart primitive (ChartContainer) for concentric polar bars. Each data row produces one bar around the chart center; each bar sweeps proportionally to its dataKey value. Bar colors come from each row's fill (e.g. fill: "var(--chart-1)"), and an optional config supplies the labels shown in the tooltip.

Reach for RadialChart when you want a compact, decorative ranking of three to five items - top categories, leading drivers, ranked metrics in a hero card. For exact comparison BarChart reads faster; for share-of-whole at a glance PieChart is more familiar.

The React edition (@gremorie/rx-data) renders with recharts inside the shadcn chart primitive; the Angular edition (@gremorie/ng-data) renders headless d3 geometry inside a styled SVG. The rendering engine differs; the public surface is identical input-for-input.

Anatomy

<radial-chart>
└─ figure (role="img")                  card surface, aspect-square
   ├─ svg
   │  └─ concentric bars, one per row
   │     └─ row fill colored (palette / per-row fill)
   ├─ tooltip overlay (optional via tooltip)
   ├─ legend
   └─ sr-only data table

The React edition composes this surface through the shadcn chart primitive:

ChartContainer                     responsive square frame + tooltip label config
└─ RadialBarChart                  recharts polar plot area
   ├─ ChartTooltip                 hover card
   │  └─ ChartTooltipContent       themed tooltip body
   ├─ PolarGrid                    circular grid
   └─ RadialBar                    one bar per row, with a faint background track

Preview

'use client';import {  RadialChart,  type ChartConfig,  type ChartDatum,} from '@gremorie/rx-data';// Categorical (pie / radial): one chart token per row via `fill`.const browserData: ChartDatum[] = [  { browser: 'Chrome', visitors: 275, fill: 'var(--chart-1)' },  { browser: 'Safari', visitors: 200, fill: 'var(--chart-2)' },  { browser: 'Firefox', visitors: 187, fill: 'var(--chart-3)' },  { browser: 'Edge', visitors: 173, fill: 'var(--chart-4)' },  { browser: 'Other', visitors: 90, fill: 'var(--chart-5)' },];const browserConfig: ChartConfig = {  visitors: { label: 'Visitors' },  Chrome: { label: 'Chrome' },  Safari: { label: 'Safari' },  Firefox: { label: 'Firefox' },  Edge: { label: 'Edge' },  Other: { label: 'Other' },};export function RadialChartPreview() {  return (    <RadialChart      data={browserData}      config={browserConfig}      nameKey="browser"      dataKey="visitors"    />  );}

Installation

bash npx gremorie@latest add rx-radial-chart

bash pnpm dlx gremorie@latest add rx-radial-chart

bash yarn dlx gremorie@latest add rx-radial-chart

bash bunx --bun gremorie@latest add rx-radial-chart

Usage

import { RadialChart, type ChartConfig, type ChartDatum } from "@gremorie/rx-data";

const data: ChartDatum[] = [
{ category: "Chrome", visitors: 275, fill: "var(--chart-1)" },
{ category: "Safari", visitors: 200, fill: "var(--chart-2)" },
{ category: "Firefox", visitors: 187, fill: "var(--chart-3)" },
{ category: "Edge", visitors: 173, fill: "var(--chart-4)" },
];

const config: ChartConfig = {
visitors: { label: "Visitors" },
Chrome: { label: "Chrome" },
Safari: { label: "Safari" },
Firefox: { label: "Firefox" },
Edge: { label: "Edge" },
};

export function TopBrowsers() {
  return (
    <RadialChart data={data} config={config} nameKey="category" dataKey="visitors" />
  );
}
import { Component } from '@angular/core';
import { RadialChart } from '@gremorie/ng-data';
import type { ChartConfig, ChartDatum } from '@gremorie/ng-data';

@Component({
selector: 'app-top-browsers',
imports: [RadialChart],
template: `     <radial-chart [data]="data" [config]="config" nameKey="category" dataKey="visitors" />
  `,
})
export class TopBrowsersComponent {
readonly data: ChartDatum[] = [
{ category: 'Chrome', visitors: 275, fill: 'var(--chart-1)' },
{ category: 'Safari', visitors: 200, fill: 'var(--chart-2)' },
{ category: 'Firefox', visitors: 187, fill: 'var(--chart-3)' },
{ category: 'Edge', visitors: 173, fill: 'var(--chart-4)' },
];

readonly config: ChartConfig = {
visitors: { label: 'Visitors' },
Chrome: { label: 'Chrome' },
Safari: { label: 'Safari' },
Firefox: { label: 'Firefox' },
Edge: { label: 'Edge' },
};
}

API

<RadialChart>

A recharts radial bar chart composed inside the shadcn chart primitive (ChartContainer). One concentric bar per row; bar colors come from each row's fill, and the optional config provides the labels shown in the tooltip.

PropTypeDefaultDescription
datareadonly ChartDatum[]-Tabular data. One row per bar. Each row needs a string field at nameKey, a numeric field at dataKey, and a fill for its bar color (e.g. var(--chart-1)).
nameKeystring-Name of the category label field. Used to resolve the tooltip label.
dataKeystring-Name of the numeric value field. The sweep of each bar is proportional to this value relative to the max across rows.
configChartConfig{}Optional label/color map keyed by category name (and value key). Powers the tooltip labels.
tooltipbooleantrueToggles the hover tooltip (ChartTooltip + ChartTooltipContent).
classNamestring-Merged onto the ChartContainer. The bundled style supplies a centered, square aspect frame.

Chart primitives for custom composition

For full control, compose raw recharts inside ChartContainer using the shadcn chart primitives, all re-exported from @gremorie/rx-data. This mirrors the official shadcn radial block (ui.shadcn.com/charts/radial).

ExportRole
ChartContainerResponsive frame; injects per-key CSS color vars (--color-<key>) from config.
ChartTooltip / ChartTooltipContentHover card and its themed content.
ChartLegend / ChartLegendContentOptional legend and its themed content.
useChartHook returning the active config from context (use inside custom children).
RadialBarChart, RadialBar, PolarGrid, LabelRaw recharts primitives composed inside ChartContainer.

Types

TypeShape
ChartDatumRecord<string, string | number> & { fill?: string } - one row of chart data; fill sets the per-bar color.
ChartConfigMap of key → { label?, icon?, color? }; provides tooltip/legend labels (and optional colors).

Bar colors come from each row's fill (e.g. fill: "var(--chart-1)"), not from config. The optional config maps each category name to a {label} and drives the labels shown in the tooltip.

Composition

  1. Pick nameKey and dataKey - the label column and the numeric column. Both must exist on every row.
  2. Set a fill per row - point each row at a --chart-* token (e.g. fill: "var(--chart-1)"). This is where bar colors come from.
  3. Add a config mapping each category name (and the value key) to a { label } so the tooltip reads cleanly.
  4. Order rows by magnitude. The largest value sits on the outer bar; the smallest on the innermost. The decreasing radius reinforces ranking visually.
  5. Cap the row count at three to five. Six or more bars get visually noisy and lose the ranking signal.

The chart auto-sizes to its parent through ChartContainer (recharts ResponsiveContainer). The frame forces aspect-square so the bars stay circular.

Variations

Default ranking

'use client';import {  RadialChart,  type ChartConfig,  type ChartDatum,} from '@gremorie/rx-data';// Categorical (pie / radial): one chart token per row via `fill`.const browserData: ChartDatum[] = [  { browser: 'Chrome', visitors: 275, fill: 'var(--chart-1)' },  { browser: 'Safari', visitors: 200, fill: 'var(--chart-2)' },  { browser: 'Firefox', visitors: 187, fill: 'var(--chart-3)' },  { browser: 'Edge', visitors: 173, fill: 'var(--chart-4)' },  { browser: 'Other', visitors: 90, fill: 'var(--chart-5)' },];const browserConfig: ChartConfig = {  visitors: { label: 'Visitors' },  Chrome: { label: 'Chrome' },  Safari: { label: 'Safari' },  Firefox: { label: 'Firefox' },  Edge: { label: 'Edge' },  Other: { label: 'Other' },};export function RadialChartPreview() {  return (    <RadialChart      data={browserData}      config={browserConfig}      nameKey="browser"      dataKey="visitors"    />  );}
<RadialChart
  data={data}
  config={config}
  nameKey="category"
  dataKey="visitors"
/>
<radial-chart
  [data]="data"
  [config]="config"
  nameKey="category"
  dataKey="visitors"
/>

The default. Four bars provide a comfortable visual rhythm without crowding.

Top-three highlight

<RadialChart
  data={topThree}
  config={config}
  nameKey="product"
  dataKey="revenue"
  className="max-w-xs"
/>
<radial-chart
  class="max-w-xs"
  [data]="topThree"
  [config]="config"
  nameKey="product"
  dataKey="revenue"
/>

For top-three callouts in a hero card. Constrain the surface width so the bars stay readable in a tight column.

No tooltip

Set tooltip to false for a static, decorative ranking - useful when the bars are labeled elsewhere or the chart is a glanceable hero element rather than an explorable surface.

<RadialChart
  data={data}
  config={config}
  nameKey="category"
  dataKey="visitors"
  tooltip={false}
/>
<radial-chart
  [data]="data"
  [config]="config"
  nameKey="category"
  dataKey="visitors"
  [tooltip]="false"
/>

Custom composition

When you need a different track treatment, gradient fills, a center label, or a legend, compose raw recharts inside ChartContainer. This mirrors the official shadcn radial block.

import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig,
  type ChartDatum,
} from '@gremorie/rx-data';
import { PolarGrid, RadialBar, RadialBarChart } from 'recharts';

export function ExplicitColorRadial({
  data,
  config,
  nameKey,
  dataKey,
}: {
  data: ChartDatum[];
  config: ChartConfig;
  nameKey: string;
  dataKey: string;
}) {
  return (
    <ChartContainer
      config={config}
      className="mx-auto aspect-square max-h-[260px]"
    >
      <RadialBarChart data={data} innerRadius={30} outerRadius={110}>
        <ChartTooltip
          cursor={false}
          content={<ChartTooltipContent nameKey={nameKey} hideLabel />}
        />
        <PolarGrid gridType="circle" />
        <RadialBar dataKey={dataKey} background />
      </RadialBarChart>
    </ChartContainer>
  );
}

Bar colors come from each row's fill; adjust innerRadius / outerRadius or swap the PolarGrid treatment for a different look.

Accessibility

  • Accessibility layer: recharts' accessibilityLayer provides keyboard navigation and screen-reader announcements for the chart data.
  • Token contrast: --chart-1 through --chart-5 ship with WCAG AA contrast against the card background in both light and dark themes.
  • Track contrast: the faint background track behind each bar (recharts background) defines the ring without competing with the fill.
  • Limit bar count: more than five bars becomes hard to scan. Reach for BarChart when more rows are needed.
  • PieChart - sibling polar layout for share-of-whole rather than ranking.
  • BarChart - reach for bars when you have more than five items or need exact comparison.
  • RadarChart - sibling polar layout for multi-axis profile comparison.

On this page