ggaction 0.0.15 → 0.0.17
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 +88 -0
- package/README.md +23 -2
- package/knowledge/action-cards.json +1 -1
- package/knowledge/intent-taxonomy.json +1 -1
- package/knowledge/mcp-resources.json +1 -1
- package/knowledge/task-packet.schema.json +1 -1
- package/knowledge/task-resolver.js +1 -1
- package/package.json +40 -7
- package/src/BasicChartProgram.js +3 -1
- package/src/ChartProgram.js +2 -0
- package/src/accessibility.js +157 -0
- package/src/actions/boxPlots/components.js +6 -8
- package/src/actions/boxPlots/create.js +4 -5
- package/src/actions/boxPlots/edit.js +3 -4
- package/src/actions/boxPlots/materialize.js +1 -1
- package/src/actions/canvas/actions.js +3 -3
- package/src/actions/canvas/fitting.js +1 -1
- package/src/actions/categoryOrder/index.js +6 -8
- package/src/actions/charts/area.js +1 -1
- package/src/actions/charts/bar.js +1 -1
- package/src/actions/charts/beeswarm.js +1 -1
- package/src/actions/charts/density.js +1 -1
- package/src/actions/charts/ecdf.js +2 -2
- package/src/actions/charts/endpoints.js +4 -4
- package/src/actions/charts/heatmap.js +1 -1
- package/src/actions/charts/histogram.js +1 -1
- package/src/actions/charts/horizon.js +1 -1
- package/src/actions/charts/interval-regression.js +2 -2
- package/src/actions/charts/line.js +1 -1
- package/src/actions/charts/parallel.js +1 -1
- package/src/actions/charts/pie.js +1 -1
- package/src/actions/charts/polar.js +2 -2
- package/src/actions/charts/radar.js +1 -1
- package/src/actions/charts/radial.js +2 -2
- package/src/actions/charts/raincloud.js +2 -2
- package/src/actions/charts/rug-strip.js +2 -2
- package/src/actions/charts/scatter.js +1 -1
- package/src/actions/composition/actions.js +20 -24
- package/src/actions/coordinates/actions.js +1 -1
- package/src/actions/coordinates/edit.js +1 -1
- package/src/actions/data/basicBin2d.js +4 -5
- package/src/actions/data/bin.js +3 -3
- package/src/actions/data/bin2d.js +6 -8
- package/src/actions/data/bin2dMaterialize.js +4 -5
- package/src/actions/data/box.js +4 -4
- package/src/actions/data/complete.js +2 -2
- package/src/actions/data/computed.js +2 -2
- package/src/actions/data/create.js +23 -17
- package/src/actions/data/density.js +4 -4
- package/src/actions/data/derived.js +25 -15
- package/src/actions/data/ecdf.js +2 -2
- package/src/actions/data/edit.js +54 -29
- package/src/actions/data/filter.js +29 -24
- package/src/actions/data/fold.js +2 -2
- package/src/actions/data/gradientProfile.js +2 -2
- package/src/actions/data/horizon.js +2 -2
- package/src/actions/data/impute.js +2 -2
- package/src/actions/data/index.js +58 -54
- package/src/actions/data/interval.js +4 -2
- package/src/actions/data/intervalEdit.js +26 -18
- package/src/actions/data/normalize.js +2 -2
- package/src/actions/data/regression.js +9 -7
- package/src/actions/data/revise.js +80 -0
- package/src/actions/data/revisionBindings.js +13 -33
- package/src/actions/data/shared.js +30 -2
- package/src/actions/data/sort.js +21 -0
- package/src/actions/data/stack.js +2 -2
- package/src/actions/data/summary.js +3 -3
- package/src/actions/data/timeUnit.js +2 -2
- package/src/actions/data/window.js +2 -2
- package/src/actions/encodings/angle.js +5 -2
- package/src/actions/encodings/appearance.js +10 -6
- package/src/actions/encodings/barWidth.js +1 -1
- package/src/actions/encodings/channels.js +2 -2
- package/src/actions/encodings/color/continuous.js +4 -1
- package/src/actions/encodings/color/index.js +5 -2
- package/src/actions/encodings/density.js +2 -2
- package/src/actions/encodings/histogram.js +1 -1
- package/src/actions/encodings/horizon.js +6 -8
- package/src/actions/encodings/offset.js +6 -3
- package/src/actions/encodings/parallel.js +4 -5
- package/src/actions/encodings/pathOrder.js +6 -11
- package/src/actions/encodings/position/index.js +4 -4
- package/src/actions/encodings/position/resolve.js +6 -1
- package/src/actions/encodings/ranged.js +11 -6
- package/src/actions/encodings/remove.js +4 -5
- package/src/actions/encodings/ruleAppearance.js +5 -2
- package/src/actions/encodings/seriesLayout.js +1 -1
- package/src/actions/encodings/stroke.js +5 -2
- package/src/actions/encodings/strokeDash.js +8 -3
- package/src/actions/encodings/text.js +7 -2
- package/src/actions/errorBands/create.js +11 -17
- package/src/actions/errorBands/edit.js +13 -131
- package/src/actions/errorBars/create.js +8 -13
- package/src/actions/errorBars/edit.js +10 -121
- package/src/actions/facets/actions.js +30 -16
- package/src/actions/facets/derive.js +8 -2
- package/src/actions/facets/guides.js +4 -5
- package/src/actions/facets/replay.js +4 -5
- package/src/actions/gradientPlots/components.js +5 -6
- package/src/actions/gradientPlots/create.js +4 -5
- package/src/actions/gradientPlots/edit.js +4 -5
- package/src/actions/gradientPlots/materialize.js +2 -2
- package/src/actions/gradientPlots/rebind.js +4 -5
- package/src/actions/guides/axes/axes.js +23 -4
- package/src/actions/guides/axes/axis.js +2 -2
- package/src/actions/guides/axes/edit.js +2 -2
- package/src/actions/guides/axes/labels.js +9 -9
- package/src/actions/guides/axes/lines.js +9 -7
- package/src/actions/guides/axes/parallel/lifecycle.js +13 -13
- package/src/actions/guides/axes/parallel.js +5 -5
- package/src/actions/guides/axes/remove.js +4 -4
- package/src/actions/guides/axes/tickGroups.js +4 -4
- package/src/actions/guides/axes/ticks.js +13 -4
- package/src/actions/guides/axes/titles.js +10 -10
- package/src/actions/guides/grids/grid.js +18 -29
- package/src/actions/guides/guides.js +1 -1
- package/src/actions/guides/legends/blocks.js +1 -1
- package/src/actions/guides/legends/categorical/actions.js +4 -4
- package/src/actions/guides/legends/categorical/components.js +38 -33
- package/src/actions/guides/legends/categorical/layout.js +1 -1
- package/src/actions/guides/legends/categorical/symbols.js +27 -30
- package/src/actions/guides/legends/continuous/common.js +46 -8
- package/src/actions/guides/legends/continuous/gradient.js +89 -155
- package/src/actions/guides/legends/continuous/interval.js +13 -13
- package/src/actions/guides/legends/continuous/opacity.js +30 -79
- package/src/actions/guides/legends/continuous/stroke.js +22 -322
- package/src/actions/guides/legends/edit.js +1 -1
- package/src/actions/guides/legends/focused.js +5 -5
- package/src/actions/guides/legends/lane.js +6 -6
- package/src/actions/guides/legends/remove.js +4 -5
- package/src/actions/guides/legends/size.js +21 -82
- package/src/actions/guides/legends/strokeWidth.js +17 -77
- package/src/actions/guides/polar/axes/facade.js +4 -4
- package/src/actions/guides/polar/axes/labels.js +5 -5
- package/src/actions/guides/polar/axes/lines.js +9 -15
- package/src/actions/guides/polar/axes/ticks.js +9 -15
- package/src/actions/guides/polar/axes/titles.js +5 -5
- package/src/actions/guides/polar/grids.js +11 -13
- package/src/actions/index.js +2 -0
- package/src/actions/intervals/revision.js +126 -0
- package/src/actions/marks/arc/actions.js +3 -3
- package/src/actions/marks/area/actions.js +4 -4
- package/src/actions/marks/bar/create.js +9 -2
- package/src/actions/marks/bar/edit.js +13 -6
- package/src/actions/marks/bar/materialize.js +12 -38
- package/src/actions/marks/line/actions.js +3 -3
- package/src/actions/marks/point/create.js +9 -2
- package/src/actions/marks/point/edit.js +13 -6
- package/src/actions/marks/point/jitter.js +6 -8
- package/src/actions/marks/point/materialize.js +20 -26
- package/src/actions/marks/point/packing.js +6 -8
- package/src/actions/marks/rect/actions.js +26 -11
- package/src/actions/marks/references.js +8 -10
- package/src/actions/marks/remove.js +5 -49
- package/src/actions/marks/rule/actions.js +28 -12
- package/src/actions/marks/text/actions.js +30 -11
- package/src/actions/marks/text/layout.js +12 -20
- package/src/actions/marks/text/removal.js +1 -1
- package/src/actions/marks/text/selection.js +4 -5
- package/src/actions/marks/tick/actions.js +26 -11
- package/src/actions/primitives/createGraphics.js +5 -4
- package/src/actions/primitives/editGraphics.js +5 -4
- package/src/actions/primitives/graphicProperties.js +6 -0
- package/src/actions/primitives/semantic.js +10 -3
- package/src/actions/primitives/semanticAction.js +44 -7
- package/src/actions/primitives/semanticValidation/dataset.js +14 -4
- package/src/actions/primitives/semanticValidation/layer.js +22 -2
- package/src/actions/primitives/semanticValidation/scale.js +6 -0
- package/src/actions/regression/components.js +10 -14
- package/src/actions/regression/create.js +28 -8
- package/src/actions/regression/edit.js +50 -16
- package/src/actions/regression/follow.js +22 -0
- package/src/actions/resources/remove.js +12 -11
- package/src/actions/scales/channels.js +11 -11
- package/src/actions/scales/consumers/common.js +2 -1
- package/src/actions/scales/create.js +3 -2
- package/src/actions/scales/definitions.js +1 -1
- package/src/actions/scales/edit.js +2 -2
- package/src/actions/scales/materialize.js +1 -1
- package/src/actions/scales/offset.js +2 -2
- package/src/actions/scales/parallel.js +2 -2
- package/src/actions/scales/patch.js +1 -1
- package/src/actions/scales/preview.js +28 -1
- package/src/actions/scales/quantitativeColor.js +4 -5
- package/src/actions/selection/actions.js +25 -36
- package/src/actions/textMetrics/index.js +56 -0
- package/src/actions/theme/actions.js +2 -2
- package/src/actions/theme/reconcile.js +67 -121
- package/src/actions/titles/actions.js +8 -8
- package/src/actions/titles/resolve.js +3 -3
- package/src/actions/violinPlots/create.js +1 -1
- package/src/actions/violinPlots/edit.js +1 -1
- package/src/core/action.js +109 -36
- package/src/core/diagnostics.js +16 -0
- package/src/core/extensionRegistry.js +27 -0
- package/src/core/font.js +18 -0
- package/src/core/identifiers.js +5 -4
- package/src/core/immutable.js +10 -3
- package/src/core/optionRequirements.js +8 -0
- package/src/core/programState.js +6 -2
- package/src/core/resourceReferences.js +15 -6
- package/src/core/textMetricProfile.js +28 -0
- package/src/core/textMetrics.js +24 -3
- package/src/core/validation.js +22 -10
- package/src/diagnostics.js +1 -0
- package/src/grammar/bin.js +39 -10
- package/src/grammar/datasetSchema.js +386 -0
- package/src/grammar/density.js +53 -5
- package/src/grammar/filter.js +133 -39
- package/src/grammar/impute.js +3 -2
- package/src/grammar/interval.js +32 -1
- package/src/grammar/itemMissing.js +59 -0
- package/src/grammar/regression/derive.js +57 -16
- package/src/grammar/regression/index.js +1 -0
- package/src/grammar/regression/models.js +51 -22
- package/src/grammar/regression/parameters.js +56 -4
- package/src/grammar/scales/definition.js +7 -0
- package/src/grammar/scales/types.js +8 -0
- package/src/grammar/schemas/graphicBounds.js +11 -11
- package/src/grammar/schemas/semanticPath.js +3 -2
- package/src/grammar/sort.js +88 -0
- package/src/grammar/summary.js +117 -19
- package/src/grammar/transformTopology.js +1 -0
- package/src/grammar/transforms.js +21 -11
- package/src/inspection.js +495 -0
- package/src/inspectionDescriptors.js +3 -0
- package/src/layout/labels.js +11 -10
- package/src/layout/legend.js +4 -4
- package/src/layout/legendItems.js +6 -6
- package/src/layout/text.js +10 -9
- package/src/layout/title.js +9 -9
- package/src/materialization/bars/resolve.js +4 -2
- package/src/materialization/facetGuides/placement.js +1 -1
- package/src/materialization/facetGuides/preparation.js +1 -1
- package/src/materialization/facetHeaders.js +11 -10
- package/src/materialization/guides/layout.js +3 -3
- package/src/materialization/revisionIdentity.js +19 -0
- package/src/materialization/scaleGuideDependencies.js +10 -0
- package/src/materialization/scales/resolve.js +67 -4
- package/src/materialization/selection/items/common.js +1 -1
- package/src/materialization/text.js +6 -4
- package/src/materialization/typography.js +31 -0
- package/src/mcp/cli.js +5 -3
- package/src/persistence/codec.js +65 -0
- package/src/persistence/validation.js +185 -0
- package/src/persistence.js +147 -0
- package/src/renderers/canvas/index.js +5 -4
- package/src/renderers/nativeBackend.js +10 -0
- package/src/renderers/options.js +13 -0
- package/src/renderers/pdf.js +25 -54
- package/src/renderers/png.js +22 -17
- package/src/renderers/svg.js +10 -14
- package/src/renderers/text.js +1 -11
- package/src/selectors/coordinates.js +3 -1
- package/src/selectors/datasets.js +8 -6
- package/src/selectors/layers.js +6 -4
- package/src/selectors/markOwners.js +46 -0
- package/src/selectors/scales.js +6 -4
- package/src/theme/defaults.js +2 -1
- package/src/version.js +2 -0
- package/types/accessibility.d.ts +37 -0
- package/types/basic.d.ts +4 -2
- package/types/diagnostics.d.ts +15 -0
- package/types/index.d.ts +5 -0
- package/types/inspection.d.ts +17 -0
- package/types/pdf.d.ts +9 -0
- package/types/persistence.d.ts +7 -0
- package/types/png.d.ts +9 -0
- package/types/program.d.ts +181 -28
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { ownedChildren, ownership } from "../../selectors/markOwners.js";
|
|
1
2
|
import { isSourceOwnedText } from "../../grammar/text.js";
|
|
2
|
-
import {
|
|
3
|
+
import { closedAction } from "../../core/action.js";
|
|
3
4
|
import { validateUserId } from "../../core/identifiers.js";
|
|
4
|
-
|
|
5
|
+
|
|
5
6
|
import { findDataset } from "../../selectors/datasets.js";
|
|
6
7
|
import { findLayer } from "../../selectors/layers.js";
|
|
7
8
|
import { applyDetachedScaleRematerialization } from "../../materialization/dependencies.js";
|
|
@@ -23,50 +24,6 @@ const REMOVE_AXIS = Object.freeze({
|
|
|
23
24
|
radius: "removeRadialAxis"
|
|
24
25
|
});
|
|
25
26
|
|
|
26
|
-
function ownedChildren(program, id) {
|
|
27
|
-
const config = program.markConfigs[id] ?? {};
|
|
28
|
-
return [
|
|
29
|
-
config.errorBar?.lowerCapId,
|
|
30
|
-
config.errorBar?.upperCapId,
|
|
31
|
-
config.errorBand?.lowerBoundaryId,
|
|
32
|
-
config.errorBand?.upperBoundaryId,
|
|
33
|
-
config.regression?.bandId,
|
|
34
|
-
config.regression?.lineId,
|
|
35
|
-
config.boxPlot?.whiskerId,
|
|
36
|
-
config.boxPlot?.medianId,
|
|
37
|
-
config.boxPlot?.outlierId,
|
|
38
|
-
config.gradientPlot?.centerId,
|
|
39
|
-
config.intervalPlot?.intervalId,
|
|
40
|
-
config.endpointPlot?.roles?.stemId,
|
|
41
|
-
config.endpointPlot?.roles?.startId,
|
|
42
|
-
config.endpointPlot?.roles?.connectorId,
|
|
43
|
-
...(config.raincloudPlot?.ownedChildIds ?? [])
|
|
44
|
-
].concat(
|
|
45
|
-
program.semanticSpec.layers
|
|
46
|
-
.filter(layer => layer.source === id)
|
|
47
|
-
.map(layer => layer.id)
|
|
48
|
-
).concat(
|
|
49
|
-
program.semanticSpec.layers
|
|
50
|
-
.filter(layer =>
|
|
51
|
-
program.markConfigs[layer.id]?.statisticalReference?.source === id
|
|
52
|
-
)
|
|
53
|
-
.map(layer => layer.id)
|
|
54
|
-
).filter(child => child !== undefined && child !== id && findLayer(program, child) !== undefined);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function ownership(program) {
|
|
58
|
-
const ownerByChild = new Map();
|
|
59
|
-
for (const layer of program.semanticSpec.layers) {
|
|
60
|
-
for (const child of ownedChildren(program, layer.id)) {
|
|
61
|
-
if (program.markConfigs[child]?.statisticalReference !== undefined) {
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
ownerByChild.set(child, layer.id);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return ownerByChild;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
27
|
function resolveOwner(program, requested) {
|
|
71
28
|
const ownerByChild = ownership(program);
|
|
72
29
|
const stable = program.semanticSpec.layers.filter(
|
|
@@ -248,10 +205,9 @@ function cleanupPositionGuides(program, scales) {
|
|
|
248
205
|
return next;
|
|
249
206
|
}
|
|
250
207
|
|
|
251
|
-
export const removeMark =
|
|
252
|
-
{ op: "removeMark", description: "Remove one stable mark owner and owned state." },
|
|
208
|
+
export const removeMark = /* @__PURE__ */ closedAction(
|
|
209
|
+
{ op: "removeMark", description: "Remove one stable mark owner and owned state." }, OPTIONS,
|
|
253
210
|
function (args = {}) {
|
|
254
|
-
validateKeys(args, OPTIONS, "removeMark");
|
|
255
211
|
const owner = resolveOwner(this, args.target);
|
|
256
212
|
const ids = collectClosure(this, owner.id);
|
|
257
213
|
const external = externalMarkReferences(this, ids);
|
|
@@ -39,13 +39,15 @@ import {
|
|
|
39
39
|
requestedStrokeDetails,
|
|
40
40
|
STROKE_STYLE_PROPERTIES
|
|
41
41
|
} from "../../../grammar/strokeStyle.js";
|
|
42
|
+
import { applyItemMissingPolicy, validateItemMissing } from
|
|
43
|
+
"../../../grammar/itemMissing.js";
|
|
42
44
|
|
|
43
45
|
const APPEARANCE_OPTIONS = Object.freeze([
|
|
44
46
|
"stroke", "strokeWidth", "strokeDash", "opacity",
|
|
45
47
|
...STROKE_STYLE_PROPERTIES
|
|
46
48
|
]);
|
|
47
|
-
const CREATE_OPTIONS = Object.freeze(["id", "data", ...APPEARANCE_OPTIONS]);
|
|
48
|
-
const EDIT_OPTIONS = Object.freeze(["target", ...APPEARANCE_OPTIONS]);
|
|
49
|
+
const CREATE_OPTIONS = Object.freeze(["id", "data", "missing", ...APPEARANCE_OPTIONS]);
|
|
50
|
+
const EDIT_OPTIONS = Object.freeze(["target", "missing", ...APPEARANCE_OPTIONS]);
|
|
49
51
|
const REMATERIALIZE_OPTIONS = Object.freeze(["id"]);
|
|
50
52
|
const SPAN_OPTIONS = Object.freeze(["id", "orientation", "size"]);
|
|
51
53
|
const DEFAULT_RULE_CONFIG = Object.freeze({
|
|
@@ -66,10 +68,11 @@ function requireRule(program, id) {
|
|
|
66
68
|
if (layer?.mark?.type !== "rule") {
|
|
67
69
|
throw new Error(`Unknown rule mark "${id}".`);
|
|
68
70
|
}
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
71
|
+
const sourceDataset = findDataset(program, layer.data);
|
|
72
|
+
if (sourceDataset === undefined) {
|
|
71
73
|
throw new Error(`Rule mark "${id}" requires an existing dataset.`);
|
|
72
74
|
}
|
|
75
|
+
const dataset = applyItemMissingPolicy(layer, sourceDataset);
|
|
73
76
|
const graphic = program.graphicSpec.objects[id];
|
|
74
77
|
if (graphic?.type !== "line" || graphic.items === undefined) {
|
|
75
78
|
throw new Error(`Rule mark "${id}" requires line collection graphics.`);
|
|
@@ -92,7 +95,7 @@ function validateEndpointBindings(layer) {
|
|
|
92
95
|
}
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
const createRuleMark = action(
|
|
98
|
+
const createRuleMark = /* @__PURE__ */ action(
|
|
96
99
|
{
|
|
97
100
|
op: "createRuleMark",
|
|
98
101
|
description: "Create a semantic rule mark and empty line collection."
|
|
@@ -118,6 +121,12 @@ const createRuleMark = action(
|
|
|
118
121
|
let created = this
|
|
119
122
|
.editSemantic({ property: `layer[${id}].mark.type`, value: "rule" })
|
|
120
123
|
.editSemantic({ property: `layer[${id}].data`, value: data });
|
|
124
|
+
if (Object.hasOwn(args, "missing")) {
|
|
125
|
+
created = created.editSemantic({
|
|
126
|
+
property: `layer[${id}].mark.missing`,
|
|
127
|
+
value: validateItemMissing(args.missing, "Rule missing")
|
|
128
|
+
});
|
|
129
|
+
}
|
|
121
130
|
created = applyLayeredMarkInheritance(created, id, inherited);
|
|
122
131
|
created = created
|
|
123
132
|
.createGraphics({
|
|
@@ -142,7 +151,7 @@ const createRuleMark = action(
|
|
|
142
151
|
}
|
|
143
152
|
);
|
|
144
153
|
|
|
145
|
-
const editRuleMark = action(
|
|
154
|
+
const editRuleMark = /* @__PURE__ */ action(
|
|
146
155
|
{ op: "editRuleMark", description: "Edit constant rule appearance through its encoding owners." },
|
|
147
156
|
function (args = {}) {
|
|
148
157
|
validateMarkOptions(args, EDIT_OPTIONS, "editRuleMark");
|
|
@@ -154,11 +163,18 @@ const editRuleMark = action(
|
|
|
154
163
|
label: "rule mark"
|
|
155
164
|
});
|
|
156
165
|
const appearance = planRuleAppearance(args, layer);
|
|
157
|
-
if (appearance.length === 0 && Object.keys(strokeDetails).length === 0
|
|
158
|
-
|
|
166
|
+
if (appearance.length === 0 && Object.keys(strokeDetails).length === 0 &&
|
|
167
|
+
!Object.hasOwn(args, "missing")) {
|
|
168
|
+
throw new Error("editRuleMark requires missing or an appearance change.");
|
|
159
169
|
}
|
|
160
|
-
const
|
|
161
|
-
|
|
170
|
+
const semantic = Object.hasOwn(args, "missing")
|
|
171
|
+
? this.editSemantic({
|
|
172
|
+
property: `layer[${layer.id}].mark.missing`,
|
|
173
|
+
value: validateItemMissing(args.missing, "Rule missing")
|
|
174
|
+
})
|
|
175
|
+
: this;
|
|
176
|
+
const configured = semantic._withMarkConfig(layer.id, {
|
|
177
|
+
...semantic.markConfigs[layer.id],
|
|
162
178
|
...strokeDetails
|
|
163
179
|
});
|
|
164
180
|
const materialized = appearance.length === 0
|
|
@@ -168,7 +184,7 @@ const editRuleMark = action(
|
|
|
168
184
|
}
|
|
169
185
|
);
|
|
170
186
|
|
|
171
|
-
const rematerializeRuleMark = action(
|
|
187
|
+
const rematerializeRuleMark = /* @__PURE__ */ action(
|
|
172
188
|
{
|
|
173
189
|
op: "rematerializeRuleMark",
|
|
174
190
|
description: "Recompute concrete rule endpoints and appearance."
|
|
@@ -377,7 +393,7 @@ const rematerializeRuleMark = action(
|
|
|
377
393
|
}
|
|
378
394
|
);
|
|
379
395
|
|
|
380
|
-
export const materializeRuleSpan = action(
|
|
396
|
+
export const materializeRuleSpan = /* @__PURE__ */ action(
|
|
381
397
|
{
|
|
382
398
|
op: "materializeRuleSpan",
|
|
383
399
|
description: "Materialize a fixed-pixel span around a rule anchor."
|
|
@@ -39,13 +39,14 @@ import {
|
|
|
39
39
|
} from "../../charts/shared.js";
|
|
40
40
|
import { resolveMarkGraphicPlacement } from
|
|
41
41
|
"../../../materialization/graphicHierarchy.js";
|
|
42
|
+
import { validateItemMissing } from "../../../grammar/itemMissing.js";
|
|
42
43
|
|
|
43
44
|
const STYLE_OPTIONS = Object.freeze([
|
|
44
45
|
"fill", "opacity", "fontSize", "fontFamily", "fontWeight",
|
|
45
46
|
"align", "baseline", "rotation", "dx", "dy"
|
|
46
47
|
]);
|
|
47
|
-
const CREATE_OPTIONS = Object.freeze(["id", "data", "source", "text", ...STYLE_OPTIONS]);
|
|
48
|
-
const EDIT_OPTIONS = Object.freeze(["target", ...STYLE_OPTIONS]);
|
|
48
|
+
const CREATE_OPTIONS = Object.freeze(["id", "data", "source", "text", "missing", ...STYLE_OPTIONS]);
|
|
49
|
+
const EDIT_OPTIONS = Object.freeze(["target", "missing", ...STYLE_OPTIONS]);
|
|
49
50
|
const REMATERIALIZE_OPTIONS = Object.freeze(["id", "replayLayout"]);
|
|
50
51
|
|
|
51
52
|
function sourceMatchesData(program, layer, requestedData) {
|
|
@@ -125,7 +126,7 @@ function requireTextLayer(program, requested, operation) {
|
|
|
125
126
|
});
|
|
126
127
|
}
|
|
127
128
|
|
|
128
|
-
const createTextMark = action(
|
|
129
|
+
const createTextMark = /* @__PURE__ */ action(
|
|
129
130
|
{
|
|
130
131
|
op: "createTextMark",
|
|
131
132
|
description: "Create a semantic text annotation layer."
|
|
@@ -139,6 +140,9 @@ const createTextMark = action(
|
|
|
139
140
|
operation: "createTextMark"
|
|
140
141
|
});
|
|
141
142
|
const inherited = resolveTextInheritance(this, args);
|
|
143
|
+
if (Object.hasOwn(args, "missing") && inherited?.source !== undefined) {
|
|
144
|
+
throw new Error("Text missing policy requires a row-backed text mark, not source-owned labels.");
|
|
145
|
+
}
|
|
142
146
|
const { data } = resolveMarkData(this, {
|
|
143
147
|
...args,
|
|
144
148
|
...(args.data === undefined && inherited?.data !== undefined
|
|
@@ -150,6 +154,12 @@ const createTextMark = action(
|
|
|
150
154
|
let next = this
|
|
151
155
|
.editSemantic({ property: `layer[${id}].mark.type`, value: "text" })
|
|
152
156
|
.editSemantic({ property: `layer[${id}].data`, value: data });
|
|
157
|
+
if (Object.hasOwn(args, "missing")) {
|
|
158
|
+
next = next.editSemantic({
|
|
159
|
+
property: `layer[${id}].mark.missing`,
|
|
160
|
+
value: validateItemMissing(args.missing, "Text missing")
|
|
161
|
+
});
|
|
162
|
+
}
|
|
153
163
|
if (inherited?.source !== undefined) {
|
|
154
164
|
next = next.editSemantic({
|
|
155
165
|
property: `layer[${id}].source`,
|
|
@@ -254,7 +264,7 @@ function resolveAnnotationBinding(program, args) {
|
|
|
254
264
|
};
|
|
255
265
|
}
|
|
256
266
|
|
|
257
|
-
const createAnnotation = action(
|
|
267
|
+
const createAnnotation = /* @__PURE__ */ action(
|
|
258
268
|
{
|
|
259
269
|
op: "createAnnotation",
|
|
260
270
|
description: "Create text at a final mark, data, or plot anchor."
|
|
@@ -327,7 +337,7 @@ const createAnnotation = action(
|
|
|
327
337
|
}
|
|
328
338
|
);
|
|
329
339
|
|
|
330
|
-
const createMarkLabels = action(
|
|
340
|
+
const createMarkLabels = /* @__PURE__ */ action(
|
|
331
341
|
{
|
|
332
342
|
op: "createMarkLabels",
|
|
333
343
|
description: "Create final-item text labels attached to an existing mark."
|
|
@@ -412,7 +422,7 @@ const createMarkLabels = action(
|
|
|
412
422
|
}
|
|
413
423
|
);
|
|
414
424
|
|
|
415
|
-
const rematerializeTextMark = action(
|
|
425
|
+
const rematerializeTextMark = /* @__PURE__ */ action(
|
|
416
426
|
{
|
|
417
427
|
op: "rematerializeTextMark",
|
|
418
428
|
description: "Recompute concrete text content, anchors, and typography."
|
|
@@ -458,27 +468,36 @@ const rematerializeTextMark = action(
|
|
|
458
468
|
}
|
|
459
469
|
);
|
|
460
470
|
|
|
461
|
-
const editTextMark = action(
|
|
471
|
+
const editTextMark = /* @__PURE__ */ action(
|
|
462
472
|
{
|
|
463
473
|
op: "editTextMark",
|
|
464
474
|
description: "Edit text typography, alignment, rotation, and offsets."
|
|
465
475
|
},
|
|
466
476
|
function (args = {}) {
|
|
467
477
|
validateMarkOptions(args, EDIT_OPTIONS, "editTextMark");
|
|
468
|
-
if (!STYLE_OPTIONS.some(option => Object.hasOwn(args, option))) {
|
|
478
|
+
if (!["missing", ...STYLE_OPTIONS].some(option => Object.hasOwn(args, option))) {
|
|
469
479
|
throw new Error("editTextMark requires at least one editable property.");
|
|
470
480
|
}
|
|
471
481
|
const layer = requireTextLayer(this, args.target, "editTextMark");
|
|
472
|
-
|
|
482
|
+
if (Object.hasOwn(args, "missing") && layer.source !== undefined) {
|
|
483
|
+
throw new Error("Text missing policy requires a row-backed text mark, not source-owned labels.");
|
|
484
|
+
}
|
|
485
|
+
const semantic = Object.hasOwn(args, "missing")
|
|
486
|
+
? this.editSemantic({
|
|
487
|
+
property: `layer[${layer.id}].mark.missing`,
|
|
488
|
+
value: validateItemMissing(args.missing, "Text missing")
|
|
489
|
+
})
|
|
490
|
+
: this;
|
|
491
|
+
const next = semantic._withMarkConfig(
|
|
473
492
|
layer.id,
|
|
474
493
|
{
|
|
475
494
|
...normalizeTextMarkConfig(
|
|
476
495
|
args,
|
|
477
|
-
|
|
496
|
+
semantic.markConfigs[layer.id] ?? DEFAULT_TEXT_MARK
|
|
478
497
|
),
|
|
479
498
|
fillExplicit: Object.hasOwn(args, "fill")
|
|
480
499
|
? true
|
|
481
|
-
:
|
|
500
|
+
: semantic.markConfigs[layer.id]?.fillExplicit ?? false
|
|
482
501
|
}
|
|
483
502
|
);
|
|
484
503
|
return canMaterializeText(next, layer)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { action } from "../../../core/action.js";
|
|
1
|
+
import { action, closedAction } from "../../../core/action.js";
|
|
2
2
|
import { validateUserId } from "../../../core/identifiers.js";
|
|
3
3
|
import { validateOptionObject } from "../../../core/validation.js";
|
|
4
4
|
import { DEFAULT_TEXT_MARK } from "../../../grammar/text.js";
|
|
@@ -221,22 +221,17 @@ function placementLeaderItems(program, layer) {
|
|
|
221
221
|
sourceY: entry.anchor.y,
|
|
222
222
|
dx: properties.x - entry.anchor.x,
|
|
223
223
|
dy: properties.y - entry.anchor.y,
|
|
224
|
-
bounds: resolveTextBounds(properties)
|
|
224
|
+
bounds: resolveTextBounds(properties, program.materializationConfigs.textMetrics)
|
|
225
225
|
};
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
const materializeMarkLabelPlacement =
|
|
229
|
+
const materializeMarkLabelPlacement = /* @__PURE__ */ closedAction(
|
|
230
230
|
{
|
|
231
231
|
op: "materializeMarkLabelPlacement",
|
|
232
232
|
description: "Reconcile semantic attached-label placement leaders."
|
|
233
|
-
},
|
|
233
|
+
}, MATERIALIZE_PLACEMENT_OPTIONS,
|
|
234
234
|
function (args = {}) {
|
|
235
|
-
validateOptionObject(
|
|
236
|
-
args,
|
|
237
|
-
MATERIALIZE_PLACEMENT_OPTIONS,
|
|
238
|
-
"materializeMarkLabelPlacement"
|
|
239
|
-
);
|
|
240
235
|
const id = validateUserId(args.id, "Attached label id");
|
|
241
236
|
const layer = findLayer(this, id);
|
|
242
237
|
if (!isSourceOwnedText(layer)) {
|
|
@@ -267,13 +262,12 @@ const materializeMarkLabelPlacement = action(
|
|
|
267
262
|
}
|
|
268
263
|
);
|
|
269
264
|
|
|
270
|
-
const materializeLabelLayout =
|
|
265
|
+
const materializeLabelLayout = /* @__PURE__ */ closedAction(
|
|
271
266
|
{
|
|
272
267
|
op: "materializeLabelLayout",
|
|
273
268
|
description: "Resolve concrete label positions and optional leader lines."
|
|
274
|
-
},
|
|
269
|
+
}, MATERIALIZE_OPTIONS,
|
|
275
270
|
function (args = {}) {
|
|
276
|
-
validateOptionObject(args, MATERIALIZE_OPTIONS, "materializeLabelLayout");
|
|
277
271
|
const id = validateUserId(args.id, "Text mark id");
|
|
278
272
|
const rematerializeBase = args.rematerializeBase ?? true;
|
|
279
273
|
if (typeof rematerializeBase !== "boolean") {
|
|
@@ -294,7 +288,7 @@ const materializeLabelLayout = action(
|
|
|
294
288
|
axis: config.axis,
|
|
295
289
|
padding: config.padding,
|
|
296
290
|
maxDisplacement: config.maxDisplacement
|
|
297
|
-
});
|
|
291
|
+
}, next.materializationConfigs.textMetrics);
|
|
298
292
|
next = editMarkGraphic(next, id, {
|
|
299
293
|
x: resolved.items.map(item => item.x),
|
|
300
294
|
y: resolved.items.map(item => item.y)
|
|
@@ -326,13 +320,12 @@ const materializeLabelLayout = action(
|
|
|
326
320
|
}
|
|
327
321
|
);
|
|
328
322
|
|
|
329
|
-
const layoutLabels =
|
|
323
|
+
const layoutLabels = /* @__PURE__ */ closedAction(
|
|
330
324
|
{
|
|
331
325
|
op: "layoutLabels",
|
|
332
326
|
description: "Assign deterministic collision-aware layout to a text mark."
|
|
333
|
-
},
|
|
327
|
+
}, TEXT_LABEL_LAYOUT_OPTIONS,
|
|
334
328
|
function (args = {}) {
|
|
335
|
-
validateOptionObject(args, TEXT_LABEL_LAYOUT_OPTIONS, "layoutLabels");
|
|
336
329
|
const layer = requireCompleteText(this, args.target, "layoutLabels");
|
|
337
330
|
const policy = normalizePolicy(args);
|
|
338
331
|
const placement = this.markConfigs[layer.id]?.labelAuthoring?.placement;
|
|
@@ -358,7 +351,7 @@ const layoutLabels = action(
|
|
|
358
351
|
}
|
|
359
352
|
);
|
|
360
353
|
|
|
361
|
-
const editMarkLabelPlacement = action(
|
|
354
|
+
const editMarkLabelPlacement = /* @__PURE__ */ action(
|
|
362
355
|
{
|
|
363
356
|
op: "editMarkLabelPlacement",
|
|
364
357
|
description: "Replace or reset semantic placement for one attached label layer."
|
|
@@ -418,13 +411,12 @@ const editMarkLabelPlacement = action(
|
|
|
418
411
|
}
|
|
419
412
|
);
|
|
420
413
|
|
|
421
|
-
const removeLabelLayout =
|
|
414
|
+
const removeLabelLayout = /* @__PURE__ */ closedAction(
|
|
422
415
|
{
|
|
423
416
|
op: "removeLabelLayout",
|
|
424
417
|
description: "Remove label layout and restore semantic base text positions."
|
|
425
|
-
},
|
|
418
|
+
}, REMOVE_OPTIONS,
|
|
426
419
|
function (args = {}) {
|
|
427
|
-
validateOptionObject(args, REMOVE_OPTIONS, "removeLabelLayout");
|
|
428
420
|
const layer = requireConfiguredText(this, args.target);
|
|
429
421
|
const config = this.materializationConfigs.labelLayouts[layer.id];
|
|
430
422
|
return removeLeaderGraphic(
|
|
@@ -140,7 +140,7 @@ function removeLabelState(program, plan) {
|
|
|
140
140
|
return Object.keys(context).length === 0 ? next : next._withContext(context);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
export const removeMarkLabels = action(
|
|
143
|
+
export const removeMarkLabels = /* @__PURE__ */ action(
|
|
144
144
|
{
|
|
145
145
|
op: "removeMarkLabels",
|
|
146
146
|
description: "Remove attached label layers while preserving their source mark."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { closedAction } from "../../../core/action.js";
|
|
2
2
|
import { validateUserId } from "../../../core/identifiers.js";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import { normalizeLabelSelectionEdit } from
|
|
5
5
|
"../../../grammar/markLabelSelection.js";
|
|
6
6
|
import { isSourceOwnedText } from "../../../grammar/text.js";
|
|
@@ -40,13 +40,12 @@ function validateSelectionSource(program, source, requested) {
|
|
|
40
40
|
resolveMarkSelection(program, source, definition.selector);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const editMarkLabelSelection =
|
|
43
|
+
const editMarkLabelSelection = /* @__PURE__ */ closedAction(
|
|
44
44
|
{
|
|
45
45
|
op: "editMarkLabelSelection",
|
|
46
46
|
description: "Replace the final-item membership requested by an attached label."
|
|
47
|
-
},
|
|
47
|
+
}, OPTIONS,
|
|
48
48
|
function (args = {}) {
|
|
49
|
-
validateOptionObject(args, OPTIONS, "editMarkLabelSelection");
|
|
50
49
|
if (!Object.hasOwn(args, "target")) {
|
|
51
50
|
throw new Error("editMarkLabelSelection requires target.");
|
|
52
51
|
}
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
requestedStrokeDetails,
|
|
22
22
|
STROKE_STYLE_PROPERTIES
|
|
23
23
|
} from "../../../grammar/strokeStyle.js";
|
|
24
|
+
import { applyItemMissingPolicy, validateItemMissing } from
|
|
25
|
+
"../../../grammar/itemMissing.js";
|
|
24
26
|
import { rematerializeHighlightBaseline } from "../lifecycle.js";
|
|
25
27
|
import { rematerializeExistingLegend } from "../../encodings/shared.js";
|
|
26
28
|
import {
|
|
@@ -37,8 +39,8 @@ import {
|
|
|
37
39
|
const APPEARANCE_OPTIONS = Object.freeze([
|
|
38
40
|
"length", "stroke", "strokeWidth", "opacity", ...STROKE_STYLE_PROPERTIES
|
|
39
41
|
]);
|
|
40
|
-
const CREATE_OPTIONS = Object.freeze(["id", "data", ...APPEARANCE_OPTIONS]);
|
|
41
|
-
const EDIT_OPTIONS = Object.freeze(["target", ...APPEARANCE_OPTIONS]);
|
|
42
|
+
const CREATE_OPTIONS = Object.freeze(["id", "data", "missing", ...APPEARANCE_OPTIONS]);
|
|
43
|
+
const EDIT_OPTIONS = Object.freeze(["target", "missing", ...APPEARANCE_OPTIONS]);
|
|
42
44
|
const REMATERIALIZE_OPTIONS = Object.freeze(["id"]);
|
|
43
45
|
|
|
44
46
|
export const DEFAULT_TICK_CONFIG = Object.freeze({
|
|
@@ -88,7 +90,7 @@ function validateTickConfig(args, current = DEFAULT_TICK_CONFIG) {
|
|
|
88
90
|
};
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
export const createTickMark = action(
|
|
93
|
+
export const createTickMark = /* @__PURE__ */ action(
|
|
92
94
|
{
|
|
93
95
|
op: "createTickMark",
|
|
94
96
|
description: "Create a centered fixed-length Tick mark."
|
|
@@ -114,6 +116,12 @@ export const createTickMark = action(
|
|
|
114
116
|
let created = this
|
|
115
117
|
.editSemantic({ property: `layer[${id}].mark.type`, value: "tick" })
|
|
116
118
|
.editSemantic({ property: `layer[${id}].data`, value: data });
|
|
119
|
+
if (Object.hasOwn(args, "missing")) {
|
|
120
|
+
created = created.editSemantic({
|
|
121
|
+
property: `layer[${id}].mark.missing`,
|
|
122
|
+
value: validateItemMissing(args.missing, "Tick missing")
|
|
123
|
+
});
|
|
124
|
+
}
|
|
117
125
|
created = applyLayeredMarkInheritance(created, id, inherited)
|
|
118
126
|
.createGraphics({
|
|
119
127
|
id,
|
|
@@ -133,7 +141,7 @@ export const createTickMark = action(
|
|
|
133
141
|
}
|
|
134
142
|
);
|
|
135
143
|
|
|
136
|
-
export const editTickMark = action(
|
|
144
|
+
export const editTickMark = /* @__PURE__ */ action(
|
|
137
145
|
{
|
|
138
146
|
op: "editTickMark",
|
|
139
147
|
description: "Edit Tick length and constant line appearance."
|
|
@@ -141,9 +149,9 @@ export const editTickMark = action(
|
|
|
141
149
|
function (args = {}) {
|
|
142
150
|
validateMarkOptions(args, EDIT_OPTIONS, "editTickMark");
|
|
143
151
|
requestedStrokeDetails(args, "editTickMark");
|
|
144
|
-
if (!APPEARANCE_OPTIONS.some(property => Object.hasOwn(args, property))) {
|
|
152
|
+
if (!["missing", ...APPEARANCE_OPTIONS].some(property => Object.hasOwn(args, property))) {
|
|
145
153
|
throw new Error(
|
|
146
|
-
"editTickMark requires length, stroke, strokeWidth, or
|
|
154
|
+
"editTickMark requires length, stroke, strokeWidth, opacity, or missing."
|
|
147
155
|
);
|
|
148
156
|
}
|
|
149
157
|
const layer = resolveTick(this, args.target, "editTickMark");
|
|
@@ -152,18 +160,24 @@ export const editTickMark = action(
|
|
|
152
160
|
"editTickMark stroke conflicts with a field encoding; use encodeStroke with value to replace it."
|
|
153
161
|
);
|
|
154
162
|
}
|
|
163
|
+
const semantic = Object.hasOwn(args, "missing")
|
|
164
|
+
? this.editSemantic({
|
|
165
|
+
property: `layer[${layer.id}].mark.missing`,
|
|
166
|
+
value: validateItemMissing(args.missing, "Tick missing")
|
|
167
|
+
})
|
|
168
|
+
: this;
|
|
155
169
|
const config = validateTickConfig(args, {
|
|
156
170
|
...DEFAULT_TICK_CONFIG,
|
|
157
|
-
...
|
|
171
|
+
...semantic.markConfigs[layer.id]
|
|
158
172
|
});
|
|
159
|
-
const materialized =
|
|
173
|
+
const materialized = semantic
|
|
160
174
|
._withMarkConfig(layer.id, config)
|
|
161
175
|
.rematerializeTickMark({ id: layer.id });
|
|
162
176
|
return rematerializeExistingLegend(materialized);
|
|
163
177
|
}
|
|
164
178
|
);
|
|
165
179
|
|
|
166
|
-
export const rematerializeTickMark = action(
|
|
180
|
+
export const rematerializeTickMark = /* @__PURE__ */ action(
|
|
167
181
|
{
|
|
168
182
|
op: "rematerializeTickMark",
|
|
169
183
|
description: "Recompute concrete centered Tick endpoints and appearance."
|
|
@@ -190,10 +204,11 @@ export const rematerializeTickMark = action(
|
|
|
190
204
|
if (graphic?.type !== "line" || !Array.isArray(graphic.items)) {
|
|
191
205
|
throw new Error(`Tick mark "${id}" requires line collection graphics.`);
|
|
192
206
|
}
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
207
|
+
const sourceDataset = findDataset(this, layer.data);
|
|
208
|
+
if (sourceDataset === undefined) {
|
|
195
209
|
throw new Error(`Tick mark "${id}" requires an existing dataset.`);
|
|
196
210
|
}
|
|
211
|
+
const dataset = applyItemMissingPolicy(layer, sourceDataset);
|
|
197
212
|
if (
|
|
198
213
|
layer.encoding?.x?.scale === undefined ||
|
|
199
214
|
layer.encoding?.y?.scale === undefined
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { closedAction } from "../../core/action.js";
|
|
2
2
|
import { validateUserId } from "../../core/identifiers.js";
|
|
3
3
|
import { freezeOwned } from "../../core/immutable.js";
|
|
4
4
|
import { validateGeneratedItemLimit } from "../../core/validation.js";
|
|
@@ -100,13 +100,14 @@ function insertSibling(siblings, id, { before, after }) {
|
|
|
100
100
|
return freezeOwned(next);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
const createGraphics =
|
|
103
|
+
const createGraphics = /* @__PURE__ */ closedAction(
|
|
104
104
|
{
|
|
105
105
|
op: "createGraphics",
|
|
106
106
|
description: "Create and optionally attach a concrete graphic.",
|
|
107
107
|
scope: "any"
|
|
108
|
-
},
|
|
109
|
-
function (
|
|
108
|
+
}, ["id", "type", "length", "parent", "before", "after"],
|
|
109
|
+
function (args = {}) {
|
|
110
|
+
const { id, type, length, parent, before, after } = args;
|
|
110
111
|
if (typeof id !== "string" || !GRAPHIC_ID_PATTERN.test(id)) {
|
|
111
112
|
throw new TypeError(
|
|
112
113
|
"createGraphics requires an id containing only letters, numbers, _ or -."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { closedAction } from "../../core/action.js";
|
|
2
2
|
import { cloneAndFreeze, freezeOwned, isPlainObject } from "../../core/immutable.js";
|
|
3
3
|
import { validateGeneratedItemLimit } from "../../core/validation.js";
|
|
4
4
|
import {
|
|
@@ -162,13 +162,14 @@ function removeGraphicTree(graphicSpec, id) {
|
|
|
162
162
|
return freezeOwned({ objects: freezeOwned(objects), order });
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
const editGraphics =
|
|
165
|
+
const editGraphics = /* @__PURE__ */ closedAction(
|
|
166
166
|
{
|
|
167
167
|
op: "editGraphics",
|
|
168
168
|
description: "Replace or remove concrete graphic state.",
|
|
169
169
|
scope: "any"
|
|
170
|
-
},
|
|
171
|
-
function (
|
|
170
|
+
}, ["target", "property", "value", "remove"],
|
|
171
|
+
function (args = {}) {
|
|
172
|
+
const { target, property, value, remove = false } = args;
|
|
172
173
|
if (typeof target !== "string" || target.length === 0) {
|
|
173
174
|
throw new TypeError("editGraphics requires a non-empty target string.");
|
|
174
175
|
}
|
|
@@ -18,12 +18,19 @@ function validateParallel(property, value) {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
function fullSemanticValidator() {
|
|
22
|
+
return createSemanticValueValidator({
|
|
23
23
|
validateDatasetTransforms,
|
|
24
24
|
validateParallel,
|
|
25
25
|
sourceMarkTypes: ["point", "bar", "line", "rule", "rect", "arc"]
|
|
26
26
|
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function validateStoredSemanticValue(program, parsed, value) {
|
|
30
|
+
return fullSemanticValidator()(program, parsed, value);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function registerSemanticPrimitiveAction(ProgramClass) {
|
|
27
34
|
ProgramClass.prototype.editSemantic =
|
|
28
|
-
createSemanticPrimitiveAction(
|
|
35
|
+
createSemanticPrimitiveAction(fullSemanticValidator(), planResourceRemoval);
|
|
29
36
|
}
|