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 { getPointGraphicType } from "../../../grammar/schemas/mark.js";
@@ -15,9 +16,12 @@ import {
15
16
  normalizePointPackingPolicy,
16
17
  resolvePointPacking
17
18
  } from "../../../grammar/pointPacking.js";
18
- import { polarToCartesian, resolvePolarFrame } from "../../../grammar/polar.js";
19
+ import { polarToCartesian } from "../../../grammar/polar.js";
19
20
  import { resolveDirectionValues } from "../../../grammar/direction.js";
20
- import { resolveGraphicBounds } from "../../../layout/canvas.js";
21
+ import {
22
+ resolveCoordinateBounds,
23
+ resolveCoordinatePolarFrame
24
+ } from "../../../materialization/coordinateBounds.js";
21
25
  import { validateMarkOptions } from "../shared.js";
22
26
  import {
23
27
  DEFAULT_COLORS,
@@ -34,6 +38,8 @@ import {
34
38
  "../../../materialization/rowEncoding.js";
35
39
  import { offsetCategoryPositions } from
36
40
  "../../../materialization/categorySlotOffset.js";
41
+ import { requestedStrokeDetails } from
42
+ "../../../grammar/strokeStyle.js";
37
43
 
38
44
  const REMATERIALIZE_OPTIONS = Object.freeze(["id"]);
39
45
  const DEFAULT_POINT_FILL = DEFAULT_COLORS.mark;
@@ -52,7 +58,7 @@ function resolvePointPositions(program, layer, dataset) {
52
58
  if (theta === undefined || radius === undefined) {
53
59
  return { x: undefined, y: undefined };
54
60
  }
55
- const frame = resolvePolarFrame(resolveGraphicBounds(program));
61
+ const frame = resolveCoordinatePolarFrame(program, layer.coordinate);
56
62
  const positions = theta.map((angle, index) => {
57
63
  const distance = radius[index];
58
64
  return Number.isFinite(angle) && Number.isFinite(distance)
@@ -76,7 +82,11 @@ function incompleteShapeGraphic(shape, properties, angle) {
76
82
  ? "path"
77
83
  : getPointGraphicType(shape);
78
84
  const incomplete = type === "path"
79
- ? { fill: properties.fill, opacity: properties.opacity }
85
+ ? {
86
+ fill: properties.fill,
87
+ opacity: properties.opacity,
88
+ ...requestedStrokeDetails(properties, "Point mark")
89
+ }
80
90
  : properties;
81
91
  return { type, properties: compactProperties(incomplete) };
82
92
  }
@@ -180,7 +190,7 @@ function applyPointJitter(program, {
180
190
  `Point jitter on "${id}" requires a resolved ${policy.channel} scale.`
181
191
  );
182
192
  }
183
- const bounds = resolveGraphicBounds(program);
193
+ const bounds = resolveCoordinateBounds(program, layer.coordinate);
184
194
  const entries = resolveJitterEntries({
185
195
  policy,
186
196
  dataset,
@@ -270,7 +280,7 @@ function applyPointPacking(program, {
270
280
  fixedHalfExtent: extent[policy.channel === "x" ? "y" : "x"]
271
281
  }];
272
282
  });
273
- const bounds = resolveGraphicBounds(program);
283
+ const bounds = resolveCoordinateBounds(program, layer.coordinate);
274
284
  const resolution = resolvePointPacking({
275
285
  target: id,
276
286
  policy,
@@ -291,7 +301,7 @@ function applyPointPacking(program, {
291
301
  };
292
302
  }
293
303
 
294
- export const rematerializePointMark = action(
304
+ export const rematerializePointMark = /* @__PURE__ */ action(
295
305
  {
296
306
  op: "rematerializePointMark",
297
307
  description: "Recompute concrete point geometry and appearance."
@@ -338,6 +348,7 @@ export const rematerializePointMark = action(
338
348
 
339
349
  const positions = resolvePointPositions(resolved, layer, dataset);
340
350
  const mappedFill = resolveRowEncodingValues(resolved, layer, dataset, "color");
351
+ const mappedStroke = resolveRowEncodingValues(resolved, layer, dataset, "stroke");
341
352
  const area = resolveRowEncodingValues(resolved, layer, dataset, "size");
342
353
  const encodedShape = resolveRowEncodingValues(resolved, layer, dataset, "shape");
343
354
  const encodedOpacity = resolveRowEncodingValues(
@@ -348,6 +359,7 @@ export const rematerializePointMark = action(
348
359
  );
349
360
  const angles = resolveDirectionValues(dataset.values, layer.encoding?.angle);
350
361
  const config = resolved.markConfigs[id] ?? {};
362
+ const strokeDetails = requestedStrokeDetails(config, "Point mark");
351
363
  const fill = mappedFill ?? config.fill ?? DEFAULT_POINT_FILL;
352
364
  const shapes = encodedShape ?? dataset.values.map(() => config.shape ?? "circle");
353
365
  const existingChildren = graphic.items ?? [];
@@ -417,7 +429,8 @@ export const rematerializePointMark = action(
417
429
  x: centerX,
418
430
  y: centerY,
419
431
  fill: color,
420
- opacity
432
+ opacity,
433
+ ...strokeDetails
421
434
  }, angle);
422
435
  }
423
436
  return createPointShapeGraphic({
@@ -426,12 +439,15 @@ export const rematerializePointMark = action(
426
439
  y: centerY,
427
440
  area: resolvedArea,
428
441
  fill: color,
429
- ...(typeof config.stroke === "string" ? { stroke: config.stroke } : {}),
430
- ...(config.strokeWidth === undefined
431
- ? {}
432
- : { strokeWidth: config.strokeWidth }),
442
+ ...(typeof (mappedStroke?.[index] ?? config.stroke) === "string"
443
+ ? { stroke: mappedStroke?.[index] ?? config.stroke }
444
+ : {}),
445
+ ...((mappedStroke !== undefined || config.strokeWidth !== undefined)
446
+ ? { strokeWidth: config.strokeWidth ?? 1 }
447
+ : {}),
433
448
  opacity,
434
- angle
449
+ angle,
450
+ ...strokeDetails
435
451
  });
436
452
  });
437
453
  return jittered.program.editGraphics({
@@ -500,21 +516,28 @@ export const rematerializePointMark = action(
500
516
  value: centersY.map((value, index) => value - (Array.isArray(sides) ? sides[index] : sides) / 2)
501
517
  });
502
518
  }
503
- next = next
504
- .editGraphics({ target: id, property: "width", value: sides })
505
- .editGraphics({ target: id, property: "height", value: sides })
506
- .editGraphics({ target: id, property: "stroke", value: fill ?? DEFAULT_POINT_FILL })
507
- .editGraphics({ target: id, property: "strokeWidth", value: 0 });
519
+ next = editGraphicProperties(next, id, {
520
+ width: sides,
521
+ height: sides,
522
+ stroke: mappedStroke ?? fill ?? DEFAULT_POINT_FILL,
523
+ strokeWidth: mappedStroke === undefined ? 0 : config.strokeWidth ?? 1
524
+ });
508
525
  }
509
526
  if (config.opacity !== undefined) {
510
527
  next = next.editGraphics({ target: id, property: "opacity", value: config.opacity });
511
528
  } else if (encodedOpacity !== undefined) {
512
529
  next = next.editGraphics({ target: id, property: "opacity", value: encodedOpacity });
513
530
  }
514
- if (config.stroke === false) {
515
- next = next
516
- .editGraphics({ target: id, property: "stroke", value: "transparent" })
517
- .editGraphics({ target: id, property: "strokeWidth", value: 0 });
531
+ if (mappedStroke !== undefined) {
532
+ next = editGraphicProperties(next, id, {
533
+ stroke: mappedStroke,
534
+ strokeWidth: config.strokeWidth ?? 1
535
+ });
536
+ } else if (config.stroke === false) {
537
+ next = editGraphicProperties(next, id, {
538
+ stroke: "transparent",
539
+ strokeWidth: 0
540
+ });
518
541
  } else if (config.stroke !== undefined) {
519
542
  next = next.editGraphics({ target: id, property: "stroke", value: config.stroke });
520
543
  next = next.editGraphics({
@@ -523,6 +546,9 @@ export const rematerializePointMark = action(
523
546
  value: config.strokeWidth
524
547
  });
525
548
  }
549
+ for (const [property, value] of Object.entries(strokeDetails)) {
550
+ next = next.editGraphics({ target: id, property, value });
551
+ }
526
552
  return next;
527
553
  }
528
554
  );
@@ -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 { normalizePointPackingPolicy } from "../../../grammar/pointPacking.js";
5
5
  import { findCoordinate } from "../../../selectors/coordinates.js";
6
6
  import { resolveEligibleLayer } from "../../../selectors/layers.js";
@@ -28,10 +28,9 @@ function target(program, requested, channel) {
28
28
  });
29
29
  }
30
30
 
31
- export const packPoints = action(
32
- { op: "packPoints", description: "Pack point glyphs deterministically within categorical slots." },
31
+ export const packPoints = /* @__PURE__ */ closedAction(
32
+ { op: "packPoints", description: "Pack point glyphs deterministically within categorical slots." }, OPTIONS,
33
33
  function (args = {}) {
34
- validateKeys(args, OPTIONS, "packPoints");
35
34
  const policy = normalizePointPackingPolicy(args);
36
35
  const layer = target(this, args.target, policy.channel);
37
36
  if (this.materializationConfigs.jitters?.[layer.id] !== undefined) {
@@ -43,10 +42,9 @@ export const packPoints = action(
43
42
  }
44
43
  );
45
44
 
46
- export const removePointPacking = action(
47
- { op: "removePointPacking", description: "Remove point packing and restore semantic positions." },
45
+ export const removePointPacking = /* @__PURE__ */ closedAction(
46
+ { op: "removePointPacking", description: "Remove point packing and restore semantic positions." }, REMOVE_OPTIONS,
48
47
  function (args = {}) {
49
- validateKeys(args, REMOVE_OPTIONS, "removePointPacking");
50
48
  const requested = args.target === undefined
51
49
  ? undefined
52
50
  : validateUserId(args.target, "Point packing target");
@@ -19,12 +19,20 @@ import {
19
19
  resolveMarkId,
20
20
  validateMarkOptions
21
21
  } from "../shared.js";
22
+ import { replaceGraphicItems } from "../../primitives/editGraphics.js";
22
23
  import { resolveMarkGraphicPlacement } from
23
24
  "../../../materialization/graphicHierarchy.js";
25
+ import { rematerializeExistingLegend } from "../../encodings/shared.js";
24
26
  import { rematerializeHighlightBaseline } from "../lifecycle.js";
27
+ import {
28
+ requestedRectStyleDetails
29
+ } from "../../../grammar/roundedRect.js";
30
+ import { STROKE_STYLE_PROPERTIES } from
31
+ "../../../grammar/strokeStyle.js";
25
32
 
26
33
  const STYLE_OPTIONS = Object.freeze([
27
- "fill", "opacity", "stroke", "strokeWidth"
34
+ "fill", "opacity", "stroke", "strokeWidth", "cornerRadius",
35
+ ...STROKE_STYLE_PROPERTIES
28
36
  ]);
29
37
  const CREATE_OPTIONS = Object.freeze(["id", "data", ...STYLE_OPTIONS]);
30
38
  const EDIT_OPTIONS = Object.freeze(["target", ...STYLE_OPTIONS]);
@@ -41,10 +49,11 @@ function requireRectLayer(program, requested, operation) {
41
49
  });
42
50
  }
43
51
 
44
- const createRectMark = action(
52
+ const createRectMark = /* @__PURE__ */ action(
45
53
  { op: "createRectMark", description: "Create a semantic rectangular cell layer." },
46
54
  function (args = {}) {
47
55
  validateMarkOptions(args, CREATE_OPTIONS, "createRectMark");
56
+ requestedRectStyleDetails(args, "createRectMark");
48
57
  const id = resolveMarkId(this, args.id, {
49
58
  defaultId: "rect",
50
59
  label: "Rect mark id",
@@ -81,7 +90,7 @@ const createRectMark = action(
81
90
  }
82
91
  );
83
92
 
84
- const rematerializeRectMark = action(
93
+ const rematerializeRectMark = /* @__PURE__ */ action(
85
94
  { op: "rematerializeRectMark", description: "Recompute concrete rectangular cells." },
86
95
  function (args = {}) {
87
96
  validateMarkOptions(args, REMATERIALIZE_OPTIONS, "rematerializeRectMark");
@@ -99,7 +108,13 @@ const rematerializeRectMark = action(
99
108
  const layer = findLayer(this, id);
100
109
  const graphic = this.graphicSpec.objects[id];
101
110
  if (layer?.mark?.type !== "rect") throw new Error(`Unknown rect mark "${id}".`);
102
- if (graphic?.type !== "rect" || !Array.isArray(graphic.items)) {
111
+ const roundedCollection = graphic?.type === "collection" &&
112
+ Object.hasOwn(this.markConfigs[id] ?? {}, "cornerRadius") &&
113
+ graphic.items?.every(item => ["rect", "path"].includes(item.type));
114
+ if (
115
+ (graphic?.type !== "rect" && !roundedCollection) ||
116
+ !Array.isArray(graphic.items)
117
+ ) {
103
118
  throw new Error(`Rect mark "${id}" requires rect collection graphics.`);
104
119
  }
105
120
  if (this.markConfigs[id]?.gradientPlot?.materialized === true) {
@@ -110,13 +125,11 @@ const rematerializeRectMark = action(
110
125
  throw new Error(`Rect mark "${id}" requires an existing dataset.`);
111
126
  }
112
127
  if (!canMaterializeRect(this, layer)) {
113
- return graphic.items.length === 0
114
- ? this
115
- : this.editGraphics({ target: id, property: "items", value: [] });
128
+ return replaceGraphicItems(this, id, "rect", []);
116
129
  }
117
130
  let next = this;
118
131
  if (args.scales !== false) {
119
- const ids = new Set(["x", "y", "x2", "y2", "color"].flatMap(channel => {
132
+ const ids = new Set(["x", "y", "x2", "y2", "color", "stroke"].flatMap(channel => {
120
133
  const scale = layer.encoding?.[channel]?.scale;
121
134
  return scale === undefined ? [] : [scale];
122
135
  }));
@@ -124,18 +137,20 @@ const rematerializeRectMark = action(
124
137
  next = next.rematerializeScale({ id: scale, marks: false });
125
138
  }
126
139
  }
127
- return next.editGraphics({
128
- target: id,
129
- property: "items",
130
- value: resolveRectGraphicItems(next, layer, dataset)
131
- });
140
+ return replaceGraphicItems(
141
+ next,
142
+ id,
143
+ "rect",
144
+ resolveRectGraphicItems(next, layer, dataset)
145
+ );
132
146
  }
133
147
  );
134
148
 
135
- const editRectMark = action(
149
+ const editRectMark = /* @__PURE__ */ action(
136
150
  { op: "editRectMark", description: "Edit rectangular cell appearance." },
137
151
  function (args = {}) {
138
152
  validateMarkOptions(args, EDIT_OPTIONS, "editRectMark");
153
+ requestedRectStyleDetails(args, "editRectMark");
139
154
  if (!STYLE_OPTIONS.some(option => Object.hasOwn(args, option))) {
140
155
  throw new Error("editRectMark requires at least one editable property.");
141
156
  }
@@ -143,6 +158,11 @@ const editRectMark = action(
143
158
  if (Object.hasOwn(args, "fill") && layer.encoding?.color !== undefined) {
144
159
  throw new Error("editRectMark fill cannot be combined with a color encoding.");
145
160
  }
161
+ if (Object.hasOwn(args, "stroke") && layer.encoding?.stroke !== undefined) {
162
+ throw new Error(
163
+ "editRectMark stroke conflicts with a field encoding; use encodeStroke with value to replace it."
164
+ );
165
+ }
146
166
  const next = this._withMarkConfig(
147
167
  layer.id,
148
168
  {
@@ -155,9 +175,10 @@ const editRectMark = action(
155
175
  : this.markConfigs[layer.id]?.fillExplicit ?? false
156
176
  }
157
177
  );
158
- return canMaterializeRect(next, layer)
178
+ const materialized = canMaterializeRect(next, layer)
159
179
  ? next.rematerializeRectMark({ id: layer.id })
160
180
  : next;
181
+ return rematerializeExistingLegend(materialized);
161
182
  }
162
183
  );
163
184