Polar marks are available only from the capability subpath:
import {
angleGrid,
polar,
radialArc,
radialArea,
radialDot,
radialGrid,
radialLine,
radialRule,
radialText,
} from '@tanstack/charts/polar'polar resolves the responsive coordinate system. The exported PolarMark and PolarGuide types are opaque composition contracts returned by the built-in radial mark and guide constructors. Use them to type collections passed to polar; do not implement their internal initialize or render lifecycle. Guide backgrounds paint first, marks paint second, and guide foregrounds paint last.
function polar(options: PolarOptions): ChartMark| Option | Type | Default | Meaning |
|---|---|---|---|
| id | string | Layer-derived | Stable container ID |
| className | string | None | Class added beside ts-chart__polar |
| marks | readonly PolarMark[] | Required | Radial marks rendered in order |
| guides | readonly PolarGuide[] | [] | Background/foreground guide layers around marks |
| angle | PolarAngleOptions | None | Angle factory or instance and optional wrapping |
| radius | PolarRadiusOptions | None | Radius scale factory or instance |
| startAngle | number | 0 | Start of the available angular range in radians |
| endAngle | number | 2π | End of the available angular range in radians |
| inset | number | 0 | Pixels removed from the maximum centered radius |
| radiusRatio | number | 1 | Multiplier applied to the radius after inset |
The default angular range is a complete circle. Angles use D3's radial convention: zero is at twelve o'clock and positive values move clockwise.
PolarAngleOptions and PolarRadiusOptions accept D3 factories with mark-inferred domains or configured instances with fixed domains. nice applies after inference. TanStack supplies responsive ranges without mutating an instance. An omitted wrap closes a complete revolution without adding a duplicate semantic category, but preserves both endpoints of a partial range. Set it explicitly to override that behavior.
PolarLayoutContext contains chart, centerX, centerY, radius, startAngle, endAngle, and optional resolved angle/radius scales. Each PolarResolvedScale exposes its semantic domain, responsive map, ticks, and bandwidth. A PolarLength is either a pixel length or a callback of the layout context. Use a callback for radii that must remain proportional during resize.
The outer chart uses x: null and y: null; guides: false makes the coordinate boundary explicit. Cartesian axes do not participate in the internal polar scales.
function radialArc<TDatum>(
source: Iterable<TDatum>,
options?: RadialArcOptions<TDatum>,
): PolarMark<TDatum>radialArc renders one D3 arc per valid interval.
| Option | Meaning |
|---|---|
| id, className | Stable layer ID and optional class |
| startAngle | Start-angle channel; defaults to datum startAngle |
| endAngle | End-angle channel; defaults to datum endAngle |
| padAngle | Padding-angle channel; defaults to datum padAngle, then zero |
| innerRadius | PolarLength; defaults to zero |
| outerRadius | PolarLength; defaults to the layout radius |
| cornerRadius | D3 arc corner radius as a PolarLength |
| padRadius | Explicit D3 arc padding radius as a PolarLength |
| generator | Responsive D3 arc factory for advanced per-datum geometry |
| key | Stable arc identity; defaults to a unique datum id, then index |
| z | Color group and interaction group |
| fill | Constant or datum-derived fill |
| fillOpacity | Fill opacity |
| stroke | Constant or datum-derived boundary stroke |
| strokeOpacity | Boundary opacity |
| strokeWidth | Boundary width |
| strokeDasharray | Boundary dash array |
| opacity | Whole-arc opacity |
Use d3-shape's pie output directly: its startAngle, endAngle, and padAngle fields are already the channels this mark needs. A pie, donut, and gauge differ only in inner radius and angular interval.
generator replaces the default D3 arc configuration. Its factory receives the final PolarLayoutContext and returns a D3 Arc whose accessors read the original datum. Use it for per-datum rings such as a sunburst:
radialArc(nodes, {
key: (node) => node.id,
generator: ({ radius }) =>
arc<SunburstNode>()
.startAngle((node) => node.x0)
.endAngle((node) => node.x1)
.innerRadius((node) => node.y0 * radius)
.outerRadius((node) => node.y1 * radius),
})Keep the D3 generator context null so it returns SVG path data.
function radialLine<TDatum>(
source: Iterable<TDatum>,
options?: RadialLineOptions<TDatum>,
): PolarMark<TDatum>
function radialArea<TDatum>(
source: Iterable<TDatum>,
options?: RadialAreaOptions<TDatum>,
): PolarMark<TDatum>Both marks use angle and radius channels and accept id, className, key, z, and a D3 curve factory. The channels default to row index and a numeric datum. radialLine accepts stroke, dash, opacity, and optional points styling. radialArea accepts fill and stroke styling plus radius1 for an explicit inner scale value; radius1 defaults to zero.
Their datum key defaults to a unique datum id, then a unique angle within each z group, then row index.
Input order is path order. Use a closed D3 curve such as curveLinearClosed for radar polygons. Grouping through z creates one path per group. radialArea can carry its own stroke; layer a closed radialLine only when the outline needs independent styling.
function radialDot<TDatum>(
source: Iterable<TDatum>,
options?: RadialDotOptions<TDatum>,
): PolarMark<TDatum>radialDot uses the same angle/radius channel defaults. It also accepts id, className, key, z, r, rScale, fill, stroke, and opacity styling. Radius defaults to 3.5 pixels. Each valid datum emits one interaction point with its original angle/radius values and projected screen position. Its key defaults to a unique datum id, then row index.
function radialText<TDatum>(
source: Iterable<TDatum>,
options?: RadialTextOptions<TDatum>,
): PolarMark<TDatum>radialText maps angle and radius channels through the container's copied polar scales, then positions labels with D3's radial point projection. It accepts text, key, z, fill, font size and weight, anchor, baseline, rotation, and pixel dx/dy. Use it for arc labels, donut-center values, and gauge readouts without leaving the polar coordinate system. Its key defaults to a unique datum id, then row index.
function radialRule<TDatum>(
source: Iterable<TDatum>,
options?: RadialRuleOptions<TDatum>,
): PolarMarkradialRule emits one radial segment per datum. angle, radius1, and radius2 are scale values; radius1 defaults to zero. The mark also accepts key, z, stroke, opacity, width, and dash styling. It covers gauge needles, ticks, and pie-label leaders without expanding one logical segment into two path rows. Its key defaults to a unique datum id, then a unique angle within each z group, then row index.
function radialGrid(options?: RadialGridOptions): PolarGuide
function angleGrid(options?: AngleGridOptions): PolarGuideradialGrid draws radius values as circles or polygons. Supply explicit values, or let ticks request values from the configured radius scale. Labels are off by default. Label angle, offset, rotation, format, fill, and font size are configurable.
angleGrid draws spokes for explicit values or the configured angle domain. It can show labels around the circumference with format and labelOffset. Labels are on by default. Both guides accept ID, class, stroke, opacity, width, and dash styling.
Guide label position and orientation can be constants or callbacks through PolarGuideLabelOption. Each callback receives a PolarGuideLabelContext with the semantic value, index, angle, radius, local x/y position, and complete layout. Use labelAnchor, labelBaseline, labelDx, labelDy, and labelRotate without rebuilding the guide. labelClassName targets the label group. Guides are decorative and emit no interaction points.
Every guide returns a PolarGuideScene:
interface PolarGuideScene {
background: readonly SceneNode[]
foreground?: readonly SceneNode[]
}polar collects every guide background in declaration order, renders all marks, then appends every optional foreground in the same guide order. The built-in grids put rings and spokes in background and labels in foreground, keeping labels legible without painting grid geometry over the data.
The exported option contracts are PolarOptions, RadialArcOptions, RadialLineOptions, RadialAreaOptions, RadialDotOptions, RadialTextOptions, RadialRuleOptions, RadialGridOptions, and AngleGridOptions. The coordinate contracts are PolarAngleOptions, PolarRadiusOptions, PolarResolvedScale, PolarLayoutContext, PolarLength, PolarGuideLabelContext, PolarGuideLabelOption, PolarMark, PolarGuide, and PolarGuideScene. PolarMark and PolarGuide annotate built-in constructor results rather than a supported custom-extension boundary.
See Polar and Radar Charts for pie, donut, gauge, radar, numeric line, and numeric scatter compositions.