ggaction 0.0.2 → 0.0.3

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 (199) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +12 -1
  3. package/package.json +6 -1
  4. package/src/actions/boxPlots/components.js +3 -3
  5. package/src/actions/boxPlots/edit.js +277 -0
  6. package/src/actions/boxPlots/index.js +2 -0
  7. package/src/actions/boxPlots/materialize.js +12 -1
  8. package/src/actions/boxPlots/options.js +25 -14
  9. package/src/actions/canvas/actions.js +21 -17
  10. package/src/actions/composition/actions.js +247 -0
  11. package/src/actions/composition/index.js +1 -0
  12. package/src/actions/coordinates/actions.js +2 -5
  13. package/src/actions/data/density.js +7 -1
  14. package/src/actions/data/filter.js +3 -1
  15. package/src/actions/encodings/appearance.js +11 -0
  16. package/src/actions/encodings/barWidth.js +5 -3
  17. package/src/actions/encodings/color.js +120 -25
  18. package/src/actions/encodings/index.js +2 -0
  19. package/src/actions/encodings/offset.js +90 -72
  20. package/src/actions/encodings/position/apply.js +66 -0
  21. package/src/actions/encodings/position/policies/arc.js +26 -0
  22. package/src/actions/encodings/position/policies/bar.js +9 -5
  23. package/src/actions/encodings/position/policies/index.js +5 -1
  24. package/src/actions/encodings/position/policies/line.js +20 -3
  25. package/src/actions/encodings/position/resolve.js +57 -8
  26. package/src/actions/encodings/position.js +44 -90
  27. package/src/actions/encodings/ranged.js +28 -6
  28. package/src/actions/encodings/shared.js +17 -21
  29. package/src/actions/encodings/text.js +73 -0
  30. package/src/actions/errorBands/create.js +37 -29
  31. package/src/actions/errorBands/edit.js +206 -0
  32. package/src/actions/errorBands/index.js +9 -0
  33. package/src/actions/errorBands/options.js +39 -0
  34. package/src/actions/errorBars/create.js +50 -43
  35. package/src/actions/errorBars/edit.js +130 -0
  36. package/src/actions/errorBars/index.js +3 -0
  37. package/src/actions/errorBars/options.js +52 -0
  38. package/src/actions/facets/actions.js +162 -0
  39. package/src/actions/facets/derive.js +200 -0
  40. package/src/actions/facets/guides.js +16 -0
  41. package/src/actions/facets/index.js +1 -0
  42. package/src/actions/facets/replay.js +69 -0
  43. package/src/actions/guides/applicability.js +113 -0
  44. package/src/actions/guides/axes/axes.js +70 -16
  45. package/src/actions/guides/axes/edit.js +126 -0
  46. package/src/actions/guides/axes/index.js +12 -0
  47. package/src/actions/guides/axes/labels.js +21 -18
  48. package/src/actions/guides/axes/remove.js +60 -0
  49. package/src/actions/guides/axes/tickGroups.js +7 -5
  50. package/src/actions/guides/axes/ticks.js +9 -4
  51. package/src/actions/guides/axes/titles.js +7 -5
  52. package/src/actions/guides/grids/grid.js +144 -15
  53. package/src/actions/guides/grids/resolve.js +5 -13
  54. package/src/actions/guides/guides.js +17 -75
  55. package/src/actions/guides/index.js +6 -0
  56. package/src/actions/guides/legends/categorical/actions.js +48 -9
  57. package/src/actions/guides/legends/categorical/components.js +16 -16
  58. package/src/actions/guides/legends/categorical/index.js +14 -14
  59. package/src/actions/guides/legends/categorical/layout.js +3 -1
  60. package/src/actions/guides/legends/categorical/options.js +2 -5
  61. package/src/actions/guides/legends/categorical/resolve.js +2 -2
  62. package/src/actions/guides/legends/categorical/symbols.js +14 -14
  63. package/src/actions/guides/legends/continuous/common.js +7 -7
  64. package/src/actions/guides/legends/continuous/interval.js +5 -5
  65. package/src/actions/guides/legends/edit.js +2 -6
  66. package/src/actions/guides/legends/focused.js +63 -0
  67. package/src/actions/guides/legends/index.js +4 -0
  68. package/src/actions/guides/legends/remove.js +64 -0
  69. package/src/actions/guides/legends/size.js +12 -14
  70. package/src/actions/guides/polar/axes/facade.js +219 -0
  71. package/src/actions/guides/polar/axes/labels.js +188 -0
  72. package/src/actions/guides/polar/axes/lines.js +113 -0
  73. package/src/actions/guides/polar/axes/shared.js +112 -0
  74. package/src/actions/guides/polar/axes/ticks.js +164 -0
  75. package/src/actions/guides/polar/axes/titles.js +165 -0
  76. package/src/actions/guides/polar/axes.js +55 -0
  77. package/src/actions/guides/polar/grids.js +252 -0
  78. package/src/actions/guides/polar/index.js +2 -0
  79. package/src/actions/guides/polar/resolve.js +269 -0
  80. package/src/actions/index.js +4 -0
  81. package/src/actions/marks/arc/actions.js +239 -0
  82. package/src/actions/marks/arc/index.js +1 -0
  83. package/src/actions/marks/{area.js → area/actions.js} +51 -38
  84. package/src/actions/marks/area/index.js +4 -0
  85. package/src/actions/marks/bar/create.js +26 -5
  86. package/src/actions/marks/bar/materialize.js +25 -31
  87. package/src/actions/marks/index.js +12 -4
  88. package/src/actions/marks/lifecycle.js +27 -0
  89. package/src/actions/marks/line/actions.js +373 -0
  90. package/src/actions/marks/line/index.js +1 -0
  91. package/src/actions/marks/{point.js → point/actions.js} +67 -108
  92. package/src/actions/marks/point/index.js +1 -0
  93. package/src/actions/marks/rect/actions.js +165 -0
  94. package/src/actions/marks/rect/index.js +1 -0
  95. package/src/actions/marks/remove.js +214 -0
  96. package/src/actions/marks/{rule.js → rule/actions.js} +34 -28
  97. package/src/actions/marks/rule/index.js +1 -0
  98. package/src/actions/marks/shared.js +156 -25
  99. package/src/actions/marks/text/actions.js +192 -0
  100. package/src/actions/marks/text/index.js +1 -0
  101. package/src/actions/primitives/createGraphics.js +13 -6
  102. package/src/actions/primitives/editGraphics.js +10 -3
  103. package/src/actions/primitives/semantic.js +26 -3
  104. package/src/actions/primitives/semanticValue.js +25 -3
  105. package/src/actions/regression/components.js +1 -1
  106. package/src/actions/regression/create.js +18 -1
  107. package/src/actions/regression/edit.js +247 -0
  108. package/src/actions/regression/index.js +3 -0
  109. package/src/actions/regression/resolve.js +3 -1
  110. package/src/actions/scales/consumers.js +15 -6
  111. package/src/actions/scales/definitions.js +13 -4
  112. package/src/actions/scales/edit.js +42 -19
  113. package/src/actions/scales/materialize.js +57 -408
  114. package/src/actions/selection/actions.js +38 -24
  115. package/src/actions/selection/index.js +2 -0
  116. package/src/actions/titles/actions.js +63 -2
  117. package/src/actions/titles/index.js +2 -0
  118. package/src/actions/titles/resolve.js +12 -17
  119. package/src/composition.js +10 -0
  120. package/src/core/ChartProgram.js +200 -2
  121. package/src/core/action.js +10 -0
  122. package/src/core/validation.js +16 -0
  123. package/src/core/vocabulary.js +154 -4
  124. package/src/grammar/arcs.js +154 -0
  125. package/src/grammar/bars/aggregate.js +2 -2
  126. package/src/grammar/bars/geometry.js +3 -3
  127. package/src/grammar/bars/policy.js +7 -1
  128. package/src/grammar/coordinates.js +3 -7
  129. package/src/grammar/density.js +20 -1
  130. package/src/grammar/facets/dependencies.js +185 -0
  131. package/src/grammar/facets/guides.js +257 -0
  132. package/src/grammar/facets/scales.js +254 -0
  133. package/src/grammar/facets.js +122 -0
  134. package/src/grammar/lineSeries.js +111 -3
  135. package/src/grammar/polar.js +102 -0
  136. package/src/grammar/polarGuides.js +243 -0
  137. package/src/grammar/polarLineCommands.js +43 -0
  138. package/src/grammar/polarPaths.js +161 -0
  139. package/src/grammar/positionCompatibility.js +18 -2
  140. package/src/grammar/rects.js +26 -0
  141. package/src/grammar/scales/continuous.js +6 -1
  142. package/src/grammar/scales/fields.js +7 -0
  143. package/src/grammar/scales/ordinal.js +5 -2
  144. package/src/grammar/scales/policies.js +1 -1
  145. package/src/grammar/schemas/graphic.js +1 -1
  146. package/src/grammar/schemas/graphicBounds.js +64 -9
  147. package/src/grammar/schemas/graphicTree.js +44 -10
  148. package/src/grammar/schemas/semanticPath.js +31 -9
  149. package/src/grammar/seriesLayout.js +13 -2
  150. package/src/grammar/text.js +71 -0
  151. package/src/grammar/ticks.js +50 -13
  152. package/src/index.js +1 -0
  153. package/src/layout/composition.js +310 -0
  154. package/src/layout/facets.js +131 -0
  155. package/src/layout/title.js +6 -0
  156. package/src/materialization/bars/aggregate.js +5 -2
  157. package/src/materialization/bars/grouped.js +75 -37
  158. package/src/materialization/composition.js +152 -0
  159. package/src/materialization/compositionSnapshot.js +114 -0
  160. package/src/materialization/dependencies.js +71 -16
  161. package/src/materialization/encodings.js +14 -28
  162. package/src/materialization/facetGuides.js +426 -0
  163. package/src/materialization/facets.js +214 -0
  164. package/src/materialization/graphicHierarchy.js +15 -5
  165. package/src/materialization/guides/resources.js +46 -0
  166. package/src/materialization/marks.js +220 -14
  167. package/src/materialization/planner.js +105 -12
  168. package/src/materialization/rect.js +138 -0
  169. package/src/materialization/rectConfig.js +38 -0
  170. package/src/materialization/rowEncoding.js +33 -0
  171. package/src/materialization/scales/map.js +40 -0
  172. package/src/materialization/scales/policies/arc.js +37 -0
  173. package/src/materialization/scales/policies/bar.js +132 -0
  174. package/src/materialization/scales/policies/series.js +76 -0
  175. package/src/materialization/scales/resolve.js +326 -0
  176. package/src/materialization/selection/items/arc.js +29 -0
  177. package/src/materialization/selection/items/bar.js +255 -0
  178. package/src/materialization/selection/items/common.js +131 -0
  179. package/src/materialization/selection/items/index.js +6 -0
  180. package/src/materialization/selection/items/path.js +59 -0
  181. package/src/materialization/selection/items/point.js +55 -0
  182. package/src/materialization/selection/items/rect.js +23 -0
  183. package/src/materialization/selection/items/rule.js +25 -0
  184. package/src/materialization/selection/policies/arc.js +10 -0
  185. package/src/materialization/selection/policies/area.js +1 -1
  186. package/src/materialization/selection/policies/bar.js +1 -1
  187. package/src/materialization/selection/policies/index.js +5 -1
  188. package/src/materialization/selection/policies/line.js +1 -1
  189. package/src/materialization/selection/policies/point.js +1 -1
  190. package/src/materialization/selection/policies/rect.js +10 -0
  191. package/src/materialization/selection/policies/rule.js +1 -1
  192. package/src/materialization/selection/styles.js +24 -16
  193. package/src/materialization/text.js +156 -0
  194. package/src/renderers/canvas/index.js +68 -22
  195. package/types/extension.d.ts +1 -0
  196. package/types/index.d.ts +56 -1
  197. package/types/program.d.ts +664 -27
  198. package/src/actions/marks/line.js +0 -248
  199. package/src/materialization/selection/items.js +0 -503
@@ -1,248 +0,0 @@
1
- import { action } from "../../core/action.js";
2
- import { deriveLineSeries } from "../../grammar/lineSeries.js";
3
- import { mapContinuousScaleValues, mapOrdinalValues } from "../../grammar/scales.js";
4
- import { validateUserId } from "../../core/identifiers.js";
5
- import { validateNonNegativeFinite } from "../../core/validation.js";
6
- import {
7
- assertMarkAvailable,
8
- resolveMarkId,
9
- resolveMarkData,
10
- validateMarkOptions
11
- } from "./shared.js";
12
- import { DEFAULT_COLORS } from "../../theme/defaults.js";
13
- import { findDataset } from "../../selectors/datasets.js";
14
- import { findLayer, resolveEligibleLayer } from "../../selectors/layers.js";
15
- import {
16
- buildCurvePathCommands,
17
- validateCurveInterpolation
18
- } from "../../grammar/curveCommands.js";
19
- import { normalizeStrokeDashPattern } from "../../grammar/scales.js";
20
- import { canMaterializeLine } from "../../materialization/marks.js";
21
- import { resolveMarkGraphicPlacement } from
22
- "../../materialization/graphicHierarchy.js";
23
-
24
- const DEFAULT_LINE_STROKE = DEFAULT_COLORS.mark;
25
- const DEFAULT_LINE_WIDTH = 2;
26
- const CREATE_OPTIONS = Object.freeze(["id", "data", "strokeWidth", "curve"]);
27
- const EDIT_OPTIONS = Object.freeze(["target", "strokeWidth", "curve"]);
28
- const REMATERIALIZE_OPTIONS = Object.freeze(["id"]);
29
-
30
- const createLineMark = action(
31
- {
32
- op: "createLineMark",
33
- description: "Create a semantic line mark and empty path collection."
34
- },
35
- function (args = {}) {
36
- validateMarkOptions(args, CREATE_OPTIONS, "createLineMark");
37
- const id = resolveMarkId(this, args.id, {
38
- defaultId: "line",
39
- label: "Line mark id",
40
- markType: "line",
41
- operation: "createLineMark"
42
- });
43
- const { data } = resolveMarkData(this, args);
44
- const strokeWidth = validateNonNegativeFinite(
45
- args.strokeWidth ?? DEFAULT_LINE_WIDTH,
46
- "Line strokeWidth"
47
- );
48
- const curve = validateCurveInterpolation(args.curve ?? "linear");
49
- assertMarkAvailable(this, id);
50
-
51
- return this
52
- .editSemantic({
53
- property: `layer[${id}].mark.type`,
54
- value: "line"
55
- })
56
- .editSemantic({
57
- property: `layer[${id}].data`,
58
- value: data
59
- })
60
- .createGraphics({
61
- id,
62
- type: "path",
63
- length: 0,
64
- ...resolveMarkGraphicPlacement(this, { data, markType: "line" })
65
- })
66
- ._withMarkConfig(
67
- id,
68
- {
69
- ...(Object.hasOwn(args, "strokeWidth") ? { strokeWidth } : {}),
70
- ...(Object.hasOwn(args, "curve") ? { curve } : {})
71
- }
72
- );
73
- }
74
- );
75
-
76
- function requireLine(program, id) {
77
- const layer = findLayer(program, id);
78
-
79
- if (layer?.mark?.type !== "line") {
80
- throw new Error(`Unknown line mark "${id}".`);
81
- }
82
-
83
- const dataset = findDataset(program, layer.data);
84
-
85
- if (dataset === undefined) {
86
- throw new Error(`Line mark "${id}" requires an existing dataset.`);
87
- }
88
-
89
- if (program.graphicSpec.objects[id]?.type !== "path") {
90
- throw new Error(`Line mark "${id}" requires path graphics.`);
91
- }
92
-
93
- return { dataset, layer };
94
- }
95
-
96
- const rematerializeLineMark = action(
97
- {
98
- op: "rematerializeLineMark",
99
- description: "Recompute aggregate series and concrete line paths."
100
- },
101
- function (args = {}) {
102
- validateMarkOptions(
103
- args,
104
- REMATERIALIZE_OPTIONS,
105
- "rematerializeLineMark"
106
- );
107
- const id = validateUserId(args.id, "Line mark id");
108
- const highlights = Object.entries(
109
- this.materializationConfigs.highlights ?? {}
110
- ).filter(([, config]) => config.target === id);
111
- if (highlights.length > 0) {
112
- let baseline = this;
113
- for (const [highlightId] of highlights) {
114
- baseline = baseline._withoutMaterializationConfig(["highlights", highlightId]);
115
- }
116
- return baseline
117
- .editGraphics({ target: id, property: "length", value: 0 })
118
- .rematerializeLineMark({ id })
119
- .rematerializeMarkHighlights({ target: id, highlights });
120
- }
121
- const { dataset, layer } = requireLine(this, id);
122
- const existingChildren = this.graphicSpec.objects[id].items;
123
- const xScaleId = layer.encoding?.x?.scale;
124
- const yScaleId = layer.encoding?.y?.scale;
125
- const derived = deriveLineSeries(dataset.values, layer);
126
-
127
- if (xScaleId === undefined || yScaleId === undefined) {
128
- throw new Error(`Line mark "${id}" requires x and y scales.`);
129
- }
130
-
131
- let resolved = this
132
- .rematerializeScale({ id: xScaleId })
133
- .rematerializeScale({ id: yScaleId });
134
-
135
- for (const channel of ["color", "strokeDash"]) {
136
- const scaleId = layer.encoding?.[channel]?.scale;
137
- if (scaleId !== undefined) {
138
- resolved = resolved.rematerializeScale({ id: scaleId });
139
- }
140
- }
141
-
142
- const xScale = resolved.resolvedScales[xScaleId];
143
- const yScale = resolved.resolvedScales[yScaleId];
144
- const commands = derived.series.map(series => {
145
- const x = mapContinuousScaleValues(
146
- series.values.map(value => value.x),
147
- xScale
148
- );
149
- const y = mapContinuousScaleValues(
150
- series.values.map(value => value.y),
151
- yScale
152
- );
153
-
154
- return buildCurvePathCommands(
155
- series.values.map((_, index) => ({ x: x[index], y: y[index] })),
156
- this.markConfigs[id]?.curve ?? "linear"
157
- );
158
- });
159
- const colorEncoding = layer.encoding?.color;
160
- const dashEncoding = layer.encoding?.strokeDash;
161
- const strokes = colorEncoding?.scale === undefined
162
- ? commands.map(
163
- (_, index) =>
164
- existingChildren[index]?.properties.stroke ?? DEFAULT_LINE_STROKE
165
- )
166
- : mapOrdinalValues(
167
- derived.series.map(series => series.key[colorEncoding.field]),
168
- resolved.resolvedScales[colorEncoding.scale].domain,
169
- resolved.resolvedScales[colorEncoding.scale].range
170
- );
171
- const strokeWidths = commands.map(
172
- (_, index) =>
173
- this.markConfigs[id]?.strokeWidth ??
174
- existingChildren[index]?.properties.strokeWidth ??
175
- DEFAULT_LINE_WIDTH
176
- );
177
- const strokeDashes = dashEncoding?.datum !== undefined
178
- ? commands.map(() => normalizeStrokeDashPattern(dashEncoding.datum))
179
- : dashEncoding?.scale === undefined
180
- ? commands.map(
181
- (_, index) => existingChildren[index]?.properties.strokeDash ?? []
182
- )
183
- : mapOrdinalValues(
184
- derived.series.map(series => series.key[dashEncoding.field]),
185
- resolved.resolvedScales[dashEncoding.scale].domain,
186
- resolved.resolvedScales[dashEncoding.scale].range
187
- );
188
-
189
- return resolved
190
- .editGraphics({ target: id, property: "length", value: commands.length })
191
- .editGraphics({ target: id, property: "commands", value: commands })
192
- .editGraphics({ target: id, property: "stroke", value: strokes })
193
- .editGraphics({ target: id, property: "strokeWidth", value: strokeWidths })
194
- .editGraphics({
195
- target: id,
196
- property: "strokeDash",
197
- value: strokeDashes
198
- });
199
- }
200
- );
201
-
202
- const editLineMark = action(
203
- {
204
- op: "editLineMark",
205
- description: "Edit line-mark curve and stroke width."
206
- },
207
- function (args = {}) {
208
- validateMarkOptions(args, EDIT_OPTIONS, "editLineMark");
209
- if (
210
- !Object.hasOwn(args, "strokeWidth") &&
211
- !Object.hasOwn(args, "curve")
212
- ) {
213
- throw new Error("editLineMark requires strokeWidth or curve.");
214
- }
215
- const target = Object.hasOwn(args, "target")
216
- ? validateUserId(args.target, "Line mark id")
217
- : undefined;
218
- const layer = resolveEligibleLayer(this, {
219
- target,
220
- predicate: candidate => candidate.mark?.type === "line",
221
- label: "line mark"
222
- });
223
- const config = {
224
- ...this.markConfigs[layer.id],
225
- ...(Object.hasOwn(args, "strokeWidth")
226
- ? {
227
- strokeWidth: validateNonNegativeFinite(
228
- args.strokeWidth,
229
- "Line strokeWidth"
230
- )
231
- }
232
- : {}),
233
- ...(Object.hasOwn(args, "curve")
234
- ? { curve: validateCurveInterpolation(args.curve) }
235
- : {})
236
- };
237
- const next = this._withMarkConfig(layer.id, config);
238
- return canMaterializeLine(next, layer)
239
- ? next.rematerializeLineMark({ id: layer.id })
240
- : next;
241
- }
242
- );
243
-
244
- export function registerLineMarkActions(ProgramClass) {
245
- ProgramClass.prototype.createLineMark = createLineMark;
246
- ProgramClass.prototype.editLineMark = editLineMark;
247
- ProgramClass.prototype.rematerializeLineMark = rematerializeLineMark;
248
- }