ggaction 0.0.3 → 0.0.4

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 (108) hide show
  1. package/CHANGELOG.md +28 -3
  2. package/README.md +95 -83
  3. package/package.json +11 -6
  4. package/src/actions/data/regression.js +1 -1
  5. package/src/actions/encodings/appearance.js +1 -1
  6. package/src/actions/encodings/color/continuous.js +137 -0
  7. package/src/actions/encodings/color/index.js +151 -0
  8. package/src/actions/encodings/color/layout.js +91 -0
  9. package/src/actions/encodings/color/policy.js +88 -0
  10. package/src/actions/encodings/index.js +2 -2
  11. package/src/actions/encodings/offset.js +1 -1
  12. package/src/actions/encodings/{position.js → position/index.js} +6 -6
  13. package/src/actions/encodings/position/resolve.js +1 -1
  14. package/src/actions/encodings/ranged.js +2 -2
  15. package/src/actions/encodings/strokeDash.js +1 -1
  16. package/src/actions/encodings/text.js +1 -1
  17. package/src/actions/errorBands/options.js +1 -1
  18. package/src/actions/errorBars/options.js +1 -1
  19. package/src/actions/facets/actions.js +1 -1
  20. package/src/actions/facets/derive.js +2 -2
  21. package/src/actions/facets/guides.js +1 -1
  22. package/src/actions/guides/axes/labels.js +1 -1
  23. package/src/actions/guides/axes/ticks.js +1 -1
  24. package/src/actions/guides/axes/titles.js +1 -1
  25. package/src/actions/guides/grids/resolve.js +1 -1
  26. package/src/actions/guides/legends/categorical/layout.js +4 -2
  27. package/src/actions/guides/legends/continuous/interval.js +1 -1
  28. package/src/actions/guides/legends/continuous/opacity.js +1 -1
  29. package/src/actions/guides/legends/edit.js +2 -20
  30. package/src/actions/guides/legends/remove.js +2 -20
  31. package/src/actions/guides/legends/size.js +1 -1
  32. package/src/actions/guides/legends/target.js +25 -0
  33. package/src/actions/guides/polar/{axes.js → axes/index.js} +5 -5
  34. package/src/actions/guides/polar/index.js +1 -1
  35. package/src/actions/guides/polar/resolve.js +1 -1
  36. package/src/actions/guides/tickValues.js +1 -1
  37. package/src/actions/intervals/resolve.js +1 -1
  38. package/src/actions/marks/arc/actions.js +2 -2
  39. package/src/actions/marks/area/actions.js +2 -2
  40. package/src/actions/marks/bar/edit.js +1 -1
  41. package/src/actions/marks/line/actions.js +3 -3
  42. package/src/actions/marks/rect/actions.js +1 -1
  43. package/src/actions/marks/rule/actions.js +1 -1
  44. package/src/actions/marks/shared.js +1 -1
  45. package/src/actions/marks/text/actions.js +1 -1
  46. package/src/actions/primitives/semanticValue.js +1 -1
  47. package/src/actions/regression/components.js +1 -1
  48. package/src/actions/regression/create.js +1 -1
  49. package/src/actions/regression/edit.js +1 -1
  50. package/src/actions/scales/consumers/common.js +91 -0
  51. package/src/actions/scales/consumers/families.js +47 -0
  52. package/src/actions/scales/consumers/index.js +41 -0
  53. package/src/actions/scales/{consumers.js → consumers/seriesLayout.js} +10 -132
  54. package/src/actions/scales/create.js +1 -1
  55. package/src/actions/scales/definitions.js +2 -2
  56. package/src/actions/scales/edit.js +3 -3
  57. package/src/actions/scales/materialize.js +2 -2
  58. package/src/core/ChartProgram.js +22 -236
  59. package/src/core/compositionState.js +169 -0
  60. package/src/core/materializationState.js +65 -0
  61. package/src/core/programState.js +28 -0
  62. package/src/grammar/arcs.js +1 -1
  63. package/src/grammar/areaSeries.js +1 -1
  64. package/src/grammar/bars/aggregate.js +1 -1
  65. package/src/grammar/density.js +1 -1
  66. package/src/grammar/{facets.js → facets/index.js} +5 -5
  67. package/src/grammar/interval.js +2 -96
  68. package/src/grammar/lineSeries.js +1 -1
  69. package/src/grammar/palettes.js +5 -7
  70. package/src/grammar/polarLineCommands.js +1 -1
  71. package/src/grammar/regression/derive.js +97 -0
  72. package/src/grammar/regression/index.js +22 -0
  73. package/src/grammar/regression/models.js +282 -0
  74. package/src/grammar/regression/parameters.js +106 -0
  75. package/src/grammar/rules.js +1 -1
  76. package/src/grammar/scales/color.js +4 -2
  77. package/src/grammar/statistics/studentT.js +98 -0
  78. package/src/grammar/transforms.js +1 -1
  79. package/src/materialization/bars/aggregate.js +1 -1
  80. package/src/materialization/bars/grouped.js +1 -1
  81. package/src/materialization/bars/histogram.js +1 -1
  82. package/src/materialization/bars/ranged.js +1 -1
  83. package/src/materialization/density.js +1 -1
  84. package/src/materialization/dependencies.js +6 -87
  85. package/src/materialization/encodings.js +2 -2
  86. package/src/materialization/facetGuides/index.js +2 -0
  87. package/src/materialization/facetGuides/legacyCategorical.js +125 -0
  88. package/src/materialization/facetGuides/placement.js +126 -0
  89. package/src/materialization/facetGuides/preparation.js +188 -0
  90. package/src/materialization/facets.js +1 -1
  91. package/src/materialization/marks/capabilities.js +141 -0
  92. package/src/materialization/marks/index.js +105 -0
  93. package/src/materialization/marks/policies.js +87 -0
  94. package/src/materialization/rect.js +1 -1
  95. package/src/materialization/rowEncoding.js +1 -1
  96. package/src/materialization/scaleGuideDependencies.js +94 -0
  97. package/src/materialization/scales/map.js +1 -1
  98. package/src/materialization/scales/policies/series.js +1 -1
  99. package/src/materialization/scales/resolve.js +1 -1
  100. package/src/materialization/selection/items/bar.js +1 -1
  101. package/src/materialization/selection/styles.js +1 -1
  102. package/src/renderers/canvas/text.js +14 -1
  103. package/types/extension.d.ts +4 -1
  104. package/src/actions/encodings/color.js +0 -424
  105. package/src/grammar/regression.js +0 -578
  106. package/src/grammar/scales.js +0 -1
  107. package/src/materialization/facetGuides.js +0 -426
  108. package/src/materialization/marks.js +0 -316
@@ -1,316 +0,0 @@
1
- import { findDataset } from "../selectors/datasets.js";
2
- import { findLayer } from "../selectors/layers.js";
3
- import { isAggregate } from "../grammar/aggregate.js";
4
- import {
5
- BAR_GRAINS,
6
- resolveBarColorLayout,
7
- resolveBarOffsetChannel,
8
- resolveBarGrain
9
- } from "../grammar/bars/policy.js";
10
- import { resolveRuleMode } from "../grammar/rules.js";
11
- import { findUpstreamTransform } from "./dataProvenance.js";
12
- import { POSITION_CHANNELS } from "../core/vocabulary.js";
13
- import { resolveRectMode } from "../grammar/rects.js";
14
-
15
- function hasCartesianPositionScales(layer) {
16
- return (
17
- layer.encoding?.x?.scale !== undefined &&
18
- layer.encoding?.y?.scale !== undefined
19
- );
20
- }
21
-
22
- function hasPolarPositionScales(layer) {
23
- return (
24
- layer.encoding?.theta?.scale !== undefined &&
25
- layer.encoding?.radius?.scale !== undefined
26
- );
27
- }
28
-
29
- function hasPositionScales(layer) {
30
- return hasCartesianPositionScales(layer);
31
- }
32
-
33
- export function canMaterializePoint(_program, layer) {
34
- return layer.mark?.type === "point" && (
35
- hasCartesianPositionScales(layer) || hasPolarPositionScales(layer)
36
- );
37
- }
38
-
39
- export function canMaterializeLine(program, layer) {
40
- const dataset = findDataset(program, layer.data);
41
- const interval = dataset?.transform?.some(item => item.type === "interval");
42
- if (hasPolarPositionScales(layer)) {
43
- return (
44
- layer.mark?.type === "line" &&
45
- ["quantitative", "temporal", "ordinal", "nominal"].includes(
46
- layer.encoding.theta.fieldType
47
- ) &&
48
- layer.encoding.radius.fieldType === "quantitative"
49
- );
50
- }
51
- return (
52
- layer.mark?.type === "line" &&
53
- hasPositionScales(layer) &&
54
- (isAggregate(layer.encoding.y.aggregate) ||
55
- (layer.encoding.x.fieldType === "quantitative" &&
56
- layer.encoding.y.fieldType === "quantitative") ||
57
- ((interval || layer.encoding.y.aggregate === undefined) &&
58
- ["quantitative", "temporal"].includes(layer.encoding.x.fieldType) &&
59
- ["quantitative", "temporal"].includes(layer.encoding.y.fieldType) &&
60
- layer.encoding.x.fieldType !== layer.encoding.y.fieldType))
61
- );
62
- }
63
-
64
- export function canMaterializeArea(program, layer) {
65
- if (layer.mark?.type !== "area" || !hasPositionScales(layer)) {
66
- return false;
67
- }
68
-
69
- const dataset = findDataset(program, layer.data);
70
- const densityTransform = findUpstreamTransform(program, dataset, "density");
71
- const completeDensity =
72
- densityTransform !== undefined &&
73
- (densityTransform.groupBy === undefined ||
74
- layer.encoding?.group?.field === densityTransform.groupBy);
75
-
76
- return (
77
- completeDensity ||
78
- layer.encoding?.y2?.scale === layer.encoding.y.scale ||
79
- layer.encoding?.x2?.scale === layer.encoding.x.scale
80
- );
81
- }
82
-
83
- export function canMaterializeArc(_program, layer) {
84
- if (
85
- layer.mark?.type !== "arc" ||
86
- layer.encoding?.theta?.scale === undefined ||
87
- !["nominal", "ordinal"].includes(layer.encoding.theta.fieldType)
88
- ) {
89
- return false;
90
- }
91
- if (layer.encoding.theta.aggregate === "count") {
92
- return layer.encoding?.radius === undefined;
93
- }
94
- return (
95
- layer.encoding.theta.aggregate === undefined &&
96
- layer.encoding?.radius?.scale !== undefined &&
97
- layer.encoding.radius.fieldType === "quantitative"
98
- );
99
- }
100
-
101
- export function canMaterializeBar(program, layer) {
102
- if (layer.mark?.type !== "bar" || !hasPositionScales(layer)) {
103
- return false;
104
- }
105
- const grain = resolveBarGrain(layer);
106
- if (![BAR_GRAINS.histogram, BAR_GRAINS.aggregate, BAR_GRAINS.ranged].includes(grain)) {
107
- return false;
108
- }
109
- if (
110
- grain === BAR_GRAINS.aggregate &&
111
- resolveBarColorLayout(layer) === "group"
112
- ) {
113
- const offsetChannel = resolveBarOffsetChannel(layer);
114
- return (
115
- layer.encoding?.color?.field !== undefined &&
116
- layer.encoding?.[offsetChannel]?.field === layer.encoding.color.field &&
117
- layer.encoding[offsetChannel].scale !== undefined
118
- );
119
- }
120
- return true;
121
- }
122
-
123
- export function canMaterializeRule(program, layer) {
124
- const fixedSpan = program.markConfigs[layer.id]?.fixedSpan;
125
- const boxSpanOwner = program.markConfigs[layer.id]?.boxSpanOwner;
126
- return layer.mark?.type === "rule" && (
127
- resolveRuleMode(layer) !== undefined ||
128
- (boxSpanOwner !== undefined && hasPositionScales(layer)) ||
129
- (fixedSpan !== undefined && hasPositionScales(layer))
130
- );
131
- }
132
-
133
- export function canMaterializeText(program, layer) {
134
- if (layer.mark?.type !== "text" || layer.encoding?.text === undefined) {
135
- return false;
136
- }
137
- if (layer.source !== undefined) {
138
- const source = findLayer(program, layer.source);
139
- return source !== undefined &&
140
- ["point", "bar", "rule", "rect"].includes(source.mark?.type) &&
141
- Array.isArray(program.graphicSpec.objects[source.id]?.items);
142
- }
143
- return hasCartesianPositionScales(layer);
144
- }
145
-
146
- export function canMaterializeRect(_program, layer) {
147
- return resolveRectMode(layer) !== undefined;
148
- }
149
-
150
- const MARK_MATERIALIZATION_POLICIES = Object.freeze({
151
- point: Object.freeze({
152
- canMaterialize: canMaterializePoint,
153
- op: "rematerializePointMark",
154
- positionEncoding: Object.freeze({ incomplete: "mark", scaleFirst: true }),
155
- encoding: Object.freeze({ scaleFirst: true }),
156
- scaleApplication: Object.freeze({
157
- deferWithMark: true,
158
- position: "rematerialize",
159
- deferredChannels: Object.freeze(["size", "shape"]),
160
- default: "direct"
161
- }),
162
- rematerializeIncompleteExisting: true
163
- }),
164
- line: Object.freeze({
165
- canMaterialize: canMaterializeLine,
166
- op: "rematerializeLineMark",
167
- positionEncoding: Object.freeze({ incomplete: "scale", scaleFirst: false }),
168
- scaleApplication: Object.freeze({ default: "defer" })
169
- }),
170
- area: Object.freeze({
171
- canMaterialize: canMaterializeArea,
172
- op: "rematerializeAreaMark",
173
- positionEncoding: Object.freeze({ incomplete: "scale", scaleFirst: true }),
174
- encoding: Object.freeze({ sharedChannels: Object.freeze(["color"]) }),
175
- scaleApplication: Object.freeze({ default: "defer" })
176
- }),
177
- arc: Object.freeze({
178
- canMaterialize: canMaterializeArc,
179
- op: "rematerializeArcMark",
180
- positionEncoding: Object.freeze({ incomplete: "scale", scaleFirst: false }),
181
- encoding: Object.freeze({ completeOnly: true }),
182
- scaleApplication: Object.freeze({ default: "defer" })
183
- }),
184
- bar: Object.freeze({
185
- canMaterialize: canMaterializeBar,
186
- op: "rematerializeBarMark",
187
- positionEncoding: Object.freeze({ incomplete: "scale", scaleFirst: false }),
188
- scaleApplication: Object.freeze({ default: "defer" })
189
- }),
190
- rule: Object.freeze({
191
- canMaterialize: canMaterializeRule,
192
- op: "rematerializeRuleMark",
193
- positionEncoding: Object.freeze({ incomplete: "mark", scaleFirst: false }),
194
- scaleApplication: Object.freeze({ default: "defer" })
195
- }),
196
- text: Object.freeze({
197
- canMaterialize: canMaterializeText,
198
- op: "rematerializeTextMark",
199
- positionEncoding: Object.freeze({ incomplete: "mark", scaleFirst: true }),
200
- encoding: Object.freeze({ scaleFirst: true }),
201
- scaleApplication: Object.freeze({
202
- deferWithMark: true,
203
- position: "rematerialize",
204
- default: "defer"
205
- }),
206
- rematerializeIncompleteExisting: true,
207
- sourceDependent: true
208
- }),
209
- rect: Object.freeze({
210
- canMaterialize: canMaterializeRect,
211
- op: "rematerializeRectMark",
212
- positionEncoding: Object.freeze({ incomplete: "scale", scaleFirst: true }),
213
- encoding: Object.freeze({ scaleFirst: true }),
214
- scaleApplication: Object.freeze({
215
- deferWithMark: true,
216
- position: "rematerialize",
217
- default: "defer"
218
- }),
219
- rematerializeIncompleteExisting: true
220
- })
221
- });
222
-
223
- function getMarkPolicy(layer) {
224
- return MARK_MATERIALIZATION_POLICIES[layer.mark?.type];
225
- }
226
-
227
- export function getMarkRematerializationStep(layer) {
228
- const policy = getMarkPolicy(layer);
229
- return policy === undefined
230
- ? undefined
231
- : { op: policy.op, args: { id: layer.id } };
232
- }
233
-
234
- export function getMarkMaterializationStep(program, layer) {
235
- const policy = getMarkPolicy(layer);
236
- if (policy === undefined || !policy.canMaterialize(program, layer)) {
237
- return undefined;
238
- }
239
- return getMarkRematerializationStep(layer);
240
- }
241
-
242
- export function getSourceDependentMarkSteps(program, sourceId) {
243
- return program.semanticSpec.layers.flatMap(layer =>
244
- layer.source === sourceId && getMarkPolicy(layer)?.sourceDependent === true
245
- ? [getMarkMaterializationStep(program, layer)].filter(
246
- step => step !== undefined
247
- )
248
- : []
249
- );
250
- }
251
-
252
- export function getPositionEncodingMaterializationSteps(program, layer, scaleId) {
253
- const policy = getMarkPolicy(layer);
254
- if (policy === undefined) return [];
255
- const scale = { op: "rematerializeScale", args: { id: scaleId } };
256
- const complete = policy.canMaterialize(program, layer);
257
- const mark = getMarkRematerializationStep(layer);
258
- if (!complete) {
259
- if (policy.positionEncoding.incomplete === "scale") return [scale];
260
- return policy.positionEncoding.scaleFirst ? [scale, mark] : [mark];
261
- }
262
- return policy.positionEncoding.scaleFirst ? [scale, mark] : [mark];
263
- }
264
-
265
- export function getScaleConsumerMaterializationMode(layer, channel) {
266
- const policy = getMarkPolicy(layer);
267
- if (policy === undefined) return "direct";
268
- if (POSITION_CHANNELS.includes(channel)) {
269
- return policy.scaleApplication.position ?? policy.scaleApplication.default;
270
- }
271
- if (policy.scaleApplication.deferredChannels?.includes(channel)) {
272
- return "defer";
273
- }
274
- return policy.scaleApplication.default;
275
- }
276
-
277
- export function canDeferScaleConsumerApplication(layer) {
278
- return getMarkPolicy(layer)?.scaleApplication.deferWithMark === true;
279
- }
280
-
281
- export function getExistingMarkRematerializationStep(program, layer) {
282
- const policy = getMarkPolicy(layer);
283
- if (
284
- policy?.rematerializeIncompleteExisting !== true ||
285
- program.graphicSpec.objects[layer.id] === undefined
286
- ) {
287
- return undefined;
288
- }
289
- return getMarkRematerializationStep(layer);
290
- }
291
-
292
- export function getEncodingMaterializationStages(program, layer, channel, scale) {
293
- const policy = getMarkPolicy(layer);
294
- if (policy === undefined) return { scales: [], marks: [] };
295
- const scales = policy.encoding?.scaleFirst === true && scale !== undefined
296
- ? [{
297
- op: "rematerializeScale",
298
- args: { id: scale, guides: false, marks: false }
299
- }]
300
- : [];
301
- const shared = policy.encoding?.sharedChannels?.includes(channel) === true &&
302
- scale !== undefined;
303
- const candidates = shared
304
- ? program.semanticSpec.layers.filter(candidate =>
305
- candidate.mark?.type === layer.mark?.type &&
306
- candidate.encoding?.[channel]?.scale === scale
307
- )
308
- : [layer];
309
- const marks = candidates.flatMap(candidate => {
310
- const step = policy.encoding?.completeOnly === true
311
- ? getMarkMaterializationStep(program, candidate)
312
- : getMarkRematerializationStep(candidate);
313
- return step === undefined ? [] : [step];
314
- });
315
- return { scales, marks };
316
- }