@graphysdk/viz-engine 0.0.1-plugins.5 → 0.0.1-plugins.6

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,24 +1,44 @@
1
1
  import { internal } from 'arquero';
2
2
 
3
+ /**
4
+ * The aesthetic mapping: data columns (or constants) bound to visual channels. Seeded globally by
5
+ * `createSpec({...})` and overridable per layer via `geom.x({ aes })`. Every field is optional; a channel
6
+ * left unset is simply not driven by data. Each channel binds to the like-named scale (e.g. `color` →
7
+ * `scale.color.*`, `size` → `scale.size.*`); position channels additionally require `scale.x()`/`scale.y()`
8
+ * to be declared (they are NOT auto-inferred).
9
+ */
3
10
  export declare interface AesMapping {
11
+ /** Horizontal position. Binds to `scale.x`. Categorical/temporal x needs `scale.x.discrete()`. */
4
12
  x?: AestheticValue;
13
+ /** Vertical position. Binds to `scale.y` (or `scale.ySecondary` when the layer sets `yScaleType: 'secondary'`). */
5
14
  y?: AestheticValue;
15
+ /** Text drawn on the observation (data labels, slice labels). Binds to no scale; rendered as-is. */
6
16
  label?: AestheticValue;
17
+ /** Series/category color. Binds to `scale.color.*`; mapping a column splits the geom into series and shows a legend. */
7
18
  color?: AestheticValue;
19
+ /** Mark size — point radius / bubble area. Binds to `scale.size.continuous({ range })`. */
8
20
  size?: AestheticValue;
21
+ /** Per-observation opacity in `[0,1]` after scaling. Binds to `scale.alpha.*`. */
9
22
  alpha?: AestheticValue;
23
+ /**
24
+ * Explicit grouping key for which observations form one connected mark (one line/area). Defaults to the
25
+ * `color` column when unset; set it to split lines/areas without colouring them differently.
26
+ */
10
27
  group?: AestheticValue;
28
+ /** Stroke thickness as a data-driven channel. Binds to `scale.strokeWidth.*`; for a fixed width use line `params.lineWidth`. */
11
29
  strokeWidth?: AestheticValue;
30
+ /** Dash style (`'solid'`/`'dashed'`/`'dotted'`). Binds to `scale.lineType.discrete({ domain, range })`; great for actual-vs-forecast lines. */
12
31
  lineType?: AestheticValue;
13
32
  }
14
33
 
34
+ /** The set of built-in aesthetic channel names — the keys of {@link AesMapping}. */
15
35
  export declare type AestheticKey = keyof AesMapping;
16
36
 
17
37
  /**
18
- * Aesthetic value can be:
19
- * - string (shorthand for { variable: string })
20
- * - { variable: string } (explicit variable mapping)
21
- * - { value: DataValue } (constant value applied to every observation)
38
+ * How a single aesthetic channel is fed. One of three forms:
39
+ * - a bare string (`'revenue'`) — shorthand for `{ variable: 'revenue' }`, the common case;
40
+ * - `{ variable: 'revenue' }` the same column binding, written explicitly;
41
+ * - `{ value: 2500 }` — a constant {@link ValueMapping} applied to every observation.
22
42
  */
23
43
  declare type AestheticValue = string | VariableMapping | ValueMapping;
24
44
 
@@ -27,22 +47,28 @@ declare function aggregate(options: AggregateOptions): AggregateTransformInput;
27
47
  /***************************************************************
28
48
  * Aggregate Transform
29
49
  ***************************************************************/
50
+ /** A single group-wise reduction applied by `transform.aggregate`. */
30
51
  declare interface AggregateOperation {
31
- /** The aggregation function to apply. */
52
+ /** Reduction to apply: `'count'` | `'sum'` | `'mean'` | `'median'` | `'mode'` | `'min'` | `'max'`. */
32
53
  op: AggregationFunction;
33
- /** The variable to aggregate. */
54
+ /** The variable to reduce within each group. */
34
55
  variableName: VariableName;
35
- /** The name of the output variable. */
56
+ /** Name of the output variable holding the reduced value. */
36
57
  as: VariableName;
37
58
  }
38
59
 
60
+ /**
61
+ * Options for `transform.aggregate` — groups observations by `groupby`, then reduces each group
62
+ * to one observation via `operations`. The idiom for pre-summarizing data (e.g. sum revenue per region).
63
+ */
39
64
  declare interface AggregateOptions {
40
- /** Variables to group by before aggregating. */
65
+ /** Variables to group by; one output observation is produced per distinct combination. */
41
66
  groupby: VariableName[];
42
- /** Aggregation operations to apply per group. */
67
+ /** One or more reductions to compute per group. */
43
68
  operations: AggregateOperation[];
44
69
  }
45
70
 
71
+ /** Group-and-reduce transform produced by `transform.aggregate`. */
46
72
  declare interface AggregateTransformInput {
47
73
  type: 'transform';
48
74
  transformType: 'aggregate';
@@ -82,11 +108,63 @@ declare interface AnchorSegment {
82
108
  direction: 'positive' | 'negative';
83
109
  }
84
110
 
111
+ /**
112
+ * The angular span of an arc/wedge in a polar coord, in **radians** (0 = straight up, increasing
113
+ * clockwise — the d3-arc convention). Either endpoint is `null` when the observation declares no x
114
+ * interval. Returned by {@link getAngleExtent}.
115
+ */
85
116
  export declare interface AngleExtent {
86
117
  startAngle: NumericDataValue;
87
118
  endAngle: NumericDataValue;
88
119
  }
89
120
 
121
+ /**
122
+ * Builder for the built-in annotation kinds — the pipeable counterpart to setting the `annotations`
123
+ * field by hand. Each method returns an {@link AnnotationItem}; piped into `createSpec`/`pipe` it appends
124
+ * to the matching {@link AnnotationsInput} field, so annotations compose left-to-right like every other
125
+ * spec feature (geoms, scales, highlights). Multiple calls of the same kind accumulate.
126
+ *
127
+ * Anchoring differs per kind: only {@link annotation.differenceArrow} snaps to DATA (two observations);
128
+ * `shape`, `text`, and `freeformArrow` position in panel fractions (`[0,1]`, top-left origin). `sticker`,
129
+ * `pinnedNumber`, and `comment` compile but have NO painter in `@graphysdk/react-renderer` (editor-only) —
130
+ * avoid them when authoring for the React renderer. For a data-anchored callout/band beyond a difference
131
+ * arrow, register a custom kind via `createGraphyBuilder({ annotations })`; its `annotation` builder adds
132
+ * one method per registered kind alongside these built-ins.
133
+ *
134
+ * @example
135
+ * import { pipe, createSpec, geom, scale, annotation } from '@graphysdk/viz-engine';
136
+ *
137
+ * pipe(
138
+ * createSpec({ x: 'month', y: 'revenue', color: 'region' }),
139
+ * geom.line(),
140
+ * scale.x.discrete(),
141
+ * scale.y(),
142
+ * scale.color.palette(),
143
+ * annotation.differenceArrow({
144
+ * start: { anchorValue: 'Jan', groupValue: 'North' },
145
+ * end: { anchorValue: 'Jun', groupValue: 'North' },
146
+ * label: 'relative-difference',
147
+ * }),
148
+ * annotation.shape({ x: 0, y: 0.7, width: 1, height: 0.3, fillColor: '#e15759', fillOpacity: 0.12 }),
149
+ * );
150
+ */
151
+ export declare const annotation: {
152
+ /** A labelled delta between two data observations — the only built-in kind that snaps to data. */
153
+ differenceArrow(input: DifferenceArrowInput): AnnotationItem;
154
+ /** A shaded box positioned in panel fractions (`[0,1]`); does not snap to a data value. */
155
+ shape(input: ShapeInput): AnnotationItem;
156
+ /** A free-standing arrow with endpoints in panel fractions (`[0,1]`); does not snap to a data value. */
157
+ freeformArrow(input: FreeformArrowInput): AnnotationItem;
158
+ /** A free-standing rich-text label positioned in panel fractions (`[0,1]`); does not snap to a data value. */
159
+ text(input: TextAnnotationInput): AnnotationItem;
160
+ /** Editor-only: compiles but has NO painter in `@graphysdk/react-renderer`. */
161
+ sticker(input: StickerAnnotationInput): AnnotationItem;
162
+ /** Editor-only: compiles but has NO painter in `@graphysdk/react-renderer`. */
163
+ pinnedNumber(input: PinnedNumberAnnotationInput): AnnotationItem;
164
+ /** Editor-only: compiles but has NO painter in `@graphysdk/react-renderer`. */
165
+ comment(input: CommentAnnotationInput): AnnotationItem;
166
+ };
167
+
90
168
  /**
91
169
  * The compile-half definition of a custom annotation kind (ADR-035).
92
170
  *
@@ -95,9 +173,11 @@ export declare interface AngleExtent {
95
173
  * params })` from `TParams`, merge `defaultParams`, and enforce the optional coordinate arity. The
96
174
  * render-half `draw` lives in the renderer and binds to this definition by import (`defineAnnotationRenderer`).
97
175
  */
98
- /** Optional coordinate-count guardrail enforced by the builder; unbounded when omitted. */
176
+ /** Allowed coordinate count for an annotation kind; each bound is inclusive, unbounded when omitted. */
99
177
  export declare interface AnnotationArity {
178
+ /** Minimum coordinates required. */
100
179
  min?: number;
180
+ /** Maximum coordinates allowed. */
101
181
  max?: number;
102
182
  }
103
183
 
@@ -142,18 +222,59 @@ declare interface AnnotationDataPoint {
142
222
  rowValue?: DataValue;
143
223
  }
144
224
 
225
+ /**
226
+ * The compile-half definition produced by {@link defineAnnotation}. Pass an array of these to
227
+ * `createGraphyBuilder({ annotations })` to get a typed `annotation.<type>(...)` spec method; the
228
+ * render-half `draw` binds to it by import in `@graphysdk/react-renderer`.
229
+ */
145
230
  export declare interface AnnotationDef<TParams extends object = object, TType extends string = string> {
231
+ /** The registered kind name; keys the `annotation.<type>(...)` builder method and the render-side `draw`. */
146
232
  type: TType;
147
233
  /** Carrier that lets the builder recover `TParams` and merge defaults before a param reaches `draw`. */
148
234
  defaultParams: TParams;
235
+ /** Coordinate-count guardrail enforced by the builder; unbounded when omitted. */
149
236
  coordinates?: AnnotationArity;
150
237
  }
151
238
 
152
- /** Pipeable spec item produced by the registration-typed `annotation.<kind>(...)` builder. */
153
- declare interface AnnotationItem {
239
+ /**
240
+ * Pipeable spec item produced by an `annotation.*` builder. `kind` routes the carried input to the
241
+ * matching {@link AnnotationsInput} field when the item is folded onto a spec by `createSpec`/`pipe`:
242
+ * each built-in kind targets its like-named field, and `'custom'` carries a registered
243
+ * {@link CustomAnnotationInput} onto `annotations.custom`.
244
+ */
245
+ export declare type AnnotationItem = {
246
+ type: 'annotation';
247
+ kind: 'differenceArrow';
248
+ annotation: DifferenceArrowInput;
249
+ } | {
250
+ type: 'annotation';
251
+ kind: 'shape';
252
+ annotation: ShapeInput;
253
+ } | {
254
+ type: 'annotation';
255
+ kind: 'freeformArrow';
256
+ annotation: FreeformArrowInput;
257
+ } | {
258
+ type: 'annotation';
259
+ kind: 'text';
260
+ annotation: TextAnnotationInput;
261
+ } | {
262
+ type: 'annotation';
263
+ kind: 'sticker';
264
+ annotation: StickerAnnotationInput;
265
+ } | {
266
+ type: 'annotation';
267
+ kind: 'pinnedNumber';
268
+ annotation: PinnedNumberAnnotationInput;
269
+ } | {
154
270
  type: 'annotation';
271
+ kind: 'comment';
272
+ annotation: CommentAnnotationInput;
273
+ } | {
274
+ type: 'annotation';
275
+ kind: 'custom';
155
276
  annotation: CustomAnnotationInput;
156
- }
277
+ };
157
278
 
158
279
  /** Recovers an annotation definition's params type — carried structurally by its `defaultParams`. */
159
280
  declare type AnnotationParamsOf<Definition> = Definition extends AnnotationDef<infer TParams> ? TParams : never;
@@ -182,17 +303,38 @@ declare interface AnnotationsCompilerInput {
182
303
  scales: CompiledScales;
183
304
  }
184
305
 
306
+ /**
307
+ * Non-data marks layered onto the panel, set as the `annotations` field on a spec. Each field holds a
308
+ * different built-in kind.
309
+ *
310
+ * Anchoring differs per field and is the deciding detail: only `differenceArrows` snap to DATA (two
311
+ * observations). `shapes`, `textAnnotations` and `freeformArrows` position in panel fractions (`[0,1]`,
312
+ * top-left origin) — they re-flow on resize but do NOT snap to a data value. For a data-anchored callout,
313
+ * band, or marker beyond a difference arrow, author a `custom` annotation.
314
+ *
315
+ * `stickers`, `pinnedNumbers` and `comments` COMPILE but have no painter in `@graphysdk/react-renderer`
316
+ * (they draw only in the editor's legacy engine) — don't use them when authoring for the React renderer.
317
+ */
185
318
  export declare interface AnnotationsInput {
319
+ /** Labelled deltas between two data observations. The only built-in kind that anchors to data. */
186
320
  differenceArrows?: DifferenceArrowInput[];
321
+ /** Shaded boxes positioned in panel fractions (`[0,1]`), not data values. */
187
322
  shapes?: ShapeInput[];
323
+ /** Free-standing arrows positioned in panel fractions (`[0,1]`), not data values. */
188
324
  freeformArrows?: FreeformArrowInput[];
325
+ /** Free-standing rich-text labels positioned in panel fractions (`[0,1]`), not data values. */
189
326
  textAnnotations?: TextAnnotationInput[];
327
+ /** Compiles but has NO painter in `@graphysdk/react-renderer` (editor-only). Avoid here. */
190
328
  stickers?: StickerAnnotationInput[];
329
+ /** Compiles but has NO painter in `@graphysdk/react-renderer` (editor-only). Avoid here. */
191
330
  pinnedNumbers?: PinnedNumberAnnotationInput[];
331
+ /** Compiles but has NO painter in `@graphysdk/react-renderer` (editor-only). Avoid here. */
192
332
  comments?: CommentAnnotationInput[];
333
+ /** Registered custom-annotation instances; the data-anchorable escape hatch when no built-in fits. */
193
334
  custom?: CustomAnnotationInput[];
194
335
  }
195
336
 
337
+ /** Resolved form of {@link AnnotationsInput} — every field present, each entry defaulted. */
196
338
  export declare interface AnnotationsSpec {
197
339
  differenceArrows: DifferenceArrowSpec[];
198
340
  shapes: ShapeSpec[];
@@ -271,6 +413,13 @@ export declare interface AppearanceSpec {
271
413
  highlightStyle: HighlightStyle;
272
414
  }
273
415
 
416
+ /**
417
+ * Area marks — a line with the region below it filled. Same render knobs as line ({@link AreaGeomParams}).
418
+ * Use `position: 'stack'` for a stacked area chart or `'fill'` for a 100%-stacked one.
419
+ *
420
+ * @example
421
+ * pipe(createSpec({ x: 'month', y: 'sales', color: 'region' }), geom.area({ position: 'stack' }), scale.x(), scale.y(), scale.color.palette());
422
+ */
274
423
  declare function area(options?: GeomOptions<'area'>): LayerInputOf<'area'>;
275
424
 
276
425
  /**
@@ -291,21 +440,37 @@ declare class AreaGeom extends Geom {
291
440
  }
292
441
 
293
442
  /**
294
- * Area-specific parameters (same rendering knobs as line, but fills under the curve)
443
+ * Render parameters for `geom.area` — same knobs as {@link LineGeomParams}, but the region below the curve
444
+ * is filled. Passed under `params`.
295
445
  */
296
446
  export declare interface AreaGeomParams {
447
+ /**
448
+ * Outline stroke width in pixels, or `'auto'` to let the theme pick a width.
449
+ * @default 'auto'
450
+ */
297
451
  lineWidth: number | 'auto';
452
+ /**
453
+ * Interpolation method between points: `'linear'` for straight segments, `'catmull-rom'` for a smooth spline.
454
+ * @default 'linear'
455
+ */
298
456
  interpolate: InterpolateType;
457
+ /**
458
+ * How to handle missing (`null`) y-values: `'zero'` drops to zero, `'gap'` breaks the area, `'connect'`
459
+ * bridges across the gap.
460
+ * @default 'zero'
461
+ */
299
462
  missingValues: MissingValuesType;
300
463
  }
301
464
 
465
+ /** An arrow endpoint as a panel fraction (`[0,1]`, top-left origin). */
302
466
  export declare interface ArrowEndpoint {
303
- /** 0..1 of plot width. */
467
+ /** `[0,1]` of panel width (0 = left). */
304
468
  x: number;
305
- /** 0..1 of plot height. */
469
+ /** `[0,1]` of panel height (0 = top). */
306
470
  y: number;
307
471
  }
308
472
 
473
+ /** Arrowhead at an endpoint: `'none'` (bare line) or `'line-arrow'` (drawn head). */
309
474
  export declare type ArrowheadStyle = 'none' | 'line-arrow';
310
475
 
311
476
  export declare type ArrowLineStyle = 'solid' | 'dashed';
@@ -446,6 +611,14 @@ export declare type BackgroundSpec = {
446
611
  color?: string;
447
612
  };
448
613
 
614
+ /**
615
+ * Bar/column marks. Drives most categorical charts: plain, stacked (`position: 'stack'`), grouped
616
+ * (`'dodge'`), 100%-stacked (`'fill'`), horizontal (add `coord.flip()`), and pie/donut (`position: 'fill'`
617
+ * inside `coord.polar({ theta: 'y' })`). No render `params`.
618
+ *
619
+ * @example
620
+ * pipe(createSpec({ x: 'quarter', y: 'sales', color: 'region' }), geom.bar({ position: 'stack' }), scale.x(), scale.y(), scale.color.palette());
621
+ */
449
622
  declare function bar(options?: GeomOptions<'bar'>): LayerInputOf<'bar'>;
450
623
 
451
624
  /**
@@ -496,27 +669,68 @@ declare interface BarOptions {
496
669
  }
497
670
 
498
671
  /**
499
- * Base params shared by all coordinate systems
672
+ * Params shared by every coordinate system. Axis limits clamp the displayed range
673
+ * after scaling.
500
674
  */
501
675
  declare interface BaseCoordParams {
502
676
  /**
503
- * Limits for x-axis [min, max]
677
+ * Fixed x-axis range as `[min, max]` in data units, or `null` to auto-fit from data.
678
+ * @default null
504
679
  */
505
680
  xLimits: [number, number] | null;
506
681
  /**
507
- * Limits for y-axis [min, max]
682
+ * Fixed y-axis range as `[min, max]` in data units, or `null` to auto-fit from data.
683
+ * @default null
508
684
  */
509
685
  yLimits: [number, number] | null;
510
686
  }
511
687
 
688
+ /**
689
+ * Options accepted by every `geom.*` builder. All fields are optional; each builder fills defaults during
690
+ * resolution. The generic `T` is the per-geom `params` shape so `geom.line` accepts {@link LineGeomParams}
691
+ * while `geom.bar` accepts none.
692
+ */
512
693
  declare interface BaseGeomOptions<T extends GeomParams> {
694
+ /**
695
+ * Layer-level aesthetic overrides, shallow-merged OVER the spec-level mapping for this layer only.
696
+ * The place to retarget a channel per layer in a combo (`geom.line({ aes: { y: 'margin' } })`) or to pin a
697
+ * constant (`aes: { y: { value: 2500 } }` for a reference line).
698
+ */
513
699
  aes?: AesMapping;
700
+ /**
701
+ * Statistical transform applied to this layer's data before positioning. `'identity'` (default) plots rows
702
+ * as-is; `'count'` tallies observations per x; `stat.mean()` collapses to a single mean-of-`y` observation
703
+ * (average line); `stat.smooth({ method })` fits a regression curve (trendline).
704
+ * @default 'identity'
705
+ */
514
706
  stat?: StatName | StatInput;
707
+ /**
708
+ * How sibling marks sharing an x position are arranged. `'identity'` overlaps them; `'stack'` stacks by
709
+ * `color`; `'dodge'` places them side by side; `'fill'` stacks then normalises each column to 100% (also
710
+ * the basis of pie/donut under `coord.polar`). Default is per-geom: `area` → `'stack'`, `bar` → `'dodge'`,
711
+ * `point`/`line`/`rule` → `'identity'`.
712
+ */
515
713
  position?: PositionType;
714
+ /**
715
+ * Which Y axis this layer binds to. `'secondary'` puts it on the right-hand axis for dual-axis combos
716
+ * (pair with `scale.ySecondary()`); the layer still maps to the `y` channel.
717
+ * @default 'primary'
718
+ */
516
719
  yScaleType?: YScaleType;
720
+ /** Geom-specific render knobs — static styling only (widths, colors, interpolation), never data channels. */
517
721
  params?: Partial<T>;
722
+ /**
723
+ * Ordered transforms applied to this layer's view of the data, on top of the spec-level transforms. Use
724
+ * when this geom needs a different data shape than its siblings.
725
+ */
518
726
  transforms?: TransformInput[];
727
+ /**
728
+ * When `false`, the layer is excluded from hover hit-detection — set it on non-data overlays like
729
+ * average and trend lines so they don't steal the tooltip. Defaults to `true` for all geoms except `rule`,
730
+ * which defaults to `false`.
731
+ */
519
732
  interactive?: boolean;
733
+ /** Per-observation value labels drawn on the marks. Off by default; see {@link DataLabelsInput}. */
520
734
  dataLabels?: DataLabelsInput;
521
735
  }
522
736
 
@@ -989,6 +1203,9 @@ export declare interface CommandStackSnapshot {
989
1203
  * Comment annotation: a marker dot pinned to a single observation, carrying
990
1204
  * rich-text content. The renderer's mini view shows a truncated comment; hover
991
1205
  * reveals the full text.
1206
+ *
1207
+ * NO PAINTER in `@graphysdk/react-renderer` — this compiles but never draws there (it renders only in
1208
+ * the editor's legacy engine). Don't reach for it when authoring for the React renderer.
992
1209
  */
993
1210
  declare interface CommentAnnotationInput {
994
1211
  id?: string;
@@ -996,6 +1213,7 @@ declare interface CommentAnnotationInput {
996
1213
  content: RichTextContent;
997
1214
  }
998
1215
 
1216
+ /** Resolved form of {@link CommentAnnotationInput} — defaults applied, anchor normalised. */
999
1217
  declare interface CommentAnnotationSpec {
1000
1218
  id: string;
1001
1219
  anchor: ObservationAnchor;
@@ -1114,10 +1332,25 @@ export declare interface CompiledFreeformArrow {
1114
1332
  hasStickerStyle: boolean;
1115
1333
  }
1116
1334
 
1335
+ /**
1336
+ * What {@link Geom.compile} returns — the reparameterised data plus any mapping the geom injects.
1337
+ * Everything here must be JSON-serialisable (it rides in the compiled spec): emit data columns and
1338
+ * plain mapping values only — no closures, no class instances.
1339
+ */
1117
1340
  export declare interface CompiledGeom {
1118
- /** The reparameterized dataset (may have new computed variables) */
1341
+ /**
1342
+ * The reparameterised dataset: the input dataset with the position columns the mark owns added. Write
1343
+ * each through `variableFor(axis, role | name)` — never a literal column string like `'yMin'` — so the
1344
+ * value readers and the coord projection find them. A geom writes only the columns it owns; the mapper
1345
+ * scales any `scalar` channel that declares an `aes` source in place from the author's mapping.
1346
+ */
1119
1347
  data: Dataset;
1120
- /** Any mapping overrides produced by the geom */
1348
+ /**
1349
+ * Mapping overrides the geom injects, merged over the layer's mapping. The common case is attaching a
1350
+ * scale a mark needs but the author never mapped — e.g. injecting `{ y: { variable } }` so a price
1351
+ * scale forms for an OHLC mark whose extent comes from a y-interval. Return `{}` to inject nothing;
1352
+ * never echo the author's own aesthetics back here.
1353
+ */
1121
1354
  mapping: AesMapping;
1122
1355
  /**
1123
1356
  * Extra single-observation tooltip rows this geom contributes (e.g. OHLC). The compiler derives
@@ -1555,7 +1788,37 @@ declare interface ComputeFreeformArrowParams {
1555
1788
  }
1556
1789
 
1557
1790
  /**
1558
- * Create a custom configuration
1791
+ * Pipeable spec item carrying chart-level configuration. Every group is
1792
+ * optional; only the keys you set override the resolved defaults. Accepts:
1793
+ *
1794
+ * - `content`: titles and attribution — `title` / `subtitle` / `caption`
1795
+ * (each a {@link TextContent}) plus `source` ({@link SourceContent}), each
1796
+ * paired with an `isXVisible` toggle.
1797
+ * - `legend`: `{ position }` — see {@link LegendPosition}.
1798
+ * - `axes`: per-axis `{ x, y, ySecondary }` overrides, e.g. `{ label }`.
1799
+ * - `numberFormat`: chart-wide number formatting — see {@link NumberFormatConfig}.
1800
+ * - `headline`: big-number summary figure — `show` / `compareWith` / `size` /
1801
+ * `position` (see {@link HeadlineShow}, highlights-headlines.md).
1802
+ * - `appearance`: render-only styling — `textScale`, `highlightStyle`,
1803
+ * `background`, `border`, `cornerRadius` (see {@link AppearanceSpec}).
1804
+ *
1805
+ * @example
1806
+ * import { pipe, createSpec, geom, scale, config } from '@graphysdk/viz-engine';
1807
+ *
1808
+ * pipe(
1809
+ * createSpec({ x: 'quarter', y: 'revenue', color: 'region' }),
1810
+ * geom.bar({ position: 'stack' }),
1811
+ * scale.x(),
1812
+ * scale.y(),
1813
+ * config({
1814
+ * content: { title: 'Quarterly revenue by region', source: { label: 'Finance', url: 'https://…' } },
1815
+ * legend: { position: 'top' },
1816
+ * axes: { y: { label: 'Revenue ($)' } },
1817
+ * numberFormat: { decimals: 0, abbreviation: 'auto', prefix: '$' },
1818
+ * headline: { show: 'total' },
1819
+ * appearance: { highlightStyle: 'dim' },
1820
+ * })
1821
+ * );
1559
1822
  */
1560
1823
  export declare function config(options: ConfigInput): ConfigItem;
1561
1824
 
@@ -1572,6 +1835,10 @@ declare interface ConfigCompilerInput {
1572
1835
  scales: CompiledScales;
1573
1836
  }
1574
1837
 
1838
+ /**
1839
+ * Author-facing argument to `config(...)`: a deep-partial of {@link ConfigSpec}.
1840
+ * Any omitted group or field falls back to its resolved default.
1841
+ */
1575
1842
  declare type ConfigInput = Omit<DeepPartial<ConfigSpec>, 'legend' | 'content'> & {
1576
1843
  legend?: LegendConfigInput;
1577
1844
  content?: ContentInput;
@@ -1586,8 +1853,9 @@ declare interface ConfigItem {
1586
1853
  }
1587
1854
 
1588
1855
  /**
1589
- * Feature configuration with resolved defaults.
1590
- * All fields are required and always populated after resolution.
1856
+ * Fully-resolved chart configuration: every group present with defaults
1857
+ * applied. This is the shape carried on a compiled spec; authors pass the
1858
+ * partial {@link ConfigInput} to `config(...)` instead.
1591
1859
  */
1592
1860
  export declare interface ConfigSpec {
1593
1861
  parsingLocale: Locale;
@@ -1624,15 +1892,20 @@ declare interface ConstantMappingCompilerOutput {
1624
1892
  /***************************************************************
1625
1893
  * Constant Transform
1626
1894
  ***************************************************************/
1895
+ /**
1896
+ * Options for `transform.constant` — adds a new variable with the same value on every observation.
1897
+ * Useful to synthesize a constant axis or a single-category grouping variable.
1898
+ */
1627
1899
  declare interface ConstantOptions {
1628
- /** The name of the new variable. */
1900
+ /** Name of the new variable to add. */
1629
1901
  variableName: VariableName;
1630
- /** The type of the new variable. */
1902
+ /** Data type of the new variable. */
1631
1903
  type: DataType;
1632
- /** The constant value to assign to every observation. */
1904
+ /** The constant value assigned to every observation. */
1633
1905
  value: DataValue;
1634
1906
  }
1635
1907
 
1908
+ /** Add-a-constant-column transform produced by `transform.constant`. */
1636
1909
  declare interface ConstantTransformInput {
1637
1910
  type: 'transform';
1638
1911
  transformType: 'constant';
@@ -1662,17 +1935,29 @@ declare interface Content {
1662
1935
  * hide cycles without losing the text the user typed.
1663
1936
  */
1664
1937
  export declare interface ContentConfig {
1938
+ /** Main chart title. `null` = unset. */
1665
1939
  title: TextContent | null;
1940
+ /** @default true */
1666
1941
  isTitleVisible: boolean;
1942
+ /** Secondary line shown under the title. `null` = unset. */
1667
1943
  subtitle: TextContent | null;
1944
+ /** @default true */
1668
1945
  isSubtitleVisible: boolean;
1946
+ /** Explanatory note shown below the plot. `null` = unset. */
1669
1947
  caption: TextContent | null;
1948
+ /** @default false */
1670
1949
  isCaptionVisible: boolean;
1950
+ /** Data-source attribution shown under the caption. `null` = unset. */
1671
1951
  source: SourceContent | null;
1952
+ /** @default false */
1672
1953
  isSourceVisible: boolean;
1673
1954
  }
1674
1955
 
1675
- /** Content input — all fields optional. */
1956
+ /**
1957
+ * Author-facing `content` argument to `config(...)`: all fields optional.
1958
+ * Setting a text slot does not show it unless the matching `isXVisible` flag is
1959
+ * also true (title and subtitle default visible; caption and source default hidden).
1960
+ */
1676
1961
  declare type ContentInput = Partial<ContentConfig>;
1677
1962
 
1678
1963
  declare type ContinuousScaleInput = {
@@ -1758,27 +2043,60 @@ declare type ContinuousScaleSpec = Required<ContinuousScaleInput>;
1758
2043
  */
1759
2044
  export declare function convertSpecToInput(spec: Spec): SpecInput;
1760
2045
 
2046
+ /**
2047
+ * Coordinate-system builder. A coord is a geom-agnostic projection applied AFTER scaling
2048
+ * that remaps the already-scaled `[0,1]` positions of any geom; it changes neither the data,
2049
+ * the scales, nor the chart's tier. Pipe at most one onto a spec — cartesian is assumed when
2050
+ * none is given.
2051
+ *
2052
+ * - `cartesian` — standard x→horizontal, y→vertical (the default).
2053
+ * - `flip` — swaps the x and y axes; the idiom for horizontal bars and long category labels.
2054
+ * - `polar` — wraps x/y around a centre; `theta` selects the angle aesthetic and the other
2055
+ * becomes the radius. The basis for pie, donut, and radar charts.
2056
+ *
2057
+ * @example
2058
+ * import { pipe, createSpec, geom, scale, coord } from '@graphysdk/viz-engine';
2059
+ *
2060
+ * // Donut: stacked value → angle, innerRadius > 0 carves the hole
2061
+ * pipe(
2062
+ * createSpec({ x: '', y: 'spend', color: 'department' }),
2063
+ * geom.bar({ position: 'fill' }),
2064
+ * coord.polar({ theta: 'y', innerRadius: 0.55 }),
2065
+ * scale.x(),
2066
+ * scale.y(),
2067
+ * scale.color.palette()
2068
+ * );
2069
+ */
1761
2070
  export declare const coord: {
1762
2071
  /**
1763
- * Standard cartesian (x-y) coordinate system. This is the default if no coord is specified.
2072
+ * Standard cartesian (x→horizontal, y→vertical) coordinate system. This is the default
2073
+ * when no coord is piped onto the spec; declare it explicitly only to set axis limits.
1764
2074
  *
1765
2075
  * @example coord.cartesian() // auto-scaled axes
1766
- * @example coord.cartesian({ yLimits: [0, 100] }) // fixed y-axis
2076
+ * @example coord.cartesian({ yLimits: [0, 100] }) // fixed y-axis range
1767
2077
  */
1768
2078
  cartesian: (params?: Partial<CartesianCoordParams>) => CartesianCoordInput;
1769
2079
  /**
1770
- * Flipped cartesian coordinates — swaps x and y axes.
1771
- * Useful for horizontal bar charts or when category labels are long.
2080
+ * Flipped cartesian coordinates — swaps the x and y axes so the x aesthetic runs
2081
+ * vertically and y runs horizontally. The idiom for horizontal bar charts and for
2082
+ * long category labels. The mapping stays the same; only the on-screen orientation flips.
1772
2083
  *
1773
- * @example coord.flip() // horizontal bars
2084
+ * @example coord.flip() // horizontal bars from a vertical-bar spec
1774
2085
  */
1775
2086
  flip: (params?: Partial<FlipCoordParams>) => FlipCoordInput;
1776
2087
  /**
1777
- * Polar coordinate system — maps data to angle (theta) and radius.
1778
- * Used for pie charts, donut charts, and radar/radial visualizations.
2088
+ * Polar coordinate system — wraps the scaled positions around a centre, mapping one
2089
+ * aesthetic to the angle (theta) and the other to the radius (scaled into
2090
+ * `[innerRadius, 1]`). `theta` defaults to `'x'`.
2091
+ *
2092
+ * - Pie / donut: `geom.bar({ position: 'fill' })` with `theta: 'y'` (stacked value → angle);
2093
+ * set `innerRadius > 0` for a donut.
2094
+ * - Radar / spider: `geom.line` or `geom.point` with `theta: 'x'` over a discrete x axis
2095
+ * (one evenly-spaced spoke per category).
1779
2096
  *
1780
- * @example coord.polar() // pie chart
1781
- * @example coord.polar({ innerRadius: 0.5 }) // donut chart
2097
+ * @example coord.polar({ theta: 'y' }) // pie: stacked value → angle
2098
+ * @example coord.polar({ theta: 'y', innerRadius: 0.5, startAngle: 90 }) // donut rotated 90°
2099
+ * @example coord.polar({ theta: 'x' }) // radar: category → spoke angle
1782
2100
  */
1783
2101
  polar: (params?: Partial<PolarCoordParams>) => PolarCoordInput;
1784
2102
  };
@@ -1797,7 +2115,10 @@ declare class CoordCompiler {
1797
2115
  }
1798
2116
 
1799
2117
  /**
1800
- * Discriminated union of all coordinate input specs (user-provided, optional params).
2118
+ * A coordinate system produced by the `coord` builder, before resolution.
2119
+ * A coord is a geom-agnostic projection applied AFTER scaling: it remaps the already-scaled
2120
+ * `[0,1]` positions of any geom without touching the data, the scales, or the chart's tier.
2121
+ * One coord per spec; defaults to cartesian when none is piped on.
1801
2122
  */
1802
2123
  declare type CoordInput = CartesianCoordInput | FlipCoordInput | PolarCoordInput;
1803
2124
 
@@ -1821,7 +2142,7 @@ declare type CoordSetupResult = {
1821
2142
  };
1822
2143
 
1823
2144
  /**
1824
- * Discriminated union of all resolved coordinate specs (params fully defaulted).
2145
+ * A fully resolved coordinate system (params defaulted) as it appears on the compiled spec.
1825
2146
  */
1826
2147
  declare type CoordSpec = CartesianCoordSpec | FlipCoordSpec | PolarCoordSpec;
1827
2148
 
@@ -1896,19 +2217,19 @@ export declare function createEmptyHighlight(strategy: HighlightStrategy | null)
1896
2217
 
1897
2218
  /**
1898
2219
  * Builds a Graphy authoring surface for a set of custom geoms and/or annotations: a `geom` builder that
1899
- * merges the built-in methods with one method per registered custom geom, an `annotation` builder with
1900
- * one method per registered annotation kind, plus the standard `createSpec`. The 90% case stays the
1901
- * plain `import { geom, createSpec }`; reach for this only when authoring custom geoms (decision 8) or
1902
- * custom annotations (ADR-035). Registration is per-instance — geoms are injected to
1903
- * `createCompiler({ geoms })`; annotations need no compile-side registry (coordinate resolution is
1904
- * generic), only the render plugin via `<GraphProvider annotationPlugins={[...]}>`.
2220
+ * merges the built-in methods with one method per registered custom geom, an `annotation` builder that
2221
+ * merges the built-in kinds with one method per registered annotation kind, plus the standard
2222
+ * `createSpec`. The 90% case stays the plain `import { geom, annotation, createSpec }`; reach for this only
2223
+ * when authoring custom geoms (decision 8) or custom annotations (ADR-035). Registration is per-instance —
2224
+ * geoms are injected to `createCompiler({ geoms })`; annotations need no compile-side registry (coordinate
2225
+ * resolution is generic), only the render plugin via `<GraphProvider annotationPlugins={[...]}>`.
1905
2226
  */
1906
2227
  export declare function createGraphyBuilder<const Geoms extends readonly Geom[] = readonly [], const Annotations extends readonly AnnotationDef[] = readonly []>(options: {
1907
2228
  geoms?: Geoms;
1908
2229
  annotations?: Annotations;
1909
2230
  }): {
1910
2231
  geom: typeof geom & CustomGeomBuilders<Geoms>;
1911
- annotation: CustomAnnotationBuilders<Annotations>;
2232
+ annotation: typeof annotation & CustomAnnotationBuilders<Annotations>;
1912
2233
  createSpec: typeof createSpec;
1913
2234
  };
1914
2235
 
@@ -1935,20 +2256,32 @@ export declare function createSegmentYReader(layer: CompiledLayer): (observation
1935
2256
  export declare const createSizeValueReader: (data: Dataset, mapping: AesMapping) => (observation: Observation) => DataValue;
1936
2257
 
1937
2258
  /**
1938
- * Create a new spec, optionally piping spec items in one call. Data is passed separately
1939
- * to {@link compile}.
2259
+ * Seed a spec the entry point for every chart. The first argument may be a bare {@link AesMapping}
2260
+ * (`{ x, y, color, ... }`), which becomes the spec's global aesthetic mapping; any further arguments are
2261
+ * pipeable spec items (geoms, scales, coords, transforms, config, ...) folded on in order. Data is supplied
2262
+ * separately to `compile` / `<GraphProvider data>`.
2263
+ *
2264
+ * This is the builder pattern: `createSpec` seeds the mapping, then `pipe` (or extra args here) folds each
2265
+ * item onto an immutable spec, accumulating layers/scales/etc. Always declare `scale.x()` / `scale.y()` for
2266
+ * any position channel — they are NOT auto-inferred and yield NaN positions if omitted.
1940
2267
  *
1941
2268
  * @example
1942
- * When the first arg is a mapping:
1943
- * createSpec({ x: 'date', y: 'value' })
2269
+ * import { createSpec, pipe, geom, scale } from '@graphysdk/viz-engine';
1944
2270
  *
1945
- * When piping spec items (more readable when chaining transforms):
1946
- * createSpec(
1947
- * transform.reshape({ reshape: ['revenue'], keyName: 'metric', valueName: 'amount' }),
1948
- * mapping({ x: 'month', y: 'amount', color: 'metric' }),
1949
- * geom.bar(),
1950
- * scale.x(),
1951
- * )
2271
+ * // Most common: mapping first, then pipe the rest.
2272
+ * const spec = pipe(createSpec({ x: 'category', y: 'revenue' }), geom.bar(), scale.x(), scale.y());
2273
+ *
2274
+ * @example
2275
+ * import { createSpec, transform, mapping, geom, scale } from '@graphysdk/viz-engine';
2276
+ *
2277
+ * // All-in-one form, clearer when a transform must run before the mapping is read.
2278
+ * const spec = createSpec(
2279
+ * transform.reshape({ reshape: ['revenue'], keyName: 'metric', valueName: 'amount' }),
2280
+ * mapping({ x: 'month', y: 'amount', color: 'metric' }),
2281
+ * geom.bar(),
2282
+ * scale.x(),
2283
+ * scale.y(),
2284
+ * );
1952
2285
  */
1953
2286
  export declare function createSpec(...items: Array<AesMapping | SpecItem>): SpecInput;
1954
2287
 
@@ -2002,6 +2335,7 @@ declare interface CustomAnnotationOptions<TParams extends object> {
2002
2335
  id?: string;
2003
2336
  }
2004
2337
 
2338
+ /** Resolved form of {@link CustomAnnotationInput} — params defaulted to `{}`, coordinates resolved. */
2005
2339
  export declare interface CustomAnnotationSpec {
2006
2340
  id: string;
2007
2341
  type: string;
@@ -2065,12 +2399,13 @@ declare type CustomPaletteInput = {
2065
2399
  export declare type CustomPalettesInput = Record<string, string[]>;
2066
2400
 
2067
2401
  /**
2068
- * Data to visualize. Structured as a table.
2402
+ * The raw input dataset to visualize, structured as a table of `columns` + `rows`. This is what you
2403
+ * hand to the compiler and to `<GraphProvider data>` — the untransformed, pre-compile shape, distinct
2404
+ * from the per-observation {@link Observation} records a geom reads after compilation.
2069
2405
  *
2070
- * The public-API contract. Row values must be {@link DataValue} (string, number,
2071
- * Date, or null). Internal entry points (e.g. the dataset parser) accept a
2072
- * looser row type — see {@link RawData} — because they must defensively handle
2073
- * malformed input.
2406
+ * The public-API contract: row values must be {@link DataValue} (string, number, Date, or null).
2407
+ * Internal entry points (e.g. the dataset parser) accept a looser row type — see {@link RawData} —
2408
+ * because they must defensively handle malformed input.
2074
2409
  */
2075
2410
  export declare interface Data {
2076
2411
  /**
@@ -2158,6 +2493,11 @@ export declare interface DataLabelsContent {
2158
2493
  labels: PlacedDataLabel[];
2159
2494
  }
2160
2495
 
2496
+ /**
2497
+ * User-facing data-labels options for a layer (`geom.x({ dataLabels })`). A partial of {@link DataLabelsConfig}
2498
+ * minus `labelSource` (the label source is derived from the geom, not set here); unset fields fall back to the
2499
+ * config defaults. Set `{ showDataLabels: true }` to turn labels on.
2500
+ */
2161
2501
  export declare type DataLabelsInput = DeepPartial<Omit<DataLabelsConfig, 'labelSource'>>;
2162
2502
 
2163
2503
  /**
@@ -2181,6 +2521,10 @@ export declare type DataLabelTextMeasurer = (kind: DataLabelKind, text: string)
2181
2521
  *
2182
2522
  * All transformation methods (filter, orderBy, addVariable etc.) return a new instance.
2183
2523
  *
2524
+ * In a geom, this is what a `compile()` half reparameterises (e.g. `addVariable` to write computed
2525
+ * columns) and what a render half receives as `layer.data` — iterate it (or `groupBy` it) to walk the
2526
+ * compiled {@link Observation}s and read each mark's positions with the value readers.
2527
+ *
2184
2528
  * @example
2185
2529
  * const data = new Dataset({
2186
2530
  * age: { type: 'numeric', values: [25, 30, 35, null] },
@@ -2472,6 +2816,10 @@ declare type DefaultPaletteConfig = {
2472
2816
  };
2473
2817
 
2474
2818
  /**
2819
+ * Declares the compile-half of a custom annotation kind: its `type` name, `defaultParams`, and optional
2820
+ * coordinate `arity`. There is no compile logic here — coordinate resolution is generic — so this only
2821
+ * exists to type and register the kind.
2822
+ *
2475
2823
  * `TType` is a `const` type parameter so the literal kind name (`'calloutBox'`) survives to the type
2476
2824
  * level — the registration-typed builder keys `annotation.<kind>(...)` off it, the same way
2477
2825
  * `createGraphyBuilder` captures a geom's name. `TParams` is recovered from `defaultParams`; annotate or
@@ -2509,25 +2857,34 @@ declare interface DifferenceArrowDimensions {
2509
2857
  }
2510
2858
 
2511
2859
  /**
2512
- * User-facing difference-arrow input. `size`, `color` and `labelCrossPosition`
2513
- * are defaulted by the resolver.
2860
+ * A labelled delta drawn between two data observations — the only built-in annotation that anchors to
2861
+ * DATA. Both endpoints are observation anchors (main-axis value + series), so the arrow snaps to the
2862
+ * dataset and survives resize. Only drawn under a cartesian coordinate system. `size`, `color` and
2863
+ * `labelCrossPosition` are defaulted by the resolver.
2514
2864
  */
2515
2865
  export declare interface DifferenceArrowInput {
2516
2866
  id?: string;
2867
+ /** Observation the arrow starts from. */
2517
2868
  start: ObservationAnchorInput;
2869
+ /** Observation the arrow points to. */
2518
2870
  end: ObservationAnchorInput;
2871
+ /** Which delta the label reports. */
2519
2872
  label: DifferenceArrowLabelKind;
2873
+ /** Arrow colour; `null`/omitted falls back to the theme default. @default null */
2520
2874
  color?: string | null;
2875
+ /** @default 'small' */
2521
2876
  size?: DifferenceArrowSize;
2877
+ /** Where the label sits along the arrow's cross-axis, as a `[0,1]` fraction. @default 0.5 */
2522
2878
  labelCrossPosition?: number;
2523
2879
  }
2524
2880
 
2881
+ /** What the arrow's label reports about the `start → end` delta. */
2525
2882
  export declare type DifferenceArrowLabelKind = 'absolute-difference' | 'relative-difference' | 'proportion';
2526
2883
 
2527
2884
  export declare type DifferenceArrowSize = 'small' | 'medium' | 'large';
2528
2885
 
2529
2886
  /**
2530
- * Resolved difference-arrow spec with all optional fields defaulted.
2887
+ * Resolved form of {@link DifferenceArrowInput} defaults applied, anchors normalised.
2531
2888
  */
2532
2889
  export declare interface DifferenceArrowSpec {
2533
2890
  id: string;
@@ -2619,15 +2976,19 @@ declare function filter(options: FilterOptions): FilterTransformInput;
2619
2976
  /***************************************************************
2620
2977
  * Filter Transform
2621
2978
  ***************************************************************/
2979
+ /**
2980
+ * Options for `transform.filter` — keeps only observations where `variableName <operator> value`.
2981
+ */
2622
2982
  declare interface FilterOptions {
2623
2983
  /** The variable to filter on. */
2624
2984
  variableName: VariableName;
2625
- /** The comparison operator. */
2985
+ /** Comparison operator: `'eq'` | `'neq'` | `'gt'` | `'gte'` | `'lt'` | `'lte'`. */
2626
2986
  operator: ComparisonOperator;
2627
- /** The value to compare against. */
2987
+ /** The value to compare each observation's `variableName` against. */
2628
2988
  value: DataValue;
2629
2989
  }
2630
2990
 
2991
+ /** Row-filtering transform produced by `transform.filter`. */
2631
2992
  declare interface FilterTransformInput {
2632
2993
  type: 'transform';
2633
2994
  transformType: 'filter';
@@ -2784,23 +3145,31 @@ export declare interface FormattedPerGroupHeadline {
2784
3145
  }
2785
3146
 
2786
3147
  /**
2787
- * Freeform arrow annotation. Endpoints sit in plot-fractional coordinates
2788
- * (0..1), so they re-flow with panel size. Distinct from
2789
- * {@link DifferenceArrowInput}, which anchors to dataset observations.
3148
+ * A free-standing arrow pointing at something on the panel. Both endpoints sit in panel fractions
3149
+ * (`[0,1]`, top-left origin), so they re-flow with panel size but do NOT snap to a data point. Distinct
3150
+ * from {@link DifferenceArrowInput}, which anchors to dataset observations.
2790
3151
  */
2791
3152
  export declare interface FreeformArrowInput {
2792
3153
  id?: string;
3154
+ /** Tail endpoint. */
2793
3155
  start: ArrowEndpoint;
3156
+ /** Head endpoint (the end pointed at). */
2794
3157
  end: ArrowEndpoint;
2795
- /** null falls back to the theme `defaultAnnotationArrowStroke`. */
3158
+ /** `null` falls back to the theme `defaultAnnotationArrowStroke`. @default null */
2796
3159
  color?: string | null;
3160
+ /** @default 'medium' */
2797
3161
  thickness?: ArrowThickness;
3162
+ /** Arrowhead at the `start` (tail) endpoint. @default 'none' */
2798
3163
  startArrowheadStyle?: ArrowheadStyle;
3164
+ /** Arrowhead at the `end` (head) endpoint. @default 'line-arrow' */
2799
3165
  endArrowheadStyle?: ArrowheadStyle;
3166
+ /** @default 'solid' */
2800
3167
  lineStyle?: ArrowLineStyle;
3168
+ /** Apply the editor's hand-drawn "sticker" styling. @default false */
2801
3169
  hasStickerStyle?: boolean;
2802
3170
  }
2803
3171
 
3172
+ /** Resolved form of {@link FreeformArrowInput} — defaults applied. */
2804
3173
  export declare interface FreeformArrowSpec {
2805
3174
  id: string;
2806
3175
  start: ArrowEndpoint;
@@ -2945,6 +3314,25 @@ export declare abstract class Geom<TParams extends object = object> {
2945
3314
  validateMapping?(input: GeomMappingValidationInput): ValidationIssue[];
2946
3315
  }
2947
3316
 
3317
+ /**
3318
+ * The built-in geom builders. Each is called with one {@link BaseGeomOptions} object and returns a pipeable
3319
+ * layer that `pipe`/`createSpec` folds onto the spec. Compose several to layer marks (e.g. bars + a trend
3320
+ * line). The five marks: `point` (scatter/bubble), `line`, `area`, `bar` (also pie/donut in polar), and
3321
+ * `rule` (a constant or data-driven reference line).
3322
+ *
3323
+ * @example
3324
+ * import { createSpec, pipe, geom, scale, config } from '@graphysdk/viz-engine';
3325
+ *
3326
+ * // Multi-series line; mapping `color` to a column splits series and adds a legend.
3327
+ * const spec = pipe(
3328
+ * createSpec({ x: 'month', y: 'sales', color: 'region' }),
3329
+ * geom.line(),
3330
+ * scale.x(),
3331
+ * scale.y(),
3332
+ * scale.color.palette(),
3333
+ * config({ legend: { position: 'top' } }),
3334
+ * );
3335
+ */
2948
3336
  export declare const geom: {
2949
3337
  point: typeof point;
2950
3338
  line: typeof line;
@@ -3004,12 +3392,31 @@ declare class GeomCompiler {
3004
3392
  resolveAnchorPosition(geomName: GeomIdentity, observation: Observation, coordSystem: CoordSystem): AnchorPosition | null;
3005
3393
  }
3006
3394
 
3395
+ /**
3396
+ * What {@link Geom.compile} receives. The geom reads these to compute its mark geometry and returns a
3397
+ * {@link CompiledGeom}. The pipeline has already run the layer's stat and resolved its aesthetics, so
3398
+ * `compile` sees finished input and only reparameterises it.
3399
+ */
3007
3400
  export declare interface GeomCompilerInput {
3008
- /** The dataset after stat transformation */
3401
+ /**
3402
+ * The dataset after stat transformation — one row per observation, columnar. Read a mapped channel's
3403
+ * column with `extractVariableName(mapping[channel])`, then `data.getValues(column, { type })`; write
3404
+ * computed columns with `data.addVariable` / `data.addConstantVariable` (each returns a new dataset —
3405
+ * the Dataset is immutable).
3406
+ */
3009
3407
  data: Dataset;
3010
- /** The effective mapping for the layer */
3408
+ /**
3409
+ * The effective mapping for the layer: which data column (or constant) backs each aesthetic the author
3410
+ * declared. The source of every channel column the geom reads — including the custom `aes` channels in
3411
+ * {@link Geom.requiredAesthetics} (an OHLC `open`, a box plot `q1`). Read a custom channel with
3412
+ * `readAesthetic(mapping, channel)`.
3413
+ */
3011
3414
  mapping: AesMapping;
3012
- /** Geom-specific params */
3415
+ /**
3416
+ * The geom's static params, already merged over {@link Geom.defaultParams} by the builder. Render
3417
+ * configuration only (widths, radii, colours) — never data columns that bind to a scale, which belong
3418
+ * in `aes`. Typed as the geom's `TParams` at the call site.
3419
+ */
3013
3420
  params: LayerSpec['params'];
3014
3421
  }
3015
3422
 
@@ -3079,12 +3486,27 @@ export declare interface GeomTooltipRow {
3079
3486
  variable: VariableName;
3080
3487
  }
3081
3488
 
3082
- /** Reads the resolved alpha (opacity) value from an observation. */
3489
+ /**
3490
+ * Reads the observation's resolved opacity in `[0,1]` (0 = transparent, 1 = opaque) — pass straight to
3491
+ * `fillOpacity`/`opacity`. The `alpha` aesthetic mapped through its scale. `null` when no `alpha`
3492
+ * aesthetic is mapped.
3493
+ */
3083
3494
  export declare function getAlpha(observation: Observation): NumericDataValue;
3084
3495
 
3496
+ /**
3497
+ * Reads a polar observation's angular extent — the x interval projected to angles. Use it to draw the
3498
+ * wedge of a pie/donut slice or polar bar; pair with {@link getRadiusExtent} for the radial span.
3499
+ * `startAngle`/`endAngle` are in **radians** (0 = straight up, increasing clockwise). The compiler has
3500
+ * already projected the x interval under `coord.polar()`, so no manual angle math is needed.
3501
+ */
3085
3502
  export declare function getAngleExtent(observation: Observation): AngleExtent;
3086
3503
 
3087
- /** Reads the resolved color string from an observation. */
3504
+ /**
3505
+ * Reads the observation's resolved fill/stroke colour as a paint-ready CSS colour string. The visual
3506
+ * mapper has already run the `color` aesthetic through the colour scale, so this is the final string to
3507
+ * hand to `fill`/`stroke` — no further lookup needed. `undefined` when the layer maps no `color`
3508
+ * aesthetic; supply your own series colour (e.g. via `useCategoricalColor`) in that case.
3509
+ */
3088
3510
  export declare function getColor(observation: Observation): string | undefined;
3089
3511
 
3090
3512
  /** Reads the coordinate lying on the cross axis of the coord system. */
@@ -3098,6 +3520,13 @@ export declare function getCrossAxisCoordinate(mainAxis: MainAxis, point: XYPoin
3098
3520
  */
3099
3521
  export declare const getDifferenceArrowDimensions: (size: DifferenceArrowSize, textScale: number) => DifferenceArrowDimensions;
3100
3522
 
3523
+ /**
3524
+ * Reads the observation's resolved series identity: the category the `group`/`color` aesthetic placed
3525
+ * it in, as a plain string. Use it to split a layer's observations into series (one polygon, line, or
3526
+ * colour per group) when painting. `null` when the layer maps no grouping aesthetic — a single,
3527
+ * ungrouped series. Reads the compiler-emitted `group` column, so the value survives any renaming of
3528
+ * the user's grouping mapping.
3529
+ */
3101
3530
  export declare const getGroup: (observation: Observation) => CategoricalDataValue;
3102
3531
 
3103
3532
  /**
@@ -3108,20 +3537,33 @@ export declare const getGroup: (observation: Observation) => CategoricalDataValu
3108
3537
  export declare const getIdentityKey: (observation: Observation) => string;
3109
3538
 
3110
3539
  /**
3111
- * Reads the resolved line type (stroke style) from an observation.
3112
- * Falls back to `'solid'` when no `lineType` variable was derived.
3540
+ * Reads the observation's resolved line style (`'solid'`, `'dashed'`, …) for use as a stroke pattern.
3541
+ * The `lineType` aesthetic mapped through its scale, falling back to `'solid'` when no `lineType`
3542
+ * aesthetic is mapped — so this reader, unlike the others, never returns `null`.
3113
3543
  */
3114
3544
  export declare function getLineType(observation: Observation): LineStyleType;
3115
3545
 
3116
3546
  /** Reads the coordinate lying on the main (independent) axis of the coord system. */
3117
3547
  export declare function getMainAxisCoordinate(mainAxis: MainAxis, point: XYPoint): number;
3118
3548
 
3549
+ /**
3550
+ * Reads a polar observation's radial extent — the y interval projected to radii. Use it with
3551
+ * {@link getAngleExtent} to draw a donut/polar-bar segment. `innerRadius`/`outerRadius` are in `[0,1]`
3552
+ * (0 = centre, 1 = outer ring); `outerRadius` falls back to the `point` y radius when the observation
3553
+ * carries no upper y endpoint (a pie slice, which has no inner cutout to oppose).
3554
+ */
3119
3555
  export declare function getRadiusExtent(observation: Observation): RadiusExtent;
3120
3556
 
3121
- /** Reads the resolved size value from an observation. */
3557
+ /**
3558
+ * Reads the observation's resolved size in **pixels** (e.g. a point's diameter or a mark's nominal
3559
+ * extent), already mapped through the `size` scale. `null` when no `size` aesthetic is mapped.
3560
+ */
3122
3561
  export declare function getSize(observation: Observation): NumericDataValue;
3123
3562
 
3124
- /** Reads the resolved stroke width value from an observation. */
3563
+ /**
3564
+ * Reads the observation's resolved stroke width in **pixels** — pass straight to `strokeWidth`. The
3565
+ * `strokeWidth` aesthetic mapped through its scale. `null` when no `strokeWidth` aesthetic is mapped.
3566
+ */
3125
3567
  export declare function getStrokeWidth(observation: Observation): NumericDataValue;
3126
3568
 
3127
3569
  declare interface GetValuesOptions {
@@ -3133,29 +3575,61 @@ declare interface GetValuesOptions {
3133
3575
  distinct?: boolean;
3134
3576
  }
3135
3577
 
3136
- /** Reads the normalized x position from an observation. */
3578
+ /**
3579
+ * Reads the observation's scaled x position: the value of the `point` x channel, already mapped
3580
+ * through the x scale to `[0,1]` of the panel width (0 = left edge, 1 = right edge). `null` when the
3581
+ * observation has no x position. Under `coord.polar({ theta: 'x' })` this returns the vertex **angle
3582
+ * in radians** instead (0 = straight up, increasing clockwise). The everyday position reader — pair
3583
+ * it with {@link getY} to place a point-anchored mark.
3584
+ */
3137
3585
  export declare function getX(observation: Observation): NumericDataValue;
3138
3586
 
3139
- /** Reads the normalized xMax (right band edge) from an observation. */
3587
+ /**
3588
+ * Reads the upper x endpoint of the observation's x interval, scaled to `[0,1]` of the panel width
3589
+ * (1 = right edge). The right edge of a band/bar or the end of a horizontal range bar. Pairs with
3590
+ * {@link getXMin}. `null` when the observation declares no x interval.
3591
+ */
3140
3592
  export declare function getXMax(observation: Observation): NumericDataValue;
3141
3593
 
3142
- /** Reads the normalized xMin (left band edge) from an observation. */
3594
+ /**
3595
+ * Reads the lower x endpoint of the observation's x interval, scaled to `[0,1]` of the panel width
3596
+ * (0 = left edge). The left edge of a band/bar, the start of a horizontal range bar, or a body's left
3597
+ * side. Pairs with {@link getXMax}; `getXMin`/`getXMax` preserve the values `compile()` wrote and are
3598
+ * never re-sorted, so `getXMin` can exceed `getXMax`. `null` when the observation declares no x interval.
3599
+ */
3143
3600
  export declare function getXMin(observation: Observation): NumericDataValue;
3144
3601
 
3145
- /** Reads the normalized y position from an observation. */
3602
+ /**
3603
+ * Reads the observation's scaled y position: the value of the `point` y channel, already mapped
3604
+ * through the y scale to `[0,1]` of the panel height with a **bottom origin** (0 = bottom, 1 = top).
3605
+ * SVG y grows downward, so paint with `1 - getY(...)`. `null` when the observation has no y position.
3606
+ * Under polar coords this returns the **radius in `[0,1]`** (0 = centre, 1 = outer ring). See
3607
+ * {@link getYRaw} to recover the pre-stack segment magnitude.
3608
+ */
3146
3609
  export declare function getY(observation: Observation): NumericDataValue;
3147
3610
 
3148
- /** Reads the normalized yMax (upper extent) from an observation. */
3611
+ /**
3612
+ * Reads the upper y endpoint of the observation's y interval, scaled to `[0,1]` of the panel height
3613
+ * with a **bottom origin** (1 = top; paint with `1 - getYMax(...)`). The bar top, the top of a
3614
+ * candlestick wick, or the end of a vertical range/gantt span. Pairs with {@link getYMin}.
3615
+ * `null` when the observation declares no y interval.
3616
+ */
3149
3617
  export declare function getYMax(observation: Observation): NumericDataValue;
3150
3618
 
3151
- /** Reads the normalized yMin (lower extent) from an observation. */
3619
+ /**
3620
+ * Reads the lower y endpoint of the observation's y interval, scaled to `[0,1]` of the panel height
3621
+ * with a **bottom origin** (0 = bottom; paint with `1 - getYMin(...)`). The bar baseline, the bottom of
3622
+ * a candlestick wick, or the start of a vertical range/gantt span. Pairs with {@link getYMax}; the pair
3623
+ * preserves the values `compile()` wrote and is never re-sorted, so `getYMin` can exceed `getYMax`.
3624
+ * `null` when the observation declares no y interval.
3625
+ */
3152
3626
  export declare function getYMin(observation: Observation): NumericDataValue;
3153
3627
 
3154
3628
  /**
3155
- * Reads the segment value written by stacking position adjusters.
3156
- *
3157
- * Survives theposition-mapper untouched, so renderers can recover original-unit values
3158
- * for stacked segments after `mapping.y` has been rewritten to the cumulative band top.
3629
+ * Reads the observation's pre-stack segment magnitude in **original data units** (not `[0,1]`).
3630
+ * Stacking position adjusters rewrite the mapped `y` to the cumulative band top and stash the segment's
3631
+ * own value here, so a renderer or data label can recover what the segment contributed before stacking.
3632
+ * `null` when the layer was not stacked (the column is written only when stacking along y).
3159
3633
  */
3160
3634
  export declare function getYRaw(observation: Observation): NumericDataValue;
3161
3635
 
@@ -3542,15 +4016,29 @@ export declare class HeuristicTextMeasurer implements TextMeasurer {
3542
4016
  }
3543
4017
 
3544
4018
  /**
3545
- * Create a pipeable highlight spec item.
4019
+ * Pipeable spec item that emphasises the observations matching `predicate` and
4020
+ * de-emphasises (dims or desaturates) everything else. Multiple `highlight(...)`
4021
+ * calls accumulate — their matches union. The de-emphasis style is chosen
4022
+ * separately via `config({ appearance: { highlightStyle: 'dim' | 'desaturate' } })`.
4023
+ *
4024
+ * @param predicate - which observations to emphasise (see {@link Predicate}).
4025
+ * @param options - `scope` ({@link HighlightScope}, default `'data-point'`),
4026
+ * `layerIndex` (target a single layer; omit to apply to all layers), and an
4027
+ * optional explicit `id`.
3546
4028
  *
3547
4029
  * @example
4030
+ * import { pipe, createSpec, geom, scale, highlight } from '@graphysdk/viz-engine';
4031
+ *
3548
4032
  * pipe(
3549
- * createSpec(data, { x: 'month', y: 'revenue', color: 'region' }),
4033
+ * createSpec({ x: 'month', y: 'revenue', color: 'region' }),
3550
4034
  * geom.bar(),
3551
- * highlight({ field: 'region', eq: 'EU' }),
3552
- * highlight({ field: 'region', eq: 'US' }, { scope: 'series' }),
3553
- * )
4035
+ * scale.x(),
4036
+ * scale.y(),
4037
+ * // emphasise one whole series; leave other layers untouched
4038
+ * highlight({ variable: 'region', eq: 'EU' }, { scope: 'series' }),
4039
+ * // and every observation at or above a threshold
4040
+ * highlight({ variable: 'revenue', gte: 2000 })
4041
+ * );
3554
4042
  */
3555
4043
  export declare function highlight(predicate: Predicate, options?: HighlightBuilderOptions): HighlightInput;
3556
4044
 
@@ -4169,8 +4657,9 @@ declare interface Legend {
4169
4657
  */
4170
4658
  declare interface LegendConfig {
4171
4659
  /**
4172
- * Position of the legend
4173
- * @default 'top'
4660
+ * Where the legend sits relative to the plot. See {@link LegendPosition} for the values;
4661
+ * `'auto'` lets the renderer pick based on chart type and series count.
4662
+ * @default 'auto'
4174
4663
  */
4175
4664
  position: LegendPosition;
4176
4665
  /**
@@ -4230,8 +4719,23 @@ declare interface LegendItemVisual {
4230
4719
  lineType?: LineStyleType;
4231
4720
  }
4232
4721
 
4722
+ /**
4723
+ * Where the legend sits relative to the plot, set via
4724
+ * `config({ legend: { position: … } })`.
4725
+ * - 'auto': let the compiler choose based on chart type (default).
4726
+ * - 'right' | 'left' | 'top' | 'bottom': pin to that edge.
4727
+ * - 'none': hide the legend entirely.
4728
+ */
4233
4729
  declare type LegendPosition = 'auto' | 'right' | 'left' | 'top' | 'bottom' | 'none';
4234
4730
 
4731
+ /**
4732
+ * Line marks — connected series. One line per `group` (defaults to the `color` column). Tune the stroke via
4733
+ * {@link LineGeomParams}. Pair with `stat.smooth()` for a trendline. Observations are connected in data
4734
+ * order, so sort by x first.
4735
+ *
4736
+ * @example
4737
+ * pipe(createSpec({ x: 'month', y: 'sales', color: 'region' }), geom.line(), scale.x(), scale.y(), scale.color.palette());
4738
+ */
4235
4739
  declare function line(options?: GeomOptions<'line'>): LayerInputOf<'line'>;
4236
4740
 
4237
4741
  /**
@@ -4254,17 +4758,22 @@ declare class LineGeom extends Geom {
4254
4758
  }
4255
4759
 
4256
4760
  /**
4257
- * Line-specific parameters
4761
+ * Render parameters for `geom.line`. Passed under `params`.
4258
4762
  */
4259
4763
  export declare interface LineGeomParams {
4764
+ /**
4765
+ * Stroke width in pixels, or `'auto'` to let the theme pick a width.
4766
+ * @default 'auto'
4767
+ */
4260
4768
  lineWidth: number | 'auto';
4261
4769
  /**
4262
- * Interpolation method to use for the line.
4770
+ * Interpolation method between points: `'linear'` for straight segments, `'catmull-rom'` for a smooth spline.
4263
4771
  * @default 'linear'
4264
4772
  */
4265
4773
  interpolate: InterpolateType;
4266
4774
  /**
4267
- * How to handle missing (NULL/undefined) values.
4775
+ * How to handle missing (`null`) y-values: `'gap'` breaks the line, `'zero'` drops to zero, `'connect'`
4776
+ * bridges across the gap.
4268
4777
  * @default 'gap'
4269
4778
  */
4270
4779
  missingValues: MissingValuesType;
@@ -4291,7 +4800,12 @@ export declare type Locale = (typeof LOCALES)[number];
4291
4800
  /** A BCP-47 string representing a supported locale. */
4292
4801
  declare const LOCALES: readonly ["en-GB", "en-US", "ar", "pt-PT"];
4293
4802
 
4294
- /** Logical composition of any predicate. */
4803
+ /**
4804
+ * Boolean composition of nested predicates:
4805
+ * - `and`: every sub-predicate matches.
4806
+ * - `or`: at least one matches.
4807
+ * - `not`: the sub-predicate does not match.
4808
+ */
4295
4809
  export declare type LogicalPredicate = {
4296
4810
  and: Predicate[];
4297
4811
  } | {
@@ -4326,7 +4840,9 @@ export declare type MainAxis = 'x' | 'y';
4326
4840
  declare type MappableAes<Definition extends Geom> = Definition['requiredAesthetics'][number] | Definition['visualAesthetics'][number] | 'group';
4327
4841
 
4328
4842
  /**
4329
- * Create a pipeable mapping spec item.
4843
+ * Create a pipeable mapping spec item. Use this form (rather than passing the mapping as the first
4844
+ * `createSpec` arg) when a transform must run before the mapping is read — e.g. reshaping wide columns
4845
+ * to long so a freshly-created column can be bound to a channel.
4330
4846
  *
4331
4847
  * @example
4332
4848
  * createSpec(
@@ -4339,7 +4855,8 @@ declare type MappableAes<Definition extends Geom> = Definition['requiredAestheti
4339
4855
  export declare function mapping(aes: AesMapping): MappingItem;
4340
4856
 
4341
4857
  /**
4342
- * A pipeable spec item that sets/merges the global aesthetic mapping.
4858
+ * A pipeable spec item that sets/merges the global {@link AesMapping}. Produced by {@link mapping} and
4859
+ * folded into the spec by `pipe`/`createSpec`; later mapping items shallow-merge over earlier channels.
4343
4860
  */
4344
4861
  declare interface MappingItem {
4345
4862
  type: 'mapping';
@@ -4455,14 +4972,16 @@ declare type NeonPaletteConfig = {
4455
4972
  declare type NeonPaletteVariant = 'default' | 'waterfall';
4456
4973
 
4457
4974
  /**
4458
- * Configuration for formatting a single number.
4459
- * Defines how numeric values should be displayed in the chart.
4975
+ * Chart-wide number formatting, applied by the renderer to every numeric value
4976
+ * (axis ticks, tooltips, data labels, headline figures). Set via
4977
+ * `config({ numberFormat: { … } })`.
4460
4978
  */
4461
4979
  export declare interface NumberFormatConfig {
4462
4980
  /**
4463
4981
  * Number of decimal places to display.
4464
4982
  * - number: Fixed decimal places (e.g., 2 → "1234.56")
4465
- * - 'auto': Automatic based on value magnitude (default)
4983
+ * - 'auto': Automatic based on value magnitude
4984
+ * @default 'auto'
4466
4985
  */
4467
4986
  decimals: number | 'auto';
4468
4987
  /**
@@ -4472,6 +4991,7 @@ export declare interface NumberFormatConfig {
4472
4991
  * - 'k': Force thousands (1234567 → "1,234.6K")
4473
4992
  * - 'm': Force millions (1234567 → "1.2M")
4474
4993
  * - 'b': Force billions (1234567890 → "1.2B")
4994
+ * @default 'auto'
4475
4995
  */
4476
4996
  abbreviation: 'auto' | 'k' | 'm' | 'b' | 'none';
4477
4997
  /**
@@ -4500,7 +5020,13 @@ declare interface NumericValueFormat {
4500
5020
  type: 'decimal' | 'integer' | 'percentage' | 'duration';
4501
5021
  }
4502
5022
 
4503
- /** A single row of data, mapping every variable name to the value in that row. */
5023
+ /**
5024
+ * One compiled per-observation record — the unit a geom's render half iterates and reads to paint a
5025
+ * single mark. Maps every variable name (the author's data columns plus the compiler's internal
5026
+ * position/visual/group columns) to that observation's value. Read positions and encodings off it with
5027
+ * the value readers ({@link getX}, {@link getYMin}, {@link getColor}, …) rather than indexing internal
5028
+ * keys by hand; read your own named columns with `readNumber`/`readString`.
5029
+ */
4504
5030
  export declare type Observation = Record<VariableName, DataValue>;
4505
5031
 
4506
5032
  /**
@@ -4519,13 +5045,16 @@ export declare interface ObservationAnchor {
4519
5045
  groupValue: DataValue;
4520
5046
  }
4521
5047
 
4522
- /** Points at a single observation by its anchor value and series. */
5048
+ /**
5049
+ * Snaps to a single data observation by its main-axis value and series. The annotation tracks that
5050
+ * observation across resize and re-layout (unlike panel-fractional positioning).
5051
+ */
4523
5052
  export declare interface ObservationAnchorInput {
4524
- /** Pick a specific layer when multiple share the same `(anchorValue, groupValue)` pair. */
5053
+ /** Pick a specific layer when multiple share the same `(anchorValue, groupValue)` pair. Index into the spec's layers. */
4525
5054
  layerIndex?: number;
4526
- /** Value on the main axis (x in cartesian, y in flipped). */
5055
+ /** Value on the main axis (x in cartesian, y in flipped) that selects the observation. */
4527
5056
  anchorValue: DataValue;
4528
- /** Series identity (the `group` aesthetic value). */
5057
+ /** Series identity the `color`/`group` aesthetic value that disambiguates within the axis value. */
4529
5058
  groupValue: DataValue;
4530
5059
  }
4531
5060
 
@@ -4620,19 +5149,29 @@ declare interface PieOptions {
4620
5149
  * Pinned-number annotation: a marker dot pinned to a single observation. The
4621
5150
  * renderer's mini view shows the observation's measurement value; hover reveals
4622
5151
  * the full tooltip (x + y + trend).
5152
+ *
5153
+ * NO PAINTER in `@graphysdk/react-renderer` — this compiles but never draws there (it renders only in
5154
+ * the editor's legacy engine). Don't reach for it when authoring for the React renderer.
4623
5155
  */
4624
5156
  declare interface PinnedNumberAnnotationInput {
4625
5157
  id?: string;
4626
5158
  anchor: ObservationAnchorInput;
4627
5159
  }
4628
5160
 
5161
+ /** Resolved form of {@link PinnedNumberAnnotationInput} — defaults applied, anchor normalised. */
4629
5162
  declare interface PinnedNumberAnnotationSpec {
4630
5163
  id: string;
4631
5164
  anchor: ObservationAnchor;
4632
5165
  }
4633
5166
 
4634
5167
  /**
4635
- * Pipe a spec through a series of spec items (left-to-right).
5168
+ * Fold a sequence of pipeable spec items onto an existing spec, left to right, returning a new spec.
5169
+ * Each item is appended by kind: layers accumulate (call `geom.*` once per mark), scales accumulate,
5170
+ * `config` deep-merges, `coord`/`mapping` overwrite/merge. The usual shape is
5171
+ * `pipe(createSpec({...}), geom.x(), scale.x(), scale.y(), ...)`.
5172
+ *
5173
+ * @example
5174
+ * pipe(createSpec({ x: 'month', y: 'sales', color: 'region' }), geom.line(), scale.x(), scale.y(), scale.color.palette());
4636
5175
  */
4637
5176
  export declare function pipe(spec: SpecInput, ...items: SpecItem[]): SpecInput;
4638
5177
 
@@ -4662,6 +5201,20 @@ export declare interface PlacedDataLabel {
4662
5201
  position: DataLabelPosition;
4663
5202
  }
4664
5203
 
5204
+ /**
5205
+ * Point marks — scatter plots and bubble charts. Map `size` to a column for a bubble chart and `color` for
5206
+ * categorical series. Sizing is controlled via {@link PointGeomParams} `size` or `scale.size.continuous`.
5207
+ *
5208
+ * @example
5209
+ * pipe(
5210
+ * createSpec({ x: 'gdp', y: 'lifeExp', size: 'population', color: 'continent' }),
5211
+ * geom.point(),
5212
+ * scale.x(),
5213
+ * scale.y(),
5214
+ * scale.size.continuous({ range: [4, 40] }),
5215
+ * scale.color.palette(),
5216
+ * );
5217
+ */
4665
5218
  declare function point(options?: GeomOptions<'point'>): LayerInputOf<'point'>;
4666
5219
 
4667
5220
  /**
@@ -4680,9 +5233,14 @@ declare class PointGeom extends Geom {
4680
5233
  }
4681
5234
 
4682
5235
  /**
4683
- * Point-specific parameters
5236
+ * Render parameters for `geom.point`. Passed under `params`.
4684
5237
  */
4685
5238
  declare interface PointGeomParams {
5239
+ /**
5240
+ * Mark diameter in pixels, used when `size` is not a data channel. To size by data instead, map the `size`
5241
+ * aesthetic and declare `scale.size.continuous({ range })`.
5242
+ * @default 8
5243
+ */
4686
5244
  size: number;
4687
5245
  }
4688
5246
 
@@ -4698,19 +5256,28 @@ declare interface PolarCoordInput {
4698
5256
  }
4699
5257
 
4700
5258
  /**
4701
- * Params for polar coordinate system
5259
+ * Resolved params for the polar coordinate system (defaults applied).
5260
+ * Drives pie, donut, and radar/radial layouts by mapping one scaled aesthetic to the
5261
+ * angle and the other to the radius.
4702
5262
  */
4703
5263
  declare interface PolarCoordParams extends BaseCoordParams {
4704
5264
  /**
4705
- * Which aesthetic maps to theta (angle): 'x' or 'y'
5265
+ * Which aesthetic becomes the angle (theta); the other aesthetic becomes the radius,
5266
+ * scaled into `[innerRadius, 1]`. Use `'y'` for pie/donut (stacked value → angle),
5267
+ * `'x'` for radar (one spoke per category).
5268
+ * @default 'x'
4706
5269
  */
4707
5270
  theta: 'x' | 'y';
4708
5271
  /**
4709
- * Starting angle in degrees
5272
+ * Rotation offset of the whole layout, in degrees. Shifts where the first datum begins;
5273
+ * the full sweep is 360°.
5274
+ * @default 0
4710
5275
  */
4711
5276
  startAngle: number;
4712
5277
  /**
4713
- * Inner radius as fraction 0-1 (for donut charts)
5278
+ * Hole radius as a fraction of the outer radius, `0`–`1`. `0` is a full pie;
5279
+ * any value `> 0` produces a donut (e.g. `0.55`).
5280
+ * @default 0
4714
5281
  */
4715
5282
  innerRadius: number;
4716
5283
  }
@@ -4880,6 +5447,10 @@ export declare type PositionType = 'stack' | 'dodge' | 'identity' | 'fill';
4880
5447
  */
4881
5448
  declare type PositionValueKind = 'value' | 'bandOffset';
4882
5449
 
5450
+ /**
5451
+ * Selects which observations a highlight emphasises: either a single-column
5452
+ * {@link VariablePredicate} or a {@link LogicalPredicate} combining several.
5453
+ */
4883
5454
  export declare type Predicate = VariablePredicate | LogicalPredicate;
4884
5455
 
4885
5456
  export declare const prefixInternalVariable: (name: string) => string;
@@ -4902,6 +5473,11 @@ declare interface QuantitativeScaleMethods {
4902
5473
  identity: (options?: IdentityScaleOptions) => IdentityScaleInput;
4903
5474
  }
4904
5475
 
5476
+ /**
5477
+ * The radial span of an arc/wedge in a polar coord, in `[0,1]` (0 = centre, 1 = outer ring).
5478
+ * `innerRadius` is `null` when the observation declares no y interval; `outerRadius` falls back to the
5479
+ * `point` radius when no upper endpoint exists. Returned by {@link getRadiusExtent}.
5480
+ */
4905
5481
  export declare interface RadiusExtent {
4906
5482
  innerRadius: NumericDataValue;
4907
5483
  outerRadius: NumericDataValue;
@@ -4916,19 +5492,28 @@ export declare interface RadiusExtent {
4916
5492
  export declare function readAesthetic(aesMapping: AesMapping, name: string): AestheticValue | undefined;
4917
5493
 
4918
5494
  /**
4919
- * Reads an author-named numeric column from an observation with the same null-discipline as the
4920
- * built-in position/visual readers (`getX`, `getColor`, ): a missing or wrong-typed value is
4921
- * `null`, never silently coerced to `0`. A custom geom writes its own columns and has no typed
4922
- * accessor for them; these readers fill that gap without re-deriving the coercion per geom.
5495
+ * Reads a value by **column name** from an observation, as a number. Use this for the columns a custom
5496
+ * geom named itself (via `variableFor(axis, name)` for scalar channels, or `addVariable` in `compile()`)
5497
+ * the position readers (`getX`, `getYMin`, …) and visual readers (`getColor`, …) cover the built-in
5498
+ * channels by their fixed internal keys, but there is no typed accessor for an author-named column, and
5499
+ * this fills that gap. The returned number is **whatever was written to that column** (a scalar channel
5500
+ * is already scaled to `[0,1]`; a plain `addVariable` value is in its original units — it carries no
5501
+ * scaling on its own).
4923
5502
  *
4924
- * Pass `fallback` to opt into a default for genuinely-missing values; the overload then narrows the
4925
- * return to `number`, so a geom that wants `0`-on-missing says so explicitly.
5503
+ * Shares the readers' null-discipline: a missing or wrong-typed value is `null`, never silently coerced
5504
+ * to `0`. Pass `fallback` to opt into a default for genuinely-missing values; the overload then narrows
5505
+ * the return to `number`, so a geom that wants `0`-on-missing says so explicitly.
4926
5506
  */
4927
5507
  export declare function readNumber(observation: Observation, key: string): number | null;
4928
5508
 
4929
5509
  export declare function readNumber(observation: Observation, key: string, fallback: number): number;
4930
5510
 
4931
- /** Reads an author-named string column from an observation; missing or wrong-typed is `null` unless a `fallback` is given. */
5511
+ /**
5512
+ * Reads a value by **column name** from an observation, as a string — the string counterpart to
5513
+ * {@link readNumber}, for author-named categorical/label columns a custom geom wrote in `compile()`.
5514
+ * A missing or wrong-typed value is `null` unless a `fallback` is given (the overload then narrows the
5515
+ * return to `string`).
5516
+ */
4932
5517
  export declare function readString(observation: Observation, key: string): string | null;
4933
5518
 
4934
5519
  export declare function readString(observation: Observation, key: string, fallback: string): string;
@@ -4992,6 +5577,11 @@ declare function reshape(options?: ReshapeOptions): ReshapeTransformInput;
4992
5577
  /***************************************************************
4993
5578
  * Reshape Transform
4994
5579
  ***************************************************************/
5580
+ /**
5581
+ * Options for `transform.reshape` — pivots a wide table to long ("tidy") form by collapsing
5582
+ * several numeric columns into two: a key column (the original column name) and a value column.
5583
+ * The idiom for turning a multi-metric table into a single series mappable by `color`.
5584
+ */
4995
5585
  declare interface ReshapeOptions {
4996
5586
  /**
4997
5587
  * Numeric variables to collapse into rows.
@@ -5015,6 +5605,7 @@ declare interface ReshapeOptions {
5015
5605
  valueName?: VariableName;
5016
5606
  }
5017
5607
 
5608
+ /** Pivot-to-long transform produced by `transform.reshape`. */
5018
5609
  declare interface ReshapeTransformInput {
5019
5610
  type: 'transform';
5020
5611
  transformType: 'reshape';
@@ -5098,15 +5689,35 @@ export declare function resolveYScaleAesthetic(yScaleType: YScaleType): ScaledAe
5098
5689
  */
5099
5690
  export declare const RESTING_HOVER_STATE: HoverState;
5100
5691
 
5101
- /** TipTap-compatible rich text node (no tiptap dependency). */
5692
+ /**
5693
+ * A node in a ProseMirror/TipTap-style rich-text document tree (no tiptap
5694
+ * dependency). NOT a plain string — it is a recursive node where `content`
5695
+ * holds child nodes and a leaf text node carries `text`. Used both for chart
5696
+ * titles/captions and for text annotation bodies.
5697
+ *
5698
+ * The root is a `{ type: 'doc' }` node; block children are `'paragraph'` or
5699
+ * `'heading'` (with `attrs.level`); inline runs are `'text'` nodes whose
5700
+ * `marks` apply styling (e.g. `{ type: 'bold' }`, `{ type: 'italic' }`,
5701
+ * `{ type: 'link', attrs: { href } }`). Plain prose is one paragraph of one
5702
+ * text node:
5703
+ *
5704
+ * ```ts
5705
+ * { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Quarterly sales' }] }] }
5706
+ * ```
5707
+ */
5102
5708
  export declare interface RichTextContent {
5709
+ /** Node kind: `'doc'` (root), `'paragraph'`, `'heading'`, `'text'`, etc. */
5103
5710
  type?: string;
5711
+ /** Child nodes. Present on container nodes; absent on `'text'` leaves. */
5104
5712
  content?: RichTextContent[];
5713
+ /** The literal string carried by a `'text'` leaf node. */
5105
5714
  text?: string;
5715
+ /** Inline formatting applied to a `'text'` node (bold, italic, link, …). */
5106
5716
  marks?: Array<{
5107
5717
  type: string;
5108
5718
  attrs?: Record<string, unknown>;
5109
5719
  }>;
5720
+ /** Node attributes, e.g. `{ level: 2 }` on a heading or `{ href }` on a link mark target. */
5110
5721
  attrs?: Record<string, unknown>;
5111
5722
  }
5112
5723
 
@@ -5121,6 +5732,18 @@ declare interface RolePositionChannel extends PositionChannelBase {
5121
5732
  name?: string;
5122
5733
  }
5123
5734
 
5735
+ /**
5736
+ * Rule marks — a single horizontal or vertical reference line, the built-in for goal/threshold/average
5737
+ * lines (no custom geom needed). Pin a constant with `aes: { y: { value } }` (horizontal) or
5738
+ * `aes: { x: { value } }` (vertical, numeric x), or compute a data-driven line with `stat.mean()`. Style and
5739
+ * label it via {@link RuleGeomParams}; set `interactive: false` so it doesn't take hover.
5740
+ *
5741
+ * @example
5742
+ * // Constant goal line at y = 2500
5743
+ * geom.rule({ aes: { y: { value: 2500 } }, params: { label: 'Target', lineType: 'dashed', labelPosition: 'start' } });
5744
+ * // Data-driven average line
5745
+ * geom.rule({ aes: { y: 'revenue' }, stat: stat.mean(), params: { label: 'Average' }, interactive: false });
5746
+ */
5124
5747
  declare function rule(options?: GeomOptions<'rule'>): LayerInputOf<'rule'>;
5125
5748
 
5126
5749
  /**
@@ -5143,20 +5766,34 @@ declare class RuleGeom extends Geom {
5143
5766
  }
5144
5767
 
5145
5768
  /**
5146
- * Rule-specific parameters.
5769
+ * Render parameters for `geom.rule`. Passed under `params`. The line's value comes from `aes`
5770
+ * (`{ y: { value } }` or `stat.mean()`), not from here — these are styling and labelling only.
5147
5771
  */
5148
5772
  export declare interface RuleGeomParams {
5149
- /** Stroke color; falls back to a theme token. */
5773
+ /** Stroke color (any CSS color). Falls back to a theme token when omitted. */
5150
5774
  color?: string;
5775
+ /**
5776
+ * Stroke width in pixels.
5777
+ * @default 1
5778
+ */
5151
5779
  strokeWidth: number;
5780
+ /**
5781
+ * Dash style of the line.
5782
+ * @default 'dashed'
5783
+ */
5152
5784
  lineType: LineStyleType;
5153
- /** Optional inline text label rendered alongside the line. */
5785
+ /** Optional inline text label rendered alongside the line (e.g. `'Target'`, `'Average'`). */
5154
5786
  label?: string;
5787
+ /**
5788
+ * Which end of the line the `label` is anchored to.
5789
+ * @default 'start'
5790
+ */
5155
5791
  labelPosition: RuleLabelPosition;
5156
5792
  }
5157
5793
 
5158
5794
  /**
5159
- * Where the optional inline label is anchored along a reference line.
5795
+ * Where the optional inline label sits along a reference line: `'start'` (left/top end) or `'end'`
5796
+ * (right/bottom end).
5160
5797
  */
5161
5798
  export declare type RuleLabelPosition = 'start' | 'end';
5162
5799
 
@@ -5188,6 +5825,31 @@ declare abstract class Scale {
5188
5825
  abstract compile(spec: ScaleSpec, values: DataValue[]): CompiledScale;
5189
5826
  }
5190
5827
 
5828
+ /**
5829
+ * Scale builder — declares how each mapped variable is turned into a visual value
5830
+ * (axis position, color, size, …). Pipe the result onto a spec.
5831
+ *
5832
+ * Position scales must be declared EXPLICITLY: the builder never auto-infers `x`/`y`,
5833
+ * so omitting `scale.x()` / `scale.y()` yields NaN positions. `scale.x`/`.y`/`.ySecondary`
5834
+ * are callable for an inferred scale (type auto-detected from the data) or expose explicit
5835
+ * sub-methods: `.continuous` / `.discrete` / `.datetime` / `.log` / `.sqrt`. Use
5836
+ * `scale.x.discrete()` for categorical or temporal-string axes.
5837
+ *
5838
+ * Non-position aesthetics auto-infer from the mapping, so their scale entry is optional —
5839
+ * add one only to override the default (e.g. `scale.color.palette()`, `scale.size.continuous({ range })`).
5840
+ *
5841
+ * @example
5842
+ * import { pipe, createSpec, geom, scale } from '@graphysdk/viz-engine';
5843
+ *
5844
+ * pipe(
5845
+ * createSpec({ x: 'gdp', y: 'lifeExp', size: 'population', color: 'continent' }),
5846
+ * geom.point(),
5847
+ * scale.x.log({ domainMin: 1 }),
5848
+ * scale.y.continuous({ zero: false, nice: true }),
5849
+ * scale.size.continuous({ range: [4, 40] }),
5850
+ * scale.color.palette()
5851
+ * );
5852
+ */
5191
5853
  export declare const scale: ScaleAPI;
5192
5854
 
5193
5855
  declare interface ScaleAPI {
@@ -5297,7 +5959,10 @@ declare type ScaledPositionAestheticKey = 'x' | 'y' | 'ySecondary';
5297
5959
  export declare type ScaledVisualAestheticKey = 'color' | 'size' | 'alpha' | 'strokeWidth' | 'lineType';
5298
5960
 
5299
5961
  /**
5300
- * Union type for all possible scale specifications (including inferred, pre-resolution).
5962
+ * Any value the `scale` builder produces, before resolution. Each pipe item carries the
5963
+ * target aesthetic plus its scale type and options; an `inferred` entry has its concrete
5964
+ * type chosen from the data during compilation. This is the type accepted by the spec
5965
+ * pipeline — author scales with the `scale` builder rather than constructing it by hand.
5301
5966
  */
5302
5967
  declare type ScaleInput = ContinuousScaleInput | DiscreteScaleInput | PaletteScaleInput | DatetimeScaleInput | IdentityScaleInput | InferredScaleInput;
5303
5968
 
@@ -5306,8 +5971,9 @@ declare class ScaleRegistry extends Registry<ScaleType, Scale> {
5306
5971
  }
5307
5972
 
5308
5973
  /**
5309
- * Union of scale specs that can appear after resolution (all fields required).
5310
- * InferredScaleInput is resolved to a concrete type during spec resolution.
5974
+ * A fully resolved scale (every option defaulted) as it appears on the compiled spec.
5975
+ * The `inferred` variant has already been collapsed to one of these concrete types
5976
+ * during resolution, so this union has no `inferred` member.
5311
5977
  */
5312
5978
  declare type ScaleSpec = ContinuousScaleSpec | DiscreteScaleSpec | DatetimeScaleSpec | IdentityScaleSpec | PaletteScaleSpec;
5313
5979
 
@@ -5521,27 +6187,37 @@ declare type SetScaleDomainParams = {
5521
6187
  };
5522
6188
 
5523
6189
  /**
5524
- * Freeform rectangle annotation. Position and size are expressed as
5525
- * fractions of the plot rect (0..1) so the annotation re-flows when the
5526
- * panel resizes.
6190
+ * A shaded box layered onto the panel. Position and size are panel fractions (`[0,1]`, top-left
6191
+ * origin) NOT data values so the shape re-flows on resize but does not snap to a data point. Use a
6192
+ * difference arrow or a custom annotation when you need data anchoring.
5527
6193
  */
5528
6194
  export declare interface ShapeInput {
5529
6195
  id?: string;
6196
+ /** @default 'rectangle' */
5530
6197
  kind?: ShapeKind;
6198
+ /** @default 'foreground' */
5531
6199
  zOrder?: ShapeZOrder;
6200
+ /** Left edge as a `[0,1]` fraction of panel width (0 = left). */
5532
6201
  x: number;
6202
+ /** Top edge as a `[0,1]` fraction of panel height (0 = top). */
5533
6203
  y: number;
6204
+ /** Width as a `[0,1]` fraction of panel width. */
5534
6205
  width: number;
6206
+ /** Height as a `[0,1]` fraction of panel height. */
5535
6207
  height: number;
6208
+ /** @default 'transparent' */
5536
6209
  fillColor?: string;
6210
+ /** Fill alpha, `[0,1]`. @default 1 */
5537
6211
  fillOpacity?: number;
6212
+ /** Stroke width in pixels. @default 1 */
5538
6213
  strokeWidth?: number;
5539
- /** null falls back to the theme `defaultAnnotationShapeStroke`. */
6214
+ /** `null` falls back to the theme `defaultAnnotationShapeStroke`. @default null */
5540
6215
  strokeColor?: string | null;
5541
6216
  }
5542
6217
 
5543
6218
  export declare type ShapeKind = 'rectangle';
5544
6219
 
6220
+ /** Resolved form of {@link ShapeInput} — defaults applied. */
5545
6221
  export declare interface ShapeSpec {
5546
6222
  id: string;
5547
6223
  kind: ShapeKind;
@@ -5562,7 +6238,9 @@ export declare interface ShapeSpec {
5562
6238
  export declare type ShapeZOrder = 'background' | 'foreground';
5563
6239
 
5564
6240
  /**
5565
- * Builder for the smooth stat.
6241
+ * Builder for the smooth stat — fits a regression trendline through the observations.
6242
+ * Pair with `geom.line` for a drawn trendline. `order` applies only to `'polynomial'`,
6243
+ * `bandwidth` only to `'loess'`; both are ignored by the other methods.
5566
6244
  *
5567
6245
  * @example
5568
6246
  * geom.line({ stat: stat.smooth({ method: 'linear' }) })
@@ -5576,7 +6254,14 @@ declare function smooth(options: {
5576
6254
  }): SmoothStatInput;
5577
6255
 
5578
6256
  /**
5579
- * Regression methods supported by the `smooth` stat.
6257
+ * Regression/trendline method fitted by the `smooth` stat through the observations:
6258
+ * - `'linear'` — straight line of best fit (`y = a + b·x`). The default.
6259
+ * - `'loess'` — locally weighted smoothing; follows local structure. Tune with `bandwidth`.
6260
+ * - `'exponential'` — `y = a·e^(b·x)`; constant-rate growth/decay.
6261
+ * - `'logarithmic'` — `y = a + b·ln(x)`; fast early then flattening.
6262
+ * - `'quadratic'` — parabola (`y = a + b·x + c·x²`); a single bend.
6263
+ * - `'power'` — `y = a·x^b`; scale-free relationships.
6264
+ * - `'polynomial'` — degree-`order` polynomial; multiple bends. Tune with `order`.
5580
6265
  */
5581
6266
  export declare type SmoothMethod = 'linear' | 'loess' | 'exponential' | 'logarithmic' | 'quadratic' | 'power' | 'polynomial';
5582
6267
 
@@ -5586,7 +6271,9 @@ export declare type SmoothMethod = 'linear' | 'loess' | 'exponential' | 'logarit
5586
6271
  declare interface SmoothStatInput {
5587
6272
  type: 'smooth';
5588
6273
  method: SmoothMethod;
6274
+ /** Polynomial degree. Only used when `method: 'polynomial'`. @default 3 */
5589
6275
  order?: number;
6276
+ /** LOESS smoothing window as a fraction (0–1) of the data. Only used when `method: 'loess'`. @default 0.3 */
5590
6277
  bandwidth?: number;
5591
6278
  }
5592
6279
 
@@ -5612,6 +6299,10 @@ export declare const sortByXIfContinuous: (data: Dataset, mapping: AesMapping) =
5612
6299
  /***************************************************************
5613
6300
  * Sort Transform
5614
6301
  ***************************************************************/
6302
+ /**
6303
+ * Options for `transform.sort` — reorders observations by one variable. Affects draw order
6304
+ * and the order categories are first seen (and thus discrete-scale domain order).
6305
+ */
5615
6306
  declare interface SortOptions {
5616
6307
  /** The variable to sort by. */
5617
6308
  variableName: VariableName;
@@ -5619,15 +6310,18 @@ declare interface SortOptions {
5619
6310
  direction?: 'asc' | 'desc';
5620
6311
  }
5621
6312
 
6313
+ /** Observation-ordering transform produced by `transform.sort`. */
5622
6314
  declare interface SortTransformInput {
5623
6315
  type: 'transform';
5624
6316
  transformType: 'sort';
5625
6317
  options: SortOptions;
5626
6318
  }
5627
6319
 
5628
- /** Data-source attribution shown under the caption. */
6320
+ /** Data-source attribution shown under the caption: a `label` and optional `url`. */
5629
6321
  export declare interface SourceContent {
6322
+ /** Displayed attribution text, e.g. `'Internal pipeline'`. */
5630
6323
  label?: string;
6324
+ /** Optional link the label points to. */
5631
6325
  url?: string;
5632
6326
  }
5633
6327
 
@@ -5701,17 +6395,30 @@ export declare interface Spec {
5701
6395
  }
5702
6396
 
5703
6397
  /**
5704
- * The canonical spec type — plain JSON, serializable. Data is provided separately
5705
- * (as a `Data` value to {@link compile}, or as a prop to `<GraphProvider>`).
6398
+ * The canonical spec type — plain JSON, serializable. Built by `createSpec`/`pipe`; data is provided
6399
+ * separately (as a `Data` value to {@link compile}, or as a prop to `<GraphProvider>`). Hand-construct it
6400
+ * only when you cannot use the builders; otherwise prefer `pipe(createSpec({...}), geom.x(), scale.x(), ...)`.
5706
6401
  */
5707
6402
  export declare interface SpecInput {
6403
+ /** Global aesthetic mapping (data columns → channels); layer `aes` overrides merge over this. */
5708
6404
  mapping: AesMapping;
6405
+ /** Geometry layers to render, in draw order. One entry per `geom.*` call. */
5709
6406
  layers: LayerInput[];
6407
+ /**
6408
+ * Scale declarations, one per aesthetic. Position scales (`scale.x`/`scale.y`/`scale.ySecondary`) are NOT
6409
+ * auto-inferred — declare them explicitly or position channels resolve to NaN. Visual scales
6410
+ * (`color`/`size`/...) are inferred from the data when omitted.
6411
+ */
5710
6412
  scales: ScaleInput[];
6413
+ /** Spec-level data transforms applied before any layer is compiled (reshape, filter, ...). */
5711
6414
  transforms: TransformInput[];
6415
+ /** Predicate-driven emphasis rules that dim or accentuate matching observations. */
5712
6416
  highlights: HighlightInput[];
6417
+ /** Annotation overlays — difference arrows, shapes, text, freeform arrows. Optional. */
5713
6418
  annotations?: AnnotationsInput;
6419
+ /** Coordinate system: cartesian (default), `coord.flip()`, or `coord.polar(...)`. Optional. */
5714
6420
  coords?: CoordInput;
6421
+ /** Chart configuration: titles/captions, legend, axes, number format, headline, appearance. */
5715
6422
  config: ConfigInput;
5716
6423
  }
5717
6424
 
@@ -5781,6 +6488,23 @@ declare abstract class Stat {
5781
6488
  protected abstract computeStat(input: StatCompilerInput): CompiledStat;
5782
6489
  }
5783
6490
 
6491
+ /**
6492
+ * Statistical-transform builder — sets a geom's `stat`, replacing each layer's raw observations
6493
+ * with a derived summary before positions are computed. Defaults to `identity` (raw data).
6494
+ *
6495
+ * - `identity()` — pass observations through unchanged (the default).
6496
+ * - `count()` — number of observations per x value, written to `y`; do NOT also map `y`.
6497
+ * - `mean()` — reduce the mapped `y` to its average (a single value); the idiom for an
6498
+ * average line (`geom.rule({ stat: stat.mean() })`).
6499
+ * - `smooth({ method })` — fit a regression trendline; the idiom for a trendline
6500
+ * (`geom.line({ stat: stat.smooth({ method: 'linear' }) })`).
6501
+ *
6502
+ * @example
6503
+ * import { geom, stat } from '@graphysdk/viz-engine';
6504
+ *
6505
+ * geom.rule({ aes: { y: 'revenue' }, stat: stat.mean(), params: { label: 'Average' } });
6506
+ * geom.line({ stat: stat.smooth({ method: 'linear' }), interactive: false });
6507
+ */
5784
6508
  export declare const stat: {
5785
6509
  identity: typeof identity;
5786
6510
  count: typeof count;
@@ -5816,7 +6540,9 @@ declare interface StatCompilerInput {
5816
6540
  }
5817
6541
 
5818
6542
  /**
5819
- * User-facing stat inputeither a {@link StatName} string shorthand or an object spec.
6543
+ * Any value the `stat` builder produces passed as the `stat` option of a geom.
6544
+ * The string-shorthand variants (`stat.identity()`, `stat.count()`, `stat.mean()`) carry only
6545
+ * a `type`; `smooth` additionally carries the regression parameters.
5820
6546
  */
5821
6547
  declare type StatInput = IdentityStatSpec | CountStatSpec | SmoothStatInput | MeanStatSpec;
5822
6548
 
@@ -5844,6 +6570,9 @@ declare type StatSpec = IdentityStatSpec | CountStatSpec | SmoothStatSpec | Mean
5844
6570
 
5845
6571
  /**
5846
6572
  * Sticker annotation: a built-in emoji-like image pinned to a single observation.
6573
+ *
6574
+ * NO PAINTER in `@graphysdk/react-renderer` — this compiles but never draws there (it renders only in
6575
+ * the editor's legacy engine). Don't reach for it when authoring for the React renderer.
5847
6576
  */
5848
6577
  declare interface StickerAnnotationInput {
5849
6578
  id?: string;
@@ -5851,6 +6580,7 @@ declare interface StickerAnnotationInput {
5851
6580
  sticker: StickerId;
5852
6581
  }
5853
6582
 
6583
+ /** Resolved form of {@link StickerAnnotationInput} — defaults applied, anchor normalised. */
5854
6584
  declare interface StickerAnnotationSpec {
5855
6585
  id: string;
5856
6586
  anchor: ObservationAnchor;
@@ -5901,26 +6631,33 @@ declare interface TemporalValueFormat {
5901
6631
  dateFormat?: string;
5902
6632
  }
5903
6633
 
6634
+ /** How `backgroundColor` is applied: `'fade'` (soft gradient) or `'opaque'` (flat fill). */
5904
6635
  export declare type TextAnnotationBackgroundColorStyle = 'fade' | 'opaque';
5905
6636
 
5906
6637
  /**
5907
- * Freeform rich-text annotation. Position and width are fractions of the plot
5908
- * rect (0..1). Height is intrinsic to the rendered content.
6638
+ * A free-standing text label on the panel. Positioned in panel fractions (`[0,1]`, top-left origin) —
6639
+ * NOT data values so it re-flows on resize but does not snap to a data point. There is no `height`
6640
+ * field: height is intrinsic to the rendered content. `content` is a structured {@link RichTextContent}
6641
+ * node tree (ProseMirror/TipTap-style), NOT a plain string — wrap a string as
6642
+ * `{ type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Label' }] }] }`.
5909
6643
  */
5910
6644
  export declare interface TextAnnotationInput {
5911
6645
  id?: string;
6646
+ /** Rich-text node tree to render (not a plain string). */
5912
6647
  content: RichTextContent;
5913
- /** 0..1 of plot width top-left corner. */
6648
+ /** Left edge as a `[0,1]` fraction of panel width (0 = left, top-left corner). */
5914
6649
  x: number;
5915
- /** 0..1 of plot height top-left corner. */
6650
+ /** Top edge as a `[0,1]` fraction of panel height (0 = top, top-left corner). */
5916
6651
  y: number;
5917
- /** 0..1 of plot width. */
6652
+ /** Box width as a `[0,1]` fraction of panel width; text wraps within it (height is intrinsic). */
5918
6653
  width: number;
5919
- /** null falls back to a transparent background. */
6654
+ /** `null` falls back to a transparent background. @default null */
5920
6655
  backgroundColor?: string | null;
6656
+ /** @default 'opaque' */
5921
6657
  backgroundColorStyle?: TextAnnotationBackgroundColorStyle;
5922
6658
  }
5923
6659
 
6660
+ /** Resolved form of {@link TextAnnotationInput} — defaults applied. */
5924
6661
  export declare interface TextAnnotationSpec {
5925
6662
  id: string;
5926
6663
  content: RichTextContent;
@@ -5931,7 +6668,11 @@ export declare interface TextAnnotationSpec {
5931
6668
  backgroundColorStyle: TextAnnotationBackgroundColorStyle;
5932
6669
  }
5933
6670
 
5934
- /** A text value — plain string or structured rich text. */
6671
+ /**
6672
+ * A text value for a title, subtitle, or caption: either a plain `string`
6673
+ * (rendered as-is) or a structured {@link RichTextContent} document tree for
6674
+ * multi-style / multi-line text.
6675
+ */
5935
6676
  export declare type TextContent = string | RichTextContent;
5936
6677
 
5937
6678
  export declare interface TextMeasurer {
@@ -5975,6 +6716,29 @@ export declare interface TooltipRow {
5975
6716
  key: string;
5976
6717
  }
5977
6718
 
6719
+ /**
6720
+ * Data-transform builder — reshapes the dataset BEFORE any geom maps over it. Pipe one or more
6721
+ * onto a spec; they apply in order, ahead of stats and scaling, and affect every layer.
6722
+ *
6723
+ * - `reshape(opts?)` — pivot wide numeric columns to long form (key/value); the move for plotting
6724
+ * several metrics as one color-split series.
6725
+ * - `filter(opts)` — keep observations matching `variableName <operator> value`.
6726
+ * - `sort(opts)` — order observations by a variable (`'asc'` | `'desc'`).
6727
+ * - `aggregate(opts)` — group by variables and reduce each group (sum/mean/count/…).
6728
+ * - `constant(opts)` — add a column with a fixed value on every observation.
6729
+ *
6730
+ * @example
6731
+ * import { pipe, createSpec, geom, scale, transform } from '@graphysdk/viz-engine';
6732
+ *
6733
+ * pipe(
6734
+ * createSpec({ x: 'region', y: 'total', color: 'region' }),
6735
+ * transform.filter({ variableName: 'year', operator: 'eq', value: 2024 }),
6736
+ * transform.aggregate({ groupby: ['region'], operations: [{ op: 'sum', variableName: 'revenue', as: 'total' }] }),
6737
+ * geom.bar(),
6738
+ * scale.x(),
6739
+ * scale.y()
6740
+ * );
6741
+ */
5978
6742
  export declare const transform: {
5979
6743
  reshape: typeof reshape;
5980
6744
  filter: typeof filter;
@@ -6003,6 +6767,10 @@ declare interface TransformCompilerInput {
6003
6767
  /***************************************************************
6004
6768
  * Transform Input
6005
6769
  ***************************************************************/
6770
+ /**
6771
+ * Any value the `transform` builder produces. Transforms run before stats and scaling, in the
6772
+ * order they appear, reshaping the dataset that every layer then maps over.
6773
+ */
6006
6774
  declare type TransformInput = ReshapeTransformInput | FilterTransformInput | SortTransformInput | AggregateTransformInput | ConstantTransformInput;
6007
6775
 
6008
6776
  /**
@@ -6020,6 +6788,7 @@ declare interface TransformStrategy {
6020
6788
  apply: (data: Dataset, transform: TransformInput) => Dataset;
6021
6789
  }
6022
6790
 
6791
+ /** Discriminant tag of a {@link TransformInput}. */
6023
6792
  declare type TransformType = TransformInput['transformType'];
6024
6793
 
6025
6794
  declare type TrendlineType = 'linear' | 'loess' | 'exponential' | 'logarithmic' | 'quadratic' | 'power' | 'polynomial';
@@ -6066,10 +6835,12 @@ export declare interface ValueFormatterFactoryParams<T = ValueFormat> {
6066
6835
  }
6067
6836
 
6068
6837
  /**
6069
- * Constant mapping - a literal value applied to every observation.
6070
- * Analogous to Vega-Lite's `{datum: X}` / ggplot2's `aes(color = "literal")`.
6838
+ * Pins a channel to a single literal value applied to every observation, instead of reading a column.
6839
+ * Use it for reference-line constants (`geom.rule({ aes: { y: { value: 2500 } } })`) or to force a fixed
6840
+ * style (`aes: { lineType: { value: 'dashed' } }`). Analogous to Vega-Lite's `{datum: X}`.
6071
6841
  */
6072
6842
  declare interface ValueMapping {
6843
+ /** The constant — a number, string, Date, or null — shared by all observations. */
6073
6844
  value: DataValue;
6074
6845
  }
6075
6846
 
@@ -6092,9 +6863,11 @@ export declare function variableFor(axis: ChannelAxis, name: string): string;
6092
6863
  declare type VariableMap = Record<VariableName, Variable>;
6093
6864
 
6094
6865
  /**
6095
- * Variable mapping - references a column in the data
6866
+ * Binds a channel to a data column by name. `{ variable: 'revenue' }` reads the `revenue` column
6867
+ * per observation. Equivalent to the bare-string shorthand `'revenue'` in an {@link AesMapping}.
6096
6868
  */
6097
6869
  declare interface VariableMapping {
6870
+ /** Column key in the data, matching a `columns[i].key`. */
6098
6871
  variable: string;
6099
6872
  }
6100
6873
 
@@ -6103,15 +6876,20 @@ declare type VariableMetadata = Record<VariableName, {
6103
6876
  valueFormat: ValueFormat;
6104
6877
  }>;
6105
6878
 
6106
- /** A type alias for variable names. */
6879
+ /** A variable (column) name. Names with the internal prefix address compiler-emitted columns; address those through the value readers (`getX`, …) or `variableFor`, never by literal. */
6107
6880
  export declare type VariableName = string;
6108
6881
 
6109
6882
  /**
6110
- * Field-based predicates against post-transform user columns.
6883
+ * A value test against one post-transform user column. The selected operator
6884
+ * decides which observations a highlight emphasises:
6885
+ * - `eq`: column equals the value.
6886
+ * - `oneOf`: column is one of the listed values.
6887
+ * - `lt` / `lte` / `gt` / `gte`: ordering comparison (numeric / datetime only).
6888
+ * - `range`: inclusive `[min, max]` interval.
6111
6889
  *
6112
- * `lt`, `lte`, `gt`, `gte`, and `range` accept `DataValue`s and are coerced at
6113
- * evaluation time by the referenced column's `DataType`. Ordering operators
6114
- * against a categorical field are a resolve-time validation error.
6890
+ * Comparison values are `DataValue`s coerced at evaluation time by the
6891
+ * referenced column's `DataType`. Ordering operators against a categorical
6892
+ * field are a resolve-time validation error.
6115
6893
  */
6116
6894
  export declare type VariablePredicate = {
6117
6895
  variable: VariableName;