ggaction 0.0.10 → 0.0.12
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 +97 -0
- package/README.md +5 -3
- package/knowledge/action-card.schema.json +1 -0
- package/knowledge/action-cards.json +1 -10941
- package/knowledge/action-cards.schema.json +1 -0
- package/knowledge/intent-taxonomy.json +1 -183
- package/knowledge/intent-taxonomy.schema.json +1 -0
- package/knowledge/mcp-resources.json +1 -95
- package/knowledge/mcp-resources.schema.json +1 -0
- package/knowledge/task-packet.schema.json +1 -159
- package/knowledge/task-resolver.js +1 -1230
- package/package.json +18 -2
- package/src/actions/boxPlots/edit.js +45 -298
- package/src/actions/boxPlots/options.js +46 -77
- package/src/actions/boxPlots/resolve.js +1 -1
- package/src/actions/charts/bar.js +3 -0
- package/src/actions/charts/heatmap.js +73 -83
- package/src/actions/charts/index.js +1 -1
- package/src/actions/charts/parallel.js +35 -1
- package/src/actions/charts/shared.js +20 -0
- package/src/actions/composition/actions.js +46 -49
- package/src/actions/data/bin2d.js +105 -2
- package/src/actions/data/box.js +17 -17
- package/src/actions/data/density.js +42 -78
- package/src/actions/data/gradientProfile.js +22 -52
- package/src/actions/data/horizon.js +16 -41
- package/src/actions/data/index.js +10 -10
- package/src/actions/data/interval.js +16 -38
- package/src/actions/data/intervalEdit.js +55 -0
- package/src/actions/data/regression.js +7 -17
- package/src/actions/data/shared.js +47 -0
- package/src/actions/data/timeUnit.js +14 -38
- package/src/actions/data/window.js +14 -38
- package/src/actions/distributions/revision.js +154 -34
- package/src/actions/encodings/angle.js +9 -10
- package/src/actions/encodings/appearance.js +17 -51
- package/src/actions/encodings/density/resolve.js +3 -1
- package/src/actions/encodings/density.js +1 -15
- package/src/actions/encodings/horizon/resolve.js +13 -3
- package/src/actions/encodings/horizon.js +8 -7
- package/src/actions/encodings/index.js +9 -9
- package/src/actions/encodings/offset.js +41 -45
- package/src/actions/encodings/parallel.js +9 -10
- package/src/actions/encodings/pathOrder.js +6 -13
- package/src/actions/encodings/position/apply.js +30 -0
- package/src/actions/encodings/position/policies/arc.js +23 -2
- package/src/actions/encodings/position/policies/index.js +4 -4
- package/src/actions/encodings/position/policies/line.js +47 -17
- package/src/actions/encodings/position/resolve.js +36 -7
- package/src/actions/encodings/ranged.js +18 -23
- package/src/actions/encodings/remove.js +15 -25
- package/src/actions/encodings/ruleAppearance.js +9 -24
- package/src/actions/encodings/shared.js +37 -0
- package/src/actions/encodings/strokeDash.js +8 -23
- package/src/actions/encodings/text.js +9 -10
- package/src/actions/errorBands/create.js +105 -39
- package/src/actions/errorBands/edit.js +89 -93
- package/src/actions/errorBands/index.js +1 -2
- package/src/actions/errorBars/create.js +212 -30
- package/src/actions/errorBars/edit.js +91 -48
- package/src/actions/errorBars/index.js +1 -2
- package/src/actions/facets/actions.js +45 -69
- package/src/actions/facets/derive.js +38 -53
- package/src/actions/facets/replay.js +0 -1
- package/src/actions/gradientPlots/components.js +59 -48
- package/src/actions/gradientPlots/edit.js +35 -216
- package/src/actions/gradientPlots/index.js +11 -10
- package/src/actions/gradientPlots/materialize.js +21 -35
- package/src/actions/gradientPlots/options.js +5 -7
- package/src/actions/gradientPlots/paint.js +9 -6
- package/src/actions/gradientPlots/resolve.js +1 -1
- package/src/actions/guides/axes/index.js +3 -3
- package/src/actions/guides/axes/labels.js +68 -26
- package/src/actions/guides/axes/lines.js +22 -2
- package/src/actions/guides/axes/policy.js +28 -8
- package/src/actions/guides/axes/ticks.js +27 -9
- package/src/actions/guides/axes/titles.js +113 -65
- package/src/actions/guides/grids/resolve.js +14 -0
- package/src/actions/guides/guides.js +2 -4
- package/src/actions/guides/index.js +2 -2
- package/src/actions/guides/legends/categorical/actions.js +44 -68
- package/src/actions/guides/legends/categorical/components.js +6 -1
- package/src/actions/guides/legends/categorical/index.js +2 -2
- package/src/actions/guides/legends/categorical/layout.js +148 -175
- package/src/actions/guides/legends/categorical/recipes.js +5 -0
- package/src/actions/guides/legends/categorical/resolve.js +8 -1
- package/src/actions/guides/legends/continuous/common.js +117 -66
- package/src/actions/guides/legends/continuous/gradient.js +38 -37
- package/src/actions/guides/legends/continuous/interval.js +97 -76
- package/src/actions/guides/legends/continuous/opacity.js +28 -38
- package/src/actions/guides/legends/edit.js +14 -1
- package/src/actions/guides/legends/index.js +1 -1
- package/src/actions/guides/legends/lane.js +2 -1
- package/src/actions/guides/legends/remove.js +8 -0
- package/src/actions/guides/legends/size.js +36 -43
- package/src/actions/guides/legends/strokeWidth.js +20 -26
- package/src/actions/guides/polar/axes/labels.js +17 -1
- package/src/actions/guides/polar/axes/shared.js +7 -1
- package/src/actions/guides/polar/axes/titles.js +19 -2
- package/src/actions/guides/polar/grids.js +4 -0
- package/src/actions/guides/polar/resolve.js +6 -0
- package/src/actions/index.js +13 -13
- package/src/actions/intervals/resolve.js +87 -117
- package/src/actions/marks/arc/actions.js +31 -36
- package/src/actions/marks/area/actions.js +23 -31
- package/src/actions/marks/index.js +6 -6
- package/src/actions/marks/line/actions.js +33 -52
- package/src/actions/marks/line/materialize.js +7 -5
- package/src/actions/marks/point/materialize.js +38 -16
- package/src/actions/marks/remove.js +21 -0
- package/src/actions/marks/rule/actions.js +79 -54
- package/src/actions/marks/shared.js +8 -4
- package/src/actions/marks/text/actions.js +14 -6
- package/src/actions/marks/text/layout.js +21 -45
- package/src/actions/marks/tick/actions.js +22 -21
- package/src/actions/primitives/createGraphics.js +4 -0
- package/src/actions/primitives/editGraphics.js +4 -0
- package/src/actions/primitives/index.js +3 -3
- package/src/actions/primitives/semantic.js +1 -1
- package/src/actions/primitives/semanticValidation/index.js +2 -2
- package/src/actions/primitives/semanticValidation/layer.js +1 -1
- package/src/actions/regression/edit.js +3 -43
- package/src/actions/scales/consumers/families.js +24 -4
- package/src/actions/scales/consumers/index.js +1 -1
- package/src/actions/scales/consumers/seriesLayout.js +17 -0
- package/src/actions/scales/definitions.js +100 -103
- package/src/actions/scales/materialize.js +5 -0
- package/src/actions/selection/actions.js +79 -121
- package/src/actions/titles/actions.js +48 -94
- package/src/actions/titles/resolve.js +14 -27
- package/src/actions/violinPlots/create.js +37 -44
- package/src/core/textMetrics.js +74 -37
- package/src/core/validation.js +18 -0
- package/src/core/vocabulary.js +2 -2
- package/src/grammar/aggregate.js +48 -28
- package/src/grammar/arcs.js +170 -32
- package/src/grammar/areaSeries.js +14 -16
- package/src/grammar/bin2d.js +37 -23
- package/src/grammar/boxPlot.js +14 -13
- package/src/grammar/categoricalDensity.js +14 -14
- package/src/grammar/categoryOrder.js +8 -14
- package/src/grammar/curveCommands.js +87 -20
- package/src/grammar/density.js +162 -141
- package/src/grammar/facets/index.js +14 -0
- package/src/grammar/facets/scales.js +7 -4
- package/src/grammar/gradientProfile.js +12 -15
- package/src/grammar/histogram.js +145 -83
- package/src/grammar/horizon.js +60 -23
- package/src/grammar/interval.js +14 -13
- package/src/grammar/lineSeries.js +91 -61
- package/src/grammar/numeric.js +290 -0
- package/src/grammar/paint.js +3 -4
- package/src/grammar/palettes.js +21 -32
- package/src/grammar/pathCommands.js +6 -0
- package/src/grammar/polarPaths.js +5 -5
- package/src/grammar/positionCompatibility.js +1 -1
- package/src/grammar/regression/derive.js +48 -9
- package/src/grammar/regression/models.js +248 -69
- package/src/grammar/regression/parameters.js +8 -0
- package/src/grammar/rules.js +2 -0
- package/src/grammar/scales/color.js +35 -26
- package/src/grammar/scales/continuous.js +71 -24
- package/src/grammar/scales/definition.js +1 -1
- package/src/grammar/scales/discretized.js +42 -12
- package/src/grammar/scales/fields.js +21 -4
- package/src/grammar/scales/ordinal.js +139 -60
- package/src/grammar/scales/temporal.js +40 -11
- package/src/grammar/scales/transformed.js +199 -52
- package/src/grammar/schemas/graphicBounds.js +270 -79
- package/src/grammar/seriesLayout.js +50 -18
- package/src/grammar/ticks.js +123 -53
- package/src/grammar/timeUnit.js +18 -8
- package/src/grammar/transforms.js +4 -1
- package/src/grammar/window.js +70 -57
- package/src/index.js +1 -1
- package/src/layout/canvas.js +4 -8
- package/src/layout/composition.js +39 -40
- package/src/layout/facets.js +55 -30
- package/src/layout/labels.js +91 -15
- package/src/layout/legend.js +22 -20
- package/src/layout/legendLane.js +54 -40
- package/src/layout/title.js +7 -7
- package/src/materialization/bars/aggregate.js +14 -40
- package/src/materialization/bars/grouped.js +7 -18
- package/src/materialization/bars/histogram.js +2 -19
- package/src/materialization/bars/ranged.js +20 -15
- package/src/materialization/bars/resolve.js +21 -0
- package/src/materialization/facetGuides/legacyCategorical.js +9 -2
- package/src/materialization/facetGuides/placement.js +49 -19
- package/src/materialization/facetGuides/preparation.js +35 -6
- package/src/materialization/facets.js +42 -28
- package/src/materialization/guides/resources.js +2 -1
- package/src/materialization/marks/capabilities.js +15 -4
- package/src/materialization/marks/index.js +29 -6
- package/src/materialization/rowEncoding.js +57 -1
- package/src/materialization/scales/policies/bar.js +61 -102
- package/src/materialization/scales/policies/binnedPosition.js +34 -0
- package/src/materialization/scales/policies/offset.js +54 -0
- package/src/materialization/scales/policies/series.js +13 -7
- package/src/materialization/scales/resolve.js +6 -9
- package/src/materialization/selection/items/arc.js +16 -2
- package/src/materialization/selection/items/bar.js +4 -2
- package/src/materialization/selection/items/common.js +21 -1
- package/src/materialization/selection/items/path.js +19 -2
- package/src/materialization/selection/items/point.js +4 -16
- package/src/materialization/selection/items/tick.js +13 -21
- package/src/materialization/selection/point.js +11 -4
- package/src/materialization/selection/styles.js +19 -27
- package/src/materialization/text.js +4 -1
- package/src/mcp/adapter.js +8 -3
- package/src/renderers/canvas/fill.js +2 -2
- package/src/renderers/canvas/index.js +35 -2
- package/src/renderers/canvas/native.js +160 -0
- package/src/renderers/pdf.js +14 -0
- package/src/renderers/svg.js +37 -4
- package/types/index.d.ts +3 -0
- package/types/program.d.ts +523 -131
- package/types/svg.d.ts +1 -0
- package/src/actions/errorBands/components.js +0 -81
- package/src/actions/errorBands/options.js +0 -39
- package/src/actions/errorBands/resolve.js +0 -28
- package/src/actions/errorBars/components.js +0 -62
- package/src/actions/errorBars/options.js +0 -58
- package/src/actions/errorBars/resolve.js +0 -25
|
@@ -14,6 +14,7 @@ import { resolveGraphicBounds } from "../../../layout/canvas.js";
|
|
|
14
14
|
import { canMaterializeText } from "../../../materialization/marks/index.js";
|
|
15
15
|
import { resolveTextGraphicEntries } from "../../../materialization/text.js";
|
|
16
16
|
import { findLayer, resolveEligibleLayer } from "../../../selectors/layers.js";
|
|
17
|
+
import { editMarkGraphic } from "../shared.js";
|
|
17
18
|
|
|
18
19
|
const LAYOUT_OPTIONS = Object.freeze([
|
|
19
20
|
"target", "axis", "padding", "maxDisplacement", "bounds", "leader"
|
|
@@ -170,42 +171,22 @@ function materializeLeaders(program, layer, config, resolved) {
|
|
|
170
171
|
if (config.leader === false) return { program: next, count: 0 };
|
|
171
172
|
const leaders = resolved.items.map(resolveLabelLeader).filter(Boolean);
|
|
172
173
|
if (leaders.length === 0) return { program: next, count: 0 };
|
|
173
|
-
next = next
|
|
174
|
-
.createGraphics({
|
|
174
|
+
next = next.createGraphics({
|
|
175
175
|
id: config.leaderId,
|
|
176
176
|
type: "line",
|
|
177
177
|
length: leaders.length,
|
|
178
178
|
...leaderPlacement(next, layer)
|
|
179
|
-
})
|
|
180
|
-
.editGraphics({
|
|
181
|
-
target: config.leaderId,
|
|
182
|
-
property: "x1",
|
|
183
|
-
value: leaders.map(line => line.x1)
|
|
184
|
-
})
|
|
185
|
-
.editGraphics({
|
|
186
|
-
target: config.leaderId,
|
|
187
|
-
property: "y1",
|
|
188
|
-
value: leaders.map(line => line.y1)
|
|
189
|
-
})
|
|
190
|
-
.editGraphics({
|
|
191
|
-
target: config.leaderId,
|
|
192
|
-
property: "x2",
|
|
193
|
-
value: leaders.map(line => line.x2)
|
|
194
|
-
})
|
|
195
|
-
.editGraphics({
|
|
196
|
-
target: config.leaderId,
|
|
197
|
-
property: "y2",
|
|
198
|
-
value: leaders.map(line => line.y2)
|
|
199
179
|
});
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
180
|
+
next = editMarkGraphic(next, config.leaderId, {
|
|
181
|
+
x1: leaders.map(line => line.x1),
|
|
182
|
+
y1: leaders.map(line => line.y1),
|
|
183
|
+
x2: leaders.map(line => line.x2),
|
|
184
|
+
y2: leaders.map(line => line.y2),
|
|
185
|
+
stroke: config.leader.stroke,
|
|
186
|
+
strokeWidth: config.leader.strokeWidth,
|
|
187
|
+
strokeDash: leaders.map(() => config.leader.strokeDash),
|
|
188
|
+
opacity: config.leader.opacity
|
|
189
|
+
});
|
|
209
190
|
return { program: next, count: leaders.length };
|
|
210
191
|
}
|
|
211
192
|
|
|
@@ -237,17 +218,10 @@ const materializeLabelLayout = action(
|
|
|
237
218
|
padding: config.padding,
|
|
238
219
|
maxDisplacement: config.maxDisplacement
|
|
239
220
|
});
|
|
240
|
-
next = next
|
|
241
|
-
.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
value: resolved.items.map(item => item.x)
|
|
245
|
-
})
|
|
246
|
-
.editGraphics({
|
|
247
|
-
target: id,
|
|
248
|
-
property: "y",
|
|
249
|
-
value: resolved.items.map(item => item.y)
|
|
250
|
-
});
|
|
221
|
+
next = editMarkGraphic(next, id, {
|
|
222
|
+
x: resolved.items.map(item => item.x),
|
|
223
|
+
y: resolved.items.map(item => item.y)
|
|
224
|
+
});
|
|
251
225
|
const leaders = materializeLeaders(next, layer, config, resolved);
|
|
252
226
|
next = leaders.program;
|
|
253
227
|
return next._withMaterializationConfig(["labelLayouts", id], {
|
|
@@ -315,7 +289,9 @@ const removeLabelLayout = action(
|
|
|
315
289
|
);
|
|
316
290
|
|
|
317
291
|
export function registerTextLabelLayoutActions(ProgramClass) {
|
|
318
|
-
ProgramClass.prototype
|
|
319
|
-
|
|
320
|
-
|
|
292
|
+
Object.assign(ProgramClass.prototype, {
|
|
293
|
+
layoutLabels,
|
|
294
|
+
removeLabelLayout,
|
|
295
|
+
materializeLabelLayout
|
|
296
|
+
});
|
|
321
297
|
}
|
|
@@ -21,6 +21,7 @@ import { rematerializeHighlightBaseline } from "../lifecycle.js";
|
|
|
21
21
|
import {
|
|
22
22
|
applyLayeredMarkInheritance,
|
|
23
23
|
assertMarkAvailable,
|
|
24
|
+
editMarkGraphic,
|
|
24
25
|
materializeInheritedMark,
|
|
25
26
|
resolveLayeredMarkInheritance,
|
|
26
27
|
resolveMarkData,
|
|
@@ -28,12 +29,11 @@ import {
|
|
|
28
29
|
validateMarkOptions
|
|
29
30
|
} from "../shared.js";
|
|
30
31
|
|
|
31
|
-
const
|
|
32
|
-
"
|
|
33
|
-
]);
|
|
34
|
-
const EDIT_OPTIONS = Object.freeze([
|
|
35
|
-
"target", "length", "stroke", "strokeWidth", "opacity"
|
|
32
|
+
const APPEARANCE_OPTIONS = Object.freeze([
|
|
33
|
+
"length", "stroke", "strokeWidth", "opacity"
|
|
36
34
|
]);
|
|
35
|
+
const CREATE_OPTIONS = Object.freeze(["id", "data", ...APPEARANCE_OPTIONS]);
|
|
36
|
+
const EDIT_OPTIONS = Object.freeze(["target", ...APPEARANCE_OPTIONS]);
|
|
37
37
|
const REMATERIALIZE_OPTIONS = Object.freeze(["id"]);
|
|
38
38
|
|
|
39
39
|
export const DEFAULT_TICK_CONFIG = Object.freeze({
|
|
@@ -116,8 +116,7 @@ export const createTickMark = action(
|
|
|
116
116
|
._withMarkConfig(id, DEFAULT_TICK_CONFIG);
|
|
117
117
|
const materialized = materializeInheritedMark(created, id);
|
|
118
118
|
const appearance = Object.fromEntries(
|
|
119
|
-
|
|
120
|
-
.filter(property => Object.hasOwn(args, property))
|
|
119
|
+
APPEARANCE_OPTIONS.filter(property => Object.hasOwn(args, property))
|
|
121
120
|
.map(property => [property, config[property]])
|
|
122
121
|
);
|
|
123
122
|
return Object.keys(appearance).length === 0
|
|
@@ -133,8 +132,7 @@ export const editTickMark = action(
|
|
|
133
132
|
},
|
|
134
133
|
function (args = {}) {
|
|
135
134
|
validateMarkOptions(args, EDIT_OPTIONS, "editTickMark");
|
|
136
|
-
|
|
137
|
-
if (!editable.some(property => Object.hasOwn(args, property))) {
|
|
135
|
+
if (!APPEARANCE_OPTIONS.some(property => Object.hasOwn(args, property))) {
|
|
138
136
|
throw new Error(
|
|
139
137
|
"editTickMark requires length, stroke, strokeWidth, or opacity."
|
|
140
138
|
);
|
|
@@ -206,20 +204,23 @@ export const rematerializeTickMark = action(
|
|
|
206
204
|
})
|
|
207
205
|
);
|
|
208
206
|
|
|
209
|
-
return this
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
207
|
+
return editMarkGraphic(this, id, {
|
|
208
|
+
length: segments.length,
|
|
209
|
+
x1: segments.map(item => item.x1),
|
|
210
|
+
y1: segments.map(item => item.y1),
|
|
211
|
+
x2: segments.map(item => item.x2),
|
|
212
|
+
y2: segments.map(item => item.y2),
|
|
213
|
+
stroke: config.stroke,
|
|
214
|
+
strokeWidth: config.strokeWidth,
|
|
215
|
+
opacity: config.opacity
|
|
216
|
+
});
|
|
218
217
|
}
|
|
219
218
|
);
|
|
220
219
|
|
|
221
220
|
export function registerTickMarkActions(ProgramClass) {
|
|
222
|
-
ProgramClass.prototype
|
|
223
|
-
|
|
224
|
-
|
|
221
|
+
Object.assign(ProgramClass.prototype, {
|
|
222
|
+
createTickMark,
|
|
223
|
+
editTickMark,
|
|
224
|
+
rematerializeTickMark
|
|
225
|
+
});
|
|
225
226
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { action } from "../../core/action.js";
|
|
2
2
|
import { validateUserId } from "../../core/identifiers.js";
|
|
3
3
|
import { freezeOwned } from "../../core/immutable.js";
|
|
4
|
+
import { validateGeneratedItemLimit } from "../../core/validation.js";
|
|
4
5
|
import {
|
|
5
6
|
isDrawableGraphicType,
|
|
6
7
|
isGraphicContainerType,
|
|
@@ -115,6 +116,9 @@ const createGraphics = action(
|
|
|
115
116
|
if (length !== undefined && (!Number.isInteger(length) || length < 0)) {
|
|
116
117
|
throw new TypeError("createGraphics length must be a non-negative integer.");
|
|
117
118
|
}
|
|
119
|
+
if (length !== undefined) {
|
|
120
|
+
validateGeneratedItemLimit(length, "createGraphics length");
|
|
121
|
+
}
|
|
118
122
|
if (validatedType === "collection" && length !== undefined) {
|
|
119
123
|
throw new Error("Heterogeneous collections use editGraphics items instead of length.");
|
|
120
124
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { action } from "../../core/action.js";
|
|
2
2
|
import { cloneAndFreeze, freezeOwned, isPlainObject } from "../../core/immutable.js";
|
|
3
|
+
import { validateGeneratedItemLimit } from "../../core/validation.js";
|
|
3
4
|
import {
|
|
4
5
|
isPrimitiveDrawableGraphicType,
|
|
5
6
|
isStructuralGraphicType,
|
|
@@ -44,6 +45,7 @@ function validateCollectionItem(item, ownerId, index) {
|
|
|
44
45
|
|
|
45
46
|
function replaceCollectionItems(value, id) {
|
|
46
47
|
if (!Array.isArray(value)) throw new TypeError("collection.items must be an array.");
|
|
48
|
+
validateGeneratedItemLimit(value.length, "collection.items length");
|
|
47
49
|
return freezeOwned(value.map((item, index) => validateCollectionItem(item, id, index)));
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -82,6 +84,7 @@ function editItems(owner, property, value, id) {
|
|
|
82
84
|
if (!Number.isInteger(value) || value < 0) {
|
|
83
85
|
throw new TypeError("Graphic collection length must be a non-negative integer.");
|
|
84
86
|
}
|
|
87
|
+
validateGeneratedItemLimit(value, "Graphic collection length");
|
|
85
88
|
const items = owner.items.slice(0, value);
|
|
86
89
|
for (let index = items.length; index < value; index += 1) {
|
|
87
90
|
if (owner.type === "collection") {
|
|
@@ -187,6 +190,7 @@ const editGraphics = action(
|
|
|
187
190
|
if (!Number.isInteger(value) || value < 0) {
|
|
188
191
|
throw new TypeError("Graphic collection length must be a non-negative integer.");
|
|
189
192
|
}
|
|
193
|
+
validateGeneratedItemLimit(value, "Graphic collection length");
|
|
190
194
|
updated = freezeOwned({
|
|
191
195
|
type: owner.type,
|
|
192
196
|
items: freezeOwned(Array.from({ length: value }, (_, index) => freezeOwned({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { createSemanticValueValidator } from "./semanticValidation/index.js";
|
|
1
2
|
import { isPlainObject } from "../../core/immutable.js";
|
|
2
3
|
import { validateBin2DTransform } from "../../grammar/bin2d.js";
|
|
3
|
-
import { registerCreateGraphicsAction } from "./createGraphics.js";
|
|
4
|
-
import { registerEditGraphicsAction } from "./editGraphics.js";
|
|
5
4
|
import { registerSemanticPrimitiveAction } from "./semantic.js";
|
|
5
|
+
import { registerEditGraphicsAction } from "./editGraphics.js";
|
|
6
|
+
import { registerCreateGraphicsAction } from "./createGraphics.js";
|
|
6
7
|
import { createSemanticPrimitiveAction } from "./semanticAction.js";
|
|
7
|
-
import { createSemanticValueValidator } from "./semanticValidation/index.js";
|
|
8
8
|
|
|
9
9
|
function validateBasicDatasetTransforms(value) {
|
|
10
10
|
if (!Array.isArray(value) || value.length !== 1 || !isPlainObject(value[0])) {
|
|
@@ -21,7 +21,7 @@ export function registerSemanticPrimitiveAction(ProgramClass) {
|
|
|
21
21
|
const validateSemanticValue = createSemanticValueValidator({
|
|
22
22
|
validateDatasetTransforms,
|
|
23
23
|
validateParallel,
|
|
24
|
-
sourceMarkTypes: ["point", "bar", "rule", "rect"]
|
|
24
|
+
sourceMarkTypes: ["point", "bar", "rule", "rect", "arc"]
|
|
25
25
|
});
|
|
26
26
|
ProgramClass.prototype.editSemantic =
|
|
27
27
|
createSemanticPrimitiveAction(validateSemanticValue);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { validateCoordinateType } from "../../../grammar/coordinates.js";
|
|
2
|
+
import { validateScaleSemanticValue } from "./scale.js";
|
|
2
3
|
import { validateDatasetSemanticValue } from "./dataset.js";
|
|
3
|
-
import { validateGuideSemanticValue } from "./guide.js";
|
|
4
4
|
import { validateLayerSemanticValue } from "./layer.js";
|
|
5
|
-
import {
|
|
5
|
+
import { validateGuideSemanticValue } from "./guide.js";
|
|
6
6
|
import { validateNonEmptySemanticString } from "./shared.js";
|
|
7
7
|
|
|
8
8
|
export function createSemanticValueValidator({
|
|
@@ -12,7 +12,8 @@ import { validateCurveInterpolation } from "../../grammar/curveCommands.js";
|
|
|
12
12
|
import { planDerivedDataRevision } from
|
|
13
13
|
"../../materialization/dataProvenance.js";
|
|
14
14
|
import { findLayer } from "../../selectors/layers.js";
|
|
15
|
-
import {
|
|
15
|
+
import { removeOwnedMark } from "../marks/remove.js";
|
|
16
|
+
import { removeOwnedColorLegends } from "../guides/legends/remove.js";
|
|
16
17
|
import { requireRegressionField } from "./resolve.js";
|
|
17
18
|
|
|
18
19
|
const OPTIONS = Object.freeze([
|
|
@@ -118,46 +119,6 @@ function resolveParameters(previous, args) {
|
|
|
118
119
|
return normalizeRegressionParameters(raw);
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
function removeOwnedColorLegends(program, target) {
|
|
122
|
-
const kinds = Object.entries(program.guideConfigs.legend ?? {})
|
|
123
|
-
.filter(([kind, config]) =>
|
|
124
|
-
config?.target === target &&
|
|
125
|
-
(
|
|
126
|
-
config.channels?.includes("color") ||
|
|
127
|
-
["gradient", "interval"].includes(kind)
|
|
128
|
-
)
|
|
129
|
-
)
|
|
130
|
-
.map(([kind]) => kind);
|
|
131
|
-
return kinds.length === 0 ? program : removeLegendKinds(program, kinds);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function removeBand(program, id) {
|
|
135
|
-
const selectionIds = Object.entries(
|
|
136
|
-
program.materializationConfigs.selections ?? {}
|
|
137
|
-
).filter(([, config]) => config.target === id).map(([selection]) => selection);
|
|
138
|
-
let next = program;
|
|
139
|
-
for (const [highlight, config] of Object.entries(
|
|
140
|
-
program.materializationConfigs.highlights ?? {}
|
|
141
|
-
)) {
|
|
142
|
-
if (config.target === id || selectionIds.includes(config.selection)) {
|
|
143
|
-
next = next._withoutMaterializationConfig(["highlights", highlight]);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
for (const selection of selectionIds) {
|
|
147
|
-
next = next._withoutMaterializationConfig(["selections", selection]);
|
|
148
|
-
}
|
|
149
|
-
return next
|
|
150
|
-
.editSemantic({ property: `layer[${id}]`, remove: true })
|
|
151
|
-
.editGraphics({ target: id, remove: true })
|
|
152
|
-
._withoutMaterializationConfig(["marks", id])
|
|
153
|
-
._withContext({
|
|
154
|
-
...(program.context.currentMark === id ? { currentMark: undefined } : {}),
|
|
155
|
-
...(selectionIds.includes(program.context.currentSelection)
|
|
156
|
-
? { currentSelection: undefined }
|
|
157
|
-
: {})
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
122
|
function regressionColorScale(owner, current, groupBy) {
|
|
162
123
|
if (groupBy === undefined || groupBy === current.groupBy) {
|
|
163
124
|
return current.colorScale;
|
|
@@ -331,7 +292,7 @@ export const editRegression = action(
|
|
|
331
292
|
|
|
332
293
|
let bandId = current.bandId;
|
|
333
294
|
if (hadBand && !wantsBand) {
|
|
334
|
-
next =
|
|
295
|
+
next = removeOwnedMark(next, current.bandId);
|
|
335
296
|
bandId = undefined;
|
|
336
297
|
} else if (!hadBand && wantsBand) {
|
|
337
298
|
bandId = `${owner.id}RegressionBands`;
|
|
@@ -400,7 +361,6 @@ export const editRegression = action(
|
|
|
400
361
|
}
|
|
401
362
|
});
|
|
402
363
|
};
|
|
403
|
-
if (changesStatistics || hadBand !== wantsBand) applyEdit(this);
|
|
404
364
|
return applyEdit(this);
|
|
405
365
|
}
|
|
406
366
|
);
|
|
@@ -5,14 +5,27 @@ import {
|
|
|
5
5
|
} from "../../../grammar/bars/policy.js";
|
|
6
6
|
import {
|
|
7
7
|
deriveLineSeries,
|
|
8
|
-
deriveLineSeriesFieldValues
|
|
8
|
+
deriveLineSeriesFieldValues,
|
|
9
|
+
resolveLineBins
|
|
9
10
|
} from "../../../grammar/lineSeries.js";
|
|
10
11
|
import { isAggregate } from "../../../grammar/aggregate.js";
|
|
11
12
|
import {
|
|
12
13
|
resolveRectConsumerValues
|
|
13
14
|
} from "../../../materialization/rect.js";
|
|
15
|
+
import { findScale } from "./common.js";
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
function lineDerivationOptions(program, consumer, dataset) {
|
|
18
|
+
const x = consumer.layer.encoding?.x;
|
|
19
|
+
if (x?.bin === undefined) return undefined;
|
|
20
|
+
const bins = resolveLineBins(
|
|
21
|
+
dataset.values,
|
|
22
|
+
consumer.layer,
|
|
23
|
+
findScale(program, x.scale)
|
|
24
|
+
);
|
|
25
|
+
return { xBinBoundaries: bins.boundaries };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function resolveMarkFamilyConsumerValues(program, consumer, dataset) {
|
|
16
29
|
if (consumer.layer.mark?.type === "rect") {
|
|
17
30
|
return {
|
|
18
31
|
matched: true,
|
|
@@ -25,10 +38,17 @@ export function resolveMarkFamilyConsumerValues(consumer, dataset) {
|
|
|
25
38
|
}
|
|
26
39
|
if (
|
|
27
40
|
consumer.layer.mark?.type === "line" &&
|
|
28
|
-
(
|
|
41
|
+
((consumer.layer.encoding?.x !== undefined &&
|
|
42
|
+
isAggregate(consumer.layer.encoding?.y?.aggregate) &&
|
|
43
|
+
!(consumer.channel === "x" &&
|
|
44
|
+
consumer.layer.encoding?.x?.bin !== undefined)) ||
|
|
29
45
|
consumer.channel === "strokeWidth")
|
|
30
46
|
) {
|
|
31
|
-
const derived = deriveLineSeries(
|
|
47
|
+
const derived = deriveLineSeries(
|
|
48
|
+
dataset.values,
|
|
49
|
+
consumer.layer,
|
|
50
|
+
lineDerivationOptions(program, consumer, dataset)
|
|
51
|
+
);
|
|
32
52
|
return {
|
|
33
53
|
matched: true,
|
|
34
54
|
values: consumer.channel === "strokeWidth"
|
|
@@ -35,7 +35,7 @@ export function resolveConsumerValues(program, consumer) {
|
|
|
35
35
|
if (isDirectCategoricalConsumer(consumer)) {
|
|
36
36
|
return readConsumerFieldValues(program, consumer, dataset, scale);
|
|
37
37
|
}
|
|
38
|
-
const family = resolveMarkFamilyConsumerValues(consumer, dataset);
|
|
38
|
+
const family = resolveMarkFamilyConsumerValues(program, consumer, dataset);
|
|
39
39
|
return family.matched
|
|
40
40
|
? family.values
|
|
41
41
|
: readConsumerFieldValues(program, consumer, dataset, scale);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { deriveBarAggregates } from "../../../grammar/bars/aggregate.js";
|
|
2
|
+
import { validateGeneratedItemLimit } from "../../../core/validation.js";
|
|
2
3
|
import {
|
|
3
4
|
BAR_GRAINS,
|
|
4
5
|
resolveBarChannels,
|
|
@@ -72,6 +73,10 @@ function resolveHistogramPartitions(program, consumer) {
|
|
|
72
73
|
const colorScale = findScale(program, colorEncoding.scale);
|
|
73
74
|
const colorValues = readNominalField(dataset.values, colorEncoding.field);
|
|
74
75
|
const colorDomain = resolveOrdinalDomain(colorScale.domain, colorValues);
|
|
76
|
+
validateGeneratedItemLimit(
|
|
77
|
+
(bins.boundaries.length - 1) * colorDomain.length,
|
|
78
|
+
"Histogram layout cell count"
|
|
79
|
+
);
|
|
75
80
|
const colorIndex = new Map(colorDomain.map((value, index) => [value, index]));
|
|
76
81
|
const partitions = bins.boundaries.slice(0, -1).map(() =>
|
|
77
82
|
colorDomain.map(() => 0)
|
|
@@ -109,6 +114,10 @@ function resolveAggregatePartitions(program, consumer) {
|
|
|
109
114
|
const colorScale = findScale(program, colorEncoding.scale);
|
|
110
115
|
const colorValues = readNominalField(dataset.values, colorEncoding.field);
|
|
111
116
|
const colorDomain = resolveOrdinalDomain(colorScale.domain, colorValues);
|
|
117
|
+
validateGeneratedItemLimit(
|
|
118
|
+
categoryDomain.length * colorDomain.length,
|
|
119
|
+
"Aggregate layout cell count"
|
|
120
|
+
);
|
|
112
121
|
const cells = new Map(derived.values.map(value => [
|
|
113
122
|
JSON.stringify([value[channels.category], value.color]),
|
|
114
123
|
value[channels.measure]
|
|
@@ -131,6 +140,10 @@ function resolveAreaPartitions(program, consumer) {
|
|
|
131
140
|
layer.encoding?.x !== undefined
|
|
132
141
|
) {
|
|
133
142
|
const derived = deriveCenteredAreaSeries(dataset.values, layer);
|
|
143
|
+
validateGeneratedItemLimit(
|
|
144
|
+
derived.series[0].values.length * derived.series.length,
|
|
145
|
+
"Area layout cell count"
|
|
146
|
+
);
|
|
134
147
|
return Array.from({ length: derived.series[0].values.length }, (_, index) =>
|
|
135
148
|
derived.series.map(series => series.values[index].y)
|
|
136
149
|
);
|
|
@@ -142,6 +155,10 @@ function resolveAreaPartitions(program, consumer) {
|
|
|
142
155
|
if (derived.series.some(series => series.values.length !== sampleCount)) {
|
|
143
156
|
throw new Error(`Area mark "${layer.id}" requires aligned layout samples.`);
|
|
144
157
|
}
|
|
158
|
+
validateGeneratedItemLimit(
|
|
159
|
+
sampleCount * derived.series.length,
|
|
160
|
+
"Area layout cell count"
|
|
161
|
+
);
|
|
145
162
|
return Array.from({ length: sampleCount }, (_, index) =>
|
|
146
163
|
derived.series.map(series => series.values[index].y)
|
|
147
164
|
);
|