@opendata-ai/openchart-engine 8.0.0-rc.10 → 8.0.0-rc.12

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 (271) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.js +123 -54
  3. package/dist/index.js.map +1 -1
  4. package/package.json +3 -4
  5. package/src/__test-fixtures__/specs.ts +0 -182
  6. package/src/__tests__/__snapshots__/compile-snapshot.test.ts.snap +0 -2401
  7. package/src/__tests__/annotation-behavior.test.ts +0 -852
  8. package/src/__tests__/axes.test.ts +0 -1579
  9. package/src/__tests__/compile-animation.test.ts +0 -161
  10. package/src/__tests__/compile-chart.test.ts +0 -1303
  11. package/src/__tests__/compile-footnotes.test.ts +0 -277
  12. package/src/__tests__/compile-layer.test.ts +0 -969
  13. package/src/__tests__/compile-snapshot.test.ts +0 -156
  14. package/src/__tests__/compound-labels.test.ts +0 -147
  15. package/src/__tests__/dimensions.test.ts +0 -918
  16. package/src/__tests__/encoding-sugar.test.ts +0 -390
  17. package/src/__tests__/facet.test.ts +0 -359
  18. package/src/__tests__/helpers/invariants.ts +0 -299
  19. package/src/__tests__/known-bugs.test.ts +0 -566
  20. package/src/__tests__/layout-fuzz.test.ts +0 -358
  21. package/src/__tests__/layout-invariants.test.ts +0 -535
  22. package/src/__tests__/legend.test.ts +0 -721
  23. package/src/__tests__/mark-keys.test.ts +0 -294
  24. package/src/__tests__/ranking-recipes.test.ts +0 -260
  25. package/src/__tests__/rotation.test.ts +0 -83
  26. package/src/__tests__/scales.test.ts +0 -323
  27. package/src/__tests__/series-search.test.ts +0 -92
  28. package/src/__tests__/spec-sugar.test.ts +0 -801
  29. package/src/__tests__/you-draw-it.test.ts +0 -160
  30. package/src/annotations/__tests__/compute.test.ts +0 -1672
  31. package/src/annotations/__tests__/geometry.test.ts +0 -66
  32. package/src/annotations/__tests__/placement-fuzz.test.ts +0 -256
  33. package/src/annotations/__tests__/placement-invariants.test.ts +0 -345
  34. package/src/annotations/__tests__/placement.test.ts +0 -316
  35. package/src/annotations/__tests__/resolve-text.test.ts +0 -788
  36. package/src/annotations/__tests__/rich-text.test.ts +0 -91
  37. package/src/annotations/__tests__/thinning.test.ts +0 -285
  38. package/src/annotations/collisions.ts +0 -326
  39. package/src/annotations/compute.ts +0 -333
  40. package/src/annotations/constants.ts +0 -162
  41. package/src/annotations/geometry.ts +0 -376
  42. package/src/annotations/move.ts +0 -135
  43. package/src/annotations/placement.ts +0 -636
  44. package/src/annotations/position.ts +0 -131
  45. package/src/annotations/resolve-range.ts +0 -117
  46. package/src/annotations/resolve-refline.ts +0 -157
  47. package/src/annotations/resolve-text.ts +0 -545
  48. package/src/annotations/rich-text.ts +0 -65
  49. package/src/annotations/thinning.ts +0 -190
  50. package/src/barlist/__tests__/compile-barlist.test.ts +0 -200
  51. package/src/barlist/compile-barlist.ts +0 -391
  52. package/src/barlist/types.ts +0 -28
  53. package/src/charts/__tests__/post-process.test.ts +0 -237
  54. package/src/charts/__tests__/registry.test.ts +0 -116
  55. package/src/charts/__tests__/utils.test.ts +0 -195
  56. package/src/charts/_shared/__tests__/density-filter.test.ts +0 -32
  57. package/src/charts/_shared/density-filter.ts +0 -26
  58. package/src/charts/_shared/format-label-value.ts +0 -16
  59. package/src/charts/bar/__tests__/compute.test.ts +0 -934
  60. package/src/charts/bar/__tests__/gradient-orient.test.ts +0 -127
  61. package/src/charts/bar/__tests__/labels.test.ts +0 -292
  62. package/src/charts/bar/compute.ts +0 -539
  63. package/src/charts/bar/index.ts +0 -60
  64. package/src/charts/bar/labels.ts +0 -311
  65. package/src/charts/beeswarm/__tests__/compute.test.ts +0 -280
  66. package/src/charts/beeswarm/__tests__/dodge.test.ts +0 -148
  67. package/src/charts/beeswarm/compute.ts +0 -203
  68. package/src/charts/beeswarm/dodge.ts +0 -155
  69. package/src/charts/beeswarm/index.ts +0 -32
  70. package/src/charts/builtin.ts +0 -75
  71. package/src/charts/calendar/__tests__/compute.test.ts +0 -417
  72. package/src/charts/calendar/compute.ts +0 -319
  73. package/src/charts/calendar/index.ts +0 -32
  74. package/src/charts/column/__tests__/compute.test.ts +0 -540
  75. package/src/charts/column/__tests__/labels.test.ts +0 -179
  76. package/src/charts/column/compute.ts +0 -493
  77. package/src/charts/column/index.ts +0 -53
  78. package/src/charts/column/labels.ts +0 -229
  79. package/src/charts/dot/__tests__/compute.test.ts +0 -380
  80. package/src/charts/dot/__tests__/labels.test.ts +0 -98
  81. package/src/charts/dot/compute.ts +0 -285
  82. package/src/charts/dot/index.ts +0 -62
  83. package/src/charts/dot/labels.ts +0 -121
  84. package/src/charts/line/__tests__/compute.test.ts +0 -1194
  85. package/src/charts/line/__tests__/curves.test.ts +0 -51
  86. package/src/charts/line/__tests__/labels.test.ts +0 -94
  87. package/src/charts/line/__tests__/mark-options.test.ts +0 -175
  88. package/src/charts/line/area.ts +0 -484
  89. package/src/charts/line/compute.ts +0 -356
  90. package/src/charts/line/curves.ts +0 -85
  91. package/src/charts/line/index.ts +0 -176
  92. package/src/charts/line/labels.ts +0 -177
  93. package/src/charts/parliament/__tests__/compute.test.ts +0 -411
  94. package/src/charts/parliament/compute.ts +0 -313
  95. package/src/charts/parliament/index.ts +0 -32
  96. package/src/charts/pie/__tests__/compute.test.ts +0 -384
  97. package/src/charts/pie/__tests__/labels.test.ts +0 -132
  98. package/src/charts/pie/compute.ts +0 -324
  99. package/src/charts/pie/index.ts +0 -49
  100. package/src/charts/pie/labels.ts +0 -143
  101. package/src/charts/post-process.ts +0 -229
  102. package/src/charts/range/__tests__/compute.test.ts +0 -486
  103. package/src/charts/range/compute.ts +0 -273
  104. package/src/charts/range/index.ts +0 -82
  105. package/src/charts/range/labels.ts +0 -169
  106. package/src/charts/rect/__tests__/compute.test.ts +0 -120
  107. package/src/charts/rect/index.ts +0 -127
  108. package/src/charts/registry.ts +0 -72
  109. package/src/charts/rule/index.ts +0 -139
  110. package/src/charts/scatter/__tests__/compute.test.ts +0 -488
  111. package/src/charts/scatter/__tests__/trendline.test.ts +0 -191
  112. package/src/charts/scatter/compute.ts +0 -192
  113. package/src/charts/scatter/index.ts +0 -46
  114. package/src/charts/scatter/trendline.ts +0 -100
  115. package/src/charts/text/__tests__/compute.test.ts +0 -307
  116. package/src/charts/text/index.ts +0 -141
  117. package/src/charts/tick/__tests__/compute.test.ts +0 -75
  118. package/src/charts/tick/index.ts +0 -99
  119. package/src/charts/utils.ts +0 -170
  120. package/src/charts/waffle/__tests__/compute.test.ts +0 -305
  121. package/src/charts/waffle/compute.ts +0 -197
  122. package/src/charts/waffle/index.ts +0 -31
  123. package/src/compile/__tests__/color-scale-range.test.ts +0 -158
  124. package/src/compile/__tests__/color-scale-reverse.test.ts +0 -89
  125. package/src/compile/__tests__/data-clip.test.ts +0 -127
  126. package/src/compile/__tests__/fill-patterns.test.ts +0 -154
  127. package/src/compile/__tests__/size-scale.test.ts +0 -108
  128. package/src/compile/__tests__/watermark-obstacle.test.ts +0 -93
  129. package/src/compile/color-scale-range.ts +0 -101
  130. package/src/compile/data-clip.ts +0 -48
  131. package/src/compile/fill-patterns.ts +0 -74
  132. package/src/compile/layer.ts +0 -630
  133. package/src/compile/size-scale.ts +0 -141
  134. package/src/compile/spec-sugar.ts +0 -767
  135. package/src/compile/watermark-obstacle.ts +0 -54
  136. package/src/compile/you-draw-it.ts +0 -123
  137. package/src/compile.ts +0 -1548
  138. package/src/compiler/__tests__/a11y-warnings.test.ts +0 -148
  139. package/src/compiler/__tests__/animation.test.ts +0 -177
  140. package/src/compiler/__tests__/compile.test.ts +0 -87
  141. package/src/compiler/__tests__/fixtures/vl-parity/axis-null.json +0 -19
  142. package/src/compiler/__tests__/fixtures/vl-parity/color-value.json +0 -20
  143. package/src/compiler/__tests__/fixtures/vl-parity/count-aggregate.json +0 -22
  144. package/src/compiler/__tests__/fixtures/vl-parity/data-values.json +0 -19
  145. package/src/compiler/__tests__/fixtures/vl-parity/layer-axis-null.json +0 -14
  146. package/src/compiler/__tests__/fixtures/vl-parity/layer-count.json +0 -34
  147. package/src/compiler/__tests__/fixtures/vl-parity/layer-data-values.json +0 -22
  148. package/src/compiler/__tests__/fixtures/vl-parity/layer-legend-null.json +0 -41
  149. package/src/compiler/__tests__/fixtures/vl-parity/layer-scheme.json +0 -38
  150. package/src/compiler/__tests__/fixtures/vl-parity/layer-sort.json +0 -28
  151. package/src/compiler/__tests__/fixtures/vl-parity/layer-theta.json +0 -28
  152. package/src/compiler/__tests__/fixtures/vl-parity/layer-title.json +0 -30
  153. package/src/compiler/__tests__/fixtures/vl-parity/layer-value-def.json +0 -29
  154. package/src/compiler/__tests__/fixtures/vl-parity/legend-null.json +0 -32
  155. package/src/compiler/__tests__/fixtures/vl-parity/scheme.json +0 -25
  156. package/src/compiler/__tests__/fixtures/vl-parity/sort-by-value.json +0 -19
  157. package/src/compiler/__tests__/fixtures/vl-parity/theta-arc.json +0 -19
  158. package/src/compiler/__tests__/fixtures/vl-parity/title-subtitle.json +0 -21
  159. package/src/compiler/__tests__/fixtures/vl-parity/width-height.json +0 -23
  160. package/src/compiler/__tests__/keys.test.ts +0 -83
  161. package/src/compiler/__tests__/normalize-highlight.test.ts +0 -103
  162. package/src/compiler/__tests__/normalize.test.ts +0 -399
  163. package/src/compiler/__tests__/sparkline-defaults.test.ts +0 -153
  164. package/src/compiler/__tests__/validate-did-you-mean.test.ts +0 -170
  165. package/src/compiler/__tests__/validate-highlight.test.ts +0 -112
  166. package/src/compiler/__tests__/validate-near-miss.test.ts +0 -251
  167. package/src/compiler/__tests__/validate.test.ts +0 -731
  168. package/src/compiler/__tests__/vl-parity.test.ts +0 -68
  169. package/src/compiler/a11y-warnings.ts +0 -110
  170. package/src/compiler/animation.ts +0 -142
  171. package/src/compiler/index.ts +0 -47
  172. package/src/compiler/keys.ts +0 -55
  173. package/src/compiler/normalize.ts +0 -734
  174. package/src/compiler/sparkline-defaults.ts +0 -138
  175. package/src/compiler/types.ts +0 -241
  176. package/src/compiler/validate.ts +0 -2093
  177. package/src/endpoint-labels/__tests__/compute.test.ts +0 -587
  178. package/src/endpoint-labels/compute.ts +0 -621
  179. package/src/endpoint-labels/constants.ts +0 -54
  180. package/src/endpoint-labels/format.ts +0 -60
  181. package/src/endpoint-labels/predict.ts +0 -139
  182. package/src/format/__tests__/field-format.test.ts +0 -164
  183. package/src/format/field-format.ts +0 -27
  184. package/src/geo/__tests__/compile-map.test.ts +0 -1128
  185. package/src/geo/compile-map.ts +0 -1376
  186. package/src/geo/join.ts +0 -115
  187. package/src/geo/projections.ts +0 -65
  188. package/src/geo/types.ts +0 -26
  189. package/src/graphs/__tests__/community.test.ts +0 -228
  190. package/src/graphs/__tests__/compile-graph.test.ts +0 -396
  191. package/src/graphs/__tests__/encoding.test.ts +0 -415
  192. package/src/graphs/community.ts +0 -92
  193. package/src/graphs/compile-graph.ts +0 -329
  194. package/src/graphs/encoding.ts +0 -356
  195. package/src/graphs/types.ts +0 -106
  196. package/src/index.ts +0 -177
  197. package/src/layout/__tests__/metrics.test.ts +0 -97
  198. package/src/layout/__tests__/scales-highlight.test.ts +0 -192
  199. package/src/layout/axes/rotation.ts +0 -152
  200. package/src/layout/axes/thinning.ts +0 -98
  201. package/src/layout/axes/ticks.ts +0 -409
  202. package/src/layout/axes.ts +0 -757
  203. package/src/layout/dimensions.ts +0 -912
  204. package/src/layout/facet.ts +0 -91
  205. package/src/layout/gridlines.ts +0 -84
  206. package/src/layout/metrics.ts +0 -132
  207. package/src/layout/plan.ts +0 -631
  208. package/src/layout/scales.ts +0 -1053
  209. package/src/layout/shared.ts +0 -44
  210. package/src/legend/__tests__/continuous.test.ts +0 -318
  211. package/src/legend/__tests__/redundancy.test.ts +0 -108
  212. package/src/legend/__tests__/size.test.ts +0 -348
  213. package/src/legend/__tests__/suppression.test.ts +0 -382
  214. package/src/legend/compute.ts +0 -748
  215. package/src/legend/continuous.ts +0 -327
  216. package/src/legend/size.ts +0 -407
  217. package/src/legend/suppression.ts +0 -226
  218. package/src/legend/wrap.ts +0 -117
  219. package/src/sankey/__tests__/compile-sankey.test.ts +0 -458
  220. package/src/sankey/__tests__/layout.test.ts +0 -165
  221. package/src/sankey/__tests__/node-label-wrap.test.ts +0 -114
  222. package/src/sankey/__tests__/node-sort.test.ts +0 -45
  223. package/src/sankey/compile-sankey.ts +0 -706
  224. package/src/sankey/layout.ts +0 -184
  225. package/src/sankey/types.ts +0 -41
  226. package/src/tables/__tests__/bar-column.test.ts +0 -147
  227. package/src/tables/__tests__/category-colors.test.ts +0 -230
  228. package/src/tables/__tests__/compile-table.test.ts +0 -236
  229. package/src/tables/__tests__/format-cells.test.ts +0 -143
  230. package/src/tables/__tests__/heatmap.test.ts +0 -148
  231. package/src/tables/__tests__/pagination.test.ts +0 -78
  232. package/src/tables/__tests__/search.test.ts +0 -94
  233. package/src/tables/__tests__/sort.test.ts +0 -107
  234. package/src/tables/__tests__/sparkline.test.ts +0 -122
  235. package/src/tables/bar-column.ts +0 -94
  236. package/src/tables/category-colors.ts +0 -78
  237. package/src/tables/compile-table.ts +0 -427
  238. package/src/tables/format-cells.ts +0 -115
  239. package/src/tables/heatmap.ts +0 -141
  240. package/src/tables/pagination.ts +0 -46
  241. package/src/tables/search.ts +0 -66
  242. package/src/tables/sort.ts +0 -69
  243. package/src/tables/sparkline.ts +0 -113
  244. package/src/tables/utils.ts +0 -16
  245. package/src/tilemap/__tests__/compile-tilemap.test.ts +0 -576
  246. package/src/tilemap/compile-tilemap.ts +0 -755
  247. package/src/tilemap/layout.ts +0 -172
  248. package/src/tilemap/types.ts +0 -33
  249. package/src/tooltips/__tests__/compute.test.ts +0 -582
  250. package/src/tooltips/compute.ts +0 -700
  251. package/src/transforms/__tests__/aggregate.test.ts +0 -159
  252. package/src/transforms/__tests__/bin.test.ts +0 -88
  253. package/src/transforms/__tests__/calculate.test.ts +0 -146
  254. package/src/transforms/__tests__/conditional.test.ts +0 -127
  255. package/src/transforms/__tests__/filter-relative.test.ts +0 -202
  256. package/src/transforms/__tests__/filter.test.ts +0 -59
  257. package/src/transforms/__tests__/fold.test.ts +0 -79
  258. package/src/transforms/__tests__/index.test.ts +0 -93
  259. package/src/transforms/__tests__/predicates.test.ts +0 -193
  260. package/src/transforms/__tests__/timeunit.test.ts +0 -129
  261. package/src/transforms/__tests__/window.test.ts +0 -286
  262. package/src/transforms/aggregate.ts +0 -131
  263. package/src/transforms/bin.ts +0 -87
  264. package/src/transforms/calculate.ts +0 -60
  265. package/src/transforms/conditional.ts +0 -46
  266. package/src/transforms/filter.ts +0 -122
  267. package/src/transforms/fold.ts +0 -49
  268. package/src/transforms/index.ts +0 -60
  269. package/src/transforms/predicates.ts +0 -123
  270. package/src/transforms/timeunit.ts +0 -88
  271. package/src/transforms/window.ts +0 -185
package/dist/index.d.ts CHANGED
@@ -376,6 +376,13 @@ interface NormalizedChartSpec {
376
376
  data: DataRow[];
377
377
  encoding: Encoding;
378
378
  chrome: NormalizedChrome;
379
+ /**
380
+ * How chrome height interacts with the height budget. `'grow'` treats the
381
+ * container height as the plot budget and grows the SVG by the chrome height;
382
+ * `'subtract'` (default) shrinks the plot to fit chrome. Carried through from
383
+ * the spec so the layout pipeline can honor it.
384
+ */
385
+ chromeLayout?: 'subtract' | 'grow';
379
386
  /** Optional KPI metric cells, passed through unchanged. */
380
387
  metrics?: _opendata_ai_openchart_core.Metric[];
381
388
  /**
package/dist/index.js CHANGED
@@ -10482,6 +10482,7 @@ function normalizeChartSpec(spec, warnings) {
10482
10482
  data: spec.data,
10483
10483
  encoding,
10484
10484
  chrome: normalizeChrome(spec.chrome),
10485
+ chromeLayout: spec.chromeLayout,
10485
10486
  metrics: spec.metrics,
10486
10487
  seriesSearch: normalizeSeriesSearch(spec, encoding, warnings),
10487
10488
  youDrawIt: normalizeYouDrawIt(spec),
@@ -12348,6 +12349,36 @@ ${errorMessages}`);
12348
12349
  return { spec: normalized, warnings };
12349
12350
  }
12350
12351
 
12352
+ // src/layout/shared.ts
12353
+ function chromeToInput(chrome) {
12354
+ return {
12355
+ eyebrow: chrome.eyebrow,
12356
+ title: chrome.title,
12357
+ subtitle: chrome.subtitle,
12358
+ source: chrome.source,
12359
+ byline: chrome.byline,
12360
+ footer: chrome.footer,
12361
+ brand: chrome.brand
12362
+ };
12363
+ }
12364
+ function scalePadding(basePadding, width, height) {
12365
+ const minDim = Math.min(width, height);
12366
+ if (minDim >= 500) return basePadding;
12367
+ if (minDim <= 200) return Math.max(Math.round(basePadding * 0.5), 4);
12368
+ const t = (minDim - 200) / 300;
12369
+ return Math.max(Math.round(basePadding * (0.5 + t * 0.5)), 4);
12370
+ }
12371
+ function bottomMargin(bottomHeight, padding, xAxisHeight) {
12372
+ return padding + bottomHeight + xAxisHeight;
12373
+ }
12374
+ var INLINE_TICK_OVERHANG_PAD = 6;
12375
+ function resolveChromeLayout(spec, options) {
12376
+ const encoding = spec?.encoding;
12377
+ const isFaceted = !!(encoding?.facet || encoding?.row || encoding?.column);
12378
+ if (isFaceted) return "subtract";
12379
+ return spec?.chromeLayout ?? options?.chromeLayout ?? "subtract";
12380
+ }
12381
+
12351
12382
  // src/barlist/compile-barlist.ts
12352
12383
  var DEFAULT_ROW_GAP = 8;
12353
12384
  var LABEL_BAR_GAP = 12;
@@ -12395,14 +12426,19 @@ function compileBarList(spec, options) {
12395
12426
  watermark
12396
12427
  );
12397
12428
  const padding = theme.spacing.padding;
12429
+ const chromeLayout = resolveChromeLayout(
12430
+ spec,
12431
+ options
12432
+ );
12433
+ const grownHeight = chromeLayout === "grow" ? options.height + chrome.topHeight + chrome.bottomHeight : options.height;
12398
12434
  const fullArea = {
12399
12435
  x: padding,
12400
12436
  y: padding + chrome.topHeight,
12401
12437
  width: options.width - padding * 2,
12402
- height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
12438
+ height: chromeLayout === "grow" ? options.height - padding * 2 : options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
12403
12439
  };
12404
12440
  if (fullArea.width <= 0 || fullArea.height <= 0) {
12405
- return emptyLayout2(chrome, theme, options, watermark);
12441
+ return emptyLayout2(chrome, theme, { ...options, height: grownHeight }, watermark);
12406
12442
  }
12407
12443
  const labelField = barlistSpec.encoding.label.field;
12408
12444
  const valueField = barlistSpec.encoding.value.field;
@@ -12587,7 +12623,7 @@ function compileBarList(spec, options) {
12587
12623
  a11y,
12588
12624
  theme,
12589
12625
  width: options.width,
12590
- height: options.height,
12626
+ height: grownHeight,
12591
12627
  animation: resolvedAnimation,
12592
12628
  watermark,
12593
12629
  measureText
@@ -14881,30 +14917,6 @@ function computeAxes(scales, chartArea, strategy, theme, measureText, dataContex
14881
14917
  return result;
14882
14918
  }
14883
14919
 
14884
- // src/layout/shared.ts
14885
- function chromeToInput(chrome) {
14886
- return {
14887
- eyebrow: chrome.eyebrow,
14888
- title: chrome.title,
14889
- subtitle: chrome.subtitle,
14890
- source: chrome.source,
14891
- byline: chrome.byline,
14892
- footer: chrome.footer,
14893
- brand: chrome.brand
14894
- };
14895
- }
14896
- function scalePadding(basePadding, width, height) {
14897
- const minDim = Math.min(width, height);
14898
- if (minDim >= 500) return basePadding;
14899
- if (minDim <= 200) return Math.max(Math.round(basePadding * 0.5), 4);
14900
- const t = (minDim - 200) / 300;
14901
- return Math.max(Math.round(basePadding * (0.5 + t * 0.5)), 4);
14902
- }
14903
- function bottomMargin(bottomHeight, padding, xAxisHeight) {
14904
- return padding + bottomHeight + xAxisHeight;
14905
- }
14906
- var INLINE_TICK_OVERHANG_PAD = 6;
14907
-
14908
14920
  // src/layout/plan.ts
14909
14921
  function createMeasureFn(measureText) {
14910
14922
  if (measureText) {
@@ -15126,7 +15138,9 @@ function resolveLayoutPlan(chartSpec, renderSpec, options, theme, strategy, wate
15126
15138
  if (hasTopLegend) topMargin += TOP_LEGEND_GAP_ABOVE + legendContent.height + gap;
15127
15139
  topMargin += effectiveTopAxisGap;
15128
15140
  const bMargin = bottomMargin(chrome.bottomHeight, padding, xAxisExtent);
15129
- const chartHeight = Math.max(0, height - topMargin - bMargin);
15141
+ const chromeLayout = resolveChromeLayout(renderSpec, options);
15142
+ const effectiveHeight = chromeLayout === "grow" ? height + chrome.topHeight + chrome.bottomHeight : height;
15143
+ const chartHeight = Math.max(0, effectiveHeight - topMargin - bMargin);
15130
15144
  const rightMargin = hPad + (isRadial ? hPad : axisMargin);
15131
15145
  const rightAxisReserve = options.rightAxisReserve ?? 0;
15132
15146
  const provisionalArea = {
@@ -18006,11 +18020,15 @@ function compileMap(spec, options) {
18006
18020
  watermark
18007
18021
  );
18008
18022
  const padding = getBreakpoint(options.width) === "compact" ? Math.max(HPAD_COMPACT_MIN2, Math.round(theme.spacing.padding * HPAD_COMPACT_FRACTION2)) : theme.spacing.padding;
18023
+ const chromeLayout = resolveChromeLayout(
18024
+ spec,
18025
+ options
18026
+ );
18009
18027
  const fullArea = {
18010
18028
  x: padding,
18011
18029
  y: padding + chrome.topHeight,
18012
18030
  width: options.width - padding * 2,
18013
- height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
18031
+ height: chromeLayout === "grow" ? options.height - padding * 2 : options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
18014
18032
  };
18015
18033
  if (fullArea.width <= 0 || fullArea.height <= 0) {
18016
18034
  return emptyLayout3(chrome, theme, options, watermark);
@@ -18112,7 +18130,7 @@ function compileMap(spec, options) {
18112
18130
  compileWarnings.push(...filteredJoinWarnings);
18113
18131
  }
18114
18132
  const droppedFeatures = [];
18115
- const formatter = buildD3Formatter2(mapSpec.valueFormat) ?? formatNumber3;
18133
+ const formatter = buildD3Formatter2(mapSpec.encoding?.color?.format ?? mapSpec.valueFormat) ?? formatNumber3;
18116
18134
  const neutralFill = isDarkMode ? "#2a2a2a" : "#e8e8e8";
18117
18135
  const neutralStroke = isDarkMode ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.06)";
18118
18136
  let featureMarks;
@@ -19387,6 +19405,7 @@ function legendLayoutHasContent(legendLayout) {
19387
19405
  }
19388
19406
  var MIN_CHART_WIDTH = 60;
19389
19407
  var MIN_CHART_HEIGHT2 = 40;
19408
+ var PLOT_SHARE_MAX = 0.4;
19390
19409
  var SERIES_SEARCH_INPUT_HEIGHT = 32;
19391
19410
  var SERIES_SEARCH_GAP = 12;
19392
19411
  function getMinChartDims(display) {
@@ -19429,8 +19448,10 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19429
19448
  watermark,
19430
19449
  bottomLegendReservation
19431
19450
  );
19451
+ const chromeLayout = resolveChromeLayout(spec, options);
19452
+ const effectiveHeight = chromeLayout === "grow" ? height + chrome.topHeight + chrome.bottomHeight : height;
19432
19453
  if (isSparkline) {
19433
- const total2 = { x: 0, y: 0, width, height };
19454
+ const total2 = { x: 0, y: 0, width, height: effectiveHeight };
19434
19455
  const sparkPad = getSparklinePad(spec);
19435
19456
  const xAxisSpace = userExplicit.xAxis ? 26 : 0;
19436
19457
  const yAxisSpace = userExplicit.yAxis ? 30 : 0;
@@ -19454,7 +19475,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19454
19475
  x: margins2.left,
19455
19476
  y: margins2.top,
19456
19477
  width: Math.max(0, width - margins2.left - margins2.right),
19457
- height: Math.max(0, height - margins2.top - margins2.bottom)
19478
+ height: Math.max(0, effectiveHeight - margins2.top - margins2.bottom)
19458
19479
  };
19459
19480
  return {
19460
19481
  total: total2,
@@ -19466,7 +19487,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19466
19487
  effectiveAxisGap: 0
19467
19488
  };
19468
19489
  }
19469
- const total = { x: 0, y: 0, width, height };
19490
+ const total = { x: 0, y: 0, width, height: effectiveHeight };
19470
19491
  const isRadial = isAxislessMark2(spec.markType);
19471
19492
  const encoding = spec.encoding;
19472
19493
  const xAxisSuppressed = encoding.x?.axis === false;
@@ -19696,10 +19717,11 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19696
19717
  x: margins.left,
19697
19718
  y: margins.top,
19698
19719
  width: Math.max(0, width - margins.left - margins.right),
19699
- height: Math.max(0, height - margins.top - margins.bottom)
19720
+ height: Math.max(0, effectiveHeight - margins.top - margins.bottom)
19700
19721
  };
19701
19722
  const minDims = getMinChartDims(spec.display);
19702
- if ((chartArea.width < minDims.width || chartArea.height < minDims.height) && chromeMode !== "hidden") {
19723
+ const chromeEatsPlot = chromeLayout !== "grow" && chrome.topHeight > height * PLOT_SHARE_MAX;
19724
+ if ((chartArea.width < minDims.width || chartArea.height < minDims.height || chromeEatsPlot) && chromeMode !== "hidden") {
19703
19725
  const fallbackMode = chromeMode === "full" ? "compact" : "hidden";
19704
19726
  const fallbackChrome = computeChrome5(
19705
19727
  chromeToInput(spec.chrome),
@@ -19725,7 +19747,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19725
19747
  x: margins.left,
19726
19748
  y: margins.top,
19727
19749
  width: Math.max(0, width - margins.left - margins.right),
19728
- height: Math.max(0, height - margins.top - margins.bottom)
19750
+ height: Math.max(0, effectiveHeight - margins.top - margins.bottom)
19729
19751
  };
19730
19752
  const fallbackMetricsTopY = topPad + fallbackChrome.topHeight;
19731
19753
  const fallbackMetricsArea = { x: hPad, width: Math.max(0, width - hPad * 2) };
@@ -19742,7 +19764,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19742
19764
  chartArea = {
19743
19765
  ...chartArea,
19744
19766
  y: margins.top,
19745
- height: Math.max(0, height - margins.top - margins.bottom)
19767
+ height: Math.max(0, effectiveHeight - margins.top - margins.bottom)
19746
19768
  };
19747
19769
  }
19748
19770
  return {
@@ -19758,7 +19780,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19758
19780
  fallbackMetricsArea
19759
19781
  ) : void 0,
19760
19782
  xAxisHeight,
19761
- effectiveAxisGap: fallbackEffectiveAxisGap
19783
+ effectiveAxisGap: fallbackEffectiveAxisGap,
19784
+ chromeStripped: true
19762
19785
  };
19763
19786
  }
19764
19787
  }
@@ -19770,7 +19793,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
19770
19793
  chartArea = {
19771
19794
  ...chartArea,
19772
19795
  y: margins.top,
19773
- height: Math.max(0, height - margins.top - margins.bottom)
19796
+ height: Math.max(0, effectiveHeight - margins.top - margins.bottom)
19774
19797
  };
19775
19798
  }
19776
19799
  return {
@@ -20522,14 +20545,19 @@ function compileSankey(spec, options) {
20522
20545
  watermark
20523
20546
  );
20524
20547
  const padding = theme.spacing.padding;
20548
+ const chromeLayout = resolveChromeLayout(
20549
+ spec,
20550
+ options
20551
+ );
20552
+ const grownHeight = chromeLayout === "grow" ? options.height + chrome.topHeight + chrome.bottomHeight : options.height;
20525
20553
  const fullArea = {
20526
20554
  x: padding,
20527
20555
  y: padding + chrome.topHeight,
20528
20556
  width: options.width - padding * 2,
20529
- height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
20557
+ height: chromeLayout === "grow" ? options.height - padding * 2 : options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
20530
20558
  };
20531
20559
  if (fullArea.width <= 0 || fullArea.height <= 0) {
20532
- return emptyLayout4(fullArea, chrome, theme, options, watermark);
20560
+ return emptyLayout4(fullArea, chrome, theme, { ...options, height: grownHeight }, watermark);
20533
20561
  }
20534
20562
  const sourceField = sankeySpec.encoding.source.field;
20535
20563
  const targetField = sankeySpec.encoding.target.field;
@@ -20569,7 +20597,7 @@ function compileSankey(spec, options) {
20569
20597
  height: fullArea.height - legend.bounds.height - legendGap2
20570
20598
  };
20571
20599
  if (area.height <= 0) {
20572
- return emptyLayout4(area, chrome, theme, options, watermark);
20600
+ return emptyLayout4(area, chrome, theme, { ...options, height: grownHeight }, watermark);
20573
20601
  }
20574
20602
  const labelFontSize = theme.fonts.sizes.small;
20575
20603
  const labelFontWeight = theme.fonts.weights.normal;
@@ -20721,7 +20749,7 @@ function compileSankey(spec, options) {
20721
20749
  theme,
20722
20750
  dimensions: {
20723
20751
  width: options.width,
20724
- height: options.height
20752
+ height: grownHeight
20725
20753
  },
20726
20754
  animation: resolvedAnimation,
20727
20755
  watermark,
@@ -21540,6 +21568,10 @@ var LEGEND_ENTRY_GAP = 16;
21540
21568
  function clamp(value2, min4, max4) {
21541
21569
  return Math.min(max4, Math.max(min4, value2));
21542
21570
  }
21571
+ function growContentHeight(contentHeight, chromeLayout, budgetHeight, chrome) {
21572
+ if (chromeLayout !== "grow") return contentHeight;
21573
+ return Math.max(contentHeight, budgetHeight + chrome.topHeight + chrome.bottomHeight);
21574
+ }
21543
21575
  function compileTileMap(spec, options) {
21544
21576
  const sugarWarnings = [];
21545
21577
  const expandedSpec = spec && typeof spec === "object" && !Array.isArray(spec) ? expandSpecSugar(spec, sugarWarnings) : spec;
@@ -21576,22 +21608,44 @@ function compileTileMap(spec, options) {
21576
21608
  watermark
21577
21609
  );
21578
21610
  const padding = getBreakpoint2(options.width) === "compact" ? Math.max(HPAD_COMPACT_MIN4, Math.round(theme.spacing.padding * HPAD_COMPACT_FRACTION4)) : theme.spacing.padding;
21611
+ const chromeLayout = resolveChromeLayout(
21612
+ spec,
21613
+ options
21614
+ );
21579
21615
  const fullArea = {
21580
21616
  x: padding,
21581
21617
  y: padding + chrome.topHeight,
21582
21618
  width: options.width - padding * 2,
21583
- height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
21619
+ height: chromeLayout === "grow" ? options.height - padding * 2 : options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
21584
21620
  };
21585
21621
  if (fullArea.width <= 0 || fullArea.height <= 0) {
21586
21622
  return emptyLayout5(chrome, theme, options, watermark);
21587
21623
  }
21588
21624
  const isCategorical = tilemapSpec.encoding.color !== void 0 || tilemapSpec.colors !== void 0;
21589
21625
  if (isCategorical) {
21590
- return compileCategorical(tilemapSpec, options, theme, chrome, fullArea, isDarkMode, watermark);
21626
+ return compileCategorical(
21627
+ tilemapSpec,
21628
+ options,
21629
+ theme,
21630
+ chrome,
21631
+ fullArea,
21632
+ isDarkMode,
21633
+ watermark,
21634
+ chromeLayout
21635
+ );
21591
21636
  }
21592
- return compileQuantitative(tilemapSpec, options, theme, chrome, fullArea, isDarkMode, watermark);
21637
+ return compileQuantitative(
21638
+ tilemapSpec,
21639
+ options,
21640
+ theme,
21641
+ chrome,
21642
+ fullArea,
21643
+ isDarkMode,
21644
+ watermark,
21645
+ chromeLayout
21646
+ );
21593
21647
  }
21594
- function compileQuantitative(tilemapSpec, options, theme, chrome, fullArea, isDarkMode, watermark) {
21648
+ function compileQuantitative(tilemapSpec, options, theme, chrome, fullArea, isDarkMode, watermark, chromeLayout) {
21595
21649
  const stateField = tilemapSpec.encoding.state.field;
21596
21650
  const valueField = tilemapSpec.encoding.value.field;
21597
21651
  const stateValueMap = /* @__PURE__ */ new Map();
@@ -21692,7 +21746,12 @@ function compileQuantitative(tilemapSpec, options, theme, chrome, fullArea, isDa
21692
21746
  };
21693
21747
  const resolvedAnimation = resolveAnimation(tilemapSpec.animation);
21694
21748
  const padding = fullArea.x;
21695
- const contentHeight = tileGridOffsetY + tilePositions.gridHeight + legendGap2 + legendTotalHeight + chrome.bottomHeight + padding;
21749
+ const contentHeight = growContentHeight(
21750
+ tileGridOffsetY + tilePositions.gridHeight + legendGap2 + legendTotalHeight + chrome.bottomHeight + padding,
21751
+ chromeLayout,
21752
+ options.height,
21753
+ chrome
21754
+ );
21696
21755
  return {
21697
21756
  area: fullArea,
21698
21757
  chrome,
@@ -21709,7 +21768,7 @@ function compileQuantitative(tilemapSpec, options, theme, chrome, fullArea, isDa
21709
21768
  measureText: options.measureText ?? ((text, fontSize) => ({ width: estimateTextWidth23(text, fontSize), height: fontSize }))
21710
21769
  };
21711
21770
  }
21712
- function compileCategorical(tilemapSpec, options, theme, chrome, fullArea, isDarkMode, watermark) {
21771
+ function compileCategorical(tilemapSpec, options, theme, chrome, fullArea, isDarkMode, watermark, chromeLayout) {
21713
21772
  const stateField = tilemapSpec.encoding.state.field;
21714
21773
  const colorField = tilemapSpec.encoding.color?.field ?? tilemapSpec.encoding.value.field;
21715
21774
  const stateCategoryMap = /* @__PURE__ */ new Map();
@@ -21828,7 +21887,12 @@ function compileCategorical(tilemapSpec, options, theme, chrome, fullArea, isDar
21828
21887
  };
21829
21888
  const resolvedAnimation = resolveAnimation(tilemapSpec.animation);
21830
21889
  const padding = fullArea.x;
21831
- const contentHeight = tileGridOffsetY + tilePositions.gridHeight + legendGap2 + legendTotalHeight + chrome.bottomHeight + padding;
21890
+ const contentHeight = growContentHeight(
21891
+ tileGridOffsetY + tilePositions.gridHeight + legendGap2 + legendTotalHeight + chrome.bottomHeight + padding,
21892
+ chromeLayout,
21893
+ options.height,
21894
+ chrome
21895
+ );
21832
21896
  return {
21833
21897
  area: fullArea,
21834
21898
  chrome,
@@ -23213,7 +23277,10 @@ function compileChart(spec, optionsInput) {
23213
23277
  skipY,
23214
23278
  markType: chartSpec.markType,
23215
23279
  totalWidth: options.width,
23216
- precomputedYTicks: plan.yTickValues.length > 0 ? plan.yTickValues : void 0
23280
+ // If the guardrail stripped chrome, the plan's y-ticks were sized
23281
+ // against the pre-strip (shorter) plot. Drop them so computeAxes
23282
+ // regenerates against the final (taller) chartArea.
23283
+ precomputedYTicks: !dims.chromeStripped && plan.yTickValues.length > 0 ? plan.yTickValues : void 0
23217
23284
  });
23218
23285
  const xAxisExtent = axes.x?.extent ?? 0;
23219
23286
  dims.chrome.bottomAnchorY = chartArea.y + chartArea.height + xAxisExtent;
@@ -23336,7 +23403,10 @@ function compileChart(spec, optionsInput) {
23336
23403
  theme,
23337
23404
  dimensions: {
23338
23405
  width: options.width,
23339
- height: options.height
23406
+ // In chromeLayout 'grow' mode, computeDimensions grows total.height by the
23407
+ // chrome height so the plot keeps its full budget. In the default
23408
+ // 'subtract' mode total.height === options.height, so this is a no-op.
23409
+ height: dims.total.height
23340
23410
  },
23341
23411
  animation: resolvedAnimation,
23342
23412
  watermark,
@@ -23393,11 +23463,10 @@ function compileFaceted(chartSpec, renderSpec, facetChannel, facetDirection, opt
23393
23463
  plan.xAxisExtent,
23394
23464
  dims.effectiveAxisGap
23395
23465
  );
23396
- const leftReservation = plan.leftGutter;
23397
23466
  const bottomReservation = plan.xAxisExtent;
23398
23467
  const effectiveColumns = facetDirection === "column" ? facetValues.length : facetChannel.columns;
23399
23468
  const grid = computeFacetGrid(facetValues, effectiveColumns, chartArea, {
23400
- left: leftReservation,
23469
+ left: 0,
23401
23470
  bottom: bottomReservation
23402
23471
  });
23403
23472
  if (!optionsInput.facetHeightGrown && grid.panels.length > 0 && grid.panels[0].area.height < MIN_PANEL_HEIGHT) {