Polar axis layout
Measured polar axis layout
Section titled “Measured polar axis layout”Applies to polarColumn, stackedPolarColumn, normalizedPolarColumn, radialColumn, radialBar and multiRingRadialBar when axes.polar is authored. Standalone Charts and Pivot share the native owner. Radar and other axis collections are outside this contract.
Native text measurement first uses the spare space beside a wide or portrait frame, then reserves a symmetric gutter bounded to 60% of the available half-size before projecting marks. The additional gutter is capped so it cannot consume the whole frame; existing padding and authored radius ratios still apply. Browser text metrics use the inherited font; SSR uses the shared deterministic text fallback. Domains, raw records, cumulative partitions and events are unchanged. Resizing recomputes layout. Authored text determines the gutter even when a runtime filter or placement hides labels, so those callbacks do not move marks.
Coincident radial axes receive parallel furniture lanes; coincident angular axes receive concentric lanes. Lane widths derive from neighboring measured text. Automatic parallel lanes keep the axis line within the plot, and concentric lanes stay within the available inner/outer gutter; crowded later axes share the bounded lane and follow the omission policy. Grids keep the mark frame. Numeric tick candidates, formatted strings and runtime tick/label predicates are computed once per paint, then reused for both phases. Runtime placement does not re-run tick decisions.
When furniture cannot fit, whole labels are omitted: axis titles first, primary before named collection enumeration order; then numeric labels in the same axis/source-tick order; finally category labels. Each retained text box must lie within the plot bounds and avoid earlier accepted text with a three-pixel gap. Axes, short ticks and grids remain. Full-circle angular seams retain one physical endpoint label. Very long titles, dense explicit ticks, narrow hosts and too many named axes can therefore omit text. The native SVG records the additional omission count from the final polar pass in data-polar-omitted-labels. Values remain inspectable through marks, accessible keyboard inspection, data views and raw exports. The existing shared text owner may wrap or truncate labels while preserving their full accessible text; the final polar pass omits any remaining out-of-bounds or colliding labels after shared formatters and text layout. Distinct authored axis positions can give long labels more room than coincident lanes.
Runtime placement
Section titled “Runtime placement”createChart({ // chartType, dataset, axes, ... rendererOptions: { polarAxis: { placement: context => context.axisId === 'revenue' ? { offset: Math.min(32, context.maxOffset), visible: true } : undefined, }, },});Pivot uses the same polarAxis option on createPivotChartsRenderer. Existing tickFilter and tickLabelFilter retain their typed raw numeric contexts. Placement is separate from those per-tick predicates.
| Context field | Meaning |
|---|---|
chartId, chartType, axisId | Canonical chart and numeric-axis identity |
coordinate | radius for polar columns, angle for radial bars |
index, count | Primary first, then named axes in collection enumeration order (Object.keys) |
bounds | Frozen physical plot bounds in SVG pixels |
suggestedOffset | Measured automatic furniture lane, in pixels |
maxOffset | min(512, max(bounds.width, bounds.height) / 2) |
The frozen ChartPolarAxisPlacementContext is passed once for every authored numeric axis per full paint, including unused named axes. Return undefined for automatic placement, or an owned ChartPolarAxisPlacement object:
| Result field | Default and limits |
|---|---|
offset | Suggested offset; finite number in [-maxOffset, maxOffset]. Radial axes move along their normal; angular axes move outward from their authored radius. Negative offsets move in the opposite direction. Angular radii clamp at zero. |
visible | true; false hides axis line, short ticks, labels and title while preserving grid and data scale. |
Offsets do not reserve more plot space: furniture can extend beyond the plot, while retained labels must stay within its bounds. Placement visibility does not suppress tick predicates that were already computed. Result fields are captured once before validation and painting.
Unknown fields, null/nonobject results, nonboolean visibility, nonfinite or out-of-bound offsets reject the render. Throwing callbacks follow the existing renderer error/rollback contract; callbacks must remain valid when the accepted model is re-rendered during rollback. Preview mode ignores runtime predicates and placement. Runtime functions are not part of the model or saved state; reattach them when creating or hydrating a restored chart. No runtime placement changes data ownership or introduces navigation.
Image/vector exports clone the painted layout, including omissions and authored furniture placement. Clean exports remove transient inspection state. Fonts or arbitrary post-layout label/CSS mutations can change measured text; use stable loaded fonts before painting and rerender after changing them. This layout does not promise to fit unbounded authored content.