Skip to main content

<CategoryAxis>

component@pond-ts/chartssource

The category-flavoured preset of XAxis<CategoryAxis /> is <XAxis />. The axis kind follows the data: on a category container (a layer that plots on the ordinal column-domain axis) it ticks once per category, labelling each band centre with the category name (the container's shared formatter). Kept as the familiar name for categorical charts, mirroring TimeAxis. Forwards every XAxisProps (label, side, …).

A crowded axis thins + truncates its labels to stay legible — triggered by measured geometry (rendered label width vs. band pitch), not category count, so few-but-wide labels fit as reliably as many short ones ([PND-CATFIT]; categorical-axis RFC, Phase 1). Truncation is from the middle (EDGE01…EQT), keeping both the prefix and the distinguishing tail. The labels come from the data (the categories list), so a d3 format prop does not apply here (it can't name a category); customize a label by changing the categories datum's label.

Props

align'center' | 'right' | 'auto'

Horizontal placement of each tick label relative to its tick.

  • 'center' (default) — every label centred on its tick. Note the first/last labels can then extend past the plot edges (the strip doesn't clip), so a wide first label may reach into the left y-axis gutter; use 'auto' if that crowds.
  • 'auto' — centred, but the first label left-anchors and the last right-anchors so the edge labels stay inside the plot (the old default).
  • 'right' — the label sits to the right of an extended tick that drops from the axis line (label beside the tick, not under it) — a style choice (the TradingView look). It re-anchors without measuring, so it is not a remedy for colliding labels; on a category axis the measured fit (thin + middle-ellipsize) is what prevents collisions.
colorstring

This axis instance's colour — tick marks, labels, the plot-facing rule, and the label title all take it, overriding the theme's axis.label / axis.grid / axis.title.color. The lever that distinguishes stacked dual axes (a blue derived-unit strip under a grey primary). Cursor and marker pills keep their own colours. Omit for the theme's axis colours.

dateStyle'flat' | 'stacked'

How a time axis lays out its date context (ignored on value / category axes, and whenever a custom format, transform, or explicit ticks owns the labels).

  • 'flat' (default) — one row: each tick that opens a coarser calendar period is relabelled inline to it (the month at a month turn, the year at a year turn, the date at a day turn under an intraday grain), every other tick a terse label (5, Feb, 14:00). The TradingView look — the row reads … 30 31 Feb 2 3 ….
  • 'stacked' — two rows: a terse top row (the grain's bare unit — 14:00, 12, Feb) over a segmented band row of the next-coarser period (day bands under intraday ticks, month bands under day ticks, year bands under month/quarter ticks). Each band is a left-aligned label + a divider at its turn, zebra-shaded by the band's calendar parity; the top-row tick on each turn is emphasized and joins its divider as one boundary line.
formatAxisFormatAxisFormattype@pond-ts/chartsstring | (value: number) => string

How to format an axis's values — a d3 [format specifier] (https://github.com/d3/d3-format#locale_format) string, or a custom (value) => string function. Omit for the scale's d3 default.

Tick / cursor value formatting — a d3 format/time specifier string or a (value) => string. Omitted ⇒ the container's shared formatter (so the axis and the cursor readout agree), which is the d3 multi-scale time format for a time axis or the number default for a value axis. The specifier is resolved against the axis's kind (time vs value).

heightnumber

Strip height in px. Defaults to fit the ticks (+ the label line if any).

labelstring

A label drawn centred below (or above) the ticks — e.g. Distance (m).

onMouseEventAxisMouseHandlerAxisMouseHandlertype@pond-ts/charts(info: AxisMouseEvent) => void

A single handler for every mouse event on an axis strip — see AxisMouseEvent. Passed as onMouseEvent to <XAxis> / <YAxis>.

Mouse events on the axis strip, with the axis value under the pointer (AxisMouseHandler, whose AxisMouseEvent payload carries it) — a click on a time axis reports the instant it landed on, a click on a category axis reports the category. The lever for axis-driven UI: pick a date by clicking its tick, open a menu on the strip (event.type === 'contextmenu'), drill into a category.

One handler takes every mouse event — click, double-click, context menu, down/up, move, enter, leave — so switch on event.type. Nothing is attached when the prop is omitted, so the move events cost nothing unless you ask for them.

The x strip has no id (only a <YAxis> does); to distinguish stacked axes, close over it: onMouseEvent={(e) => onAxis('delta', e)}.

side'top' | 'bottom'

Which edge the axis sits on. Default 'bottom'. Declaration order in the <ChartContainer> places it; side orients the ticks + label.

ticksreadonly { at: number; label: string }[]

Explicit ticks — { at, label } in axis-value units — instead of the scale's automatic ticks. The value-axis lever for e.g. lap markers placed at their cumulative-distance positions ({ at: lap.endMeters, label: 'Lap 3' }).

transformAxisTransformAxisTransforminterface@pond-ts/charts{ from: unknown; to: unknown }

A derived-unit transform: to/from are monotonic inverses (either direction — a decreasing transform is fine); they may be nonlinear.

Relabel this axis into a derived unit on the same scale — a second tick layout, not a second scale (the pixel mapping never changes). E.g. a BS-delta strip under a std-moneyness chart (transform={{ to: sigmaToDelta, from: deltaToSigma }}) or a moneyness axis over a strike chart (transform={{ to: (k) => k / spot, from: (m) => m * spot }}). to/from are monotonic inverses (either direction); they may be nonlinear — ticks are nice derived-unit values at mixed 1-2-5 step sizes, admitted wherever they keep pixel room, so a span the transform compresses gets coarser ticks and a span it stretches gets finer ones. format (or the d3 number default) formats the derived values; the cursor pill and marker indicators on this axis read in the derived unit too. Ignored on a category axis; explicit ticks win. Typically used on a second <XAxis> stacked with the primary one — declaration order places the strips; gridlines stay on the container's own (primary) ticks.