ggaction 0.0.13 → 0.0.16

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 (359) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/README.md +41 -12
  3. package/knowledge/action-cards.json +1 -1
  4. package/knowledge/intent-taxonomy.json +1 -1
  5. package/knowledge/mcp-resources.json +1 -1
  6. package/knowledge/task-packet.schema.json +1 -1
  7. package/knowledge/task-resolver.js +1 -1
  8. package/package.json +39 -7
  9. package/src/BasicChartProgram.js +3 -1
  10. package/src/ChartProgram.js +2 -0
  11. package/src/accessibility.js +157 -0
  12. package/src/actions/basic.js +2 -2
  13. package/src/actions/boxPlots/components.js +20 -12
  14. package/src/actions/boxPlots/create.js +4 -5
  15. package/src/actions/boxPlots/edit.js +34 -9
  16. package/src/actions/boxPlots/materialize.js +12 -4
  17. package/src/actions/boxPlots/options.js +48 -16
  18. package/src/actions/canvas/actions.js +3 -3
  19. package/src/actions/canvas/fitting.js +1 -1
  20. package/src/actions/categoryOrder/index.js +21 -12
  21. package/src/actions/charts/area.js +6 -2
  22. package/src/actions/charts/bar.js +3 -2
  23. package/src/actions/charts/beeswarm.js +1 -1
  24. package/src/actions/charts/density.js +7 -3
  25. package/src/actions/charts/ecdf.js +6 -3
  26. package/src/actions/charts/endpoints.js +29 -7
  27. package/src/actions/charts/heatmap.js +3 -2
  28. package/src/actions/charts/histogram.js +5 -4
  29. package/src/actions/charts/horizon.js +4 -2
  30. package/src/actions/charts/interval-regression.js +7 -4
  31. package/src/actions/charts/line.js +4 -2
  32. package/src/actions/charts/parallel.js +9 -3
  33. package/src/actions/charts/pie.js +11 -3
  34. package/src/actions/charts/polar.js +17 -6
  35. package/src/actions/charts/radar.js +9 -3
  36. package/src/actions/charts/radial.js +12 -4
  37. package/src/actions/charts/raincloud.js +2 -2
  38. package/src/actions/charts/rug-strip.js +8 -4
  39. package/src/actions/charts/scatter.js +4 -2
  40. package/src/actions/composition/actions.js +29 -24
  41. package/src/actions/coordinates/actions.js +2 -2
  42. package/src/actions/coordinates/edit.js +76 -0
  43. package/src/actions/data/basicBin2d.js +4 -5
  44. package/src/actions/data/bin.js +3 -3
  45. package/src/actions/data/bin2d.js +63 -193
  46. package/src/actions/data/bin2dMaterialize.js +4 -5
  47. package/src/actions/data/box.js +4 -4
  48. package/src/actions/data/complete.js +26 -0
  49. package/src/actions/data/computed.js +4 -4
  50. package/src/actions/data/create.js +7 -14
  51. package/src/actions/data/density.js +15 -23
  52. package/src/actions/data/derived.js +57 -31
  53. package/src/actions/data/ecdf.js +2 -2
  54. package/src/actions/data/edit.js +551 -0
  55. package/src/actions/data/filter.js +28 -22
  56. package/src/actions/data/fold.js +2 -2
  57. package/src/actions/data/gradientProfile.js +2 -2
  58. package/src/actions/data/horizon.js +2 -2
  59. package/src/actions/data/impute.js +26 -0
  60. package/src/actions/data/index.js +62 -47
  61. package/src/actions/data/interval.js +2 -2
  62. package/src/actions/data/intervalEdit.js +26 -18
  63. package/src/actions/data/normalize.js +27 -0
  64. package/src/actions/data/regression.js +21 -27
  65. package/src/actions/data/revise.js +48 -0
  66. package/src/actions/data/revisionBindings.js +125 -0
  67. package/src/actions/data/shared.js +20 -4
  68. package/src/actions/data/stack.js +2 -2
  69. package/src/actions/data/summary.js +3 -3
  70. package/src/actions/data/timeUnit.js +6 -3
  71. package/src/actions/data/window.js +3 -3
  72. package/src/actions/encodings/angle.js +1 -1
  73. package/src/actions/encodings/appearance.js +4 -4
  74. package/src/actions/encodings/barWidth.js +1 -1
  75. package/src/actions/encodings/channels.js +415 -0
  76. package/src/actions/encodings/color/index.js +3 -2
  77. package/src/actions/encodings/density.js +7 -4
  78. package/src/actions/encodings/histogram.js +4 -3
  79. package/src/actions/encodings/horizon.js +6 -8
  80. package/src/actions/encodings/index.js +4 -0
  81. package/src/actions/encodings/offset.js +22 -15
  82. package/src/actions/encodings/parallel.js +4 -5
  83. package/src/actions/encodings/pathOrder.js +6 -11
  84. package/src/actions/encodings/position/apply.js +53 -7
  85. package/src/actions/encodings/position/index.js +14 -6
  86. package/src/actions/encodings/position/policies/bar.js +9 -0
  87. package/src/actions/encodings/position/resolve.js +24 -7
  88. package/src/actions/encodings/ranged.js +5 -5
  89. package/src/actions/encodings/remove.js +13 -9
  90. package/src/actions/encodings/ruleAppearance.js +2 -24
  91. package/src/actions/encodings/seriesLayout.js +2 -1
  92. package/src/actions/encodings/shared.js +82 -14
  93. package/src/actions/encodings/stroke.js +226 -0
  94. package/src/actions/encodings/strokeDash.js +2 -2
  95. package/src/actions/encodings/text.js +1 -1
  96. package/src/actions/errorBands/create.js +34 -20
  97. package/src/actions/errorBands/edit.js +34 -137
  98. package/src/actions/errorBars/create.js +43 -20
  99. package/src/actions/errorBars/edit.js +29 -125
  100. package/src/actions/facets/actions.js +267 -73
  101. package/src/actions/facets/derive.js +99 -28
  102. package/src/actions/facets/guides.js +4 -5
  103. package/src/actions/facets/replay.js +4 -5
  104. package/src/actions/gradientPlots/components.js +15 -8
  105. package/src/actions/gradientPlots/create.js +4 -5
  106. package/src/actions/gradientPlots/edit.js +18 -9
  107. package/src/actions/gradientPlots/materialize.js +5 -3
  108. package/src/actions/gradientPlots/options.js +10 -2
  109. package/src/actions/gradientPlots/rebind.js +4 -5
  110. package/src/actions/guides/applicability.js +8 -2
  111. package/src/actions/guides/axes/axes.js +23 -4
  112. package/src/actions/guides/axes/axis.js +2 -2
  113. package/src/actions/guides/axes/edit.js +2 -2
  114. package/src/actions/guides/axes/labels.js +67 -21
  115. package/src/actions/guides/axes/lines.js +15 -9
  116. package/src/actions/guides/axes/parallel/lifecycle.js +13 -13
  117. package/src/actions/guides/axes/parallel/resolve.js +6 -2
  118. package/src/actions/guides/axes/parallel.js +5 -5
  119. package/src/actions/guides/axes/remove.js +4 -4
  120. package/src/actions/guides/axes/tickGroups.js +6 -5
  121. package/src/actions/guides/axes/ticks.js +19 -6
  122. package/src/actions/guides/axes/titles.js +21 -13
  123. package/src/actions/guides/grids/grid.js +18 -29
  124. package/src/actions/guides/grids/resolve.js +7 -2
  125. package/src/actions/guides/guides.js +20 -4
  126. package/src/actions/guides/legends/blocks.js +426 -0
  127. package/src/actions/guides/legends/categorical/actions.js +138 -52
  128. package/src/actions/guides/legends/categorical/components.js +55 -45
  129. package/src/actions/guides/legends/categorical/index.js +37 -33
  130. package/src/actions/guides/legends/categorical/layout.js +98 -16
  131. package/src/actions/guides/legends/categorical/options.js +2 -2
  132. package/src/actions/guides/legends/categorical/recipes.js +111 -20
  133. package/src/actions/guides/legends/categorical/resolve.js +12 -8
  134. package/src/actions/guides/legends/categorical/symbols.js +104 -52
  135. package/src/actions/guides/legends/continuous/common.js +76 -20
  136. package/src/actions/guides/legends/continuous/gradient.js +95 -158
  137. package/src/actions/guides/legends/continuous/index.js +2 -0
  138. package/src/actions/guides/legends/continuous/interval.js +21 -16
  139. package/src/actions/guides/legends/continuous/opacity.js +37 -83
  140. package/src/actions/guides/legends/continuous/stroke.js +225 -0
  141. package/src/actions/guides/legends/creation.js +14 -1
  142. package/src/actions/guides/legends/edit.js +159 -60
  143. package/src/actions/guides/legends/focused.js +5 -5
  144. package/src/actions/guides/legends/index.js +2 -0
  145. package/src/actions/guides/legends/lane.js +59 -24
  146. package/src/actions/guides/legends/lifecycle.js +19 -8
  147. package/src/actions/guides/legends/remove.js +17 -8
  148. package/src/actions/guides/legends/sampling.js +140 -0
  149. package/src/actions/guides/legends/size.js +100 -108
  150. package/src/actions/guides/legends/strokeWidth.js +38 -92
  151. package/src/actions/guides/legends/target.js +112 -1
  152. package/src/actions/guides/legends/transition.js +165 -16
  153. package/src/actions/guides/polar/axes/facade.js +8 -8
  154. package/src/actions/guides/polar/axes/labels.js +29 -10
  155. package/src/actions/guides/polar/axes/lines.js +19 -19
  156. package/src/actions/guides/polar/axes/shared.js +16 -0
  157. package/src/actions/guides/polar/axes/ticks.js +10 -16
  158. package/src/actions/guides/polar/axes/titles.js +6 -6
  159. package/src/actions/guides/polar/grids.js +12 -14
  160. package/src/actions/guides/polar/resolve.js +12 -8
  161. package/src/actions/index.js +16 -3
  162. package/src/actions/intervals/revision.js +126 -0
  163. package/src/actions/marks/arc/actions.js +80 -22
  164. package/src/actions/marks/area/actions.js +38 -13
  165. package/src/actions/marks/area/materialize.js +17 -1
  166. package/src/actions/marks/bar/create.js +12 -3
  167. package/src/actions/marks/bar/edit.js +21 -4
  168. package/src/actions/marks/bar/materialize.js +34 -40
  169. package/src/actions/marks/index.js +10 -1
  170. package/src/actions/marks/line/actions.js +40 -17
  171. package/src/actions/marks/line/materialize.js +29 -10
  172. package/src/actions/marks/point/create.js +9 -3
  173. package/src/actions/marks/point/edit.js +19 -7
  174. package/src/actions/marks/point/jitter.js +6 -8
  175. package/src/actions/marks/point/materialize.js +48 -22
  176. package/src/actions/marks/point/packing.js +6 -8
  177. package/src/actions/marks/rect/actions.js +36 -15
  178. package/src/actions/marks/references.js +602 -33
  179. package/src/actions/marks/remove.js +67 -41
  180. package/src/actions/marks/rule/actions.js +51 -14
  181. package/src/actions/marks/shared.js +1 -1
  182. package/src/actions/marks/text/actions.js +79 -14
  183. package/src/actions/marks/text/index.js +4 -0
  184. package/src/actions/marks/text/layout.js +157 -17
  185. package/src/actions/marks/text/removal.js +173 -0
  186. package/src/actions/marks/text/selection.js +72 -0
  187. package/src/actions/marks/tick/actions.js +25 -8
  188. package/src/actions/primitives/createGraphics.js +5 -4
  189. package/src/actions/primitives/editGraphics.js +31 -4
  190. package/src/actions/primitives/graphicProperties.js +6 -0
  191. package/src/actions/primitives/semantic.js +11 -3
  192. package/src/actions/primitives/semanticAction.js +90 -14
  193. package/src/actions/primitives/semanticValidation/dataset.js +2 -4
  194. package/src/actions/primitives/semanticValidation/guide.js +1 -1
  195. package/src/actions/primitives/semanticValidation/index.js +9 -1
  196. package/src/actions/primitives/semanticValidation/layer.js +5 -0
  197. package/src/actions/primitives/semanticValidation/scale.js +28 -7
  198. package/src/actions/regression/components.js +36 -25
  199. package/src/actions/regression/create.js +13 -6
  200. package/src/actions/regression/edit.js +24 -11
  201. package/src/actions/resources/index.js +7 -0
  202. package/src/actions/resources/remove.js +173 -0
  203. package/src/actions/scales/channels.js +212 -0
  204. package/src/actions/scales/consumers/common.js +1 -1
  205. package/src/actions/scales/consumers/families.js +3 -2
  206. package/src/actions/scales/consumers/index.js +19 -2
  207. package/src/actions/scales/consumers/seriesLayout.js +28 -14
  208. package/src/actions/scales/create.js +55 -23
  209. package/src/actions/scales/definitions.js +94 -40
  210. package/src/actions/scales/edit.js +67 -12
  211. package/src/actions/scales/editPolicy.js +81 -11
  212. package/src/actions/scales/index.js +6 -0
  213. package/src/actions/scales/materialize.js +5 -4
  214. package/src/actions/scales/offset.js +48 -0
  215. package/src/actions/scales/parallel.js +71 -0
  216. package/src/actions/scales/preview.js +111 -10
  217. package/src/actions/scales/quantitativeColor.js +4 -5
  218. package/src/actions/selection/actions.js +179 -66
  219. package/src/actions/selection/index.js +3 -0
  220. package/src/actions/textMetrics/index.js +56 -0
  221. package/src/actions/theme/actions.js +70 -15
  222. package/src/actions/theme/composition.js +238 -0
  223. package/src/actions/theme/index.js +9 -2
  224. package/src/actions/theme/reconcile.js +313 -121
  225. package/src/actions/theme/state.js +160 -0
  226. package/src/actions/titles/actions.js +8 -8
  227. package/src/actions/titles/resolve.js +3 -3
  228. package/src/actions/violinPlots/create.js +6 -3
  229. package/src/actions/violinPlots/edit.js +2 -1
  230. package/src/core/action.js +117 -35
  231. package/src/core/compositionState.js +6 -1
  232. package/src/core/diagnostics.js +16 -0
  233. package/src/core/extensionRegistry.js +27 -0
  234. package/src/core/font.js +18 -0
  235. package/src/core/identifiers.js +5 -4
  236. package/src/core/immutable.js +10 -3
  237. package/src/core/optionRequirements.js +8 -0
  238. package/src/core/programState.js +21 -1
  239. package/src/core/resourceReferences.js +341 -0
  240. package/src/core/textMetricProfile.js +28 -0
  241. package/src/core/textMetrics.js +24 -3
  242. package/src/core/validation.js +22 -10
  243. package/src/core/vocabulary.js +16 -3
  244. package/src/diagnostics.js +1 -0
  245. package/src/grammar/bars/aggregate.js +4 -1
  246. package/src/grammar/bars/geometry.js +44 -0
  247. package/src/grammar/bin.js +54 -9
  248. package/src/grammar/complete.js +279 -0
  249. package/src/grammar/computed.js +265 -64
  250. package/src/grammar/coordinates.js +37 -0
  251. package/src/grammar/density.js +239 -37
  252. package/src/grammar/displayLabels.js +57 -0
  253. package/src/grammar/facets/dependencies.js +133 -1
  254. package/src/grammar/facets/guides.js +3 -0
  255. package/src/grammar/facets/index.js +7 -47
  256. package/src/grammar/facets/scales.js +15 -18
  257. package/src/grammar/impute.js +341 -0
  258. package/src/grammar/markLabelSelection.js +57 -0
  259. package/src/grammar/markLabels.js +18 -1
  260. package/src/grammar/normalize.js +366 -0
  261. package/src/grammar/pathSeries.js +26 -8
  262. package/src/grammar/pointShapes.js +13 -4
  263. package/src/grammar/polar.js +90 -8
  264. package/src/grammar/regression/index.js +1 -0
  265. package/src/grammar/regression/parameters.js +23 -0
  266. package/src/grammar/roundedRect.js +180 -0
  267. package/src/grammar/rules.js +1 -0
  268. package/src/grammar/scales/colorConsumers.js +20 -1
  269. package/src/grammar/scales/continuous.js +2 -2
  270. package/src/grammar/scales/definition.js +27 -4
  271. package/src/grammar/scales/index.js +1 -0
  272. package/src/grammar/scales/ordinal.js +12 -3
  273. package/src/grammar/scales/policies.js +2 -2
  274. package/src/grammar/scales/size.js +456 -0
  275. package/src/grammar/scales/types.js +8 -0
  276. package/src/grammar/schemas/concreteGraphic.js +14 -2
  277. package/src/grammar/schemas/graphic.js +15 -0
  278. package/src/grammar/schemas/graphicBounds.js +190 -41
  279. package/src/grammar/schemas/semanticPath.js +7 -2
  280. package/src/grammar/statisticalReference.js +103 -0
  281. package/src/grammar/strokeStyle.js +77 -0
  282. package/src/grammar/summary.js +78 -16
  283. package/src/grammar/timeUnit.js +216 -5
  284. package/src/grammar/transformTopology.js +4 -0
  285. package/src/grammar/transforms.js +394 -28
  286. package/src/grammar/weightedStatistics.js +374 -0
  287. package/src/grammar/window.js +221 -16
  288. package/src/layout/aspect.js +80 -0
  289. package/src/layout/facets.js +59 -5
  290. package/src/layout/labels.js +351 -7
  291. package/src/layout/legend.js +4 -4
  292. package/src/layout/legendItems.js +6 -6
  293. package/src/layout/text.js +10 -9
  294. package/src/layout/title.js +9 -9
  295. package/src/materialization/bars/aggregate.js +25 -2
  296. package/src/materialization/bars/histogram.js +84 -24
  297. package/src/materialization/bars/ranged.js +19 -3
  298. package/src/materialization/bars/resolve.js +7 -4
  299. package/src/materialization/composition.js +3 -1
  300. package/src/materialization/coordinateBounds.js +204 -0
  301. package/src/materialization/dependencies.js +36 -0
  302. package/src/materialization/facetGuides/legacyCategorical.js +3 -0
  303. package/src/materialization/facetGuides/placement.js +9 -3
  304. package/src/materialization/facetGuides/preparation.js +13 -8
  305. package/src/materialization/facetHeaders.js +347 -0
  306. package/src/materialization/facets.js +15 -65
  307. package/src/materialization/guides/layout.js +3 -3
  308. package/src/materialization/guides/resources.js +26 -0
  309. package/src/materialization/legends.js +1 -1
  310. package/src/materialization/marks/index.js +11 -5
  311. package/src/materialization/marks/policies.js +2 -1
  312. package/src/materialization/rect.js +25 -12
  313. package/src/materialization/rectConfig.js +5 -1
  314. package/src/materialization/scaleGuideDependencies.js +10 -0
  315. package/src/materialization/scales/map.js +5 -3
  316. package/src/materialization/scales/policies/binnedPosition.js +2 -2
  317. package/src/materialization/scales/policies/offset.js +50 -8
  318. package/src/materialization/scales/policies/series.js +4 -1
  319. package/src/materialization/scales/resolve.js +22 -6
  320. package/src/materialization/selection/items/arc.js +28 -4
  321. package/src/materialization/selection/items/bar.js +30 -3
  322. package/src/materialization/selection/items/common.js +20 -5
  323. package/src/materialization/selection/items/rect.js +28 -4
  324. package/src/materialization/selection/path.js +1 -1
  325. package/src/materialization/selection/point.js +3 -1
  326. package/src/materialization/text.js +265 -14
  327. package/src/materialization/typography.js +31 -0
  328. package/src/mcp/cli.js +5 -3
  329. package/src/persistence/codec.js +65 -0
  330. package/src/persistence/validation.js +185 -0
  331. package/src/persistence.js +74 -0
  332. package/src/renderers/canvas/circle.js +2 -3
  333. package/src/renderers/canvas/index.js +5 -4
  334. package/src/renderers/canvas/line.js +2 -3
  335. package/src/renderers/canvas/native.js +4 -4
  336. package/src/renderers/canvas/path.js +2 -3
  337. package/src/renderers/canvas/rect.js +2 -3
  338. package/src/renderers/canvas/stroke.js +11 -0
  339. package/src/renderers/nativeBackend.js +10 -0
  340. package/src/renderers/options.js +13 -0
  341. package/src/renderers/pdf.js +25 -54
  342. package/src/renderers/png.js +22 -17
  343. package/src/renderers/svg.js +29 -14
  344. package/src/renderers/text.js +1 -11
  345. package/src/selectors/coordinates.js +3 -1
  346. package/src/selectors/datasets.js +38 -5
  347. package/src/selectors/layers.js +10 -4
  348. package/src/selectors/markOwners.js +46 -0
  349. package/src/selectors/scales.js +6 -4
  350. package/src/theme/defaults.js +103 -1
  351. package/src/version.js +2 -0
  352. package/types/accessibility.d.ts +37 -0
  353. package/types/basic.d.ts +10 -2
  354. package/types/diagnostics.d.ts +15 -0
  355. package/types/index.d.ts +90 -0
  356. package/types/pdf.d.ts +9 -0
  357. package/types/persistence.d.ts +7 -0
  358. package/types/png.d.ts +9 -0
  359. package/types/program.d.ts +944 -118
@@ -4,10 +4,14 @@ import { readQuantitativeField } from "../../grammar/scales/index.js";
4
4
  import { BAR_GRAINS, resolveBarGrain } from "../../grammar/bars/policy.js";
5
5
  import { resolveFacetScaleDomains } from "../../grammar/facets/scales.js";
6
6
  import {
7
+ applyLayerEmptyDataView,
7
8
  applyMaterializationPlan,
8
9
  planScaleGuideRematerialization
9
10
  } from "../../materialization/dependencies.js";
10
- import { getMarkMaterializationStep } from "../../materialization/marks/index.js";
11
+ import {
12
+ getLayerScaleIds,
13
+ getMarkMaterializationStep
14
+ } from "../../materialization/marks/index.js";
11
15
  import { buildMaterializationPlan } from "../../materialization/planner.js";
12
16
  import { requireDataset } from "../../selectors/datasets.js";
13
17
  import { requireLayer } from "../../selectors/layers.js";
@@ -56,7 +60,7 @@ function applySharedHistogramBoundaries(program, layerId, boundaries) {
56
60
  });
57
61
  }
58
62
 
59
- function deriveCellProgram(
63
+ function buildFacetCellCandidate(
60
64
  base,
61
65
  definition,
62
66
  cell,
@@ -81,12 +85,6 @@ function deriveCellProgram(
81
85
  });
82
86
  source = id;
83
87
  }
84
- if (requireDataset(child, cell.data).values.length === 0) {
85
- while (child.semanticSpec.layers.length > 0) {
86
- child = child.removeMark({ target: child.semanticSpec.layers[0].id });
87
- }
88
- return child;
89
- }
90
88
  const datasets = new Map([[definition.data, cell.data]]);
91
89
  for (const replay of definition.dependencies.replay) {
92
90
  const source = datasets.get(replay.source);
@@ -108,6 +106,7 @@ function deriveCellProgram(
108
106
  });
109
107
  datasets.set(replay.id, id);
110
108
  }
109
+ const reboundData = new Map();
111
110
  for (const layer of definition.dependencies.layers) {
112
111
  const data = datasets.get(layer.data);
113
112
  if (data === undefined) {
@@ -115,6 +114,14 @@ function deriveCellProgram(
115
114
  `Facet layer "${layer.id}" has no replayed dataset in cell "${cell.id}".`
116
115
  );
117
116
  }
117
+ reboundData.set(layer.id, data);
118
+ const statistical = child.markConfigs[layer.id]?.statisticalReference;
119
+ if (statistical !== undefined) {
120
+ child = child._withMarkConfig(layer.id, {
121
+ ...child.markConfigs[layer.id],
122
+ statisticalReference: { ...statistical, dataId: data }
123
+ });
124
+ }
118
125
  child = child.rebindLayerData({ id: layer.id, data });
119
126
  child = applySharedHistogramBoundaries(
120
127
  child,
@@ -134,20 +141,35 @@ function deriveCellProgram(
134
141
  }
135
142
  child = child.rebindGradientPlotProfile({ id, profile, source });
136
143
  }
137
- const scaleIds = [...new Set(child.semanticSpec.layers.flatMap(layer =>
138
- Object.values(layer.encoding ?? {})
139
- .map(encoding => encoding?.scale)
140
- .filter(id => id !== undefined)
141
- ))];
142
- return applyMaterializationPlan(child, buildMaterializationPlan({
144
+ const primaryLayers = definition.dependencies.primaryLayers ??
145
+ definition.dependencies.layers.map(layer => layer.id);
146
+ const populated = primaryLayers.some(id => {
147
+ const data = reboundData.get(id);
148
+ return data !== undefined && requireDataset(child, data).values.length > 0;
149
+ });
150
+ if (!populated) {
151
+ for (const layer of definition.dependencies.layers) {
152
+ child = applyLayerEmptyDataView(child, layer.id);
153
+ }
154
+ return { program: child, populated: false };
155
+ }
156
+ const scaleIds = [...new Set(child.semanticSpec.layers.flatMap(getLayerScaleIds))];
157
+ const program = applyMaterializationPlan(child, buildMaterializationPlan({
143
158
  scales: scaleIds.map(id => ({
144
159
  op: "rematerializeScale",
145
160
  args: { id, guides: false, marks: false }
146
161
  }))
147
162
  }));
163
+ return { program, populated: true };
148
164
  }
149
165
 
150
- function applyResolvedDomains(program, childId, resolution, baseResolved) {
166
+ function applyResolvedDomains(
167
+ program,
168
+ childId,
169
+ resolution,
170
+ baseResolved,
171
+ { marks: materializeMarks = true } = {}
172
+ ) {
151
173
  let next = program;
152
174
  for (const [id, scaleResolution] of Object.entries(resolution.scales)) {
153
175
  const current = next.resolvedScales[id];
@@ -157,19 +179,22 @@ function applyResolvedDomains(program, childId, resolution, baseResolved) {
157
179
  const shared = scaleResolution.policy === "shared"
158
180
  ? baseResolved?.[id]
159
181
  : undefined;
182
+ const semanticDomain = findSemanticScale(next, id)?.domain;
183
+ const domain = scaleResolution.childDomains[childId] ??
184
+ scaleResolution.domain ?? semanticDomain;
160
185
  next = next._withResolvedScale(id, {
161
186
  ...current,
162
187
  ...shared,
163
- domain: scaleResolution.childDomains[childId]
188
+ domain
164
189
  });
165
190
  }
166
- const marks = next.semanticSpec.layers.flatMap(layer => {
191
+ const marks = materializeMarks ? next.semanticSpec.layers.flatMap(layer => {
167
192
  const step = getMarkMaterializationStep(next, layer);
168
193
  if (step === undefined) return [];
169
- return ["bar", "line", "area"].includes(layer.mark?.type)
194
+ return ["bar", "line", "area", "arc"].includes(layer.mark?.type)
170
195
  ? [{ ...step, args: { ...step.args, scales: false } }]
171
196
  : [step];
172
- });
197
+ }) : [];
173
198
  const guides = Object.keys(resolution.scales).flatMap(id =>
174
199
  planScaleGuideRematerialization(next, id)
175
200
  );
@@ -179,6 +204,22 @@ function applyResolvedDomains(program, childId, resolution, baseResolved) {
179
204
  );
180
205
  }
181
206
 
207
+ function materializeFacetCell(
208
+ child,
209
+ childId,
210
+ resolution,
211
+ baseResolved,
212
+ populated
213
+ ) {
214
+ return applyResolvedDomains(
215
+ child,
216
+ childId,
217
+ resolution,
218
+ baseResolved,
219
+ { marks: populated }
220
+ );
221
+ }
222
+
182
223
  export function deriveFacetChildren(
183
224
  base,
184
225
  definition,
@@ -196,32 +237,49 @@ export function deriveFacetChildren(
196
237
  const bins = xPolicy === "shared"
197
238
  ? sharedHistogramBoundaries(template)
198
239
  : new Map();
199
- const independentlyResolved = Object.fromEntries(definition.cells.map(cell => [
240
+ const candidates = Object.fromEntries(definition.cells.map(cell => [
200
241
  cell.id,
201
- deriveCellProgram(template, definition, cell, bins, scales)
242
+ buildFacetCellCandidate(template, definition, cell, bins, scales)
202
243
  ]));
244
+ const independentlyResolved = Object.fromEntries(Object.entries(candidates).map(
245
+ ([id, candidate]) => [id, candidate.program]
246
+ ));
247
+ const populatedIds = new Set(Object.entries(candidates).flatMap(
248
+ ([id, candidate]) => candidate.populated ? [id] : []
249
+ ));
203
250
  return resolveFacetChildrenScales(
204
251
  template,
205
252
  definition.cells.map(cell => cell.id),
206
253
  independentlyResolved,
207
254
  scales,
208
- closeInheritedAction
255
+ closeInheritedAction,
256
+ populatedIds
209
257
  );
210
258
  }
211
259
 
260
+ function closeInheritedActions(program) {
261
+ let closed = program;
262
+ while (closed.actionStack.length > 0) closed = closed._exitAction();
263
+ return closed;
264
+ }
265
+
212
266
  export function resolveFacetChildrenScales(
213
267
  template,
214
268
  cellIds,
215
269
  independentlyResolved,
216
270
  scales = {},
217
- closeInheritedAction = false
271
+ closeInheritedAction = false,
272
+ populatedIds = undefined
218
273
  ) {
219
274
  const populated = Object.fromEntries(cellIds.flatMap(id => {
220
275
  const child = independentlyResolved[id];
221
276
  if (child === undefined) {
222
277
  throw new Error(`Facet derivation is missing child "${id}".`);
223
278
  }
224
- return child.semanticSpec.layers.length > 0 ? [[id, child]] : [];
279
+ const populated = populatedIds === undefined
280
+ ? child.semanticSpec.layers.length > 0
281
+ : populatedIds.has(id);
282
+ return populated ? [[id, child]] : [];
225
283
  }));
226
284
  if (Object.keys(populated).length === 0) {
227
285
  throw new Error("Facet derivation requires at least one populated cell.");
@@ -235,19 +293,32 @@ export function resolveFacetChildrenScales(
235
293
  scales,
236
294
  template.resolvedScales
237
295
  );
296
+ const emptyIds = cellIds.filter(id => !Object.hasOwn(populated, id));
297
+ const scalesById = new Map(template.semanticSpec.scales.map(scale => [scale.id, scale]));
298
+ for (const childId of emptyIds) {
299
+ const unresolved = Object.entries(resolution.scales).find(([id, value]) =>
300
+ value.policy === "independent" && scalesById.get(id)?.domain === "auto"
301
+ );
302
+ if (unresolved !== undefined) {
303
+ throw new Error(
304
+ `Facet child "${childId}" cannot resolve independent scale "${unresolved[0]}" from an empty partition.`
305
+ );
306
+ }
307
+ }
238
308
  const resolvedChildren = Object.fromEntries(
239
309
  cellIds.map(id => {
240
310
  const child = independentlyResolved[id];
241
311
  if (child.semanticSpec.layers.length === 0) {
242
- return [id, closeInheritedAction ? child._exitAction() : child];
312
+ return [id, closeInheritedAction ? closeInheritedActions(child) : child];
243
313
  }
244
- const resolved = applyResolvedDomains(
314
+ const resolved = materializeFacetCell(
245
315
  child,
246
316
  id,
247
317
  resolution,
248
- template.resolvedScales
318
+ template.resolvedScales,
319
+ Object.hasOwn(populated, id)
249
320
  );
250
- return [id, closeInheritedAction ? resolved._exitAction() : resolved];
321
+ return [id, closeInheritedAction ? closeInheritedActions(resolved) : resolved];
251
322
  })
252
323
  );
253
324
  const firstPopulatedId = Object.keys(populated)[0];
@@ -1,16 +1,15 @@
1
- import { action } from "../../core/action.js";
2
- import { validateKeys } from "../../core/validation.js";
1
+ import { closedAction } from "../../core/action.js";
2
+
3
3
  import { applyFacetGuideComposition } from
4
4
  "../../materialization/facetGuides/index.js";
5
5
 
6
- export const composeFacetGuides = action(
6
+ export const composeFacetGuides = /* @__PURE__ */ closedAction(
7
7
  {
8
8
  op: "composeFacetGuides",
9
9
  description: "Apply outer-axis ownership and promote shared facet legends.",
10
10
  scope: "composition"
11
- },
11
+ }, ["layout", "plot"],
12
12
  function ({ layout, plot } = {}) {
13
- validateKeys({ layout, plot }, ["layout", "plot"], "composeFacetGuides");
14
13
  return applyFacetGuideComposition(this, { layout, plot });
15
14
  }
16
15
  );
@@ -1,7 +1,7 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { isPlainObject } from "../../core/immutable.js";
3
3
  import { validateUserId } from "../../core/identifiers.js";
4
- import { validateKeys } from "../../core/validation.js";
4
+
5
5
  import { findTransformPolicy } from "../../grammar/transforms.js";
6
6
 
7
7
  const REPLAY_OPTIONS = Object.freeze(["id", "source", "transform"]);
@@ -22,13 +22,12 @@ function requestedTransform(transform) {
22
22
  };
23
23
  }
24
24
 
25
- export const replayDerivedData = action(
25
+ export const replayDerivedData = /* @__PURE__ */ closedAction(
26
26
  {
27
27
  op: "replayDerivedData",
28
28
  description: "Replay one stored derived-data transform for a facet cell."
29
- },
29
+ }, REPLAY_OPTIONS,
30
30
  function (args = {}) {
31
- validateKeys(args, REPLAY_OPTIONS, "replayDerivedData");
32
31
  const id = validateUserId(args.id, "Facet replay dataset id");
33
32
  const source = validateUserId(args.source, "Facet replay source id");
34
33
  const resolved = requestedTransform(args.transform);
@@ -1,7 +1,11 @@
1
1
  import { assertGuideOptions, guideConflict } from "../guides/reuse.js";
2
- import { action } from "../../core/action.js";
2
+ import { action, closedAction } from "../../core/action.js";
3
3
  import { validateKeys } from "../../core/validation.js";
4
4
  import { GRADIENT_PROFILE_FIELDS } from "../../grammar/gradientProfile.js";
5
+ import {
6
+ requestedStrokeDetails,
7
+ STROKE_STYLE_PROPERTIES
8
+ } from "../../grammar/strokeStyle.js";
5
9
  import { resolveGraphicBounds } from "../../layout/canvas.js";
6
10
  import { findLayer } from "../../selectors/layers.js";
7
11
  import { createDensityLegendPaint } from "./paint.js";
@@ -9,21 +13,24 @@ import { createDensityLegendPaint } from "./paint.js";
9
13
  const CENTER_OPTIONS = Object.freeze([
10
14
  "id", "owner", "data", "category", "categoryType", "coordinate",
11
15
  "categoryScale", "measureScale", "orientation", "size", "stroke",
12
- "strokeWidth"
16
+ "strokeWidth", ...STROKE_STYLE_PROPERTIES
13
17
  ]);
14
18
  const LEGEND_OPTIONS = Object.freeze(["owner", "title", "position"]);
15
19
 
16
- export const createGradientPlotCenter = action(
20
+ export const createGradientPlotCenter = /* @__PURE__ */ closedAction(
17
21
  {
18
22
  op: "createGradientPlotCenter",
19
23
  description: "Create the optional center rule for one gradient plot."
20
- },
24
+ }, CENTER_OPTIONS,
21
25
  function (args = {}) {
22
- validateKeys(args, CENTER_OPTIONS, "createGradientPlotCenter");
23
26
  const categoryAction = args.orientation === "vertical" ? "encodeX" : "encodeY";
24
27
  const measureAction = args.orientation === "vertical" ? "encodeY" : "encodeX";
25
28
  const spanOrientation = args.orientation === "vertical" ? "horizontal" : "vertical";
26
- let next = this.createRuleMark({ id: args.id, data: args.data });
29
+ let next = this.createRuleMark({
30
+ id: args.id,
31
+ data: args.data,
32
+ ...requestedStrokeDetails(args, "createGradientPlotCenter")
33
+ });
27
34
  next = next[categoryAction]({
28
35
  target: args.id,
29
36
  field: args.category,
@@ -74,7 +81,7 @@ function editProperties(program, target, properties) {
74
81
  return next;
75
82
  }
76
83
 
77
- export const rematerializeGradientPlotLegend = action(
84
+ export const rematerializeGradientPlotLegend = /* @__PURE__ */ action(
78
85
  {
79
86
  op: "rematerializeGradientPlotLegend",
80
87
  description: "Rematerialize one gradient plot density legend."
@@ -152,7 +159,7 @@ export function fulfillGradientPlotLegend(program, args) {
152
159
  return program;
153
160
  }
154
161
 
155
- export const createGradientPlotLegend = action(
162
+ export const createGradientPlotLegend = /* @__PURE__ */ action(
156
163
  {
157
164
  op: "createGradientPlotLegend",
158
165
  description: "Create the neutral density legend owned by one gradient plot."
@@ -1,5 +1,5 @@
1
- import { action } from "../../core/action.js";
2
- import { validateKeys } from "../../core/validation.js";
1
+ import { closedAction } from "../../core/action.js";
2
+
3
3
  import { findDataset } from "../../selectors/datasets.js";
4
4
  import { findSemanticScale } from "../../selectors/scales.js";
5
5
  import {
@@ -18,13 +18,12 @@ import {
18
18
  resolveGradientSourceLayer
19
19
  } from "./resolve.js";
20
20
 
21
- export const createGradientPlot = action(
21
+ export const createGradientPlot = /* @__PURE__ */ closedAction(
22
22
  {
23
23
  op: "createGradientPlot",
24
24
  description: "Create a categorical density gradient plot."
25
- },
25
+ }, GRADIENT_PLOT_OPTIONS,
26
26
  function (args = {}) {
27
- validateKeys(args, GRADIENT_PLOT_OPTIONS, "createGradientPlot");
28
27
  const id = resolveGradientPlotId(this, args.id);
29
28
  const source = resolveGradientSourceLayer(this, args.target);
30
29
  const data = args.data ?? source?.data ?? this.context.currentData ??
@@ -1,12 +1,13 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { isPlainObject } from "../../core/immutable.js";
3
3
  import { validateUserId } from "../../core/identifiers.js";
4
- import { validateKeys } from "../../core/validation.js";
4
+
5
5
  import { planDerivedDataRevision } from "../../materialization/dataProvenance.js";
6
6
  import { findDataset } from "../../selectors/datasets.js";
7
7
  import { findLayer } from "../../selectors/layers.js";
8
8
  import { removeOwnedMark } from "../marks/remove.js";
9
9
  import { GRADIENT_PROFILE_FIELDS } from "../../grammar/gradientProfile.js";
10
+ import { requestedStrokeDetails } from "../../grammar/strokeStyle.js";
10
11
  import { removeGradientPlotLegend } from "./components.js";
11
12
  import {
12
13
  resolveDistributionRoles,
@@ -40,6 +41,13 @@ function removeCenter(program, id) {
40
41
  return removeOwnedMark(program, id, true);
41
42
  }
42
43
 
44
+ function editCenterStrokeDetails(program, id, center) {
45
+ const details = requestedStrokeDetails(center, "Gradient plot center");
46
+ return Object.keys(details).length === 0
47
+ ? program
48
+ : program.editRuleMark({ target: id, ...details });
49
+ }
50
+
43
51
  function roleCandidate(program, owner, current, args) {
44
52
  return {
45
53
  source: Object.hasOwn(args, "data")
@@ -102,13 +110,12 @@ function updateGradientPositions(program, owner, current, candidate, hasCenter)
102
110
  );
103
111
  }
104
112
 
105
- export const editGradientPlot = action(
113
+ export const editGradientPlot = /* @__PURE__ */ closedAction(
106
114
  {
107
115
  op: "editGradientPlot",
108
116
  description: "Edit one stable categorical gradient plot."
109
- },
117
+ }, OPTIONS,
110
118
  function (args = {}) {
111
- validateKeys(args, OPTIONS, "editGradientPlot");
112
119
  if (!OPTIONS.slice(1).some(key => Object.hasOwn(args, key))) {
113
120
  throw new Error("editGradientPlot requires at least one gradient-plot option.");
114
121
  }
@@ -219,10 +226,11 @@ export const editGradientPlot = action(
219
226
  orientation: candidate.orientation,
220
227
  size: spanSize,
221
228
  stroke: center.stroke,
222
- strokeWidth: center.strokeWidth
229
+ strokeWidth: center.strokeWidth,
230
+ ...requestedStrokeDetails(center, "Gradient plot center")
223
231
  });
224
232
  } else if (retainedCenter) {
225
- next = next
233
+ next = editCenterStrokeDetails(next, current.centerId, center)
226
234
  .encodeStroke({ target: current.centerId, value: center.stroke })
227
235
  .encodeStrokeWidth({
228
236
  target: current.centerId,
@@ -291,10 +299,11 @@ export const editGradientPlot = action(
291
299
  orientation: current.orientation,
292
300
  size: 1,
293
301
  stroke: center.stroke,
294
- strokeWidth: center.strokeWidth
302
+ strokeWidth: center.strokeWidth,
303
+ ...requestedStrokeDetails(center, "Gradient plot center")
295
304
  });
296
305
  } else if (center !== false) {
297
- next = next
306
+ next = editCenterStrokeDetails(next, current.centerId, center)
298
307
  .encodeStroke({ target: current.centerId, value: center.stroke })
299
308
  .encodeStrokeWidth({ target: current.centerId, value: center.strokeWidth });
300
309
  }
@@ -4,6 +4,7 @@ import { action } from "../../core/action.js";
4
4
  import { validateUserId } from "../../core/identifiers.js";
5
5
  import { isPlainObject } from "../../core/immutable.js";
6
6
  import { GRADIENT_PROFILE_FIELDS } from "../../grammar/gradientProfile.js";
7
+ import { requestedStrokeDetails } from "../../grammar/strokeStyle.js";
7
8
  import {
8
9
  mapContinuousScaleValues,
9
10
  mapOrdinalPositionValues
@@ -122,7 +123,7 @@ function bodyItems(program, layer, dataset, config) {
122
123
  });
123
124
  }
124
125
 
125
- export const materializeGradientPlotFill = action(
126
+ export const materializeGradientPlotFill = /* @__PURE__ */ action(
126
127
  {
127
128
  op: "materializeGradientPlotFill",
128
129
  description: "Materialize categorical density profiles as gradient strips."
@@ -169,7 +170,7 @@ export const materializeGradientPlotFill = action(
169
170
  }
170
171
  );
171
172
 
172
- export const materializeGradientPlot = action(
173
+ export const materializeGradientPlot = /* @__PURE__ */ action(
173
174
  {
174
175
  op: "materializeGradientPlot",
175
176
  description: "Materialize one complete categorical gradient plot."
@@ -248,7 +249,8 @@ export const materializeGradientPlot = action(
248
249
  orientation,
249
250
  size: Math.max(1, categoryScale.bandwidth * config.width.band - 16),
250
251
  stroke: config.center.stroke,
251
- strokeWidth: config.center.strokeWidth
252
+ strokeWidth: config.center.strokeWidth,
253
+ ...requestedStrokeDetails(config.center, "Gradient plot center")
252
254
  });
253
255
  }
254
256
  const guides = config.guides;
@@ -5,6 +5,10 @@ import {
5
5
  validateUnitInterval
6
6
  } from "../../core/validation.js";
7
7
  import { normalizePalette } from "../../grammar/palettes.js";
8
+ import {
9
+ requestedStrokeDetails,
10
+ STROKE_STYLE_PROPERTIES
11
+ } from "../../grammar/strokeStyle.js";
8
12
 
9
13
  export const GRADIENT_PLOT_OPTIONS = Object.freeze([
10
14
  "id", "target", "data", "x", "y", "coordinate", "density", "width",
@@ -90,7 +94,7 @@ export function resolveGradientCenter(
90
94
  if (value === false) return false;
91
95
  const options = plain(
92
96
  value,
93
- ["type", "stroke", "strokeWidth"],
97
+ ["type", "stroke", "strokeWidth", ...STROKE_STYLE_PROPERTIES],
94
98
  "center",
95
99
  operation
96
100
  );
@@ -108,7 +112,11 @@ export function resolveGradientCenter(
108
112
  : validateNonNegativeFinite(
109
113
  options.strokeWidth,
110
114
  `${operation} center.strokeWidth`
111
- )
115
+ ),
116
+ ...requestedStrokeDetails(
117
+ { ...(previous ?? {}), ...options },
118
+ `${operation} center`
119
+ )
112
120
  });
113
121
  }
114
122
 
@@ -1,18 +1,17 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { validateUserId } from "../../core/identifiers.js";
3
- import { validateKeys } from "../../core/validation.js";
3
+
4
4
  import { findDataset } from "../../selectors/datasets.js";
5
5
  import { findLayer } from "../../selectors/layers.js";
6
6
 
7
7
  const OPTIONS = Object.freeze(["id", "profile", "source"]);
8
8
 
9
- export const rebindGradientPlotProfile = action(
9
+ export const rebindGradientPlotProfile = /* @__PURE__ */ closedAction(
10
10
  {
11
11
  op: "rebindGradientPlotProfile",
12
12
  description: "Rebind one gradient plot to a replayed profile revision."
13
- },
13
+ }, OPTIONS,
14
14
  function (args = {}) {
15
- validateKeys(args, OPTIONS, "rebindGradientPlotProfile");
16
15
  const id = validateUserId(args.id, "Gradient-plot id");
17
16
  const profileId = validateUserId(
18
17
  args.profile,
@@ -51,6 +51,8 @@ export function hasInferableLegend(program, layers = program.semanticSpec.layers
51
51
  isOpacityLegendLayer(layer) ||
52
52
  (layer.mark?.type === "point" &&
53
53
  layer.encoding?.size?.scale !== undefined) ||
54
+ (layer.mark?.type === "point" &&
55
+ layer.encoding?.stroke?.scale !== undefined) ||
54
56
  (layer.mark?.type === "point" &&
55
57
  layer.encoding?.color?.scale !== undefined &&
56
58
  (layer.encoding?.shape?.scale !== undefined ||
@@ -58,11 +60,15 @@ export function hasInferableLegend(program, layers = program.semanticSpec.layers
58
60
  findSemanticScale(program, layer.encoding.color.scale)?.type
59
61
  ))) ||
60
62
  (layer.mark?.type === "line" &&
61
- ["color", "strokeDash"].some(
63
+ ["color", "stroke", "strokeDash"].some(
62
64
  channel => layer.encoding?.[channel]?.scale !== undefined
63
65
  )) ||
64
66
  (["bar", "area", "arc", "rect"].includes(layer.mark?.type) &&
65
- layer.encoding?.color?.scale !== undefined)
67
+ ["color", "stroke"].some(
68
+ channel => layer.encoding?.[channel]?.scale !== undefined
69
+ )) ||
70
+ (["rule", "tick"].includes(layer.mark?.type) &&
71
+ layer.encoding?.stroke?.scale !== undefined)
66
72
  )
67
73
  );
68
74
  }
@@ -38,6 +38,7 @@ export function validateAxesArgs(args) {
38
38
  if (!COORDINATE_API_TYPES.has(type)) {
39
39
  throw new Error(`Unknown createAxes coordinate type "${type}".`);
40
40
  }
41
+ if (coordinate.id !== undefined) validateUserId(coordinate.id, "Coordinate id");
41
42
 
42
43
  return coordinate;
43
44
  }
@@ -121,7 +122,7 @@ function resolveCoordinate(program, descriptor, cartesianLayers) {
121
122
  }
122
123
 
123
124
  if (existing.type !== "cartesian") {
124
- throw new Error("createAxes does not yet support Polar axes.");
125
+ throw new Error("createAxes x/y options require a Cartesian coordinate.");
125
126
  }
126
127
 
127
128
  return { id, layers };
@@ -184,10 +185,10 @@ function resolveAxisArgs(layers, channel, option) {
184
185
  return { ...args, scale };
185
186
  }
186
187
 
187
- const createAxes = action(
188
+ const createAxes = /* @__PURE__ */ action(
188
189
  {
189
190
  op: "createAxes",
190
- description: "Read a semantic coordinate and create its Cartesian axes."
191
+ description: "Read a stored coordinate and create its applicable axes."
191
192
  },
192
193
  function (args = {}) {
193
194
  const coordinateDescriptor = validateAxesArgs(args);
@@ -197,6 +198,16 @@ const createAxes = action(
197
198
  const requestedCoordinateType = coordinateDescriptor.id === undefined
198
199
  ? undefined
199
200
  : findCoordinate(this, coordinateDescriptor.id)?.type;
201
+ if (coordinateDescriptor.id !== undefined) {
202
+ if (requestedCoordinateType === undefined) {
203
+ throw new Error(`Unknown coordinate "${coordinateDescriptor.id}".`);
204
+ }
205
+ if (coordinateDescriptor.type !== undefined &&
206
+ coordinateDescriptor.type !== "auto" &&
207
+ coordinateDescriptor.type !== requestedCoordinateType) {
208
+ throw new Error(`Coordinate "${coordinateDescriptor.id}" has type "${requestedCoordinateType}", not "${coordinateDescriptor.type}".`);
209
+ }
210
+ }
200
211
  const explicitlyPolar = coordinateDescriptor.type === "polar" ||
201
212
  requestedCoordinateType === "polar" ||
202
213
  args.theta !== undefined || args.radius !== undefined;
@@ -206,6 +217,10 @@ const createAxes = action(
206
217
  (cartesianLayers.length === 0 && polarLayers.length === 0) ||
207
218
  explicitlyParallel
208
219
  )) {
220
+ if (coordinateDescriptor.type !== undefined &&
221
+ !["auto", "parallel"].includes(coordinateDescriptor.type)) {
222
+ throw new Error("createAxes coordinate type conflicts with Parallel encodings.");
223
+ }
209
224
  if (
210
225
  args.x !== undefined || args.y !== undefined ||
211
226
  args.theta !== undefined || args.radius !== undefined
@@ -231,7 +246,8 @@ const createAxes = action(
231
246
  }
232
247
  if (polarLayers.length > 0 &&
233
248
  (cartesianLayers.length === 0 || explicitlyPolar)) {
234
- if (coordinateDescriptor.type === "cartesian") {
249
+ if (coordinateDescriptor.type !== undefined &&
250
+ !["auto", "polar"].includes(coordinateDescriptor.type)) {
235
251
  throw new Error("createAxes coordinate type conflicts with Polar encodings.");
236
252
  }
237
253
  if (args.x !== undefined || args.y !== undefined) {
@@ -263,6 +279,9 @@ const createAxes = action(
263
279
  }
264
280
  return polarProgram;
265
281
  }
282
+ if (args.theta !== undefined || args.radius !== undefined) {
283
+ throw new Error("createAxes theta/radius options require Polar encodings.");
284
+ }
266
285
  const coordinate = resolveCoordinate(
267
286
  this,
268
287
  coordinateDescriptor,
@@ -122,8 +122,8 @@ function makeCreateAxis(channel) {
122
122
  );
123
123
  }
124
124
 
125
- const createXAxis = makeCreateAxis("x");
126
- const createYAxis = makeCreateAxis("y");
125
+ const createXAxis = /* @__PURE__ */ makeCreateAxis("x");
126
+ const createYAxis = /* @__PURE__ */ makeCreateAxis("y");
127
127
 
128
128
  export function registerAxisActions(Class) {
129
129
  Class.prototype.createXAxis = createXAxis;
@@ -164,8 +164,8 @@ function makeEditAxis(channel) {
164
164
  );
165
165
  }
166
166
 
167
- const editXAxis = makeEditAxis("x");
168
- const editYAxis = makeEditAxis("y");
167
+ const editXAxis = /* @__PURE__ */ makeEditAxis("x");
168
+ const editYAxis = /* @__PURE__ */ makeEditAxis("y");
169
169
 
170
170
  export function registerCompleteAxisEditActions(ProgramClass) {
171
171
  ProgramClass.prototype.editXAxis = editXAxis;