@graphysdk/viz-engine 0.0.1-plugins.10 → 0.0.1-plugins.2

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,44 +1,24 @@
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
- */
10
3
  export declare interface AesMapping {
11
- /** Horizontal position. Binds to `scale.x`. Categorical/temporal x needs `scale.x.discrete()`. */
12
4
  x?: AestheticValue;
13
- /** Vertical position. Binds to `scale.y` (or `scale.ySecondary` when the layer sets `yScaleType: 'secondary'`). */
14
5
  y?: AestheticValue;
15
- /** Text drawn on the observation (data labels, slice labels). Binds to no scale; rendered as-is. */
16
6
  label?: AestheticValue;
17
- /** Series/category color. Binds to `scale.color.*`; mapping a column splits the geom into series and shows a legend. */
18
7
  color?: AestheticValue;
19
- /** Mark size — point radius / bubble area. Binds to `scale.size.continuous({ range })`. */
20
8
  size?: AestheticValue;
21
- /** Per-observation opacity in `[0,1]` after scaling. Binds to `scale.alpha.*`. */
22
9
  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
- */
27
10
  group?: AestheticValue;
28
- /** Stroke thickness as a data-driven channel. Binds to `scale.strokeWidth.*`; for a fixed width use line `params.lineWidth`. */
29
11
  strokeWidth?: AestheticValue;
30
- /** Dash style (`'solid'`/`'dashed'`/`'dotted'`). Binds to `scale.lineType.discrete({ domain, range })`; great for actual-vs-forecast lines. */
31
12
  lineType?: AestheticValue;
32
13
  }
33
14
 
34
- /** The set of built-in aesthetic channel names — the keys of {@link AesMapping}. */
35
15
  export declare type AestheticKey = keyof AesMapping;
36
16
 
37
17
  /**
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.
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)
42
22
  */
43
23
  declare type AestheticValue = string | VariableMapping | ValueMapping;
44
24
 
@@ -47,28 +27,22 @@ declare function aggregate(options: AggregateOptions): AggregateTransformInput;
47
27
  /***************************************************************
48
28
  * Aggregate Transform
49
29
  ***************************************************************/
50
- /** A single group-wise reduction applied by `transform.aggregate`. */
51
30
  declare interface AggregateOperation {
52
- /** Reduction to apply: `'count'` | `'sum'` | `'mean'` | `'median'` | `'mode'` | `'min'` | `'max'`. */
31
+ /** The aggregation function to apply. */
53
32
  op: AggregationFunction;
54
- /** The variable to reduce within each group. */
33
+ /** The variable to aggregate. */
55
34
  variableName: VariableName;
56
- /** Name of the output variable holding the reduced value. */
35
+ /** The name of the output variable. */
57
36
  as: VariableName;
58
37
  }
59
38
 
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
- */
64
39
  declare interface AggregateOptions {
65
- /** Variables to group by; one output observation is produced per distinct combination. */
40
+ /** Variables to group by before aggregating. */
66
41
  groupby: VariableName[];
67
- /** One or more reductions to compute per group. */
42
+ /** Aggregation operations to apply per group. */
68
43
  operations: AggregateOperation[];
69
44
  }
70
45
 
71
- /** Group-and-reduce transform produced by `transform.aggregate`. */
72
46
  declare interface AggregateTransformInput {
73
47
  type: 'transform';
74
48
  transformType: 'aggregate';
@@ -108,63 +82,11 @@ declare interface AnchorSegment {
108
82
  direction: 'positive' | 'negative';
109
83
  }
110
84
 
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
- */
116
85
  export declare interface AngleExtent {
117
86
  startAngle: NumericDataValue;
118
87
  endAngle: NumericDataValue;
119
88
  }
120
89
 
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
-
168
90
  /**
169
91
  * The compile-half definition of a custom annotation kind (ADR-035).
170
92
  *
@@ -173,11 +95,9 @@ export declare const annotation: {
173
95
  * params })` from `TParams`, merge `defaultParams`, and enforce the optional coordinate arity. The
174
96
  * render-half `draw` lives in the renderer and binds to this definition by import (`defineAnnotationRenderer`).
175
97
  */
176
- /** Allowed coordinate count for an annotation kind; each bound is inclusive, unbounded when omitted. */
177
- export declare interface AnnotationArity {
178
- /** Minimum coordinates required. */
98
+ /** Optional coordinate-count guardrail enforced by the builder; unbounded when omitted. */
99
+ declare interface AnnotationArity {
179
100
  min?: number;
180
- /** Maximum coordinates allowed. */
181
101
  max?: number;
182
102
  }
183
103
 
@@ -222,59 +142,18 @@ declare interface AnnotationDataPoint {
222
142
  rowValue?: DataValue;
223
143
  }
224
144
 
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
- */
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`. */
145
+ declare interface AnnotationDef<TParams extends object = object, TType extends string = string> {
232
146
  type: TType;
233
147
  /** Carrier that lets the builder recover `TParams` and merge defaults before a param reaches `draw`. */
234
148
  defaultParams: TParams;
235
- /** Coordinate-count guardrail enforced by the builder; unbounded when omitted. */
236
149
  coordinates?: AnnotationArity;
237
150
  }
238
151
 
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 = {
152
+ /** Pipeable spec item produced by the registration-typed `annotation.<kind>(...)` builder. */
153
+ declare interface AnnotationItem {
246
154
  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
- } | {
270
- type: 'annotation';
271
- kind: 'comment';
272
- annotation: CommentAnnotationInput;
273
- } | {
274
- type: 'annotation';
275
- kind: 'custom';
276
155
  annotation: CustomAnnotationInput;
277
- };
156
+ }
278
157
 
279
158
  /** Recovers an annotation definition's params type — carried structurally by its `defaultParams`. */
280
159
  declare type AnnotationParamsOf<Definition> = Definition extends AnnotationDef<infer TParams> ? TParams : never;
@@ -303,38 +182,17 @@ declare interface AnnotationsCompilerInput {
303
182
  scales: CompiledScales;
304
183
  }
305
184
 
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
- */
318
185
  export declare interface AnnotationsInput {
319
- /** Labelled deltas between two data observations. The only built-in kind that anchors to data. */
320
186
  differenceArrows?: DifferenceArrowInput[];
321
- /** Shaded boxes positioned in panel fractions (`[0,1]`), not data values. */
322
187
  shapes?: ShapeInput[];
323
- /** Free-standing arrows positioned in panel fractions (`[0,1]`), not data values. */
324
188
  freeformArrows?: FreeformArrowInput[];
325
- /** Free-standing rich-text labels positioned in panel fractions (`[0,1]`), not data values. */
326
189
  textAnnotations?: TextAnnotationInput[];
327
- /** Compiles but has NO painter in `@graphysdk/react-renderer` (editor-only). Avoid here. */
328
190
  stickers?: StickerAnnotationInput[];
329
- /** Compiles but has NO painter in `@graphysdk/react-renderer` (editor-only). Avoid here. */
330
191
  pinnedNumbers?: PinnedNumberAnnotationInput[];
331
- /** Compiles but has NO painter in `@graphysdk/react-renderer` (editor-only). Avoid here. */
332
192
  comments?: CommentAnnotationInput[];
333
- /** Registered custom-annotation instances; the data-anchorable escape hatch when no built-in fits. */
334
193
  custom?: CustomAnnotationInput[];
335
194
  }
336
195
 
337
- /** Resolved form of {@link AnnotationsInput} — every field present, each entry defaulted. */
338
196
  export declare interface AnnotationsSpec {
339
197
  differenceArrows: DifferenceArrowSpec[];
340
198
  shapes: ShapeSpec[];
@@ -408,20 +266,11 @@ export declare interface AppearanceSpec {
408
266
  */
409
267
  cornerRadius: number;
410
268
  /**
411
- * How non-matched observations are de-emphasised when a highlight is active.
412
- * See {@link HighlightStyle}: `'dim'` lowers opacity, `'desaturate'` greys them out.
413
269
  * @default 'dim'
414
270
  */
415
271
  highlightStyle: HighlightStyle;
416
272
  }
417
273
 
418
- /**
419
- * Area marks — a line with the region below it filled. Same render knobs as line ({@link AreaGeomParams}).
420
- * Use `position: 'stack'` for a stacked area chart or `'fill'` for a 100%-stacked one.
421
- *
422
- * @example
423
- * pipe(createSpec({ x: 'month', y: 'sales', color: 'region' }), geom.area({ position: 'stack' }), scale.x(), scale.y(), scale.color.palette());
424
- */
425
274
  declare function area(options?: GeomOptions<'area'>): LayerInputOf<'area'>;
426
275
 
427
276
  /**
@@ -442,37 +291,21 @@ declare class AreaGeom extends Geom {
442
291
  }
443
292
 
444
293
  /**
445
- * Render parameters for `geom.area` — same knobs as {@link LineGeomParams}, but the region below the curve
446
- * is filled. Passed under `params`.
294
+ * Area-specific parameters (same rendering knobs as line, but fills under the curve)
447
295
  */
448
296
  export declare interface AreaGeomParams {
449
- /**
450
- * Outline stroke width in pixels, or `'auto'` to let the theme pick a width.
451
- * @default 'auto'
452
- */
453
297
  lineWidth: number | 'auto';
454
- /**
455
- * Interpolation method between points: `'linear'` for straight segments, `'catmull-rom'` for a smooth spline.
456
- * @default 'linear'
457
- */
458
298
  interpolate: InterpolateType;
459
- /**
460
- * How to handle missing (`null`) y-values: `'zero'` drops to zero, `'gap'` breaks the area, `'connect'`
461
- * bridges across the gap.
462
- * @default 'zero'
463
- */
464
299
  missingValues: MissingValuesType;
465
300
  }
466
301
 
467
- /** An arrow endpoint as a panel fraction (`[0,1]`, top-left origin). */
468
302
  export declare interface ArrowEndpoint {
469
- /** `[0,1]` of panel width (0 = left). */
303
+ /** 0..1 of plot width. */
470
304
  x: number;
471
- /** `[0,1]` of panel height (0 = top). */
305
+ /** 0..1 of plot height. */
472
306
  y: number;
473
307
  }
474
308
 
475
- /** Arrowhead at an endpoint: `'none'` (bare line) or `'line-arrow'` (drawn head). */
476
309
  export declare type ArrowheadStyle = 'none' | 'line-arrow';
477
310
 
478
311
  export declare type ArrowLineStyle = 'solid' | 'dashed';
@@ -505,11 +338,8 @@ declare interface Axes {
505
338
  * Groups all axis-related settings per axis.
506
339
  */
507
340
  declare interface AxesConfig {
508
- /** Configuration for the horizontal (x) axis. */
509
341
  x: XAxisConfig;
510
- /** Configuration for the primary vertical (y) axis. */
511
342
  y: YAxisConfig;
512
- /** Configuration for the secondary y axis, present only on dual-axis charts. */
513
343
  ySecondary?: YAxisConfig;
514
344
  }
515
345
 
@@ -585,9 +415,7 @@ export declare interface AxisTickCandidate {
585
415
  * Configuration for a single axis's ticks
586
416
  */
587
417
  declare interface AxisTicksConfig {
588
- /** Whether tick marks and their labels are drawn for this axis. */
589
418
  isVisible: boolean;
590
- /** Which ticks to label — see {@link AxisLabelMode} (`'auto'` = all, `'edges'` = first/last only). */
591
419
  mode: AxisLabelMode;
592
420
  }
593
421
 
@@ -618,14 +446,6 @@ export declare type BackgroundSpec = {
618
446
  color?: string;
619
447
  };
620
448
 
621
- /**
622
- * Bar/column marks. Drives most categorical charts: plain, stacked (`position: 'stack'`), grouped
623
- * (`'dodge'`), 100%-stacked (`'fill'`), horizontal (add `coord.flip()`), and pie/donut (`position: 'fill'`
624
- * inside `coord.polar({ theta: 'y' })`). No render `params`.
625
- *
626
- * @example
627
- * pipe(createSpec({ x: 'quarter', y: 'sales', color: 'region' }), geom.bar({ position: 'stack' }), scale.x(), scale.y(), scale.color.palette());
628
- */
629
449
  declare function bar(options?: GeomOptions<'bar'>): LayerInputOf<'bar'>;
630
450
 
631
451
  /**
@@ -676,68 +496,27 @@ declare interface BarOptions {
676
496
  }
677
497
 
678
498
  /**
679
- * Params shared by every coordinate system. Axis limits clamp the displayed range
680
- * after scaling.
499
+ * Base params shared by all coordinate systems
681
500
  */
682
501
  declare interface BaseCoordParams {
683
502
  /**
684
- * Fixed x-axis range as `[min, max]` in data units, or `null` to auto-fit from data.
685
- * @default null
503
+ * Limits for x-axis [min, max]
686
504
  */
687
505
  xLimits: [number, number] | null;
688
506
  /**
689
- * Fixed y-axis range as `[min, max]` in data units, or `null` to auto-fit from data.
690
- * @default null
507
+ * Limits for y-axis [min, max]
691
508
  */
692
509
  yLimits: [number, number] | null;
693
510
  }
694
511
 
695
- /**
696
- * Options accepted by every `geom.*` builder. All fields are optional; each builder fills defaults during
697
- * resolution. The generic `T` is the per-geom `params` shape so `geom.line` accepts {@link LineGeomParams}
698
- * while `geom.bar` accepts none.
699
- */
700
512
  declare interface BaseGeomOptions<T extends GeomParams> {
701
- /**
702
- * Layer-level aesthetic overrides, shallow-merged OVER the spec-level mapping for this layer only.
703
- * The place to retarget a channel per layer in a combo (`geom.line({ aes: { y: 'margin' } })`) or to pin a
704
- * constant (`aes: { y: { value: 2500 } }` for a reference line).
705
- */
706
513
  aes?: AesMapping;
707
- /**
708
- * Statistical transform applied to this layer's data before positioning. `'identity'` (default) plots rows
709
- * as-is; `'count'` tallies observations per x; `stat.mean()` collapses to a single mean-of-`y` observation
710
- * (average line); `stat.smooth({ method })` fits a regression curve (trendline).
711
- * @default 'identity'
712
- */
713
- stat?: StatLayerInput | StatLayerInput[];
714
- /**
715
- * How sibling marks sharing an x position are arranged. `'identity'` overlaps them; `'stack'` stacks by
716
- * `color`; `'dodge'` places them side by side; `'fill'` stacks then normalises each column to 100% (also
717
- * the basis of pie/donut under `coord.polar`). Default is per-geom: `area` → `'stack'`, `bar` → `'dodge'`,
718
- * `point`/`line`/`rule` → `'identity'`.
719
- */
514
+ stat?: StatName | StatInput;
720
515
  position?: PositionType;
721
- /**
722
- * Which Y axis this layer binds to. `'secondary'` puts it on the right-hand axis for dual-axis combos
723
- * (pair with `scale.ySecondary()`); the layer still maps to the `y` channel.
724
- * @default 'primary'
725
- */
726
516
  yScaleType?: YScaleType;
727
- /** Geom-specific render knobs — static styling only (widths, colors, interpolation), never data channels. */
728
517
  params?: Partial<T>;
729
- /**
730
- * Ordered transforms applied to this layer's view of the data, on top of the spec-level transforms. Use
731
- * when this geom needs a different data shape than its siblings.
732
- */
733
518
  transforms?: TransformInput[];
734
- /**
735
- * When `false`, the layer is excluded from hover hit-detection — set it on non-data overlays like
736
- * average and trend lines so they don't steal the tooltip. Defaults to `true` for all geoms except `rule`,
737
- * which defaults to `false`.
738
- */
739
519
  interactive?: boolean;
740
- /** Per-observation value labels drawn on the marks. Off by default; see {@link DataLabelsInput}. */
741
520
  dataLabels?: DataLabelsInput;
742
521
  }
743
522
 
@@ -929,12 +708,6 @@ declare type BuiltinParams<G extends string> = G extends GeomName ? Extract<Buil
929
708
  geom: G;
930
709
  }>['params'] : Record<string, unknown>;
931
710
 
932
- /***************************************************************
933
- * Transform Input
934
- ***************************************************************/
935
- /** The built-in transforms; their `transformType` literals form the closed {@link TransformType}. */
936
- declare type BuiltinTransformInput = ReshapeTransformInput | FilterTransformInput | SortTransformInput | AggregateTransformInput | ConstantTransformInput;
937
-
938
711
  /**
939
712
  * Caching decorator for any TextMeasurer implementation.
940
713
  *
@@ -1078,17 +851,6 @@ export declare interface CommandApplyResult {
1078
851
  readonly revert: Command;
1079
852
  }
1080
853
 
1081
- /**
1082
- * Descriptor that knows how to deserialize a specific command type.
1083
- * Each concrete command co-locates its descriptor alongside the command class.
1084
- *
1085
- * Serialization is handled uniformly by the registry via `Command.params`.
1086
- */
1087
- declare interface CommandDescriptor<TParams extends Record<string, unknown> = Record<string, unknown>> {
1088
- readonly type: string;
1089
- deserialize: (params: TParams, metadata: CommandMetadata) => Command;
1090
- }
1091
-
1092
854
  /**
1093
855
  * Unique identifier for commands.
1094
856
  */
@@ -1108,33 +870,6 @@ export declare interface CommandMetadata {
1108
870
  readonly author: string;
1109
871
  }
1110
872
 
1111
- /**
1112
- * Central registry mapping command types to their serialization descriptors.
1113
- */
1114
- export declare class CommandRegistry {
1115
- private readonly descriptors;
1116
- /**
1117
- * Register a command descriptor. Throws if the type is already registered.
1118
- */
1119
- register<TParams extends Record<string, unknown>>(descriptor: CommandDescriptor<TParams>): void;
1120
- /**
1121
- * Serialize a command to its wire format.
1122
- */
1123
- serialize(command: Command): SerializedCommand;
1124
- /**
1125
- * Deserialize a command from its wire format.
1126
- */
1127
- deserialize(data: SerializedCommand): Command;
1128
- /**
1129
- * Get all registered command type names.
1130
- */
1131
- getRegisteredTypes(): string[];
1132
- private getDescriptor;
1133
- }
1134
-
1135
- /** Default singleton registry instance. */
1136
- export declare const commandRegistry: CommandRegistry;
1137
-
1138
873
  /**
1139
874
  * Event types emitted by CommandStackManager.
1140
875
  */
@@ -1254,9 +989,6 @@ export declare interface CommandStackSnapshot {
1254
989
  * Comment annotation: a marker dot pinned to a single observation, carrying
1255
990
  * rich-text content. The renderer's mini view shows a truncated comment; hover
1256
991
  * reveals the full text.
1257
- *
1258
- * NO PAINTER in `@graphysdk/react-renderer` — this compiles but never draws there (it renders only in
1259
- * the editor's legacy engine). Don't reach for it when authoring for the React renderer.
1260
992
  */
1261
993
  declare interface CommentAnnotationInput {
1262
994
  id?: string;
@@ -1264,7 +996,6 @@ declare interface CommentAnnotationInput {
1264
996
  content: RichTextContent;
1265
997
  }
1266
998
 
1267
- /** Resolved form of {@link CommentAnnotationInput} — defaults applied, anchor normalised. */
1268
999
  declare interface CommentAnnotationSpec {
1269
1000
  id: string;
1270
1001
  anchor: ObservationAnchor;
@@ -1383,25 +1114,10 @@ export declare interface CompiledFreeformArrow {
1383
1114
  hasStickerStyle: boolean;
1384
1115
  }
1385
1116
 
1386
- /**
1387
- * What {@link Geom.compile} returns the reparameterised data plus any mapping the geom injects.
1388
- * Everything here must be JSON-serialisable (it rides in the compiled spec): emit data columns and
1389
- * plain mapping values only — no closures, no class instances.
1390
- */
1391
- export declare interface CompiledGeom {
1392
- /**
1393
- * The reparameterised dataset: the input dataset with the position columns the mark owns added. Write
1394
- * each through `variableFor(axis, role | name)` — never a literal column string like `'yMin'` — so the
1395
- * value readers and the coord projection find them. A geom writes only the columns it owns; the mapper
1396
- * scales any `scalar` channel that declares an `aes` source in place from the author's mapping.
1397
- */
1117
+ declare interface CompiledGeom {
1118
+ /** The reparameterized dataset (may have new computed variables) */
1398
1119
  data: Dataset;
1399
- /**
1400
- * Mapping overrides the geom injects, merged over the layer's mapping. The common case is attaching a
1401
- * scale a mark needs but the author never mapped — e.g. injecting `{ y: { variable } }` so a price
1402
- * scale forms for an OHLC mark whose extent comes from a y-interval. Return `{}` to inject nothing;
1403
- * never echo the author's own aesthetics back here.
1404
- */
1120
+ /** Any mapping overrides produced by the geom */
1405
1121
  mapping: AesMapping;
1406
1122
  /**
1407
1123
  * Extra single-observation tooltip rows this geom contributes (e.g. OHLC). The compiler derives
@@ -1624,7 +1340,7 @@ export declare interface CompiledSpec {
1624
1340
  annotations: CompiledAnnotations;
1625
1341
  }
1626
1342
 
1627
- export declare interface CompiledStat {
1343
+ declare interface CompiledStat {
1628
1344
  /** The transformed dataset. */
1629
1345
  data: Dataset;
1630
1346
  /** Any mapping overrides produced by the stat (e.g., `y` → `'count'` for `CountStat`). */
@@ -1839,37 +1555,7 @@ declare interface ComputeFreeformArrowParams {
1839
1555
  }
1840
1556
 
1841
1557
  /**
1842
- * Pipeable spec item carrying chart-level configuration. Every group is
1843
- * optional; only the keys you set override the resolved defaults. Accepts:
1844
- *
1845
- * - `content`: titles and attribution — `title` / `subtitle` / `caption`
1846
- * (each a {@link TextContent}) plus `source` ({@link SourceContent}), each
1847
- * paired with an `isXVisible` toggle.
1848
- * - `legend`: `{ position }` — see {@link LegendPosition}.
1849
- * - `axes`: per-axis `{ x, y, ySecondary }` overrides, e.g. `{ label }`.
1850
- * - `numberFormat`: chart-wide number formatting — see {@link NumberFormatConfig}.
1851
- * - `headline`: big-number summary figure — `show` / `compareWith` / `size` /
1852
- * `position` (see {@link HeadlineShow}, highlights-headlines.md).
1853
- * - `appearance`: render-only styling — `textScale`, `highlightStyle`,
1854
- * `background`, `border`, `cornerRadius` (see {@link AppearanceSpec}).
1855
- *
1856
- * @example
1857
- * import { pipe, createSpec, geom, scale, config } from '@graphysdk/viz-engine';
1858
- *
1859
- * pipe(
1860
- * createSpec({ x: 'quarter', y: 'revenue', color: 'region' }),
1861
- * geom.bar({ position: 'stack' }),
1862
- * scale.x(),
1863
- * scale.y(),
1864
- * config({
1865
- * content: { title: 'Quarterly revenue by region', source: { label: 'Finance', url: 'https://…' } },
1866
- * legend: { position: 'top' },
1867
- * axes: { y: { label: 'Revenue ($)' } },
1868
- * numberFormat: { decimals: 0, abbreviation: 'auto', prefix: '$' },
1869
- * headline: { show: 'total' },
1870
- * appearance: { highlightStyle: 'dim' },
1871
- * })
1872
- * );
1558
+ * Create a custom configuration
1873
1559
  */
1874
1560
  export declare function config(options: ConfigInput): ConfigItem;
1875
1561
 
@@ -1886,20 +1572,8 @@ declare interface ConfigCompilerInput {
1886
1572
  scales: CompiledScales;
1887
1573
  }
1888
1574
 
1889
- /**
1890
- * Author-facing argument to `config(...)`: a deep-partial of {@link ConfigSpec}.
1891
- * Any omitted group or field falls back to its resolved default.
1892
- */
1893
1575
  declare type ConfigInput = Omit<DeepPartial<ConfigSpec>, 'legend' | 'content'> & {
1894
- /**
1895
- * Legend overrides. Overridden from the deep-partial default so it accepts the
1896
- * flat {@link LegendConfigInput} (`{ position, display }`) rather than a nested partial.
1897
- */
1898
1576
  legend?: LegendConfigInput;
1899
- /**
1900
- * Content overrides. Overridden from the deep-partial default so titles/source
1901
- * accept the author-friendly {@link ContentInput} shape (strings or rich objects).
1902
- */
1903
1577
  content?: ContentInput;
1904
1578
  };
1905
1579
 
@@ -1907,38 +1581,22 @@ declare type ConfigInput = Omit<DeepPartial<ConfigSpec>, 'legend' | 'content'> &
1907
1581
  * Config specification with type tag
1908
1582
  */
1909
1583
  declare interface ConfigItem {
1910
- /** Discriminant marking this as a config item in a pipeable spec. */
1911
1584
  type: 'config';
1912
- /** The author-supplied partial configuration to merge over the defaults. */
1913
1585
  config: ConfigInput;
1914
1586
  }
1915
1587
 
1916
1588
  /**
1917
- * Fully-resolved chart configuration: every group present with defaults
1918
- * applied. This is the shape carried on a compiled spec; authors pass the
1919
- * partial {@link ConfigInput} to `config(...)` instead.
1589
+ * Feature configuration with resolved defaults.
1590
+ * All fields are required and always populated after resolution.
1920
1591
  */
1921
1592
  export declare interface ConfigSpec {
1922
- /**
1923
- * Locale used to interpret raw string values into numbers/dates (e.g. which
1924
- * thousands/decimal separators to expect). Acts as the fallback for output
1925
- * formatting when no separate `formattingLocale` is supplied.
1926
- * @default 'en-US'
1927
- */
1928
1593
  parsingLocale: Locale;
1929
- /** Legend placement and display mode. */
1930
1594
  legend: LegendConfig;
1931
- /** Per-axis settings for the x, y, and optional secondary y axes. */
1932
1595
  axes: AxesConfig;
1933
- /** Plot panel framing (the box drawn around the data area). */
1934
1596
  panel: PanelConfig;
1935
- /** Big-number summary figure shown above or inside the chart. */
1936
1597
  headline: HeadlineConfig;
1937
- /** Chart-wide number formatting applied by the renderer to every numeric value. */
1938
1598
  numberFormat: NumberFormatConfig;
1939
- /** Titles, subtitle, caption, and source attribution. */
1940
1599
  content: ContentConfig;
1941
- /** Render-only styling: text scale, background, border, corner radius, highlight style. */
1942
1600
  appearance: AppearanceSpec;
1943
1601
  }
1944
1602
 
@@ -1966,20 +1624,15 @@ declare interface ConstantMappingCompilerOutput {
1966
1624
  /***************************************************************
1967
1625
  * Constant Transform
1968
1626
  ***************************************************************/
1969
- /**
1970
- * Options for `transform.constant` — adds a new variable with the same value on every observation.
1971
- * Useful to synthesize a constant axis or a single-category grouping variable.
1972
- */
1973
1627
  declare interface ConstantOptions {
1974
- /** Name of the new variable to add. */
1628
+ /** The name of the new variable. */
1975
1629
  variableName: VariableName;
1976
- /** Data type of the new variable. */
1630
+ /** The type of the new variable. */
1977
1631
  type: DataType;
1978
- /** The constant value assigned to every observation. */
1632
+ /** The constant value to assign to every observation. */
1979
1633
  value: DataValue;
1980
1634
  }
1981
1635
 
1982
- /** Add-a-constant-column transform produced by `transform.constant`. */
1983
1636
  declare interface ConstantTransformInput {
1984
1637
  type: 'transform';
1985
1638
  transformType: 'constant';
@@ -2009,29 +1662,17 @@ declare interface Content {
2009
1662
  * hide cycles without losing the text the user typed.
2010
1663
  */
2011
1664
  export declare interface ContentConfig {
2012
- /** Main chart title. `null` = unset. */
2013
1665
  title: TextContent | null;
2014
- /** @default true */
2015
1666
  isTitleVisible: boolean;
2016
- /** Secondary line shown under the title. `null` = unset. */
2017
1667
  subtitle: TextContent | null;
2018
- /** @default true */
2019
1668
  isSubtitleVisible: boolean;
2020
- /** Explanatory note shown below the plot. `null` = unset. */
2021
1669
  caption: TextContent | null;
2022
- /** @default false */
2023
1670
  isCaptionVisible: boolean;
2024
- /** Data-source attribution shown under the caption. `null` = unset. */
2025
1671
  source: SourceContent | null;
2026
- /** @default false */
2027
1672
  isSourceVisible: boolean;
2028
1673
  }
2029
1674
 
2030
- /**
2031
- * Author-facing `content` argument to `config(...)`: all fields optional.
2032
- * Setting a text slot does not show it unless the matching `isXVisible` flag is
2033
- * also true (title and subtitle default visible; caption and source default hidden).
2034
- */
1675
+ /** Content input — all fields optional. */
2035
1676
  declare type ContentInput = Partial<ContentConfig>;
2036
1677
 
2037
1678
  declare type ContinuousScaleInput = {
@@ -2117,60 +1758,27 @@ declare type ContinuousScaleSpec = Required<ContinuousScaleInput>;
2117
1758
  */
2118
1759
  export declare function convertSpecToInput(spec: Spec): SpecInput;
2119
1760
 
2120
- /**
2121
- * Coordinate-system builder. A coord is a geom-agnostic projection applied AFTER scaling
2122
- * that remaps the already-scaled `[0,1]` positions of any geom; it changes neither the data,
2123
- * the scales, nor the chart's tier. Pipe at most one onto a spec — cartesian is assumed when
2124
- * none is given.
2125
- *
2126
- * - `cartesian` — standard x→horizontal, y→vertical (the default).
2127
- * - `flip` — swaps the x and y axes; the idiom for horizontal bars and long category labels.
2128
- * - `polar` — wraps x/y around a centre; `theta` selects the angle aesthetic and the other
2129
- * becomes the radius. The basis for pie, donut, and radar charts.
2130
- *
2131
- * @example
2132
- * import { pipe, createSpec, geom, scale, coord } from '@graphysdk/viz-engine';
2133
- *
2134
- * // Donut: stacked value → angle, innerRadius > 0 carves the hole
2135
- * pipe(
2136
- * createSpec({ x: '', y: 'spend', color: 'department' }),
2137
- * geom.bar({ position: 'fill' }),
2138
- * coord.polar({ theta: 'y', innerRadius: 0.55 }),
2139
- * scale.x(),
2140
- * scale.y(),
2141
- * scale.color.palette()
2142
- * );
2143
- */
2144
1761
  export declare const coord: {
2145
1762
  /**
2146
- * Standard cartesian (x→horizontal, y→vertical) coordinate system. This is the default
2147
- * when no coord is piped onto the spec; declare it explicitly only to set axis limits.
1763
+ * Standard cartesian (x-y) coordinate system. This is the default if no coord is specified.
2148
1764
  *
2149
1765
  * @example coord.cartesian() // auto-scaled axes
2150
- * @example coord.cartesian({ yLimits: [0, 100] }) // fixed y-axis range
1766
+ * @example coord.cartesian({ yLimits: [0, 100] }) // fixed y-axis
2151
1767
  */
2152
1768
  cartesian: (params?: Partial<CartesianCoordParams>) => CartesianCoordInput;
2153
1769
  /**
2154
- * Flipped cartesian coordinates — swaps the x and y axes so the x aesthetic runs
2155
- * vertically and y runs horizontally. The idiom for horizontal bar charts and for
2156
- * long category labels. The mapping stays the same; only the on-screen orientation flips.
1770
+ * Flipped cartesian coordinates — swaps x and y axes.
1771
+ * Useful for horizontal bar charts or when category labels are long.
2157
1772
  *
2158
- * @example coord.flip() // horizontal bars from a vertical-bar spec
1773
+ * @example coord.flip() // horizontal bars
2159
1774
  */
2160
1775
  flip: (params?: Partial<FlipCoordParams>) => FlipCoordInput;
2161
1776
  /**
2162
- * Polar coordinate system — wraps the scaled positions around a centre, mapping one
2163
- * aesthetic to the angle (theta) and the other to the radius (scaled into
2164
- * `[innerRadius, 1]`). `theta` defaults to `'x'`.
2165
- *
2166
- * - Pie / donut: `geom.bar({ position: 'fill' })` with `theta: 'y'` (stacked value → angle);
2167
- * set `innerRadius > 0` for a donut.
2168
- * - Radar / spider: `geom.line` or `geom.point` with `theta: 'x'` over a discrete x axis
2169
- * (one evenly-spaced spoke per category).
1777
+ * Polar coordinate system — maps data to angle (theta) and radius.
1778
+ * Used for pie charts, donut charts, and radar/radial visualizations.
2170
1779
  *
2171
- * @example coord.polar({ theta: 'y' }) // pie: stacked value → angle
2172
- * @example coord.polar({ theta: 'y', innerRadius: 0.5, startAngle: 90 }) // donut rotated 90°
2173
- * @example coord.polar({ theta: 'x' }) // radar: category → spoke angle
1780
+ * @example coord.polar() // pie chart
1781
+ * @example coord.polar({ innerRadius: 0.5 }) // donut chart
2174
1782
  */
2175
1783
  polar: (params?: Partial<PolarCoordParams>) => PolarCoordInput;
2176
1784
  };
@@ -2189,10 +1797,7 @@ declare class CoordCompiler {
2189
1797
  }
2190
1798
 
2191
1799
  /**
2192
- * A coordinate system produced by the `coord` builder, before resolution.
2193
- * A coord is a geom-agnostic projection applied AFTER scaling: it remaps the already-scaled
2194
- * `[0,1]` positions of any geom without touching the data, the scales, or the chart's tier.
2195
- * One coord per spec; defaults to cartesian when none is piped on.
1800
+ * Discriminated union of all coordinate input specs (user-provided, optional params).
2196
1801
  */
2197
1802
  declare type CoordInput = CartesianCoordInput | FlipCoordInput | PolarCoordInput;
2198
1803
 
@@ -2216,7 +1821,7 @@ declare type CoordSetupResult = {
2216
1821
  };
2217
1822
 
2218
1823
  /**
2219
- * A fully resolved coordinate system (params defaulted) as it appears on the compiled spec.
1824
+ * Discriminated union of all resolved coordinate specs (params fully defaulted).
2220
1825
  */
2221
1826
  declare type CoordSpec = CartesianCoordSpec | FlipCoordSpec | PolarCoordSpec;
2222
1827
 
@@ -2259,7 +1864,7 @@ declare interface CoordTransformInput {
2259
1864
  * - `'polar'` — Polar coordinates for pie, radar, and radial charts
2260
1865
  * - `'flip'` — Cartesian with x and y axes swapped
2261
1866
  */
2262
- export declare type CoordType = 'cartesian' | 'polar' | 'flip';
1867
+ declare type CoordType = 'cartesian' | 'polar' | 'flip';
2263
1868
 
2264
1869
  declare function count(): CountStatSpec;
2265
1870
 
@@ -2275,27 +1880,12 @@ export declare const createAlphaValueReader: (data: Dataset, mapping: AesMapping
2275
1880
  export declare const createColorValueReader: (data: Dataset, mapping: AesMapping) => (observation: Observation) => DataValue;
2276
1881
 
2277
1882
  /**
2278
- * Create command metadata with defaults.
2279
- */
2280
- export declare function createCommandMetadata(options: CreateCommandMetadataOptions): CommandMetadata;
2281
-
2282
- declare interface CreateCommandMetadataOptions {
2283
- id?: string;
2284
- timestamp?: number;
2285
- description: string;
2286
- author?: string;
2287
- }
2288
-
2289
- /**
2290
- * Builds a compiler instance. Pass `geoms` / `stats` / `transforms` to register custom (or override
2291
- * built-in) definitions per-instance — there is no global registry to mutate, so injected definitions
2292
- * never bleed across instances. An injected definition whose `type` matches a built-in overrides it
2293
- * (last write wins).
1883
+ * Builds a compiler instance. Pass `geoms` to register custom (or override built-in) geom
1884
+ * definitions per-instance — there is no global registry to mutate, so injected geoms never bleed
1885
+ * across instances. An injected geom whose `type` matches a built-in overrides it (last write wins).
2294
1886
  */
2295
1887
  export declare const createCompiler: (opts?: {
2296
1888
  geoms?: readonly Geom[];
2297
- stats?: readonly Stat[];
2298
- transforms?: readonly TransformStrategy[];
2299
1889
  }) => Compiler;
2300
1890
 
2301
1891
  /**
@@ -2305,27 +1895,20 @@ export declare const createCompiler: (opts?: {
2305
1895
  export declare function createEmptyHighlight(strategy: HighlightStrategy | null): CompiledLayerHighlight | null;
2306
1896
 
2307
1897
  /**
2308
- * Builds a Graphy authoring surface for a set of custom geoms, stats, transforms, and/or annotations: a
2309
- * `geom` builder merging the built-in methods with one per registered custom geom, a `stat` builder
2310
- * merging the built-in stats with one per registered custom stat, a `transform` builder merging the
2311
- * built-in transforms with one per registered custom transform, an `annotation` builder merging the
2312
- * built-in kinds with one per registered annotation kind, plus the standard `createSpec`. The 90% case
2313
- * stays the plain `import { geom, stat, transform, annotation, createSpec }`; reach for this only when
2314
- * authoring custom geoms (ADR-033), stats/transforms (ADR-039), or annotations (ADR-035). Registration is
2315
- * per-instance — geoms, stats, and transforms are injected to `createCompiler({ geoms, stats, transforms })`;
2316
- * annotations need no compile-side registry (coordinate resolution is generic), only the render plugin via
2317
- * `<GraphProvider annotationPlugins={[...]}>`.
1898
+ * 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={[...]}>`.
2318
1905
  */
2319
- export declare function createGraphyBuilder<const Geoms extends readonly Geom[] = readonly [], const Stats extends readonly StatDef[] = readonly [], const Transforms extends readonly TransformDef[] = readonly [], const Annotations extends readonly AnnotationDef[] = readonly []>(options: {
1906
+ export declare function createGraphyBuilder<const Geoms extends readonly Geom[] = readonly [], const Annotations extends readonly AnnotationDef[] = readonly []>(options: {
2320
1907
  geoms?: Geoms;
2321
- stats?: Stats;
2322
- transforms?: Transforms;
2323
1908
  annotations?: Annotations;
2324
1909
  }): {
2325
1910
  geom: typeof geom & CustomGeomBuilders<Geoms>;
2326
- stat: typeof stat & CustomStatBuilders<Stats>;
2327
- transform: typeof transform & CustomTransformBuilders<Transforms>;
2328
- annotation: typeof annotation & CustomAnnotationBuilders<Annotations>;
1911
+ annotation: CustomAnnotationBuilders<Annotations>;
2329
1912
  createSpec: typeof createSpec;
2330
1913
  };
2331
1914
 
@@ -2333,9 +1916,6 @@ export declare const createGroupValueReader: (data: Dataset, mapping: AesMapping
2333
1916
 
2334
1917
  export declare const createLabelValueReader: (data: Dataset, mapping: AesMapping) => (observation: Observation) => DataValue;
2335
1918
 
2336
- /** Opens a {@link MarkTable} builder for a heterogeneous, kind-tagged geom-layout dataset. */
2337
- export declare function createMarkTable(): MarkTable;
2338
-
2339
1919
  /**
2340
1920
  * Builds a per-observation reader for an `AestheticValue`:
2341
1921
  * - `{ value: X }` → returns `X` for every observation.
@@ -2352,32 +1932,20 @@ export declare function createSegmentYReader(layer: CompiledLayer): (observation
2352
1932
  export declare const createSizeValueReader: (data: Dataset, mapping: AesMapping) => (observation: Observation) => DataValue;
2353
1933
 
2354
1934
  /**
2355
- * Seed a spec the entry point for every chart. The first argument may be a bare {@link AesMapping}
2356
- * (`{ x, y, color, ... }`), which becomes the spec's global aesthetic mapping; any further arguments are
2357
- * pipeable spec items (geoms, scales, coords, transforms, config, ...) folded on in order. Data is supplied
2358
- * separately to `compile` / `<GraphProvider data>`.
2359
- *
2360
- * This is the builder pattern: `createSpec` seeds the mapping, then `pipe` (or extra args here) folds each
2361
- * item onto an immutable spec, accumulating layers/scales/etc. Always declare `scale.x()` / `scale.y()` for
2362
- * any position channel — they are NOT auto-inferred and yield NaN positions if omitted.
2363
- *
2364
- * @example
2365
- * import { createSpec, pipe, geom, scale } from '@graphysdk/viz-engine';
2366
- *
2367
- * // Most common: mapping first, then pipe the rest.
2368
- * const spec = pipe(createSpec({ x: 'category', y: 'revenue' }), geom.bar(), scale.x(), scale.y());
1935
+ * Create a new spec, optionally piping spec items in one call. Data is passed separately
1936
+ * to {@link compile}.
2369
1937
  *
2370
1938
  * @example
2371
- * import { createSpec, transform, mapping, geom, scale } from '@graphysdk/viz-engine';
1939
+ * When the first arg is a mapping:
1940
+ * createSpec({ x: 'date', y: 'value' })
2372
1941
  *
2373
- * // All-in-one form, clearer when a transform must run before the mapping is read.
2374
- * const spec = createSpec(
2375
- * transform.reshape({ reshape: ['revenue'], keyName: 'metric', valueName: 'amount' }),
2376
- * mapping({ x: 'month', y: 'amount', color: 'metric' }),
2377
- * geom.bar(),
2378
- * scale.x(),
2379
- * scale.y(),
2380
- * );
1942
+ * When piping spec items (more readable when chaining transforms):
1943
+ * createSpec(
1944
+ * transform.reshape({ reshape: ['revenue'], keyName: 'metric', valueName: 'amount' }),
1945
+ * mapping({ x: 'month', y: 'amount', color: 'metric' }),
1946
+ * geom.bar(),
1947
+ * scale.x(),
1948
+ * )
2381
1949
  */
2382
1950
  export declare function createSpec(...items: Array<AesMapping | SpecItem>): SpecInput;
2383
1951
 
@@ -2431,7 +1999,6 @@ declare interface CustomAnnotationOptions<TParams extends object> {
2431
1999
  id?: string;
2432
2000
  }
2433
2001
 
2434
- /** Resolved form of {@link CustomAnnotationInput} — params defaulted to `{}`, coordinates resolved. */
2435
2002
  export declare interface CustomAnnotationSpec {
2436
2003
  id: string;
2437
2004
  type: string;
@@ -2457,7 +2024,7 @@ declare type CustomGeomBuilders<Geoms extends readonly Geom[]> = {
2457
2024
  */
2458
2025
  declare interface CustomGeomOptions<TParams extends object, TAes extends string> {
2459
2026
  aes?: Partial<Record<TAes, AestheticValue>>;
2460
- stat?: StatLayerInput | StatLayerInput[];
2027
+ stat?: StatName | StatInput;
2461
2028
  position?: PositionType;
2462
2029
  yScaleType?: YScaleType;
2463
2030
  params?: Partial<TParams>;
@@ -2495,53 +2062,12 @@ declare type CustomPaletteInput = {
2495
2062
  export declare type CustomPalettesInput = Record<string, string[]>;
2496
2063
 
2497
2064
  /**
2498
- * One builder method per registered custom stat, keyed by its `type` and typed from its definition — so
2499
- * `stat.shareOfTotal(...)` exists because `shareOfTotal` was registered, with options checked against the
2500
- * stat's resolved spec. The options argument is required only when the stat declares a required option;
2501
- * a stat with no options or only optional ones is callable with none.
2502
- */
2503
- declare type CustomStatBuilders<Stats extends readonly StatDef[]> = {
2504
- [Definition in Stats[number] as Definition['type']]: Partial<StatOptionsOf<Definition>> extends StatOptionsOf<Definition> ? (options?: StatOptionsOf<Definition>) => CustomStatInput : (options: StatOptionsOf<Definition>) => CustomStatInput;
2505
- };
2506
-
2507
- /**
2508
- * A custom stat's serialised input — its registered `type` plus arbitrary plain-data options. Produced
2509
- * by the `stat.<type>(...)` method of `createGraphyBuilder({ stats })`; carried on a layer's `stat`
2510
- * field and passed through resolution unchanged (it is already a resolved spec).
2511
- */
2512
- export declare interface CustomStatInput extends StatSpecBase {
2513
- [option: string]: unknown;
2514
- }
2515
-
2516
- /**
2517
- * One builder method per registered custom transform, keyed by its `transformType` and typed from its
2518
- * definition — so `transform.topN(...)` exists because `topN` was registered, with options checked
2519
- * against the transform's options. The options argument is required only when the transform declares a
2520
- * required option; a transform with no options or only optional ones is callable with none.
2521
- */
2522
- declare type CustomTransformBuilders<Transforms extends readonly TransformDef[]> = {
2523
- [Definition in Transforms[number] as Definition['transformType']]: Partial<TransformOptionsOf<Definition>> extends TransformOptionsOf<Definition> ? (options?: TransformOptionsOf<Definition>) => CustomTransformInput : (options: TransformOptionsOf<Definition>) => CustomTransformInput;
2524
- };
2525
-
2526
- /**
2527
- * A custom transform's serialised input — its registered `transformType` plus plain-data options.
2528
- * Produced by the `transform.<type>(...)` method of `createGraphyBuilder({ transforms })`; carried on a
2529
- * spec or layer `transforms` array and dispatched by `transformType` like any built-in.
2530
- */
2531
- export declare interface CustomTransformInput {
2532
- type: 'transform';
2533
- transformType: string;
2534
- options?: Record<string, unknown>;
2535
- }
2536
-
2537
- /**
2538
- * The raw input dataset to visualize, structured as a table of `columns` + `rows`. This is what you
2539
- * hand to the compiler and to `<GraphProvider data>` — the untransformed, pre-compile shape, distinct
2540
- * from the per-observation {@link Observation} records a geom reads after compilation.
2065
+ * Data to visualize. Structured as a table.
2541
2066
  *
2542
- * The public-API contract: row values must be {@link DataValue} (string, number, Date, or null).
2543
- * Internal entry points (e.g. the dataset parser) accept a looser row type — see {@link RawData} —
2544
- * because they must defensively handle malformed input.
2067
+ * The public-API contract. Row values must be {@link DataValue} (string, number,
2068
+ * Date, or null). Internal entry points (e.g. the dataset parser) accept a
2069
+ * looser row type — see {@link RawData} — because they must defensively handle
2070
+ * malformed input.
2545
2071
  */
2546
2072
  export declare interface Data {
2547
2073
  /**
@@ -2629,11 +2155,6 @@ export declare interface DataLabelsContent {
2629
2155
  labels: PlacedDataLabel[];
2630
2156
  }
2631
2157
 
2632
- /**
2633
- * User-facing data-labels options for a layer (`geom.x({ dataLabels })`). A partial of {@link DataLabelsConfig}
2634
- * minus `labelSource` (the label source is derived from the geom, not set here); unset fields fall back to the
2635
- * config defaults. Set `{ showDataLabels: true }` to turn labels on.
2636
- */
2637
2158
  export declare type DataLabelsInput = DeepPartial<Omit<DataLabelsConfig, 'labelSource'>>;
2638
2159
 
2639
2160
  /**
@@ -2657,10 +2178,6 @@ export declare type DataLabelTextMeasurer = (kind: DataLabelKind, text: string)
2657
2178
  *
2658
2179
  * All transformation methods (filter, orderBy, addVariable etc.) return a new instance.
2659
2180
  *
2660
- * In a geom, this is what a `compile()` half reparameterises (e.g. `addVariable` to write computed
2661
- * columns) and what a render half receives as `layer.data` — iterate it (or `groupBy` it) to walk the
2662
- * compiled {@link Observation}s and read each mark's positions with the value readers.
2663
- *
2664
2181
  * @example
2665
2182
  * const data = new Dataset({
2666
2183
  * age: { type: 'numeric', values: [25, 30, 35, null] },
@@ -2928,13 +2445,9 @@ declare type DatetimeTickIntervalUnit = 'hour' | 'day' | 'week' | 'month' | 'qua
2928
2445
  /**
2929
2446
  * Recursively makes every property of `T` optional.
2930
2447
  * Unlike the built-in `Partial`, this applies to nested objects as well.
2931
- *
2932
- * An `unknown`/`any` property is treated as a leaf (kept as-is) rather than recursed into — recursing an
2933
- * open value bag like `Record<string, unknown>` would otherwise rewrite each `unknown` value to `{}`,
2934
- * making the original value un-assignable to its own `DeepPartial`.
2935
2448
  */
2936
2449
  declare type DeepPartial<T> = {
2937
- [K in keyof T]?: unknown extends T[K] ? T[K] : T[K] extends Array<infer U> ? Array<DeepPartial<U>> : NonNullable<T[K]> extends object ? DeepPartial<NonNullable<T[K]>> : T[K];
2450
+ [K in keyof T]?: T[K] extends Array<infer U> ? Array<DeepPartial<U>> : NonNullable<T[K]> extends object ? DeepPartial<NonNullable<T[K]>> : T[K];
2938
2451
  };
2939
2452
 
2940
2453
  export declare const DEFAULT_COLOR_PALETTE: string[];
@@ -2955,62 +2468,6 @@ declare type DefaultPaletteConfig = {
2955
2468
  type: 'default';
2956
2469
  };
2957
2470
 
2958
- /**
2959
- * Declares the compile-half of a custom annotation kind: its `type` name, `defaultParams`, and optional
2960
- * coordinate `arity`. There is no compile logic here — coordinate resolution is generic — so this only
2961
- * exists to type and register the kind.
2962
- *
2963
- * `TType` is a `const` type parameter so the literal kind name (`'calloutBox'`) survives to the type
2964
- * level — the registration-typed builder keys `annotation.<kind>(...)` off it, the same way
2965
- * `createGraphyBuilder` captures a geom's name. `TParams` is recovered from `defaultParams`; annotate or
2966
- * cast it (`defaultParams: {...} as CalloutBoxParams`) when a param's literal union would otherwise widen.
2967
- */
2968
- export declare function defineAnnotation<const TType extends string, TParams extends object = object>(def: {
2969
- type: TType;
2970
- defaultParams?: TParams;
2971
- coordinates?: AnnotationArity;
2972
- }): AnnotationDef<TParams, TType>;
2973
-
2974
- /**
2975
- * Declares a custom stat — the grammar-correct home for a per-group derived value (share-of-total,
2976
- * running total, rank, z-score). The `compute` receives the layer dataset, the effective mapping, the
2977
- * resolved spec, and a `column` namespacing helper; it returns the transformed dataset plus any mapping
2978
- * rebinding (`{ y: column('share') }`), exactly as the built-in `count`/`smooth` stats do.
2979
- *
2980
- * `TSpec` is the resolved spec interface (its `type` literal plus options). Declare it so the builder
2981
- * method `stat.<type>(options)` is typed; the compute reads `input.spec` narrowed to it.
2982
- *
2983
- * @example
2984
- * interface ShareStatSpec { type: 'shareOfTotal'; field: string }
2985
- * export const shareOfTotal = defineStat<ShareStatSpec>({
2986
- * type: 'shareOfTotal',
2987
- * computedColumns: ['share'],
2988
- * computedVariables: ['y'],
2989
- * compute: ({ data, spec, column }) => {
2990
- * const total = data.getValues(spec.field, { type: 'numeric', skipNulls: true }).reduce((a, b) => a + b, 0);
2991
- * const share = column('share');
2992
- * const values = data.getValues(spec.field, { type: 'numeric' }).map((v) => (v ?? 0) / total);
2993
- * return { data: data.addVariable(share, 'numeric', values), mapping: { y: share } };
2994
- * },
2995
- * });
2996
- */
2997
- export declare function defineStat<const TSpec extends StatSpecBase = StatSpecBase>(manifest: StatDefinitionManifest<TSpec>): StatDef<TSpec>;
2998
-
2999
- /**
3000
- * Declares a custom transform — mapping-blind, whole-table reshaping (top-N-with-"Other", an exotic
3001
- * fold/pivot) the five built-ins don't cover. Prefer a stat (`defineStat`) for any per-group derived
3002
- * value; reach for a transform only to reshape the table itself. The `apply` receives the dataset and
3003
- * the transform's options and returns a new dataset.
3004
- *
3005
- * @example
3006
- * interface TopNOptions { valueName: string; n: number }
3007
- * export const topN = defineTransform<'topN', TopNOptions>({
3008
- * transformType: 'topN',
3009
- * apply: (data, { valueName }) => data.orderBy(valueName, 'desc'), // …keep first n, fold rest into "Other"…
3010
- * });
3011
- */
3012
- export declare function defineTransform<const TType extends string, TOptions extends object = object>(manifest: TransformDefinitionManifest<TType, TOptions>): TransformDef<TType, TOptions>;
3013
-
3014
2471
  declare interface DifferenceArrowDimensions {
3015
2472
  /** Gap between the arrow start point and its anchored observation. */
3016
2473
  arrowStartGap: number;
@@ -3037,34 +2494,25 @@ declare interface DifferenceArrowDimensions {
3037
2494
  }
3038
2495
 
3039
2496
  /**
3040
- * A labelled delta drawn between two data observations — the only built-in annotation that anchors to
3041
- * DATA. Both endpoints are observation anchors (main-axis value + series), so the arrow snaps to the
3042
- * dataset and survives resize. Only drawn under a cartesian coordinate system. `size`, `color` and
3043
- * `labelCrossPosition` are defaulted by the resolver.
2497
+ * User-facing difference-arrow input. `size`, `color` and `labelCrossPosition`
2498
+ * are defaulted by the resolver.
3044
2499
  */
3045
2500
  export declare interface DifferenceArrowInput {
3046
2501
  id?: string;
3047
- /** Observation the arrow starts from. */
3048
2502
  start: ObservationAnchorInput;
3049
- /** Observation the arrow points to. */
3050
2503
  end: ObservationAnchorInput;
3051
- /** Which delta the label reports. */
3052
2504
  label: DifferenceArrowLabelKind;
3053
- /** Arrow colour; `null`/omitted falls back to the theme default. @default null */
3054
2505
  color?: string | null;
3055
- /** @default 'small' */
3056
2506
  size?: DifferenceArrowSize;
3057
- /** Where the label sits along the arrow's cross-axis, as a `[0,1]` fraction. @default 0.5 */
3058
2507
  labelCrossPosition?: number;
3059
2508
  }
3060
2509
 
3061
- /** What the arrow's label reports about the `start → end` delta. */
3062
2510
  export declare type DifferenceArrowLabelKind = 'absolute-difference' | 'relative-difference' | 'proportion';
3063
2511
 
3064
2512
  export declare type DifferenceArrowSize = 'small' | 'medium' | 'large';
3065
2513
 
3066
2514
  /**
3067
- * Resolved form of {@link DifferenceArrowInput} defaults applied, anchors normalised.
2515
+ * Resolved difference-arrow spec with all optional fields defaulted.
3068
2516
  */
3069
2517
  export declare interface DifferenceArrowSpec {
3070
2518
  id: string;
@@ -3136,39 +2584,23 @@ export declare interface ExternalMeasurements {
3136
2584
  footerSize: BoxSize;
3137
2585
  }
3138
2586
 
3139
- /**
3140
- * Extracts the constant value from a `{ value }` mapping. Returns undefined for variable mappings.
3141
- */
3142
- export declare function extractConstantValue(aestheticValue: AestheticValue | undefined): DataValue | undefined;
3143
-
3144
2587
  /** Flattens a title, subtitle, or caption to plain text for measurement and static renderers. */
3145
2588
  export declare const extractPlainText: (content: TextContent) => string;
3146
2589
 
3147
- /**
3148
- * Extracts the variable name from an AestheticValue.
3149
- * Returns the variable name for string shorthands and { variable } mappings.
3150
- * Returns null for constant { value } mappings or undefined values.
3151
- */
3152
- export declare function extractVariableName(aestheticValue: AestheticValue | undefined): VariableName | null;
3153
-
3154
2590
  declare function filter(options: FilterOptions): FilterTransformInput;
3155
2591
 
3156
2592
  /***************************************************************
3157
2593
  * Filter Transform
3158
2594
  ***************************************************************/
3159
- /**
3160
- * Options for `transform.filter` — keeps only observations where `variableName <operator> value`.
3161
- */
3162
2595
  declare interface FilterOptions {
3163
2596
  /** The variable to filter on. */
3164
2597
  variableName: VariableName;
3165
- /** Comparison operator: `'eq'` | `'neq'` | `'gt'` | `'gte'` | `'lt'` | `'lte'`. */
2598
+ /** The comparison operator. */
3166
2599
  operator: ComparisonOperator;
3167
- /** The value to compare each observation's `variableName` against. */
2600
+ /** The value to compare against. */
3168
2601
  value: DataValue;
3169
2602
  }
3170
2603
 
3171
- /** Row-filtering transform produced by `transform.filter`. */
3172
2604
  declare interface FilterTransformInput {
3173
2605
  type: 'transform';
3174
2606
  transformType: 'filter';
@@ -3191,24 +2623,6 @@ export declare function findAxisGuide(guides: CompiledGuides, scaleAestheticKey:
3191
2623
  */
3192
2624
  export declare function findLegendForAesthetic(guides: CompiledGuides, aesthetic: AestheticKey): CompiledLegendGuide | null;
3193
2625
 
3194
- /**
3195
- * A gate fixture: a chart authored as plain data — its spec, the custom geom(s) it uses, and the rows —
3196
- * with no React. The codegen harness's compile and semantic gates load one (authored beside the geom as
3197
- * `src/<name>.fixture.ts`, exporting a `fixture`) to check that the geom compiles to finite, serialisable
3198
- * positions and that a synthetic cursor placed on each probed observation resolves hover and a localised
3199
- * tooltip. It is the rendered chart minus the renderer, so the gates run headlessly.
3200
- */
3201
- export declare interface Fixture {
3202
- /** The custom geom instance(s) to register with the compiler — the same instances the spec uses. */
3203
- geoms: readonly Geom[];
3204
- /** The spec rendered in `App.tsx`, built with `createGraphyBuilder` + `pipe`. */
3205
- spec: SpecInput;
3206
- /** Rows matching the spec's channels (OHLC for a candlestick, a node/link graph for a sankey, …). */
3207
- data: Data;
3208
- /** Observation indices the semantic gate fires a cursor at. Defaults to `[0]` when omitted. */
3209
- probes?: number[];
3210
- }
3211
-
3212
2626
  declare interface FlipCoordInput {
3213
2627
  type: 'coord';
3214
2628
  coordType: 'flip';
@@ -3325,31 +2739,23 @@ export declare interface FormattedPerGroupHeadline {
3325
2739
  }
3326
2740
 
3327
2741
  /**
3328
- * A free-standing arrow pointing at something on the panel. Both endpoints sit in panel fractions
3329
- * (`[0,1]`, top-left origin), so they re-flow with panel size but do NOT snap to a data point. Distinct
3330
- * from {@link DifferenceArrowInput}, which anchors to dataset observations.
2742
+ * Freeform arrow annotation. Endpoints sit in plot-fractional coordinates
2743
+ * (0..1), so they re-flow with panel size. Distinct from
2744
+ * {@link DifferenceArrowInput}, which anchors to dataset observations.
3331
2745
  */
3332
2746
  export declare interface FreeformArrowInput {
3333
2747
  id?: string;
3334
- /** Tail endpoint. */
3335
2748
  start: ArrowEndpoint;
3336
- /** Head endpoint (the end pointed at). */
3337
2749
  end: ArrowEndpoint;
3338
- /** `null` falls back to the theme `defaultAnnotationArrowStroke`. @default null */
2750
+ /** null falls back to the theme `defaultAnnotationArrowStroke`. */
3339
2751
  color?: string | null;
3340
- /** @default 'medium' */
3341
2752
  thickness?: ArrowThickness;
3342
- /** Arrowhead at the `start` (tail) endpoint. @default 'none' */
3343
2753
  startArrowheadStyle?: ArrowheadStyle;
3344
- /** Arrowhead at the `end` (head) endpoint. @default 'line-arrow' */
3345
2754
  endArrowheadStyle?: ArrowheadStyle;
3346
- /** @default 'solid' */
3347
2755
  lineStyle?: ArrowLineStyle;
3348
- /** Apply the editor's hand-drawn "sticker" styling. @default false */
3349
2756
  hasStickerStyle?: boolean;
3350
2757
  }
3351
2758
 
3352
- /** Resolved form of {@link FreeformArrowInput} — defaults applied. */
3353
2759
  export declare interface FreeformArrowSpec {
3354
2760
  id: string;
3355
2761
  start: ArrowEndpoint;
@@ -3386,7 +2792,7 @@ declare type GenerateTicksOptions = {
3386
2792
  * empty default and keep their typed params through the spec builder's static surface; a custom geom
3387
2793
  * names its params type and declares matching {@link defaultParams}.
3388
2794
  */
3389
- export declare abstract class Geom<TParams extends object = object> {
2795
+ declare abstract class Geom<TParams extends object = object> {
3390
2796
  /**
3391
2797
  * The aesthetics an author must map for this geom. Built-ins list closed aesthetic keys
3392
2798
  * (`['x','y']`); a custom geom may also list open channel names (a box plot's `min`/`q1`/…) that it
@@ -3478,13 +2884,6 @@ export declare abstract class Geom<TParams extends object = object> {
3478
2884
  * renderer how to place the annotation.
3479
2885
  */
3480
2886
  resolveAnchorPosition(_observation: Observation, _coordSystem: CoordSystem): AnchorPosition | null;
3481
- /**
3482
- * Reparameterizes the stat-transformed data into the shape this geom's geometry needs, the central
3483
- * hook a custom geom implements. Receives the transformed dataset, effective mapping and geom params;
3484
- * returns the dataset with any computed position variables added (e.g. a bar's `xMin`/`xMax`/`yMin`
3485
- * interval), the mapping overrides the geom injects, and any extra tooltip rows it contributes. The
3486
- * compile pipeline runs this per layer before the position and visual mappers read the result.
3487
- */
3488
2887
  abstract compile(input: GeomCompilerInput): CompiledGeom;
3489
2888
  /**
3490
2889
  * Validates the layer's mapping against invariants specific to this geom (e.g. a rule needs exactly
@@ -3494,25 +2893,6 @@ export declare abstract class Geom<TParams extends object = object> {
3494
2893
  validateMapping?(input: GeomMappingValidationInput): ValidationIssue[];
3495
2894
  }
3496
2895
 
3497
- /**
3498
- * The built-in geom builders. Each is called with one {@link BaseGeomOptions} object and returns a pipeable
3499
- * layer that `pipe`/`createSpec` folds onto the spec. Compose several to layer marks (e.g. bars + a trend
3500
- * line). The five marks: `point` (scatter/bubble), `line`, `area`, `bar` (also pie/donut in polar), and
3501
- * `rule` (a constant or data-driven reference line).
3502
- *
3503
- * @example
3504
- * import { createSpec, pipe, geom, scale, config } from '@graphysdk/viz-engine';
3505
- *
3506
- * // Multi-series line; mapping `color` to a column splits series and adds a legend.
3507
- * const spec = pipe(
3508
- * createSpec({ x: 'month', y: 'sales', color: 'region' }),
3509
- * geom.line(),
3510
- * scale.x(),
3511
- * scale.y(),
3512
- * scale.color.palette(),
3513
- * config({ legend: { position: 'top' } }),
3514
- * );
3515
- */
3516
2896
  export declare const geom: {
3517
2897
  point: typeof point;
3518
2898
  line: typeof line;
@@ -3572,31 +2952,12 @@ declare class GeomCompiler {
3572
2952
  resolveAnchorPosition(geomName: GeomIdentity, observation: Observation, coordSystem: CoordSystem): AnchorPosition | null;
3573
2953
  }
3574
2954
 
3575
- /**
3576
- * What {@link Geom.compile} receives. The geom reads these to compute its mark geometry and returns a
3577
- * {@link CompiledGeom}. The pipeline has already run the layer's stat and resolved its aesthetics, so
3578
- * `compile` sees finished input and only reparameterises it.
3579
- */
3580
- export declare interface GeomCompilerInput {
3581
- /**
3582
- * The dataset after stat transformation — one row per observation, columnar. Read a mapped channel's
3583
- * column with `extractVariableName(mapping[channel])`, then `data.getValues(column, { type })`; write
3584
- * computed columns with `data.addVariable` / `data.addConstantVariable` (each returns a new dataset —
3585
- * the Dataset is immutable).
3586
- */
2955
+ declare interface GeomCompilerInput {
2956
+ /** The dataset after stat transformation */
3587
2957
  data: Dataset;
3588
- /**
3589
- * The effective mapping for the layer: which data column (or constant) backs each aesthetic the author
3590
- * declared. The source of every channel column the geom reads — including the custom `aes` channels in
3591
- * {@link Geom.requiredAesthetics} (an OHLC `open`, a box plot `q1`). Read a custom channel with
3592
- * `readAesthetic(mapping, channel)`.
3593
- */
2958
+ /** The effective mapping for the layer */
3594
2959
  mapping: AesMapping;
3595
- /**
3596
- * The geom's static params, already merged over {@link Geom.defaultParams} by the builder. Render
3597
- * configuration only (widths, radii, colours) — never data columns that bind to a scale, which belong
3598
- * in `aes`. Typed as the geom's `TParams` at the call site.
3599
- */
2960
+ /** Geom-specific params */
3600
2961
  params: LayerSpec['params'];
3601
2962
  }
3602
2963
 
@@ -3625,10 +2986,8 @@ declare interface GeomMappingValidationInput {
3625
2986
  /** A built-in geom's name — the default vocabulary the spec builder offers out of the box. */
3626
2987
  export declare type GeomName = (typeof GEOM_NAMES)[number];
3627
2988
 
3628
- /** {@link BaseGeomOptions} specialised to geom `G`, so its `params` is typed to that geom's param shape. */
3629
2989
  declare type GeomOptions<G extends GeomName> = BaseGeomOptions<GeomParamsMap[G]>;
3630
2990
 
3631
- /** Union of every built-in geom's params type; the upper bound for {@link BaseGeomOptions}'s generic. */
3632
2991
  declare type GeomParams = GeomParamsMap[keyof GeomParamsMap];
3633
2992
 
3634
2993
  /**
@@ -3661,34 +3020,19 @@ declare class GeomRegistry extends Registry<string, Geom> {
3661
3020
  * data: the `label` is static text and the `variable` names a column, so the rows ride in the
3662
3021
  * serialisable compiled spec.
3663
3022
  */
3664
- export declare interface GeomTooltipRow {
3023
+ declare interface GeomTooltipRow {
3665
3024
  /** The row's label (e.g. "Open"). Static text the geom supplies. */
3666
3025
  label: string;
3667
3026
  /** The data column whose per-observation value the row displays. */
3668
3027
  variable: VariableName;
3669
3028
  }
3670
3029
 
3671
- /**
3672
- * Reads the observation's resolved opacity in `[0,1]` (0 = transparent, 1 = opaque) — pass straight to
3673
- * `fillOpacity`/`opacity`. The `alpha` aesthetic mapped through its scale. `null` when no `alpha`
3674
- * aesthetic is mapped.
3675
- */
3030
+ /** Reads the resolved alpha (opacity) value from an observation. */
3676
3031
  export declare function getAlpha(observation: Observation): NumericDataValue;
3677
3032
 
3678
- /**
3679
- * Reads a polar observation's angular extent — the x interval projected to angles. Use it to draw the
3680
- * wedge of a pie/donut slice or polar bar; pair with {@link getRadiusExtent} for the radial span.
3681
- * `startAngle`/`endAngle` are in **radians** (0 = straight up, increasing clockwise). The compiler has
3682
- * already projected the x interval under `coord.polar()`, so no manual angle math is needed.
3683
- */
3684
3033
  export declare function getAngleExtent(observation: Observation): AngleExtent;
3685
3034
 
3686
- /**
3687
- * Reads the observation's resolved fill/stroke colour as a paint-ready CSS colour string. The visual
3688
- * mapper has already run the `color` aesthetic through the colour scale, so this is the final string to
3689
- * hand to `fill`/`stroke` — no further lookup needed. `undefined` when the layer maps no `color`
3690
- * aesthetic; supply your own series colour (e.g. via `useCategoricalColor`) in that case.
3691
- */
3035
+ /** Reads the resolved color string from an observation. */
3692
3036
  export declare function getColor(observation: Observation): string | undefined;
3693
3037
 
3694
3038
  /** Reads the coordinate lying on the cross axis of the coord system. */
@@ -3702,13 +3046,6 @@ export declare function getCrossAxisCoordinate(mainAxis: MainAxis, point: XYPoin
3702
3046
  */
3703
3047
  export declare const getDifferenceArrowDimensions: (size: DifferenceArrowSize, textScale: number) => DifferenceArrowDimensions;
3704
3048
 
3705
- /**
3706
- * Reads the observation's resolved series identity: the category the `group`/`color` aesthetic placed
3707
- * it in, as a plain string. Use it to split a layer's observations into series (one polygon, line, or
3708
- * colour per group) when painting. `null` when the layer maps no grouping aesthetic — a single,
3709
- * ungrouped series. Reads the compiler-emitted `group` column, so the value survives any renaming of
3710
- * the user's grouping mapping.
3711
- */
3712
3049
  export declare const getGroup: (observation: Observation) => CategoricalDataValue;
3713
3050
 
3714
3051
  /**
@@ -3719,33 +3056,20 @@ export declare const getGroup: (observation: Observation) => CategoricalDataValu
3719
3056
  export declare const getIdentityKey: (observation: Observation) => string;
3720
3057
 
3721
3058
  /**
3722
- * Reads the observation's resolved line style (`'solid'`, `'dashed'`, …) for use as a stroke pattern.
3723
- * The `lineType` aesthetic mapped through its scale, falling back to `'solid'` when no `lineType`
3724
- * aesthetic is mapped — so this reader, unlike the others, never returns `null`.
3059
+ * Reads the resolved line type (stroke style) from an observation.
3060
+ * Falls back to `'solid'` when no `lineType` variable was derived.
3725
3061
  */
3726
3062
  export declare function getLineType(observation: Observation): LineStyleType;
3727
3063
 
3728
3064
  /** Reads the coordinate lying on the main (independent) axis of the coord system. */
3729
3065
  export declare function getMainAxisCoordinate(mainAxis: MainAxis, point: XYPoint): number;
3730
3066
 
3731
- /**
3732
- * Reads a polar observation's radial extent — the y interval projected to radii. Use it with
3733
- * {@link getAngleExtent} to draw a donut/polar-bar segment. `innerRadius`/`outerRadius` are in `[0,1]`
3734
- * (0 = centre, 1 = outer ring); `outerRadius` falls back to the `point` y radius when the observation
3735
- * carries no upper y endpoint (a pie slice, which has no inner cutout to oppose).
3736
- */
3737
3067
  export declare function getRadiusExtent(observation: Observation): RadiusExtent;
3738
3068
 
3739
- /**
3740
- * Reads the observation's resolved size in **pixels** (e.g. a point's diameter or a mark's nominal
3741
- * extent), already mapped through the `size` scale. `null` when no `size` aesthetic is mapped.
3742
- */
3069
+ /** Reads the resolved size value from an observation. */
3743
3070
  export declare function getSize(observation: Observation): NumericDataValue;
3744
3071
 
3745
- /**
3746
- * Reads the observation's resolved stroke width in **pixels** — pass straight to `strokeWidth`. The
3747
- * `strokeWidth` aesthetic mapped through its scale. `null` when no `strokeWidth` aesthetic is mapped.
3748
- */
3072
+ /** Reads the resolved stroke width value from an observation. */
3749
3073
  export declare function getStrokeWidth(observation: Observation): NumericDataValue;
3750
3074
 
3751
3075
  declare interface GetValuesOptions {
@@ -3757,61 +3081,29 @@ declare interface GetValuesOptions {
3757
3081
  distinct?: boolean;
3758
3082
  }
3759
3083
 
3760
- /**
3761
- * Reads the observation's scaled x position: the value of the `point` x channel, already mapped
3762
- * through the x scale to `[0,1]` of the panel width (0 = left edge, 1 = right edge). `null` when the
3763
- * observation has no x position. Under `coord.polar({ theta: 'x' })` this returns the vertex **angle
3764
- * in radians** instead (0 = straight up, increasing clockwise). The everyday position reader — pair
3765
- * it with {@link getY} to place a point-anchored mark.
3766
- */
3084
+ /** Reads the normalized x position from an observation. */
3767
3085
  export declare function getX(observation: Observation): NumericDataValue;
3768
3086
 
3769
- /**
3770
- * Reads the upper x endpoint of the observation's x interval, scaled to `[0,1]` of the panel width
3771
- * (1 = right edge). The right edge of a band/bar or the end of a horizontal range bar. Pairs with
3772
- * {@link getXMin}. `null` when the observation declares no x interval.
3773
- */
3087
+ /** Reads the normalized xMax (right band edge) from an observation. */
3774
3088
  export declare function getXMax(observation: Observation): NumericDataValue;
3775
3089
 
3776
- /**
3777
- * Reads the lower x endpoint of the observation's x interval, scaled to `[0,1]` of the panel width
3778
- * (0 = left edge). The left edge of a band/bar, the start of a horizontal range bar, or a body's left
3779
- * side. Pairs with {@link getXMax}; `getXMin`/`getXMax` preserve the values `compile()` wrote and are
3780
- * never re-sorted, so `getXMin` can exceed `getXMax`. `null` when the observation declares no x interval.
3781
- */
3090
+ /** Reads the normalized xMin (left band edge) from an observation. */
3782
3091
  export declare function getXMin(observation: Observation): NumericDataValue;
3783
3092
 
3784
- /**
3785
- * Reads the observation's scaled y position: the value of the `point` y channel, already mapped
3786
- * through the y scale to `[0,1]` of the panel height with a **bottom origin** (0 = bottom, 1 = top).
3787
- * SVG y grows downward, so paint with `1 - getY(...)`. `null` when the observation has no y position.
3788
- * Under polar coords this returns the **radius in `[0,1]`** (0 = centre, 1 = outer ring). See
3789
- * {@link getYRaw} to recover the pre-stack segment magnitude.
3790
- */
3093
+ /** Reads the normalized y position from an observation. */
3791
3094
  export declare function getY(observation: Observation): NumericDataValue;
3792
3095
 
3793
- /**
3794
- * Reads the upper y endpoint of the observation's y interval, scaled to `[0,1]` of the panel height
3795
- * with a **bottom origin** (1 = top; paint with `1 - getYMax(...)`). The bar top, the top of a
3796
- * candlestick wick, or the end of a vertical range/gantt span. Pairs with {@link getYMin}.
3797
- * `null` when the observation declares no y interval.
3798
- */
3096
+ /** Reads the normalized yMax (upper extent) from an observation. */
3799
3097
  export declare function getYMax(observation: Observation): NumericDataValue;
3800
3098
 
3801
- /**
3802
- * Reads the lower y endpoint of the observation's y interval, scaled to `[0,1]` of the panel height
3803
- * with a **bottom origin** (0 = bottom; paint with `1 - getYMin(...)`). The bar baseline, the bottom of
3804
- * a candlestick wick, or the start of a vertical range/gantt span. Pairs with {@link getYMax}; the pair
3805
- * preserves the values `compile()` wrote and is never re-sorted, so `getYMin` can exceed `getYMax`.
3806
- * `null` when the observation declares no y interval.
3807
- */
3099
+ /** Reads the normalized yMin (lower extent) from an observation. */
3808
3100
  export declare function getYMin(observation: Observation): NumericDataValue;
3809
3101
 
3810
3102
  /**
3811
- * Reads the observation's pre-stack segment magnitude in **original data units** (not `[0,1]`).
3812
- * Stacking position adjusters rewrite the mapped `y` to the cumulative band top and stash the segment's
3813
- * own value here, so a renderer or data label can recover what the segment contributed before stacking.
3814
- * `null` when the layer was not stacked (the column is written only when stacking along y).
3103
+ * Reads the segment value written by stacking position adjusters.
3104
+ *
3105
+ * Survives theposition-mapper untouched, so renderers can recover original-unit values
3106
+ * for stacked segments after `mapping.y` has been rewritten to the cumulative band top.
3815
3107
  */
3816
3108
  export declare function getYRaw(observation: Observation): NumericDataValue;
3817
3109
 
@@ -3952,7 +3244,7 @@ declare type GraphyPaletteVariant = 'default' | 'waterfall';
3952
3244
  * for instance. A geom declares these so the axis guide resolves grid policy from the definition
3953
3245
  * instead of a geom-keyed lookup. Every field absent means the geom imposes no policy.
3954
3246
  */
3955
- export declare interface GridPolicy {
3247
+ declare interface GridPolicy {
3956
3248
  hideGridX?: boolean;
3957
3249
  hideGridY?: boolean;
3958
3250
  hideBorder?: boolean;
@@ -4198,29 +3490,15 @@ export declare class HeuristicTextMeasurer implements TextMeasurer {
4198
3490
  }
4199
3491
 
4200
3492
  /**
4201
- * Pipeable spec item that emphasises the observations matching `predicate` and
4202
- * de-emphasises (dims or desaturates) everything else. Multiple `highlight(...)`
4203
- * calls accumulate — their matches union. The de-emphasis style is chosen
4204
- * separately via `config({ appearance: { highlightStyle: 'dim' | 'desaturate' } })`.
4205
- *
4206
- * @param predicate - which observations to emphasise (see {@link Predicate}).
4207
- * @param options - `scope` ({@link HighlightScope}, default `'data-point'`),
4208
- * `layerIndex` (target a single layer; omit to apply to all layers), and an
4209
- * optional explicit `id`.
3493
+ * Create a pipeable highlight spec item.
4210
3494
  *
4211
3495
  * @example
4212
- * import { pipe, createSpec, geom, scale, highlight } from '@graphysdk/viz-engine';
4213
- *
4214
3496
  * pipe(
4215
- * createSpec({ x: 'month', y: 'revenue', color: 'region' }),
3497
+ * createSpec(data, { x: 'month', y: 'revenue', color: 'region' }),
4216
3498
  * geom.bar(),
4217
- * scale.x(),
4218
- * scale.y(),
4219
- * // emphasise one whole series; leave other layers untouched
4220
- * highlight({ variable: 'region', eq: 'EU' }, { scope: 'series' }),
4221
- * // and every observation at or above a threshold
4222
- * highlight({ variable: 'revenue', gte: 2000 })
4223
- * );
3499
+ * highlight({ field: 'region', eq: 'EU' }),
3500
+ * highlight({ field: 'region', eq: 'US' }, { scope: 'series' }),
3501
+ * )
4224
3502
  */
4225
3503
  export declare function highlight(predicate: Predicate, options?: HighlightBuilderOptions): HighlightInput;
4226
3504
 
@@ -4370,10 +3648,10 @@ export declare class HoverEngine {
4370
3648
  */
4371
3649
  private nonInteractiveLayerIds;
4372
3650
  /**
4373
- * Render-side hit-testers registered per layer for `render-hit-test` (geom-layout) layers, keyed by
3651
+ * Render-side hit-testers registered per layer for `render-hit-test` (Tier-C) layers, keyed by
4374
3652
  * `CompiledLayer.id`. The renderer owns this map and injects it via {@link setHitTesters}; the
4375
3653
  * engine holds the live reference so a plugin mounting or updating its tester is visible at the
4376
- * next `query()` without a re-index. Empty for charts with no geom-layout geom.
3654
+ * next `query()` without a re-index. Empty for charts with no Tier-C geom.
4377
3655
  */
4378
3656
  private hitTesters;
4379
3657
  constructor({ layers, coordSystem }: HoverEngineInput);
@@ -4514,17 +3792,6 @@ declare interface InferredScaleInput {
4514
3792
 
4515
3793
  declare type InferredScaleOptions = ContinuousScaleOptions | DiscreteScaleOptions | DatetimeScaleOptions;
4516
3794
 
4517
- /**
4518
- * Recovers where a raw sub-value sits inside an already-scaled interval. Given a raw `[rawLo, rawHi]`
4519
- * pair that the compiler mapped to the scaled `[scaledLo, scaledHi]` endpoints, returns the scaled
4520
- * position of `raw` by affine interpolation. The geom-scaled trick a candlestick uses to place its open/close
4521
- * inside the scaled `[low, high]` wick without re-running the y-scale.
4522
- *
4523
- * Exact only when the scale between raw and scaled space is **linear** — both endpoints pin a straight
4524
- * line every interior value reads off. A degenerate interval (`rawLo === rawHi`) returns `scaledLo`.
4525
- */
4526
- export declare function interpolateInScaledInterval(raw: number, rawLo: number, rawHi: number, scaledLo: number, scaledHi: number): number;
4527
-
4528
3795
  /**
4529
3796
  * Curve interpolation method for lines and areas.
4530
3797
  *
@@ -4608,27 +3875,13 @@ declare interface LayerCompilerInput {
4608
3875
  */
4609
3876
  declare type LayerInput = BuiltinLayerInput | CustomLayerInput;
4610
3877
 
4611
- /**
4612
- * Geom-agnostic fields shared by every layer input, before resolution. Builders produce this shape (with
4613
- * `geom` and `params` added per geom); all fields are optional and filled with defaults during resolution.
4614
- */
4615
3878
  declare interface LayerInputBase {
4616
- /** Discriminant marking this spec item as a layer. */
4617
3879
  type: 'layer';
4618
- /** Optional stable identifier for the layer; auto-assigned during resolution when omitted. */
4619
3880
  id?: string;
4620
- /**
4621
- * Layer-level aesthetic mapping (the builder's `aes`), shallow-merged OVER the spec-level mapping for this
4622
- * layer only. Retargets a channel per layer or pins a constant via `{ y: { value } }`.
4623
- */
4624
3881
  mapping?: AesMapping;
4625
- /** Statistical transform(s) applied before positioning — a single stat or a pipeline. @default 'identity' */
4626
- stat?: StatLayerInput | StatLayerInput[];
4627
- /** How sibling marks sharing an x position are arranged (`'stack'`, `'dodge'`, `'fill'`, `'identity'`). Default is per-geom. */
3882
+ stat?: StatName | StatInput;
4628
3883
  position?: PositionType;
4629
- /** Which Y axis the layer binds to — `'secondary'` targets the right-hand axis in a dual-axis combo. @default 'primary' */
4630
3884
  yScaleType?: YScaleType;
4631
- /** Per-observation value labels drawn on the marks. @default off */
4632
3885
  dataLabels?: DataLabelsInput;
4633
3886
  /**
4634
3887
  * Ordered transforms applied to this layer's view of the data, on top of any
@@ -4643,7 +3896,6 @@ declare interface LayerInputBase {
4643
3896
  interactive?: boolean;
4644
3897
  }
4645
3898
 
4646
- /** A built-in layer input narrowed to geom `G`: the shared base plus that geom's tag and partial `params`. */
4647
3899
  declare type LayerInputOf<G extends GeomName> = LayerInputBase & {
4648
3900
  geom: G;
4649
3901
  params?: Partial<GeomParamsMap[G]>;
@@ -4654,32 +3906,18 @@ declare type LayerInputOf<G extends GeomName> = LayerInputBase & {
4654
3906
  */
4655
3907
  declare type LayerSpec = BuiltinLayerSpec | CustomLayerSpec;
4656
3908
 
4657
- /**
4658
- * Geom-agnostic fields shared by every resolved layer spec. Mirrors {@link LayerInputBase} with all fields
4659
- * required and defaults applied (`stat` resolved to {@link ResolvedStatSpec}[], `dataLabels` fully expanded).
4660
- */
4661
3909
  declare interface LayerSpecBase {
4662
- /** Discriminant marking this spec item as a layer. */
4663
3910
  type: 'layer';
4664
- /** Resolved stable identifier for the layer (always present after resolution). */
4665
3911
  id: string;
4666
- /** Resolved aesthetic mapping for this layer, merged from spec-level and layer-level inputs. */
4667
3912
  mapping: AesMapping;
4668
- /** Resolved statistical-transform pipeline (empty array means identity). */
4669
- stat: ResolvedStatSpec[];
4670
- /** Resolved arrangement of sibling marks at the same x position. */
3913
+ stat: StatSpec;
4671
3914
  position: PositionType;
4672
- /** Resolved Y-axis binding (`'primary'` or `'secondary'`). */
4673
3915
  yScaleType: YScaleType;
4674
- /** Resolved ordered transforms applied to this layer's view of the data. */
4675
3916
  transforms: TransformInput[];
4676
- /** Whether the layer participates in hover hit-detection. */
4677
3917
  interactive: boolean;
4678
- /** Resolved per-observation data-labels configuration. */
4679
3918
  dataLabels: DataLabelsConfig;
4680
3919
  }
4681
3920
 
4682
- /** A resolved built-in layer spec narrowed to geom `G`: the shared base plus that geom's tag and full `params`. */
4683
3921
  declare type LayerSpecOf<G extends GeomName> = LayerSpecBase & {
4684
3922
  geom: G;
4685
3923
  params: GeomParamsMap[G];
@@ -4715,7 +3953,7 @@ declare interface LayerValidationCheckInput {
4715
3953
  declare interface LayerValidationInput {
4716
3954
  layerId: string;
4717
3955
  geom: GeomIdentity;
4718
- stat: ResolvedStatSpec[];
3956
+ stat: StatSpec;
4719
3957
  /** `spec.mapping` merged with `layer.mapping` */
4720
3958
  effectiveMapping: AesMapping;
4721
3959
  /** Layer's dataset after its own transforms have been applied */
@@ -4754,9 +3992,6 @@ declare class LayerValidator {
4754
3992
  * without a `validateMapping` hook impose none.
4755
3993
  */
4756
3994
  private validateGeomMapping;
4757
- /** Unions the `computedVariables` of every stat in the layer's pipeline — any aesthetic computed by
4758
- * any stage is waived from the pre-stat existence/required checks. */
4759
- private collectComputedVariables;
4760
3995
  /**
4761
3996
  * Rejects a layer whose coord is absent from the geom's declared `supportedCoordTypes` (e.g. a rule
4762
3997
  * has no meaning under polar pie/donut coords). The supported set lives on the geom definition, so
@@ -4775,16 +4010,14 @@ export declare const LAYOUT_PADDING = 24;
4775
4010
  * settled after the first resolve.
4776
4011
  *
4777
4012
  * Here's the pipeline:
4778
- * 1. **Polar prep**: split cartesian from polar axes, format the polar axes whole, and derive the
4779
- * symmetric `polarMargin` their rim labels reserve (both empty/zero for a cartesian chart).
4780
- * 2. **Seed**: stamp each cartesian axis with a placeholder label so the grid has something to measure.
4781
- * 3. **Resolve v1**: first grid pass; `panel.height` is now final.
4782
- * 4. **Finalize vertical**: pick the densest candidate that fits `panel.height` for left/right
4013
+ * 1. **Seed**: stamp each axis with a placeholder label so the grid has something to measure.
4014
+ * 2. **Resolve v1**: first grid pass; `panel.height` is now final.
4015
+ * 3. **Finalize vertical**: pick the densest candidate that fits `panel.height` for left/right
4783
4016
  * axes; horizontal axes keep their seed.
4784
- * 5. **Resolve v2**: vertical edge widths now reflect final labels, so `panel.width` is final.
4785
- * 6. **Finalize horizontal**: pick the densest candidate that fits `panel.width` for top/bottom
4786
- * axes. Vertical axes carry over from step 4.
4787
- * 7. **Resolve v3**: final grid pass with all axes finalized.
4017
+ * 4. **Resolve v2**: vertical edge widths now reflect final labels, so `panel.width` is final.
4018
+ * 5. **Finalize horizontal**: pick the densest candidate that fits `panel.width` for top/bottom
4019
+ * axes. Vertical axes carry over from step 3.
4020
+ * 6. **Resolve v3**: final grid pass with all axes finalized.
4788
4021
  */
4789
4022
  export declare class LayoutCompiler {
4790
4023
  private readonly measurer;
@@ -4871,9 +4104,8 @@ declare interface Legend {
4871
4104
  */
4872
4105
  declare interface LegendConfig {
4873
4106
  /**
4874
- * Where the legend sits relative to the plot. See {@link LegendPosition} for the values;
4875
- * `'auto'` lets the renderer pick based on chart type and series count.
4876
- * @default 'auto'
4107
+ * Position of the legend
4108
+ * @default 'top'
4877
4109
  */
4878
4110
  position: LegendPosition;
4879
4111
  /**
@@ -4933,23 +4165,8 @@ declare interface LegendItemVisual {
4933
4165
  lineType?: LineStyleType;
4934
4166
  }
4935
4167
 
4936
- /**
4937
- * Where the legend sits relative to the plot, set via
4938
- * `config({ legend: { position: … } })`.
4939
- * - 'auto': let the compiler choose based on chart type (default).
4940
- * - 'right' | 'left' | 'top' | 'bottom': pin to that edge.
4941
- * - 'none': hide the legend entirely.
4942
- */
4943
4168
  declare type LegendPosition = 'auto' | 'right' | 'left' | 'top' | 'bottom' | 'none';
4944
4169
 
4945
- /**
4946
- * Line marks — connected series. One line per `group` (defaults to the `color` column). Tune the stroke via
4947
- * {@link LineGeomParams}. Pair with `stat.smooth()` for a trendline. Observations are connected in data
4948
- * order, so sort by x first.
4949
- *
4950
- * @example
4951
- * pipe(createSpec({ x: 'month', y: 'sales', color: 'region' }), geom.line(), scale.x(), scale.y(), scale.color.palette());
4952
- */
4953
4170
  declare function line(options?: GeomOptions<'line'>): LayerInputOf<'line'>;
4954
4171
 
4955
4172
  /**
@@ -4972,22 +4189,17 @@ declare class LineGeom extends Geom {
4972
4189
  }
4973
4190
 
4974
4191
  /**
4975
- * Render parameters for `geom.line`. Passed under `params`.
4192
+ * Line-specific parameters
4976
4193
  */
4977
4194
  export declare interface LineGeomParams {
4978
- /**
4979
- * Stroke width in pixels, or `'auto'` to let the theme pick a width.
4980
- * @default 'auto'
4981
- */
4982
4195
  lineWidth: number | 'auto';
4983
4196
  /**
4984
- * Interpolation method between points: `'linear'` for straight segments, `'catmull-rom'` for a smooth spline.
4197
+ * Interpolation method to use for the line.
4985
4198
  * @default 'linear'
4986
4199
  */
4987
4200
  interpolate: InterpolateType;
4988
4201
  /**
4989
- * How to handle missing (`null`) y-values: `'gap'` breaks the line, `'zero'` drops to zero, `'connect'`
4990
- * bridges across the gap.
4202
+ * How to handle missing (NULL/undefined) values.
4991
4203
  * @default 'gap'
4992
4204
  */
4993
4205
  missingValues: MissingValuesType;
@@ -5014,12 +4226,7 @@ export declare type Locale = (typeof LOCALES)[number];
5014
4226
  /** A BCP-47 string representing a supported locale. */
5015
4227
  declare const LOCALES: readonly ["en-GB", "en-US", "ar", "pt-PT"];
5016
4228
 
5017
- /**
5018
- * Boolean composition of nested predicates:
5019
- * - `and`: every sub-predicate matches.
5020
- * - `or`: at least one matches.
5021
- * - `not`: the sub-predicate does not match.
5022
- */
4229
+ /** Logical composition of any predicate. */
5023
4230
  export declare type LogicalPredicate = {
5024
4231
  and: Predicate[];
5025
4232
  } | {
@@ -5054,9 +4261,7 @@ export declare type MainAxis = 'x' | 'y';
5054
4261
  declare type MappableAes<Definition extends Geom> = Definition['requiredAesthetics'][number] | Definition['visualAesthetics'][number] | 'group';
5055
4262
 
5056
4263
  /**
5057
- * Create a pipeable mapping spec item. Use this form (rather than passing the mapping as the first
5058
- * `createSpec` arg) when a transform must run before the mapping is read — e.g. reshaping wide columns
5059
- * to long so a freshly-created column can be bound to a channel.
4264
+ * Create a pipeable mapping spec item.
5060
4265
  *
5061
4266
  * @example
5062
4267
  * createSpec(
@@ -5069,38 +4274,13 @@ declare type MappableAes<Definition extends Geom> = Definition['requiredAestheti
5069
4274
  export declare function mapping(aes: AesMapping): MappingItem;
5070
4275
 
5071
4276
  /**
5072
- * A pipeable spec item that sets/merges the global {@link AesMapping}. Produced by {@link mapping} and
5073
- * folded into the spec by `pipe`/`createSpec`; later mapping items shallow-merge over earlier channels.
4277
+ * A pipeable spec item that sets/merges the global aesthetic mapping.
5074
4278
  */
5075
4279
  declare interface MappingItem {
5076
4280
  type: 'mapping';
5077
4281
  mapping: AesMapping;
5078
4282
  }
5079
4283
 
5080
- /** Declares one mark kind's own columns and the data type of each. */
5081
- export declare type MarkColumnSchema = Record<string, DataType>;
5082
-
5083
- /**
5084
- * Builds one columnar {@link Dataset} from heterogeneous marks discriminated by a `kind` column — *the*
5085
- * geom-layout dataset shape (node+link, group+leaf, node+edge). Each kind declares its own columns; the union
5086
- * across kinds forms the dataset's columns, and a row's off-kind columns are filled with `null` **by
5087
- * construction**, so the null-padding invariant a hand-built builder maintains by hand (and breaks when a
5088
- * column is omitted from one kind's push) can no longer drift.
5089
- */
5090
- declare class MarkTable {
5091
- /** Column name → declared type, accumulated as the union across every declared kind. */
5092
- private readonly columnTypes;
5093
- /** Kind name → the column names that kind owns. */
5094
- private readonly kindColumns;
5095
- private readonly rows;
5096
- /** Declares a mark kind and the columns it carries. Throws if the kind repeats or a column's type conflicts. */
5097
- kind(name: string, columns: MarkColumnSchema): this;
5098
- /** Appends one row for a declared kind. Throws if the kind is unknown, or a value misses/overshoots the kind's columns. */
5099
- push(kind: string, values: Record<string, DataValue>): this;
5100
- /** Materialises the rows into a {@link Dataset}, null-padding every off-kind column. */
5101
- toDataset(options: ToDatasetOptions): Dataset;
5102
- }
5103
-
5104
4284
  declare function mean(): MeanStatSpec;
5105
4285
 
5106
4286
  /**
@@ -5186,16 +4366,14 @@ declare type NeonPaletteConfig = {
5186
4366
  declare type NeonPaletteVariant = 'default' | 'waterfall';
5187
4367
 
5188
4368
  /**
5189
- * Chart-wide number formatting, applied by the renderer to every numeric value
5190
- * (axis ticks, tooltips, data labels, headline figures). Set via
5191
- * `config({ numberFormat: { … } })`.
4369
+ * Configuration for formatting a single number.
4370
+ * Defines how numeric values should be displayed in the chart.
5192
4371
  */
5193
4372
  export declare interface NumberFormatConfig {
5194
4373
  /**
5195
4374
  * Number of decimal places to display.
5196
4375
  * - number: Fixed decimal places (e.g., 2 → "1234.56")
5197
- * - 'auto': Automatic based on value magnitude
5198
- * @default 'auto'
4376
+ * - 'auto': Automatic based on value magnitude (default)
5199
4377
  */
5200
4378
  decimals: number | 'auto';
5201
4379
  /**
@@ -5205,7 +4383,6 @@ export declare interface NumberFormatConfig {
5205
4383
  * - 'k': Force thousands (1234567 → "1,234.6K")
5206
4384
  * - 'm': Force millions (1234567 → "1.2M")
5207
4385
  * - 'b': Force billions (1234567890 → "1.2B")
5208
- * @default 'auto'
5209
4386
  */
5210
4387
  abbreviation: 'auto' | 'k' | 'm' | 'b' | 'none';
5211
4388
  /**
@@ -5234,13 +4411,7 @@ declare interface NumericValueFormat {
5234
4411
  type: 'decimal' | 'integer' | 'percentage' | 'duration';
5235
4412
  }
5236
4413
 
5237
- /**
5238
- * One compiled per-observation record — the unit a geom's render half iterates and reads to paint a
5239
- * single mark. Maps every variable name (the author's data columns plus the compiler's internal
5240
- * position/visual/group columns) to that observation's value. Read positions and encodings off it with
5241
- * the value readers ({@link getX}, {@link getYMin}, {@link getColor}, …) rather than indexing internal
5242
- * keys by hand; read your own named columns with `readNumber`/`readString`.
5243
- */
4414
+ /** A single row of data, mapping every variable name to the value in that row. */
5244
4415
  export declare type Observation = Record<VariableName, DataValue>;
5245
4416
 
5246
4417
  /**
@@ -5259,16 +4430,13 @@ export declare interface ObservationAnchor {
5259
4430
  groupValue: DataValue;
5260
4431
  }
5261
4432
 
5262
- /**
5263
- * Snaps to a single data observation by its main-axis value and series. The annotation tracks that
5264
- * observation across resize and re-layout (unlike panel-fractional positioning).
5265
- */
4433
+ /** Points at a single observation by its anchor value and series. */
5266
4434
  export declare interface ObservationAnchorInput {
5267
- /** Pick a specific layer when multiple share the same `(anchorValue, groupValue)` pair. Index into the spec's layers. */
4435
+ /** Pick a specific layer when multiple share the same `(anchorValue, groupValue)` pair. */
5268
4436
  layerIndex?: number;
5269
- /** Value on the main axis (x in cartesian, y in flipped) that selects the observation. */
4437
+ /** Value on the main axis (x in cartesian, y in flipped). */
5270
4438
  anchorValue: DataValue;
5271
- /** Series identity the `color`/`group` aesthetic value that disambiguates within the axis value. */
4439
+ /** Series identity (the `group` aesthetic value). */
5272
4440
  groupValue: DataValue;
5273
4441
  }
5274
4442
 
@@ -5300,15 +4468,13 @@ declare interface PaletteScaleSpec {
5300
4468
  * Panel configuration
5301
4469
  */
5302
4470
  declare interface PanelConfig {
5303
- /** Border drawn around the plot panel (the data area). */
5304
4471
  border: {
5305
- /** Whether the panel border is rendered. */
5306
4472
  isVisible: boolean;
5307
4473
  };
5308
4474
  }
5309
4475
 
5310
4476
  /**
5311
- * A render-side hit-test a geom-layout geom registers for a `render-hit-test` layer. The engine calls it
4477
+ * A render-side hit-test a Tier-C geom registers for a `render-hit-test` layer. The engine calls it
5312
4478
  * with the cursor in panel `[0, 1]` space using a **top-left origin (y-down)** — the same frame the
5313
4479
  * geom paints in (unit-space SVG / `toPercent`), so the geom can test against its own rendered
5314
4480
  * geometry without re-flipping. It returns the declared identity `key` of the observation under the
@@ -5365,29 +4531,19 @@ declare interface PieOptions {
5365
4531
  * Pinned-number annotation: a marker dot pinned to a single observation. The
5366
4532
  * renderer's mini view shows the observation's measurement value; hover reveals
5367
4533
  * the full tooltip (x + y + trend).
5368
- *
5369
- * NO PAINTER in `@graphysdk/react-renderer` — this compiles but never draws there (it renders only in
5370
- * the editor's legacy engine). Don't reach for it when authoring for the React renderer.
5371
4534
  */
5372
4535
  declare interface PinnedNumberAnnotationInput {
5373
4536
  id?: string;
5374
4537
  anchor: ObservationAnchorInput;
5375
4538
  }
5376
4539
 
5377
- /** Resolved form of {@link PinnedNumberAnnotationInput} — defaults applied, anchor normalised. */
5378
4540
  declare interface PinnedNumberAnnotationSpec {
5379
4541
  id: string;
5380
4542
  anchor: ObservationAnchor;
5381
4543
  }
5382
4544
 
5383
4545
  /**
5384
- * Fold a sequence of pipeable spec items onto an existing spec, left to right, returning a new spec.
5385
- * Each item is appended by kind: layers accumulate (call `geom.*` once per mark), scales accumulate,
5386
- * `config` deep-merges, `coord`/`mapping` overwrite/merge. The usual shape is
5387
- * `pipe(createSpec({...}), geom.x(), scale.x(), scale.y(), ...)`.
5388
- *
5389
- * @example
5390
- * pipe(createSpec({ x: 'month', y: 'sales', color: 'region' }), geom.line(), scale.x(), scale.y(), scale.color.palette());
4546
+ * Pipe a spec through a series of spec items (left-to-right).
5391
4547
  */
5392
4548
  export declare function pipe(spec: SpecInput, ...items: SpecItem[]): SpecInput;
5393
4549
 
@@ -5417,20 +4573,6 @@ export declare interface PlacedDataLabel {
5417
4573
  position: DataLabelPosition;
5418
4574
  }
5419
4575
 
5420
- /**
5421
- * Point marks — scatter plots and bubble charts. Map `size` to a column for a bubble chart and `color` for
5422
- * categorical series. Sizing is controlled via {@link PointGeomParams} `size` or `scale.size.continuous`.
5423
- *
5424
- * @example
5425
- * pipe(
5426
- * createSpec({ x: 'gdp', y: 'lifeExp', size: 'population', color: 'continent' }),
5427
- * geom.point(),
5428
- * scale.x(),
5429
- * scale.y(),
5430
- * scale.size.continuous({ range: [4, 40] }),
5431
- * scale.color.palette(),
5432
- * );
5433
- */
5434
4576
  declare function point(options?: GeomOptions<'point'>): LayerInputOf<'point'>;
5435
4577
 
5436
4578
  /**
@@ -5449,14 +4591,9 @@ declare class PointGeom extends Geom {
5449
4591
  }
5450
4592
 
5451
4593
  /**
5452
- * Render parameters for `geom.point`. Passed under `params`.
4594
+ * Point-specific parameters
5453
4595
  */
5454
4596
  declare interface PointGeomParams {
5455
- /**
5456
- * Mark diameter in pixels, used when `size` is not a data channel. To size by data instead, map the `size`
5457
- * aesthetic and declare `scale.size.continuous({ range })`.
5458
- * @default 8
5459
- */
5460
4597
  size: number;
5461
4598
  }
5462
4599
 
@@ -5472,28 +4609,19 @@ declare interface PolarCoordInput {
5472
4609
  }
5473
4610
 
5474
4611
  /**
5475
- * Resolved params for the polar coordinate system (defaults applied).
5476
- * Drives pie, donut, and radar/radial layouts by mapping one scaled aesthetic to the
5477
- * angle and the other to the radius.
4612
+ * Params for polar coordinate system
5478
4613
  */
5479
4614
  declare interface PolarCoordParams extends BaseCoordParams {
5480
4615
  /**
5481
- * Which aesthetic becomes the angle (theta); the other aesthetic becomes the radius,
5482
- * scaled into `[innerRadius, 1]`. Use `'y'` for pie/donut (stacked value → angle),
5483
- * `'x'` for radar (one spoke per category).
5484
- * @default 'x'
4616
+ * Which aesthetic maps to theta (angle): 'x' or 'y'
5485
4617
  */
5486
4618
  theta: 'x' | 'y';
5487
4619
  /**
5488
- * Rotation offset of the whole layout, in degrees. Shifts where the first datum begins;
5489
- * the full sweep is 360°.
5490
- * @default 0
4620
+ * Starting angle in degrees
5491
4621
  */
5492
4622
  startAngle: number;
5493
4623
  /**
5494
- * Hole radius as a fraction of the outer radius, `0`–`1`. `0` is a full pie;
5495
- * any value `> 0` produces a donut (e.g. `0.55`).
5496
- * @default 0
4624
+ * Inner radius as fraction 0-1 (for donut charts)
5497
4625
  */
5498
4626
  innerRadius: number;
5499
4627
  }
@@ -5615,7 +4743,7 @@ declare interface PositionalScaleMethods {
5615
4743
  * derives from. A geom's channels are the manifest the position mapper and coord projection iterate
5616
4744
  * instead of hardcoding the column set.
5617
4745
  */
5618
- export declare type PositionChannel = RolePositionChannel | ScalarPositionChannel;
4746
+ declare type PositionChannel = RolePositionChannel | ScalarPositionChannel;
5619
4747
 
5620
4748
  declare interface PositionChannelBase {
5621
4749
  axis: ChannelAxis;
@@ -5663,10 +4791,6 @@ export declare type PositionType = 'stack' | 'dodge' | 'identity' | 'fill';
5663
4791
  */
5664
4792
  declare type PositionValueKind = 'value' | 'bandOffset';
5665
4793
 
5666
- /**
5667
- * Selects which observations a highlight emphasises: either a single-column
5668
- * {@link VariablePredicate} or a {@link LogicalPredicate} combining several.
5669
- */
5670
4794
  export declare type Predicate = VariablePredicate | LogicalPredicate;
5671
4795
 
5672
4796
  export declare const prefixInternalVariable: (name: string) => string;
@@ -5689,51 +4813,11 @@ declare interface QuantitativeScaleMethods {
5689
4813
  identity: (options?: IdentityScaleOptions) => IdentityScaleInput;
5690
4814
  }
5691
4815
 
5692
- /**
5693
- * The radial span of an arc/wedge in a polar coord, in `[0,1]` (0 = centre, 1 = outer ring).
5694
- * `innerRadius` is `null` when the observation declares no y interval; `outerRadius` falls back to the
5695
- * `point` radius when no upper endpoint exists. Returned by {@link getRadiusExtent}.
5696
- */
5697
4816
  export declare interface RadiusExtent {
5698
4817
  innerRadius: NumericDataValue;
5699
4818
  outerRadius: NumericDataValue;
5700
4819
  }
5701
4820
 
5702
- /**
5703
- * Reads an aesthetic value by an open channel name — built-in (`x`, `color`, …) or custom. A custom
5704
- * geom maps extra channels (a box plot's `q1`/`median`/`q3`, an error bar's bounds) under names outside
5705
- * the closed {@link AestheticKey} set; those keys ride in the mapping at runtime and are read here
5706
- * through the one sanctioned widening, so a channel's value is sourced from `aes` rather than `params`.
5707
- */
5708
- export declare function readAesthetic(aesMapping: AesMapping, name: string): AestheticValue | undefined;
5709
-
5710
- /**
5711
- * Reads a value by **column name** from an observation, as a number. Use this for the columns a custom
5712
- * geom named itself (via `variableFor(axis, name)` for scalar channels, or `addVariable` in `compile()`)
5713
- * — the position readers (`getX`, `getYMin`, …) and visual readers (`getColor`, …) cover the built-in
5714
- * channels by their fixed internal keys, but there is no typed accessor for an author-named column, and
5715
- * this fills that gap. The returned number is **whatever was written to that column** (a scalar channel
5716
- * is already scaled to `[0,1]`; a plain `addVariable` value is in its original units — it carries no
5717
- * scaling on its own).
5718
- *
5719
- * Shares the readers' null-discipline: a missing or wrong-typed value is `null`, never silently coerced
5720
- * to `0`. Pass `fallback` to opt into a default for genuinely-missing values; the overload then narrows
5721
- * the return to `number`, so a geom that wants `0`-on-missing says so explicitly.
5722
- */
5723
- export declare function readNumber(observation: Observation, key: string): number | null;
5724
-
5725
- export declare function readNumber(observation: Observation, key: string, fallback: number): number;
5726
-
5727
- /**
5728
- * Reads a value by **column name** from an observation, as a string — the string counterpart to
5729
- * {@link readNumber}, for author-named categorical/label columns a custom geom wrote in `compile()`.
5730
- * A missing or wrong-typed value is `null` unless a `fallback` is given (the overload then narrows the
5731
- * return to `string`).
5732
- */
5733
- export declare function readString(observation: Observation, key: string): string | null;
5734
-
5735
- export declare function readString(observation: Observation, key: string, fallback: string): string;
5736
-
5737
4821
  /** A rectangle in pixel coordinates, origin at top-left. */
5738
4822
  export declare interface Rect {
5739
4823
  x: number;
@@ -5793,11 +4877,6 @@ declare function reshape(options?: ReshapeOptions): ReshapeTransformInput;
5793
4877
  /***************************************************************
5794
4878
  * Reshape Transform
5795
4879
  ***************************************************************/
5796
- /**
5797
- * Options for `transform.reshape` — pivots a wide table to long ("tidy") form by collapsing
5798
- * several numeric columns into two: a key column (the original column name) and a value column.
5799
- * The idiom for turning a multi-metric table into a single series mappable by `color`.
5800
- */
5801
4880
  declare interface ReshapeOptions {
5802
4881
  /**
5803
4882
  * Numeric variables to collapse into rows.
@@ -5821,7 +4900,6 @@ declare interface ReshapeOptions {
5821
4900
  valueName?: VariableName;
5822
4901
  }
5823
4902
 
5824
- /** Pivot-to-long transform produced by `transform.reshape`. */
5825
4903
  declare interface ReshapeTransformInput {
5826
4904
  type: 'transform';
5827
4905
  transformType: 'reshape';
@@ -5860,12 +4938,6 @@ export declare interface ResolvedObservationAnchor extends AnchorPosition {
5860
4938
  color: string | undefined;
5861
4939
  }
5862
4940
 
5863
- /**
5864
- * A fully-resolved stat spec: a built-in {@link StatSpec} or a custom stat's `{ type, ...options }`.
5865
- * What the {@link StatCompiler} dispatches on and a stat's `compute` receives.
5866
- */
5867
- export declare type ResolvedStatSpec = StatSpec | CustomStatInput;
5868
-
5869
4941
  /**
5870
4942
  * A custom annotation's coordinate resolved to normalized panel space, in **top-left [0,1]** — the
5871
4943
  * space the draw function paints in. `observation` is attached only for a snap-to-observation
@@ -5911,35 +4983,15 @@ export declare function resolveYScaleAesthetic(yScaleType: YScaleType): ScaledAe
5911
4983
  */
5912
4984
  export declare const RESTING_HOVER_STATE: HoverState;
5913
4985
 
5914
- /**
5915
- * A node in a ProseMirror/TipTap-style rich-text document tree (no tiptap
5916
- * dependency). NOT a plain string — it is a recursive node where `content`
5917
- * holds child nodes and a leaf text node carries `text`. Used both for chart
5918
- * titles/captions and for text annotation bodies.
5919
- *
5920
- * The root is a `{ type: 'doc' }` node; block children are `'paragraph'` or
5921
- * `'heading'` (with `attrs.level`); inline runs are `'text'` nodes whose
5922
- * `marks` apply styling (e.g. `{ type: 'bold' }`, `{ type: 'italic' }`,
5923
- * `{ type: 'link', attrs: { href } }`). Plain prose is one paragraph of one
5924
- * text node:
5925
- *
5926
- * ```ts
5927
- * { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Quarterly sales' }] }] }
5928
- * ```
5929
- */
4986
+ /** TipTap-compatible rich text node (no tiptap dependency). */
5930
4987
  export declare interface RichTextContent {
5931
- /** Node kind: `'doc'` (root), `'paragraph'`, `'heading'`, `'text'`, etc. */
5932
4988
  type?: string;
5933
- /** Child nodes. Present on container nodes; absent on `'text'` leaves. */
5934
4989
  content?: RichTextContent[];
5935
- /** The literal string carried by a `'text'` leaf node. */
5936
4990
  text?: string;
5937
- /** Inline formatting applied to a `'text'` node (bold, italic, link, …). */
5938
4991
  marks?: Array<{
5939
4992
  type: string;
5940
4993
  attrs?: Record<string, unknown>;
5941
4994
  }>;
5942
- /** Node attributes, e.g. `{ level: 2 }` on a heading or `{ href }` on a link mark target. */
5943
4995
  attrs?: Record<string, unknown>;
5944
4996
  }
5945
4997
 
@@ -5954,18 +5006,6 @@ declare interface RolePositionChannel extends PositionChannelBase {
5954
5006
  name?: string;
5955
5007
  }
5956
5008
 
5957
- /**
5958
- * Rule marks — a single horizontal or vertical reference line, the built-in for goal/threshold/average
5959
- * lines (no custom geom needed). Pin a constant with `aes: { y: { value } }` (horizontal) or
5960
- * `aes: { x: { value } }` (vertical, numeric x), or compute a data-driven line with `stat.mean()`. Style and
5961
- * label it via {@link RuleGeomParams}; set `interactive: false` so it doesn't take hover.
5962
- *
5963
- * @example
5964
- * // Constant goal line at y = 2500
5965
- * geom.rule({ aes: { y: { value: 2500 } }, params: { label: 'Target', lineType: 'dashed', labelPosition: 'start' } });
5966
- * // Data-driven average line
5967
- * geom.rule({ aes: { y: 'revenue' }, stat: stat.mean(), params: { label: 'Average' }, interactive: false });
5968
- */
5969
5009
  declare function rule(options?: GeomOptions<'rule'>): LayerInputOf<'rule'>;
5970
5010
 
5971
5011
  /**
@@ -5988,34 +5028,20 @@ declare class RuleGeom extends Geom {
5988
5028
  }
5989
5029
 
5990
5030
  /**
5991
- * Render parameters for `geom.rule`. Passed under `params`. The line's value comes from `aes`
5992
- * (`{ y: { value } }` or `stat.mean()`), not from here — these are styling and labelling only.
5031
+ * Rule-specific parameters.
5993
5032
  */
5994
5033
  export declare interface RuleGeomParams {
5995
- /** Stroke color (any CSS color). Falls back to a theme token when omitted. */
5034
+ /** Stroke color; falls back to a theme token. */
5996
5035
  color?: string;
5997
- /**
5998
- * Stroke width in pixels.
5999
- * @default 1
6000
- */
6001
5036
  strokeWidth: number;
6002
- /**
6003
- * Dash style of the line.
6004
- * @default 'dashed'
6005
- */
6006
5037
  lineType: LineStyleType;
6007
- /** Optional inline text label rendered alongside the line (e.g. `'Target'`, `'Average'`). */
5038
+ /** Optional inline text label rendered alongside the line. */
6008
5039
  label?: string;
6009
- /**
6010
- * Which end of the line the `label` is anchored to.
6011
- * @default 'start'
6012
- */
6013
5040
  labelPosition: RuleLabelPosition;
6014
5041
  }
6015
5042
 
6016
5043
  /**
6017
- * Where the optional inline label sits along a reference line: `'start'` (left/top end) or `'end'`
6018
- * (right/bottom end).
5044
+ * Where the optional inline label is anchored along a reference line.
6019
5045
  */
6020
5046
  export declare type RuleLabelPosition = 'start' | 'end';
6021
5047
 
@@ -6047,31 +5073,6 @@ declare abstract class Scale {
6047
5073
  abstract compile(spec: ScaleSpec, values: DataValue[]): CompiledScale;
6048
5074
  }
6049
5075
 
6050
- /**
6051
- * Scale builder — declares how each mapped variable is turned into a visual value
6052
- * (axis position, color, size, …). Pipe the result onto a spec.
6053
- *
6054
- * Position scales must be declared EXPLICITLY: the builder never auto-infers `x`/`y`,
6055
- * so omitting `scale.x()` / `scale.y()` yields NaN positions. `scale.x`/`.y`/`.ySecondary`
6056
- * are callable for an inferred scale (type auto-detected from the data) or expose explicit
6057
- * sub-methods: `.continuous` / `.discrete` / `.datetime` / `.log` / `.sqrt`. Use
6058
- * `scale.x.discrete()` for categorical or temporal-string axes.
6059
- *
6060
- * Non-position aesthetics auto-infer from the mapping, so their scale entry is optional —
6061
- * add one only to override the default (e.g. `scale.color.palette()`, `scale.size.continuous({ range })`).
6062
- *
6063
- * @example
6064
- * import { pipe, createSpec, geom, scale } from '@graphysdk/viz-engine';
6065
- *
6066
- * pipe(
6067
- * createSpec({ x: 'gdp', y: 'lifeExp', size: 'population', color: 'continent' }),
6068
- * geom.point(),
6069
- * scale.x.log({ domainMin: 1 }),
6070
- * scale.y.continuous({ zero: false, nice: true }),
6071
- * scale.size.continuous({ range: [4, 40] }),
6072
- * scale.color.palette()
6073
- * );
6074
- */
6075
5076
  export declare const scale: ScaleAPI;
6076
5077
 
6077
5078
  declare interface ScaleAPI {
@@ -6178,13 +5179,10 @@ export declare type ScaledAestheticKey = ScaledPositionAestheticKey | ScaledVisu
6178
5179
 
6179
5180
  declare type ScaledPositionAestheticKey = 'x' | 'y' | 'ySecondary';
6180
5181
 
6181
- export declare type ScaledVisualAestheticKey = 'color' | 'size' | 'alpha' | 'strokeWidth' | 'lineType';
5182
+ declare type ScaledVisualAestheticKey = 'color' | 'size' | 'alpha' | 'strokeWidth' | 'lineType';
6182
5183
 
6183
5184
  /**
6184
- * Any value the `scale` builder produces, before resolution. Each pipe item carries the
6185
- * target aesthetic plus its scale type and options; an `inferred` entry has its concrete
6186
- * type chosen from the data during compilation. This is the type accepted by the spec
6187
- * pipeline — author scales with the `scale` builder rather than constructing it by hand.
5185
+ * Union type for all possible scale specifications (including inferred, pre-resolution).
6188
5186
  */
6189
5187
  declare type ScaleInput = ContinuousScaleInput | DiscreteScaleInput | PaletteScaleInput | DatetimeScaleInput | IdentityScaleInput | InferredScaleInput;
6190
5188
 
@@ -6193,9 +5191,8 @@ declare class ScaleRegistry extends Registry<ScaleType, Scale> {
6193
5191
  }
6194
5192
 
6195
5193
  /**
6196
- * A fully resolved scale (every option defaulted) as it appears on the compiled spec.
6197
- * The `inferred` variant has already been collapsed to one of these concrete types
6198
- * during resolution, so this union has no `inferred` member.
5194
+ * Union of scale specs that can appear after resolution (all fields required).
5195
+ * InferredScaleInput is resolved to a concrete type during spec resolution.
6199
5196
  */
6200
5197
  declare type ScaleSpec = ContinuousScaleSpec | DiscreteScaleSpec | DatetimeScaleSpec | IdentityScaleSpec | PaletteScaleSpec;
6201
5198
 
@@ -6409,37 +5406,27 @@ declare type SetScaleDomainParams = {
6409
5406
  };
6410
5407
 
6411
5408
  /**
6412
- * A shaded box layered onto the panel. Position and size are panel fractions (`[0,1]`, top-left
6413
- * origin) NOT data values so the shape re-flows on resize but does not snap to a data point. Use a
6414
- * difference arrow or a custom annotation when you need data anchoring.
5409
+ * Freeform rectangle annotation. Position and size are expressed as
5410
+ * fractions of the plot rect (0..1) so the annotation re-flows when the
5411
+ * panel resizes.
6415
5412
  */
6416
5413
  export declare interface ShapeInput {
6417
5414
  id?: string;
6418
- /** @default 'rectangle' */
6419
5415
  kind?: ShapeKind;
6420
- /** @default 'foreground' */
6421
5416
  zOrder?: ShapeZOrder;
6422
- /** Left edge as a `[0,1]` fraction of panel width (0 = left). */
6423
5417
  x: number;
6424
- /** Top edge as a `[0,1]` fraction of panel height (0 = top). */
6425
5418
  y: number;
6426
- /** Width as a `[0,1]` fraction of panel width. */
6427
5419
  width: number;
6428
- /** Height as a `[0,1]` fraction of panel height. */
6429
5420
  height: number;
6430
- /** @default 'transparent' */
6431
5421
  fillColor?: string;
6432
- /** Fill alpha, `[0,1]`. @default 1 */
6433
5422
  fillOpacity?: number;
6434
- /** Stroke width in pixels. @default 1 */
6435
5423
  strokeWidth?: number;
6436
- /** `null` falls back to the theme `defaultAnnotationShapeStroke`. @default null */
5424
+ /** null falls back to the theme `defaultAnnotationShapeStroke`. */
6437
5425
  strokeColor?: string | null;
6438
5426
  }
6439
5427
 
6440
5428
  export declare type ShapeKind = 'rectangle';
6441
5429
 
6442
- /** Resolved form of {@link ShapeInput} — defaults applied. */
6443
5430
  export declare interface ShapeSpec {
6444
5431
  id: string;
6445
5432
  kind: ShapeKind;
@@ -6460,9 +5447,7 @@ export declare interface ShapeSpec {
6460
5447
  export declare type ShapeZOrder = 'background' | 'foreground';
6461
5448
 
6462
5449
  /**
6463
- * Builder for the smooth stat — fits a regression trendline through the observations.
6464
- * Pair with `geom.line` for a drawn trendline. `order` applies only to `'polynomial'`,
6465
- * `bandwidth` only to `'loess'`; both are ignored by the other methods.
5450
+ * Builder for the smooth stat.
6466
5451
  *
6467
5452
  * @example
6468
5453
  * geom.line({ stat: stat.smooth({ method: 'linear' }) })
@@ -6476,14 +5461,7 @@ declare function smooth(options: {
6476
5461
  }): SmoothStatInput;
6477
5462
 
6478
5463
  /**
6479
- * Regression/trendline method fitted by the `smooth` stat through the observations:
6480
- * - `'linear'` — straight line of best fit (`y = a + b·x`). The default.
6481
- * - `'loess'` — locally weighted smoothing; follows local structure. Tune with `bandwidth`.
6482
- * - `'exponential'` — `y = a·e^(b·x)`; constant-rate growth/decay.
6483
- * - `'logarithmic'` — `y = a + b·ln(x)`; fast early then flattening.
6484
- * - `'quadratic'` — parabola (`y = a + b·x + c·x²`); a single bend.
6485
- * - `'power'` — `y = a·x^b`; scale-free relationships.
6486
- * - `'polynomial'` — degree-`order` polynomial; multiple bends. Tune with `order`.
5464
+ * Regression methods supported by the `smooth` stat.
6487
5465
  */
6488
5466
  export declare type SmoothMethod = 'linear' | 'loess' | 'exponential' | 'logarithmic' | 'quadratic' | 'power' | 'polynomial';
6489
5467
 
@@ -6493,9 +5471,7 @@ export declare type SmoothMethod = 'linear' | 'loess' | 'exponential' | 'logarit
6493
5471
  declare interface SmoothStatInput {
6494
5472
  type: 'smooth';
6495
5473
  method: SmoothMethod;
6496
- /** Polynomial degree. Only used when `method: 'polynomial'`. @default 3 */
6497
5474
  order?: number;
6498
- /** LOESS smoothing window as a fraction (0–1) of the data. Only used when `method: 'loess'`. @default 0.3 */
6499
5475
  bandwidth?: number;
6500
5476
  }
6501
5477
 
@@ -6513,18 +5489,9 @@ declare interface SmoothStatSpec {
6513
5489
 
6514
5490
  declare function sort(options: SortOptions): SortTransformInput;
6515
5491
 
6516
- /**
6517
- * Sorts the data by the x variable if it is numeric or temporal.
6518
- */
6519
- export declare const sortByXIfContinuous: (data: Dataset, mapping: AesMapping) => Dataset;
6520
-
6521
5492
  /***************************************************************
6522
5493
  * Sort Transform
6523
5494
  ***************************************************************/
6524
- /**
6525
- * Options for `transform.sort` — reorders observations by one variable. Affects draw order
6526
- * and the order categories are first seen (and thus discrete-scale domain order).
6527
- */
6528
5495
  declare interface SortOptions {
6529
5496
  /** The variable to sort by. */
6530
5497
  variableName: VariableName;
@@ -6532,18 +5499,15 @@ declare interface SortOptions {
6532
5499
  direction?: 'asc' | 'desc';
6533
5500
  }
6534
5501
 
6535
- /** Observation-ordering transform produced by `transform.sort`. */
6536
5502
  declare interface SortTransformInput {
6537
5503
  type: 'transform';
6538
5504
  transformType: 'sort';
6539
5505
  options: SortOptions;
6540
5506
  }
6541
5507
 
6542
- /** Data-source attribution shown under the caption: a `label` and optional `url`. */
5508
+ /** Data-source attribution shown under the caption. */
6543
5509
  export declare interface SourceContent {
6544
- /** Displayed attribution text, e.g. `'Internal pipeline'`. */
6545
5510
  label?: string;
6546
- /** Optional link the label points to. */
6547
5511
  url?: string;
6548
5512
  }
6549
5513
 
@@ -6552,7 +5516,7 @@ export declare interface SourceContent {
6552
5516
  * runtime's index builders, so the descriptor lets the engine dispatch on declared data instead
6553
5517
  * of branching on the geom name.
6554
5518
  *
6555
- * `render-hit-test` is the geom-layout escape hatch: the geom's geometry comes from a layout algorithm,
5519
+ * `render-hit-test` is the Tier-C escape hatch: the geom's geometry comes from a layout algorithm,
6556
5520
  * not from scales, so the compiler cannot build a spatial index from position columns. The geom
6557
5521
  * instead provides a render-side hit-test function (injected per-instance through the renderer),
6558
5522
  * and the engine resolves the observation it returns against the declared identity key. Only the
@@ -6564,7 +5528,7 @@ export declare interface SourceContent {
6564
5528
  * time (no stored cartesian, no Delaunay), staying correct across resizes. Geoms never declare it; a
6565
5529
  * polar coord refines a `points`-natural mark to it during the coord transform.
6566
5530
  */
6567
- export declare type SpatialIndexKind = 'buckets' | 'rects' | 'points' | 'arcs' | 'noop' | 'render-hit-test' | 'polar-points';
5531
+ declare type SpatialIndexKind = 'buckets' | 'rects' | 'points' | 'arcs' | 'noop' | 'render-hit-test' | 'polar-points';
6568
5532
 
6569
5533
  /**
6570
5534
  * A layer's geometry-agnostic hit-test declaration. Pure serialisable data riding in the compiled
@@ -6617,30 +5581,17 @@ export declare interface Spec {
6617
5581
  }
6618
5582
 
6619
5583
  /**
6620
- * The canonical spec type — plain JSON, serializable. Built by `createSpec`/`pipe`; data is provided
6621
- * separately (as a `Data` value to {@link compile}, or as a prop to `<GraphProvider>`). Hand-construct it
6622
- * only when you cannot use the builders; otherwise prefer `pipe(createSpec({...}), geom.x(), scale.x(), ...)`.
5584
+ * The canonical spec type — plain JSON, serializable. Data is provided separately
5585
+ * (as a `Data` value to {@link compile}, or as a prop to `<GraphProvider>`).
6623
5586
  */
6624
5587
  export declare interface SpecInput {
6625
- /** Global aesthetic mapping (data columns → channels); layer `aes` overrides merge over this. */
6626
5588
  mapping: AesMapping;
6627
- /** Geometry layers to render, in draw order. One entry per `geom.*` call. */
6628
5589
  layers: LayerInput[];
6629
- /**
6630
- * Scale declarations, one per aesthetic. Position scales (`scale.x`/`scale.y`/`scale.ySecondary`) are NOT
6631
- * auto-inferred — declare them explicitly or position channels resolve to NaN. Visual scales
6632
- * (`color`/`size`/...) are inferred from the data when omitted.
6633
- */
6634
5590
  scales: ScaleInput[];
6635
- /** Spec-level data transforms applied before any layer is compiled (reshape, filter, ...). */
6636
5591
  transforms: TransformInput[];
6637
- /** Predicate-driven emphasis rules that dim or accentuate matching observations. */
6638
5592
  highlights: HighlightInput[];
6639
- /** Annotation overlays — difference arrows, shapes, text, freeform arrows. Optional. */
6640
5593
  annotations?: AnnotationsInput;
6641
- /** Coordinate system: cartesian (default), `coord.flip()`, or `coord.polar(...)`. Optional. */
6642
5594
  coords?: CoordInput;
6643
- /** Chart configuration: titles/captions, legend, axes, number format, headline, appearance. */
6644
5595
  config: ConfigInput;
6645
5596
  }
6646
5597
 
@@ -6657,18 +5608,6 @@ export declare class SpecResolver {
6657
5608
  }): Spec;
6658
5609
  }
6659
5610
 
6660
- /**
6661
- * Render a {@link SpecInput} as fluent builder source — `pipe(createSpec({…}), geom.x(…), scale.x(…),
6662
- * config({…}))` — emitting only values that differ from their defaults. Returns `null` when the spec
6663
- * contains something the builder form cannot faithfully represent (a custom geom, a transform, a polar
6664
- * coord, …), so the caller can fall back to a literal object and never lose data.
6665
- *
6666
- * The defaults are static (data-independent), so this needs no dataset. Position scales are emitted in
6667
- * the inferred `scale.x(opts)` form on purpose: the resolver only applies context defaults (e.g. a bar
6668
- * chart's `zero: true`) to inferred scales, so converting them to an explicit type would change the chart.
6669
- */
6670
- export declare function specToBuilderSource(input: SpecInput): string | null;
6671
-
6672
5611
  export declare interface StackTotalEntry {
6673
5612
  /** Serialised x value for stable join keys across observations. */
6674
5613
  xKey: string;
@@ -6711,11 +5650,9 @@ declare abstract class Stage<Input, Output> {
6711
5650
 
6712
5651
  /**
6713
5652
  * Base class for statistical transformations applied to layer data (e.g. binning, counting, smoothing).
6714
- * Built-ins use a literal {@link StatName}; custom stats authored with `defineStat` carry any registered
6715
- * `type` string ({@link StatIdentity}).
6716
5653
  */
6717
- export declare abstract class Stat {
6718
- abstract readonly type: StatIdentity;
5654
+ declare abstract class Stat {
5655
+ abstract readonly type: StatName;
6719
5656
  /**
6720
5657
  * Aesthetics this stat will compute (e.g. count computes 'y'). Used by validation to skip existence checks.
6721
5658
  */
@@ -6724,23 +5661,6 @@ export declare abstract class Stat {
6724
5661
  protected abstract computeStat(input: StatCompilerInput): CompiledStat;
6725
5662
  }
6726
5663
 
6727
- /**
6728
- * Statistical-transform builder — sets a geom's `stat`, replacing each layer's raw observations
6729
- * with a derived summary before positions are computed. Defaults to `identity` (raw data).
6730
- *
6731
- * - `identity()` — pass observations through unchanged (the default).
6732
- * - `count()` — number of observations per x value, written to `y`; do NOT also map `y`.
6733
- * - `mean()` — reduce the mapped `y` to its average (a single value); the idiom for an
6734
- * average line (`geom.rule({ stat: stat.mean() })`).
6735
- * - `smooth({ method })` — fit a regression trendline; the idiom for a trendline
6736
- * (`geom.line({ stat: stat.smooth({ method: 'linear' }) })`).
6737
- *
6738
- * @example
6739
- * import { geom, stat } from '@graphysdk/viz-engine';
6740
- *
6741
- * geom.rule({ aes: { y: 'revenue' }, stat: stat.mean(), params: { label: 'Average' } });
6742
- * geom.line({ stat: stat.smooth({ method: 'linear' }), interactive: false });
6743
- */
6744
5664
  export declare const stat: {
6745
5665
  identity: typeof identity;
6746
5666
  count: typeof count;
@@ -6749,28 +5669,25 @@ export declare const stat: {
6749
5669
  };
6750
5670
 
6751
5671
  /**
6752
- * Resolves stats by name and delegates computation. A layer's `stat` is an ordered pipeline (Decision 8):
6753
- * each step sees the dataset and effective mapping produced by the previous step, so a later stat can read
6754
- * an earlier stat's emitted column. Returns the net mapping overrides (last-writer-wins) for the caller to
6755
- * merge over the layer's effective mapping.
5672
+ * Resolves a stat by name and delegates computation.
6756
5673
  */
6757
5674
  declare class StatCompiler {
6758
5675
  private readonly registry;
6759
5676
  constructor(registry: StatRegistry);
6760
- compute(specs: ResolvedStatSpec[], input: {
5677
+ compute(spec: StatSpec, input: {
6761
5678
  data: Dataset;
6762
5679
  mapping: AesMapping;
6763
5680
  xScaleIsDiscrete: boolean;
6764
5681
  }): CompiledStat;
6765
5682
  }
6766
5683
 
6767
- export declare interface StatCompilerInput {
5684
+ declare interface StatCompilerInput {
6768
5685
  /** The input dataset. */
6769
5686
  data: Dataset;
6770
5687
  /** The effective mapping for the layer. */
6771
5688
  mapping: AesMapping;
6772
- /** The resolved stat spec (built-in or custom). Narrow by `spec.type` to access stat-specific params. */
6773
- spec: ResolvedStatSpec;
5689
+ /** The resolved stat spec. Narrow by `spec.type` to access stat-specific params. */
5690
+ spec: StatSpec;
6774
5691
  /**
6775
5692
  * Whether the x aesthetic resolves to a discrete (band) scale. The `smooth` stat emits one fitted
6776
5693
  * point per observed x when set.
@@ -6779,70 +5696,9 @@ export declare interface StatCompilerInput {
6779
5696
  }
6780
5697
 
6781
5698
  /**
6782
- * A registered custom stat: a {@link Stat} the compiler consumes, carrying the resolved-spec type so
6783
- * `createGraphyBuilder({ stats })` can type its `stat.<type>(options)` builder method.
6784
- */
6785
- export declare interface StatDef<TSpec extends StatSpecBase = StatSpecBase> extends Stat {
6786
- readonly type: TSpec['type'] & string;
6787
- /**
6788
- * Phantom — carries the resolved-spec type to the type level so the registration-typed builder can
6789
- * recover the stat's options. Never set at runtime.
6790
- */
6791
- readonly __spec?: TSpec;
6792
- }
6793
-
6794
- /**
6795
- * The compute input an authored stat receives: the standard {@link StatCompilerInput}, but with `spec`
6796
- * narrowed to the stat's own resolved spec `TSpec`, plus a `column` helper that namespaces a declared
6797
- * computed column to a collision-safe internal name (Decision 9).
6798
- */
6799
- export declare interface StatDefinitionInput<TSpec extends StatSpecBase = StatSpecBase> extends Omit<StatCompilerInput, 'spec'> {
6800
- /** The resolved spec for this stat — its `type` plus the options the builder passed. */
6801
- spec: TSpec;
6802
- /**
6803
- * Namespaces a column declared in `computedColumns` to `\0graphy\0_<type>_<local>` — globally unique,
6804
- * so a stat's output can never collide with a user column or another stat. Throws on an undeclared name.
6805
- * Write the returned name into `addVariable`/`addConstantVariable` and into any `mapping` rebinding.
6806
- */
6807
- column: (localName: string) => string;
6808
- }
6809
-
6810
- /**
6811
- * The manifest passed to {@link defineStat}. Declares the stat's `type`, the columns it emits
6812
- * (`computedColumns`, namespaced per-type), the aesthetics it rebinds (`computedVariables`, which waive
6813
- * the validator's pre-stat existence/required checks), and the `compute` itself.
6814
- */
6815
- export declare interface StatDefinitionManifest<TSpec extends StatSpecBase = StatSpecBase> {
6816
- /** The registered stat name; keys both the registry and the `stat.<type>(...)` builder method. */
6817
- type: TSpec['type'] & string;
6818
- /** Local names of the columns `compute` emits via `column(...)`. Namespaced per-type for collision-safety. */
6819
- computedColumns?: readonly string[];
6820
- /** Aesthetics `compute` rebinds (e.g. `'y'`). Waives the validator's pre-stat existence/required checks. */
6821
- computedVariables?: readonly AestheticKey[];
6822
- /** Derives the layer's summary from its dataset. Not called on an empty dataset (the base short-circuits). */
6823
- compute: (input: StatDefinitionInput<TSpec>) => CompiledStat;
6824
- }
6825
-
6826
- /**
6827
- * The open identity of a stat: a built-in {@link StatName} or any custom stat's `type` string
6828
- * registered via `createCompiler({ stats })`. The `& {}` keeps the built-in names as autocomplete
6829
- * candidates without collapsing the union to bare `string` (mirrors `GeomIdentity`).
6830
- */
6831
- export declare type StatIdentity = StatName | (string & {});
6832
-
6833
- /**
6834
- * Any value the `stat` builder produces — passed as the `stat` option of a geom.
6835
- * The string-shorthand variants (`stat.identity()`, `stat.count()`, `stat.mean()`) carry only
6836
- * a `type`; `smooth` additionally carries the regression parameters.
6837
- */
6838
- export declare type StatInput = IdentityStatSpec | CountStatSpec | SmoothStatInput | MeanStatSpec;
6839
-
6840
- /**
6841
- * A single stat a layer's `stat` option accepts — a built-in name, a built-in {@link StatInput}, or a
6842
- * custom stat input. A layer's `stat` is one of these or an ordered list of them (Decision 8): each step
6843
- * sees the previous step's emitted columns, e.g. `[stat.percentOfTotal(...), stat.window({ op: 'rank' })]`.
5699
+ * User-facing stat input either a {@link StatName} string shorthand or an object spec.
6844
5700
  */
6845
- declare type StatLayerInput = StatName | StatInput | CustomStatInput;
5701
+ declare type StatInput = IdentityStatSpec | CountStatSpec | SmoothStatInput | MeanStatSpec;
6846
5702
 
6847
5703
  /**
6848
5704
  * Statistical transformation applied to data before rendering.
@@ -6852,43 +5708,22 @@ declare type StatLayerInput = StatName | StatInput | CustomStatInput;
6852
5708
  * - `'smooth'` — Fit a regression curve through `(x, y)` and emit the fitted points
6853
5709
  * - `'mean'` — Reduce the dataset to a single observation holding the mean of `y`
6854
5710
  */
6855
- export declare type StatName = 'identity' | 'count' | 'smooth' | 'mean';
6856
-
6857
- /**
6858
- * The options a registered custom stat's builder method accepts — its resolved spec minus the `type`
6859
- * discriminant (the builder fills `type`). Recovered structurally from the definition's phantom spec.
6860
- */
6861
- declare type StatOptionsOf<Definition> = Definition extends StatDef<infer TSpec> ? Omit<TSpec, 'type'> : never;
5711
+ declare type StatName = 'identity' | 'count' | 'smooth' | 'mean';
6862
5712
 
6863
5713
  /**
6864
- * Stat implementations keyed by `type`. Built-ins are registered first; any custom stats injected via
6865
- * `createCompiler({ stats })` register afterwards (a custom `type` matching a built-in overrides it,
6866
- * last write wins) — mirroring `GeomRegistry`.
5714
+ * Built-in stat implementations keyed by {@link StatName}.
6867
5715
  */
6868
- declare class StatRegistry extends Registry<string, Stat> {
6869
- constructor(opts?: {
6870
- stats?: readonly Stat[];
6871
- });
5716
+ declare class StatRegistry extends Registry<StatName, Stat> {
5717
+ constructor();
6872
5718
  }
6873
5719
 
6874
5720
  /**
6875
- * Discriminated union of all built-in resolved stat specs (post-resolution).
5721
+ * Discriminated union of all resolved stat specs (post-resolution).
6876
5722
  */
6877
- export declare type StatSpec = IdentityStatSpec | CountStatSpec | SmoothStatSpec | MeanStatSpec;
6878
-
6879
- /**
6880
- * The minimal shape every stat spec shares: its `type` discriminant. A custom stat's resolved spec
6881
- * extends this with arbitrary plain-data options; `defineStat<TSpec>` narrows `TSpec` from it.
6882
- */
6883
- export declare interface StatSpecBase {
6884
- type: StatIdentity;
6885
- }
5723
+ declare type StatSpec = IdentityStatSpec | CountStatSpec | SmoothStatSpec | MeanStatSpec;
6886
5724
 
6887
5725
  /**
6888
5726
  * Sticker annotation: a built-in emoji-like image pinned to a single observation.
6889
- *
6890
- * NO PAINTER in `@graphysdk/react-renderer` — this compiles but never draws there (it renders only in
6891
- * the editor's legacy engine). Don't reach for it when authoring for the React renderer.
6892
5727
  */
6893
5728
  declare interface StickerAnnotationInput {
6894
5729
  id?: string;
@@ -6896,7 +5731,6 @@ declare interface StickerAnnotationInput {
6896
5731
  sticker: StickerId;
6897
5732
  }
6898
5733
 
6899
- /** Resolved form of {@link StickerAnnotationInput} — defaults applied, anchor normalised. */
6900
5734
  declare interface StickerAnnotationSpec {
6901
5735
  id: string;
6902
5736
  anchor: ObservationAnchor;
@@ -6947,33 +5781,26 @@ declare interface TemporalValueFormat {
6947
5781
  dateFormat?: string;
6948
5782
  }
6949
5783
 
6950
- /** How `backgroundColor` is applied: `'fade'` (soft gradient) or `'opaque'` (flat fill). */
6951
5784
  export declare type TextAnnotationBackgroundColorStyle = 'fade' | 'opaque';
6952
5785
 
6953
5786
  /**
6954
- * A free-standing text label on the panel. Positioned in panel fractions (`[0,1]`, top-left origin) —
6955
- * NOT data values so it re-flows on resize but does not snap to a data point. There is no `height`
6956
- * field: height is intrinsic to the rendered content. `content` is a structured {@link RichTextContent}
6957
- * node tree (ProseMirror/TipTap-style), NOT a plain string — wrap a string as
6958
- * `{ type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Label' }] }] }`.
5787
+ * Freeform rich-text annotation. Position and width are fractions of the plot
5788
+ * rect (0..1). Height is intrinsic to the rendered content.
6959
5789
  */
6960
5790
  export declare interface TextAnnotationInput {
6961
5791
  id?: string;
6962
- /** Rich-text node tree to render (not a plain string). */
6963
5792
  content: RichTextContent;
6964
- /** Left edge as a `[0,1]` fraction of panel width (0 = left, top-left corner). */
5793
+ /** 0..1 of plot width top-left corner. */
6965
5794
  x: number;
6966
- /** Top edge as a `[0,1]` fraction of panel height (0 = top, top-left corner). */
5795
+ /** 0..1 of plot height top-left corner. */
6967
5796
  y: number;
6968
- /** Box width as a `[0,1]` fraction of panel width; text wraps within it (height is intrinsic). */
5797
+ /** 0..1 of plot width. */
6969
5798
  width: number;
6970
- /** `null` falls back to a transparent background. @default null */
5799
+ /** null falls back to a transparent background. */
6971
5800
  backgroundColor?: string | null;
6972
- /** @default 'opaque' */
6973
5801
  backgroundColorStyle?: TextAnnotationBackgroundColorStyle;
6974
5802
  }
6975
5803
 
6976
- /** Resolved form of {@link TextAnnotationInput} — defaults applied. */
6977
5804
  export declare interface TextAnnotationSpec {
6978
5805
  id: string;
6979
5806
  content: RichTextContent;
@@ -6984,22 +5811,13 @@ export declare interface TextAnnotationSpec {
6984
5811
  backgroundColorStyle: TextAnnotationBackgroundColorStyle;
6985
5812
  }
6986
5813
 
6987
- /**
6988
- * A text value for a title, subtitle, or caption: either a plain `string`
6989
- * (rendered as-is) or a structured {@link RichTextContent} document tree for
6990
- * multi-style / multi-line text.
6991
- */
5814
+ /** A text value — plain string or structured rich text. */
6992
5815
  export declare type TextContent = string | RichTextContent;
6993
5816
 
6994
5817
  export declare interface TextMeasurer {
6995
5818
  measureText: (text: string, font: FontSpec) => MeasuredText;
6996
5819
  }
6997
5820
 
6998
- declare interface ToDatasetOptions {
6999
- /** Name of the categorical column that discriminates each row's kind. Must not collide with a declared column. */
7000
- kindColumn: string;
7001
- }
7002
-
7003
5821
  /** A chart's semantic content for the hovered observations, in reading order. */
7004
5822
  export declare interface TooltipContent {
7005
5823
  /** Localized main-axis value of the primary's observation. `null` for polar. */
@@ -7032,29 +5850,6 @@ export declare interface TooltipRow {
7032
5850
  key: string;
7033
5851
  }
7034
5852
 
7035
- /**
7036
- * Data-transform builder — reshapes the dataset BEFORE any geom maps over it. Pipe one or more
7037
- * onto a spec; they apply in order, ahead of stats and scaling, and affect every layer.
7038
- *
7039
- * - `reshape(opts?)` — pivot wide numeric columns to long form (key/value); the move for plotting
7040
- * several metrics as one color-split series.
7041
- * - `filter(opts)` — keep observations matching `variableName <operator> value`.
7042
- * - `sort(opts)` — order observations by a variable (`'asc'` | `'desc'`).
7043
- * - `aggregate(opts)` — group by variables and reduce each group (sum/mean/count/…).
7044
- * - `constant(opts)` — add a column with a fixed value on every observation.
7045
- *
7046
- * @example
7047
- * import { pipe, createSpec, geom, scale, transform } from '@graphysdk/viz-engine';
7048
- *
7049
- * pipe(
7050
- * createSpec({ x: 'region', y: 'total', color: 'region' }),
7051
- * transform.filter({ variableName: 'year', operator: 'eq', value: 2024 }),
7052
- * transform.aggregate({ groupby: ['region'], operations: [{ op: 'sum', variableName: 'revenue', as: 'total' }] }),
7053
- * geom.bar(),
7054
- * scale.x(),
7055
- * scale.y()
7056
- * );
7057
- */
7058
5853
  export declare const transform: {
7059
5854
  reshape: typeof reshape;
7060
5855
  filter: typeof filter;
@@ -7080,71 +5875,27 @@ declare interface TransformCompilerInput {
7080
5875
  transforms: TransformInput[];
7081
5876
  }
7082
5877
 
7083
- /**
7084
- * A registered custom transform: a {@link TransformStrategy} the compiler consumes, carrying the option
7085
- * type so `createGraphyBuilder({ transforms })` can type its `transform.<type>(options)` builder method.
7086
- */
7087
- export declare interface TransformDef<TType extends string = string, TOptions extends object = object> extends TransformStrategy {
7088
- readonly transformType: TType;
7089
- /**
7090
- * Phantom — carries the options type to the type level so the registration-typed builder can recover
7091
- * the transform's options. Never set at runtime.
7092
- */
7093
- readonly __options?: TOptions;
7094
- }
7095
-
7096
- /**
7097
- * The manifest passed to {@link defineTransform}. Declares the `transformType` and an `apply` that
7098
- * reshapes the dataset given the transform's plain-data options.
7099
- */
7100
- export declare interface TransformDefinitionManifest<TType extends string = string, TOptions extends object = object> {
7101
- /** The registered transform name; keys both the registry and the `transform.<type>(...)` builder method. */
7102
- transformType: TType;
7103
- /** Reshapes the dataset given the transform's options. Mapping-blind, whole-table surgery. */
7104
- apply: (data: Dataset, options: TOptions) => Dataset;
7105
- }
7106
-
7107
- /**
7108
- * The open identity of a transform: a built-in {@link TransformType} or any custom transform's
7109
- * `transformType` string registered via `createCompiler({ transforms })` (mirrors `GeomIdentity`).
7110
- */
7111
- export declare type TransformIdentity = TransformType | (string & {});
7112
-
7113
- /**
7114
- * Any value the `transform` builder produces. Transforms run before stats and scaling, in the
7115
- * order they appear, reshaping the dataset that every layer then maps over.
7116
- */
7117
- export declare type TransformInput = BuiltinTransformInput | CustomTransformInput;
7118
-
7119
- /**
7120
- * The options a registered custom transform's builder method accepts — recovered structurally from the
7121
- * definition's phantom options type.
7122
- */
7123
- declare type TransformOptionsOf<Definition> = Definition extends TransformDef<string, infer TOptions> ? TOptions : never;
5878
+ /***************************************************************
5879
+ * Transform Input
5880
+ ***************************************************************/
5881
+ declare type TransformInput = ReshapeTransformInput | FilterTransformInput | SortTransformInput | AggregateTransformInput | ConstantTransformInput;
7124
5882
 
7125
5883
  /**
7126
- * Transform strategies keyed by `transformType`. Built-ins register first; any custom transforms
7127
- * injected via `createCompiler({ transforms })` register afterwards (a custom `transformType` matching
7128
- * a built-in overrides it, last write wins) — mirroring `GeomRegistry` / `StatRegistry`.
5884
+ * Built-in transform implementations keyed by transform type.
7129
5885
  */
7130
- declare class TransformRegistry extends Registry<string, TransformStrategy> {
7131
- constructor(opts?: {
7132
- transforms?: readonly TransformStrategy[];
7133
- });
5886
+ declare class TransformRegistry extends Registry<TransformType, TransformStrategy> {
5887
+ constructor();
7134
5888
  }
7135
5889
 
7136
5890
  /**
7137
- * Strategy interface for compiling a specific transform type. Built-ins use a literal
7138
- * {@link TransformType}; custom transforms authored with `defineTransform` carry any registered
7139
- * `transformType` string ({@link TransformIdentity}).
5891
+ * Strategy interface for compiling a specific transform type.
7140
5892
  */
7141
- export declare interface TransformStrategy {
7142
- readonly transformType: TransformIdentity;
5893
+ declare interface TransformStrategy {
5894
+ readonly transformType: TransformType;
7143
5895
  apply: (data: Dataset, transform: TransformInput) => Dataset;
7144
5896
  }
7145
5897
 
7146
- /** Discriminant tag of a built-in {@link TransformInput}. */
7147
- export declare type TransformType = BuiltinTransformInput['transformType'];
5898
+ declare type TransformType = TransformInput['transformType'];
7148
5899
 
7149
5900
  declare type TrendlineType = 'linear' | 'loess' | 'exponential' | 'logarithmic' | 'quadratic' | 'power' | 'polynomial';
7150
5901
 
@@ -7190,39 +5941,27 @@ export declare interface ValueFormatterFactoryParams<T = ValueFormat> {
7190
5941
  }
7191
5942
 
7192
5943
  /**
7193
- * Pins a channel to a single literal value applied to every observation, instead of reading a column.
7194
- * Use it for reference-line constants (`geom.rule({ aes: { y: { value: 2500 } } })`) or to force a fixed
7195
- * style (`aes: { lineType: { value: 'dashed' } }`). Analogous to Vega-Lite's `{datum: X}`.
5944
+ * Constant mapping - a literal value applied to every observation.
5945
+ * Analogous to Vega-Lite's `{datum: X}` / ggplot2's `aes(color = "literal")`.
7196
5946
  */
7197
5947
  declare interface ValueMapping {
7198
- /** The constant — a number, string, Date, or null — shared by all observations. */
7199
5948
  value: DataValue;
7200
5949
  }
7201
5950
 
7202
5951
  /** A column of a variable in the dataset. When `valueFormat` is omitted, the Dataset assigns a type-based default (`numeric → decimal`, `categorical → text`, `temporal → date`). */
7203
- export declare type Variable = {
5952
+ declare type Variable = {
7204
5953
  type: DataType;
7205
5954
  values: DataValue[];
7206
5955
  valueFormat?: ValueFormat;
7207
5956
  };
7208
5957
 
7209
- /**
7210
- * The internal dataset variable a channel reads and writes, derived from its axis and open name. The
7211
- * built-in names (`point`/`lower`/`upper`) resolve to the canonical position columns (`x`, `xMin`, …),
7212
- * so value readers and renderer recipes stay untouched; any other name resolves to a namespaced column,
7213
- * so a custom scaled channel never collides with a built-in or another geom's channel.
7214
- */
7215
- export declare function variableFor(axis: ChannelAxis, name: string): string;
7216
-
7217
5958
  /** A map of variable names to their type and values. */
7218
- export declare type VariableMap = Record<VariableName, Variable>;
5959
+ declare type VariableMap = Record<VariableName, Variable>;
7219
5960
 
7220
5961
  /**
7221
- * Binds a channel to a data column by name. `{ variable: 'revenue' }` reads the `revenue` column
7222
- * per observation. Equivalent to the bare-string shorthand `'revenue'` in an {@link AesMapping}.
5962
+ * Variable mapping - references a column in the data
7223
5963
  */
7224
5964
  declare interface VariableMapping {
7225
- /** Column key in the data, matching a `columns[i].key`. */
7226
5965
  variable: string;
7227
5966
  }
7228
5967
 
@@ -7231,20 +5970,15 @@ declare type VariableMetadata = Record<VariableName, {
7231
5970
  valueFormat: ValueFormat;
7232
5971
  }>;
7233
5972
 
7234
- /** 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. */
5973
+ /** A type alias for variable names. */
7235
5974
  export declare type VariableName = string;
7236
5975
 
7237
5976
  /**
7238
- * A value test against one post-transform user column. The selected operator
7239
- * decides which observations a highlight emphasises:
7240
- * - `eq`: column equals the value.
7241
- * - `oneOf`: column is one of the listed values.
7242
- * - `lt` / `lte` / `gt` / `gte`: ordering comparison (numeric / datetime only).
7243
- * - `range`: inclusive `[min, max]` interval.
5977
+ * Field-based predicates against post-transform user columns.
7244
5978
  *
7245
- * Comparison values are `DataValue`s coerced at evaluation time by the
7246
- * referenced column's `DataType`. Ordering operators against a categorical
7247
- * field are a resolve-time validation error.
5979
+ * `lt`, `lte`, `gt`, `gte`, and `range` accept `DataValue`s and are coerced at
5980
+ * evaluation time by the referenced column's `DataType`. Ordering operators
5981
+ * against a categorical field are a resolve-time validation error.
7248
5982
  */
7249
5983
  export declare type VariablePredicate = {
7250
5984
  variable: VariableName;
@@ -7314,7 +6048,7 @@ declare interface XAxisConfig {
7314
6048
  */
7315
6049
  label: string | null;
7316
6050
  /**
7317
- * Position of the x axis.
6051
+ * Position of the y axis.
7318
6052
  * @default 'bottom'
7319
6053
  */
7320
6054
  position: AxisPosition;