@cascivo/charts 0.3.3 → 0.3.8

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
@@ -1,5 +1,6 @@
1
+ import { ReadonlySignal, Signal } from "@cascivo/core";
1
2
  import { ReactNode } from "react";
2
- import { Signal } from "@preact/signals-react";
3
+ import { Signal as Signal$1 } from "@preact/signals-react";
3
4
 
4
5
  interface LinearScale {
5
6
  domain: [number, number];
@@ -39,10 +40,139 @@ interface TimeScale {
39
40
  }
40
41
  declare function timeScale(domain: [Date, Date], range: [number, number]): TimeScale;
41
42
  type Point = readonly [x: number, y: number];
42
- declare function linePath(points: readonly Point[], curve?: 'linear' | 'monotone'): string;
43
- declare function areaPath(points: readonly Point[], baseline: number, curve?: 'linear' | 'monotone'): string;
43
+ /**
44
+ * Split a list of points (where `null` marks a gap / missing value) into
45
+ * contiguous defined runs. With `connectNulls`, drops the gaps and returns one
46
+ * run bridging them. A series `[a, null, b]` yields `[[a], [b]]` by default,
47
+ * or `[[a, b]]` when connecting — so a gap renders as a real break, not an
48
+ * invented straight segment.
49
+ */
50
+ declare function splitDefined(points: readonly (Point | null)[], connectNulls?: boolean): Point[][];
51
+ /** Curve interpolations supported by linePath / areaPath. */
52
+ type Curve = 'linear' | 'monotone' | 'step' | 'stepBefore' | 'stepAfter' | 'natural' | 'basis' | 'cardinal' | 'catmullRom';
53
+ declare function linePath(points: readonly Point[], curve?: Curve): string;
54
+ declare function areaPath(points: readonly Point[], baseline: number, curve?: Curve): string;
44
55
  declare function arcPath(cx: number, cy: number, outerRadius: number, innerRadius: number, startAngle: number, endAngle: number): string;
45
56
  declare function stackSeries(series: readonly (readonly number[])[]): [number, number][][];
57
+ /** A scale that maps a domain value to a pixel position within the plot area. */
58
+ interface AnnotationScale {
59
+ map: (value: never) => number | undefined;
60
+ /** Band scales place a category at its start; add half the bandwidth to center. */
61
+ bandwidth?: number;
62
+ }
63
+ /**
64
+ * A declarative chart annotation. `line` draws a threshold/target rule across the
65
+ * plot; `area` shades a band between two values; `dot` marks a single point.
66
+ */
67
+ type Annotation = {
68
+ kind: 'line'; /** Which axis the `value` is measured on. */
69
+ axis: 'x' | 'y';
70
+ value: number | string | Date;
71
+ label?: string;
72
+ color?: string; /** Dashed rule (default) vs solid. */
73
+ dash?: boolean;
74
+ } | {
75
+ kind: 'area';
76
+ axis: 'x' | 'y';
77
+ from: number | string | Date;
78
+ to: number | string | Date;
79
+ label?: string;
80
+ color?: string;
81
+ } | {
82
+ kind: 'dot';
83
+ x: number | string | Date;
84
+ y: number;
85
+ label?: string;
86
+ color?: string;
87
+ } | {
88
+ /** A subject marker at (x, y) with a connector/leader line to an offset note label. */kind: 'note';
89
+ x: number | string | Date;
90
+ y: number;
91
+ label: string; /** Label offset from the subject, in px (default up-right). */
92
+ dx?: number;
93
+ dy?: number;
94
+ color?: string;
95
+ } | {
96
+ /** Shade the region above/below a y value — a difference-from-threshold band. */kind: 'threshold';
97
+ value: number;
98
+ side: 'above' | 'below';
99
+ label?: string;
100
+ color?: string;
101
+ };
102
+ interface AnnotationContext {
103
+ xScale: AnnotationScale;
104
+ yScale: AnnotationScale;
105
+ innerW: number;
106
+ innerH: number;
107
+ }
108
+ /** Render a single annotation against the resolved scales. Returns null if it maps off-scale. */
109
+ declare function renderAnnotation(annotation: Annotation, ctx: AnnotationContext, key: number): ReactNode;
110
+ /** Render every annotation in the list against the resolved scales. */
111
+ declare function renderAnnotations(annotations: readonly Annotation[] | undefined, ctx: AnnotationContext): ReactNode;
112
+ /** Short human summary of an annotation, for the chart description / a11y tree. */
113
+ declare function annotationSummary(a: Annotation): string;
114
+ /**
115
+ * Opt-in value labels printed at each mark. `true` uses the defaults; an object
116
+ * tunes the formatter and placement. Labels are decorative (`aria-hidden`) — the
117
+ * value is already in the a11y tree via the fallback table and the aria-live tooltip.
118
+ */
119
+ type LabelOptions = boolean | {
120
+ /** Format the raw value (default: `toLocaleString`). */format?: (value: number) => string; /** Where to place the label relative to its mark. `auto` flips above→inside when it won't fit. */
121
+ position?: 'auto' | 'above' | 'inside' | 'outside';
122
+ };
123
+ interface ResolvedLabelOptions {
124
+ format: (value: number) => string;
125
+ position: 'auto' | 'above' | 'inside' | 'outside';
126
+ }
127
+ /** Normalize the `labels` prop into resolved options, or `null` when disabled. */
128
+ declare function resolveLabels(labels: LabelOptions | undefined): ResolvedLabelOptions | null;
129
+ interface DataLabelProps {
130
+ x: number;
131
+ y: number;
132
+ text: string;
133
+ /** `muted` for inside-the-mark labels (on a colored fill), default otherwise. */
134
+ tone?: 'default' | 'muted';
135
+ anchor?: 'start' | 'middle' | 'end';
136
+ }
137
+ /** A single decorative value label. Always `aria-hidden` (value is in the a11y tree elsewhere). */
138
+ declare function DataLabel({
139
+ x,
140
+ y,
141
+ text,
142
+ tone,
143
+ anchor
144
+ }: DataLabelProps): ReactNode;
145
+ type FillKind = 'solid' | 'gradient' | 'pattern';
146
+ type PatternKind = 'dots' | 'lines' | 'cross';
147
+ interface DefSeries {
148
+ id: string;
149
+ color: string;
150
+ }
151
+ declare function gradientId(prefix: string, seriesId: string): string;
152
+ declare function patternId(prefix: string, seriesId: string): string;
153
+ /**
154
+ * Resolve a series' fill: a `url(#id)` referencing a `<ChartDefs>` gradient/pattern,
155
+ * or the solid color when `fill === 'solid'`.
156
+ */
157
+ declare function fillFor(prefix: string, seriesId: string, fill: FillKind, color: string): string;
158
+ interface ChartDefsProps {
159
+ /** Unique per-chart prefix — pass a `useId()` so two charts on a page don't collide. */
160
+ prefix: string;
161
+ series: readonly DefSeries[];
162
+ fill: FillKind;
163
+ patternKind?: PatternKind | undefined;
164
+ }
165
+ /**
166
+ * Mint theme-derived SVG `<defs>` for the given series. Gradients fade the series
167
+ * color top→bottom; patterns stroke a dot/line/cross motif in the series color over
168
+ * a faint tint. All colors come from the resolved palette, so they stay CVD-safe.
169
+ */
170
+ declare function ChartDefs({
171
+ prefix,
172
+ series,
173
+ fill,
174
+ patternKind
175
+ }: ChartDefsProps): ReactNode;
46
176
  /** A single focusable data point for the chart tooltip system.
47
177
  * cx/cy are absolute SVG coordinates (already include margin offsets). */
48
178
  interface ChartPoint {
@@ -72,6 +202,12 @@ interface TooltipModel {
72
202
  points: ChartPoint[];
73
203
  /** Custom formatter — defaults to "label: value" */
74
204
  format?: (p: ChartPoint) => string;
205
+ /**
206
+ * Hit-test + presentation mode. `item` (default): nearest point in 2-D, one datum
207
+ * per tooltip. `axis`: nearest x-bucket, a vertical crosshair, and one tooltip
208
+ * listing every series at that x (carried as the point's `segments`).
209
+ */
210
+ mode?: 'item' | 'axis';
75
211
  }
76
212
  interface BarChartSeries<Datum> {
77
213
  id: string;
@@ -89,7 +225,7 @@ interface BarChartProps<Datum = {
89
225
  title: string;
90
226
  description?: string;
91
227
  orientation?: 'vertical' | 'horizontal';
92
- mode?: 'grouped' | 'stacked';
228
+ mode?: 'grouped' | 'stacked' | 'percent';
93
229
  width?: number;
94
230
  height?: number;
95
231
  xTicks?: number;
@@ -103,6 +239,19 @@ interface BarChartProps<Datum = {
103
239
  className?: string;
104
240
  /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
105
241
  plain?: boolean;
242
+ /**
243
+ * Reference lines, bands, and markers drawn over the plot. Geometric axes: `y` is the
244
+ * vertical axis (a threshold on a vertical bar chart's value), `x` is horizontal.
245
+ */
246
+ annotations?: readonly Annotation[];
247
+ /** Print each bar's value as a label. `true` for defaults, or tune format/position. */
248
+ labels?: LabelOptions;
249
+ /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
250
+ onSelect?: (point: ChartPoint) => void;
251
+ /** Bar fill style: solid (default), a gradient, or a pattern. */
252
+ fill?: FillKind;
253
+ /** Pattern motif when `fill="pattern"`. */
254
+ patternKind?: PatternKind;
106
255
  }
107
256
  declare function BarChart<Datum = {
108
257
  x: string;
@@ -124,7 +273,12 @@ declare function BarChart<Datum = {
124
273
  tooltip,
125
274
  tooltipFormat,
126
275
  className,
127
- plain
276
+ plain,
277
+ annotations,
278
+ labels,
279
+ onSelect,
280
+ fill,
281
+ patternKind
128
282
  }: BarChartProps<Datum>): import("react").JSX.Element;
129
283
  /** One layer of a stacked bar at a category. */
130
284
  interface StackedSegment {
@@ -165,6 +319,28 @@ declare function toStackedSeries(rows: readonly StackedRow[]): {
165
319
  };
166
320
  /** Binary search for the index of the nearest value in a sorted array. */
167
321
  declare function nearestIndex(values: readonly number[], target: number): number;
322
+ type Vec = readonly [x: number, y: number];
323
+ interface Rect {
324
+ x0: number;
325
+ y0: number;
326
+ x1: number;
327
+ y1: number;
328
+ }
329
+ /**
330
+ * Index of the nearest site to (x, y) — i.e. which Voronoi cell the point falls in.
331
+ * Euclidean; returns -1 for an empty set. This is the precise nearest-point lookup
332
+ * for dense scatter/line hover.
333
+ */
334
+ declare function voronoiFind(sites: readonly Vec[], x: number, y: number): number;
335
+ /**
336
+ * Compute each site's Voronoi cell polygon by clipping `bounds` with the
337
+ * perpendicular bisector against every other site. O(n²) but correct and
338
+ * dependency-free — fine for the hundreds-of-points hover-mesh use case.
339
+ * Returns one polygon (array of points) per site, in site order.
340
+ */
341
+ declare function voronoiCells(sites: readonly Vec[], bounds: Rect): Vec[][];
342
+ /** Render a cell polygon as an SVG path `d` (closed). */
343
+ declare function cellPath(cell: Vec[]): string;
168
344
  /** Statistical helpers for histogram and boxplot charts. */
169
345
  interface Bin {
170
346
  x0: number;
@@ -205,6 +381,356 @@ interface TreemapRect {
205
381
  * Returns rectangles positioned within [0, width] × [0, height].
206
382
  */
207
383
  declare function squarify(nodes: TreemapNode[], width: number, height: number): TreemapRect[];
384
+ type StreamOffset = 'zero' | 'silhouette';
385
+ /**
386
+ * Stacked `[y0, y1]` bands per series with a baseline offset. `zero` is a standard
387
+ * stack; `silhouette` centers each category's stack on a flowing baseline (the
388
+ * classic streamgraph). Dependency-free, built on `stackSeries`.
389
+ */
390
+ declare function streamLayout(values: readonly (readonly number[])[], offset?: StreamOffset): [number, number][][];
391
+ /** Min/max y across all bands — for the value-axis domain. */
392
+ declare function streamExtent(bands: readonly (readonly [number, number])[][]): [number, number];
393
+ interface HierNode {
394
+ id?: string;
395
+ label: string;
396
+ value?: number;
397
+ color?: string;
398
+ children?: HierNode[];
399
+ }
400
+ interface PartitionedNode {
401
+ node: HierNode;
402
+ depth: number;
403
+ /** Start/end angle in radians (0 = top, clockwise). */
404
+ a0: number;
405
+ a1: number;
406
+ value: number;
407
+ }
408
+ /** Sum a node's value bottom-up (a leaf's own value, or the sum of its children). */
409
+ declare function sumValue(n: HierNode): number;
410
+ /**
411
+ * Radial partition of a tree: each node gets an angular slice proportional to its
412
+ * value, nested by depth. Dependency-free; the radial sibling of the squarified
413
+ * treemap. Returns a flat list (root first) for easy rendering.
414
+ */
415
+ declare function partition(root: HierNode, fullAngle?: number): PartitionedNode[];
416
+ declare function maxDepth(nodes: readonly PartitionedNode[]): number;
417
+ interface SankeyNode {
418
+ id: string;
419
+ label: string;
420
+ color?: string;
421
+ }
422
+ interface SankeyLink {
423
+ source: string;
424
+ target: string;
425
+ value: number;
426
+ }
427
+ interface LaidNode extends SankeyNode {
428
+ rank: number;
429
+ value: number;
430
+ x0: number;
431
+ x1: number;
432
+ y0: number;
433
+ y1: number;
434
+ }
435
+ interface LaidLink {
436
+ source: LaidNode;
437
+ target: LaidNode;
438
+ value: number;
439
+ /** Y at the source's right edge and target's left edge (band centers' tops). */
440
+ sy: number;
441
+ ty: number;
442
+ width: number;
443
+ }
444
+ interface SankeyLayout {
445
+ nodes: LaidNode[];
446
+ links: LaidLink[];
447
+ }
448
+ interface SankeyOptions {
449
+ width: number;
450
+ height: number;
451
+ nodeWidth?: number;
452
+ nodePadding?: number;
453
+ }
454
+ /**
455
+ * A dependency-free Sankey layout: rank nodes by longest path from a source,
456
+ * stack them within each rank sized by throughput, and route links as ribbons.
457
+ * No crossing-minimization sweep (stable input order) — good for the common
458
+ * small/medium flow diagram.
459
+ */
460
+ declare function sankeyLayout(nodes: readonly SankeyNode[], links: readonly SankeyLink[], {
461
+ width,
462
+ height,
463
+ nodeWidth,
464
+ nodePadding
465
+ }: SankeyOptions): SankeyLayout;
466
+ /** Cubic ribbon path for one link (a filled band from source edge to target edge). */
467
+ declare function linkPath(l: LaidLink): string;
468
+ /**
469
+ * CVD-safe colour ramps for data→colour encoding. Colours are interpolated in
470
+ * **oklch** between perceptually ordered anchors:
471
+ * - `sequential` runs light→dark with monotonically decreasing lightness, so the
472
+ * ordering survives any colour-vision deficiency (luminance carries the signal).
473
+ * - `diverging` runs a CVD-safe blue→neutral→orange pair, symmetric in lightness.
474
+ * Returned values are CSS `oklch()` strings — no `var()`, so they serialize cleanly
475
+ * for export and render identically across themes.
476
+ */
477
+ type RampKind = 'sequential' | 'diverging';
478
+ /** Sequential ramp (light→dark) at `t ∈ [0,1]`; clamps out-of-range. */
479
+ declare function sequentialRamp(t: number): string;
480
+ /** Diverging ramp (blue→neutral→orange) at `t ∈ [0,1]`; clamps out-of-range. */
481
+ declare function divergingRamp(t: number): string;
482
+ /** The ramp function for a kind. */
483
+ declare function rampOf(kind: RampKind): (t: number) => string;
484
+ /** `n` evenly-spaced ramp colours (for piecewise buckets + the legend gradient). */
485
+ declare function rampStops(n: number, kind?: RampKind): string[];
486
+ /** Read the lightness (L) component out of an `oklch(L C H)` string — test/util helper. */
487
+ declare function rampLightness(color: string): number;
488
+ /** Convert a polar (radius, angle) around a centre to cartesian (x, y). */
489
+ declare function polarPoint(cx: number, cy: number, radius: number, angle: number): [number, number];
490
+ interface AngleBand<T extends string = string> {
491
+ /** Start angle (radians) of a category's band. */
492
+ map: (v: T) => number | undefined;
493
+ /** Centre angle (radians) of a category's band. */
494
+ center: (v: T) => number | undefined;
495
+ /** Angular width of one band (radians). */
496
+ bandwidth: number;
497
+ /** Step between band starts (radians) — equals bandwidth for a gapless ring. */
498
+ step: number;
499
+ }
500
+ /**
501
+ * A band scale over the circle: maps categories to equal angular slices spanning
502
+ * `[a0, a1]` (radians, default a full turn).
503
+ */
504
+ declare function angleBand<T extends string>(domain: readonly T[], range?: [number, number]): AngleBand<T>;
505
+ /** A linear radius scale: value domain → `[innerR, outerR]` pixels. */
506
+ declare function radiusScale(domain: [number, number], range: [number, number]): LinearScale;
507
+ /**
508
+ * Pure, composable data-pipeline helpers — cascivo's answer to ECharts' dataset
509
+ * `transform`s. Each is a dependency-free `(rows) => rows` (or `rows → aggregated`)
510
+ * function meant to be chained left-to-right before handing the result to `encode`
511
+ * (see `dataset.ts`). No React, no signals; safe to run anywhere.
512
+ */
513
+ type Row = Record<string, unknown>;
514
+ /** Keep rows for which `pred` is true (stable order preserved). */
515
+ declare function filter<T>(rows: readonly T[], pred: (row: T, index: number) => boolean): T[];
516
+ type SortKey<T> = keyof T | ((row: T) => unknown);
517
+ /** Stable sort by a field or accessor, ascending (default) or descending. */
518
+ declare function sort<T>(rows: readonly T[], key: SortKey<T>, dir?: 'asc' | 'desc'): T[];
519
+ type AggOp = 'sum' | 'mean' | 'min' | 'max' | 'count' | 'median';
520
+ interface AggregateSpec {
521
+ /** Field(s) to group by. */
522
+ groupBy: string | readonly string[];
523
+ /** Map of output field → aggregation op applied to that field's numeric values. */
524
+ ops: Record<string, AggOp>;
525
+ }
526
+ /**
527
+ * Group rows by `groupBy` and aggregate each configured field. Output rows carry the
528
+ * group key fields plus one field per `ops` entry. Group order is first-seen (stable).
529
+ */
530
+ declare function aggregate(rows: readonly Row[], spec: AggregateSpec): Row[];
531
+ interface HistogramBin {
532
+ x0: number;
533
+ x1: number;
534
+ count: number;
535
+ values: number[];
536
+ }
537
+ /**
538
+ * Partition numeric values into evenly-spaced histogram buckets. Buckets are
539
+ * `[x0, x1)` except the last, which is closed so the maximum lands inside.
540
+ */
541
+ declare function bin(values: readonly number[], opts?: {
542
+ bins?: number;
543
+ range?: [number, number];
544
+ }): HistogramBin[];
545
+ type RegressionType = 'linear' | 'exponential' | {
546
+ type: 'polynomial';
547
+ order: number;
548
+ };
549
+ interface RegressionResult {
550
+ predict: (x: number) => number;
551
+ /** Fitted points at each input x (sorted by x). */
552
+ points: [number, number][];
553
+ /** Coefficient of determination R² against the input y. */
554
+ r2: number;
555
+ /** Model coefficients (linear: [intercept, slope]; polynomial: [c0..cN]). */
556
+ coefficients: number[];
557
+ }
558
+ /**
559
+ * Least-squares regression. `linear` fits y = m·x + b; `exponential` fits y = a·e^(b·x)
560
+ * (over points with y > 0); `polynomial(order)` fits a degree-N curve. Returns a
561
+ * `predict`, the fitted points, R², and the coefficients. Degenerate inputs (fewer than
562
+ * two points) yield a constant fit rather than throwing.
563
+ */
564
+ declare function regression(points: readonly [number, number][], opts?: {
565
+ type?: RegressionType;
566
+ }): RegressionResult;
567
+ interface EncodeMapping {
568
+ /** Field for the x value. */
569
+ x: string;
570
+ /** Field for the y value. */
571
+ y: string;
572
+ /** Optional field whose distinct values split rows into separate series. */
573
+ series?: string;
574
+ /** Optional label for the single-series case (default: the `y` field name). */
575
+ label?: string;
576
+ }
577
+ interface EncodedSeries {
578
+ id: string;
579
+ label: string;
580
+ data: {
581
+ x: unknown;
582
+ y: number;
583
+ }[];
584
+ }
585
+ interface EncodedResult {
586
+ series: EncodedSeries[];
587
+ x: (d: {
588
+ x: unknown;
589
+ y: number;
590
+ }) => unknown;
591
+ y: (d: {
592
+ x: unknown;
593
+ y: number;
594
+ }) => number;
595
+ }
596
+ /**
597
+ * Encode a flat table into chart-ready series. Without a `series` key the whole table
598
+ * becomes one series; with one, rows are split by that field's distinct values
599
+ * (first-seen order). Missing `x`/`y` fields yield `undefined`/`NaN` rather than throwing.
600
+ */
601
+ declare function encode(rows: readonly Row[], mapping: EncodeMapping): EncodedResult;
602
+ interface CategoryMapping {
603
+ /** Field for the slice/bar label. */
604
+ category: string;
605
+ /** Field for the numeric value. */
606
+ value: string;
607
+ }
608
+ interface CategoryDatum {
609
+ label: string;
610
+ value: number;
611
+ }
612
+ /** Encode a table into `{ label, value }[]` for pie/single-series bar charts. */
613
+ declare function encodeCategory(rows: readonly Row[], mapping: CategoryMapping): CategoryDatum[];
614
+ /**
615
+ * Downsampling for dense series — render thousands of points fast without losing
616
+ * visual shape. `lttb` (Largest-Triangle-Three-Buckets) preserves the perceived
617
+ * curve; `minmax` preserves spikes (keeps each bucket's extremes). Both are pure,
618
+ * dependency-free, and no-ops when the input already fits the threshold. The chart's
619
+ * fallback `<table>` keeps the full data, so a11y is unaffected by decimation.
620
+ */
621
+ type Pt = readonly [number, number];
622
+ /**
623
+ * Largest-Triangle-Three-Buckets. Returns at most `threshold` points, always keeping
624
+ * the first and last, choosing the point in each bucket that forms the largest
625
+ * triangle with the previously kept point and the next bucket's average.
626
+ */
627
+ declare function lttb(points: readonly Pt[], threshold: number): Pt[];
628
+ /**
629
+ * Min-max decimation. Splits into ~threshold/2 buckets and keeps each bucket's min and
630
+ * max y (emitted in x order), plus the first and last point — so spikes survive.
631
+ */
632
+ declare function minmax(points: readonly Pt[], threshold: number): Pt[];
633
+ type DecimateMethod = 'lttb' | 'minmax';
634
+ /** Decimate with the chosen method (default LTTB); no-op below the threshold. */
635
+ declare function decimate$1(points: readonly Pt[], threshold: number, method?: DecimateMethod): Pt[];
636
+ /**
637
+ * A live source: call `push(point)` for each new datum; return an unsubscribe.
638
+ * This is the seam a polling loop, an `EventSource` (SSE), or a WebSocket plugs
639
+ * into — the helper never opens a connection itself.
640
+ */
641
+ type StreamSource<P> = (push: (point: P) => void) => () => void;
642
+ interface StreamDecimate<P> {
643
+ /** Cap the rendered point count at this many. */
644
+ to: number;
645
+ /** Numeric value used to choose which points to keep. */
646
+ y: (point: P) => number;
647
+ /** LTTB (default, shape-preserving) or min-max (spike-preserving). */
648
+ method?: DecimateMethod;
649
+ }
650
+ interface StreamSeriesOptions<P> {
651
+ /** Maximum retained points. Oldest evicted past this (O(1) ring buffer). */
652
+ capacity: number;
653
+ /** The live source feeding the buffer. */
654
+ source: StreamSource<P>;
655
+ /** Optionally downsample the window so the rendered series never exceeds `to`. */
656
+ decimate?: StreamDecimate<P>;
657
+ }
658
+ /**
659
+ * Feed a live `source` into a bounded, O(1) ring buffer and expose the current
660
+ * window as a signal for `LineChart`/`AreaChart`. Optionally decimate so a fast
661
+ * stream never blows the rendered point count. Component-scoped: the
662
+ * subscription starts on mount and tears down (unsubscribe + cancel flush) on
663
+ * unmount. No `useState`/`useEffect`.
664
+ */
665
+ declare function useStreamSeries<P>(options: StreamSeriesOptions<P>): ReadonlySignal<readonly P[]>;
666
+ interface BoundStream<P> {
667
+ signal: ReadonlySignal<readonly P[]>;
668
+ stop: () => void;
669
+ }
670
+ /**
671
+ * Non-hook form of {@link useStreamSeries} for imperative callers (outside a
672
+ * component). Returns the window signal plus a `stop()` that unsubscribes the
673
+ * source and cancels any pending flush.
674
+ */
675
+ declare function bindStream<P>(options: StreamSeriesOptions<P>): BoundStream<P>;
676
+ interface CanvasSize {
677
+ width: number;
678
+ height: number;
679
+ }
680
+ type CanvasPaint = (ctx: CanvasRenderingContext2D, size: CanvasSize) => void;
681
+ interface CanvasLayerProps {
682
+ /** Getter that reads the (possibly signal-backed) size so a resize repaints. */
683
+ size: () => CanvasSize;
684
+ paint: CanvasPaint;
685
+ }
686
+ /**
687
+ * A `<canvas>` painted via `useSignalEffect`, positioned to overlay the plot. The
688
+ * size getter reads the chart's size signals, so a resize (or any signal the paint
689
+ * reads) repaints. Decorative — `aria-hidden`; the data lives in the SVG/DOM a11y
690
+ * tree above it. devicePixelRatio-scaled for crisp marks.
691
+ */
692
+ declare function CanvasLayer({
693
+ size,
694
+ paint
695
+ }: CanvasLayerProps): ReactNode;
696
+ /** Resolve a CSS custom property (e.g. `--cascivo-chart-1`) to a concrete color via the canvas element. */
697
+ declare function resolveColor(ctx: CanvasRenderingContext2D, cssValue: string): string;
698
+ interface ToolboxOptions {
699
+ /** Export the chart as a PNG (default true). */
700
+ png?: boolean;
701
+ /** Export the chart as a standalone SVG (default true). */
702
+ svg?: boolean;
703
+ /** Toggle a readable data `<table>` (default true). */
704
+ dataView?: boolean;
705
+ /** Reset zoom / visualMap / legend filters (default true). */
706
+ restore?: boolean;
707
+ }
708
+ interface ToolboxProps {
709
+ options: ToolboxOptions;
710
+ onPng: () => void;
711
+ onSvg: () => void;
712
+ onToggleData: () => void;
713
+ onRestore: () => void;
714
+ showData: boolean;
715
+ }
716
+ /**
717
+ * The chart's utility belt — real `<button>`s (keyboard + focus-visible, ≥44px under
718
+ * coarse pointers) to export a PNG/SVG, toggle a data-view table, and restore the
719
+ * default view. Rendered in the chart's corner by `ChartFrame`.
720
+ */
721
+ declare function Toolbox({
722
+ options,
723
+ onPng,
724
+ onSvg,
725
+ onToggleData,
726
+ onRestore,
727
+ showData
728
+ }: ToolboxProps): import("react").JSX.Element;
729
+ /** In-plot zoom-pan config: a shared index window + the total item count. */
730
+ interface ZoomConfig {
731
+ window: Signal<[number, number]>;
732
+ count: number;
733
+ }
208
734
  interface ChartFrameProps {
209
735
  title: string;
210
736
  description?: string | undefined;
@@ -228,6 +754,40 @@ interface ChartFrameProps {
228
754
  width: number;
229
755
  height: number;
230
756
  }) => TooltipModel | undefined) | undefined;
757
+ /** Fired when the focused/hovered point is clicked or activated (Enter/Space). */
758
+ onSelect?: ((point: ChartPoint) => void) | undefined;
759
+ /** Hover hit-test strategy: `rect` (default, nearest by x/y) or `voronoi` (precise cell membership). */
760
+ hover?: 'rect' | 'voronoi' | undefined;
761
+ /** When `'canvas'` and `paint` is given, dense marks paint to a `<canvas>` under the SVG chrome. */
762
+ renderer?: 'svg' | 'canvas' | undefined;
763
+ /** Canvas paint callback (marks only) — used when `renderer === 'canvas'`. */
764
+ paint?: CanvasPaint | undefined;
765
+ /** Enable in-plot wheel/drag zoom-pan + keyboard (`+`/`-`/`0`) bound to an index window. */
766
+ zoom?: ZoomConfig | undefined;
767
+ /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
768
+ toolbox?: boolean | ToolboxOptions | undefined;
769
+ /** Extra reset run by the toolbox's Restore (e.g. clearing a visualMap filter). */
770
+ onRestore?: (() => void) | undefined;
771
+ /**
772
+ * Tune the (reduced-motion-gated) enter/update transitions. `false` disables them;
773
+ * an object sets `duration` (ms), `easing`, and the transitioned `properties`. Unset
774
+ * keeps the defaults. Always fully suppressed under `prefers-reduced-motion`.
775
+ */
776
+ transition?: boolean | {
777
+ duration?: number;
778
+ easing?: string;
779
+ properties?: string[];
780
+ } | undefined;
781
+ /** Render custom SVG behind the marks (a watermark, a region) — a lightweight extension seam. */
782
+ onBeforeDraw?: ((ctx: {
783
+ width: number;
784
+ height: number;
785
+ }) => ReactNode) | undefined;
786
+ /** Render custom SVG over the marks (an overlay, an extra series) — a lightweight extension seam. */
787
+ onAfterDraw?: ((ctx: {
788
+ width: number;
789
+ height: number;
790
+ }) => ReactNode) | undefined;
231
791
  }
232
792
  declare function ChartFrame({
233
793
  title,
@@ -240,7 +800,17 @@ declare function ChartFrame({
240
800
  'data-state': dataState,
241
801
  emptyLabel,
242
802
  plain,
243
- tooltip
803
+ tooltip,
804
+ onSelect,
805
+ hover,
806
+ renderer,
807
+ paint,
808
+ zoom,
809
+ toolbox,
810
+ onRestore,
811
+ transition,
812
+ onBeforeDraw,
813
+ onAfterDraw
244
814
  }: ChartFrameProps): import("react").JSX.Element;
245
815
  interface ChartSize {
246
816
  width: number;
@@ -264,6 +834,66 @@ declare const PLAIN_MARGINS: {
264
834
  readonly bottom: 2;
265
835
  readonly left: 2;
266
836
  };
837
+ /**
838
+ * Pure index-window math shared by the DataZoom slider and the in-plot wheel/drag
839
+ * zoom-pan. A "window" is an inclusive `[startIndex, endIndex]` over a series of
840
+ * `count` items; charts slice their data to it so the axes re-tick for free.
841
+ */
842
+ /**
843
+ * Zoom a window toward an anchor expressed as a fraction (0–1) across the current
844
+ * window. `factor < 1` zooms in (narrows), `factor > 1` zooms out (widens). The
845
+ * result is rounded to integer indices and clamped to `[0, count-1]` with a
846
+ * minimum span.
847
+ */
848
+ declare function zoomWindow(win: readonly [number, number], count: number, factor: number, anchorFraction: number): [number, number];
849
+ /**
850
+ * Pan a window by a (possibly fractional) index delta, preserving its width and
851
+ * clamping to `[0, count-1]`.
852
+ */
853
+ declare function panWindow(win: readonly [number, number], count: number, deltaIdx: number): [number, number];
854
+ /** Whether a window is anything other than the full `[0, count-1]` range. */
855
+ declare function isZoomed(win: readonly [number, number], count: number): boolean;
856
+ /**
857
+ * A shared zoom window + hovered-x index for a group of connected charts. Charts
858
+ * passing the same `syncId` mirror each other's zoom and hover through this group.
859
+ * `null` means "unset" (use each chart's full range / no hover).
860
+ */
861
+ interface SyncGroup {
862
+ window: Signal<[number, number] | null>;
863
+ hoverX: Signal<number | null>;
864
+ }
865
+ /**
866
+ * Get (lazily creating) the shared group for an id and increment its ref count.
867
+ * Every `getSyncGroup` must be paired with a `releaseSyncGroup` on teardown.
868
+ */
869
+ declare function getSyncGroup(id: string): SyncGroup;
870
+ /** Decrement an id's ref count; drop the group from the registry when it hits zero. */
871
+ declare function releaseSyncGroup(id: string): void;
872
+ /** Test-only: number of live sync groups. */
873
+ declare function _syncGroupCount(): number;
874
+ /**
875
+ * Chart export helpers — serialize the live `<svg>` to a standalone file (with the
876
+ * chart's resolved paint inlined so it renders without the page's CSS), rasterize it
877
+ * to a PNG at devicePixelRatio, and trigger a download. All guard SSR/jsdom: they
878
+ * no-op (returning null / doing nothing) when the DOM APIs are unavailable.
879
+ */
880
+ /**
881
+ * Serialize an SVG element to a standalone string, inlining each element's resolved
882
+ * `fill`/`stroke`/`stop-color` (so `var(--cascivo-*)` tokens become concrete colours
883
+ * that render outside the page). Literal colours pass straight through.
884
+ */
885
+ declare function serializeSvg(svg: SVGSVGElement): string;
886
+ /**
887
+ * Rasterize a serialized SVG string to a PNG `Blob` at `width × height × dpr`.
888
+ * Resolves `null` when canvas/Image isn't available (SSR) or the image fails to load.
889
+ */
890
+ declare function svgToPngBlob(svgString: string, opts: {
891
+ width: number;
892
+ height: number;
893
+ dpr?: number;
894
+ }): Promise<Blob | null>;
895
+ /** Trigger a browser download of a Blob (or string) under `filename`. No-op in SSR. */
896
+ declare function download(content: Blob | string, filename: string): void;
267
897
  type AnyScale = LinearScale | BandScale | LogScale | TimeScale;
268
898
  interface AxisProps {
269
899
  scale: AnyScale;
@@ -298,6 +928,159 @@ declare function GridLines({
298
928
  tickCount,
299
929
  transform
300
930
  }: GridLinesProps): import("react").JSX.Element;
931
+ type GlyphShape = 'circle' | 'square' | 'diamond' | 'triangle' | 'cross' | 'star';
932
+ /**
933
+ * Centered path `d` for a glyph of the given pixel `size` (full width/height).
934
+ * `circle` returns an empty string — render a `<circle>` for crispness instead.
935
+ */
936
+ declare function glyphPath(shape: GlyphShape, size: number): string;
937
+ interface GlyphProps {
938
+ shape: GlyphShape;
939
+ x: number;
940
+ y: number;
941
+ size: number;
942
+ color: string;
943
+ opacity?: number;
944
+ stroke?: string;
945
+ strokeWidth?: number;
946
+ }
947
+ /** A single point glyph, centered at (x, y). Decorative — the value lives in the a11y tree. */
948
+ declare function Glyph({
949
+ shape,
950
+ x,
951
+ y,
952
+ size,
953
+ color,
954
+ opacity,
955
+ stroke,
956
+ strokeWidth
957
+ }: GlyphProps): ReactNode;
958
+ /** Greedily wrap `text` to lines no wider than `maxWidth` (px) at the given font size. */
959
+ declare function wrapText(text: string, maxWidth: number, fontSize: number): string[];
960
+ interface TextProps {
961
+ x: number;
962
+ y: number;
963
+ children: string;
964
+ /** Max line width in px; when set, the text wraps into `<tspan>` lines. */
965
+ width?: number;
966
+ fontSize?: number;
967
+ anchor?: 'start' | 'middle' | 'end';
968
+ fill?: string;
969
+ lineHeight?: number;
970
+ className?: string;
971
+ }
972
+ /**
973
+ * An SVG text primitive that wraps to a max width (canvas-measured, with a char
974
+ * fallback). The `@visx/text` analogue — used by `Axis` for long category labels
975
+ * and available to custom charts.
976
+ */
977
+ declare function Text({
978
+ x,
979
+ y,
980
+ children,
981
+ width,
982
+ fontSize,
983
+ anchor,
984
+ fill,
985
+ lineHeight,
986
+ className
987
+ }: TextProps): ReactNode;
988
+ interface BrushProps {
989
+ /** Total number of selectable items (data length). */
990
+ count: number;
991
+ /** Track height in px. */
992
+ height?: number;
993
+ /** [startIndex, endIndex] window, inclusive. The brush mutates this signal. */
994
+ window: Signal<[number, number]>;
995
+ /** Accessible label for the range group. */
996
+ label?: string;
997
+ }
998
+ /**
999
+ * A keyboard-operable range selector. Two handles bound to a `[start, end]` window
1000
+ * signal; pointer-drag or Arrow/Home/End move them. Resolution-independent (0–100
1001
+ * viewBox stretched to the container width) so it tracks the chart's responsive size.
1002
+ */
1003
+ declare function Brush({
1004
+ count,
1005
+ height,
1006
+ window: win,
1007
+ label
1008
+ }: BrushProps): import("react").JSX.Element;
1009
+ interface DataZoomProps {
1010
+ /** Total number of selectable items (data length). */
1011
+ count: number;
1012
+ /** Track height in px. */
1013
+ height?: number;
1014
+ /** [startIndex, endIndex] window, inclusive. The control mutates this signal. */
1015
+ window: Signal<[number, number]>;
1016
+ /** Accessible label for the range group. */
1017
+ label?: string;
1018
+ }
1019
+ /**
1020
+ * A dataZoom slider — the v52 Brush plus a draggable **body** that pans the whole
1021
+ * window (drag it, or Arrow it with the body focused) while the two handles resize
1022
+ * it. Bound to a `[start, end]` window signal; resolution-independent (0–100 viewBox).
1023
+ */
1024
+ declare function DataZoom({
1025
+ count,
1026
+ height,
1027
+ window: win,
1028
+ label
1029
+ }: DataZoomProps): import("react").JSX.Element;
1030
+ type VisualChannel = 'color' | 'size' | 'both';
1031
+ type VisualMode = 'continuous' | 'piecewise';
1032
+ interface VisualMapOptions {
1033
+ /** Domain minimum (value mapped to ramp t=0). */
1034
+ min: number;
1035
+ /** Domain maximum (value mapped to ramp t=1). */
1036
+ max: number;
1037
+ /** `continuous` ramp (default) or `piecewise` buckets. */
1038
+ mode?: VisualMode;
1039
+ /** Which visual channel(s) the value drives. Default `color`. */
1040
+ channel?: VisualChannel;
1041
+ /** Ramp family — CVD-safe `sequential` (default) or `diverging`. */
1042
+ ramp?: RampKind;
1043
+ /** Bucket count for `piecewise` (default 5). */
1044
+ pieces?: number;
1045
+ /** [min, max] mark radius in px for the `size` channel (default [3, 14]). */
1046
+ sizeRange?: [number, number];
1047
+ }
1048
+ interface VisualResult {
1049
+ color?: string;
1050
+ size?: number;
1051
+ }
1052
+ /** Piecewise bucket index (0…pieces-1) a value falls into. */
1053
+ declare function pieceIndex(value: number, o: VisualMapOptions): number;
1054
+ /** Resolve a value to its `{ color?, size? }` on the configured channel(s). */
1055
+ declare function mapVisual(value: number, o: VisualMapOptions): VisualResult;
1056
+ /**
1057
+ * Whether a value passes the legend filter — within the continuous `range`, or in a
1058
+ * non-hidden piecewise bucket. Charts dim/hide marks for which this is false.
1059
+ */
1060
+ declare function visualVisible(value: number, o: VisualMapOptions, range: [number, number] | null, hidden: ReadonlySet<number> | null): boolean;
1061
+ interface VisualMapProps {
1062
+ options: VisualMapOptions;
1063
+ /** Continuous filter window in value space (mutated by the thumbs). */
1064
+ range?: Signal<[number, number]>;
1065
+ /** Piecewise hidden bucket indices (toggled by the swatches). */
1066
+ hidden?: Signal<Set<number>>;
1067
+ /** Accessible label for the legend group. */
1068
+ label?: string;
1069
+ /** Value formatter for tick/swatch labels. */
1070
+ format?: (v: number) => string;
1071
+ }
1072
+ /**
1073
+ * The visualMap legend. `continuous` → a CVD-safe gradient bar with two draggable,
1074
+ * keyboard-operable thumbs that filter the visible range. `piecewise` → a row of
1075
+ * clickable swatches that toggle their bucket. Resolution-independent (0–100 viewBox).
1076
+ */
1077
+ declare function VisualMap({
1078
+ options,
1079
+ range,
1080
+ hidden,
1081
+ label,
1082
+ format
1083
+ }: VisualMapProps): import("react").JSX.Element;
301
1084
  interface LegendSeries {
302
1085
  id: string;
303
1086
  label: string;
@@ -305,17 +1088,23 @@ interface LegendSeries {
305
1088
  }
306
1089
  interface LegendProps {
307
1090
  series: readonly LegendSeries[];
308
- hidden: Signal<Set<string>>;
1091
+ hidden: Signal$1<Set<string>>;
309
1092
  }
310
1093
  declare function Legend({
311
1094
  series,
312
1095
  hidden
313
1096
  }: LegendProps): import("react").JSX.Element;
1097
+ interface DecimateOptions {
1098
+ method?: DecimateMethod;
1099
+ threshold?: number;
1100
+ }
314
1101
  interface LineChartSeries<Datum> {
315
1102
  id: string;
316
1103
  label: string;
317
1104
  data: readonly Datum[];
318
1105
  color?: string;
1106
+ /** Which y-axis this series is measured against. Default 'left'. */
1107
+ axis?: 'left' | 'right';
319
1108
  }
320
1109
  interface LineChartProps<Datum = {
321
1110
  x: number;
@@ -326,7 +1115,7 @@ interface LineChartProps<Datum = {
326
1115
  y: (d: Datum) => number;
327
1116
  title: string;
328
1117
  description?: string;
329
- curve?: 'linear' | 'monotone';
1118
+ curve?: Curve;
330
1119
  width?: number;
331
1120
  height?: number;
332
1121
  xTicks?: number;
@@ -337,12 +1126,55 @@ interface LineChartProps<Datum = {
337
1126
  className?: string;
338
1127
  /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
339
1128
  plain?: boolean;
1129
+ /** Reference lines, shaded bands, and markers drawn over the plot (target/threshold annotations). */
1130
+ annotations?: readonly Annotation[];
1131
+ /** Print each point's value as a label above the mark. */
1132
+ labels?: LabelOptions;
1133
+ /** Bridge `null`/non-finite y gaps instead of breaking the line at them (default: break). */
1134
+ connectNulls?: boolean;
1135
+ /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
1136
+ onSelect?: (point: ChartPoint) => void;
1137
+ /** Show a keyboard-operable Brush below the plot to subset (zoom) the series to a window. */
1138
+ brush?: boolean;
1139
+ /** Show a DataZoom slider below the plot — a Brush whose body also pans the window. */
1140
+ dataZoom?: boolean;
1141
+ /** Enable in-plot wheel/drag/keyboard zoom-pan (`+`/`-`/`0`) over the series index window. */
1142
+ zoom?: boolean;
1143
+ /** Connect this chart to others sharing the same id — they mirror zoom window + hovered x. */
1144
+ syncId?: string;
1145
+ /** Tooltip trigger: `item` (default, nearest point) or `axis` (crosshair + all series at the hovered x). */
1146
+ tooltipMode?: 'item' | 'axis';
1147
+ /** Add a right-hand y-axis for series with `axis: 'right'` (e.g. bandwidth vs requests/sec). */
1148
+ secondAxis?: {
1149
+ label?: string;
1150
+ format?: (value: number) => string;
1151
+ };
1152
+ /** Downsample dense series before drawing (LTTB/min-max). The fallback table keeps full data. */
1153
+ decimate?: boolean | DecimateOptions;
1154
+ /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
1155
+ toolbox?: boolean | ToolboxOptions;
1156
+ /** Tune the reduced-motion-gated transitions: `false` disables; an object sets duration/easing/properties. */
1157
+ transition?: boolean | {
1158
+ duration?: number;
1159
+ easing?: string;
1160
+ properties?: string[];
1161
+ };
1162
+ /** Render custom SVG behind the marks (watermark/region) — a lightweight extension seam. */
1163
+ onBeforeDraw?: (ctx: {
1164
+ width: number;
1165
+ height: number;
1166
+ }) => ReactNode;
1167
+ /** Render custom SVG over the marks (overlay/extra series) — a lightweight extension seam. */
1168
+ onAfterDraw?: (ctx: {
1169
+ width: number;
1170
+ height: number;
1171
+ }) => ReactNode;
340
1172
  }
341
1173
  declare function LineChart<Datum = {
342
1174
  x: number;
343
1175
  y: number;
344
1176
  }>({
345
- series,
1177
+ series: rawSeries,
346
1178
  x,
347
1179
  y,
348
1180
  title,
@@ -356,13 +1188,34 @@ declare function LineChart<Datum = {
356
1188
  tooltip,
357
1189
  formatTooltip,
358
1190
  className,
359
- plain
1191
+ plain,
1192
+ annotations,
1193
+ labels,
1194
+ connectNulls,
1195
+ onSelect,
1196
+ brush,
1197
+ dataZoom,
1198
+ zoom,
1199
+ syncId,
1200
+ tooltipMode,
1201
+ secondAxis,
1202
+ decimate,
1203
+ toolbox,
1204
+ transition,
1205
+ onBeforeDraw,
1206
+ onAfterDraw
360
1207
  }: LineChartProps<Datum>): import("react").JSX.Element;
1208
+ interface AreaDecimateOptions {
1209
+ method?: DecimateMethod;
1210
+ threshold?: number;
1211
+ }
361
1212
  interface AreaChartSeries<Datum> {
362
1213
  id: string;
363
1214
  label: string;
364
1215
  data: readonly Datum[];
365
1216
  color?: string;
1217
+ /** Which y-axis this series is measured against (ignored when `stacked`). Default 'left'. */
1218
+ axis?: 'left' | 'right';
366
1219
  }
367
1220
  interface AreaChartProps<Datum = {
368
1221
  x: number;
@@ -374,7 +1227,11 @@ interface AreaChartProps<Datum = {
374
1227
  title: string;
375
1228
  description?: string;
376
1229
  stacked?: boolean;
377
- curve?: 'linear' | 'monotone';
1230
+ curve?: Curve;
1231
+ /** Area fill style: solid (default), a top→bottom gradient, or a pattern. */
1232
+ fill?: FillKind;
1233
+ /** Pattern motif when `fill="pattern"`. */
1234
+ patternKind?: PatternKind;
378
1235
  width?: number;
379
1236
  height?: number;
380
1237
  xTicks?: number;
@@ -384,18 +1241,45 @@ interface AreaChartProps<Datum = {
384
1241
  className?: string;
385
1242
  /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
386
1243
  plain?: boolean;
1244
+ /** Reference lines, shaded bands, and markers drawn over the plot (target/threshold annotations). */
1245
+ annotations?: readonly Annotation[];
1246
+ /** Print each point's value as a label above the top edge. */
1247
+ labels?: LabelOptions;
1248
+ /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
1249
+ onSelect?: (point: ChartPoint) => void;
1250
+ /** Show a keyboard-operable Brush below the plot to subset the series to a window. */
1251
+ brush?: boolean;
1252
+ /** Show a DataZoom slider below the plot — a Brush whose body also pans the window. */
1253
+ dataZoom?: boolean;
1254
+ /** Enable in-plot wheel/drag/keyboard zoom-pan (`+`/`-`/`0`) over the series index window. */
1255
+ zoom?: boolean;
1256
+ /** Connect this chart to others sharing the same id — they mirror zoom window + hovered x. */
1257
+ syncId?: string;
1258
+ /** Tooltip trigger: `item` (default, nearest point) or `axis` (crosshair + all series at the hovered x). */
1259
+ tooltipMode?: 'item' | 'axis';
1260
+ /** Add a right-hand y-axis for series with `axis: 'right'` (non-stacked only). */
1261
+ secondAxis?: {
1262
+ label?: string;
1263
+ format?: (value: number) => string;
1264
+ };
1265
+ /** Downsample dense (non-stacked) series before drawing (LTTB/min-max). The fallback table keeps full data. */
1266
+ decimate?: boolean | AreaDecimateOptions;
1267
+ /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
1268
+ toolbox?: boolean | ToolboxOptions;
387
1269
  }
388
1270
  declare function AreaChart<Datum = {
389
1271
  x: number;
390
1272
  y: number;
391
1273
  }>({
392
- series,
1274
+ series: rawSeries,
393
1275
  x,
394
1276
  y,
395
1277
  title,
396
1278
  description,
397
1279
  stacked,
398
1280
  curve,
1281
+ fill,
1282
+ patternKind,
399
1283
  width: fixedWidth,
400
1284
  height,
401
1285
  xTicks,
@@ -403,7 +1287,18 @@ declare function AreaChart<Datum = {
403
1287
  legend,
404
1288
  tooltip,
405
1289
  className,
406
- plain
1290
+ plain,
1291
+ annotations,
1292
+ labels,
1293
+ onSelect,
1294
+ brush,
1295
+ dataZoom,
1296
+ zoom,
1297
+ syncId,
1298
+ tooltipMode,
1299
+ secondAxis,
1300
+ decimate,
1301
+ toolbox
407
1302
  }: AreaChartProps<Datum>): import("react").JSX.Element;
408
1303
  interface PieChartDatum {
409
1304
  id: string;
@@ -439,6 +1334,10 @@ interface PieChartProps {
439
1334
  className?: string;
440
1335
  /** Render only the marks — no legend. For micro/inline charts. */
441
1336
  plain?: boolean;
1337
+ /** Label each slice. Defaults to its percentage; pass `{ format }` to show the value instead. */
1338
+ labels?: LabelOptions;
1339
+ /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
1340
+ onSelect?: (point: ChartPoint) => void;
442
1341
  }
443
1342
  declare function PieChart({
444
1343
  data,
@@ -457,7 +1356,9 @@ declare function PieChart({
457
1356
  tooltipFormat,
458
1357
  legend,
459
1358
  className,
460
- plain
1359
+ plain,
1360
+ labels,
1361
+ onSelect
461
1362
  }: PieChartProps): import("react").JSX.Element;
462
1363
  interface ScatterDatum {
463
1364
  x: number;
@@ -484,6 +1385,18 @@ interface ScatterChartProps {
484
1385
  className?: string;
485
1386
  /** Render only the marks — no axes, grid lines, or legend. For micro/inline charts. */
486
1387
  plain?: boolean;
1388
+ /** Reference lines, shaded bands, and markers drawn over the plot (target/threshold annotations). */
1389
+ annotations?: readonly Annotation[];
1390
+ /** Fired when a point is clicked or activated (Enter/Space) — for drill-down. */
1391
+ onSelect?: (point: ChartPoint) => void;
1392
+ /** Point glyph shape — a fixed shape, or a function to encode a category by shape. Defaults to a circle. */
1393
+ glyph?: GlyphShape | ((d: ScatterDatum, seriesId: string) => GlyphShape);
1394
+ /** Renderer: `svg` (default), `canvas` (force), or `auto` (canvas past ~2000 points). */
1395
+ renderer?: 'svg' | 'canvas' | 'auto';
1396
+ /** Map each point's y → CVD-safe colour and/or size via a legend that filters the range. */
1397
+ visualMap?: VisualMapOptions;
1398
+ /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
1399
+ toolbox?: boolean | ToolboxOptions;
487
1400
  }
488
1401
  declare function ScatterChart({
489
1402
  series,
@@ -497,7 +1410,13 @@ declare function ScatterChart({
497
1410
  legend,
498
1411
  tooltip,
499
1412
  className,
500
- plain
1413
+ plain,
1414
+ annotations,
1415
+ onSelect,
1416
+ glyph,
1417
+ renderer,
1418
+ visualMap,
1419
+ toolbox
501
1420
  }: ScatterChartProps): import("react").JSX.Element;
502
1421
  interface SparklineProps {
503
1422
  data: readonly number[];
@@ -623,6 +1542,8 @@ interface BubbleChartProps {
623
1542
  className?: string;
624
1543
  /** Render only the marks — no axes or grid lines. For micro/inline charts. */
625
1544
  plain?: boolean;
1545
+ /** Point glyph shape — a fixed shape, or a function to encode a category by shape. Defaults to a circle. */
1546
+ glyph?: GlyphShape | ((d: BubbleDatum, seriesName: string) => GlyphShape);
626
1547
  }
627
1548
  declare function BubbleChart({
628
1549
  series,
@@ -632,7 +1553,8 @@ declare function BubbleChart({
632
1553
  height,
633
1554
  tooltip,
634
1555
  className,
635
- plain
1556
+ plain,
1557
+ glyph
636
1558
  }: BubbleChartProps): import("react").JSX.Element;
637
1559
  interface ComboChartBar {
638
1560
  label: string;
@@ -654,6 +1576,8 @@ interface ComboChartProps {
654
1576
  className?: string;
655
1577
  /** Render only the marks — no axes or grid lines. For micro/inline charts. */
656
1578
  plain?: boolean;
1579
+ /** Reference lines, bands, and markers. `y` maps to the bar value axis. */
1580
+ annotations?: readonly Annotation[];
657
1581
  }
658
1582
  declare function ComboChart({
659
1583
  bars,
@@ -665,7 +1589,8 @@ declare function ComboChart({
665
1589
  height,
666
1590
  tooltip,
667
1591
  className,
668
- plain
1592
+ plain,
1593
+ annotations
669
1594
  }: ComboChartProps): import("react").JSX.Element;
670
1595
  interface HeatmapDatum {
671
1596
  x: string;
@@ -681,6 +1606,10 @@ interface HeatmapProps {
681
1606
  className?: string;
682
1607
  /** Render only the marks — no axes. For micro/inline charts. */
683
1608
  plain?: boolean;
1609
+ /** Map cell value → CVD-safe colour via a continuous/piecewise legend that filters the range. */
1610
+ visualMap?: VisualMapOptions;
1611
+ /** Render a toolbox (PNG/SVG export, data-view toggle, restore). `true` enables all tools. */
1612
+ toolbox?: boolean | ToolboxOptions;
684
1613
  }
685
1614
  declare function Heatmap({
686
1615
  data,
@@ -689,7 +1618,9 @@ declare function Heatmap({
689
1618
  width: fixedWidth,
690
1619
  height,
691
1620
  className,
692
- plain
1621
+ plain,
1622
+ visualMap,
1623
+ toolbox
693
1624
  }: HeatmapProps): import("react").JSX.Element;
694
1625
  interface TreemapDatum {
695
1626
  id: string;
@@ -765,4 +1696,342 @@ declare function Bullet({
765
1696
  height,
766
1697
  className
767
1698
  }: BulletProps): import("react").JSX.Element;
768
- export { AreaChart, AreaChartProps, AreaChartSeries, Axis, AxisProps, BandScale, BarChart, BarChartProps, BarChartSeries, Bin, BoxStats, Boxplot, BoxplotProps, BoxplotSeries, BubbleChart, BubbleChartProps, BubbleDatum, BubbleSeries, Bullet, BulletProps, ChartFrame, ChartFrameProps, ChartSize, ComboChart, ComboChartBar, ComboChartPoint, ComboChartProps, DEFAULT_MARGINS, GridLines, GridLinesProps, Heatmap, HeatmapDatum, HeatmapProps, Histogram, HistogramProps, Kpi, KpiProps, Legend, LegendProps, LegendSeries, LineChart, LineChartProps, LineChartSeries, LinearScale, LogScale, Meter, MeterProps, MeterThresholds, PLAIN_MARGINS, PieChart, PieChartDatum, PieChartProps, Point, Radar, RadarProps, RadarSeries, ScatterChart, ScatterChartProps, ScatterChartSeries, ScatterDatum, Sparkline, SparklineProps, StackedRow, StackedSegment, TimeScale, Treemap, TreemapDatum, TreemapNode, TreemapProps, TreemapRect, arcPath, areaPath, bandScale, binValues, boxStats, extent, linePath, linearScale, logScale, nearestIndex, niceTicks, sqrtScale, squarify, stackSeries, timeScale, toStackedSeries, useChartSize };
1699
+ interface RadialBarDatum {
1700
+ id: string;
1701
+ label: string;
1702
+ value: number;
1703
+ /** CSS color overriding the positional palette for this ring. */
1704
+ color?: string;
1705
+ }
1706
+ interface RadialBarProps {
1707
+ data: readonly RadialBarDatum[];
1708
+ title: string;
1709
+ description?: string;
1710
+ /** Square shorthand: sets width === height. Explicit width/height win. */
1711
+ size?: number;
1712
+ width?: number;
1713
+ height?: number;
1714
+ /** Domain top — the value a full sweep represents. Defaults to the largest datum. */
1715
+ max?: number;
1716
+ /** Sweep angle in degrees (default 270 — a gauge arc). */
1717
+ sweep?: number;
1718
+ /** Center value text rendered in the hole. */
1719
+ centerValue?: string;
1720
+ /** Center label text rendered below the value. */
1721
+ centerLabel?: string;
1722
+ /** Arbitrary content rendered in the hole; takes precedence over centerValue/centerLabel. */
1723
+ centerSlot?: ReactNode;
1724
+ tooltip?: boolean;
1725
+ legend?: boolean;
1726
+ className?: string;
1727
+ /** Render only the marks — no legend. For micro/inline charts. */
1728
+ plain?: boolean;
1729
+ }
1730
+ /**
1731
+ * Concentric radial bars — a circular gauge family. Each datum is a ring whose
1732
+ * filled sweep is proportional to its value over `max`. Reuses the pie arc math.
1733
+ */
1734
+ declare function RadialBar({
1735
+ data,
1736
+ title,
1737
+ description,
1738
+ size,
1739
+ width: fixedWidth,
1740
+ height,
1741
+ max,
1742
+ sweep,
1743
+ centerValue,
1744
+ centerLabel,
1745
+ centerSlot,
1746
+ tooltip,
1747
+ legend,
1748
+ className,
1749
+ plain
1750
+ }: RadialBarProps): import("react").JSX.Element;
1751
+ interface FunnelStage {
1752
+ id: string;
1753
+ label: string;
1754
+ value: number;
1755
+ /** CSS color overriding the positional palette for this stage. */
1756
+ color?: string;
1757
+ }
1758
+ interface FunnelProps {
1759
+ data: readonly FunnelStage[];
1760
+ title: string;
1761
+ description?: string;
1762
+ width?: number;
1763
+ height?: number;
1764
+ /** Show per-stage conversion: value + % of the first stage. */
1765
+ showConversion?: boolean;
1766
+ tooltip?: boolean;
1767
+ className?: string;
1768
+ /** Render only the marks — no labels. For micro/inline charts. */
1769
+ plain?: boolean;
1770
+ }
1771
+ /**
1772
+ * A vertical funnel — each stage is a trapezoid whose top width is its value and
1773
+ * bottom width is the next stage's value, so the silhouette narrows down the
1774
+ * stages. Useful for conversion / drop-off flows.
1775
+ */
1776
+ declare function Funnel({
1777
+ data,
1778
+ title,
1779
+ description,
1780
+ width: fixedWidth,
1781
+ height,
1782
+ showConversion,
1783
+ tooltip,
1784
+ className,
1785
+ plain
1786
+ }: FunnelProps): import("react").JSX.Element;
1787
+ interface StreamSeries {
1788
+ id: string;
1789
+ label: string;
1790
+ /** One value per category, aligned with `categories`. */
1791
+ values: number[];
1792
+ color?: string;
1793
+ }
1794
+ interface StreamProps {
1795
+ series: readonly StreamSeries[];
1796
+ /** X-axis category labels, aligned with each series' `values`. */
1797
+ categories: readonly (string | number)[];
1798
+ title: string;
1799
+ description?: string;
1800
+ /** `silhouette` (centered streamgraph, default) or `zero` (baseline stack). */
1801
+ offset?: StreamOffset;
1802
+ curve?: Curve;
1803
+ width?: number;
1804
+ height?: number;
1805
+ legend?: boolean;
1806
+ tooltip?: boolean;
1807
+ className?: string;
1808
+ plain?: boolean;
1809
+ }
1810
+ /** A streamgraph — stacked areas on a flowing (centered) baseline. */
1811
+ declare function Stream({
1812
+ series,
1813
+ categories,
1814
+ title,
1815
+ description,
1816
+ offset,
1817
+ curve,
1818
+ width: fixedWidth,
1819
+ height,
1820
+ legend,
1821
+ tooltip,
1822
+ className,
1823
+ plain
1824
+ }: StreamProps): import("react").JSX.Element;
1825
+ interface SunburstProps {
1826
+ /** Root of the hierarchy. Leaves carry `value`; parents sum their children. */
1827
+ data: HierNode;
1828
+ title: string;
1829
+ description?: string;
1830
+ size?: number;
1831
+ width?: number;
1832
+ height?: number;
1833
+ tooltip?: boolean;
1834
+ className?: string;
1835
+ plain?: boolean;
1836
+ }
1837
+ /** A sunburst — a radial partition of a tree; each node is an annular segment. */
1838
+ declare function Sunburst({
1839
+ data,
1840
+ title,
1841
+ description,
1842
+ size,
1843
+ width: fixedWidth,
1844
+ height,
1845
+ tooltip,
1846
+ className,
1847
+ plain
1848
+ }: SunburstProps): import("react").JSX.Element;
1849
+ interface SankeyProps {
1850
+ nodes: readonly SankeyNode[];
1851
+ links: readonly SankeyLink[];
1852
+ title: string;
1853
+ description?: string;
1854
+ width?: number;
1855
+ height?: number;
1856
+ tooltip?: boolean;
1857
+ className?: string;
1858
+ plain?: boolean;
1859
+ }
1860
+ /** A Sankey flow diagram — ranked nodes with throughput-sized link ribbons. */
1861
+ declare function Sankey({
1862
+ nodes,
1863
+ links,
1864
+ title,
1865
+ description,
1866
+ width: fixedWidth,
1867
+ height,
1868
+ tooltip,
1869
+ className,
1870
+ plain
1871
+ }: SankeyProps): import("react").JSX.Element;
1872
+ interface CalendarDatum {
1873
+ day: string | Date;
1874
+ value: number;
1875
+ }
1876
+ interface CalendarProps {
1877
+ data: readonly CalendarDatum[];
1878
+ title: string;
1879
+ description?: string;
1880
+ /** Range start/end (ISO string or Date). Defaults to the data's min/max day. */
1881
+ from?: string | Date;
1882
+ to?: string | Date;
1883
+ width?: number;
1884
+ height?: number;
1885
+ tooltip?: boolean;
1886
+ className?: string;
1887
+ plain?: boolean;
1888
+ /** Map day value → CVD-safe colour via a continuous/piecewise legend that filters the range. */
1889
+ visualMap?: VisualMapOptions;
1890
+ }
1891
+ /** A calendar heatmap — a week-column grid of day cells colored by value. */
1892
+ declare function Calendar({
1893
+ data,
1894
+ title,
1895
+ description,
1896
+ from,
1897
+ to,
1898
+ width: fixedWidth,
1899
+ height,
1900
+ tooltip,
1901
+ className,
1902
+ plain,
1903
+ visualMap
1904
+ }: CalendarProps): import("react").JSX.Element;
1905
+ interface CandlestickDatum {
1906
+ /** Period label (date string or index). */
1907
+ t: string;
1908
+ open: number;
1909
+ high: number;
1910
+ low: number;
1911
+ close: number;
1912
+ /** Optional traded volume for the secondary axis. */
1913
+ volume?: number;
1914
+ }
1915
+ interface CandlestickProps {
1916
+ data: readonly CandlestickDatum[];
1917
+ title: string;
1918
+ description?: string;
1919
+ width?: number;
1920
+ height?: number;
1921
+ yTicks?: number;
1922
+ /** Colour for up candles (close ≥ open). */
1923
+ upColor?: string;
1924
+ /** Colour for down candles (close < open). */
1925
+ downColor?: string;
1926
+ /** Render volume bars beneath the candles. */
1927
+ volume?: boolean;
1928
+ tooltip?: boolean;
1929
+ className?: string;
1930
+ plain?: boolean;
1931
+ /** Reference lines, shaded bands, and markers over the plot (e.g. a last-price rule). */
1932
+ annotations?: readonly Annotation[];
1933
+ /** Show a keyboard-operable Brush below the plot to subset (zoom) the candles to a window. */
1934
+ brush?: boolean;
1935
+ /** Show a DataZoom slider below the plot — a Brush whose body also pans the window. */
1936
+ dataZoom?: boolean;
1937
+ /** Enable in-plot wheel/drag/keyboard zoom-pan (`+`/`-`/`0`) over the candle index window. */
1938
+ zoom?: boolean;
1939
+ /** Connect this chart to others sharing the same id — they mirror the zoom window. */
1940
+ syncId?: string;
1941
+ /** Tooltip trigger: `item` (default, nearest candle) or `axis` (crosshair + OHLC at hovered x). */
1942
+ tooltipMode?: 'item' | 'axis';
1943
+ }
1944
+ declare function Candlestick({
1945
+ data: rawData,
1946
+ title,
1947
+ description,
1948
+ width: fixedWidth,
1949
+ height,
1950
+ yTicks,
1951
+ upColor,
1952
+ downColor,
1953
+ volume,
1954
+ tooltip,
1955
+ className,
1956
+ plain,
1957
+ annotations,
1958
+ brush,
1959
+ dataZoom,
1960
+ zoom,
1961
+ syncId,
1962
+ tooltipMode
1963
+ }: CandlestickProps): import("react").JSX.Element;
1964
+ interface PolarDatum {
1965
+ label: string;
1966
+ value: number;
1967
+ color?: string;
1968
+ }
1969
+ interface PolarProps {
1970
+ data: readonly PolarDatum[];
1971
+ title: string;
1972
+ description?: string;
1973
+ /** Plot bars (a rose), or a polar line / filled area. */
1974
+ mode?: 'bar' | 'line' | 'area';
1975
+ width?: number;
1976
+ height?: number;
1977
+ /** Radial ring count. */
1978
+ rings?: number;
1979
+ /** Domain top (full radius). Defaults to the largest value. */
1980
+ max?: number;
1981
+ tooltip?: boolean;
1982
+ className?: string;
1983
+ plain?: boolean;
1984
+ }
1985
+ declare function Polar({
1986
+ data,
1987
+ title,
1988
+ description,
1989
+ mode,
1990
+ width: fixedWidth,
1991
+ height,
1992
+ rings,
1993
+ max,
1994
+ tooltip,
1995
+ className,
1996
+ plain
1997
+ }: PolarProps): import("react").JSX.Element;
1998
+ interface GaugeThreshold {
1999
+ /** Upper bound of this coloured zone (in value units). */
2000
+ upTo: number;
2001
+ color: string;
2002
+ }
2003
+ interface GaugeProps {
2004
+ value: number;
2005
+ min?: number;
2006
+ max?: number;
2007
+ /** Coloured zones from `min` upward; the last should reach `max`. */
2008
+ thresholds?: readonly GaugeThreshold[];
2009
+ /** Unit suffix shown after the centre value. */
2010
+ unit?: string;
2011
+ /** Total sweep in degrees (default 270 — a speedometer arc). */
2012
+ sweep?: number;
2013
+ /** Major tick count (labels at min…max). */
2014
+ ticks?: number;
2015
+ title: string;
2016
+ description?: string;
2017
+ width?: number;
2018
+ height?: number;
2019
+ className?: string;
2020
+ plain?: boolean;
2021
+ }
2022
+ declare function Gauge({
2023
+ value,
2024
+ min,
2025
+ max,
2026
+ thresholds,
2027
+ unit,
2028
+ sweep,
2029
+ ticks,
2030
+ title,
2031
+ description,
2032
+ width: fixedWidth,
2033
+ height,
2034
+ className,
2035
+ plain
2036
+ }: GaugeProps): import("react").JSX.Element;
2037
+ 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, bandScale, bin, binValues, bindStream, boxStats, cellPath, decimate$1 as decimate, divergingRamp, download, encode, encodeCategory, extent, fillFor, filter, getSyncGroup, glyphPath, gradientId, isZoomed, linePath, linearScale, linkPath, logScale, lttb, mapVisual, maxDepth, minmax, nearestIndex, niceTicks, panWindow, partition, patternId, pieceIndex, polarPoint, 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 };