ggaction 0.0.13 → 0.0.15
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 +78 -0
- package/README.md +20 -11
- package/knowledge/action-cards.json +1 -1
- package/knowledge/intent-taxonomy.json +1 -1
- package/knowledge/mcp-resources.json +1 -1
- package/package.json +8 -3
- package/src/actions/basic.js +2 -2
- package/src/actions/boxPlots/components.js +14 -4
- package/src/actions/boxPlots/edit.js +31 -5
- package/src/actions/boxPlots/materialize.js +11 -3
- package/src/actions/boxPlots/options.js +48 -16
- package/src/actions/categoryOrder/index.js +15 -4
- package/src/actions/charts/area.js +5 -1
- package/src/actions/charts/bar.js +2 -1
- package/src/actions/charts/density.js +6 -2
- package/src/actions/charts/ecdf.js +4 -1
- package/src/actions/charts/endpoints.js +25 -3
- package/src/actions/charts/heatmap.js +2 -1
- package/src/actions/charts/histogram.js +4 -3
- package/src/actions/charts/horizon.js +3 -1
- package/src/actions/charts/interval-regression.js +5 -2
- package/src/actions/charts/line.js +3 -1
- package/src/actions/charts/parallel.js +8 -2
- package/src/actions/charts/pie.js +10 -2
- package/src/actions/charts/polar.js +15 -4
- package/src/actions/charts/radar.js +8 -2
- package/src/actions/charts/radial.js +10 -2
- package/src/actions/charts/rug-strip.js +6 -2
- package/src/actions/charts/scatter.js +3 -1
- package/src/actions/composition/actions.js +13 -4
- package/src/actions/coordinates/actions.js +1 -1
- package/src/actions/coordinates/edit.js +76 -0
- package/src/actions/data/bin.js +1 -1
- package/src/actions/data/bin2d.js +57 -185
- package/src/actions/data/complete.js +26 -0
- package/src/actions/data/computed.js +2 -2
- package/src/actions/data/create.js +2 -2
- package/src/actions/data/density.js +12 -20
- package/src/actions/data/derived.js +47 -17
- package/src/actions/data/edit.js +539 -0
- package/src/actions/data/filter.js +14 -2
- package/src/actions/data/impute.js +26 -0
- package/src/actions/data/index.js +14 -0
- package/src/actions/data/normalize.js +27 -0
- package/src/actions/data/regression.js +16 -21
- package/src/actions/data/revisionBindings.js +145 -0
- package/src/actions/data/shared.js +20 -4
- package/src/actions/data/summary.js +1 -1
- package/src/actions/data/timeUnit.js +4 -1
- package/src/actions/data/window.js +1 -1
- package/src/actions/encodings/channels.js +415 -0
- package/src/actions/encodings/color/index.js +2 -1
- package/src/actions/encodings/density.js +5 -2
- package/src/actions/encodings/histogram.js +3 -2
- package/src/actions/encodings/index.js +4 -0
- package/src/actions/encodings/offset.js +20 -13
- package/src/actions/encodings/position/apply.js +53 -7
- package/src/actions/encodings/position/index.js +10 -2
- package/src/actions/encodings/position/policies/bar.js +9 -0
- package/src/actions/encodings/position/resolve.js +24 -7
- package/src/actions/encodings/remove.js +9 -4
- package/src/actions/encodings/ruleAppearance.js +1 -23
- package/src/actions/encodings/seriesLayout.js +1 -0
- package/src/actions/encodings/shared.js +82 -14
- package/src/actions/encodings/stroke.js +226 -0
- package/src/actions/errorBands/create.js +23 -3
- package/src/actions/errorBands/edit.js +21 -6
- package/src/actions/errorBars/create.js +35 -7
- package/src/actions/errorBars/edit.js +19 -4
- package/src/actions/facets/actions.js +237 -57
- package/src/actions/facets/derive.js +91 -26
- package/src/actions/gradientPlots/components.js +10 -2
- package/src/actions/gradientPlots/edit.js +14 -4
- package/src/actions/gradientPlots/materialize.js +3 -1
- package/src/actions/gradientPlots/options.js +10 -2
- package/src/actions/guides/applicability.js +8 -2
- package/src/actions/guides/axes/labels.js +58 -12
- package/src/actions/guides/axes/lines.js +6 -2
- package/src/actions/guides/axes/parallel/resolve.js +6 -2
- package/src/actions/guides/axes/tickGroups.js +2 -1
- package/src/actions/guides/axes/ticks.js +6 -2
- package/src/actions/guides/axes/titles.js +11 -3
- package/src/actions/guides/grids/resolve.js +7 -2
- package/src/actions/guides/guides.js +19 -3
- package/src/actions/guides/legends/blocks.js +426 -0
- package/src/actions/guides/legends/categorical/actions.js +134 -48
- package/src/actions/guides/legends/categorical/components.js +17 -12
- package/src/actions/guides/legends/categorical/index.js +37 -33
- package/src/actions/guides/legends/categorical/layout.js +97 -15
- package/src/actions/guides/legends/categorical/options.js +2 -2
- package/src/actions/guides/legends/categorical/recipes.js +111 -20
- package/src/actions/guides/legends/categorical/resolve.js +12 -8
- package/src/actions/guides/legends/categorical/symbols.js +85 -30
- package/src/actions/guides/legends/continuous/common.js +30 -12
- package/src/actions/guides/legends/continuous/gradient.js +10 -7
- package/src/actions/guides/legends/continuous/index.js +2 -0
- package/src/actions/guides/legends/continuous/interval.js +8 -3
- package/src/actions/guides/legends/continuous/opacity.js +8 -5
- package/src/actions/guides/legends/continuous/stroke.js +525 -0
- package/src/actions/guides/legends/creation.js +14 -1
- package/src/actions/guides/legends/edit.js +158 -59
- package/src/actions/guides/legends/index.js +2 -0
- package/src/actions/guides/legends/lane.js +54 -19
- package/src/actions/guides/legends/lifecycle.js +19 -8
- package/src/actions/guides/legends/remove.js +13 -3
- package/src/actions/guides/legends/sampling.js +140 -0
- package/src/actions/guides/legends/size.js +93 -40
- package/src/actions/guides/legends/strokeWidth.js +34 -28
- package/src/actions/guides/legends/target.js +112 -1
- package/src/actions/guides/legends/transition.js +165 -16
- package/src/actions/guides/polar/axes/facade.js +4 -4
- package/src/actions/guides/polar/axes/labels.js +24 -5
- package/src/actions/guides/polar/axes/lines.js +10 -4
- package/src/actions/guides/polar/axes/shared.js +16 -0
- package/src/actions/guides/polar/axes/ticks.js +1 -1
- package/src/actions/guides/polar/axes/titles.js +1 -1
- package/src/actions/guides/polar/grids.js +1 -1
- package/src/actions/guides/polar/resolve.js +12 -8
- package/src/actions/index.js +14 -3
- package/src/actions/marks/arc/actions.js +77 -19
- package/src/actions/marks/area/actions.js +34 -9
- package/src/actions/marks/area/materialize.js +17 -1
- package/src/actions/marks/bar/create.js +11 -2
- package/src/actions/marks/bar/edit.js +20 -3
- package/src/actions/marks/bar/materialize.js +22 -2
- package/src/actions/marks/index.js +10 -1
- package/src/actions/marks/line/actions.js +37 -14
- package/src/actions/marks/line/materialize.js +29 -10
- package/src/actions/marks/point/create.js +8 -2
- package/src/actions/marks/point/edit.js +18 -6
- package/src/actions/marks/point/materialize.js +49 -15
- package/src/actions/marks/rect/actions.js +33 -12
- package/src/actions/marks/references.js +601 -30
- package/src/actions/marks/remove.js +71 -1
- package/src/actions/marks/rule/actions.js +47 -10
- package/src/actions/marks/shared.js +1 -1
- package/src/actions/marks/text/actions.js +74 -9
- package/src/actions/marks/text/index.js +4 -0
- package/src/actions/marks/text/layout.js +154 -6
- package/src/actions/marks/text/removal.js +173 -0
- package/src/actions/marks/text/selection.js +73 -0
- package/src/actions/marks/tick/actions.js +22 -5
- package/src/actions/primitives/editGraphics.js +26 -0
- package/src/actions/primitives/semantic.js +2 -1
- package/src/actions/primitives/semanticAction.js +83 -10
- package/src/actions/primitives/semanticValidation/guide.js +1 -1
- package/src/actions/primitives/semanticValidation/index.js +9 -1
- package/src/actions/primitives/semanticValidation/layer.js +5 -0
- package/src/actions/primitives/semanticValidation/scale.js +28 -7
- package/src/actions/regression/components.js +26 -11
- package/src/actions/regression/create.js +10 -2
- package/src/actions/regression/edit.js +21 -7
- package/src/actions/resources/index.js +7 -0
- package/src/actions/resources/remove.js +172 -0
- package/src/actions/scales/channels.js +212 -0
- package/src/actions/scales/consumers/common.js +1 -1
- package/src/actions/scales/consumers/families.js +3 -2
- package/src/actions/scales/consumers/index.js +19 -2
- package/src/actions/scales/consumers/seriesLayout.js +28 -14
- package/src/actions/scales/create.js +54 -22
- package/src/actions/scales/definitions.js +94 -40
- package/src/actions/scales/edit.js +66 -11
- package/src/actions/scales/editPolicy.js +81 -11
- package/src/actions/scales/index.js +6 -0
- package/src/actions/scales/materialize.js +4 -3
- package/src/actions/scales/offset.js +48 -0
- package/src/actions/scales/parallel.js +71 -0
- package/src/actions/scales/preview.js +111 -10
- package/src/actions/selection/actions.js +154 -30
- package/src/actions/selection/index.js +3 -0
- package/src/actions/theme/actions.js +68 -13
- package/src/actions/theme/composition.js +238 -0
- package/src/actions/theme/index.js +9 -2
- package/src/actions/theme/reconcile.js +315 -67
- package/src/actions/theme/state.js +160 -0
- package/src/actions/violinPlots/create.js +5 -2
- package/src/actions/violinPlots/edit.js +1 -0
- package/src/core/action.js +10 -0
- package/src/core/compositionState.js +6 -1
- package/src/core/programState.js +20 -0
- package/src/core/resourceReferences.js +332 -0
- package/src/core/vocabulary.js +16 -3
- package/src/grammar/bars/aggregate.js +4 -1
- package/src/grammar/bars/geometry.js +44 -0
- package/src/grammar/bin.js +54 -9
- package/src/grammar/complete.js +279 -0
- package/src/grammar/computed.js +265 -64
- package/src/grammar/coordinates.js +37 -0
- package/src/grammar/density.js +239 -37
- package/src/grammar/displayLabels.js +57 -0
- package/src/grammar/facets/dependencies.js +133 -1
- package/src/grammar/facets/guides.js +3 -0
- package/src/grammar/facets/index.js +7 -47
- package/src/grammar/facets/scales.js +15 -18
- package/src/grammar/impute.js +340 -0
- package/src/grammar/markLabelSelection.js +57 -0
- package/src/grammar/markLabels.js +18 -1
- package/src/grammar/normalize.js +366 -0
- package/src/grammar/pathSeries.js +26 -8
- package/src/grammar/pointShapes.js +13 -4
- package/src/grammar/polar.js +90 -8
- package/src/grammar/regression/index.js +1 -0
- package/src/grammar/regression/parameters.js +23 -0
- package/src/grammar/roundedRect.js +180 -0
- package/src/grammar/rules.js +1 -0
- package/src/grammar/scales/colorConsumers.js +20 -1
- package/src/grammar/scales/continuous.js +2 -2
- package/src/grammar/scales/definition.js +27 -4
- package/src/grammar/scales/index.js +1 -0
- package/src/grammar/scales/ordinal.js +12 -3
- package/src/grammar/scales/policies.js +2 -2
- package/src/grammar/scales/size.js +456 -0
- package/src/grammar/schemas/concreteGraphic.js +14 -2
- package/src/grammar/schemas/graphic.js +15 -0
- package/src/grammar/schemas/graphicBounds.js +179 -30
- package/src/grammar/schemas/semanticPath.js +7 -2
- package/src/grammar/statisticalReference.js +103 -0
- package/src/grammar/strokeStyle.js +77 -0
- package/src/grammar/summary.js +78 -16
- package/src/grammar/timeUnit.js +216 -5
- package/src/grammar/transformTopology.js +4 -0
- package/src/grammar/transforms.js +394 -28
- package/src/grammar/weightedStatistics.js +374 -0
- package/src/grammar/window.js +221 -16
- package/src/layout/aspect.js +80 -0
- package/src/layout/facets.js +59 -5
- package/src/layout/labels.js +343 -0
- package/src/materialization/bars/aggregate.js +25 -2
- package/src/materialization/bars/histogram.js +84 -24
- package/src/materialization/bars/ranged.js +19 -3
- package/src/materialization/bars/resolve.js +7 -4
- package/src/materialization/composition.js +3 -1
- package/src/materialization/coordinateBounds.js +204 -0
- package/src/materialization/dependencies.js +36 -0
- package/src/materialization/facetGuides/legacyCategorical.js +3 -0
- package/src/materialization/facetGuides/placement.js +8 -2
- package/src/materialization/facetGuides/preparation.js +12 -7
- package/src/materialization/facetHeaders.js +346 -0
- package/src/materialization/facets.js +15 -65
- package/src/materialization/guides/resources.js +26 -0
- package/src/materialization/legends.js +1 -1
- package/src/materialization/marks/index.js +11 -5
- package/src/materialization/marks/policies.js +2 -1
- package/src/materialization/rect.js +25 -12
- package/src/materialization/rectConfig.js +5 -1
- package/src/materialization/scales/map.js +5 -3
- package/src/materialization/scales/policies/binnedPosition.js +2 -2
- package/src/materialization/scales/policies/offset.js +50 -8
- package/src/materialization/scales/policies/series.js +4 -1
- package/src/materialization/scales/resolve.js +22 -6
- package/src/materialization/selection/items/arc.js +28 -4
- package/src/materialization/selection/items/bar.js +30 -3
- package/src/materialization/selection/items/common.js +19 -4
- package/src/materialization/selection/items/rect.js +28 -4
- package/src/materialization/selection/path.js +1 -1
- package/src/materialization/selection/point.js +3 -1
- package/src/materialization/text.js +265 -14
- package/src/renderers/canvas/circle.js +2 -3
- package/src/renderers/canvas/line.js +2 -3
- package/src/renderers/canvas/native.js +4 -4
- package/src/renderers/canvas/path.js +2 -3
- package/src/renderers/canvas/rect.js +2 -3
- package/src/renderers/canvas/stroke.js +11 -0
- package/src/renderers/svg.js +19 -0
- package/src/selectors/datasets.js +32 -1
- package/src/selectors/layers.js +4 -0
- package/src/theme/defaults.js +101 -0
- package/types/basic.d.ts +6 -0
- package/types/index.d.ts +85 -0
- package/types/program.d.ts +910 -117
|
@@ -150,7 +150,8 @@ const encodeColor = action(
|
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
152
|
next = applyEncodingScale(next, scale, requestedScale, {
|
|
153
|
-
reassignment: layer.encoding?.color?.scale === scale.id
|
|
153
|
+
reassignment: layer.encoding?.color?.scale === scale.id,
|
|
154
|
+
allowTypeChange: true
|
|
154
155
|
});
|
|
155
156
|
next = applyColorLayoutCompanion(next, {
|
|
156
157
|
target,
|
|
@@ -28,12 +28,12 @@ import {
|
|
|
28
28
|
|
|
29
29
|
const OPTIONS = Object.freeze([
|
|
30
30
|
"field", "target", "source", "groupBy", "bandwidth", "extent", "steps",
|
|
31
|
-
"kernel", "normalization", "as", "densityChannel", "coordinate",
|
|
31
|
+
"kernel", "normalization", "weight", "as", "densityChannel", "coordinate",
|
|
32
32
|
"valueScale", "densityScale", "placement"
|
|
33
33
|
]);
|
|
34
34
|
const EDIT_OPTIONS = Object.freeze([
|
|
35
35
|
"target", "source", "field", "groupBy", "bandwidth", "extent", "steps",
|
|
36
|
-
"kernel", "normalization", "densityChannel", "valueScale", "placement"
|
|
36
|
+
"kernel", "normalization", "weight", "densityChannel", "valueScale", "placement"
|
|
37
37
|
]);
|
|
38
38
|
const EDITABLE = Object.freeze(EDIT_OPTIONS.filter(option => option !== "target"));
|
|
39
39
|
const SCALE_PROPERTIES = Object.freeze([
|
|
@@ -193,6 +193,7 @@ const encodeDensity = action(
|
|
|
193
193
|
...(args.normalization === undefined
|
|
194
194
|
? {}
|
|
195
195
|
: { normalization: args.normalization }),
|
|
196
|
+
...(args.weight === undefined ? {} : { weight: args.weight }),
|
|
196
197
|
...(args.as === undefined ? {} : { as: args.as }),
|
|
197
198
|
...(placement === undefined ? {} : { placement })
|
|
198
199
|
};
|
|
@@ -350,6 +351,7 @@ const editDensity = action(
|
|
|
350
351
|
const option = property => Object.hasOwn(args, property)
|
|
351
352
|
? args[property]
|
|
352
353
|
: transform[property];
|
|
354
|
+
const weight = option("weight");
|
|
353
355
|
|
|
354
356
|
const dataArgs = {
|
|
355
357
|
id: revision.id,
|
|
@@ -364,6 +366,7 @@ const editDensity = action(
|
|
|
364
366
|
kernel: option("kernel") ?? "gaussian",
|
|
365
367
|
normalization: option("normalization") ?? "unit",
|
|
366
368
|
as: transform.as,
|
|
369
|
+
...(weight === undefined || weight === false ? {} : { weight }),
|
|
367
370
|
...(requestedPlacement === undefined
|
|
368
371
|
? {}
|
|
369
372
|
: { placement: requestedPlacement })
|
|
@@ -3,7 +3,7 @@ import { validateOptions } from "./shared.js";
|
|
|
3
3
|
|
|
4
4
|
const HISTOGRAM_OPTIONS = Object.freeze([
|
|
5
5
|
"field", "target", "coordinate", "maxBins", "binStep", "binBoundaries",
|
|
6
|
-
"stack", "xScale", "yScale"
|
|
6
|
+
"stack", "xScale", "yScale", "weight"
|
|
7
7
|
]);
|
|
8
8
|
|
|
9
9
|
const encodeHistogram = action(
|
|
@@ -28,7 +28,8 @@ const encodeHistogram = action(
|
|
|
28
28
|
: { maxBins: args.maxBins ?? 10 };
|
|
29
29
|
const x = {
|
|
30
30
|
field: args.field,
|
|
31
|
-
bin
|
|
31
|
+
bin,
|
|
32
|
+
...(args.weight === undefined ? {} : { weight: args.weight })
|
|
32
33
|
};
|
|
33
34
|
const y = {
|
|
34
35
|
stack: Object.hasOwn(args, "stack") ? args.stack : "zero"
|
|
@@ -13,8 +13,10 @@ import { registerTextEncodingAction } from "./text.js";
|
|
|
13
13
|
import { registerAppearanceEncodingAction } from "./appearance.js";
|
|
14
14
|
import { registerStrokeDashEncodingActions } from "./strokeDash.js";
|
|
15
15
|
import { registerRuleAppearanceEncodingActions } from "./ruleAppearance.js";
|
|
16
|
+
import { registerStrokeEncodingAction } from "./stroke.js";
|
|
16
17
|
import { registerBarWidthEncodingAction } from "./barWidth.js";
|
|
17
18
|
import { registerEncodingRemovalAction } from "./remove.js";
|
|
19
|
+
import { registerAtomicEncodingAction } from "./channels.js";
|
|
18
20
|
|
|
19
21
|
export function registerEncodingActions(ProgramClass) {
|
|
20
22
|
registerSeriesLayoutAction(ProgramClass);
|
|
@@ -31,7 +33,9 @@ export function registerEncodingActions(ProgramClass) {
|
|
|
31
33
|
registerAppearanceEncodingAction(ProgramClass);
|
|
32
34
|
registerAngleEncodingAction(ProgramClass);
|
|
33
35
|
registerRuleAppearanceEncodingActions(ProgramClass);
|
|
36
|
+
registerStrokeEncodingAction(ProgramClass);
|
|
34
37
|
registerTextEncodingAction(ProgramClass);
|
|
35
38
|
registerParallelEncodingAction(ProgramClass);
|
|
36
39
|
registerEncodingRemovalAction(ProgramClass);
|
|
40
|
+
registerAtomicEncodingAction(ProgramClass);
|
|
37
41
|
}
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
resolveBarChannels,
|
|
19
19
|
resolveBarGrain
|
|
20
20
|
} from "../../grammar/bars/policy.js";
|
|
21
|
-
import { normalizeOffsetPadding } from "../../grammar/bars/geometry.js";
|
|
22
21
|
|
|
23
22
|
const ENCODING_OPTIONS = Object.freeze([
|
|
24
23
|
"field", "target", "fieldType", "scale", "paddingInner", "paddingOuter"
|
|
@@ -69,30 +68,38 @@ function createOffsetEncoding(channel) {
|
|
|
69
68
|
layer.encoding?.[channel],
|
|
70
69
|
args.scale ?? {}
|
|
71
70
|
);
|
|
72
|
-
const
|
|
71
|
+
const scaleOptions = {
|
|
72
|
+
...requestedScale,
|
|
73
|
+
...Object.fromEntries(
|
|
74
|
+
["paddingInner", "paddingOuter"]
|
|
75
|
+
.filter(property => Object.hasOwn(args, property))
|
|
76
|
+
.map(property => [property, args[property]])
|
|
77
|
+
)
|
|
78
|
+
};
|
|
79
|
+
const scale = resolveOffsetScaleDefinition(this, scaleOptions, channel);
|
|
73
80
|
if (Object.hasOwn(scale, "unknown")) {
|
|
74
81
|
throw new Error(
|
|
75
82
|
`${channel} scale unknown is not supported for offset positions.`
|
|
76
83
|
);
|
|
77
84
|
}
|
|
78
|
-
const padding = normalizeOffsetPadding(
|
|
79
|
-
args,
|
|
80
|
-
this.markConfigs[target]?.[channel],
|
|
81
|
-
channel
|
|
82
|
-
);
|
|
83
85
|
|
|
84
86
|
const grouped = layer.mark.type === "bar" ? inferSeriesGroup(this, layer, args.field, "offset") : this;
|
|
85
87
|
let next = setEncodingProperties(grouped, target, channel, {
|
|
86
88
|
field: args.field,
|
|
87
89
|
fieldType,
|
|
88
90
|
scale: scale.id
|
|
89
|
-
})._withMarkConfig(target, {
|
|
90
|
-
...this.markConfigs[target],
|
|
91
|
-
[channel]: padding
|
|
92
|
-
});
|
|
93
|
-
next = applyEncodingScale(next, scale, requestedScale, {
|
|
94
|
-
reassignment: layer.encoding?.[channel]?.scale === scale.id
|
|
95
91
|
});
|
|
92
|
+
next = applyEncodingScale(next, scale, {
|
|
93
|
+
...Object.fromEntries(Object.entries(scaleOptions).filter(
|
|
94
|
+
([property]) => property !== "range"
|
|
95
|
+
)),
|
|
96
|
+
paddingInner: scale.paddingInner,
|
|
97
|
+
paddingOuter: scale.paddingOuter,
|
|
98
|
+
align: scale.align
|
|
99
|
+
}, {
|
|
100
|
+
reassignment: findSemanticScale(this, scale.id) !== undefined
|
|
101
|
+
});
|
|
102
|
+
next = next._withoutMaterializationConfig(["marks", target, channel]);
|
|
96
103
|
if (layer.mark.type === "bar") {
|
|
97
104
|
if (findSemanticScale(this, scale.id) === undefined && args.scale?.id === undefined) next = next._withMarkConfig(target, { ...next.markConfigs[target], seriesOffsetScale: scale.id });
|
|
98
105
|
if (layer.layout?.mode !== "group" || layer.encoding?.group?.field !== args.field) return next.layoutSeries({ target, mode: "group" });
|
|
@@ -66,18 +66,35 @@ function applyBin(program, target, channel, previous, bin) {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
function applyPositionWeight(
|
|
70
|
+
program,
|
|
71
|
+
target,
|
|
72
|
+
channel,
|
|
73
|
+
previous,
|
|
74
|
+
bin,
|
|
75
|
+
aggregate,
|
|
76
|
+
weight
|
|
77
|
+
) {
|
|
78
|
+
const histogram = channel === "x" && bin !== undefined;
|
|
79
|
+
const arcSum = channel === "theta" && aggregate === "sum";
|
|
80
|
+
if (!histogram && !arcSum) {
|
|
81
|
+
return previous?.weight === undefined
|
|
82
|
+
? program
|
|
83
|
+
: program.editSemantic({
|
|
84
|
+
property: `layer[${target}].encoding.${channel}.weight`,
|
|
85
|
+
remove: true
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (weight === undefined) {
|
|
72
89
|
return previous?.weight === undefined
|
|
73
90
|
? program
|
|
74
91
|
: program.editSemantic({
|
|
75
|
-
property: `layer[${target}].encoding.
|
|
92
|
+
property: `layer[${target}].encoding.${channel}.weight`,
|
|
76
93
|
remove: true
|
|
77
94
|
});
|
|
78
95
|
}
|
|
79
96
|
return program.editSemantic({
|
|
80
|
-
property: `layer[${target}].encoding.
|
|
97
|
+
property: `layer[${target}].encoding.${channel}.weight`,
|
|
81
98
|
value: weight
|
|
82
99
|
});
|
|
83
100
|
}
|
|
@@ -104,6 +121,26 @@ function removeStaleArcThetaAggregate(
|
|
|
104
121
|
});
|
|
105
122
|
}
|
|
106
123
|
|
|
124
|
+
function removeMeasuredRadiusAggregate(
|
|
125
|
+
program,
|
|
126
|
+
target,
|
|
127
|
+
channel,
|
|
128
|
+
previous,
|
|
129
|
+
clearRadialMapping
|
|
130
|
+
) {
|
|
131
|
+
if (
|
|
132
|
+
channel !== "radius" ||
|
|
133
|
+
!clearRadialMapping ||
|
|
134
|
+
previous?.aggregate === undefined
|
|
135
|
+
) {
|
|
136
|
+
return program;
|
|
137
|
+
}
|
|
138
|
+
return program.editSemantic({
|
|
139
|
+
property: `layer[${target}].encoding.radius.aggregate`,
|
|
140
|
+
remove: true
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
107
144
|
export function applyPositionSemantics(program, {
|
|
108
145
|
target,
|
|
109
146
|
channel,
|
|
@@ -117,7 +154,8 @@ export function applyPositionSemantics(program, {
|
|
|
117
154
|
bin,
|
|
118
155
|
aggregate,
|
|
119
156
|
stack,
|
|
120
|
-
weight
|
|
157
|
+
weight,
|
|
158
|
+
clearRadialMapping
|
|
121
159
|
}) {
|
|
122
160
|
let next = reconcileInheritedRulePosition(program, {
|
|
123
161
|
target,
|
|
@@ -160,11 +198,19 @@ export function applyPositionSemantics(program, {
|
|
|
160
198
|
fieldType,
|
|
161
199
|
aggregate
|
|
162
200
|
);
|
|
163
|
-
|
|
201
|
+
next = removeMeasuredRadiusAggregate(
|
|
202
|
+
next,
|
|
203
|
+
target,
|
|
204
|
+
channel,
|
|
205
|
+
previous,
|
|
206
|
+
clearRadialMapping
|
|
207
|
+
);
|
|
208
|
+
return applyPositionWeight(
|
|
164
209
|
next,
|
|
165
210
|
target,
|
|
166
211
|
channel,
|
|
167
212
|
previous,
|
|
213
|
+
bin,
|
|
168
214
|
aggregate,
|
|
169
215
|
weight
|
|
170
216
|
);
|
|
@@ -31,7 +31,8 @@ function encodePosition(program, channel, args, operation) {
|
|
|
31
31
|
aggregate,
|
|
32
32
|
stack,
|
|
33
33
|
weight,
|
|
34
|
-
companion
|
|
34
|
+
companion,
|
|
35
|
+
clearRadialMapping
|
|
35
36
|
} = resolvePositionEncoding(program, channel, args, operation);
|
|
36
37
|
|
|
37
38
|
let next = program
|
|
@@ -53,13 +54,20 @@ function encodePosition(program, channel, args, operation) {
|
|
|
53
54
|
bin,
|
|
54
55
|
aggregate,
|
|
55
56
|
stack,
|
|
56
|
-
weight
|
|
57
|
+
weight,
|
|
58
|
+
clearRadialMapping
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
next = next.editSemantic({
|
|
60
62
|
property: `layer[${target}].encoding.${channel}.scale`,
|
|
61
63
|
value: scale.id
|
|
62
64
|
});
|
|
65
|
+
if (
|
|
66
|
+
clearRadialMapping &&
|
|
67
|
+
findSemanticScale(next, scale.id)?.radialMapping !== undefined
|
|
68
|
+
) {
|
|
69
|
+
next = next.editScale({ id: scale.id, radialMapping: undefined });
|
|
70
|
+
}
|
|
63
71
|
next = applyEncodingScale(next, scale, requestedScale, {
|
|
64
72
|
reassignment: previous?.scale === scale.id,
|
|
65
73
|
allowTypeChange: layer.mark.type === "area"
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
resolveBarOrientation
|
|
11
11
|
} from "../../../../grammar/bars/policy.js";
|
|
12
12
|
import { resolveBin, validateStack } from "./common.js";
|
|
13
|
+
import { normalizeStatisticalWeight } from
|
|
14
|
+
"../../../../grammar/weightedStatistics.js";
|
|
13
15
|
|
|
14
16
|
function resolveBarChannelPolicy({
|
|
15
17
|
program,
|
|
@@ -37,6 +39,10 @@ function resolveBarChannelPolicy({
|
|
|
37
39
|
throw new Error("Binned bar x encoding does not support aggregate or stack.");
|
|
38
40
|
}
|
|
39
41
|
bin = resolveBin(args.bin);
|
|
42
|
+
const weight = args.weight === undefined
|
|
43
|
+
? undefined
|
|
44
|
+
: normalizeStatisticalWeight(args.weight, "Histogram weight");
|
|
45
|
+
return { bin, aggregate, stack, weight };
|
|
40
46
|
} else if (
|
|
41
47
|
fieldType === "quantitative" &&
|
|
42
48
|
channel === "y" &&
|
|
@@ -89,6 +95,9 @@ function resolveBarChannelPolicy({
|
|
|
89
95
|
);
|
|
90
96
|
}
|
|
91
97
|
|
|
98
|
+
if (args.weight !== undefined) {
|
|
99
|
+
throw new Error("Bar weight is supported only for a binned x encoding.");
|
|
100
|
+
}
|
|
92
101
|
return { bin, aggregate, stack };
|
|
93
102
|
}
|
|
94
103
|
|
|
@@ -97,19 +97,26 @@ export function resolvePositionEncoding(program, channel, args, operation) {
|
|
|
97
97
|
args.target,
|
|
98
98
|
getPositionChannelDefinition(channel).markTypes
|
|
99
99
|
);
|
|
100
|
+
const previous = layer.encoding?.[channel];
|
|
100
101
|
if (isSourceOwnedText(layer)) {
|
|
101
102
|
throw new Error(`${operation} cannot replace source-owned Text positions; edit the source, use dx/dy, or create independent Text with data.`);
|
|
102
103
|
}
|
|
103
104
|
if (
|
|
104
105
|
Object.hasOwn(args, "weight") &&
|
|
105
|
-
!(layer.mark.type === "arc" && channel === "theta")
|
|
106
|
+
!(layer.mark.type === "arc" && channel === "theta") &&
|
|
107
|
+
!(layer.mark.type === "bar" && channel === "x" &&
|
|
108
|
+
(args.bin !== undefined || previous?.bin !== undefined))
|
|
106
109
|
) {
|
|
107
|
-
|
|
110
|
+
throw new Error(
|
|
111
|
+
`${operation} weight is supported only for arc theta encoding or histogram x encoding.`
|
|
112
|
+
);
|
|
108
113
|
}
|
|
109
114
|
if (Object.hasOwn(args, "mapping") && (layer.mark.type !== "arc" || channel !== "radius")) {
|
|
110
115
|
throw new Error(`${operation} mapping requires Arc radius.`);
|
|
111
116
|
}
|
|
112
117
|
validateCoordinateFamily(layer, channel, operation);
|
|
118
|
+
const clearRadialMapping =
|
|
119
|
+
layer.mark.type === "arc" && channel === "radius" && args.mapping === false;
|
|
113
120
|
const hasField = Object.hasOwn(args, "field");
|
|
114
121
|
const hasDatum = Object.hasOwn(args, "datum");
|
|
115
122
|
if (["rule", "rect", "text", "point", "tick"].includes(layer.mark.type)) {
|
|
@@ -128,9 +135,10 @@ export function resolvePositionEncoding(program, channel, args, operation) {
|
|
|
128
135
|
} else if (hasDatum) {
|
|
129
136
|
throw new Error(`${operation} does not support datum for a ${layer.mark.type} mark.`);
|
|
130
137
|
}
|
|
131
|
-
const previous = layer.encoding?.[channel];
|
|
132
138
|
const mapping = channel === "radius" && layer.mark.type === "arc"
|
|
133
|
-
?
|
|
139
|
+
? clearRadialMapping
|
|
140
|
+
? undefined
|
|
141
|
+
: args.mapping ?? findSemanticScale(program, previous?.scale)?.radialMapping
|
|
134
142
|
: undefined;
|
|
135
143
|
const countRadius = mapping !== undefined && (args.aggregate ?? previous?.aggregate) === "count";
|
|
136
144
|
const requestedFieldType = args.fieldType ?? previous?.fieldType ?? (
|
|
@@ -165,7 +173,9 @@ export function resolvePositionEncoding(program, channel, args, operation) {
|
|
|
165
173
|
validateAggregateFieldValues(dataset.values, field, fieldType);
|
|
166
174
|
} else readScaleField(dataset.values, field, fieldType, { temporalUnit });
|
|
167
175
|
}
|
|
168
|
-
const effectiveArgs = { ...args
|
|
176
|
+
const effectiveArgs = { ...args };
|
|
177
|
+
if (clearRadialMapping) delete effectiveArgs.mapping;
|
|
178
|
+
else if (mapping !== undefined) effectiveArgs.mapping = mapping;
|
|
169
179
|
const directQuantitativeArcTheta =
|
|
170
180
|
layer.mark.type === "arc" &&
|
|
171
181
|
channel === "theta" &&
|
|
@@ -173,7 +183,8 @@ export function resolvePositionEncoding(program, channel, args, operation) {
|
|
|
173
183
|
for (const property of ["aggregate", "bin", "stack"]) {
|
|
174
184
|
if (!Object.hasOwn(effectiveArgs, property) && previous !== undefined &&
|
|
175
185
|
Object.hasOwn(previous, property) &&
|
|
176
|
-
!(directQuantitativeArcTheta && property === "aggregate")
|
|
186
|
+
!(directQuantitativeArcTheta && property === "aggregate") &&
|
|
187
|
+
!(clearRadialMapping && property === "aggregate")) {
|
|
177
188
|
effectiveArgs[property] = previous[property];
|
|
178
189
|
}
|
|
179
190
|
}
|
|
@@ -201,7 +212,7 @@ export function resolvePositionEncoding(program, channel, args, operation) {
|
|
|
201
212
|
previous,
|
|
202
213
|
Object.hasOwn(args, "scale") ? args.scale : {}
|
|
203
214
|
);
|
|
204
|
-
const
|
|
215
|
+
const resolvedScale = resolvePositionScaleDefinition(
|
|
205
216
|
program,
|
|
206
217
|
channel,
|
|
207
218
|
aggregateOutput ? "quantitative" : fieldType,
|
|
@@ -229,6 +240,11 @@ export function resolvePositionEncoding(program, channel, args, operation) {
|
|
|
229
240
|
}
|
|
230
241
|
: {}
|
|
231
242
|
);
|
|
243
|
+
const scale = clearRadialMapping
|
|
244
|
+
? Object.fromEntries(
|
|
245
|
+
Object.entries(resolvedScale).filter(([property]) => property !== "radialMapping")
|
|
246
|
+
)
|
|
247
|
+
: resolvedScale;
|
|
232
248
|
if (
|
|
233
249
|
layer.mark.type === "bar" &&
|
|
234
250
|
program.markConfigs[target]?.boxPlot === undefined &&
|
|
@@ -310,6 +326,7 @@ export function resolvePositionEncoding(program, channel, args, operation) {
|
|
|
310
326
|
temporalUnit,
|
|
311
327
|
scale,
|
|
312
328
|
coordinate: resolveCoordinate(program, channel, layer, args.coordinate),
|
|
329
|
+
clearRadialMapping,
|
|
313
330
|
...policy
|
|
314
331
|
};
|
|
315
332
|
}
|
|
@@ -25,11 +25,12 @@ import { applyDetachedScaleRematerialization } from "../../materialization/depen
|
|
|
25
25
|
import { findDataset } from "../../selectors/datasets.js";
|
|
26
26
|
import { assertPathGroupCompatible, validatePathGroupAppearance } from "../../materialization/marks/grouping.js";
|
|
27
27
|
import { assertEncodingSelectionCompatibility } from "../../materialization/selection/compatibility.js";
|
|
28
|
+
import { planLegendBlockTransitions } from "../guides/legends/transition.js";
|
|
28
29
|
|
|
29
30
|
const OPTIONS = Object.freeze(["target", "channel"]);
|
|
30
31
|
const REMOVABLE_CHANNELS = Object.freeze([
|
|
31
32
|
"x", "y", "x2", "y2", "xOffset", "yOffset", "theta", "radius",
|
|
32
|
-
"color", "strokeDash", "strokeWidth", "size", "shape", "group",
|
|
33
|
+
"color", "stroke", "strokeDash", "strokeWidth", "size", "shape", "group",
|
|
33
34
|
"angle", "opacity", "text"
|
|
34
35
|
]);
|
|
35
36
|
const REMOVE_AXIS = Object.freeze({
|
|
@@ -40,6 +41,7 @@ const REMOVE_AXIS = Object.freeze({
|
|
|
40
41
|
});
|
|
41
42
|
const SPECIALIZED_LEGEND_KIND = Object.freeze({
|
|
42
43
|
color: Object.freeze(["gradient", "interval"]),
|
|
44
|
+
stroke: Object.freeze(["strokeGradient", "strokeInterval"]),
|
|
43
45
|
size: Object.freeze(["size"]),
|
|
44
46
|
opacity: Object.freeze(["opacity"]),
|
|
45
47
|
strokeWidth: Object.freeze(["strokeWidth"])
|
|
@@ -157,7 +159,7 @@ function cleanupPositionGuides(program, removed) {
|
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
function reconcileCategoricalLegend(program, target, channels) {
|
|
160
|
-
const entry = ["series", "color"]
|
|
162
|
+
const entry = ["series", "color", "stroke"]
|
|
161
163
|
.map(kind => [kind, program.guideConfigs.legend?.[kind]])
|
|
162
164
|
.find(([, config]) =>
|
|
163
165
|
config?.target === target &&
|
|
@@ -172,7 +174,10 @@ function reconcileCategoricalLegend(program, target, channels) {
|
|
|
172
174
|
if (remaining.length === 0) {
|
|
173
175
|
return removeLegendKinds(program, [kind]);
|
|
174
176
|
}
|
|
175
|
-
const
|
|
177
|
+
const resolved = resolveCategoricalLegendRevision(program, kind, config, remaining);
|
|
178
|
+
const revision = planLegendBlockTransitions(program, target, [
|
|
179
|
+
{ ...resolved, kind: resolved.config.kind }
|
|
180
|
+
])[0];
|
|
176
181
|
const next = removeLegendKinds(program, [kind]);
|
|
177
182
|
return createCategoricalLegendFromConfig(next, revision.config, revision.order);
|
|
178
183
|
}
|
|
@@ -218,7 +223,7 @@ export const removeEncoding = action(
|
|
|
218
223
|
}
|
|
219
224
|
const channels = activeCascade(layer, args.channel);
|
|
220
225
|
assertEncodingSelectionCompatibility(this, layer.id, channels);
|
|
221
|
-
for (const kind of ["series", "color"]) {
|
|
226
|
+
for (const kind of ["series", "color", "stroke"]) {
|
|
222
227
|
const config = this.guideConfigs.legend?.[kind];
|
|
223
228
|
const order = this.semanticSpec.guides.legend?.[kind]?.order;
|
|
224
229
|
if (config?.target === layer.id && channels.includes(order?.channel) &&
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { action } from "../../core/action.js";
|
|
2
|
-
import {
|
|
3
|
-
validateRuleStroke,
|
|
4
|
-
validateRuleStrokeWidth
|
|
5
|
-
} from "../../grammar/ruleAppearance.js";
|
|
2
|
+
import { validateRuleStrokeWidth } from "../../grammar/ruleAppearance.js";
|
|
6
3
|
import { readQuantitativeField } from "../../grammar/scales/index.js";
|
|
7
4
|
import { resolveStrokeWidthScaleDefinition } from "../scales/definitions.js";
|
|
8
5
|
import {
|
|
@@ -18,28 +15,10 @@ import { findLayer } from "../../selectors/layers.js";
|
|
|
18
15
|
import { validatePathSeriesAppearance } from "../../grammar/pathSeries.js";
|
|
19
16
|
import { assertEncodingSelectionCompatibility } from "../../materialization/selection/compatibility.js";
|
|
20
17
|
|
|
21
|
-
const STROKE_OPTIONS = Object.freeze(["target", "value"]);
|
|
22
18
|
const WIDTH_OPTIONS = Object.freeze([
|
|
23
19
|
"target", "value", "field", "fieldType", "scale"
|
|
24
20
|
]);
|
|
25
21
|
|
|
26
|
-
const encodeStroke = action(
|
|
27
|
-
{
|
|
28
|
-
op: "encodeStroke",
|
|
29
|
-
description: "Set a constant graphical stroke on a rule mark."
|
|
30
|
-
},
|
|
31
|
-
function (args = {}) {
|
|
32
|
-
validateOptions(args, STROKE_OPTIONS, "encodeStroke");
|
|
33
|
-
const { id } = resolveTarget(this, args.target, ["rule"], "rule mark");
|
|
34
|
-
return this
|
|
35
|
-
._withMarkConfig(id, {
|
|
36
|
-
...this.markConfigs[id],
|
|
37
|
-
stroke: validateRuleStroke(args.value)
|
|
38
|
-
})
|
|
39
|
-
.rematerializeRuleMark({ id });
|
|
40
|
-
}
|
|
41
|
-
);
|
|
42
|
-
|
|
43
22
|
const encodeStrokeWidth = action(
|
|
44
23
|
{
|
|
45
24
|
op: "encodeStrokeWidth",
|
|
@@ -119,6 +98,5 @@ const encodeStrokeWidth = action(
|
|
|
119
98
|
);
|
|
120
99
|
|
|
121
100
|
export function registerRuleAppearanceEncodingActions(ProgramClass) {
|
|
122
|
-
ProgramClass.prototype.encodeStroke = encodeStroke;
|
|
123
101
|
ProgramClass.prototype.encodeStrokeWidth = encodeStrokeWidth;
|
|
124
102
|
}
|
|
@@ -85,6 +85,7 @@ export const layoutSeries = action({ op: "layoutSeries", description: "Assign se
|
|
|
85
85
|
next = offset.field === undefined
|
|
86
86
|
? setEncodingProperties(next, target, offsetChannel, offset).createScale(offsetScale)
|
|
87
87
|
: next[offsetChannel === "xOffset" ? "encodeXOffset" : "encodeYOffset"]({ target, field: offset.field, fieldType: offset.fieldType, scale: offsetScale });
|
|
88
|
+
next = next._withoutMaterializationConfig(["marks", target, offsetChannel]);
|
|
88
89
|
if (findSemanticScale(this, offsetScale.id) === undefined) next = next._withMarkConfig(target, { ...next.markConfigs[target], seriesOffsetScale: offsetScale.id });
|
|
89
90
|
} else {
|
|
90
91
|
const owned = next.markConfigs[target]?.seriesOffsetScale;
|
|
@@ -8,6 +8,7 @@ import { planEncodingRematerialization } from "../../materialization/encodings.j
|
|
|
8
8
|
import { findSemanticScale } from "../../selectors/scales.js";
|
|
9
9
|
import { validateOptionObject } from "../../core/validation.js";
|
|
10
10
|
import { getMarkGraphicTypes, getPositionChannelDefinition } from "../../core/vocabulary.js";
|
|
11
|
+
import { DEFAULT_TICK_COUNT } from "../guides/tickValues.js";
|
|
11
12
|
|
|
12
13
|
export function validateOptions(args, supported, operation) {
|
|
13
14
|
validateOptionObject(args, supported, operation);
|
|
@@ -105,33 +106,100 @@ export function rebindPositionGuides(
|
|
|
105
106
|
const direction = definition.gridDirection;
|
|
106
107
|
const grid = program.semanticSpec.guides.grid?.[direction];
|
|
107
108
|
const ownsAxis = axis?.scale === previousScale;
|
|
109
|
+
const refreshesReboundAxis = axis?.scale === nextScale;
|
|
108
110
|
const ownsGrid = grid?.scale === previousScale;
|
|
109
|
-
if (!ownsAxis && !ownsGrid) return program;
|
|
111
|
+
if (!ownsAxis && !ownsGrid && !refreshesReboundAxis) return program;
|
|
110
112
|
|
|
111
113
|
const remaining = program.semanticSpec.layers.some(layer =>
|
|
112
114
|
layer.id !== target && !isSourceOwnedText(layer) && layer.encoding?.[channel]?.scale === previousScale
|
|
113
115
|
);
|
|
114
|
-
if (remaining) {
|
|
116
|
+
if ((ownsAxis || ownsGrid) && remaining) {
|
|
115
117
|
throw new Error(
|
|
116
118
|
`Cannot rebind ${channel} guides from shared scale "${previousScale}" while it has other consumers.`
|
|
117
119
|
);
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
let next = program;
|
|
121
|
-
if (ownsAxis) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
123
|
+
if (ownsAxis || refreshesReboundAxis) {
|
|
124
|
+
const previousAxisConfig = next.guideConfigs.axis?.[definition.guideChannel];
|
|
125
|
+
const previousTicks = previousAxisConfig?.ticks;
|
|
126
|
+
const previousLabels = previousAxisConfig?.labels;
|
|
127
|
+
const labelsFollowTicks = previousTicks !== undefined &&
|
|
128
|
+
previousLabels !== undefined &&
|
|
129
|
+
previousTicks.mode === previousLabels.mode &&
|
|
130
|
+
(previousTicks.mode === "count"
|
|
131
|
+
? previousTicks.count === previousLabels.count
|
|
132
|
+
: previousTicks.values?.length === previousLabels.values?.length &&
|
|
133
|
+
previousTicks.values.every(
|
|
134
|
+
(value, index) => Object.is(value, previousLabels.values[index])
|
|
135
|
+
));
|
|
136
|
+
if (ownsAxis) {
|
|
137
|
+
next = next.editSemantic({
|
|
138
|
+
property: `guide.axis.${definition.guideChannel}.scale`,
|
|
139
|
+
value: nextScale
|
|
140
|
+
});
|
|
141
|
+
for (const component of ["line", "ticks", "labels", "title"]) {
|
|
142
|
+
const config = next.guideConfigs.axis?.[definition.guideChannel]?.[component];
|
|
143
|
+
if (config?.scale === previousScale) {
|
|
144
|
+
next = next._withGuideConfig(definition.guideChannel, component, {
|
|
145
|
+
...config,
|
|
146
|
+
scale: nextScale
|
|
147
|
+
});
|
|
148
|
+
}
|
|
133
149
|
}
|
|
134
150
|
}
|
|
151
|
+
const resolved = next.resolvedScales[nextScale] ??
|
|
152
|
+
findSemanticScale(next, nextScale);
|
|
153
|
+
const discrete = ["ordinal", "band", "point"].includes(resolved?.type);
|
|
154
|
+
let ticks = next.guideConfigs.axis?.[definition.guideChannel]?.ticks;
|
|
155
|
+
if (ticks !== undefined && discrete && ticks.mode !== "values") {
|
|
156
|
+
ticks = {
|
|
157
|
+
...ticks,
|
|
158
|
+
mode: "values",
|
|
159
|
+
values: resolved.domain,
|
|
160
|
+
inferredValues: true
|
|
161
|
+
};
|
|
162
|
+
delete ticks.count;
|
|
163
|
+
next = next._withGuideConfig(definition.guideChannel, "ticks", ticks);
|
|
164
|
+
} else if (
|
|
165
|
+
ticks !== undefined &&
|
|
166
|
+
!discrete &&
|
|
167
|
+
ticks.mode === "values" &&
|
|
168
|
+
ticks.inferredValues === true
|
|
169
|
+
) {
|
|
170
|
+
ticks = {
|
|
171
|
+
...ticks,
|
|
172
|
+
mode: "count",
|
|
173
|
+
count: DEFAULT_TICK_COUNT,
|
|
174
|
+
inferredValues: true
|
|
175
|
+
};
|
|
176
|
+
delete ticks.values;
|
|
177
|
+
next = next._withGuideConfig(definition.guideChannel, "ticks", ticks);
|
|
178
|
+
} else if (
|
|
179
|
+
ticks !== undefined &&
|
|
180
|
+
discrete &&
|
|
181
|
+
ticks.inferredValues === true
|
|
182
|
+
) {
|
|
183
|
+
ticks = { ...ticks, values: resolved.domain };
|
|
184
|
+
next = next._withGuideConfig(definition.guideChannel, "ticks", ticks);
|
|
185
|
+
}
|
|
186
|
+
if (previousLabels !== undefined && labelsFollowTicks && ticks !== undefined) {
|
|
187
|
+
const labels = {
|
|
188
|
+
...next.guideConfigs.axis[definition.guideChannel].labels,
|
|
189
|
+
mode: ticks.mode,
|
|
190
|
+
inferredValues: ticks.inferredValues === true,
|
|
191
|
+
...(ticks.mode === "values"
|
|
192
|
+
? { values: ticks.values }
|
|
193
|
+
: { count: ticks.count })
|
|
194
|
+
};
|
|
195
|
+
if (ticks.mode === "values") delete labels.count;
|
|
196
|
+
else delete labels.values;
|
|
197
|
+
next = next._withGuideConfig(
|
|
198
|
+
definition.guideChannel,
|
|
199
|
+
"labels",
|
|
200
|
+
labels
|
|
201
|
+
);
|
|
202
|
+
}
|
|
135
203
|
}
|
|
136
204
|
if (ownsGrid) {
|
|
137
205
|
next = next
|