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
@@ -1,3 +1,4 @@
1
+ import { editGraphicProperties } from "../../primitives/graphicProperties.js";
1
2
  import { action } from "../../../core/action.js";
2
3
  import { validateUserId } from "../../../core/identifiers.js";
3
4
  import { validateMarkOptions } from "../shared.js";
@@ -12,47 +13,36 @@ import {
12
13
  import { rematerializeHighlightBaseline } from "../lifecycle.js";
13
14
  import { offsetCategoryRectangles } from
14
15
  "../../../materialization/categorySlotOffset.js";
16
+ import { materializeRectItem } from "../../../grammar/roundedRect.js";
17
+ import { STROKE_STYLE_PROPERTIES } from
18
+ "../../../grammar/strokeStyle.js";
19
+ import { replaceGraphicItems } from "../../primitives/editGraphics.js";
15
20
 
16
21
  const REMATERIALIZE_OPTIONS = Object.freeze(["id", "scales"]);
17
22
 
18
23
  function editRectangles(program, id, rectangles) {
19
- let next = program
20
- .editGraphics({ target: id, property: "length", value: rectangles.length })
21
- .editGraphics({
22
- target: id,
23
- property: "x",
24
- value: rectangles.map(rect => rect.x)
25
- })
26
- .editGraphics({
27
- target: id,
28
- property: "y",
29
- value: rectangles.map(rect => rect.y)
30
- })
31
- .editGraphics({
32
- target: id,
33
- property: "width",
34
- value: rectangles.map(rect => rect.width)
35
- })
36
- .editGraphics({
37
- target: id,
38
- property: "height",
39
- value: rectangles.map(rect => rect.height)
40
- })
41
- .editGraphics({
42
- target: id,
43
- property: "fill",
44
- value: rectangles.map(rect => rect.fill)
45
- })
46
- .editGraphics({
47
- target: id,
48
- property: "stroke",
49
- value: rectangles.map(rect => rect.stroke)
50
- })
51
- .editGraphics({
52
- target: id,
53
- property: "strokeWidth",
54
- value: rectangles.map(rect => rect.strokeWidth)
55
- });
24
+ const appearance = program.markConfigs[id]?.barAppearance ?? {};
25
+ const hasShapeStyle = ["cornerRadius", ...STROKE_STYLE_PROPERTIES]
26
+ .some(property => Object.hasOwn(appearance, property));
27
+ if (hasShapeStyle) {
28
+ const radius = appearance.cornerRadius ?? 0;
29
+ return replaceGraphicItems(
30
+ program,
31
+ id,
32
+ "rect",
33
+ rectangles.map(rectangle => materializeRectItem(rectangle, radius))
34
+ );
35
+ }
36
+ let next = editGraphicProperties(program, id, {
37
+ length: rectangles.length,
38
+ x: rectangles.map(rect => rect.x),
39
+ y: rectangles.map(rect => rect.y),
40
+ width: rectangles.map(rect => rect.width),
41
+ height: rectangles.map(rect => rect.height),
42
+ fill: rectangles.map(rect => rect.fill),
43
+ stroke: rectangles.map(rect => rect.stroke),
44
+ strokeWidth: rectangles.map(rect => rect.strokeWidth)
45
+ });
56
46
  if (rectangles.some(rect => rect.opacity !== undefined)) {
57
47
  next = next.editGraphics({
58
48
  target: id,
@@ -63,7 +53,7 @@ function editRectangles(program, id, rectangles) {
63
53
  return next;
64
54
  }
65
55
 
66
- export const rematerializeBarMark = action(
56
+ export const rematerializeBarMark = /* @__PURE__ */ action(
67
57
  {
68
58
  op: "rematerializeBarMark",
69
59
  description: "Recompute concrete bar graphics from complete semantics."
@@ -81,8 +71,8 @@ export const rematerializeBarMark = action(
81
71
  const highlighted = rematerializeHighlightBaseline(this, {
82
72
  target: id,
83
73
  operation: "rematerializeBarMark",
84
- resetProperty: "length",
85
- resetValue: 0
74
+ resetProperty: "items",
75
+ resetValue: []
86
76
  });
87
77
  if (highlighted !== undefined) return highlighted;
88
78
  const required = requireCompleteBar(this, id);
@@ -97,6 +87,10 @@ export const rematerializeBarMark = action(
97
87
  if (colorScaleId !== undefined && args.scales !== false) {
98
88
  resolved = resolved.rematerializeScale({ id: colorScaleId });
99
89
  }
90
+ const strokeScaleId = required.layer.encoding?.stroke?.scale;
91
+ if (strokeScaleId !== undefined && args.scales !== false) {
92
+ resolved = resolved.rematerializeScale({ id: strokeScaleId });
93
+ }
100
94
 
101
95
  if (required.materialization === "aggregate") {
102
96
  const offsetChannel = resolveBarOffsetChannel(required.layer);
@@ -1,5 +1,10 @@
1
1
  import { removeMark } from "./remove.js";
2
- import { createReferenceLine, createReferenceBand } from "./references.js";
2
+ import {
3
+ createReferenceLine,
4
+ createReferenceBand,
5
+ materializeStatisticalReferenceData,
6
+ rematerializeStatisticalReference
7
+ } from "./references.js";
3
8
  import { registerRuleMarkActions } from "./rule/index.js";
4
9
  import { registerAreaMarkActions } from "./area/index.js";
5
10
  import { registerTickMarkActions } from "./tick/index.js";
@@ -29,4 +34,8 @@ export function registerMarkActions(ProgramClass) {
29
34
  ProgramClass.prototype.removeMark = removeMark;
30
35
  ProgramClass.prototype.createReferenceLine = createReferenceLine;
31
36
  ProgramClass.prototype.createReferenceBand = createReferenceBand;
37
+ ProgramClass.prototype.materializeStatisticalReferenceData =
38
+ materializeStatisticalReferenceData;
39
+ ProgramClass.prototype.rematerializeStatisticalReference =
40
+ rematerializeStatisticalReference;
32
41
  }
@@ -19,7 +19,11 @@ import { DEFAULT_COLORS } from "../../../theme/defaults.js";
19
19
  import { findDataset } from "../../../selectors/datasets.js";
20
20
  import { findLayer, resolveEligibleLayer } from "../../../selectors/layers.js";
21
21
  import { validateCurveInterpolation } from "../../../grammar/curveCommands.js";
22
- import { resolveGraphicBounds } from "../../../layout/canvas.js";
22
+ import {
23
+ resolveCoordinateBounds,
24
+ resolveCoordinatePolarFrame
25
+ } from "../../../materialization/coordinateBounds.js";
26
+ import { rematerializeExistingLegend } from "../../encodings/shared.js";
23
27
  import { canMaterializeLine } from "../../../materialization/marks/index.js";
24
28
  import { resolveMarkGraphicPlacement } from
25
29
  "../../../materialization/graphicHierarchy.js";
@@ -31,14 +35,20 @@ import {
31
35
  } from "./materialize.js";
32
36
  import { resolveLineBins } from "../../../grammar/lineSeries.js";
33
37
  import { requireSemanticScale } from "../../../selectors/scales.js";
38
+ import {
39
+ requestedStrokeDetails,
40
+ STROKE_STYLE_PROPERTIES
41
+ } from "../../../grammar/strokeStyle.js";
34
42
 
35
43
  const DEFAULT_LINE_STROKE = DEFAULT_COLORS.mark;
36
44
  const DEFAULT_LINE_WIDTH = 2;
37
45
  const CREATE_OPTIONS = Object.freeze([
38
- "id", "data", "stroke", "strokeWidth", "opacity", "curve", "closed"
46
+ "id", "data", "stroke", "strokeWidth", "opacity", "curve", "closed",
47
+ ...STROKE_STYLE_PROPERTIES
39
48
  ]);
40
49
  const EDIT_OPTIONS = Object.freeze([
41
- "target", "stroke", "strokeWidth", "opacity", "curve", "closed"
50
+ "target", "stroke", "strokeWidth", "opacity", "curve", "closed",
51
+ ...STROKE_STYLE_PROPERTIES
42
52
  ]);
43
53
  const REMATERIALIZE_OPTIONS = Object.freeze(["id", "scales"]);
44
54
 
@@ -71,24 +81,26 @@ function validatePolarLineConfig(layer, config) {
71
81
  }
72
82
  }
73
83
 
74
- function applyLineMaterialization(program, id, materialization) {
84
+ function applyLineMaterialization(program, id, materialization, config) {
75
85
  return editMarkGraphic(program, id, {
76
86
  length: materialization.commands.length,
77
87
  commands: materialization.commands,
78
88
  stroke: materialization.strokes,
79
89
  strokeWidth: materialization.strokeWidths,
80
90
  strokeDash: materialization.strokeDashes,
81
- ...(materialization.opacities === undefined ? {} : { opacity: materialization.opacities })
91
+ ...(materialization.opacities === undefined ? {} : { opacity: materialization.opacities }),
92
+ ...requestedStrokeDetails(config, "Line mark")
82
93
  });
83
94
  }
84
95
 
85
- const createLineMark = action(
96
+ const createLineMark = /* @__PURE__ */ action(
86
97
  {
87
98
  op: "createLineMark",
88
99
  description: "Create a semantic line mark and empty path collection."
89
100
  },
90
101
  function (args = {}) {
91
102
  validateMarkOptions(args, CREATE_OPTIONS, "createLineMark");
103
+ const strokeDetails = requestedStrokeDetails(args, "createLineMark");
92
104
  const id = resolveMarkId(this, args.id, {
93
105
  defaultId: "line",
94
106
  label: "Line mark id",
@@ -139,7 +151,8 @@ const createLineMark = action(
139
151
  {
140
152
  ...(Object.hasOwn(args, "strokeWidth") ? { strokeWidth } : {}),
141
153
  ...(Object.hasOwn(args, "curve") ? { curve } : {}),
142
- ...(Object.hasOwn(args, "closed") ? { closed } : {})
154
+ ...(Object.hasOwn(args, "closed") ? { closed } : {}),
155
+ ...strokeDetails
143
156
  }
144
157
  );
145
158
  created = materializeInheritedMark(created, id);
@@ -173,7 +186,7 @@ function requireLine(program, id) {
173
186
  return { dataset, layer };
174
187
  }
175
188
 
176
- const rematerializeLineMark = action(
189
+ const rematerializeLineMark = /* @__PURE__ */ action(
177
190
  {
178
191
  op: "rematerializeLineMark",
179
192
  description: "Recompute aggregate series and concrete line paths."
@@ -214,7 +227,7 @@ const rematerializeLineMark = action(
214
227
  }
215
228
  let resolved = this;
216
229
  if (args.scales !== false) {
217
- const appearance = ["color", "strokeDash", "strokeWidth", "opacity"]
230
+ const appearance = ["color", "stroke", "strokeDash", "strokeWidth", "opacity"]
218
231
  .map(channel => layer.encoding?.[channel]?.scale).filter(scale => scale !== undefined);
219
232
  for (const scale of [...positions, ...appearance]) {
220
233
  resolved = resolved.rematerializeScale({ id: scale });
@@ -223,12 +236,12 @@ const rematerializeLineMark = action(
223
236
  const shared = {
224
237
  rows: dataset.values, layer, config, existingChildren,
225
238
  resolvedScales: resolved.resolvedScales,
226
- bounds: resolveGraphicBounds(resolved),
239
+ bounds: resolveCoordinateBounds(resolved, layer.coordinate),
227
240
  defaults: { stroke: DEFAULT_LINE_STROKE, strokeWidth: DEFAULT_LINE_WIDTH }
228
241
  };
229
242
  if (parallel !== undefined) {
230
243
  return applyLineMaterialization(resolved, id,
231
- resolveParallelLineMaterialization({ ...shared, parallel }));
244
+ resolveParallelLineMaterialization({ ...shared, parallel }), config);
232
245
  }
233
246
 
234
247
  const materialization = resolvePositionedLineMaterialization({
@@ -240,24 +253,29 @@ const rematerializeLineMark = action(
240
253
  layer,
241
254
  requireSemanticScale(resolved, xScaleId)
242
255
  ).boundaries,
243
- polar
256
+ polar,
257
+ ...(polar
258
+ ? { polarFrame: resolveCoordinatePolarFrame(resolved, layer.coordinate) }
259
+ : {})
244
260
  });
245
261
 
246
262
  return applyLineMaterialization(
247
263
  resolved,
248
264
  id,
249
- materialization
265
+ materialization,
266
+ config
250
267
  );
251
268
  }
252
269
  );
253
270
 
254
- const editLineMark = action(
271
+ const editLineMark = /* @__PURE__ */ action(
255
272
  {
256
273
  op: "editLineMark",
257
274
  description: "Edit line-mark curve and stroke width."
258
275
  },
259
276
  function (args = {}) {
260
277
  validateMarkOptions(args, EDIT_OPTIONS, "editLineMark");
278
+ const strokeDetails = requestedStrokeDetails(args, "editLineMark");
261
279
  if (!EDIT_OPTIONS.slice(1).some(key => Object.hasOwn(args, key))) {
262
280
  throw new Error("editLineMark requires stroke, strokeWidth, opacity, curve, or closed.");
263
281
  }
@@ -269,9 +287,12 @@ const editLineMark = action(
269
287
  predicate: candidate => candidate.mark?.type === "line",
270
288
  label: "line mark"
271
289
  });
272
- if (Object.hasOwn(args, "stroke") && layer.encoding?.color !== undefined) {
290
+ if (Object.hasOwn(args, "stroke") && (
291
+ layer.encoding?.color !== undefined ||
292
+ layer.encoding?.stroke !== undefined
293
+ )) {
273
294
  throw new Error(
274
- "editLineMark stroke cannot be combined with a color encoding."
295
+ "editLineMark stroke cannot be combined with a color encoding or a stroke encoding; use encodeStroke with value to replace it."
275
296
  );
276
297
  }
277
298
  for (const channel of ["strokeWidth", "opacity"]) {
@@ -284,6 +305,7 @@ const editLineMark = action(
284
305
  throw new Error("Line closed requires theta/radius Polar position encodings.");
285
306
  }
286
307
  const config = { ...this.markConfigs[layer.id] };
308
+ Object.assign(config, strokeDetails);
287
309
  for (const [key, validate] of Object.entries({
288
310
  stroke: validateNonEmptyString,
289
311
  strokeWidth: validateNonNegativeFinite,
@@ -295,9 +317,10 @@ const editLineMark = action(
295
317
  }
296
318
  validatePolarLineConfig(layer, config);
297
319
  const next = this._withMarkConfig(layer.id, config);
298
- return canMaterializeLine(next, layer)
320
+ const materialized = canMaterializeLine(next, layer)
299
321
  ? next.rematerializeLineMark({ id: layer.id })
300
322
  : next;
323
+ return rematerializeExistingLegend(materialized);
301
324
  }
302
325
  );
303
326
 
@@ -27,7 +27,11 @@ function appearanceMapper(layer, scales, fieldValues) {
27
27
  return fallback.map(() => normalizeStrokeDashPattern(encoding.datum));
28
28
  }
29
29
  if (encoding?.scale === undefined) return fallback;
30
- return mapScaleConsumerValues(fieldValues(encoding.field, channel), scales[encoding.scale], channel);
30
+ return mapScaleConsumerValues(
31
+ fieldValues(encoding.field, channel, encoding),
32
+ scales[encoding.scale],
33
+ channel
34
+ );
31
35
  };
32
36
  }
33
37
 
@@ -53,11 +57,15 @@ export function resolveParallelLineMaterialization({
53
57
  field => sourceRows.map(row => row[field]));
54
58
  return {
55
59
  commands: items.map(item => item.commands),
56
- strokes: mapAppearance(
57
- "color",
58
- items.map((_, index) => config.stroke ??
59
- existingValue(existingChildren, index, "stroke", defaults.stroke))
60
- ),
60
+ strokes: layer.encoding?.stroke?.scale !== undefined
61
+ ? mapAppearance("stroke", items.map(() => defaults.stroke))
62
+ : config.stroke !== undefined
63
+ ? items.map(() => config.stroke)
64
+ : mapAppearance(
65
+ "color",
66
+ items.map((_, index) =>
67
+ existingValue(existingChildren, index, "stroke", defaults.stroke))
68
+ ),
61
69
  strokeWidths: mapAppearance(
62
70
  "strokeWidth",
63
71
  items.map((_, index) => config.strokeWidth ??
@@ -80,6 +88,7 @@ export function resolvePositionedLineMaterialization({
80
88
  config,
81
89
  existingChildren,
82
90
  polar,
91
+ polarFrame,
83
92
  defaults
84
93
  }) {
85
94
  const xScaleId = layer.encoding?.x?.scale;
@@ -98,7 +107,7 @@ export function resolvePositionedLineMaterialization({
98
107
  thetaFieldType: derived.thetaFieldType,
99
108
  thetaScale: resolvedScales[thetaScaleId],
100
109
  radiusScale: resolvedScales[radiusScaleId],
101
- frame: resolvePolarFrame(bounds),
110
+ frame: polarFrame ?? resolvePolarFrame(bounds),
102
111
  closed: config.closed ?? false
103
112
  }))
104
113
  : derived.series.map(series => {
@@ -116,11 +125,21 @@ export function resolvePositionedLineMaterialization({
116
125
  );
117
126
  });
118
127
  const appearance = appearanceMapper(layer, resolvedScales,
119
- (field, channel) => derivePathSeriesFieldValues(rows, derived.series, field, channel));
128
+ (field, channel, encoding) => derivePathSeriesFieldValues(
129
+ rows,
130
+ derived.series,
131
+ field,
132
+ channel,
133
+ encoding
134
+ ));
120
135
  return {
121
136
  commands,
122
- strokes: appearance("color", commands.map((_, index) => config.stroke ??
123
- existingValue(existingChildren, index, "stroke", defaults.stroke))),
137
+ strokes: layer.encoding?.stroke?.scale !== undefined
138
+ ? appearance("stroke", commands.map(() => defaults.stroke))
139
+ : config.stroke !== undefined
140
+ ? commands.map(() => config.stroke)
141
+ : appearance("color", commands.map((_, index) =>
142
+ existingValue(existingChildren, index, "stroke", defaults.stroke))),
124
143
  strokeWidths: appearance("strokeWidth", commands.map((_, index) => config.strokeWidth ??
125
144
  existingValue(existingChildren, index, "strokeWidth", defaults.strokeWidth))),
126
145
  strokeDashes: appearance("strokeDash", commands.map((_, index) =>
@@ -1,6 +1,10 @@
1
1
  import { action } from "../../../core/action.js";
2
2
  import { validatePointShape } from "../../../grammar/pointShapes.js";
3
3
  import { getPointGraphicType } from "../../../grammar/schemas/mark.js";
4
+ import {
5
+ requestedStrokeDetails,
6
+ STROKE_STYLE_PROPERTIES
7
+ } from "../../../grammar/strokeStyle.js";
4
8
  import { resolveMarkGraphicPlacement } from
5
9
  "../../../materialization/graphicHierarchy.js";
6
10
  import {
@@ -14,16 +18,18 @@ import {
14
18
  } from "../shared.js";
15
19
 
16
20
  const OPTIONS = Object.freeze([
17
- "id", "data", "shape", "fill", "opacity", "stroke", "strokeWidth"
21
+ "id", "data", "shape", "fill", "opacity", "stroke", "strokeWidth",
22
+ ...STROKE_STYLE_PROPERTIES
18
23
  ]);
19
24
 
20
- export const createPointMark = action(
25
+ export const createPointMark = /* @__PURE__ */ action(
21
26
  {
22
27
  op: "createPointMark",
23
28
  description: "Create a semantic point mark and concrete point graphics."
24
29
  },
25
30
  function (args = {}) {
26
31
  validateMarkOptions(args, OPTIONS, "createPointMark");
32
+ requestedStrokeDetails(args, "createPointMark");
27
33
  const id = resolveMarkId(this, args.id, {
28
34
  defaultId: "point",
29
35
  label: "Point mark id",
@@ -65,7 +71,7 @@ export const createPointMark = action(
65
71
  ._withMarkConfig(id, { shape });
66
72
  const created = materializeInheritedMark(next, id);
67
73
  const appearance = Object.fromEntries(
68
- ["fill", "opacity", "stroke", "strokeWidth"]
74
+ ["fill", "opacity", "stroke", "strokeWidth", ...STROKE_STYLE_PROPERTIES]
69
75
  .filter(property => Object.hasOwn(args, property))
70
76
  .map(property => [property, args[property]])
71
77
  );
@@ -6,22 +6,31 @@ import {
6
6
  validateUnitInterval
7
7
  } from "../../../core/validation.js";
8
8
  import { validatePointShape } from "../../../grammar/pointShapes.js";
9
+ import {
10
+ requestedStrokeDetails,
11
+ STROKE_STYLE_PROPERTIES
12
+ } from "../../../grammar/strokeStyle.js";
9
13
  import { resolveEligibleLayer } from "../../../selectors/layers.js";
10
14
  import { rematerializeExistingLegend } from "../../encodings/shared.js";
11
15
  import { validateMarkOptions } from "../shared.js";
12
16
 
13
17
  const OPTIONS = Object.freeze([
14
- "target", "shape", "fill", "opacity", "stroke", "strokeWidth"
18
+ "target", "shape", "fill", "opacity", "stroke", "strokeWidth",
19
+ ...STROKE_STYLE_PROPERTIES
15
20
  ]);
16
21
 
17
- export const editPointMark = action(
22
+ export const editPointMark = /* @__PURE__ */ action(
18
23
  {
19
24
  op: "editPointMark",
20
25
  description: "Edit constant point-mark appearance."
21
26
  },
22
27
  function (args = {}) {
23
28
  validateMarkOptions(args, OPTIONS, "editPointMark");
24
- const editable = ["shape", "fill", "opacity", "stroke", "strokeWidth"];
29
+ const strokeDetails = requestedStrokeDetails(args, "editPointMark");
30
+ const editable = [
31
+ "shape", "fill", "opacity", "stroke", "strokeWidth",
32
+ ...STROKE_STYLE_PROPERTIES
33
+ ];
25
34
  if (!editable.some(property => Object.hasOwn(args, property))) {
26
35
  throw new Error(
27
36
  "editPointMark requires shape, fill, opacity, stroke, or strokeWidth."
@@ -44,10 +53,16 @@ export const editPointMark = action(
44
53
  "editPointMark fill cannot be combined with a color encoding."
45
54
  );
46
55
  }
56
+ if (Object.hasOwn(args, "stroke") && layer.encoding?.stroke !== undefined) {
57
+ throw new Error(
58
+ "editPointMark stroke conflicts with a field encoding; use encodeStroke with value to replace it."
59
+ );
60
+ }
47
61
  if (Object.hasOwn(args, "opacity") && layer.encoding?.opacity?.field !== undefined) {
48
62
  throw new Error("editPointMark opacity conflicts with a field encoding; use encodeOpacity with value to replace it.");
49
63
  }
50
64
  const config = { ...this.markConfigs[id] };
65
+ Object.assign(config, strokeDetails);
51
66
  if (Object.hasOwn(args, "shape")) {
52
67
  config.shape = validatePointShape(args.shape);
53
68
  }
@@ -85,9 +100,6 @@ export const editPointMark = action(
85
100
  const next = this
86
101
  ._withMarkConfig(id, config)
87
102
  .rematerializePointMark({ id });
88
- const legend = next.guideConfigs.legend?.series;
89
- return legend?.target === id && legend.channels.includes("shape")
90
- ? rematerializeExistingLegend(next)
91
- : next;
103
+ return rematerializeExistingLegend(next);
92
104
  }
93
105
  );
@@ -1,6 +1,6 @@
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 { normalizePointJitterPolicy } from "../../../grammar/jitter.js";
5
5
  import { findCoordinate } from "../../../selectors/coordinates.js";
6
6
  import { resolveEligibleLayer } from "../../../selectors/layers.js";
@@ -28,13 +28,12 @@ function resolveJitterTarget(program, target, channel) {
28
28
  });
29
29
  }
30
30
 
31
- export const jitterPoints = action(
31
+ export const jitterPoints = /* @__PURE__ */ closedAction(
32
32
  {
33
33
  op: "jitterPoints",
34
34
  description: "Apply deterministic bounded graphical jitter to a point mark."
35
- },
35
+ }, JITTER_OPTIONS,
36
36
  function (args = {}) {
37
- validateKeys(args, JITTER_OPTIONS, "jitterPoints");
38
37
  const policy = normalizePointJitterPolicy(args);
39
38
  const layer = resolveJitterTarget(this, args.target, policy.channel);
40
39
  if (this.materializationConfigs.pointPacking?.[layer.id] !== undefined) {
@@ -46,13 +45,12 @@ export const jitterPoints = action(
46
45
  }
47
46
  );
48
47
 
49
- export const removeJitter = action(
48
+ export const removeJitter = /* @__PURE__ */ closedAction(
50
49
  {
51
50
  op: "removeJitter",
52
51
  description: "Remove point jitter and restore semantic scale positions."
53
- },
52
+ }, REMOVE_OPTIONS,
54
53
  function (args = {}) {
55
- validateKeys(args, REMOVE_OPTIONS, "removeJitter");
56
54
  const requested = args.target === undefined
57
55
  ? undefined
58
56
  : validateUserId(args.target, "Point jitter target");