@cascivo/charts 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -7,11 +7,31 @@ interface LinearScale {
7
7
  range: [number, number];
8
8
  map(value: number): number;
9
9
  invert(position: number): number;
10
- ticks(count?: number): number[];
10
+ ticks(count?: number, allowDecimals?: boolean): number[];
11
11
  }
12
12
  declare function linearScale(domain: [number, number], range: [number, number]): LinearScale;
13
- /** Extended nice-numbers: steps are 1, 2, 2.5 or 5 × 10^k covering [min, max]. */
14
- declare function niceTicks(min: number, max: number, count?: number): number[];
13
+ /**
14
+ * Extended nice-numbers: steps are 1, 2, 2.5 or 5 × 10^k covering [min, max].
15
+ *
16
+ * `count` is a **density hint**, not a tick count — the step is snapped to the nearest
17
+ * nice number, so the result may have more or fewer ticks than asked for. That is standard
18
+ * (d3 behaves the same) and is right for continuous data.
19
+ *
20
+ * It is wrong for a whole-number domain. `(max - min) / count` happily produces a
21
+ * *fractional* step when the requested density is finer than the data's own unit:
22
+ * `max=1, count=2` → rawStep 0.5 → `[0, 0.5, 1]`; `max=1, count=5` →
23
+ * `[0, 0.2, 0.4, 0.6, 0.8, 1]`. An incident-count chart with 0–3 incidents per severity
24
+ * hits this constantly, and the obvious workaround (`yTicks={max + 1}`) lands straight on
25
+ * it at `max=1` (2026-07-28 report C17a).
26
+ *
27
+ * So when every bound is an integer, the step is floored at 1 and snapped to an integer
28
+ * nice-number unless `allowDecimals` is explicitly `true`. Callers with genuinely
29
+ * continuous integer-bounded data (a 0–1 ratio axis) opt back in.
30
+ *
31
+ * @param allowDecimals Force fractional steps on (`true`) or off (`false`). Omit to
32
+ * auto-detect: integer bounds get integer ticks, anything else keeps today's behavior.
33
+ */
34
+ declare function niceTicks(min: number, max: number, count?: number, allowDecimals?: boolean): number[];
15
35
  interface BandScale<T extends string = string> {
16
36
  domain: readonly T[];
17
37
  range: [number, number];
@@ -226,7 +246,24 @@ interface BarChartSeries<Datum> {
226
246
  id: string;
227
247
  label: string;
228
248
  data: readonly Datum[];
229
- color?: string;
249
+ /**
250
+ * Bar color. A string colors the whole series; a function colors each bar from its own
251
+ * datum.
252
+ *
253
+ * The per-datum form exists for the common single-series categorical chart whose
254
+ * categories each carry meaning — incidents by severity, where SEV1 should read as
255
+ * danger and SEV4 as neutral regardless of which bar is tallest. Before it, the only
256
+ * route was one single-point series per category with `mode="grouped"`, which renders
257
+ * *wrong*: the bars overlap and only the first series' category label survives
258
+ * (2026-07-28 report C18).
259
+ *
260
+ * ```tsx
261
+ * series={[{ id: 'count', label: 'Incidents', data, color: (d) => SEVERITY_COLOR[d.x] }]}
262
+ * ```
263
+ *
264
+ * Each bar is also stamped with `data-x`, so CSS can target one category directly.
265
+ */
266
+ color?: string | ((datum: Datum, index: number) => string);
230
267
  /**
231
268
  * Per-series Y accessor. Overrides the chart-level `y` for this series only —
232
269
  * use it to plot two series from one shared `data` row against different fields
@@ -249,20 +286,92 @@ interface BarChartProps<Datum = {
249
286
  y: (d: Datum) => number;
250
287
  title: string;
251
288
  description?: string;
289
+ /**
290
+ * Layout orientation of the component.
291
+ *
292
+ * @defaultValue `vertical`
293
+ * @see the component manifest
294
+ */
252
295
  orientation?: 'vertical' | 'horizontal';
253
296
  mode?: 'grouped' | 'stacked' | 'percent';
297
+ /**
298
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
299
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
300
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
301
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
302
+ * this — charts call it internally.
303
+ * @see the component manifest
304
+ */
254
305
  width?: number;
255
306
  height?: number;
307
+ /**
308
+ * Approximate number of ticks on the x-axis.
309
+ *
310
+ * ⚠ **Follows SCREEN position, so its meaning swaps with `orientation`.** On a vertical
311
+ * chart the x-axis is the category axis; on a horizontal one it is the VALUE axis. Prefer
312
+ * {@link BarChartProps.valueAxisTicks} / {@link BarChartProps.categoryAxisTicks}, which
313
+ * name the axis by role and never swap.
314
+ *
315
+ * @defaultValue `5`
316
+ * @deprecated Use `valueAxisTicks` / `categoryAxisTicks`.
317
+ */
256
318
  xTicks?: number;
319
+ /**
320
+ * Approximate number of ticks on the y-axis.
321
+ *
322
+ * ⚠ **Follows SCREEN position, so its meaning swaps with `orientation`** — see
323
+ * {@link BarChartProps.xTicks}.
324
+ *
325
+ * @defaultValue `5`
326
+ * @deprecated Use `valueAxisTicks` / `categoryAxisTicks`.
327
+ */
257
328
  yTicks?: number;
258
- /** Show every Nth category label (and always the last) to thin a crowded x-axis. */
329
+ /**
330
+ * Approximate number of ticks on the **value** axis, whichever way the chart is turned.
331
+ *
332
+ * This is the prop you want. `xTicks`/`yTicks` are named for where the axis is *drawn*,
333
+ * so on `orientation="horizontal"` the value axis moves from screen-y to screen-x and the
334
+ * controlling prop moves with it — `yTicks={1}` silently does nothing while `xTicks={1}`
335
+ * works. Meanwhile `xLabelEvery` does NOT swap: it always strides the category axis. Two
336
+ * conventions in one component, with nothing in the types to say so (2026-07-28 report
337
+ * C17b). Wins over `xTicks`/`yTicks` when both are given.
338
+ *
339
+ * @defaultValue `5`
340
+ */
341
+ valueAxisTicks?: number;
342
+ /**
343
+ * Approximate number of ticks on the CATEGORY axis, on both orientations. Role-named twin
344
+ * of valueAxisTicks.
345
+ *
346
+ * @defaultValue `5`
347
+ * @see the component manifest
348
+ */
349
+ categoryAxisTicks?: number;
350
+ /**
351
+ * Show every Nth category label (and always the last) to thin a crowded axis.
352
+ *
353
+ * Always strides the **category** axis (the `x` field of each datum), on both
354
+ * orientations — unlike `xTicks`/`yTicks`, which follow screen position.
355
+ * {@link BarChartProps.categoryLabelEvery} is the unambiguous name; this is kept for
356
+ * compatibility.
357
+ */
259
358
  xLabelEvery?: number;
359
+ /**
360
+ * Show every Nth category label (and always the last). Role-named twin of
361
+ * `xLabelEvery`; wins when both are given.
362
+ */
363
+ categoryLabelEvery?: number;
260
364
  legend?: boolean;
261
365
  tooltip?: boolean;
262
366
  /** Custom tooltip formatter. Stacked default lists "label · total" + per-layer values. */
263
367
  tooltipFormat?: (p: ChartPoint) => string;
264
368
  className?: string;
265
- /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
369
+ /**
370
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
371
+ *
372
+ * @defaultValue `false`
373
+ * @see the component manifest
374
+ */
266
375
  plain?: boolean;
267
376
  /**
268
377
  * Reference lines, bands, and markers drawn over the plot. Geometric axes: `y` is the
@@ -273,10 +382,23 @@ interface BarChartProps<Datum = {
273
382
  labels?: LabelOptions;
274
383
  /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
275
384
  onSelect?: (point: ChartPoint) => void;
276
- /** Bar fill style: solid (default), a gradient, or a pattern. */
385
+ /**
386
+ * Bar fill style — solid, a gradient, or a pattern.
387
+ *
388
+ * @defaultValue `solid`
389
+ * @see the component manifest
390
+ */
277
391
  fill?: FillKind;
278
392
  /** Pattern motif when `fill="pattern"`. */
279
393
  patternKind?: PatternKind;
394
+ /**
395
+ * Format each category/x-axis tick label. Receives the datum's raw `x` value — a number,
396
+ * a string, or a `Date`, whichever the series carries.
397
+ *
398
+ * Threads through `Axis`'s own `format`, which every chart composing an axis should
399
+ * surface (2026-07-28 report C16); enforced by `axis-parity.test.ts`.
400
+ */
401
+ format?: (value: number | string | Date) => string;
280
402
  }
281
403
  declare function BarChart<Datum = {
282
404
  x: string;
@@ -293,7 +415,10 @@ declare function BarChart<Datum = {
293
415
  height,
294
416
  xTicks,
295
417
  yTicks,
418
+ valueAxisTicks,
419
+ categoryAxisTicks,
296
420
  xLabelEvery,
421
+ categoryLabelEvery,
297
422
  legend,
298
423
  tooltip,
299
424
  tooltipFormat,
@@ -303,7 +428,8 @@ declare function BarChart<Datum = {
303
428
  labels,
304
429
  onSelect,
305
430
  fill,
306
- patternKind
431
+ patternKind,
432
+ format: xFormat
307
433
  }: BarChartProps<Datum>): import("react").JSX.Element;
308
434
  /** One layer of a stacked bar at a category. */
309
435
  interface StackedSegment {
@@ -887,17 +1013,42 @@ declare const PLAIN_MARGINS: {
887
1013
  readonly bottom: 2;
888
1014
  readonly left: 2;
889
1015
  };
1016
+ /**
1017
+ * Approximate advance width (px) of one axis-label character at the 11px axis font.
1018
+ * A conservative average across digits, separators, and short month names — good
1019
+ * enough to reserve room without measuring text (no DOM in SSR/tests).
1020
+ */
1021
+ declare const AXIS_CHAR_PX = 6.5;
890
1022
  /**
891
1023
  * Left margin sized to the widest left-axis label so wide ticks (e.g. `40,000`)
892
1024
  * aren't clipped past the SVG's `0` origin. The default 36px only fits ~4 glyphs;
893
1025
  * a 6-glyph thousands label needs ~45px. `plain` charts keep their tiny margin.
894
1026
  */
895
1027
  declare function leftMarginForLabels(leftAxisLabels: readonly string[], plain: boolean | undefined): number;
1028
+ /**
1029
+ * Right margin sized so the axis chrome on the right-hand side isn't clipped by the SVG
1030
+ * edge. Two independent causes, both of which the default 8px margin failed:
1031
+ *
1032
+ * - a **right-hand value axis** (`secondAxis`) needs the full width of its widest label,
1033
+ * which renders *outside* the plot via `Axis orientation="y-right"`;
1034
+ * - the **final bottom-axis label** is centred on the last tick, which sits at the plot's
1035
+ * right edge, so half of it overhangs (`7/26/2026` → `7/26/202`).
1036
+ *
1037
+ * Pass whichever apply; the larger wins. `plain` charts keep their tiny margin.
1038
+ */
1039
+ declare function rightMarginForLabels(options?: {
1040
+ /** Labels of a right-hand value axis, if the chart has one. */rightAxisLabels?: readonly string[]; /** Labels of the bottom axis — only the last one's overhang matters. */
1041
+ bottomAxisLabels?: readonly string[];
1042
+ plain?: boolean | undefined;
1043
+ }): number;
896
1044
  /**
897
1045
  * Stride for a crowded categorical (band) axis: render every Nth label so they stop
898
1046
  * colliding (e.g. 14 `Jul 1`…`Jul 14` dates in a narrow chart). Returns `undefined`
899
1047
  * when every label fits — callers pass that straight to `Axis.labelEvery` (all shown).
900
1048
  * An explicit `xLabelEvery` from the caller always overrides this.
1049
+ *
1050
+ * `Axis` always draws the final label, and drops the strided label before it when the two
1051
+ * would collide — so a stride that doesn't divide the domain evenly is safe.
901
1052
  */
902
1053
  declare function autoLabelStride(labels: readonly string[], axisLength: number): number | undefined;
903
1054
  /**
@@ -963,11 +1114,24 @@ declare function download(content: Blob | string, filename: string): void;
963
1114
  type AnyScale = LinearScale | BandScale | LogScale | TimeScale;
964
1115
  interface AxisProps {
965
1116
  scale: AnyScale;
966
- orientation: 'x' | 'y';
1117
+ /**
1118
+ * `x` — horizontal axis, labels below the line.
1119
+ * `y` — vertical axis on the **left**, labels outside to the left.
1120
+ * `y-right` — vertical axis on the **right**, labels outside to the right.
1121
+ *
1122
+ * A right-hand axis MUST use `y-right`: a `y` axis translated to the plot's right edge
1123
+ * draws its labels at `x: -8` with `text-anchor: end`, i.e. *inside the plot*, on top of
1124
+ * the marks. That was the actual rendering of every right axis in the catalog.
1125
+ */
1126
+ orientation: 'x' | 'y' | 'y-right';
967
1127
  length: number;
968
1128
  format?: (value: number | string | Date) => string;
969
1129
  tickCount?: number;
970
- /** For band scales: render every Nth category label (and always the last) to avoid crowding. */
1130
+ /**
1131
+ * For band scales: render every Nth category label to avoid crowding. The final label is
1132
+ * always drawn, and a strided label that would collide with it is dropped —
1133
+ * see `autoLabelStride`, which computes this for you. Pass explicitly only to override.
1134
+ */
971
1135
  labelEvery?: number | undefined;
972
1136
  transform?: string;
973
1137
  }
@@ -1193,34 +1357,109 @@ interface LineChartProps<Datum = {
1193
1357
  y: (d: Datum) => number;
1194
1358
  title: string;
1195
1359
  description?: string;
1360
+ /**
1361
+ * Line interpolation curve
1362
+ *
1363
+ * @defaultValue `monotone`
1364
+ * @see the component manifest
1365
+ */
1196
1366
  curve?: Curve;
1197
1367
  width?: number;
1368
+ /**
1369
+ * SVG height in px
1370
+ *
1371
+ * @defaultValue `300`
1372
+ * @see the component manifest
1373
+ */
1198
1374
  height?: number;
1375
+ /**
1376
+ * Approximate number of X-axis ticks
1377
+ *
1378
+ * @defaultValue `5`
1379
+ * @see the component manifest
1380
+ */
1199
1381
  xTicks?: number;
1382
+ /**
1383
+ * Approximate number of Y-axis ticks
1384
+ *
1385
+ * @defaultValue `5`
1386
+ * @see the component manifest
1387
+ */
1200
1388
  yTicks?: number;
1389
+ /**
1390
+ * Format each X-axis tick label. Receives the datum's raw `x` value — a number, a
1391
+ * string, or a `Date`, whichever the series carries.
1392
+ *
1393
+ * Without it a numeric x renders raw: a `Date.now()`-scale value (the natural shape for
1394
+ * a time series) renders as `1,785,217,000,000`. Passing `Date` objects instead switches
1395
+ * the axis to a time scale, but that format is fixed, so every bucket narrower than a day
1396
+ * collapses to the same label — worse than the epoch number, which at least differed
1397
+ * between buckets. This threads through `Axis`'s existing `format`, mirroring what
1398
+ * `secondAxis.format` already offers on the right (2026-07-28 report C16).
1399
+ *
1400
+ * ```tsx
1401
+ * <LineChart
1402
+ * series={series}
1403
+ * format={(x) => new Date(Number(x)).toLocaleTimeString([], { timeStyle: 'short' })}
1404
+ * />
1405
+ * ```
1406
+ */
1407
+ format?: (value: number | string | Date) => string;
1201
1408
  legend?: boolean;
1202
1409
  tooltip?: boolean;
1203
1410
  formatTooltip?: (datum: Datum, series: LineChartSeries<Datum>) => string;
1204
1411
  className?: string;
1205
- /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
1412
+ /**
1413
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
1414
+ *
1415
+ * @defaultValue `false`
1416
+ * @see the component manifest
1417
+ */
1206
1418
  plain?: boolean;
1207
1419
  /** Reference lines, shaded bands, and markers drawn over the plot (target/threshold annotations). */
1208
1420
  annotations?: readonly Annotation[];
1209
1421
  /** Print each point's value as a label above the mark. */
1210
1422
  labels?: LabelOptions;
1211
- /** Bridge `null`/non-finite y gaps instead of breaking the line at them (default: break). */
1423
+ /**
1424
+ * Bridge non-finite y gaps instead of breaking the line at them.
1425
+ *
1426
+ * @defaultValue `false`
1427
+ * @see the component manifest
1428
+ */
1212
1429
  connectNulls?: boolean;
1213
1430
  /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
1214
1431
  onSelect?: (point: ChartPoint) => void;
1215
- /** Show a keyboard-operable Brush below the plot to subset (zoom) the series to a window. */
1432
+ /**
1433
+ * Show a keyboard-operable Brush below the plot to subset (zoom) the series to a window.
1434
+ *
1435
+ * @defaultValue `false`
1436
+ * @see the component manifest
1437
+ */
1216
1438
  brush?: boolean;
1217
- /** Show a DataZoom slider below the plot — a Brush whose body also pans the window. */
1439
+ /**
1440
+ * Show a DataZoom slider below the plot — a Brush whose body also pans the window.
1441
+ *
1442
+ * @defaultValue `false`
1443
+ * @see the component manifest
1444
+ */
1218
1445
  dataZoom?: boolean;
1219
- /** Enable in-plot wheel/drag/keyboard zoom-pan (`+`/`-`/`0`) over the series index window. */
1446
+ /**
1447
+ * Enable in-plot wheel/drag/keyboard zoom-pan (+/-/0) over the series index window, with a
1448
+ * reset control and re-ticked axes.
1449
+ *
1450
+ * @defaultValue `false`
1451
+ * @see the component manifest
1452
+ */
1220
1453
  zoom?: boolean;
1221
1454
  /** Connect this chart to others sharing the same id — they mirror zoom window + hovered x. */
1222
1455
  syncId?: string;
1223
- /** Tooltip trigger: `item` (default, nearest point) or `axis` (crosshair + all series at the hovered x). */
1456
+ /**
1457
+ * Tooltip trigger — item (nearest point) or axis (a crosshair + a shared tooltip listing
1458
+ * every series at the hovered x).
1459
+ *
1460
+ * @defaultValue `item`
1461
+ * @see the component manifest
1462
+ */
1224
1463
  tooltipMode?: 'item' | 'axis';
1225
1464
  /** Add a right-hand y-axis for series with `axis: 'right'` (e.g. bandwidth vs requests/sec). */
1226
1465
  secondAxis?: {
@@ -1262,6 +1501,7 @@ declare function LineChart<Datum = {
1262
1501
  height,
1263
1502
  xTicks,
1264
1503
  yTicks,
1504
+ format: xFormat,
1265
1505
  legend,
1266
1506
  tooltip,
1267
1507
  formatTooltip,
@@ -1322,19 +1562,55 @@ interface AreaChartProps<Datum = {
1322
1562
  title: string;
1323
1563
  description?: string;
1324
1564
  stacked?: boolean;
1565
+ /**
1566
+ * Line/area interpolation curve.
1567
+ *
1568
+ * @defaultValue `monotone`
1569
+ * @see the component manifest
1570
+ */
1325
1571
  curve?: Curve;
1326
- /** Area fill style: solid (default), a top→bottom gradient, or a pattern. */
1572
+ /**
1573
+ * Area fill style — solid, a top→bottom gradient, or a pattern.
1574
+ *
1575
+ * @defaultValue `solid`
1576
+ * @see the component manifest
1577
+ */
1327
1578
  fill?: FillKind;
1328
1579
  /** Pattern motif when `fill="pattern"`. */
1329
1580
  patternKind?: PatternKind;
1581
+ /**
1582
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
1583
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
1584
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
1585
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
1586
+ * this — charts call it internally.
1587
+ * @see the component manifest
1588
+ */
1330
1589
  width?: number;
1331
1590
  height?: number;
1591
+ /**
1592
+ * Approximate number of ticks on the x-axis.
1593
+ *
1594
+ * @defaultValue `5`
1595
+ * @see the component manifest
1596
+ */
1332
1597
  xTicks?: number;
1598
+ /**
1599
+ * Approximate number of ticks on the y-axis.
1600
+ *
1601
+ * @defaultValue `5`
1602
+ * @see the component manifest
1603
+ */
1333
1604
  yTicks?: number;
1334
1605
  legend?: boolean;
1335
1606
  tooltip?: boolean;
1336
1607
  className?: string;
1337
- /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
1608
+ /**
1609
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
1610
+ *
1611
+ * @defaultValue `false`
1612
+ * @see the component manifest
1613
+ */
1338
1614
  plain?: boolean;
1339
1615
  /** Reference lines, shaded bands, and markers drawn over the plot (target/threshold annotations). */
1340
1616
  annotations?: readonly Annotation[];
@@ -1342,15 +1618,37 @@ interface AreaChartProps<Datum = {
1342
1618
  labels?: LabelOptions;
1343
1619
  /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
1344
1620
  onSelect?: (point: ChartPoint) => void;
1345
- /** Show a keyboard-operable Brush below the plot to subset the series to a window. */
1621
+ /**
1622
+ * Show a keyboard-operable Brush below the plot to subset the series to a window.
1623
+ *
1624
+ * @defaultValue `false`
1625
+ * @see the component manifest
1626
+ */
1346
1627
  brush?: boolean;
1347
- /** Show a DataZoom slider below the plot — a Brush whose body also pans the window. */
1628
+ /**
1629
+ * Show a DataZoom slider below the plot — a Brush whose body also pans the window.
1630
+ *
1631
+ * @defaultValue `false`
1632
+ * @see the component manifest
1633
+ */
1348
1634
  dataZoom?: boolean;
1349
- /** Enable in-plot wheel/drag/keyboard zoom-pan (`+`/`-`/`0`) over the series index window. */
1635
+ /**
1636
+ * Enable in-plot wheel/drag/keyboard zoom-pan (+/-/0) over the series index window, with a
1637
+ * reset control and re-ticked axes.
1638
+ *
1639
+ * @defaultValue `false`
1640
+ * @see the component manifest
1641
+ */
1350
1642
  zoom?: boolean;
1351
1643
  /** Connect this chart to others sharing the same id — they mirror zoom window + hovered x. */
1352
1644
  syncId?: string;
1353
- /** Tooltip trigger: `item` (default, nearest point) or `axis` (crosshair + all series at the hovered x). */
1645
+ /**
1646
+ * Tooltip trigger — item (nearest point) or axis (a crosshair + a shared tooltip listing
1647
+ * every series at the hovered x).
1648
+ *
1649
+ * @defaultValue `item`
1650
+ * @see the component manifest
1651
+ */
1354
1652
  tooltipMode?: 'item' | 'axis';
1355
1653
  /** Add a right-hand y-axis for series with `axis: 'right'` (non-stacked only). */
1356
1654
  secondAxis?: {
@@ -1361,6 +1659,16 @@ interface AreaChartProps<Datum = {
1361
1659
  decimate?: boolean | AreaDecimateOptions;
1362
1660
  /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
1363
1661
  toolbox?: boolean | ToolboxOptions;
1662
+ /**
1663
+ * Format each X-axis tick label. Receives the datum's raw `x` value — a number, a string,
1664
+ * or a `Date`, whichever the series carries.
1665
+ *
1666
+ * Without it a numeric x renders raw: a `Date.now()`-scale value (the natural shape for a
1667
+ * time series) renders as `1,785,217,000,000`. Passing `Date` objects switches the axis to
1668
+ * a time scale, but that format is fixed, so every bucket narrower than a day collapses to
1669
+ * the same label. Threads through `Axis`'s own `format` (2026-07-28 report C16).
1670
+ */
1671
+ format?: (value: number | string | Date) => string;
1364
1672
  }
1365
1673
  declare function AreaChart<Datum = {
1366
1674
  x: number;
@@ -1393,7 +1701,8 @@ declare function AreaChart<Datum = {
1393
1701
  tooltipMode,
1394
1702
  secondAxis,
1395
1703
  decimate,
1396
- toolbox
1704
+ toolbox,
1705
+ format: xFormat
1397
1706
  }: AreaChartProps<Datum>): import("react").JSX.Element;
1398
1707
  interface PieChartDatum {
1399
1708
  id: string;
@@ -1423,6 +1732,8 @@ interface PieChartProps {
1423
1732
  centerSlot?: ReactNode;
1424
1733
  /** Visible placeholder text when data is empty. Defaults to the i18n built-in ("No data"). */
1425
1734
  emptyLabel?: string;
1735
+ /** Show tooltips (default `true`). Parity with Area/Bar/Line/Combo, which all take this. */
1736
+ tooltip?: boolean;
1426
1737
  /** Custom tooltip formatter. Defaults to "value (pct%)". Receives ChartPoint.percent. */
1427
1738
  tooltipFormat?: (p: ChartPoint) => string;
1428
1739
  legend?: boolean;
@@ -1448,6 +1759,7 @@ declare function PieChart({
1448
1759
  centerLabel,
1449
1760
  centerSlot,
1450
1761
  emptyLabel,
1762
+ tooltip,
1451
1763
  tooltipFormat,
1452
1764
  legend,
1453
1765
  className,
@@ -1458,6 +1770,12 @@ declare function PieChart({
1458
1770
  interface ScatterDatum {
1459
1771
  x: number;
1460
1772
  y: number;
1773
+ /**
1774
+ * Point radius or accessor
1775
+ *
1776
+ * @defaultValue `4`
1777
+ * @see the component manifest
1778
+ */
1461
1779
  r?: number;
1462
1780
  }
1463
1781
  interface ScatterChartSeries {
@@ -1471,14 +1789,39 @@ interface ScatterChartProps {
1471
1789
  title: string;
1472
1790
  description?: string;
1473
1791
  r?: number | ((d: ScatterDatum) => number);
1792
+ /**
1793
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
1794
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
1795
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
1796
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
1797
+ * this — charts call it internally.
1798
+ * @see the component manifest
1799
+ */
1474
1800
  width?: number;
1475
1801
  height?: number;
1802
+ /**
1803
+ * Approximate number of ticks on the x-axis.
1804
+ *
1805
+ * @defaultValue `5`
1806
+ * @see the component manifest
1807
+ */
1476
1808
  xTicks?: number;
1809
+ /**
1810
+ * Approximate number of ticks on the y-axis.
1811
+ *
1812
+ * @defaultValue `5`
1813
+ * @see the component manifest
1814
+ */
1477
1815
  yTicks?: number;
1478
1816
  legend?: boolean;
1479
1817
  tooltip?: boolean;
1480
1818
  className?: string;
1481
- /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
1819
+ /**
1820
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
1821
+ *
1822
+ * @defaultValue `false`
1823
+ * @see the component manifest
1824
+ */
1482
1825
  plain?: boolean;
1483
1826
  /** Reference lines, shaded bands, and markers drawn over the plot (target/threshold annotations). */
1484
1827
  annotations?: readonly Annotation[];
@@ -1486,12 +1829,28 @@ interface ScatterChartProps {
1486
1829
  onSelect?: (point: ChartPoint) => void;
1487
1830
  /** Point glyph shape — a fixed shape, or a function to encode a category by shape. Defaults to a circle. */
1488
1831
  glyph?: GlyphShape | ((d: ScatterDatum, seriesId: string) => GlyphShape);
1489
- /** Renderer: `svg` (default), `canvas` (force), or `auto` (canvas past ~2000 points). */
1832
+ /**
1833
+ * Renderer — svg (default), canvas (force), or auto (canvas past ~2000 points). Canvas
1834
+ * keeps the full a11y fallback table + keyboard layer.
1835
+ *
1836
+ * @defaultValue `svg`
1837
+ * @see the component manifest
1838
+ */
1490
1839
  renderer?: 'svg' | 'canvas' | 'auto';
1491
1840
  /** Map each point's y → CVD-safe colour and/or size via a legend that filters the range. */
1492
1841
  visualMap?: VisualMapOptions;
1493
1842
  /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
1494
1843
  toolbox?: boolean | ToolboxOptions;
1844
+ /**
1845
+ * Format each X-axis tick label. Receives the datum's raw `x` value — a number, a string,
1846
+ * or a `Date`, whichever the series carries.
1847
+ *
1848
+ * Without it a numeric x renders raw: a `Date.now()`-scale value (the natural shape for a
1849
+ * time series) renders as `1,785,217,000,000`. Passing `Date` objects switches the axis to
1850
+ * a time scale, but that format is fixed, so every bucket narrower than a day collapses to
1851
+ * the same label. Threads through `Axis`'s own `format` (2026-07-28 report C16).
1852
+ */
1853
+ format?: (value: number | string | Date) => string;
1495
1854
  }
1496
1855
  declare function ScatterChart({
1497
1856
  series,
@@ -1511,10 +1870,21 @@ declare function ScatterChart({
1511
1870
  glyph,
1512
1871
  renderer,
1513
1872
  visualMap,
1514
- toolbox
1873
+ toolbox,
1874
+ format
1515
1875
  }: ScatterChartProps): import("react").JSX.Element;
1516
1876
  interface SparklineBaseProps {
1517
1877
  data: readonly number[];
1878
+ /**
1879
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
1880
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
1881
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
1882
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
1883
+ * this — charts call it internally.
1884
+ *
1885
+ * @defaultValue `80`
1886
+ * @see the component manifest
1887
+ */
1518
1888
  width?: number;
1519
1889
  height?: number;
1520
1890
  color?: string;
@@ -1548,11 +1918,37 @@ interface MeterThresholds {
1548
1918
  }
1549
1919
  interface MeterProps {
1550
1920
  value: number;
1921
+ /**
1922
+ * Minimum allowed value.
1923
+ *
1924
+ * @defaultValue `0`
1925
+ * @see the component manifest
1926
+ */
1551
1927
  min?: number;
1928
+ /**
1929
+ * Maximum allowed value.
1930
+ *
1931
+ * @defaultValue `100`
1932
+ * @see the component manifest
1933
+ */
1552
1934
  max?: number;
1553
1935
  label: string;
1936
+ /**
1937
+ * Selects the visual style variant.
1938
+ *
1939
+ * @defaultValue `bar`
1940
+ * @see the component manifest
1941
+ */
1554
1942
  variant?: 'bar' | 'gauge';
1555
1943
  thresholds?: MeterThresholds;
1944
+ /**
1945
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
1946
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
1947
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
1948
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
1949
+ * this — charts call it internally.
1950
+ * @see the component manifest
1951
+ */
1556
1952
  width?: number;
1557
1953
  height?: number;
1558
1954
  }
@@ -1603,11 +1999,34 @@ interface HistogramProps {
1603
1999
  title: string;
1604
2000
  label: string;
1605
2001
  description?: string;
2002
+ /**
2003
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2004
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2005
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2006
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2007
+ * this — charts call it internally.
2008
+ * @see the component manifest
2009
+ */
1606
2010
  width?: number;
1607
2011
  height?: number;
1608
2012
  className?: string;
1609
- /** Render only the marks — no axes or grid lines. For micro/inline charts. */
2013
+ /**
2014
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
2015
+ *
2016
+ * @defaultValue `false`
2017
+ * @see the component manifest
2018
+ */
1610
2019
  plain?: boolean;
2020
+ /**
2021
+ * Format each X-axis tick label. Receives the datum's raw `x` value — a number, a string,
2022
+ * or a `Date`, whichever the series carries.
2023
+ *
2024
+ * Without it a numeric x renders raw: a `Date.now()`-scale value (the natural shape for a
2025
+ * time series) renders as `1,785,217,000,000`. Passing `Date` objects switches the axis to
2026
+ * a time scale, but that format is fixed, so every bucket narrower than a day collapses to
2027
+ * the same label. Threads through `Axis`'s own `format` (2026-07-28 report C16).
2028
+ */
2029
+ format?: (value: number | string | Date) => string;
1611
2030
  }
1612
2031
  declare function Histogram({
1613
2032
  data,
@@ -1618,7 +2037,8 @@ declare function Histogram({
1618
2037
  width: fixedWidth,
1619
2038
  height,
1620
2039
  className,
1621
- plain
2040
+ plain,
2041
+ format
1622
2042
  }: HistogramProps): import("react").JSX.Element;
1623
2043
  interface BoxplotSeries {
1624
2044
  id: string;
@@ -1629,11 +2049,32 @@ interface BoxplotProps {
1629
2049
  series: BoxplotSeries[];
1630
2050
  title: string;
1631
2051
  description?: string;
2052
+ /**
2053
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2054
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2055
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2056
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2057
+ * this — charts call it internally.
2058
+ * @see the component manifest
2059
+ */
1632
2060
  width?: number;
1633
2061
  height?: number;
1634
2062
  className?: string;
1635
- /** Render only the marks — no axes. For micro/inline charts. */
2063
+ /**
2064
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
2065
+ *
2066
+ * @defaultValue `false`
2067
+ * @see the component manifest
2068
+ */
1636
2069
  plain?: boolean;
2070
+ /**
2071
+ * Format each category/x-axis tick label. Receives the datum's raw `x` value — a number,
2072
+ * a string, or a `Date`, whichever the series carries.
2073
+ *
2074
+ * Threads through `Axis`'s own `format`, which every chart composing an axis should
2075
+ * surface (2026-07-28 report C16); enforced by `axis-parity.test.ts`.
2076
+ */
2077
+ format?: (value: number | string | Date) => string;
1637
2078
  }
1638
2079
  declare function Boxplot({
1639
2080
  series,
@@ -1642,7 +2083,8 @@ declare function Boxplot({
1642
2083
  width: fixedWidth,
1643
2084
  height,
1644
2085
  className,
1645
- plain
2086
+ plain,
2087
+ format
1646
2088
  }: BoxplotProps): import("react").JSX.Element;
1647
2089
  interface BubbleDatum {
1648
2090
  x: number;
@@ -1657,14 +2099,37 @@ interface BubbleChartProps {
1657
2099
  series: BubbleSeries[];
1658
2100
  title: string;
1659
2101
  description?: string;
2102
+ /**
2103
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2104
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2105
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2106
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2107
+ * this — charts call it internally.
2108
+ * @see the component manifest
2109
+ */
1660
2110
  width?: number;
1661
2111
  height?: number;
1662
2112
  tooltip?: boolean;
1663
2113
  className?: string;
1664
- /** Render only the marks — no axes or grid lines. For micro/inline charts. */
2114
+ /**
2115
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
2116
+ *
2117
+ * @defaultValue `false`
2118
+ * @see the component manifest
2119
+ */
1665
2120
  plain?: boolean;
1666
2121
  /** Point glyph shape — a fixed shape, or a function to encode a category by shape. Defaults to a circle. */
1667
2122
  glyph?: GlyphShape | ((d: BubbleDatum, seriesName: string) => GlyphShape);
2123
+ /**
2124
+ * Format each X-axis tick label. Receives the datum's raw `x` value — a number, a string,
2125
+ * or a `Date`, whichever the series carries.
2126
+ *
2127
+ * Without it a numeric x renders raw: a `Date.now()`-scale value (the natural shape for a
2128
+ * time series) renders as `1,785,217,000,000`. Passing `Date` objects switches the axis to
2129
+ * a time scale, but that format is fixed, so every bucket narrower than a day collapses to
2130
+ * the same label. Threads through `Axis`'s own `format` (2026-07-28 report C16).
2131
+ */
2132
+ format?: (value: number | string | Date) => string;
1668
2133
  }
1669
2134
  declare function BubbleChart({
1670
2135
  series,
@@ -1675,30 +2140,77 @@ declare function BubbleChart({
1675
2140
  tooltip,
1676
2141
  className,
1677
2142
  plain,
1678
- glyph
2143
+ glyph,
2144
+ format
1679
2145
  }: BubbleChartProps): import("react").JSX.Element;
1680
2146
  interface ComboChartBar {
1681
2147
  label: string;
1682
2148
  value: number;
1683
2149
  }
1684
2150
  interface ComboChartPoint {
2151
+ /** Index into `bars` — point `i` is drawn at the centre of bar `i`. */
1685
2152
  x: number;
1686
2153
  y: number;
1687
2154
  }
1688
2155
  interface ComboChartProps {
2156
+ /** Bar series — one entry per category, in x order. */
1689
2157
  bars: ComboChartBar[];
2158
+ /**
2159
+ * Line series, correlated with `bars` **by array index**: `line[i]` is drawn over
2160
+ * `bars[i]`. Pass the same number of points as bars — a length mismatch is a data bug
2161
+ * and warns in dev.
2162
+ */
1690
2163
  line: ComboChartPoint[];
1691
2164
  title: string;
1692
2165
  description?: string;
2166
+ /** Measure the line on its own right-hand axis (use when the two metrics differ in scale). */
1693
2167
  secondAxis?: boolean;
2168
+ /** Legend label for the bar series. Defaults to `'Bars'`. */
2169
+ barsLabel?: string;
2170
+ /** Legend label for the line series. Defaults to `'Line'`. */
2171
+ lineLabel?: string;
2172
+ /**
2173
+ * Show the legend. Defaults to **on** when both series have data — a two-metric chart
2174
+ * with nothing naming the two metrics is unreadable.
2175
+ */
2176
+ legend?: boolean;
2177
+ /**
2178
+ * Render every Nth category label. **Omit this — it is auto-computed** from the label
2179
+ * widths and the plot width; pass it only to override the automatic stride.
2180
+ */
2181
+ xLabelEvery?: number;
2182
+ /**
2183
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2184
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2185
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2186
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2187
+ * this — charts call it internally.
2188
+ * @see the component manifest
2189
+ */
1694
2190
  width?: number;
2191
+ /** SVG height in px (default 320). Unlike `width`, this does not track the container. */
1695
2192
  height?: number;
1696
2193
  tooltip?: boolean;
1697
2194
  className?: string;
1698
- /** Render only the marks — no axes or grid lines. For micro/inline charts. */
2195
+ /**
2196
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
2197
+ *
2198
+ * @defaultValue `false`
2199
+ * @see the component manifest
2200
+ */
1699
2201
  plain?: boolean;
1700
2202
  /** Reference lines, bands, and markers. `y` maps to the bar value axis. */
1701
2203
  annotations?: readonly Annotation[];
2204
+ /**
2205
+ * Format each X-axis tick label. Receives the datum's raw `x` value — a number, a string,
2206
+ * or a `Date`, whichever the series carries.
2207
+ *
2208
+ * Without it a numeric x renders raw: a `Date.now()`-scale value (the natural shape for a
2209
+ * time series) renders as `1,785,217,000,000`. Passing `Date` objects switches the axis to
2210
+ * a time scale, but that format is fixed, so every bucket narrower than a day collapses to
2211
+ * the same label. Threads through `Axis`'s own `format` (2026-07-28 report C16).
2212
+ */
2213
+ format?: (value: number | string | Date) => string;
1702
2214
  }
1703
2215
  declare function ComboChart({
1704
2216
  bars,
@@ -1706,12 +2218,17 @@ declare function ComboChart({
1706
2218
  title,
1707
2219
  description,
1708
2220
  secondAxis,
2221
+ barsLabel,
2222
+ lineLabel,
2223
+ legend,
2224
+ xLabelEvery,
1709
2225
  width: fixedWidth,
1710
2226
  height,
1711
2227
  tooltip,
1712
2228
  className,
1713
2229
  plain,
1714
- annotations
2230
+ annotations,
2231
+ format
1715
2232
  }: ComboChartProps): import("react").JSX.Element;
1716
2233
  interface HeatmapDatum {
1717
2234
  x: string;
@@ -1722,15 +2239,36 @@ interface HeatmapProps {
1722
2239
  data: HeatmapDatum[];
1723
2240
  title: string;
1724
2241
  description?: string;
2242
+ /**
2243
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2244
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2245
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2246
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2247
+ * this — charts call it internally.
2248
+ * @see the component manifest
2249
+ */
1725
2250
  width?: number;
1726
2251
  height?: number;
1727
2252
  className?: string;
1728
- /** Render only the marks — no axes. For micro/inline charts. */
2253
+ /**
2254
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
2255
+ *
2256
+ * @defaultValue `false`
2257
+ * @see the component manifest
2258
+ */
1729
2259
  plain?: boolean;
1730
2260
  /** Map cell value → CVD-safe colour via a continuous/piecewise legend that filters the range. */
1731
2261
  visualMap?: VisualMapOptions;
1732
2262
  /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
1733
2263
  toolbox?: boolean | ToolboxOptions;
2264
+ /**
2265
+ * Format each category/x-axis tick label. Receives the datum's raw `x` value — a number,
2266
+ * a string, or a `Date`, whichever the series carries.
2267
+ *
2268
+ * Threads through `Axis`'s own `format`, which every chart composing an axis should
2269
+ * surface (2026-07-28 report C16); enforced by `axis-parity.test.ts`.
2270
+ */
2271
+ format?: (value: number | string | Date) => string;
1734
2272
  }
1735
2273
  declare function Heatmap({
1736
2274
  data,
@@ -1741,7 +2279,8 @@ declare function Heatmap({
1741
2279
  className,
1742
2280
  plain,
1743
2281
  visualMap,
1744
- toolbox
2282
+ toolbox,
2283
+ format
1745
2284
  }: HeatmapProps): import("react").JSX.Element;
1746
2285
  interface TreemapDatum {
1747
2286
  id: string;
@@ -1752,10 +2291,23 @@ interface TreemapProps {
1752
2291
  data: TreemapDatum[];
1753
2292
  title: string;
1754
2293
  description?: string;
2294
+ /**
2295
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2296
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2297
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2298
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2299
+ * this — charts call it internally.
2300
+ * @see the component manifest
2301
+ */
1755
2302
  width?: number;
1756
2303
  height?: number;
1757
2304
  className?: string;
1758
- /** Render only the colored rects — no text labels. For micro/inline charts. */
2305
+ /**
2306
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
2307
+ *
2308
+ * @defaultValue `false`
2309
+ * @see the component manifest
2310
+ */
1759
2311
  plain?: boolean;
1760
2312
  }
1761
2313
  declare function Treemap({
@@ -1778,10 +2330,23 @@ interface RadarProps {
1778
2330
  max?: number;
1779
2331
  title: string;
1780
2332
  description?: string;
2333
+ /**
2334
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2335
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2336
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2337
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2338
+ * this — charts call it internally.
2339
+ * @see the component manifest
2340
+ */
1781
2341
  width?: number;
1782
2342
  height?: number;
1783
2343
  className?: string;
1784
- /** Render only the data polygons — no rings, spokes, or axis labels. For micro/inline charts. */
2344
+ /**
2345
+ * Marks only — no axes, grid lines, or legend. For micro/inline charts.
2346
+ *
2347
+ * @defaultValue `false`
2348
+ * @see the component manifest
2349
+ */
1785
2350
  plain?: boolean;
1786
2351
  }
1787
2352
  declare function Radar({
@@ -1800,8 +2365,24 @@ interface BulletProps {
1800
2365
  target: number;
1801
2366
  ranges: number[];
1802
2367
  label: string;
2368
+ /**
2369
+ * Minimum allowed value.
2370
+ *
2371
+ * @defaultValue `0`
2372
+ * @see the component manifest
2373
+ */
1803
2374
  min?: number;
1804
2375
  max?: number;
2376
+ /**
2377
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2378
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2379
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2380
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2381
+ * this — charts call it internally.
2382
+ *
2383
+ * @defaultValue `300`
2384
+ * @see the component manifest
2385
+ */
1805
2386
  width?: number;
1806
2387
  height?: number;
1807
2388
  className?: string;
@@ -1830,11 +2411,24 @@ interface RadialBarProps {
1830
2411
  description?: string;
1831
2412
  /** Square shorthand: sets width === height. Explicit width/height win. */
1832
2413
  size?: number;
2414
+ /**
2415
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2416
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2417
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2418
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2419
+ * this — charts call it internally.
2420
+ * @see the component manifest
2421
+ */
1833
2422
  width?: number;
1834
2423
  height?: number;
1835
2424
  /** Domain top — the value a full sweep represents. Defaults to the largest datum. */
1836
2425
  max?: number;
1837
- /** Sweep angle in degrees (default 270 — a gauge arc). */
2426
+ /**
2427
+ * Sweep angle in degrees (270 = a gauge arc; 360 = a full ring).
2428
+ *
2429
+ * @defaultValue `270`
2430
+ * @see the component manifest
2431
+ */
1838
2432
  sweep?: number;
1839
2433
  /** Center value text rendered in the hole. */
1840
2434
  centerValue?: string;
@@ -1845,7 +2439,12 @@ interface RadialBarProps {
1845
2439
  tooltip?: boolean;
1846
2440
  legend?: boolean;
1847
2441
  className?: string;
1848
- /** Render only the marks — no legend. For micro/inline charts. */
2442
+ /**
2443
+ * Marks only — no legend. For micro/inline charts.
2444
+ *
2445
+ * @defaultValue `false`
2446
+ * @see the component manifest
2447
+ */
1849
2448
  plain?: boolean;
1850
2449
  }
1851
2450
  /**
@@ -1880,13 +2479,31 @@ interface FunnelProps {
1880
2479
  data: readonly FunnelStage[];
1881
2480
  title: string;
1882
2481
  description?: string;
2482
+ /**
2483
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2484
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2485
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2486
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2487
+ * this — charts call it internally.
2488
+ * @see the component manifest
2489
+ */
1883
2490
  width?: number;
1884
2491
  height?: number;
1885
- /** Show per-stage conversion: value + % of the first stage. */
2492
+ /**
2493
+ * Append each stage’s % of the first stage to its label.
2494
+ *
2495
+ * @defaultValue `false`
2496
+ * @see the component manifest
2497
+ */
1886
2498
  showConversion?: boolean;
1887
2499
  tooltip?: boolean;
1888
2500
  className?: string;
1889
- /** Render only the marks — no labels. For micro/inline charts. */
2501
+ /**
2502
+ * Marks only — no labels. For micro/inline charts.
2503
+ *
2504
+ * @defaultValue `false`
2505
+ * @see the component manifest
2506
+ */
1890
2507
  plain?: boolean;
1891
2508
  }
1892
2509
  /**
@@ -1918,15 +2535,48 @@ interface StreamProps {
1918
2535
  categories: readonly (string | number)[];
1919
2536
  title: string;
1920
2537
  description?: string;
1921
- /** `silhouette` (centered streamgraph, default) or `zero` (baseline stack). */
2538
+ /**
2539
+ * silhouette centers the stack (streamgraph); zero is a baseline stack.
2540
+ *
2541
+ * @defaultValue `silhouette`
2542
+ * @see the component manifest
2543
+ */
1922
2544
  offset?: StreamOffset;
2545
+ /**
2546
+ * Interpolation curve.
2547
+ *
2548
+ * @defaultValue `basis`
2549
+ * @see the component manifest
2550
+ */
1923
2551
  curve?: Curve;
2552
+ /**
2553
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2554
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2555
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2556
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2557
+ * this — charts call it internally.
2558
+ * @see the component manifest
2559
+ */
1924
2560
  width?: number;
1925
2561
  height?: number;
1926
2562
  legend?: boolean;
1927
2563
  tooltip?: boolean;
1928
2564
  className?: string;
2565
+ /**
2566
+ * When true, renders a minimal variant without chart chrome.
2567
+ *
2568
+ * @defaultValue `false`
2569
+ * @see the component manifest
2570
+ */
1929
2571
  plain?: boolean;
2572
+ /**
2573
+ * Format each category/x-axis tick label. Receives the datum's raw `x` value — a number,
2574
+ * a string, or a `Date`, whichever the series carries.
2575
+ *
2576
+ * Threads through `Axis`'s own `format`, which every chart composing an axis should
2577
+ * surface (2026-07-28 report C16); enforced by `axis-parity.test.ts`.
2578
+ */
2579
+ format?: (value: number | string | Date) => string;
1930
2580
  }
1931
2581
  /** A streamgraph — stacked areas on a flowing (centered) baseline. */
1932
2582
  declare function Stream({
@@ -1941,7 +2591,8 @@ declare function Stream({
1941
2591
  legend,
1942
2592
  tooltip,
1943
2593
  className,
1944
- plain
2594
+ plain,
2595
+ format
1945
2596
  }: StreamProps): import("react").JSX.Element;
1946
2597
  interface SunburstProps {
1947
2598
  /** Root of the hierarchy. Leaves carry `value`; parents sum their children. */
@@ -1949,10 +2600,24 @@ interface SunburstProps {
1949
2600
  title: string;
1950
2601
  description?: string;
1951
2602
  size?: number;
2603
+ /**
2604
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2605
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2606
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2607
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2608
+ * this — charts call it internally.
2609
+ * @see the component manifest
2610
+ */
1952
2611
  width?: number;
1953
2612
  height?: number;
1954
2613
  tooltip?: boolean;
1955
2614
  className?: string;
2615
+ /**
2616
+ * When true, renders a minimal variant without chart chrome.
2617
+ *
2618
+ * @defaultValue `false`
2619
+ * @see the component manifest
2620
+ */
1956
2621
  plain?: boolean;
1957
2622
  }
1958
2623
  /** A sunburst — a radial partition of a tree; each node is an annular segment. */
@@ -1972,10 +2637,24 @@ interface SankeyProps {
1972
2637
  links: readonly SankeyLink[];
1973
2638
  title: string;
1974
2639
  description?: string;
2640
+ /**
2641
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2642
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2643
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2644
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2645
+ * this — charts call it internally.
2646
+ * @see the component manifest
2647
+ */
1975
2648
  width?: number;
1976
2649
  height?: number;
1977
2650
  tooltip?: boolean;
1978
2651
  className?: string;
2652
+ /**
2653
+ * When true, renders a minimal variant without chart chrome.
2654
+ *
2655
+ * @defaultValue `false`
2656
+ * @see the component manifest
2657
+ */
1979
2658
  plain?: boolean;
1980
2659
  }
1981
2660
  /** A Sankey flow diagram — ranked nodes with throughput-sized link ribbons. */
@@ -2001,10 +2680,24 @@ interface CalendarProps {
2001
2680
  /** Range start/end (ISO string or Date). Defaults to the data's min/max day. */
2002
2681
  from?: string | Date;
2003
2682
  to?: string | Date;
2683
+ /**
2684
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2685
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2686
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2687
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2688
+ * this — charts call it internally.
2689
+ * @see the component manifest
2690
+ */
2004
2691
  width?: number;
2005
2692
  height?: number;
2006
2693
  tooltip?: boolean;
2007
2694
  className?: string;
2695
+ /**
2696
+ * When true, renders a minimal variant without chart chrome.
2697
+ *
2698
+ * @defaultValue `false`
2699
+ * @see the component manifest
2700
+ */
2008
2701
  plain?: boolean;
2009
2702
  /** Map day value → CVD-safe colour via a continuous/piecewise legend that filters the range. */
2010
2703
  visualMap?: VisualMapOptions;
@@ -2030,15 +2723,34 @@ interface CandlestickDatum {
2030
2723
  high: number;
2031
2724
  low: number;
2032
2725
  close: number;
2033
- /** Optional traded volume for the secondary axis. */
2726
+ /**
2727
+ * Render volume bars beneath the candles.
2728
+ *
2729
+ * @defaultValue `false`
2730
+ * @see the component manifest
2731
+ */
2034
2732
  volume?: number;
2035
2733
  }
2036
2734
  interface CandlestickProps {
2037
2735
  data: readonly CandlestickDatum[];
2038
2736
  title: string;
2039
2737
  description?: string;
2738
+ /**
2739
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2740
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2741
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2742
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2743
+ * this — charts call it internally.
2744
+ * @see the component manifest
2745
+ */
2040
2746
  width?: number;
2041
2747
  height?: number;
2748
+ /**
2749
+ * Approximate number of ticks on the y-axis.
2750
+ *
2751
+ * @defaultValue `5`
2752
+ * @see the component manifest
2753
+ */
2042
2754
  yTicks?: number;
2043
2755
  /** Colour for up candles (close ≥ open). */
2044
2756
  upColor?: string;
@@ -2048,6 +2760,12 @@ interface CandlestickProps {
2048
2760
  volume?: boolean;
2049
2761
  tooltip?: boolean;
2050
2762
  className?: string;
2763
+ /**
2764
+ * Marks only — no axes. For micro/inline charts.
2765
+ *
2766
+ * @defaultValue `false`
2767
+ * @see the component manifest
2768
+ */
2051
2769
  plain?: boolean;
2052
2770
  /** Reference lines, shaded bands, and markers over the plot (e.g. a last-price rule). */
2053
2771
  annotations?: readonly Annotation[];
@@ -2059,8 +2777,23 @@ interface CandlestickProps {
2059
2777
  zoom?: boolean;
2060
2778
  /** Connect this chart to others sharing the same id — they mirror the zoom window. */
2061
2779
  syncId?: string;
2062
- /** Tooltip trigger: `item` (default, nearest candle) or `axis` (crosshair + OHLC at hovered x). */
2780
+ /**
2781
+ * item (nearest candle) or axis (crosshair + OHLC at the hovered x).
2782
+ *
2783
+ * @defaultValue `item`
2784
+ * @see the component manifest
2785
+ */
2063
2786
  tooltipMode?: 'item' | 'axis';
2787
+ /**
2788
+ * Format each X-axis tick label. Receives the datum's raw `x` value — a number, a string,
2789
+ * or a `Date`, whichever the series carries.
2790
+ *
2791
+ * Without it a numeric x renders raw: a `Date.now()`-scale value (the natural shape for a
2792
+ * time series) renders as `1,785,217,000,000`. Passing `Date` objects switches the axis to
2793
+ * a time scale, but that format is fixed, so every bucket narrower than a day collapses to
2794
+ * the same label. Threads through `Axis`'s own `format` (2026-07-28 report C16).
2795
+ */
2796
+ format?: (value: number | string | Date) => string;
2064
2797
  }
2065
2798
  declare function Candlestick({
2066
2799
  data: rawData,
@@ -2080,7 +2813,8 @@ declare function Candlestick({
2080
2813
  dataZoom,
2081
2814
  zoom,
2082
2815
  syncId,
2083
- tooltipMode
2816
+ tooltipMode,
2817
+ format: xFormat
2084
2818
  }: CandlestickProps): import("react").JSX.Element;
2085
2819
  interface PolarDatum {
2086
2820
  label: string;
@@ -2091,16 +2825,40 @@ interface PolarProps {
2091
2825
  data: readonly PolarDatum[];
2092
2826
  title: string;
2093
2827
  description?: string;
2094
- /** Plot bars (a rose), or a polar line / filled area. */
2828
+ /**
2829
+ * Bars (rose), a polar line, or a filled polar area.
2830
+ *
2831
+ * @defaultValue `bar`
2832
+ * @see the component manifest
2833
+ */
2095
2834
  mode?: 'bar' | 'line' | 'area';
2835
+ /**
2836
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2837
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2838
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2839
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2840
+ * this — charts call it internally.
2841
+ * @see the component manifest
2842
+ */
2096
2843
  width?: number;
2097
2844
  height?: number;
2098
- /** Radial ring count. */
2845
+ /**
2846
+ * Radial ring count.
2847
+ *
2848
+ * @defaultValue `4`
2849
+ * @see the component manifest
2850
+ */
2099
2851
  rings?: number;
2100
2852
  /** Domain top (full radius). Defaults to the largest value. */
2101
2853
  max?: number;
2102
2854
  tooltip?: boolean;
2103
2855
  className?: string;
2856
+ /**
2857
+ * Marks only — no rings or labels. For micro/inline charts.
2858
+ *
2859
+ * @defaultValue `false`
2860
+ * @see the component manifest
2861
+ */
2104
2862
  plain?: boolean;
2105
2863
  }
2106
2864
  declare function Polar({
@@ -2123,21 +2881,57 @@ interface GaugeThreshold {
2123
2881
  }
2124
2882
  interface GaugeProps {
2125
2883
  value: number;
2884
+ /**
2885
+ * Minimum allowed value.
2886
+ *
2887
+ * @defaultValue `0`
2888
+ * @see the component manifest
2889
+ */
2126
2890
  min?: number;
2891
+ /**
2892
+ * Maximum allowed value.
2893
+ *
2894
+ * @defaultValue `100`
2895
+ * @see the component manifest
2896
+ */
2127
2897
  max?: number;
2128
2898
  /** Coloured zones from `min` upward; the last should reach `max`. */
2129
2899
  thresholds?: readonly GaugeThreshold[];
2130
2900
  /** Unit suffix shown after the centre value. */
2131
2901
  unit?: string;
2132
- /** Total sweep in degrees (default 270 — a speedometer arc). */
2902
+ /**
2903
+ * Total sweep angle in degrees (270 = a speedometer arc).
2904
+ *
2905
+ * @defaultValue `270`
2906
+ * @see the component manifest
2907
+ */
2133
2908
  sweep?: number;
2134
- /** Major tick count (labels at min…max). */
2909
+ /**
2910
+ * Major tick count.
2911
+ *
2912
+ * @defaultValue `5`
2913
+ * @see the component manifest
2914
+ */
2135
2915
  ticks?: number;
2136
2916
  title: string;
2137
2917
  description?: string;
2918
+ /**
2919
+ * Fixed SVG width in px. ⚠ **Omit for a responsive chart** — the chart fills and tracks
2920
+ * its container via a ResizeObserver; there is no correct pixel number in a responsive
2921
+ * grid. A fixed width is clamped to the container (max-inline-size: 100%) so it can never
2922
+ * overflow its card, but it also stops the chart growing. `useChartSize` is NOT needed for
2923
+ * this — charts call it internally.
2924
+ * @see the component manifest
2925
+ */
2138
2926
  width?: number;
2139
2927
  height?: number;
2140
2928
  className?: string;
2929
+ /**
2930
+ * Marks only — no ticks/labels. For micro/inline charts.
2931
+ *
2932
+ * @defaultValue `false`
2933
+ * @see the component manifest
2934
+ */
2141
2935
  plain?: boolean;
2142
2936
  }
2143
2937
  declare function Gauge({
@@ -2155,4 +2949,4 @@ declare function Gauge({
2155
2949
  className,
2156
2950
  plain
2157
2951
  }: GaugeProps): import("react").JSX.Element;
2158
- export { AggOp, AggregateSpec, AngleBand, Annotation, AnnotationContext, AnnotationScale, AreaChart, AreaChartProps, AreaChartSeries, AreaDecimateOptions, Axis, AxisProps, BandScale, BarChart, BarChartProps, BarChartSeries, Bin, BoundStream, BoxStats, Boxplot, BoxplotProps, BoxplotSeries, Brush, BrushProps, BubbleChart, BubbleChartProps, BubbleDatum, BubbleSeries, Bullet, BulletProps, Calendar, CalendarDatum, CalendarProps, Candlestick, CandlestickDatum, CandlestickProps, CanvasLayer, CanvasLayerProps, CanvasPaint, CanvasSize, CategoryDatum, CategoryMapping, ChartDefs, ChartDefsProps, ChartFrame, ChartFrameProps, ChartSize, ComboChart, ComboChartBar, ComboChartPoint, ComboChartProps, Curve, DEFAULT_MARGINS, DataLabel, DataLabelProps, DataZoom, DataZoomProps, DecimateMethod, DecimateOptions, DefSeries, EncodeMapping, EncodedResult, EncodedSeries, FillKind, Funnel, FunnelProps, FunnelStage, Gauge, GaugeProps, GaugeThreshold, Glyph, GlyphProps, GlyphShape, GridLines, GridLinesProps, Heatmap, HeatmapDatum, HeatmapProps, HierNode, Histogram, HistogramBin, HistogramProps, Kpi, KpiProps, LabelOptions, LaidLink, LaidNode, Legend, LegendProps, LegendSeries, LineChart, LineChartProps, LineChartSeries, LinearScale, LogScale, Meter, MeterProps, MeterThresholds, PLAIN_MARGINS, PartitionedNode, PatternKind, PieChart, PieChartDatum, PieChartProps, Point, Polar, PolarDatum, PolarProps, Pt, Radar, RadarProps, RadarSeries, RadialBar, RadialBarDatum, RadialBarProps, RampKind, Rect, RegressionResult, RegressionType, ResolvedLabelOptions, Row, Sankey, SankeyLayout, SankeyLink, SankeyNode, SankeyOptions, SankeyProps, ScatterChart, ScatterChartProps, ScatterChartSeries, ScatterDatum, Sparkline, SparklineProps, StackedRow, StackedSegment, Stream, StreamDecimate, StreamOffset, StreamProps, StreamSeries, StreamSeriesOptions, StreamSource, Sunburst, SunburstProps, SyncGroup, Text, TextProps, TimeScale, Toolbox, ToolboxOptions, ToolboxProps, Treemap, TreemapDatum, TreemapNode, TreemapProps, TreemapRect, Vec, VisualChannel, VisualMap, VisualMapOptions, VisualMapProps, VisualMode, VisualResult, ZoomConfig, _syncGroupCount, aggregate, angleBand, annotationSummary, arcPath, areaPath, autoLabelStride, bandScale, bin, binValues, bindStream, boxStats, cellPath, decimate$1 as decimate, divergingRamp, download, encode, encodeCategory, extent, fillFor, filter, getSyncGroup, glyphPath, gradientId, isZoomed, leftMarginForLabels, linePath, linearScale, linkPath, logScale, lttb, mapVisual, maxDepth, minmax, nearestIndex, niceTicks, panWindow, partition, patternId, pieceIndex, polarPoint, quantize, radiusScale, rampLightness, rampOf, rampStops, regression, releaseSyncGroup, renderAnnotation, renderAnnotations, resolveColor, resolveLabels, sankeyLayout, sequentialRamp, serializeSvg, sort, splitDefined, sqrtScale, squarify, stackSeries, streamExtent, streamLayout, sumValue, svgToPngBlob, timeScale, toStackedSeries, useChartSize, useStreamSeries, visualVisible, voronoiCells, voronoiFind, wrapText, zoomWindow };
2952
+ export { AXIS_CHAR_PX, AggOp, AggregateSpec, AngleBand, Annotation, AnnotationContext, AnnotationScale, AreaChart, AreaChartProps, AreaChartSeries, AreaDecimateOptions, Axis, AxisProps, BandScale, BarChart, BarChartProps, BarChartSeries, Bin, BoundStream, BoxStats, Boxplot, BoxplotProps, BoxplotSeries, Brush, BrushProps, BubbleChart, BubbleChartProps, BubbleDatum, BubbleSeries, Bullet, BulletProps, Calendar, CalendarDatum, CalendarProps, Candlestick, CandlestickDatum, CandlestickProps, CanvasLayer, CanvasLayerProps, CanvasPaint, CanvasSize, CategoryDatum, CategoryMapping, ChartDefs, ChartDefsProps, ChartFrame, ChartFrameProps, ChartSize, ComboChart, ComboChartBar, ComboChartPoint, ComboChartProps, Curve, DEFAULT_MARGINS, DataLabel, DataLabelProps, DataZoom, DataZoomProps, DecimateMethod, DecimateOptions, DefSeries, EncodeMapping, EncodedResult, EncodedSeries, FillKind, Funnel, FunnelProps, FunnelStage, Gauge, GaugeProps, GaugeThreshold, Glyph, GlyphProps, GlyphShape, GridLines, GridLinesProps, Heatmap, HeatmapDatum, HeatmapProps, HierNode, Histogram, HistogramBin, HistogramProps, Kpi, KpiProps, LabelOptions, LaidLink, LaidNode, Legend, LegendProps, LegendSeries, LineChart, LineChartProps, LineChartSeries, LinearScale, LogScale, Meter, MeterProps, MeterThresholds, PLAIN_MARGINS, PartitionedNode, PatternKind, PieChart, PieChartDatum, PieChartProps, Point, Polar, PolarDatum, PolarProps, Pt, Radar, RadarProps, RadarSeries, RadialBar, RadialBarDatum, RadialBarProps, RampKind, Rect, RegressionResult, RegressionType, ResolvedLabelOptions, Row, Sankey, SankeyLayout, SankeyLink, SankeyNode, SankeyOptions, SankeyProps, ScatterChart, ScatterChartProps, ScatterChartSeries, ScatterDatum, Sparkline, SparklineProps, StackedRow, StackedSegment, Stream, StreamDecimate, StreamOffset, StreamProps, StreamSeries, StreamSeriesOptions, StreamSource, Sunburst, SunburstProps, SyncGroup, Text, TextProps, TimeScale, Toolbox, ToolboxOptions, ToolboxProps, Treemap, TreemapDatum, TreemapNode, TreemapProps, TreemapRect, Vec, VisualChannel, VisualMap, VisualMapOptions, VisualMapProps, VisualMode, VisualResult, ZoomConfig, _syncGroupCount, aggregate, angleBand, annotationSummary, arcPath, areaPath, autoLabelStride, bandScale, bin, binValues, bindStream, boxStats, cellPath, decimate$1 as decimate, divergingRamp, download, encode, encodeCategory, extent, fillFor, filter, getSyncGroup, glyphPath, gradientId, isZoomed, leftMarginForLabels, linePath, linearScale, linkPath, logScale, lttb, mapVisual, maxDepth, minmax, nearestIndex, niceTicks, panWindow, partition, patternId, pieceIndex, polarPoint, quantize, radiusScale, rampLightness, rampOf, rampStops, regression, releaseSyncGroup, renderAnnotation, renderAnnotations, resolveColor, resolveLabels, rightMarginForLabels, sankeyLayout, sequentialRamp, serializeSvg, sort, splitDefined, sqrtScale, squarify, stackSeries, streamExtent, streamLayout, sumValue, svgToPngBlob, timeScale, toStackedSeries, useChartSize, useStreamSeries, visualVisible, voronoiCells, voronoiFind, wrapText, zoomWindow };