ggaction 0.0.5 → 0.0.7
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 +48 -0
- package/README.md +77 -14
- package/package.json +19 -2
- package/src/BasicChartProgram.js +10 -0
- package/src/actions/basic.js +21 -0
- package/src/actions/boxPlots/edit.js +455 -3
- package/src/actions/boxPlots/options.js +3 -3
- package/src/actions/canvas/actions.js +42 -0
- package/src/actions/canvas/index.js +5 -1
- package/src/actions/charts/basic.js +13 -0
- package/src/actions/composition/actions.js +13 -3
- package/src/actions/data/basic.js +11 -0
- package/src/actions/data/basicBin2d.js +43 -0
- package/src/actions/data/bin2d.js +138 -40
- package/src/actions/data/bin2dMaterialize.js +29 -0
- package/src/actions/data/index.js +6 -1
- package/src/actions/data/intervalEdit.js +76 -0
- package/src/actions/distributions/revision.js +326 -0
- package/src/actions/encodings/appearance.js +41 -3
- package/src/actions/encodings/basic.js +21 -0
- package/src/actions/encodings/density.js +215 -80
- package/src/actions/encodings/index.js +2 -0
- package/src/actions/encodings/position/index.js +5 -1
- package/src/actions/encodings/ranged.js +6 -2
- package/src/actions/encodings/remove.js +268 -0
- package/src/actions/errorBands/edit.js +121 -13
- package/src/actions/errorBars/edit.js +45 -8
- package/src/actions/errorBars/options.js +7 -1
- package/src/actions/facets/actions.js +136 -1
- package/src/actions/gradientPlots/edit.js +352 -4
- package/src/actions/guides/axes/edit.js +129 -47
- package/src/actions/guides/axes/index.js +10 -2
- package/src/actions/guides/basic.js +19 -0
- package/src/actions/guides/grids/grid.js +7 -3
- package/src/actions/guides/grids/index.js +1 -1
- package/src/actions/guides/legends/categorical/actions.js +19 -8
- package/src/actions/guides/legends/categorical/index.js +6 -2
- package/src/actions/guides/legends/continuous/common.js +3 -3
- package/src/actions/guides/legends/continuous/index.js +6 -2
- package/src/actions/guides/legends/edit.js +61 -3
- package/src/actions/guides/legends/remove.js +124 -23
- package/src/actions/guides/legends/strokeWidth.js +42 -14
- package/src/actions/marks/arc/actions.js +46 -14
- package/src/actions/marks/bar/index.js +5 -1
- package/src/actions/marks/basic.js +11 -0
- package/src/actions/marks/line/actions.js +5 -1
- package/src/actions/marks/line/index.js +4 -1
- package/src/actions/marks/point/edit.js +15 -3
- package/src/actions/marks/point/index.js +5 -1
- package/src/actions/marks/point/materialize.js +9 -3
- package/src/actions/marks/rect/actions.js +5 -1
- package/src/actions/marks/rect/index.js +4 -1
- package/src/actions/marks/rule/actions.js +4 -1
- package/src/actions/regression/edit.js +235 -74
- package/src/actions/scales/index.js +5 -1
- package/src/actions/selection/actions.js +122 -2
- package/src/actions/selection/index.js +6 -0
- package/src/basic.js +2 -0
- package/src/core/vocabulary.js +7 -0
- package/src/renderers/canvas/index.js +96 -60
- package/src/renderers/canvas/text.js +3 -14
- package/src/renderers/pdf.js +112 -0
- package/src/renderers/svg.js +559 -0
- package/src/renderers/text.js +11 -0
- package/types/basic.d.ts +107 -0
- package/types/index.d.ts +1 -0
- package/types/pdf.d.ts +26 -0
- package/types/program.d.ts +71 -7
- package/types/svg.d.ts +11 -0
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
resolveAppearanceScaleDefinition,
|
|
10
10
|
resolveOpacityScaleDefinition
|
|
11
11
|
} from "../scales/definitions.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
findLayer,
|
|
14
|
+
resolveEligibleLayer
|
|
15
|
+
} from "../../selectors/layers.js";
|
|
13
16
|
import { applyMaterializationPlan } from "../../materialization/dependencies.js";
|
|
14
17
|
import { planEncodingRematerialization } from "../../materialization/encodings.js";
|
|
15
18
|
import {
|
|
@@ -20,6 +23,7 @@ import {
|
|
|
20
23
|
} from "./shared.js";
|
|
21
24
|
|
|
22
25
|
const RADIUS_OPTIONS = Object.freeze(["value", "target"]);
|
|
26
|
+
const REMOVE_RADIUS_OPTIONS = Object.freeze(["target"]);
|
|
23
27
|
const OPACITY_OPTIONS = Object.freeze([
|
|
24
28
|
"value", "field", "target", "fieldType", "scale"
|
|
25
29
|
]);
|
|
@@ -129,6 +133,35 @@ const encodePointRadius = action(
|
|
|
129
133
|
}
|
|
130
134
|
);
|
|
131
135
|
|
|
136
|
+
const removePointRadius = action(
|
|
137
|
+
{
|
|
138
|
+
op: "removePointRadius",
|
|
139
|
+
description: "Remove a constant point radius and restore the theme default."
|
|
140
|
+
},
|
|
141
|
+
function (args = {}) {
|
|
142
|
+
validateOptions(args, REMOVE_RADIUS_OPTIONS, "removePointRadius");
|
|
143
|
+
const requested = args.target === undefined
|
|
144
|
+
? undefined
|
|
145
|
+
: args.target;
|
|
146
|
+
const layer = resolveEligibleLayer(this, {
|
|
147
|
+
target: requested,
|
|
148
|
+
predicate: candidate =>
|
|
149
|
+
candidate.mark?.type === "point" &&
|
|
150
|
+
this.markConfigs[candidate.id]?.radius !== undefined,
|
|
151
|
+
label: "point mark with an explicit radius"
|
|
152
|
+
});
|
|
153
|
+
const next = this
|
|
154
|
+
._withoutMaterializationConfig(["marks", layer.id, "radius"]);
|
|
155
|
+
const graphic = next.graphicSpec.objects[layer.id];
|
|
156
|
+
const baseline = graphic === undefined
|
|
157
|
+
? next
|
|
158
|
+
: graphic.type === "collection"
|
|
159
|
+
? next.editGraphics({ target: layer.id, property: "items", value: [] })
|
|
160
|
+
: next.editGraphics({ target: layer.id, property: "length", value: 0 });
|
|
161
|
+
return baseline.rematerializePointMark({ id: layer.id });
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
|
|
132
165
|
const encodeSize = action(
|
|
133
166
|
{
|
|
134
167
|
op: "encodeSize",
|
|
@@ -244,11 +277,16 @@ const encodeOpacity = action(
|
|
|
244
277
|
}
|
|
245
278
|
);
|
|
246
279
|
|
|
280
|
+
export function registerBasicAppearanceEncodingActions(ProgramClass) {
|
|
281
|
+
ProgramClass.prototype.encodeSize = encodeSize;
|
|
282
|
+
ProgramClass.prototype.encodeShape = encodeShape;
|
|
283
|
+
}
|
|
284
|
+
|
|
247
285
|
export function registerAppearanceEncodingAction(ProgramClass) {
|
|
286
|
+
registerBasicAppearanceEncodingActions(ProgramClass);
|
|
248
287
|
ProgramClass.prototype.encodeRadius = encodeRadius;
|
|
249
288
|
ProgramClass.prototype.encodePointRadius = encodePointRadius;
|
|
250
|
-
ProgramClass.prototype.
|
|
251
|
-
ProgramClass.prototype.encodeShape = encodeShape;
|
|
289
|
+
ProgramClass.prototype.removePointRadius = removePointRadius;
|
|
252
290
|
ProgramClass.prototype.encodeOpacity = encodeOpacity;
|
|
253
291
|
ProgramClass.prototype.clearOpacityEncoding = clearOpacityEncoding;
|
|
254
292
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { registerBasicAppearanceEncodingActions } from "./appearance.js";
|
|
2
|
+
import { registerBarWidthEncodingAction } from "./barWidth.js";
|
|
3
|
+
import { registerColorEncodingAction } from "./color/index.js";
|
|
4
|
+
import { registerHistogramEncodingAction } from "./histogram.js";
|
|
5
|
+
import { registerOffsetEncodingAction } from "./offset.js";
|
|
6
|
+
import {
|
|
7
|
+
registerCartesianPositionEncodingActions
|
|
8
|
+
} from "./position/index.js";
|
|
9
|
+
import { registerBasicRangedEncodingActions } from "./ranged.js";
|
|
10
|
+
import { registerStrokeDashEncodingActions } from "./strokeDash.js";
|
|
11
|
+
|
|
12
|
+
export function registerBasicEncodingActions(ProgramClass) {
|
|
13
|
+
registerCartesianPositionEncodingActions(ProgramClass);
|
|
14
|
+
registerBasicRangedEncodingActions(ProgramClass);
|
|
15
|
+
registerColorEncodingAction(ProgramClass);
|
|
16
|
+
registerBasicAppearanceEncodingActions(ProgramClass);
|
|
17
|
+
registerStrokeDashEncodingActions(ProgramClass);
|
|
18
|
+
registerOffsetEncodingAction(ProgramClass);
|
|
19
|
+
registerHistogramEncodingAction(ProgramClass);
|
|
20
|
+
registerBarWidthEncodingAction(ProgramClass);
|
|
21
|
+
}
|
|
@@ -15,6 +15,7 @@ import { planDerivedDataRevision } from
|
|
|
15
15
|
import { validateOptions } from "./shared.js";
|
|
16
16
|
import { normalizeDensityPlacement } from "../../grammar/density.js";
|
|
17
17
|
import { scaleEditPatch } from "../scales/patch.js";
|
|
18
|
+
import { removeLegendKinds } from "../guides/legends/remove.js";
|
|
18
19
|
import {
|
|
19
20
|
requireDensityField,
|
|
20
21
|
resolveDensityCategoryScaleOptions,
|
|
@@ -29,8 +30,8 @@ const OPTIONS = Object.freeze([
|
|
|
29
30
|
"valueScale", "densityScale", "placement"
|
|
30
31
|
]);
|
|
31
32
|
const EDIT_OPTIONS = Object.freeze([
|
|
32
|
-
"target", "
|
|
33
|
-
"placement"
|
|
33
|
+
"target", "source", "field", "groupBy", "bandwidth", "extent", "steps",
|
|
34
|
+
"kernel", "normalization", "placement"
|
|
34
35
|
]);
|
|
35
36
|
const EDITABLE = Object.freeze(EDIT_OPTIONS.filter(option => option !== "target"));
|
|
36
37
|
|
|
@@ -190,6 +191,43 @@ function findDensityArea(program, requested) {
|
|
|
190
191
|
});
|
|
191
192
|
}
|
|
192
193
|
|
|
194
|
+
function densityCategoryField(layer, transform, groupBy) {
|
|
195
|
+
if (transform.placement === undefined) return undefined;
|
|
196
|
+
if (transform.placement.categoryField !== transform.groupBy) {
|
|
197
|
+
return transform.placement.categoryField;
|
|
198
|
+
}
|
|
199
|
+
return groupBy ?? `${layer.id}DensityCategory`;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function assertGroupingSelectionCompatibility(program, layer, changesGroup) {
|
|
203
|
+
if (!changesGroup) return;
|
|
204
|
+
const referenced = Object.entries(
|
|
205
|
+
program.materializationConfigs.selections ?? {}
|
|
206
|
+
).find(([, selection]) =>
|
|
207
|
+
selection.target === layer.id &&
|
|
208
|
+
["group", "color"].includes(selection.selector?.channel)
|
|
209
|
+
);
|
|
210
|
+
if (referenced !== undefined) {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`editDensity cannot change groupBy while selection "${referenced[0]}" ` +
|
|
213
|
+
`references ${referenced[1].selector.channel}.`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function removeOwnedColorLegends(program, target) {
|
|
219
|
+
const kinds = Object.entries(program.guideConfigs.legend ?? {})
|
|
220
|
+
.filter(([kind, config]) =>
|
|
221
|
+
config?.target === target &&
|
|
222
|
+
(
|
|
223
|
+
config.channels?.includes("color") ||
|
|
224
|
+
["gradient", "interval"].includes(kind)
|
|
225
|
+
)
|
|
226
|
+
)
|
|
227
|
+
.map(([kind]) => kind);
|
|
228
|
+
return kinds.length === 0 ? program : removeLegendKinds(program, kinds);
|
|
229
|
+
}
|
|
230
|
+
|
|
193
231
|
const editDensity = action(
|
|
194
232
|
{
|
|
195
233
|
op: "editDensity",
|
|
@@ -203,21 +241,55 @@ const editDensity = action(
|
|
|
203
241
|
const layer = findDensityArea(this, args.target);
|
|
204
242
|
const previous = findDataset(this, layer.data);
|
|
205
243
|
const transform = previous.transform[0];
|
|
244
|
+
const source = Object.hasOwn(args, "source")
|
|
245
|
+
? validateUserId(args.source, "Density source dataset id")
|
|
246
|
+
: previous.source;
|
|
247
|
+
const field = Object.hasOwn(args, "field")
|
|
248
|
+
? requireDensityField(args.field, "Density field")
|
|
249
|
+
: transform.field;
|
|
250
|
+
const groupBy = Object.hasOwn(args, "groupBy")
|
|
251
|
+
? args.groupBy === false
|
|
252
|
+
? undefined
|
|
253
|
+
: requireDensityField(args.groupBy, "Density groupBy")
|
|
254
|
+
: transform.groupBy;
|
|
255
|
+
const changesGroup = groupBy !== transform.groupBy;
|
|
256
|
+
assertGroupingSelectionCompatibility(this, layer, changesGroup);
|
|
257
|
+
const categoryField = densityCategoryField(layer, transform, groupBy);
|
|
206
258
|
const requestedPlacement = Object.hasOwn(args, "placement")
|
|
207
259
|
? normalizeDensityPlacement(args.placement, {
|
|
208
260
|
densityChannel: transform.placement?.channel ?? "x",
|
|
209
|
-
groupBy
|
|
210
|
-
categoryField:
|
|
211
|
-
transform.placement?.categoryField ??
|
|
261
|
+
groupBy,
|
|
262
|
+
categoryField: categoryField ?? groupBy ??
|
|
212
263
|
`${layer.id}DensityCategory`
|
|
213
264
|
})
|
|
214
|
-
: transform.placement
|
|
265
|
+
: transform.placement === undefined || !changesGroup
|
|
266
|
+
? transform.placement
|
|
267
|
+
: normalizeDensityPlacement({
|
|
268
|
+
type: "category",
|
|
269
|
+
...(transform.placement.side === undefined
|
|
270
|
+
? {}
|
|
271
|
+
: { side: transform.placement.side }),
|
|
272
|
+
width: transform.placement.width,
|
|
273
|
+
...(transform.placement.split === undefined
|
|
274
|
+
? {}
|
|
275
|
+
: { split: transform.placement.split })
|
|
276
|
+
}, {
|
|
277
|
+
densityChannel: transform.placement.channel,
|
|
278
|
+
groupBy,
|
|
279
|
+
categoryField
|
|
280
|
+
});
|
|
215
281
|
const colorField = layer.encoding?.color?.field;
|
|
282
|
+
const colorFollowsGroup = transform.groupBy !== undefined &&
|
|
283
|
+
colorField === transform.groupBy;
|
|
216
284
|
const availableColorFields = [
|
|
217
|
-
|
|
285
|
+
groupBy,
|
|
218
286
|
requestedPlacement?.split?.field
|
|
219
287
|
].filter(Boolean);
|
|
220
|
-
if (
|
|
288
|
+
if (
|
|
289
|
+
colorField !== undefined &&
|
|
290
|
+
!colorFollowsGroup &&
|
|
291
|
+
!availableColorFields.includes(colorField)
|
|
292
|
+
) {
|
|
221
293
|
throw new Error(
|
|
222
294
|
`editDensity placement would remove color field "${colorField}" from the density series.`
|
|
223
295
|
);
|
|
@@ -234,11 +306,11 @@ const editDensity = action(
|
|
|
234
306
|
|
|
235
307
|
const dataArgs = {
|
|
236
308
|
id: revision.id,
|
|
237
|
-
source
|
|
238
|
-
field
|
|
239
|
-
...(
|
|
309
|
+
source,
|
|
310
|
+
field,
|
|
311
|
+
...(groupBy === undefined
|
|
240
312
|
? {}
|
|
241
|
-
: { groupBy
|
|
313
|
+
: { groupBy }),
|
|
242
314
|
bandwidth: option("bandwidth"),
|
|
243
315
|
extent: option("extent"),
|
|
244
316
|
steps: option("steps"),
|
|
@@ -249,78 +321,141 @@ const editDensity = action(
|
|
|
249
321
|
? {}
|
|
250
322
|
: { placement: requestedPlacement })
|
|
251
323
|
};
|
|
252
|
-
let next = requestedPlacement === undefined
|
|
253
|
-
? this.createDensityData(dataArgs)
|
|
254
|
-
: this.createCategoricalDensityData(dataArgs);
|
|
255
|
-
next = next.rebindLayerData(revision.rebinds[0])
|
|
256
|
-
.releaseDerivedData(revision.release);
|
|
257
|
-
|
|
258
324
|
const changesPlacementMode = Object.hasOwn(args, "placement") &&
|
|
259
325
|
(transform.placement === undefined) !== (requestedPlacement === undefined);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const scaleId = layer.encoding[channel].scale;
|
|
309
|
-
const requestedScale = resolveDensityCategoryScaleOptions(
|
|
310
|
-
args.placement.scale,
|
|
311
|
-
scaleId
|
|
312
|
-
);
|
|
313
|
-
if (requestedScale.id !== scaleId) {
|
|
314
|
-
throw new Error("editDensity placement scale cannot change its id.");
|
|
326
|
+
const applyEdit = program => {
|
|
327
|
+
let next = requestedPlacement === undefined
|
|
328
|
+
? program.createDensityData(dataArgs)
|
|
329
|
+
: program.createCategoricalDensityData(dataArgs);
|
|
330
|
+
next = next.rebindLayerData(revision.rebinds[0])
|
|
331
|
+
.releaseDerivedData(revision.release);
|
|
332
|
+
|
|
333
|
+
if (changesGroup) {
|
|
334
|
+
if (groupBy === undefined) {
|
|
335
|
+
if (findLayer(next, layer.id).encoding?.group !== undefined) {
|
|
336
|
+
next = next.editSemantic({
|
|
337
|
+
property: `layer[${layer.id}].encoding.group`,
|
|
338
|
+
remove: true
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
if (colorFollowsGroup) {
|
|
342
|
+
next = next.editSemantic({
|
|
343
|
+
property: `layer[${layer.id}].encoding.color`,
|
|
344
|
+
remove: true
|
|
345
|
+
});
|
|
346
|
+
next = removeOwnedColorLegends(next, layer.id);
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
next = next
|
|
350
|
+
.editSemantic({
|
|
351
|
+
property: `layer[${layer.id}].encoding.group.field`,
|
|
352
|
+
value: groupBy
|
|
353
|
+
})
|
|
354
|
+
.editSemantic({
|
|
355
|
+
property: `layer[${layer.id}].encoding.group.fieldType`,
|
|
356
|
+
value: "nominal"
|
|
357
|
+
});
|
|
358
|
+
if (colorFollowsGroup) {
|
|
359
|
+
next = next.editSemantic({
|
|
360
|
+
property: `layer[${layer.id}].encoding.color.field`,
|
|
361
|
+
value: groupBy
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (
|
|
366
|
+
requestedPlacement !== undefined &&
|
|
367
|
+
transform.placement?.categoryField !== requestedPlacement.categoryField
|
|
368
|
+
) {
|
|
369
|
+
next = next.editSemantic({
|
|
370
|
+
property: `layer[${layer.id}].encoding.${requestedPlacement.channel}.field`,
|
|
371
|
+
value: requestedPlacement.categoryField
|
|
372
|
+
});
|
|
373
|
+
}
|
|
315
374
|
}
|
|
316
|
-
next = next.editScale(scaleEditPatch(scaleId, requestedScale));
|
|
317
|
-
}
|
|
318
375
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
376
|
+
if (changesPlacementMode) {
|
|
377
|
+
const xScaleId = layer.encoding?.x?.scale;
|
|
378
|
+
const yScaleId = layer.encoding?.y?.scale;
|
|
379
|
+
const scaleDefinitions = resolveDensityTransitionScaleDefinitions(
|
|
380
|
+
program,
|
|
381
|
+
layer,
|
|
382
|
+
transform,
|
|
383
|
+
requestedPlacement,
|
|
384
|
+
args.placement
|
|
385
|
+
);
|
|
386
|
+
next = next
|
|
387
|
+
.editSemantic({
|
|
388
|
+
property: `layer[${layer.id}].encoding.x`,
|
|
389
|
+
remove: true
|
|
390
|
+
})
|
|
391
|
+
.editSemantic({
|
|
392
|
+
property: `layer[${layer.id}].encoding.y`,
|
|
393
|
+
remove: true
|
|
394
|
+
});
|
|
395
|
+
next = next
|
|
396
|
+
.editScale(scaleEditPatch(xScaleId, scaleDefinitions.x))
|
|
397
|
+
.editScale(scaleEditPatch(yScaleId, scaleDefinitions.y));
|
|
398
|
+
const densityChannel = requestedPlacement?.channel ?? (
|
|
399
|
+
layer.encoding.x.field === transform.as[1] ? "x" : "y"
|
|
400
|
+
);
|
|
401
|
+
const valueChannel = requestedPlacement?.channel === "x" ? "y" : "x";
|
|
402
|
+
const definition = resolveDensityPositionDefinition({
|
|
403
|
+
layer: { densityChannel },
|
|
404
|
+
output: transform.as,
|
|
405
|
+
groupBy,
|
|
406
|
+
placement: requestedPlacement,
|
|
407
|
+
coordinate: layer.coordinate,
|
|
408
|
+
valueScale: {
|
|
409
|
+
id: valueChannel === "y" ? yScaleId : xScaleId,
|
|
410
|
+
...scaleDefinitions[valueChannel]
|
|
411
|
+
},
|
|
412
|
+
densityScale: requestedPlacement === undefined
|
|
413
|
+
? {
|
|
414
|
+
id: densityChannel === "x" ? xScaleId : yScaleId,
|
|
415
|
+
...scaleDefinitions[densityChannel]
|
|
416
|
+
}
|
|
417
|
+
: undefined,
|
|
418
|
+
placementScale: requestedPlacement === undefined
|
|
419
|
+
? undefined
|
|
420
|
+
: {
|
|
421
|
+
id: requestedPlacement.channel === "x" ? xScaleId : yScaleId,
|
|
422
|
+
...scaleDefinitions[requestedPlacement.channel]
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
next = applyDensityPosition(next, layer.id, definition, groupBy);
|
|
426
|
+
} else if (
|
|
427
|
+
requestedPlacement !== undefined &&
|
|
428
|
+
Object.hasOwn(args.placement ?? {}, "scale")
|
|
429
|
+
) {
|
|
430
|
+
const channel = requestedPlacement.channel;
|
|
431
|
+
const scaleId = layer.encoding[channel].scale;
|
|
432
|
+
const requestedScale = resolveDensityCategoryScaleOptions(
|
|
433
|
+
args.placement.scale,
|
|
434
|
+
scaleId
|
|
435
|
+
);
|
|
436
|
+
if (requestedScale.id !== scaleId) {
|
|
437
|
+
throw new Error("editDensity placement scale cannot change its id.");
|
|
438
|
+
}
|
|
439
|
+
next = next.editScale(scaleEditPatch(scaleId, requestedScale));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
next = applyMaterializationPlan(
|
|
443
|
+
next,
|
|
444
|
+
planDensityRematerialization(next, layer.id)
|
|
445
|
+
);
|
|
446
|
+
if (
|
|
447
|
+
changesGroup &&
|
|
448
|
+
colorFollowsGroup &&
|
|
449
|
+
groupBy !== undefined &&
|
|
450
|
+
Object.values(next.guideConfigs.legend ?? {})
|
|
451
|
+
.some(config => config?.target === layer.id)
|
|
452
|
+
) {
|
|
453
|
+
next = next.rematerializeLegend();
|
|
454
|
+
}
|
|
455
|
+
return next;
|
|
456
|
+
};
|
|
457
|
+
applyEdit(this);
|
|
458
|
+
return applyEdit(this);
|
|
324
459
|
}
|
|
325
460
|
);
|
|
326
461
|
|
|
@@ -12,6 +12,7 @@ import { registerStrokeDashEncodingActions } from "./strokeDash.js";
|
|
|
12
12
|
import { registerRuleAppearanceEncodingActions } from "./ruleAppearance.js";
|
|
13
13
|
import { registerTextEncodingAction } from "./text.js";
|
|
14
14
|
import { registerParallelEncodingAction } from "./parallel.js";
|
|
15
|
+
import { registerEncodingRemovalAction } from "./remove.js";
|
|
15
16
|
|
|
16
17
|
export function registerEncodingActions(ProgramClass) {
|
|
17
18
|
registerPositionEncodingActions(ProgramClass);
|
|
@@ -28,4 +29,5 @@ export function registerEncodingActions(ProgramClass) {
|
|
|
28
29
|
registerRuleAppearanceEncodingActions(ProgramClass);
|
|
29
30
|
registerTextEncodingAction(ProgramClass);
|
|
30
31
|
registerParallelEncodingAction(ProgramClass);
|
|
32
|
+
registerEncodingRemovalAction(ProgramClass);
|
|
31
33
|
}
|
|
@@ -135,9 +135,13 @@ const encodeR = action(
|
|
|
135
135
|
}
|
|
136
136
|
);
|
|
137
137
|
|
|
138
|
-
export function
|
|
138
|
+
export function registerCartesianPositionEncodingActions(ProgramClass) {
|
|
139
139
|
ProgramClass.prototype.encodeX = encodeX;
|
|
140
140
|
ProgramClass.prototype.encodeY = encodeY;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function registerPositionEncodingActions(ProgramClass) {
|
|
144
|
+
registerCartesianPositionEncodingActions(ProgramClass);
|
|
141
145
|
ProgramClass.prototype.encodeTheta = encodeTheta;
|
|
142
146
|
ProgramClass.prototype.encodeR = encodeR;
|
|
143
147
|
}
|
|
@@ -291,10 +291,14 @@ const encodeGroup = action(
|
|
|
291
291
|
}
|
|
292
292
|
);
|
|
293
293
|
|
|
294
|
-
export function
|
|
294
|
+
export function registerBasicRangedEncodingActions(ProgramClass) {
|
|
295
295
|
ProgramClass.prototype.encodeX2 = encodeX2;
|
|
296
296
|
ProgramClass.prototype.encodeY2 = encodeY2;
|
|
297
|
+
ProgramClass.prototype.encodeGroup = encodeGroup;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function registerRangedEncodingActions(ProgramClass) {
|
|
301
|
+
registerBasicRangedEncodingActions(ProgramClass);
|
|
297
302
|
ProgramClass.prototype.encodeXRange = encodeXRange;
|
|
298
303
|
ProgramClass.prototype.encodeYRange = encodeYRange;
|
|
299
|
-
ProgramClass.prototype.encodeGroup = encodeGroup;
|
|
300
304
|
}
|