@opendata-ai/openchart-core 8.0.0-rc.9 → 8.1.0

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.
Files changed (83) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +403 -45
  3. package/dist/index.js +50 -18
  4. package/dist/index.js.map +1 -1
  5. package/dist/styles.css +1 -1
  6. package/dist/styles.css.map +1 -1
  7. package/package.json +1 -2
  8. package/schema/chart.schema.json +375 -69
  9. package/schema/table.schema.json +35 -1
  10. package/schema/vizspec.schema.json +992 -171
  11. package/src/accessibility/__tests__/alt-text.test.ts +0 -110
  12. package/src/accessibility/__tests__/aria.test.ts +0 -125
  13. package/src/accessibility/alt-text.ts +0 -155
  14. package/src/accessibility/aria.ts +0 -75
  15. package/src/accessibility/index.ts +0 -6
  16. package/src/colors/__tests__/colorblind.test.ts +0 -75
  17. package/src/colors/__tests__/contrast.test.ts +0 -119
  18. package/src/colors/__tests__/palettes.test.ts +0 -74
  19. package/src/colors/colorblind.ts +0 -131
  20. package/src/colors/contrast.ts +0 -143
  21. package/src/colors/index.ts +0 -36
  22. package/src/colors/palettes.ts +0 -206
  23. package/src/helpers/__tests__/deep-merge.test.ts +0 -54
  24. package/src/helpers/__tests__/spec-builders.test.ts +0 -338
  25. package/src/helpers/deep-merge.ts +0 -29
  26. package/src/helpers/spec-builders.ts +0 -479
  27. package/src/index.ts +0 -215
  28. package/src/labels/__tests__/collision.test.ts +0 -310
  29. package/src/labels/collision.ts +0 -249
  30. package/src/labels/index.ts +0 -13
  31. package/src/layout/__tests__/chrome.test.ts +0 -208
  32. package/src/layout/__tests__/text-measure.test.ts +0 -57
  33. package/src/layout/chrome.ts +0 -470
  34. package/src/layout/index.ts +0 -18
  35. package/src/layout/text-measure.ts +0 -404
  36. package/src/layout/text-wrap.ts +0 -93
  37. package/src/locale/__tests__/format.test.ts +0 -606
  38. package/src/locale/format.ts +0 -459
  39. package/src/locale/index.ts +0 -21
  40. package/src/responsive/__tests__/breakpoints.test.ts +0 -146
  41. package/src/responsive/__tests__/metrics.test.ts +0 -52
  42. package/src/responsive/breakpoints.ts +0 -177
  43. package/src/responsive/index.ts +0 -53
  44. package/src/responsive/metrics.ts +0 -299
  45. package/src/schema/__tests__/generated-artifacts.test.ts +0 -42
  46. package/src/schema/__tests__/schema.test.ts +0 -179
  47. package/src/styles/__tests__/reduced-motion-selectors.test.ts +0 -28
  48. package/src/styles/animation.css +0 -213
  49. package/src/styles/base.css +0 -102
  50. package/src/styles/chrome.css +0 -174
  51. package/src/styles/dark.css +0 -44
  52. package/src/styles/graph.css +0 -135
  53. package/src/styles/index.css +0 -28
  54. package/src/styles/keyframes.css +0 -151
  55. package/src/styles/legend.css +0 -18
  56. package/src/styles/reduced-motion.css +0 -67
  57. package/src/styles/series-search.css +0 -153
  58. package/src/styles/sparkline.css +0 -16
  59. package/src/styles/table-animation.css +0 -93
  60. package/src/styles/table.css +0 -398
  61. package/src/styles/token-definitions.ts +0 -199
  62. package/src/styles/tokens.css +0 -156
  63. package/src/styles/tooltip.css +0 -126
  64. package/src/styles/you-draw-it.css +0 -126
  65. package/src/theme/__tests__/dark-mode.test.ts +0 -232
  66. package/src/theme/__tests__/defaults.test.ts +0 -73
  67. package/src/theme/__tests__/resolve.test.ts +0 -277
  68. package/src/theme/dark-mode.ts +0 -258
  69. package/src/theme/defaults.ts +0 -110
  70. package/src/theme/index.ts +0 -8
  71. package/src/theme/presets.ts +0 -64
  72. package/src/theme/resolve.ts +0 -312
  73. package/src/types/__tests__/encoding.test.ts +0 -368
  74. package/src/types/__tests__/gradient.test.ts +0 -95
  75. package/src/types/__tests__/spec.test.ts +0 -499
  76. package/src/types/encoding.ts +0 -280
  77. package/src/types/events.ts +0 -236
  78. package/src/types/index.ts +0 -290
  79. package/src/types/layout.ts +0 -2024
  80. package/src/types/schema-roots.ts +0 -32
  81. package/src/types/spec.ts +0 -2925
  82. package/src/types/table.ts +0 -108
  83. package/src/types/theme.ts +0 -209
package/dist/index.d.ts CHANGED
@@ -67,7 +67,12 @@ interface LayoutStrategy {
67
67
  *
68
68
  * Compact: minimal chrome, no inline labels, legend on top, reduced axes.
69
69
  * Medium: moderate labels, legend on top, reduced axes.
70
- * Full: all labels, legend on right, full axes.
70
+ * Full: all labels, legend on top, full axes.
71
+ *
72
+ * Legend position is 'top' at every breakpoint: a top legend reads as a key to
73
+ * the chart before the eye reaches the plot, and it keeps the plotting area
74
+ * full-width instead of surrendering a right-hand column. `legend.position`
75
+ * still overrides it per spec.
71
76
  *
72
77
  * Height constraints further reduce chrome and legend when container is short.
73
78
  */
@@ -432,6 +437,29 @@ declare function isGradientDef(value: unknown): value is GradientDef;
432
437
  * overlays that need a flat color.
433
438
  */
434
439
  declare function getRepresentativeColor(fill: string | GradientDef): string;
440
+ /**
441
+ * Configuration for the scatter regression trend line. Passed as the object
442
+ * form of `MarkDef.trendline`.
443
+ */
444
+ interface TrendlineConfig {
445
+ /**
446
+ * Stacking order relative to the point marks. `'below'` (default) draws the
447
+ * line behind the dots; `'above'` draws it on top so it stays visible over a
448
+ * dense cloud.
449
+ */
450
+ layer?: 'above' | 'below';
451
+ /**
452
+ * Stroke color. Defaults to the theme's high-contrast text color so the line
453
+ * reads on both light and dark grounds. Set an explicit CSS color to override.
454
+ */
455
+ stroke?: string;
456
+ /**
457
+ * Stroke width in pixels. Defaults to 1.5. Over a dense cloud with `layer:
458
+ * 'above'`, a heavier line (e.g. 2.5) stays legible where the thin default
459
+ * disappears into the dots.
460
+ */
461
+ strokeWidth?: number;
462
+ }
435
463
  /**
436
464
  * Mark definition object with visual properties.
437
465
  *
@@ -479,7 +507,15 @@ interface MarkDef {
479
507
  endAngle?: number;
480
508
  /** Corner radius for rect/bar marks. 'pill' sets rx to half the bar thickness. */
481
509
  cornerRadius?: number | 'pill';
482
- /** Fixed bar thickness in pixels for bar/column marks. When set, bars are this height (horizontal) or width (vertical), centered within the band. */
510
+ /**
511
+ * Bar/column marks: fixed bar thickness in pixels. When set, bars are this
512
+ * height (horizontal) or width (vertical), centered within the band.
513
+ *
514
+ * Point marks: the dot RADIUS in pixels (default 5, typical 2-12). This is
515
+ * NOT Vega-Lite's point `size`, which is an area in px^2 -- a VL size of
516
+ * 110 corresponds to `size: 6` here (r = sqrt(area / pi)). Validation
517
+ * rejects values above 50 with the conversion.
518
+ */
483
519
  size?: number;
484
520
  /** Whether the mark is filled (vs stroked only). */
485
521
  filled?: boolean;
@@ -501,8 +537,13 @@ interface MarkDef {
501
537
  * suppress it when the chart already carries its own reference line (e.g. a
502
538
  * manual x=y diagonal in a separate layer), which would otherwise produce
503
539
  * two competing diagonals.
540
+ *
541
+ * Pass an object to control stacking order: the line renders `below` the
542
+ * points by default, but a dense scatter (thousands of overlapping dots)
543
+ * fully occludes a line drawn underneath, so `{ layer: 'above' }` lifts the
544
+ * reference line over the cloud.
504
545
  */
505
- trendline?: boolean;
546
+ trendline?: boolean | TrendlineConfig;
506
547
  /**
507
548
  * Horizontal pixel offset from the data anchor. Only meaningful when `type`
508
549
  * is `'text'`. Use it to lift a label clear of the mark it annotates instead
@@ -684,7 +725,13 @@ interface ScaleConfig {
684
725
  reverse?: boolean;
685
726
  /** Clamp output to the range. */
686
727
  clamp?: boolean;
687
- /** Padding for band/point scales. */
728
+ /**
729
+ * Padding for band/point scales. Point-scale default (a categorical x/y on a
730
+ * line/area/point mark) is 0 for line and area marks (the trend runs flush
731
+ * to the plot edges) and 0.5 for other marks (e.g. scatter, so points don't
732
+ * collide with the axis). `paddingOuter` is accepted as an alias here since
733
+ * point scales have no inner bands.
734
+ */
688
735
  padding?: number;
689
736
  /** Inner padding for band scales. */
690
737
  paddingInner?: number;
@@ -902,9 +949,13 @@ interface Encoding<TData extends DataRow = DataRow> {
902
949
  */
903
950
  color?: EncodingChannel<TData> | ConditionalValueDef<TData> | ValueDef;
904
951
  /**
905
- * Size channel. Used by point/bubble charts to scale dot area by a quantitative field.
906
- * Accepts a conditional definition to vary size based on data predicates,
907
- * or a bare `{ value }` constant (VL aligned; expanded to `mark.size`).
952
+ * Size channel. Used by point/bubble charts to scale dots by a quantitative
953
+ * field, area-proportionally (sqrt curve). The units are dot RADII in px:
954
+ * `scale.range` defaults to [3, 30] for scatter, and a bare `{ value }`
955
+ * constant expands to `mark.size`, also a radius. This differs from
956
+ * Vega-Lite, where point size is an area in px^2 -- VL-scale values
957
+ * (60-900) are rejected by validation with the conversion.
958
+ * Accepts a conditional definition to vary size based on data predicates.
908
959
  */
909
960
  size?: EncodingChannel<TData> | ConditionalValueDef<TData> | ValueDef;
910
961
  /**
@@ -968,6 +1019,20 @@ interface Encoding<TData extends DataRow = DataRow> {
968
1019
  * per-panel axes.
969
1020
  */
970
1021
  facet?: FacetChannel<TData>;
1022
+ /**
1023
+ * Row facet channel: partitions data into vertically-stacked panels.
1024
+ * Each unique value of the row field produces one panel, arranged in a
1025
+ * single column. Shares the x-axis scale by default; y-axis is independent.
1026
+ * Mutually exclusive with `facet` and `column`.
1027
+ */
1028
+ row?: FacetChannel<TData>;
1029
+ /**
1030
+ * Column facet channel: partitions data into side-by-side panels.
1031
+ * Each unique value of the column field produces one panel, arranged in a
1032
+ * single row. Shares the y-axis scale by default; x-axis is independent.
1033
+ * Mutually exclusive with `facet` and `row`.
1034
+ */
1035
+ column?: FacetChannel<TData>;
971
1036
  }
972
1037
  /** Encoding channel for graph nodes and edges. */
973
1038
  interface GraphEncodingChannel {
@@ -977,13 +1042,40 @@ interface GraphEncodingChannel {
977
1042
  type?: FieldType;
978
1043
  /** Scale configuration. Auto-derived from data if omitted. */
979
1044
  scale?: ScaleConfig;
1045
+ /**
1046
+ * Category ordering for the color domain and legend. Graph channels default
1047
+ * `'ascending'` (VL-aligned, deterministic); `string[]` pins an explicit
1048
+ * order; `null` keeps data order.
1049
+ *
1050
+ * NOTE: chart encoding channels keep data-order — this graph default is a
1051
+ * deliberate divergence this release (see docs/migrating-v8.md).
1052
+ */
1053
+ sort?: 'ascending' | 'descending' | null | string[];
1054
+ /**
1055
+ * Category values to emphasize on load; the rest dim. Mirrors the chart
1056
+ * `encoding.color.highlight` value list. Distinct from the `highlight()`
1057
+ * runtime verb and `interaction.hover.mode`.
1058
+ */
1059
+ highlight?: string | string[];
980
1060
  }
981
1061
  /** Graph-specific encoding mapping visual properties to node/edge data fields. */
982
1062
  interface GraphEncoding {
983
1063
  /** Color mapping for nodes. */
984
1064
  nodeColor?: GraphEncodingChannel;
985
- /** Size mapping for nodes. */
1065
+ /**
1066
+ * Size mapping for nodes. `scale.type` defaults to `'sqrt'` (area-perceptual,
1067
+ * today's behavior); set `scale.type: 'linear'` for a linear radius ramp.
1068
+ * `scale.range` sets the pixel radius extent (default `[3, 12]`).
1069
+ */
986
1070
  nodeSize?: GraphEncodingChannel;
1071
+ /**
1072
+ * Opacity mapping for nodes (VL opacity channel). Quantitative fields map
1073
+ * linearly to `[0.25, 1]`; `scale.range` overrides.
1074
+ *
1075
+ * NOTE: there is deliberately no `edgeOpacity` channel — edge alpha is owned
1076
+ * by the interaction alpha-tier machinery (hover dimming, search).
1077
+ */
1078
+ nodeOpacity?: GraphEncodingChannel;
987
1079
  /** Color mapping for edges. */
988
1080
  edgeColor?: GraphEncodingChannel;
989
1081
  /** Width mapping for edges. */
@@ -992,6 +1084,13 @@ interface GraphEncoding {
992
1084
  edgeStyle?: GraphEncodingChannel;
993
1085
  /** Label field for nodes. */
994
1086
  nodeLabel?: GraphEncodingChannel;
1087
+ /**
1088
+ * Label priority mapping for nodes. Maps a quantitative field to a 0-1
1089
+ * priority range; higher values are shown first as the user zooms in.
1090
+ * Omit to use the default degree-based priority.
1091
+ * `nodeOverrides[id].alwaysShowLabel` still wins as the hard override.
1092
+ */
1093
+ nodeLabelPriority?: GraphEncodingChannel;
995
1094
  }
996
1095
  /** Layout algorithm for graph visualization. */
997
1096
  interface GraphLayoutConfig {
@@ -1012,6 +1111,31 @@ interface GraphLayoutConfig {
1012
1111
  linkStrength?: number;
1013
1112
  /** Whether to apply center force (default true). */
1014
1113
  centerForce?: boolean;
1114
+ /**
1115
+ * Deterministic layout seed. Same spec + seed ⇒ identical settled layout
1116
+ * within a given execution path (worker vs sync parity is not guaranteed).
1117
+ */
1118
+ seed?: number;
1119
+ /**
1120
+ * Repulsion preset (plain-language, no d3 jargon):
1121
+ * `gentle`/`balanced`/`energetic` → chargeStrength −150/−300/−600 and
1122
+ * velocityDecay 0.5/0.4/0.3. A raw `chargeStrength` wins over the preset.
1123
+ */
1124
+ energy?: 'gentle' | 'balanced' | 'energetic';
1125
+ /**
1126
+ * Settle-speed preset: `quick`/`balanced`/`thorough` → alphaDecay
1127
+ * 0.05/0.0228/0.01. Higher = faster cool-down, less final refinement.
1128
+ */
1129
+ settle?: 'quick' | 'balanced' | 'thorough';
1130
+ /**
1131
+ * Headless settle ticks run before the first paint. `true` → 100 ticks under
1132
+ * a 250ms budget; a number sets an explicit tick count; `false` disables.
1133
+ *
1134
+ * Lives in `layout`, NOT `animation`, on purpose: warmup *reduces* motion, so
1135
+ * it must survive `animation: false` (opt-out consumers get less settling
1136
+ * chaos, not more).
1137
+ */
1138
+ warmup?: boolean | number;
1015
1139
  }
1016
1140
  /** Style overrides for a chrome text element. */
1017
1141
  interface ChromeTextStyle {
@@ -1023,6 +1147,14 @@ interface ChromeTextStyle {
1023
1147
  fontFamily?: string;
1024
1148
  /** Text color (CSS color string). */
1025
1149
  color?: string;
1150
+ /**
1151
+ * Maximum number of lines this chrome text may wrap to. Additional lines are
1152
+ * dropped and the last kept line is truncated with an ellipsis. Bounds the
1153
+ * chrome's contribution to layout height at any container width. Applies
1154
+ * whether the font size comes from the theme default or an explicit override.
1155
+ * Caps height only, not horizontal overflow of a single unbreakable word.
1156
+ */
1157
+ maxLines?: number;
1026
1158
  }
1027
1159
  /** A chrome text element with optional style overrides. */
1028
1160
  interface ChromeText {
@@ -1613,6 +1745,20 @@ interface AnimationPhaseConfig {
1613
1745
  /** Stagger config. true = defaults, false = no stagger. Default: true for enter. */
1614
1746
  stagger?: AnimationStagger | boolean;
1615
1747
  }
1748
+ /**
1749
+ * Data-update phase config. Adds `maxMarks` on top of the shared phase
1750
+ * options; the cap is meaningless for enter/exit, which animate via CSS.
1751
+ */
1752
+ interface UpdatePhaseConfig extends AnimationPhaseConfig {
1753
+ /**
1754
+ * Maximum mark count that still runs a tweened data-update transition.
1755
+ * Default: 500. Above the cap the chart swaps instantly instead, because
1756
+ * per-frame SVG attribute writes on thousands of elements drop frames on
1757
+ * low-end devices. Raise it deliberately when the audience is desktop-heavy
1758
+ * and you have measured the frame budget.
1759
+ */
1760
+ maxMarks?: number;
1761
+ }
1616
1762
  /**
1617
1763
  * Full animation config object. Structured as enter/update/exit phases
1618
1764
  * following Vega's encoding set model.
@@ -1621,7 +1767,7 @@ interface AnimationConfig {
1621
1767
  /** Entrance animation when chart first renders. */
1622
1768
  enter?: AnimationPhaseConfig | boolean;
1623
1769
  /** Transition animation when data updates. */
1624
- update?: AnimationPhaseConfig | boolean;
1770
+ update?: UpdatePhaseConfig | boolean;
1625
1771
  /** Exit animation when marks are removed. */
1626
1772
  exit?: AnimationPhaseConfig | boolean;
1627
1773
  /** Delay before annotations animate in (ms after marks). Default: 200. */
@@ -1876,6 +2022,20 @@ interface BaseChartSpec<TData extends DataRow = DataRow> {
1876
2022
  transform?: Transform[];
1877
2023
  /** Editorial chrome (title, subtitle, source, etc.). */
1878
2024
  chrome?: Chrome;
2025
+ /**
2026
+ * How chrome height interacts with the container height budget.
2027
+ *
2028
+ * - `'subtract'` (default): the container height is fixed and chrome text
2029
+ * (title/subtitle/source) is subtracted from it, shrinking the plot. This
2030
+ * is the historical behavior.
2031
+ * - `'grow'`: the container height is treated as the *plot* budget, and the
2032
+ * rendered SVG grows taller by the measured chrome height. The plot keeps
2033
+ * its full budget (minus axis/padding overhead) regardless of how many
2034
+ * lines the title wraps to.
2035
+ *
2036
+ * `'grow'` is a no-op for faceted specs in this version.
2037
+ */
2038
+ chromeLayout?: 'subtract' | 'grow';
1879
2039
  /**
1880
2040
  * Top-level title sugar (Vega-Lite aligned). Expanded into `chrome.title`
1881
2041
  * (and `chrome.subtitle` for the object form). `chrome.title` wins when
@@ -1940,7 +2100,11 @@ interface BaseChartSpec<TData extends DataRow = DataRow> {
1940
2100
  theme?: ThemeConfig;
1941
2101
  /** Dark mode behavior. Defaults to "off". */
1942
2102
  darkMode?: DarkMode;
1943
- /** Whether to show the tryOpenData.ai watermark. Defaults to true. */
2103
+ /**
2104
+ * Whether to show the tryOpenData.ai watermark. Defaults to true; auto-hides
2105
+ * when the container is under 200px tall (the cramped height class) unless
2106
+ * explicitly set.
2107
+ */
1944
2108
  watermark?: boolean;
1945
2109
  /**
1946
2110
  * Series names to hide from rendering by default. This is the authored
@@ -2200,6 +2364,70 @@ interface NodeOverride {
2200
2364
  /** Force label to always show regardless of zoom/priority. */
2201
2365
  alwaysShowLabel?: boolean;
2202
2366
  }
2367
+ /**
2368
+ * Per-phase and per-behavior motion config for a graph.
2369
+ *
2370
+ * DEFAULT-ON semantics (deliberately different from charts, which are opt-in):
2371
+ * omit `animation` → the resolver returns full defaults; `animation: false` →
2372
+ * no choreography (but `layout.warmup` still applies); a per-phase `false`
2373
+ * disables just that phase. Graphs are default-on because physics motion
2374
+ * already exists on load and choreography reduces the chaos.
2375
+ */
2376
+ interface GraphAnimationConfig {
2377
+ /** Node/edge reveal on first render. Default `{ duration: 500, ease: 'smooth', stagger: true }`. */
2378
+ enter?: AnimationPhaseConfig | boolean;
2379
+ /** Data-update enter-fade for newly added marks. Default `{ duration: 300, ease: 'smooth' }`. */
2380
+ update?: AnimationPhaseConfig | boolean;
2381
+ /** Ghost fade-out for removed marks. Default `{ duration: 300, ease: 'smooth' }`. */
2382
+ exit?: AnimationPhaseConfig | boolean;
2383
+ /** Camera flight easing. Default duration `'auto'` (derived from the zoom distance). */
2384
+ camera?: {
2385
+ duration?: number;
2386
+ ease?: AnimationEase;
2387
+ } | boolean;
2388
+ /** Hover emphasis crossfade. Default `{ duration: 150, ease: 'smooth' }`. */
2389
+ hover?: {
2390
+ duration?: number;
2391
+ ease?: AnimationEase;
2392
+ } | boolean;
2393
+ }
2394
+ /**
2395
+ * Graph motion spec.
2396
+ * - omitted → full defaults (default-ON)
2397
+ * - `false` → no choreography (warmup still applies)
2398
+ * - object → per-phase control
2399
+ *
2400
+ * `prefers-reduced-motion` is always respected regardless of this value.
2401
+ */
2402
+ type GraphAnimationSpec = boolean | GraphAnimationConfig;
2403
+ /** Interaction behavior for a graph (hover mode, select-fly, opt-in physics). */
2404
+ interface GraphInteractionConfig {
2405
+ /**
2406
+ * Hover emphasis behavior. `neighbors` (default) lights the hovered node and
2407
+ * its adjacency; `category` lights same-category nodes; `node` lights only the
2408
+ * hovered node; `none` disables. `dimOpacity` (default 0.15) is the node dim
2409
+ * tier. Named `mode` (not `highlight`) to avoid colliding with the three other
2410
+ * meanings of "highlight" (the encoding value list, the `highlight()` verb).
2411
+ */
2412
+ hover?: {
2413
+ mode?: 'neighbors' | 'category' | 'node' | 'none';
2414
+ dimOpacity?: number;
2415
+ };
2416
+ /** Selecting a node flies the camera to it. Default `false`. */
2417
+ select?: {
2418
+ flyTo?: boolean;
2419
+ };
2420
+ /**
2421
+ * Opt-in cursor repulsion (nodes drift away from the pointer). Disabled under
2422
+ * `prefers-reduced-motion` and above the node-count gate.
2423
+ */
2424
+ cursorRepulsion?: boolean | {
2425
+ radius?: number;
2426
+ strength?: number;
2427
+ };
2428
+ /** Opt-in springy node drag (user-initiated; no reduced-motion gate). */
2429
+ springyDrag?: boolean;
2430
+ }
2203
2431
  interface GraphSpec {
2204
2432
  /** Discriminant: always "graph". */
2205
2433
  type: 'graph';
@@ -2213,6 +2441,26 @@ interface GraphSpec {
2213
2441
  layout?: GraphLayoutConfig;
2214
2442
  /** Per-node visual overrides, keyed by node id. */
2215
2443
  nodeOverrides?: Record<string, NodeOverride>;
2444
+ /**
2445
+ * Node treated as the graph's seed/root: gets a distinct ring and an
2446
+ * always-on label without needing a `nodeOverrides` entry, and stays lit when
2447
+ * a category highlight or legend filter dims everything else.
2448
+ *
2449
+ * String shorthand is the node id; the object form adds styling that layers
2450
+ * under any `nodeOverrides` entry for the same id (an explicit override
2451
+ * always wins). The seed's radius is deliberately left to the `nodeSize`
2452
+ * encoding — set `style.radius` to make it bigger.
2453
+ *
2454
+ * NOT related to `layout.seed`, which is the deterministic RNG seed for the
2455
+ * force layout. This field names a node; `layout.seed` is a number.
2456
+ *
2457
+ * An id that isn't in `nodes` warns and is ignored (it does not throw), so a
2458
+ * filtered or paginated node update can't crash the host.
2459
+ */
2460
+ seedNode?: string | {
2461
+ id: string;
2462
+ style?: NodeOverride;
2463
+ };
2216
2464
  /** Editorial chrome. */
2217
2465
  chrome?: Chrome;
2218
2466
  /** Annotations. */
@@ -2221,6 +2469,21 @@ interface GraphSpec {
2221
2469
  theme?: ThemeConfig;
2222
2470
  /** Dark mode behavior. */
2223
2471
  darkMode?: DarkMode;
2472
+ /**
2473
+ * Motion configuration. DEFAULT-ON: omit for full defaults, `false` to opt
2474
+ * out of choreography (layout warmup still applies).
2475
+ */
2476
+ animation?: GraphAnimationSpec;
2477
+ /** Interaction behavior (hover mode, select-fly, opt-in physics). */
2478
+ interaction?: GraphInteractionConfig;
2479
+ /**
2480
+ * Built-in legend. Interactive by default. Set `false` if you render your own
2481
+ * legend, so the built-in filter UI doesn't compete with it.
2482
+ */
2483
+ legend?: boolean | {
2484
+ interactive?: boolean;
2485
+ counts?: boolean;
2486
+ };
2224
2487
  /** Whether to show the tryOpenData.ai watermark. Defaults to true. */
2225
2488
  watermark?: boolean;
2226
2489
  }
@@ -2446,32 +2709,32 @@ interface TileMapSpec {
2446
2709
  valueFormat?: string;
2447
2710
  }
2448
2711
  /** Supported map projections. */
2449
- type MapProjection = 'albersUsa' | 'mercator' | 'equalEarth' | 'identity';
2712
+ type GeoMapProjection = 'albersUsa' | 'mercator' | 'equalEarth' | 'identity';
2450
2713
  /** Focus target for map camera: feature id(s) to zoom/pan to. */
2451
2714
  /**
2452
2715
  * Fit the point layer's cluster. `true` fits every point; `{ field, value }`
2453
2716
  * fits only the points whose data row has `row[field] === value` (e.g. only the
2454
2717
  * campuses rated "F"), which lets a story pan between sub-clusters.
2455
2718
  */
2456
- type MapPointsFocus = true | {
2719
+ type GeoMapPointsFocus = true | {
2457
2720
  field: string;
2458
2721
  value: string | number;
2459
2722
  };
2460
- type MapFocus = string | number | Array<string | number> | {
2723
+ type GeoMapFocus = string | number | Array<string | number> | {
2461
2724
  features: string | number | Array<string | number>;
2462
2725
  padding?: number;
2463
2726
  } | {
2464
- points: MapPointsFocus;
2727
+ points: GeoMapPointsFocus;
2465
2728
  padding?: number;
2466
2729
  };
2467
2730
  /** Geo configuration for map specs. */
2468
- interface MapGeo {
2731
+ interface GeoMapGeo {
2469
2732
  /** TopoJSON topology object. User imports this from us-atlas, world-atlas, or their own source. */
2470
2733
  features: unknown;
2471
2734
  /** Field in the TopoJSON feature properties to use as the join key. Defaults to 'id'. */
2472
2735
  idField?: string;
2473
2736
  /** Map projection. Defaults to 'albersUsa'. */
2474
- projection?: MapProjection;
2737
+ projection?: GeoMapProjection;
2475
2738
  /**
2476
2739
  * Focus the camera. A feature id (or array) fits those features; `{ features, padding }`
2477
2740
  * adds breathing room; `{ points: true, padding }` fits the points layer's cluster
@@ -2480,10 +2743,10 @@ interface MapGeo {
2480
2743
  * `{ points: { field, value }, padding }` fits only the matching point subset, so a
2481
2744
  * story can pan between sub-clusters. null clears focus from a prior story step.
2482
2745
  */
2483
- focus?: MapFocus | null;
2746
+ focus?: GeoMapFocus | null;
2484
2747
  }
2485
2748
  /** Encoding channels specific to map visualizations. */
2486
- interface MapEncoding {
2749
+ interface GeoMapEncoding {
2487
2750
  /** Join key field in the data. Required for choropleth; optional in basemap-only mode (points layer with empty data). */
2488
2751
  key?: EncodingChannel;
2489
2752
  /** Color encoding (quantitative or nominal). Drives fill color of features. Optional when a points layer is present (basemap-only mode). */
@@ -2492,7 +2755,7 @@ interface MapEncoding {
2492
2755
  tooltip?: EncodingChannel | EncodingChannel[];
2493
2756
  }
2494
2757
  /** Point/symbol layer rendered above choropleth features. */
2495
- interface MapPointsLayer {
2758
+ interface GeoMapPointsLayer {
2496
2759
  /** Tabular data for the points. Independent of the choropleth data join. */
2497
2760
  data: DataRow[];
2498
2761
  /** Field holding longitude (x coordinate). */
@@ -2503,22 +2766,23 @@ interface MapPointsLayer {
2503
2766
  size?: EncodingChannel;
2504
2767
  /** Optional color encoding (nominal or quantitative). Independent scale from choropleth. */
2505
2768
  color?: EncodingChannel;
2506
- /** Tooltip channel(s), same shape as MapEncoding.tooltip. */
2769
+ /** Tooltip channel(s), same shape as GeoMapEncoding.tooltip. */
2507
2770
  tooltip?: EncodingChannel | EncodingChannel[];
2508
- /** Stable id for event callbacks. Data-update transitions for points are not yet supported. */
2771
+ /** Stable id for event callbacks, and the key used to match points across
2772
+ * renders so fill, radius, and position tween on data update. */
2509
2773
  key?: EncodingChannel;
2510
2774
  /** Fill opacity for point circles. Default 0.65. Range 0-1. */
2511
2775
  opacity?: number;
2512
2776
  }
2513
- interface MapSpec {
2777
+ interface GeoMapSpec {
2514
2778
  /** Discriminant: always "map". */
2515
2779
  type: 'map';
2516
2780
  /** Geo configuration: TopoJSON features, join key, and projection. */
2517
- geo: MapGeo;
2781
+ geo: GeoMapGeo;
2518
2782
  /** Tabular data to join to geo features. */
2519
2783
  data: DataRow[];
2520
2784
  /** Encoding channels mapping data fields to visual properties. */
2521
- encoding: MapEncoding;
2785
+ encoding: GeoMapEncoding;
2522
2786
  /** Editorial chrome (title, subtitle, source, byline, footer). */
2523
2787
  chrome?: Chrome;
2524
2788
  /** Legend display configuration. */
@@ -2530,7 +2794,7 @@ interface MapSpec {
2530
2794
  /** Whether to show the tryOpenData.ai watermark. Defaults to true. */
2531
2795
  watermark?: boolean;
2532
2796
  /** Optional point/symbol layer rendered above choropleth features. */
2533
- points?: MapPointsLayer;
2797
+ points?: GeoMapPointsLayer;
2534
2798
  /** Animation configuration for entrance animations. */
2535
2799
  animation?: AnimationSpec;
2536
2800
  /**
@@ -2595,7 +2859,7 @@ interface BarListEncoding {
2595
2859
  * - GraphSpec: has `type: 'graph'`
2596
2860
  * - SankeySpec: has `type: 'sankey'`
2597
2861
  * - TileMapSpec: has `type: 'tilemap'`
2598
- * - MapSpec: has `type: 'map'`
2862
+ * - GeoMapSpec: has `type: 'map'`
2599
2863
  * - BarListSpec: has `type: 'barlist'`
2600
2864
  *
2601
2865
  * Election parliament (hemicycle) charts are `ChartSpec` with `mark:
@@ -2605,7 +2869,7 @@ interface BarListEncoding {
2605
2869
  * for free instead of a second bespoke compile path (see
2606
2870
  * `packages/engine/src/charts/parliament/`).
2607
2871
  */
2608
- type VizSpec = ChartSpec | LayerSpec | TableSpec | GraphSpec | SankeySpec | TileMapSpec | MapSpec | BarListSpec;
2872
+ type VizSpec = ChartSpec | LayerSpec | TableSpec | GraphSpec | SankeySpec | TileMapSpec | GeoMapSpec | BarListSpec;
2609
2873
  /**
2610
2874
  * Chart spec without runtime data, for persistence/storage.
2611
2875
  * Generic: `ChartSpecWithoutData<MyRow>` constrains encoding field names.
@@ -2620,13 +2884,13 @@ type SankeySpecWithoutData = Omit<SankeySpec, 'data'>;
2620
2884
  /** TileMap spec without runtime data, for persistence/storage. */
2621
2885
  type TileMapSpecWithoutData = Omit<TileMapSpec, 'data'>;
2622
2886
  /** Map spec without runtime data, for persistence/storage. */
2623
- type MapSpecWithoutData = Omit<MapSpec, 'data' | 'points'> & {
2624
- points?: Omit<MapPointsLayer, 'data'>;
2887
+ type GeoMapSpecWithoutData = Omit<GeoMapSpec, 'data' | 'points'> & {
2888
+ points?: Omit<GeoMapPointsLayer, 'data'>;
2625
2889
  };
2626
2890
  /** BarList spec without runtime data, for persistence/storage. */
2627
2891
  type BarListSpecWithoutData = Omit<BarListSpec, 'data'>;
2628
2892
  /** Union of data-stripped spec types for persistence/storage. */
2629
- type StoredVizSpec = ChartSpecWithoutData | TableSpecWithoutData | GraphSpecWithoutData | SankeySpecWithoutData | TileMapSpecWithoutData | MapSpecWithoutData | BarListSpecWithoutData;
2893
+ type StoredVizSpec = ChartSpecWithoutData | TableSpecWithoutData | GraphSpecWithoutData | SankeySpecWithoutData | TileMapSpecWithoutData | GeoMapSpecWithoutData | BarListSpecWithoutData;
2630
2894
  /** Logical AND combinator for filter predicates. */
2631
2895
  interface LogicalAnd<T> {
2632
2896
  and: T[];
@@ -2855,8 +3119,8 @@ declare function isSankeySpec(spec: VizSpec | Record<string, unknown>): spec is
2855
3119
  declare function isTileMapSpec(spec: VizSpec | Record<string, unknown>): spec is TileMapSpec;
2856
3120
  /** Check if a spec is a BarListSpec. */
2857
3121
  declare function isBarListSpec(spec: VizSpec | Record<string, unknown>): spec is BarListSpec;
2858
- /** Check if a spec is a MapSpec. */
2859
- declare function isMapSpec(spec: VizSpec | Record<string, unknown>): spec is MapSpec;
3122
+ /** Check if a spec is a GeoMapSpec. */
3123
+ declare function isGeoMapSpec(spec: VizSpec | Record<string, unknown>): spec is GeoMapSpec;
2860
3124
  /** Check if an annotation is a TextAnnotation. */
2861
3125
  declare function isTextAnnotation(annotation: Annotation): annotation is TextAnnotation;
2862
3126
  /** Check if an annotation is a RangeAnnotation. */
@@ -3201,6 +3465,12 @@ interface ResolvedChromeElement {
3201
3465
  y: number;
3202
3466
  /** Maximum width for line wrapping. */
3203
3467
  maxWidth: number;
3468
+ /**
3469
+ * Maximum wrapped lines. When set, the renderer caps the wrapped output to
3470
+ * this many lines and truncates the last kept line with an ellipsis. The
3471
+ * layout height reserved for this element already reflects the cap.
3472
+ */
3473
+ maxLines?: number;
3204
3474
  /** Computed text style. */
3205
3475
  style: TextStyle;
3206
3476
  }
@@ -3242,6 +3512,14 @@ interface AxisTick {
3242
3512
  fullLabel?: string;
3243
3513
  /** Secondary label text from axis.labelField. */
3244
3514
  subtitle?: string;
3515
+ /**
3516
+ * Pixel position the LABEL is drawn at, set only when it differs from
3517
+ * `position` because the label was nudged inward to stay inside the
3518
+ * container. Point/band x-scales run flush to the plot edges, so a label
3519
+ * centered on the outermost tick can spill past the SVG. Gridlines, marks
3520
+ * and transitions still key off `position`; only the text moves.
3521
+ */
3522
+ labelPosition?: number;
3245
3523
  }
3246
3524
  /** A single gridline with computed positions. */
3247
3525
  interface Gridline {
@@ -3809,6 +4087,8 @@ interface LegendEntry {
3809
4087
  active?: boolean;
3810
4088
  /** True for overflow indicator entries ("+N more"). Not interactive. */
3811
4089
  overflow?: boolean;
4090
+ /** Node/edge count for this category (graph legends). Additive; undefined elsewhere. */
4091
+ count?: number;
3812
4092
  }
3813
4093
  /** The encoding channel a legend keys. */
3814
4094
  type LegendChannel = 'color' | 'size';
@@ -4047,6 +4327,12 @@ interface A11yMetadata {
4047
4327
  altText: string;
4048
4328
  /** Tabular data fallback for screen readers. Each inner array is a row. */
4049
4329
  dataTableFallback: unknown[][];
4330
+ /**
4331
+ * True row count of the underlying data. Only set when `dataTableFallback`
4332
+ * was truncated, so its presence is the signal that rows are missing and the
4333
+ * caption should name the total.
4334
+ */
4335
+ totalRows?: number;
4050
4336
  /** ARIA role for the visualization root element. */
4051
4337
  role: string;
4052
4338
  /** Whether the visualization is keyboard-navigable. */
@@ -4069,6 +4355,12 @@ interface ResolvedAnimationPhase {
4069
4355
  staggerDelay: number;
4070
4356
  /** Stagger ordering. */
4071
4357
  staggerOrder: 'index' | 'value' | 'reverse';
4358
+ /**
4359
+ * Author-set cap on the mark count that still runs a tweened data-update
4360
+ * transition (update phase only). Present only when explicitly set on the
4361
+ * spec — the renderer supplies the default so it can vary by render mode.
4362
+ */
4363
+ maxMarks?: number;
4072
4364
  }
4073
4365
  /** Resolved animation config. A phase is present iff that phase is enabled. */
4074
4366
  interface ResolvedAnimation {
@@ -4226,6 +4518,7 @@ interface FacetPanelLayout {
4226
4518
  y: number;
4227
4519
  fontSize: number;
4228
4520
  fontWeight: number;
4521
+ textAnchor?: 'start' | 'middle' | 'end';
4229
4522
  };
4230
4523
  }
4231
4524
  /** Layout for a faceted (small-multiples) chart. */
@@ -4238,6 +4531,8 @@ interface FacetLayout {
4238
4531
  columns: number;
4239
4532
  /** Whether scales are shared across panels. */
4240
4533
  sharedScales: boolean;
4534
+ /** How panels are arranged: 'row' (vertical stack), 'column' (horizontal), 'wrap' (grid). */
4535
+ direction: 'row' | 'column' | 'wrap';
4241
4536
  }
4242
4537
  /**
4243
4538
  * ChartLayout: the complete engine output for chart visualizations.
@@ -4318,6 +4613,16 @@ interface ChartLayout {
4318
4613
  yInvert?: ScaleInvert;
4319
4614
  /** Faceted (small-multiples) layout. When present, renderers iterate panels instead of using top-level marks/axes. */
4320
4615
  facet?: FacetLayout;
4616
+ /**
4617
+ * Resolved rendering backend for point marks. Absent means `'svg'`.
4618
+ *
4619
+ * ADVISORY metadata only: it tells the mount and export layers that a canvas
4620
+ * mark layer is worth creating for this layout. The SVG renderer keys solely
4621
+ * on its own `canvasMarks` render option and never reads this field, so a
4622
+ * server-side or export render of a canvas-mode layout still produces
4623
+ * full-fidelity SVG.
4624
+ */
4625
+ markRenderMode?: 'svg' | 'canvas';
4321
4626
  }
4322
4627
  /** A resolved column definition with computed properties. */
4323
4628
  interface ResolvedColumn {
@@ -4733,7 +5038,7 @@ interface CompileWarning {
4733
5038
  context?: Record<string, unknown>;
4734
5039
  }
4735
5040
  /** Resolved focus target for map camera framing. */
4736
- interface MapFocusLayout {
5041
+ interface GeoMapFocusLayout {
4737
5042
  target: {
4738
5043
  x: number;
4739
5044
  y: number;
@@ -4744,7 +5049,7 @@ interface MapFocusLayout {
4744
5049
  ids: Array<string | number>;
4745
5050
  }
4746
5051
  /** A resolved map feature mark with computed SVG path and fill. */
4747
- interface MapFeatureMark {
5052
+ interface GeoMapFeatureMark {
4748
5053
  type: 'map-feature';
4749
5054
  /** SVG path `d` attribute for this feature's shape. */
4750
5055
  path: string;
@@ -4775,7 +5080,7 @@ interface MapFeatureMark {
4775
5080
  centroid: [number, number];
4776
5081
  }
4777
5082
  /** A resolved map point mark with projected coordinates and visual properties. */
4778
- interface MapPointMark {
5083
+ interface GeoMapPointMark {
4779
5084
  type: 'map-point';
4780
5085
  /** Projected center x in map-local coordinates. */
4781
5086
  cx: number;
@@ -4801,7 +5106,7 @@ interface MapPointMark {
4801
5106
  animationIndex: number;
4802
5107
  }
4803
5108
  /** Border paths for the map (interior borders and coastline/outline). */
4804
- interface MapBorders {
5109
+ interface GeoMapBorders {
4805
5110
  /** SVG path `d` for interior borders between features. */
4806
5111
  interiorPath: string;
4807
5112
  /** SVG path `d` for the outer boundary / coastline. */
@@ -4812,23 +5117,23 @@ interface MapBorders {
4812
5117
  outlineStroke: string;
4813
5118
  }
4814
5119
  /**
4815
- * MapLayout: the complete engine output for map visualizations.
5120
+ * GeoMapLayout: the complete engine output for map visualizations.
4816
5121
  *
4817
5122
  * Contains everything an adapter needs to render the map: dimensions,
4818
5123
  * chrome, feature paths, borders, legend, tooltip descriptors, and
4819
5124
  * accessibility metadata.
4820
5125
  */
4821
- interface MapLayout {
5126
+ interface GeoMapLayout {
4822
5127
  /** The map drawing area (after chrome and legend are subtracted). */
4823
5128
  area: Rect;
4824
5129
  /** Resolved chrome text elements with positions and styles. */
4825
5130
  chrome: ResolvedChrome;
4826
5131
  /** Resolved feature marks with paths, fills, and joined data. */
4827
- features: MapFeatureMark[];
5132
+ features: GeoMapFeatureMark[];
4828
5133
  /** Border paths (interior mesh and outline). */
4829
- borders: MapBorders;
5134
+ borders: GeoMapBorders;
4830
5135
  /** Resolved point marks for the symbol layer (empty array if no points layer). */
4831
- pointMarks: MapPointMark[];
5136
+ pointMarks: GeoMapPointMark[];
4832
5137
  /** Categorical legend for the point color channel (null if no point color). */
4833
5138
  pointCategoricalLegend: CategoricalLegendLayout | null;
4834
5139
  /** Continuous legend for the point color channel (null if no point color). */
@@ -4861,7 +5166,7 @@ interface MapLayout {
4861
5166
  height: number;
4862
5167
  };
4863
5168
  /** Resolved focus target for camera framing (null if no focus). */
4864
- focus: MapFocusLayout | null;
5169
+ focus: GeoMapFocusLayout | null;
4865
5170
  }
4866
5171
  /** A resolved bar list row with computed positions and visual properties. */
4867
5172
  interface BarListRowMark {
@@ -4952,6 +5257,14 @@ interface CompileOptions {
4952
5257
  width: number;
4953
5258
  /** Total available height in pixels. */
4954
5259
  height: number;
5260
+ /**
5261
+ * How chrome height interacts with the height budget. Mirrors the spec-level
5262
+ * `chromeLayout`; the engine reads whichever is set (spec wins).
5263
+ *
5264
+ * - `'subtract'` (default): `height` is the fixed total; chrome shrinks the plot.
5265
+ * - `'grow'`: `height` is the plot budget; the SVG grows by the chrome height.
5266
+ */
5267
+ chromeLayout?: 'subtract' | 'grow';
4955
5268
  /** Theme overrides. */
4956
5269
  theme?: ThemeConfig;
4957
5270
  /**
@@ -4962,6 +5275,26 @@ interface CompileOptions {
4962
5275
  * before calling compile. The engine always receives a resolved boolean.
4963
5276
  */
4964
5277
  darkMode?: boolean;
5278
+ /**
5279
+ * Rendering backend for point marks, mirroring vega-embed's `renderer`
5280
+ * embed option: backend choice is host policy, not part of the spec.
5281
+ * High-cardinality scatter plots draw thousands of SVG circles, which is
5282
+ * what makes their entrance and update transitions stutter; a canvas layer
5283
+ * draws the same dots in a handful of batched paint calls.
5284
+ *
5285
+ * - `'auto'` (default): canvas above 1,000 compiled point marks, SVG below.
5286
+ * - `'svg'`: always SVG, whatever the point count.
5287
+ * - `'canvas'`: always canvas, whatever the point count.
5288
+ *
5289
+ * Canvas mode trades per-mark keyboard focus and edit-mode point selection
5290
+ * (the screen-reader data table still carries every row), and draws the
5291
+ * trendline above the dots even when `trendline.layer` is `'below'`.
5292
+ * Tooltips, hover, and click callbacks work the same in both modes.
5293
+ *
5294
+ * Ignored with a console warning for non-point marks, and for faceted,
5295
+ * layered, and sparkline charts.
5296
+ */
5297
+ renderer?: 'auto' | 'svg' | 'canvas';
4965
5298
  /** Whether to show the tryOpenData.ai watermark. Defaults to true. */
4966
5299
  watermark?: boolean;
4967
5300
  /**
@@ -5010,6 +5343,13 @@ interface CompileOptions {
5010
5343
  * different area than the one the axes are rendered in.
5011
5344
  */
5012
5345
  frozenChartArea?: Rect;
5346
+ /**
5347
+ * Marks this compile as one leaf (or the primary spec) of a multi-leaf layer.
5348
+ * Set by compileLayer; callers should not set it. Only consumer today is the
5349
+ * canvas mark-layer resolution, which refuses canvas mode for layered charts
5350
+ * because the layer layout concatenates marks from several compiles.
5351
+ */
5352
+ layered?: boolean;
5013
5353
  }
5014
5354
  /** Extended compile options for table visualizations. */
5015
5355
  interface CompileTableOptions extends CompileOptions {
@@ -5530,12 +5870,20 @@ declare function computeXAxisExtentFromLabels(input: XAxisExtentInput): number;
5530
5870
  */
5531
5871
  declare function maxRotatedLabelWidth(tickAngle: number, tickFontSize: number): number;
5532
5872
  /**
5533
- * Truncate a rotated tick label with an ellipsis so it fits inside the capped
5534
- * reservation. Returns the label unchanged when it already fits.
5873
+ * Truncate a label with an ellipsis so it fits inside an explicit pixel budget.
5874
+ * Returns the label unchanged when it already fits.
5535
5875
  *
5536
5876
  * Binary-search on character count against the real measure function, so it
5537
5877
  * respects proportional fonts rather than assuming a fixed character width.
5538
5878
  */
5879
+ declare function truncateToWidth(label: string, budget: number, fontSize: number, fontWeight: number, measure?: (text: string, fontSize: number, fontWeight?: number) => number): string;
5880
+ /**
5881
+ * Truncate a rotated tick label with an ellipsis so it fits inside the capped
5882
+ * reservation. Returns the label unchanged when it already fits.
5883
+ *
5884
+ * Delegates to `truncateToWidth` with the budget derived from the rotation
5885
+ * geometry, so the binary-search stays in one place.
5886
+ */
5539
5887
  declare function truncateRotatedLabel(label: string, tickAngle: number, tickFontSize: number, tickFontWeight: number, measure?: (text: string, fontSize: number, fontWeight?: number) => number): string;
5540
5888
 
5541
5889
  /**
@@ -5712,12 +6060,22 @@ declare function buildTemporalFormatter(formatStr: string | undefined): ((value:
5712
6060
  * @param data - The data array.
5713
6061
  */
5714
6062
  declare function generateAltText(spec: ChartSpec, data: DataRow[]): string;
6063
+ /**
6064
+ * Maximum number of data rows in the screen-reader table. A 50k-point scatter
6065
+ * would otherwise put 50k hidden rows in the DOM.
6066
+ */
6067
+ declare const MAX_SR_TABLE_ROWS = 1000;
5715
6068
  /**
5716
6069
  * Generate a tabular data fallback for screen readers.
5717
6070
  *
5718
6071
  * Returns a 2D array where the first row is headers and subsequent
5719
6072
  * rows are data values. Only includes fields referenced in the encoding.
5720
6073
  *
6074
+ * Data rows are capped at MAX_SR_TABLE_ROWS (the header row does not count
6075
+ * against the cap). SCOPE: this caps the chart compile path only. Graph,
6076
+ * sankey, tilemap and map build their `dataTableFallback` independently and
6077
+ * stay uncapped.
6078
+ *
5721
6079
  * @param spec - The chart spec.
5722
6080
  * @param data - The data array.
5723
6081
  */
@@ -5970,4 +6328,4 @@ declare const CSS_TOKEN_ROOT_SELECTORS: readonly string[];
5970
6328
  declare const CSS_TOKENS: readonly CssTokenDef[];
5971
6329
  declare function cssTokenDefault(name: string, mode: 'light' | 'dark'): string;
5972
6330
 
5973
- export { type A11yConfig, type A11yMetadata, ACHROMATIC_RAMP, AXIS_TITLE_GAP, AXIS_TITLE_OFFSET_COMPACT, AXIS_TITLE_OFFSET_DEFAULT, AXIS_TITLE_TRAILING_PAD, type AggregateOp, type AggregateTransform, type AnimationConfig, type AnimationEase, type AnimationPhaseConfig, type AnimationSpec, type AnimationStagger, type Annotation, type AnnotationAnchor, type AnnotationFootnote, type AnnotationOffset, type AnnotationPosition, type ArcEncoding, type ArcMark, type AreaEncoding, type AreaMark, type AxisConfig, type AxisLabelDensity, type AxisLayout, type AxisTick, BRAND_FONT_SIZE, BRAND_MIN_WIDTH, BRAND_RESERVE_WIDTH, BREAKPOINT_COMPACT_MAX, BREAKPOINT_MEDIUM_MAX, type BarColumnConfig, type BarEncoding, type BarListEncoding, type BarListLayout, type BarListRowMark, type BarListSpec, type BarListSpecWithoutData, type BarTableCell, type BaseLegendLayout, type BeeswarmEncoding, type BinParams, type BinTransform, type Breakpoint, CATEGORICAL_PALETTE, COMPACT_WIDTH, CSS_TOKENS, CSS_TOKEN_ROOT_SELECTORS, type CalculateExpression, type CalculateTransform, type CalendarEncoding, type CategoricalLegendLayout, type CategoricalPalette, type CategoryColorsConfig, type CategoryTableCell, type CellStyle, type ChannelRule, type ChartBuilderOptions, type ChartEventHandlers, type ChartLayout, type ChartSpec, type ChartSpecOverride, type ChartSpecWithoutData, type Chrome, type ChromeDefaults, type ChromeKey, type ChromeMode, type ChromeText, type ChromeTextStyle, type ChromeThemeOverride, type CircleEncoding, type ColorBlindnessType, type ColumnConfig, type CompileOptions, type CompileTableOptions, type CompileWarning, type Condition, type ConditionalValueDef, type ConnectorConfig, type ConnectorType, type ContinuousLegendBin, type ContinuousLegendLayout, type ContinuousLegendTick, type CssTokenDef, DEFAULT_THEME, DIVERGING_PALETTES, type DarkMode, type DataRow, type DateGranularity, type Display, type DivergingPalette, EXTENDED_OFFSET_STRATEGIES, type ElementEdit, type ElementRef, type Encoding, type EncodingChannel, type EncodingRule, type EndpointLabelContent, type EndpointLabelEntry, type EndpointLabelsConfig, type EndpointLabelsLayout, FOOTNOTE_LINE_HEIGHT, type FacetChannel, type FacetLayout, type FacetPanelLayout, type FieldFormatContext, type FieldPredicate, type FieldRef, type FieldType, type FillPatternType, type FilterPredicate, type FilterTransform, type FlagTableCell, type FoldTransform, GRAPH_ENCODING_RULES, type GradientColorStop, type GradientDef, type GradientLegendLayout, type GradientStop, type GraphChannelRule, type GraphEdge, type GraphEdgeLayout, type GraphEncoding, type GraphEncodingChannel, type GraphLayout, type GraphLayoutConfig, type GraphNode, type GraphNodeLayout, type GraphSpec, type GraphSpecWithoutData, type Gridline, HEIGHT_CRAMPED_MAX, HEIGHT_SHORT_MAX, HPAD_COMPACT_FRACTION, HPAD_COMPACT_MIN, type HeatmapColumnConfig, type HeatmapTableCell, type HeightClass, type ImageColumnConfig, type ImageTableCell, LABEL_GAP_COMPACT, LABEL_GAP_DEFAULT, LABEL_GAP_NARROW_MAX, type LabelCandidate, type LabelConfig, type LabelDensity, type LabelMode, type LabelPriority, type LabelSpec, type LayerSpec, type LayoutStrategy, type LegendChannel, type LegendConfig, type LegendEntry, type LegendEntryPosition, type LegendLayout, type LegendPosition, type LineEncoding, type LineMark, type LinearGradient, type LogicalAnd, type LogicalNot, type LogicalOr, type LollipopEncoding, MARK_DISPLAY_NAMES, MARK_ENCODING_RULES, MARK_TYPES, MAX_LEFT_LABEL_FRACTION_COMPACT, MAX_LEFT_LABEL_FRACTION_DEFAULT, MAX_LEFT_LABEL_FRACTION_MEDIUM, MAX_LEFT_LABEL_FRACTION_MEDIUM_MAX, type MapBorders, type MapEncoding, type MapFeatureMark, type MapFocus, type MapFocusLayout, type MapGeo, type MapLayout, type MapPointMark, type MapPointsLayer, type MapProjection, type MapSpec, type MapSpecWithoutData, type Margins, type Mark, type MarkAria, type MarkDef, type MarkEvent, type MarkType, type MeasureTextFn, type Metric, NARROW_VIEWPORT_MAX, type NodeOverride, type NumberFormatter, OFFSET_STRATEGIES, type OffsetStrategy, type PaginationState, type ParliamentEncoding, type Point, type PointEncoding, type PointMark, type RadialGradient, type RangeAnnotation, type RangeEncoding, type Rect, type RectEncoding, type RectMark, type RefLineAnnotation, type RelativeTimeRef, type ResolveConfig, type ResolveMode, type ResolvedAnimation, type ResolvedAnimationPhase, type ResolvedAnnotation, type ResolvedChrome, type ResolvedChromeElement, type ResolvedColumn, type ResolvedFillPattern, type ResolvedLabel, type ResolvedMetricBar, type ResolvedMetricCell, type ResolvedSeriesSearch, type ResolvedTheme, type ResolvedYouDrawIt, type ResponsiveConfig, type RuleMarkLayout, SEQUENTIAL_PALETTES, SUPPORTED_SCHEME_NAMES, type SankeyEncoding, type SankeyLayout, type SankeyLinkColor, type SankeyLinkMark, type SankeyNodeAlign, type SankeyNodeMark, type SankeySpec, type SankeySpecWithoutData, type ScaleConfig, type ScaleInvert, type ScaleType, type SequentialPalette, type SeriesSearchConfig, type SeriesStrategy, type SeriesStyle, type SizeLegendCircle, type SizeLegendLayout, type SortByField, type SortState, type SparklineColumnConfig, type SparklineData, type SparklineTableCell, type StoredVizSpec, TICK_LABEL_OFFSET, TICK_LINE_HEIGHT_FACTOR, TOP_PAD_EXTRA_NARROW, TOP_PAD_NARROW_MAX, type TableBuilderOptions, type TableCell, type TableCellBase, type TableLayout, type TableRow, type TableSpec, type TableSpecWithoutData, type TextAnnotation, type TextEncoding, type TextMarkLayout, type TextStyle, type TextTableCell, type Theme, type ThemeChromeDefaults, type ThemeColors, type ThemeConfig, type ThemeFontSizes, type ThemeFontWeights, type ThemeFonts, type ThemeSpacing, type TickEncoding, type TickMarkLayout, type TileMapBuilderOptions, type TileMapEncoding, type TileMapLayout, type TileMapPalette, type TileMapSpec, type TileMapSpecWithoutData, type TileMapTileMark, type TimeUnit, type TimeUnitTransform, type TokenValue, type TooltipContent, type TooltipField, type Transform, type ValueDef, type VizSpec, type WaffleEncoding, type WindowFieldDef, type WindowOp, type WindowSortField, type WindowTransform, type XAxisExtentInput, X_AXIS_BAND_HEIGHT, X_AXIS_ROTATED_EXTENT_CAP, X_AXIS_TITLE_BAND, X_AXIS_TITLE_BAND_ROTATED, type YouDrawItConfig, type YouDrawItSample, type YouDrawItYInvert, abbreviateNumber, adaptColorForDarkMode, adaptForLightLineStroke, adaptTheme, areaChart, axisTitleOffset, barChart, buildCompactStepFormatter, buildD3Formatter, buildTemporalFormatter, checkPaletteDistinguishability, columnChart, computeChrome, computeFieldFormatContext, computeLabelBounds, computeXAxisExtentFromLabels, contrastRatio, cssTokenDefault, dataTable, deepMergeSpec, defaultNumberFormatter, detectCollision, donutChart, dotChart, editorial, elementRef, essay, estimateTextWidth, findAccessibleColor, footnoteBandHeight, formatCurrency, formatDate, formatNumber, formatOrdinal, formatPercent, generateAltText, generateAriaLabels, generateDataTable, getAxisTitleOffset, getBreakpoint, getHeightClass, getLayoutStrategy, getRepresentativeColor, heuristicMeasure, inferFieldType, isAxislessMark, isBarListSpec, isChartSpec, isConditionalDef, isEncodingChannel, isGradientDef, isGraphSpec, isLayerSpec, isMapSpec, isOpaqueColor, isRangeAnnotation, isRefLineAnnotation, isSankeySpec, isTableSpec, isTextAnnotation, isTileMapSpec, isValueDef, isYearContext, lineChart, maxRotatedLabelWidth, meetsAA, overlapArea, pickLabelColor, pieChart, resolveCollisions, resolveMarkDef, resolveMarkType, resolveMeasurer, resolveNumberFormatter, resolveSchemeName, resolveTheme, scatterChart, simulateColorBlindness, textAscent, tileMap, truncateRotatedLabel, wire, wrapText };
6331
+ export { type A11yConfig, type A11yMetadata, ACHROMATIC_RAMP, AXIS_TITLE_GAP, AXIS_TITLE_OFFSET_COMPACT, AXIS_TITLE_OFFSET_DEFAULT, AXIS_TITLE_TRAILING_PAD, type AggregateOp, type AggregateTransform, type AnimationConfig, type AnimationEase, type AnimationPhaseConfig, type AnimationSpec, type AnimationStagger, type Annotation, type AnnotationAnchor, type AnnotationFootnote, type AnnotationOffset, type AnnotationPosition, type ArcEncoding, type ArcMark, type AreaEncoding, type AreaMark, type AxisConfig, type AxisLabelDensity, type AxisLayout, type AxisTick, BRAND_FONT_SIZE, BRAND_MIN_WIDTH, BRAND_RESERVE_WIDTH, BREAKPOINT_COMPACT_MAX, BREAKPOINT_MEDIUM_MAX, type BarColumnConfig, type BarEncoding, type BarListEncoding, type BarListLayout, type BarListRowMark, type BarListSpec, type BarListSpecWithoutData, type BarTableCell, type BaseLegendLayout, type BeeswarmEncoding, type BinParams, type BinTransform, type Breakpoint, CATEGORICAL_PALETTE, COMPACT_WIDTH, CSS_TOKENS, CSS_TOKEN_ROOT_SELECTORS, type CalculateExpression, type CalculateTransform, type CalendarEncoding, type CategoricalLegendLayout, type CategoricalPalette, type CategoryColorsConfig, type CategoryTableCell, type CellStyle, type ChannelRule, type ChartBuilderOptions, type ChartEventHandlers, type ChartLayout, type ChartSpec, type ChartSpecOverride, type ChartSpecWithoutData, type Chrome, type ChromeDefaults, type ChromeKey, type ChromeMode, type ChromeText, type ChromeTextStyle, type ChromeThemeOverride, type CircleEncoding, type ColorBlindnessType, type ColumnConfig, type CompileOptions, type CompileTableOptions, type CompileWarning, type Condition, type ConditionalValueDef, type ConnectorConfig, type ConnectorType, type ContinuousLegendBin, type ContinuousLegendLayout, type ContinuousLegendTick, type CssTokenDef, DEFAULT_THEME, DIVERGING_PALETTES, type DarkMode, type DataRow, type DateGranularity, type Display, type DivergingPalette, EXTENDED_OFFSET_STRATEGIES, type ElementEdit, type ElementRef, type Encoding, type EncodingChannel, type EncodingRule, type EndpointLabelContent, type EndpointLabelEntry, type EndpointLabelsConfig, type EndpointLabelsLayout, FOOTNOTE_LINE_HEIGHT, type FacetChannel, type FacetLayout, type FacetPanelLayout, type FieldFormatContext, type FieldPredicate, type FieldRef, type FieldType, type FillPatternType, type FilterPredicate, type FilterTransform, type FlagTableCell, type FoldTransform, GRAPH_ENCODING_RULES, type GeoMapBorders, type GeoMapEncoding, type GeoMapFeatureMark, type GeoMapFocus, type GeoMapFocusLayout, type GeoMapGeo, type GeoMapLayout, type GeoMapPointMark, type GeoMapPointsLayer, type GeoMapProjection, type GeoMapSpec, type GeoMapSpecWithoutData, type GradientColorStop, type GradientDef, type GradientLegendLayout, type GradientStop, type GraphAnimationConfig, type GraphAnimationSpec, type GraphChannelRule, type GraphEdge, type GraphEdgeLayout, type GraphEncoding, type GraphEncodingChannel, type GraphInteractionConfig, type GraphLayout, type GraphLayoutConfig, type GraphNode, type GraphNodeLayout, type GraphSpec, type GraphSpecWithoutData, type Gridline, HEIGHT_CRAMPED_MAX, HEIGHT_SHORT_MAX, HPAD_COMPACT_FRACTION, HPAD_COMPACT_MIN, type HeatmapColumnConfig, type HeatmapTableCell, type HeightClass, type ImageColumnConfig, type ImageTableCell, LABEL_GAP_COMPACT, LABEL_GAP_DEFAULT, LABEL_GAP_NARROW_MAX, type LabelCandidate, type LabelConfig, type LabelDensity, type LabelMode, type LabelPriority, type LabelSpec, type LayerSpec, type LayoutStrategy, type LegendChannel, type LegendConfig, type LegendEntry, type LegendEntryPosition, type LegendLayout, type LegendPosition, type LineEncoding, type LineMark, type LinearGradient, type LogicalAnd, type LogicalNot, type LogicalOr, type LollipopEncoding, MARK_DISPLAY_NAMES, MARK_ENCODING_RULES, MARK_TYPES, MAX_LEFT_LABEL_FRACTION_COMPACT, MAX_LEFT_LABEL_FRACTION_DEFAULT, MAX_LEFT_LABEL_FRACTION_MEDIUM, MAX_LEFT_LABEL_FRACTION_MEDIUM_MAX, MAX_SR_TABLE_ROWS, type Margins, type Mark, type MarkAria, type MarkDef, type MarkEvent, type MarkType, type MeasureTextFn, type Metric, NARROW_VIEWPORT_MAX, type NodeOverride, type NumberFormatter, OFFSET_STRATEGIES, type OffsetStrategy, type PaginationState, type ParliamentEncoding, type Point, type PointEncoding, type PointMark, type RadialGradient, type RangeAnnotation, type RangeEncoding, type Rect, type RectEncoding, type RectMark, type RefLineAnnotation, type RelativeTimeRef, type ResolveConfig, type ResolveMode, type ResolvedAnimation, type ResolvedAnimationPhase, type ResolvedAnnotation, type ResolvedChrome, type ResolvedChromeElement, type ResolvedColumn, type ResolvedFillPattern, type ResolvedLabel, type ResolvedMetricBar, type ResolvedMetricCell, type ResolvedSeriesSearch, type ResolvedTheme, type ResolvedYouDrawIt, type ResponsiveConfig, type RuleMarkLayout, SEQUENTIAL_PALETTES, SUPPORTED_SCHEME_NAMES, type SankeyEncoding, type SankeyLayout, type SankeyLinkColor, type SankeyLinkMark, type SankeyNodeAlign, type SankeyNodeMark, type SankeySpec, type SankeySpecWithoutData, type ScaleConfig, type ScaleInvert, type ScaleType, type SequentialPalette, type SeriesSearchConfig, type SeriesStrategy, type SeriesStyle, type SizeLegendCircle, type SizeLegendLayout, type SortByField, type SortState, type SparklineColumnConfig, type SparklineData, type SparklineTableCell, type StoredVizSpec, TICK_LABEL_OFFSET, TICK_LINE_HEIGHT_FACTOR, TOP_PAD_EXTRA_NARROW, TOP_PAD_NARROW_MAX, type TableBuilderOptions, type TableCell, type TableCellBase, type TableLayout, type TableRow, type TableSpec, type TableSpecWithoutData, type TextAnnotation, type TextEncoding, type TextMarkLayout, type TextStyle, type TextTableCell, type Theme, type ThemeChromeDefaults, type ThemeColors, type ThemeConfig, type ThemeFontSizes, type ThemeFontWeights, type ThemeFonts, type ThemeSpacing, type TickEncoding, type TickMarkLayout, type TileMapBuilderOptions, type TileMapEncoding, type TileMapLayout, type TileMapPalette, type TileMapSpec, type TileMapSpecWithoutData, type TileMapTileMark, type TimeUnit, type TimeUnitTransform, type TokenValue, type TooltipContent, type TooltipField, type Transform, type UpdatePhaseConfig, type ValueDef, type VizSpec, type WaffleEncoding, type WindowFieldDef, type WindowOp, type WindowSortField, type WindowTransform, type XAxisExtentInput, X_AXIS_BAND_HEIGHT, X_AXIS_ROTATED_EXTENT_CAP, X_AXIS_TITLE_BAND, X_AXIS_TITLE_BAND_ROTATED, type YouDrawItConfig, type YouDrawItSample, type YouDrawItYInvert, abbreviateNumber, adaptColorForDarkMode, adaptForLightLineStroke, adaptTheme, areaChart, axisTitleOffset, barChart, buildCompactStepFormatter, buildD3Formatter, buildTemporalFormatter, checkPaletteDistinguishability, columnChart, computeChrome, computeFieldFormatContext, computeLabelBounds, computeXAxisExtentFromLabels, contrastRatio, cssTokenDefault, dataTable, deepMergeSpec, defaultNumberFormatter, detectCollision, donutChart, dotChart, editorial, elementRef, essay, estimateTextWidth, findAccessibleColor, footnoteBandHeight, formatCurrency, formatDate, formatNumber, formatOrdinal, formatPercent, generateAltText, generateAriaLabels, generateDataTable, getAxisTitleOffset, getBreakpoint, getHeightClass, getLayoutStrategy, getRepresentativeColor, heuristicMeasure, inferFieldType, isAxislessMark, isBarListSpec, isChartSpec, isConditionalDef, isEncodingChannel, isGeoMapSpec, isGradientDef, isGraphSpec, isLayerSpec, isOpaqueColor, isRangeAnnotation, isRefLineAnnotation, isSankeySpec, isTableSpec, isTextAnnotation, isTileMapSpec, isValueDef, isYearContext, lineChart, maxRotatedLabelWidth, meetsAA, overlapArea, pickLabelColor, pieChart, resolveCollisions, resolveMarkDef, resolveMarkType, resolveMeasurer, resolveNumberFormatter, resolveSchemeName, resolveTheme, scatterChart, simulateColorBlindness, textAscent, tileMap, truncateRotatedLabel, truncateToWidth, wire, wrapText };