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.
- package/CHANGELOG.md +28 -3
- package/README.md +95 -83
- package/package.json +11 -6
- package/src/actions/data/regression.js +1 -1
- package/src/actions/encodings/appearance.js +1 -1
- package/src/actions/encodings/color/continuous.js +137 -0
- package/src/actions/encodings/color/index.js +151 -0
- package/src/actions/encodings/color/layout.js +91 -0
- package/src/actions/encodings/color/policy.js +88 -0
- package/src/actions/encodings/index.js +2 -2
- package/src/actions/encodings/offset.js +1 -1
- package/src/actions/encodings/{position.js → position/index.js} +6 -6
- package/src/actions/encodings/position/resolve.js +1 -1
- package/src/actions/encodings/ranged.js +2 -2
- package/src/actions/encodings/strokeDash.js +1 -1
- package/src/actions/encodings/text.js +1 -1
- package/src/actions/errorBands/options.js +1 -1
- package/src/actions/errorBars/options.js +1 -1
- package/src/actions/facets/actions.js +1 -1
- package/src/actions/facets/derive.js +2 -2
- package/src/actions/facets/guides.js +1 -1
- package/src/actions/guides/axes/labels.js +1 -1
- package/src/actions/guides/axes/ticks.js +1 -1
- package/src/actions/guides/axes/titles.js +1 -1
- package/src/actions/guides/grids/resolve.js +1 -1
- package/src/actions/guides/legends/categorical/layout.js +4 -2
- package/src/actions/guides/legends/continuous/interval.js +1 -1
- package/src/actions/guides/legends/continuous/opacity.js +1 -1
- package/src/actions/guides/legends/edit.js +2 -20
- package/src/actions/guides/legends/remove.js +2 -20
- package/src/actions/guides/legends/size.js +1 -1
- package/src/actions/guides/legends/target.js +25 -0
- package/src/actions/guides/polar/{axes.js → axes/index.js} +5 -5
- package/src/actions/guides/polar/index.js +1 -1
- package/src/actions/guides/polar/resolve.js +1 -1
- package/src/actions/guides/tickValues.js +1 -1
- package/src/actions/intervals/resolve.js +1 -1
- package/src/actions/marks/arc/actions.js +2 -2
- package/src/actions/marks/area/actions.js +2 -2
- package/src/actions/marks/bar/edit.js +1 -1
- package/src/actions/marks/line/actions.js +3 -3
- package/src/actions/marks/rect/actions.js +1 -1
- package/src/actions/marks/rule/actions.js +1 -1
- package/src/actions/marks/shared.js +1 -1
- package/src/actions/marks/text/actions.js +1 -1
- package/src/actions/primitives/semanticValue.js +1 -1
- package/src/actions/regression/components.js +1 -1
- package/src/actions/regression/create.js +1 -1
- package/src/actions/regression/edit.js +1 -1
- package/src/actions/scales/consumers/common.js +91 -0
- package/src/actions/scales/consumers/families.js +47 -0
- package/src/actions/scales/consumers/index.js +41 -0
- package/src/actions/scales/{consumers.js → consumers/seriesLayout.js} +10 -132
- package/src/actions/scales/create.js +1 -1
- package/src/actions/scales/definitions.js +2 -2
- package/src/actions/scales/edit.js +3 -3
- package/src/actions/scales/materialize.js +2 -2
- package/src/core/ChartProgram.js +22 -236
- package/src/core/compositionState.js +169 -0
- package/src/core/materializationState.js +65 -0
- package/src/core/programState.js +28 -0
- package/src/grammar/arcs.js +1 -1
- package/src/grammar/areaSeries.js +1 -1
- package/src/grammar/bars/aggregate.js +1 -1
- package/src/grammar/density.js +1 -1
- package/src/grammar/{facets.js → facets/index.js} +5 -5
- package/src/grammar/interval.js +2 -96
- package/src/grammar/lineSeries.js +1 -1
- package/src/grammar/palettes.js +5 -7
- package/src/grammar/polarLineCommands.js +1 -1
- package/src/grammar/regression/derive.js +97 -0
- package/src/grammar/regression/index.js +22 -0
- package/src/grammar/regression/models.js +282 -0
- package/src/grammar/regression/parameters.js +106 -0
- package/src/grammar/rules.js +1 -1
- package/src/grammar/scales/color.js +4 -2
- package/src/grammar/statistics/studentT.js +98 -0
- package/src/grammar/transforms.js +1 -1
- package/src/materialization/bars/aggregate.js +1 -1
- package/src/materialization/bars/grouped.js +1 -1
- package/src/materialization/bars/histogram.js +1 -1
- package/src/materialization/bars/ranged.js +1 -1
- package/src/materialization/density.js +1 -1
- package/src/materialization/dependencies.js +6 -87
- package/src/materialization/encodings.js +2 -2
- package/src/materialization/facetGuides/index.js +2 -0
- package/src/materialization/facetGuides/legacyCategorical.js +125 -0
- package/src/materialization/facetGuides/placement.js +126 -0
- package/src/materialization/facetGuides/preparation.js +188 -0
- package/src/materialization/facets.js +1 -1
- package/src/materialization/marks/capabilities.js +141 -0
- package/src/materialization/marks/index.js +105 -0
- package/src/materialization/marks/policies.js +87 -0
- package/src/materialization/rect.js +1 -1
- package/src/materialization/rowEncoding.js +1 -1
- package/src/materialization/scaleGuideDependencies.js +94 -0
- package/src/materialization/scales/map.js +1 -1
- package/src/materialization/scales/policies/series.js +1 -1
- package/src/materialization/scales/resolve.js +1 -1
- package/src/materialization/selection/items/bar.js +1 -1
- package/src/materialization/selection/styles.js +1 -1
- package/src/renderers/canvas/text.js +14 -1
- package/types/extension.d.ts +4 -1
- package/src/actions/encodings/color.js +0 -424
- package/src/grammar/regression.js +0 -578
- package/src/grammar/scales.js +0 -1
- package/src/materialization/facetGuides.js +0 -426
- 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
|
-
}
|