For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The dithercn agent skill, for building any dither on the engine, is at /.well-known/agent-skills/dithercn/SKILL.md.
dithercn

Radar chart

One or more series across several axes, drawn as polygons of dither cells whose density steps up ring by ring.

Controls
Fill
Bloom
Grid
First series
Rings4
Interactive

Installation

pnpm dlx shadcn@latest add https://dithercn.dev/r/radar-chart.json

Usage

import { RadarChart } from "@/components/dithercn/radar-chart";
 
export function Evals() {
  return (
    <RadarChart
      axes={["Reasoning", "Coding", "Math", "Writing", "Vision"]}
      series={[
        { label: "Model v3", values: [86, 91, 78, 72, 64] },
        { label: "Model v2", values: [71, 74, 69, 76, 40] },
      ]}
      max={100}
    />
  );
}

Axes run clockwise from 12 o'clock. Each series lists one value per axis in the same order. Without max, the outer ring sits at a round number above the largest value.

Every series is a polygon of whole dither cells with a solid one-cell outline and square markers on its corners. With fill="gradient" the density steps up once per ring, thin at the centre and dense near the rim, so the grid reads straight through the shape. Each series takes the next palette colour. Where series overlap their cells interleave, so neither hides the other, and every outline stays on top.

Move the pointer around the chart and the readout snaps to the nearest axis, with every series' value there. Focus the chart and the arrow keys step around the axes. Hover a legend entry to spotlight a series, click to keep it lit, and press Escape to let go.

The chart fills its container up to size and shrinks with it, keeping room for the labels.

Examples

Single series in a card

One series in green with fill="dotted" and a round grid. The legend hides itself when there is only one series.

Comparing plans

Three series on seven axes with fill="hatched", five rings and bloom="high". Hatching keeps overlapping shapes readable because each one's lines run between the other's.

Props

PropTypeDefault
axes*

Axis labels, clockwise from the top. Three or more read best.

Type: [string, ...string[]]Default –
series*

{ label: string; values: number[]; color?: DitherColor; fill?: FillVariant }, one value per axis.

Type: [RadarSeries, ...RadarSeries[]]Default –
max

The value at the outer ring.

Type: numberDefault A round number above the largest value
rings

Grid rings. They also set the steps of the gradient fill.

Type: numberDefault 4
grid

Shape of the grid rings.

Type: "polygon" | "circle"Default "polygon"
fill

Texture of every series. A series' own fill wins.

Type: "gradient" | "dotted" | "hatched" | "solid"Default "gradient"
bloom

Soft glow in each series' colour behind it.

Type: "off" | "low" | "high"Default "off"
colors

Colours by series position. A series' own color wins.

Type: DitherColor[]Default –
size

Largest width and height in CSS pixels. It shrinks to fit its container.

Type: numberDefault 360
format

How values are written in the readout and the data table.

Type: Intl.NumberFormatOptions | ((value: number) => string)Default Compact, as in 1.2K
legend

Show the legend.

Type: booleanDefault With two or more series
interactive

The axis scrub, keyboard and legend spotlight. false draws a static image.

Type: booleanDefault true
animate

Grow out from the centre the first time the chart is seen.

Type: booleanDefault true
matrix

Threshold pattern of the gradient fill.

Type: "bayer2" | "bayer4" | "bayer8" | "blue-noise"Default "bayer4"
cell

Size of one dither cell in CSS pixels.

Type: numberDefault --dither-cell

Notes

  • The chart is a focusable group with a summary label. The arrow keys move between axes, a live region reads each axis's values, and a hidden table lists every value.
  • The shapes grow out from the centre once when the chart scrolls into view. With reduced motion they appear at once and the readout moves without easing.
  • The drawing is one SVG path per series, built from whole cells snapped to device pixels. Scrubbing only moves the readout by transform and restyles one spoke.