ggaction 0.0.13 → 0.0.16
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 +146 -0
- package/README.md +41 -12
- 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 +39 -7
- package/src/BasicChartProgram.js +3 -1
- package/src/ChartProgram.js +2 -0
- package/src/accessibility.js +157 -0
- package/src/actions/basic.js +2 -2
- package/src/actions/boxPlots/components.js +20 -12
- package/src/actions/boxPlots/create.js +4 -5
- package/src/actions/boxPlots/edit.js +34 -9
- package/src/actions/boxPlots/materialize.js +12 -4
- package/src/actions/boxPlots/options.js +48 -16
- package/src/actions/canvas/actions.js +3 -3
- package/src/actions/canvas/fitting.js +1 -1
- package/src/actions/categoryOrder/index.js +21 -12
- package/src/actions/charts/area.js +6 -2
- package/src/actions/charts/bar.js +3 -2
- package/src/actions/charts/beeswarm.js +1 -1
- package/src/actions/charts/density.js +7 -3
- package/src/actions/charts/ecdf.js +6 -3
- package/src/actions/charts/endpoints.js +29 -7
- package/src/actions/charts/heatmap.js +3 -2
- package/src/actions/charts/histogram.js +5 -4
- package/src/actions/charts/horizon.js +4 -2
- package/src/actions/charts/interval-regression.js +7 -4
- package/src/actions/charts/line.js +4 -2
- package/src/actions/charts/parallel.js +9 -3
- package/src/actions/charts/pie.js +11 -3
- package/src/actions/charts/polar.js +17 -6
- package/src/actions/charts/radar.js +9 -3
- package/src/actions/charts/radial.js +12 -4
- package/src/actions/charts/raincloud.js +2 -2
- package/src/actions/charts/rug-strip.js +8 -4
- package/src/actions/charts/scatter.js +4 -2
- package/src/actions/composition/actions.js +29 -24
- package/src/actions/coordinates/actions.js +2 -2
- package/src/actions/coordinates/edit.js +76 -0
- package/src/actions/data/basicBin2d.js +4 -5
- package/src/actions/data/bin.js +3 -3
- package/src/actions/data/bin2d.js +63 -193
- package/src/actions/data/bin2dMaterialize.js +4 -5
- package/src/actions/data/box.js +4 -4
- package/src/actions/data/complete.js +26 -0
- package/src/actions/data/computed.js +4 -4
- package/src/actions/data/create.js +7 -14
- package/src/actions/data/density.js +15 -23
- package/src/actions/data/derived.js +57 -31
- package/src/actions/data/ecdf.js +2 -2
- package/src/actions/data/edit.js +551 -0
- package/src/actions/data/filter.js +28 -22
- 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 +26 -0
- package/src/actions/data/index.js +62 -47
- package/src/actions/data/interval.js +2 -2
- package/src/actions/data/intervalEdit.js +26 -18
- package/src/actions/data/normalize.js +27 -0
- package/src/actions/data/regression.js +21 -27
- package/src/actions/data/revise.js +48 -0
- package/src/actions/data/revisionBindings.js +125 -0
- package/src/actions/data/shared.js +20 -4
- package/src/actions/data/stack.js +2 -2
- package/src/actions/data/summary.js +3 -3
- package/src/actions/data/timeUnit.js +6 -3
- package/src/actions/data/window.js +3 -3
- package/src/actions/encodings/angle.js +1 -1
- package/src/actions/encodings/appearance.js +4 -4
- package/src/actions/encodings/barWidth.js +1 -1
- package/src/actions/encodings/channels.js +415 -0
- package/src/actions/encodings/color/index.js +3 -2
- package/src/actions/encodings/density.js +7 -4
- package/src/actions/encodings/histogram.js +4 -3
- package/src/actions/encodings/horizon.js +6 -8
- package/src/actions/encodings/index.js +4 -0
- package/src/actions/encodings/offset.js +22 -15
- package/src/actions/encodings/parallel.js +4 -5
- package/src/actions/encodings/pathOrder.js +6 -11
- package/src/actions/encodings/position/apply.js +53 -7
- package/src/actions/encodings/position/index.js +14 -6
- package/src/actions/encodings/position/policies/bar.js +9 -0
- package/src/actions/encodings/position/resolve.js +24 -7
- package/src/actions/encodings/ranged.js +5 -5
- package/src/actions/encodings/remove.js +13 -9
- package/src/actions/encodings/ruleAppearance.js +2 -24
- package/src/actions/encodings/seriesLayout.js +2 -1
- package/src/actions/encodings/shared.js +82 -14
- package/src/actions/encodings/stroke.js +226 -0
- package/src/actions/encodings/strokeDash.js +2 -2
- package/src/actions/encodings/text.js +1 -1
- package/src/actions/errorBands/create.js +34 -20
- package/src/actions/errorBands/edit.js +34 -137
- package/src/actions/errorBars/create.js +43 -20
- package/src/actions/errorBars/edit.js +29 -125
- package/src/actions/facets/actions.js +267 -73
- package/src/actions/facets/derive.js +99 -28
- package/src/actions/facets/guides.js +4 -5
- package/src/actions/facets/replay.js +4 -5
- package/src/actions/gradientPlots/components.js +15 -8
- package/src/actions/gradientPlots/create.js +4 -5
- package/src/actions/gradientPlots/edit.js +18 -9
- package/src/actions/gradientPlots/materialize.js +5 -3
- package/src/actions/gradientPlots/options.js +10 -2
- package/src/actions/gradientPlots/rebind.js +4 -5
- package/src/actions/guides/applicability.js +8 -2
- 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 +67 -21
- package/src/actions/guides/axes/lines.js +15 -9
- package/src/actions/guides/axes/parallel/lifecycle.js +13 -13
- package/src/actions/guides/axes/parallel/resolve.js +6 -2
- 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 +6 -5
- package/src/actions/guides/axes/ticks.js +19 -6
- package/src/actions/guides/axes/titles.js +21 -13
- package/src/actions/guides/grids/grid.js +18 -29
- package/src/actions/guides/grids/resolve.js +7 -2
- package/src/actions/guides/guides.js +20 -4
- package/src/actions/guides/legends/blocks.js +426 -0
- package/src/actions/guides/legends/categorical/actions.js +138 -52
- package/src/actions/guides/legends/categorical/components.js +55 -45
- package/src/actions/guides/legends/categorical/index.js +37 -33
- package/src/actions/guides/legends/categorical/layout.js +98 -16
- 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 +104 -52
- package/src/actions/guides/legends/continuous/common.js +76 -20
- package/src/actions/guides/legends/continuous/gradient.js +95 -158
- package/src/actions/guides/legends/continuous/index.js +2 -0
- package/src/actions/guides/legends/continuous/interval.js +21 -16
- package/src/actions/guides/legends/continuous/opacity.js +37 -83
- package/src/actions/guides/legends/continuous/stroke.js +225 -0
- package/src/actions/guides/legends/creation.js +14 -1
- package/src/actions/guides/legends/edit.js +159 -60
- package/src/actions/guides/legends/focused.js +5 -5
- package/src/actions/guides/legends/index.js +2 -0
- package/src/actions/guides/legends/lane.js +59 -24
- package/src/actions/guides/legends/lifecycle.js +19 -8
- package/src/actions/guides/legends/remove.js +17 -8
- package/src/actions/guides/legends/sampling.js +140 -0
- package/src/actions/guides/legends/size.js +100 -108
- package/src/actions/guides/legends/strokeWidth.js +38 -92
- 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 +8 -8
- package/src/actions/guides/polar/axes/labels.js +29 -10
- package/src/actions/guides/polar/axes/lines.js +19 -19
- package/src/actions/guides/polar/axes/shared.js +16 -0
- package/src/actions/guides/polar/axes/ticks.js +10 -16
- package/src/actions/guides/polar/axes/titles.js +6 -6
- package/src/actions/guides/polar/grids.js +12 -14
- package/src/actions/guides/polar/resolve.js +12 -8
- package/src/actions/index.js +16 -3
- package/src/actions/intervals/revision.js +126 -0
- package/src/actions/marks/arc/actions.js +80 -22
- package/src/actions/marks/area/actions.js +38 -13
- package/src/actions/marks/area/materialize.js +17 -1
- package/src/actions/marks/bar/create.js +12 -3
- package/src/actions/marks/bar/edit.js +21 -4
- package/src/actions/marks/bar/materialize.js +34 -40
- package/src/actions/marks/index.js +10 -1
- package/src/actions/marks/line/actions.js +40 -17
- package/src/actions/marks/line/materialize.js +29 -10
- package/src/actions/marks/point/create.js +9 -3
- package/src/actions/marks/point/edit.js +19 -7
- package/src/actions/marks/point/jitter.js +6 -8
- package/src/actions/marks/point/materialize.js +48 -22
- package/src/actions/marks/point/packing.js +6 -8
- package/src/actions/marks/rect/actions.js +36 -15
- package/src/actions/marks/references.js +602 -33
- package/src/actions/marks/remove.js +67 -41
- package/src/actions/marks/rule/actions.js +51 -14
- package/src/actions/marks/shared.js +1 -1
- package/src/actions/marks/text/actions.js +79 -14
- package/src/actions/marks/text/index.js +4 -0
- package/src/actions/marks/text/layout.js +157 -17
- package/src/actions/marks/text/removal.js +173 -0
- package/src/actions/marks/text/selection.js +72 -0
- package/src/actions/marks/tick/actions.js +25 -8
- package/src/actions/primitives/createGraphics.js +5 -4
- package/src/actions/primitives/editGraphics.js +31 -4
- package/src/actions/primitives/graphicProperties.js +6 -0
- package/src/actions/primitives/semantic.js +11 -3
- package/src/actions/primitives/semanticAction.js +90 -14
- package/src/actions/primitives/semanticValidation/dataset.js +2 -4
- 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 +36 -25
- package/src/actions/regression/create.js +13 -6
- package/src/actions/regression/edit.js +24 -11
- package/src/actions/resources/index.js +7 -0
- package/src/actions/resources/remove.js +173 -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 +55 -23
- package/src/actions/scales/definitions.js +94 -40
- package/src/actions/scales/edit.js +67 -12
- package/src/actions/scales/editPolicy.js +81 -11
- package/src/actions/scales/index.js +6 -0
- package/src/actions/scales/materialize.js +5 -4
- 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/scales/quantitativeColor.js +4 -5
- package/src/actions/selection/actions.js +179 -66
- package/src/actions/selection/index.js +3 -0
- package/src/actions/textMetrics/index.js +56 -0
- package/src/actions/theme/actions.js +70 -15
- package/src/actions/theme/composition.js +238 -0
- package/src/actions/theme/index.js +9 -2
- package/src/actions/theme/reconcile.js +313 -121
- package/src/actions/theme/state.js +160 -0
- package/src/actions/titles/actions.js +8 -8
- package/src/actions/titles/resolve.js +3 -3
- package/src/actions/violinPlots/create.js +6 -3
- package/src/actions/violinPlots/edit.js +2 -1
- package/src/core/action.js +117 -35
- package/src/core/compositionState.js +6 -1
- 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 +21 -1
- package/src/core/resourceReferences.js +341 -0
- package/src/core/textMetricProfile.js +28 -0
- package/src/core/textMetrics.js +24 -3
- package/src/core/validation.js +22 -10
- package/src/core/vocabulary.js +16 -3
- package/src/diagnostics.js +1 -0
- 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 +341 -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/scales/types.js +8 -0
- package/src/grammar/schemas/concreteGraphic.js +14 -2
- package/src/grammar/schemas/graphic.js +15 -0
- package/src/grammar/schemas/graphicBounds.js +190 -41
- 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 +351 -7
- 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/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 +9 -3
- package/src/materialization/facetGuides/preparation.js +13 -8
- package/src/materialization/facetHeaders.js +347 -0
- package/src/materialization/facets.js +15 -65
- package/src/materialization/guides/layout.js +3 -3
- 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/scaleGuideDependencies.js +10 -0
- 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 +20 -5
- 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/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 +74 -0
- package/src/renderers/canvas/circle.js +2 -3
- package/src/renderers/canvas/index.js +5 -4
- 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/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 +29 -14
- package/src/renderers/text.js +1 -11
- package/src/selectors/coordinates.js +3 -1
- package/src/selectors/datasets.js +38 -5
- package/src/selectors/layers.js +10 -4
- package/src/selectors/markOwners.js +46 -0
- package/src/selectors/scales.js +6 -4
- package/src/theme/defaults.js +103 -1
- package/src/version.js +2 -0
- package/types/accessibility.d.ts +37 -0
- package/types/basic.d.ts +10 -2
- package/types/diagnostics.d.ts +15 -0
- package/types/index.d.ts +90 -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 +944 -118
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { currentIntervalRoleArgs, resolveIntervalRoleScales, applyIntervalStatistics } from "../intervals/revision.js";
|
|
2
|
+
import { closedAction } from "../../core/action.js";
|
|
2
3
|
import { isPlainObject } from "../../core/immutable.js";
|
|
3
4
|
import { validateUserId } from "../../core/identifiers.js";
|
|
4
|
-
import {
|
|
5
|
-
validateOptionObject,
|
|
6
|
-
validateKeys,
|
|
7
|
-
validateNonEmptyString,
|
|
8
|
-
validateNonNegativeFinite,
|
|
9
|
-
validateUnitInterval
|
|
10
|
-
} from "../../core/validation.js";
|
|
5
|
+
import { validateKeys, validateNonEmptyString, validateNonNegativeFinite, validateUnitInterval } from "../../core/validation.js";
|
|
11
6
|
import { validateCurveInterpolation } from "../../grammar/curveCommands.js";
|
|
12
7
|
import { normalizeStrokeDashPattern } from "../../grammar/scales/index.js";
|
|
8
|
+
import {
|
|
9
|
+
requestedStrokeDetails,
|
|
10
|
+
STROKE_STYLE_PROPERTIES
|
|
11
|
+
} from "../../grammar/strokeStyle.js";
|
|
13
12
|
import { findLayer } from "../../selectors/layers.js";
|
|
14
|
-
import { findSemanticScale } from "../../selectors/scales.js";
|
|
15
13
|
import { removeOwnedMark } from "../marks/remove.js";
|
|
16
14
|
import { DEFAULT_COLORS } from "../../theme/defaults.js";
|
|
17
15
|
import { resolveIntervalComposite } from "../intervals/resolve.js";
|
|
18
16
|
import {
|
|
19
|
-
resolveDistributionScalePlan,
|
|
20
17
|
setCartesianPosition,
|
|
21
18
|
updateDistributionPositions
|
|
22
19
|
} from "../distributions/revision.js";
|
|
@@ -32,7 +29,8 @@ import {
|
|
|
32
29
|
} from "../data/intervalEdit.js";
|
|
33
30
|
|
|
34
31
|
export const ERROR_BAND_BOUNDARY_OPTIONS = Object.freeze([
|
|
35
|
-
"stroke", "strokeWidth", "strokeDash", "opacity", "curve"
|
|
32
|
+
"stroke", "strokeWidth", "strokeDash", "opacity", "curve",
|
|
33
|
+
...STROKE_STYLE_PROPERTIES
|
|
36
34
|
]);
|
|
37
35
|
|
|
38
36
|
export function resolveBoundaryAppearance(value, { defaults, operation }) {
|
|
@@ -49,14 +47,20 @@ export function resolveBoundaryAppearance(value, { defaults, operation }) {
|
|
|
49
47
|
validateNonNegativeFinite(strokeWidth, `${operation} strokeWidth`);
|
|
50
48
|
const resolvedStrokeDash = normalizeStrokeDashPattern(strokeDash);
|
|
51
49
|
validateUnitInterval(opacity, `${operation} opacity`);
|
|
52
|
-
return {
|
|
50
|
+
return {
|
|
51
|
+
stroke,
|
|
52
|
+
strokeWidth,
|
|
53
|
+
strokeDash: resolvedStrokeDash,
|
|
54
|
+
opacity,
|
|
55
|
+
curve,
|
|
56
|
+
...requestedStrokeDetails({ ...defaults, ...value }, operation)
|
|
57
|
+
};
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
const EDIT_OPTIONS = Object.freeze([
|
|
56
61
|
"target", "data", "x", "y", "groupBy", "fill", "opacity", "curve",
|
|
57
|
-
"statistics", "boundaries"
|
|
62
|
+
"statistics", "boundaries", ...STROKE_STYLE_PROPERTIES
|
|
58
63
|
]);
|
|
59
|
-
const STATISTICS_OPTIONS = Object.freeze(["center", "extent", "method", "level"]);
|
|
60
64
|
const EDIT_POLICY = Object.freeze({
|
|
61
65
|
operation: "editErrorBand",
|
|
62
66
|
resourceLabel: "error-band",
|
|
@@ -104,48 +108,13 @@ function resolveOwner(program, requested) {
|
|
|
104
108
|
});
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
function currentRoleArgs(program, owner, current) {
|
|
108
|
-
const transform = findIntervalTransform(program, current.data);
|
|
109
|
-
const intervalChannel = current.orientation === "vertical" ? "y" : "x";
|
|
110
|
-
const positionChannel = intervalChannel === "x" ? "y" : "x";
|
|
111
|
-
const position = {
|
|
112
|
-
field: current.position.field,
|
|
113
|
-
fieldType: current.position.fieldType,
|
|
114
|
-
...(current.position.temporalUnit === undefined
|
|
115
|
-
? {}
|
|
116
|
-
: { temporalUnit: current.position.temporalUnit }),
|
|
117
|
-
scale: { id: current.positionScale }
|
|
118
|
-
};
|
|
119
|
-
const interval = transform === undefined
|
|
120
|
-
? {
|
|
121
|
-
center: current.centerField ?? owner.encoding[intervalChannel].title,
|
|
122
|
-
lower: current.lowerField,
|
|
123
|
-
upper: current.upperField,
|
|
124
|
-
scale: { id: current.intervalScale }
|
|
125
|
-
}
|
|
126
|
-
: {
|
|
127
|
-
field: transform.field,
|
|
128
|
-
center: transform.center,
|
|
129
|
-
extent: transform.extent,
|
|
130
|
-
...(transform.method === undefined ? {} : { method: transform.method }),
|
|
131
|
-
...(transform.level === undefined ? {} : { level: transform.level }),
|
|
132
|
-
scale: { id: current.intervalScale }
|
|
133
|
-
};
|
|
134
|
-
return {
|
|
135
|
-
source: current.source ?? transform?.source ?? current.data,
|
|
136
|
-
x: positionChannel === "x" ? position : interval,
|
|
137
|
-
y: positionChannel === "y" ? position : interval,
|
|
138
|
-
groupBy: current.groupBy
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
111
|
function channelArgs(requested, fallback) {
|
|
143
112
|
if (requested === undefined) return fallback;
|
|
144
113
|
return requested;
|
|
145
114
|
}
|
|
146
115
|
|
|
147
116
|
function resolveRoleCandidate(program, owner, current, args) {
|
|
148
|
-
const previous =
|
|
117
|
+
const previous = currentIntervalRoleArgs(program, owner, current, false);
|
|
149
118
|
const full = {
|
|
150
119
|
data: Object.hasOwn(args, "data") ? args.data : previous.source,
|
|
151
120
|
x: channelArgs(args.x, previous.x),
|
|
@@ -167,75 +136,11 @@ function resolveRoleCandidate(program, owner, current, args) {
|
|
|
167
136
|
"editErrorBand groupBy must differ from the independent position field."
|
|
168
137
|
);
|
|
169
138
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
throw new TypeError("editErrorBand statistics must be a plain object.");
|
|
173
|
-
}
|
|
174
|
-
validateKeys(args.statistics, STATISTICS_OPTIONS, "editErrorBand statistics");
|
|
175
|
-
if (!STATISTICS_OPTIONS.some(key => Object.hasOwn(args.statistics, key))) {
|
|
176
|
-
throw new Error(
|
|
177
|
-
"editErrorBand statistics requires center, extent, method, or level."
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
full[resolved.interval.channel] = {
|
|
181
|
-
...full[resolved.interval.channel],
|
|
182
|
-
...args.statistics
|
|
183
|
-
};
|
|
184
|
-
resolved = resolveIntervalComposite(program, full, policy);
|
|
185
|
-
}
|
|
186
|
-
const positionRole = {
|
|
187
|
-
field: resolved.position.field,
|
|
188
|
-
fieldType: resolved.position.fieldType,
|
|
189
|
-
scale: resolved.position.scale
|
|
190
|
-
};
|
|
191
|
-
const intervalTitle = resolved.interval.mode === "statistical"
|
|
192
|
-
? resolved.interval.field
|
|
193
|
-
: resolved.interval.title;
|
|
194
|
-
const intervalRole = {
|
|
195
|
-
field: intervalTitle,
|
|
196
|
-
fieldType: "quantitative",
|
|
197
|
-
scale: resolved.interval.scale
|
|
198
|
-
};
|
|
199
|
-
const x = resolved.position.channel === "x" ? positionRole : intervalRole;
|
|
200
|
-
const y = resolved.position.channel === "y" ? positionRole : intervalRole;
|
|
201
|
-
const plan = (channel, role) => {
|
|
202
|
-
const fallback = role === intervalRole
|
|
203
|
-
? current.intervalScale
|
|
204
|
-
: current.positionScale;
|
|
205
|
-
const stored = findSemanticScale(program, fallback);
|
|
206
|
-
const compatible = role.fieldType === "temporal"
|
|
207
|
-
? stored?.type === "time"
|
|
208
|
-
: ["linear", "log", "pow", "sqrt", "symlog"].includes(stored?.type);
|
|
209
|
-
const requested = role.scale.type !== undefined || compatible
|
|
210
|
-
? role.scale
|
|
211
|
-
: { ...role.scale, type: role.fieldType === "temporal" ? "time" : "linear" };
|
|
212
|
-
return resolveDistributionScalePlan(program, {
|
|
213
|
-
channel,
|
|
214
|
-
fieldType: role.fieldType,
|
|
215
|
-
requested,
|
|
216
|
-
fallback,
|
|
217
|
-
defaults: role === intervalRole
|
|
218
|
-
? EDIT_POLICY.intervalScaleDefaults
|
|
219
|
-
: EDIT_POLICY.scaleDefaults(role.fieldType)
|
|
220
|
-
});
|
|
221
|
-
};
|
|
222
|
-
const xScale = plan("x", x);
|
|
223
|
-
const yScale = plan("y", y);
|
|
139
|
+
resolved = applyIntervalStatistics(program, full, policy, args, resolved);
|
|
140
|
+
const roles = resolveIntervalRoleScales(program, resolved, current, EDIT_POLICY, owner, previous);
|
|
224
141
|
return {
|
|
225
142
|
...resolved,
|
|
226
|
-
|
|
227
|
-
y: { ...y, scale: yScale.id },
|
|
228
|
-
xScale,
|
|
229
|
-
yScale,
|
|
230
|
-
category: resolved.position.field,
|
|
231
|
-
categoryType: resolved.position.fieldType,
|
|
232
|
-
measure: intervalTitle,
|
|
233
|
-
previous: {
|
|
234
|
-
x: { field: previous.x.center ?? previous.x.field,
|
|
235
|
-
fieldType: owner.encoding.x.fieldType, scale: owner.encoding.x.scale },
|
|
236
|
-
y: { field: previous.y.center ?? previous.y.field,
|
|
237
|
-
fieldType: owner.encoding.y.fieldType, scale: owner.encoding.y.scale }
|
|
238
|
-
}
|
|
143
|
+
...roles
|
|
239
144
|
};
|
|
240
145
|
}
|
|
241
146
|
|
|
@@ -331,7 +236,8 @@ function currentBoundaryAppearance(program, id) {
|
|
|
331
236
|
strokeWidth: config.strokeWidth,
|
|
332
237
|
strokeDash: config.strokeDash,
|
|
333
238
|
opacity: config.opacity,
|
|
334
|
-
curve: config.curve ?? "linear"
|
|
239
|
+
curve: config.curve ?? "linear",
|
|
240
|
+
...requestedStrokeDetails(config, "Error-band boundary")
|
|
335
241
|
};
|
|
336
242
|
}
|
|
337
243
|
|
|
@@ -376,17 +282,12 @@ function removeBoundary(program, id) {
|
|
|
376
282
|
return removeOwnedMark(program, id);
|
|
377
283
|
}
|
|
378
284
|
|
|
379
|
-
export const rematerializeErrorBandBoundary =
|
|
285
|
+
export const rematerializeErrorBandBoundary = /* @__PURE__ */ closedAction(
|
|
380
286
|
{
|
|
381
287
|
op: "rematerializeErrorBandBoundary",
|
|
382
288
|
description: "Rematerialize one owned error-band boundary."
|
|
383
|
-
},
|
|
289
|
+
}, REMATERIALIZE_OPTIONS,
|
|
384
290
|
function (args = {}) {
|
|
385
|
-
validateOptionObject(
|
|
386
|
-
args,
|
|
387
|
-
REMATERIALIZE_OPTIONS,
|
|
388
|
-
"rematerializeErrorBandBoundary"
|
|
389
|
-
);
|
|
390
291
|
const id = validateUserId(args.id, "Error-band boundary id");
|
|
391
292
|
currentBoundaryAppearance(this, id);
|
|
392
293
|
const graphic = this.graphicSpec.objects[id];
|
|
@@ -397,7 +298,8 @@ export const rematerializeErrorBandBoundary = action(
|
|
|
397
298
|
strokeWidth: args.strokeWidth,
|
|
398
299
|
strokeDash: args.strokeDash,
|
|
399
300
|
opacity: args.opacity,
|
|
400
|
-
curve: args.curve
|
|
301
|
+
curve: args.curve,
|
|
302
|
+
...requestedStrokeDetails(args, "Error-band boundary")
|
|
401
303
|
})
|
|
402
304
|
.editGraphics({
|
|
403
305
|
target: id,
|
|
@@ -408,20 +310,20 @@ export const rematerializeErrorBandBoundary = action(
|
|
|
408
310
|
}
|
|
409
311
|
);
|
|
410
312
|
|
|
411
|
-
export const editErrorBand =
|
|
313
|
+
export const editErrorBand = /* @__PURE__ */ closedAction(
|
|
412
314
|
{
|
|
413
315
|
op: "editErrorBand",
|
|
414
316
|
description: "Revise one error band's roles, statistics, body, and boundaries."
|
|
415
|
-
},
|
|
317
|
+
}, EDIT_OPTIONS,
|
|
416
318
|
function (args = {}) {
|
|
417
|
-
validateOptionObject(args, EDIT_OPTIONS, "editErrorBand");
|
|
418
319
|
if (!["data", "x", "y", "groupBy", "fill", "opacity", "curve",
|
|
419
|
-
"statistics", "boundaries"]
|
|
320
|
+
"statistics", "boundaries", ...STROKE_STYLE_PROPERTIES]
|
|
420
321
|
.some(key => Object.hasOwn(args, key))) {
|
|
421
322
|
throw new Error("editErrorBand requires at least one change.");
|
|
422
323
|
}
|
|
423
324
|
const owner = resolveOwner(this, args.target);
|
|
424
325
|
const config = { ...this.markConfigs[owner.id] };
|
|
326
|
+
Object.assign(config, requestedStrokeDetails(args, "editErrorBand"));
|
|
425
327
|
const errorBand = { ...config.errorBand };
|
|
426
328
|
if (Object.hasOwn(args, "fill")) {
|
|
427
329
|
if (args.fill === false) {
|
|
@@ -570,17 +472,12 @@ export const editErrorBand = action(
|
|
|
570
472
|
}
|
|
571
473
|
);
|
|
572
474
|
|
|
573
|
-
export const editErrorBandBoundary =
|
|
475
|
+
export const editErrorBandBoundary = /* @__PURE__ */ closedAction(
|
|
574
476
|
{
|
|
575
477
|
op: "editErrorBandBoundary",
|
|
576
478
|
description: "Edit one or both owned error-band boundaries."
|
|
577
|
-
},
|
|
479
|
+
}, BOUNDARY_EDIT_OPTIONS,
|
|
578
480
|
function (args = {}) {
|
|
579
|
-
validateOptionObject(
|
|
580
|
-
args,
|
|
581
|
-
BOUNDARY_EDIT_OPTIONS,
|
|
582
|
-
"editErrorBandBoundary"
|
|
583
|
-
);
|
|
584
481
|
if (!ERROR_BAND_BOUNDARY_OPTIONS.some(key => Object.hasOwn(args, key))) {
|
|
585
482
|
throw new Error("editErrorBandBoundary requires an appearance change.");
|
|
586
483
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
validateKeys,
|
|
4
|
-
validateOptionObject
|
|
5
|
-
} from "../../core/validation.js";
|
|
1
|
+
import { closedAction } from "../../core/action.js";
|
|
2
|
+
import { validateOptionObject } from "../../core/validation.js";
|
|
6
3
|
import { findLayer } from "../../selectors/layers.js";
|
|
7
4
|
import { findDataset } from "../../selectors/datasets.js";
|
|
5
|
+
import { findSemanticScale } from "../../selectors/scales.js";
|
|
8
6
|
import { DEFAULT_COLORS } from "../../theme/defaults.js";
|
|
9
7
|
import {
|
|
10
8
|
readNominalField,
|
|
11
9
|
validateCategoricalFieldType
|
|
12
10
|
} from "../../grammar/scales/index.js";
|
|
13
11
|
import { normalizeOffsetPadding } from "../../grammar/bars/geometry.js";
|
|
12
|
+
import { STROKE_STYLE_PROPERTIES } from "../../grammar/strokeStyle.js";
|
|
14
13
|
import { createResolvedIntervalData, ownOptions } from
|
|
15
14
|
"../data/intervalEdit.js";
|
|
16
15
|
import { resolveIntervalComposite } from "../intervals/resolve.js";
|
|
@@ -31,7 +30,8 @@ const OPTIONS = Object.freeze([
|
|
|
31
30
|
"stroke",
|
|
32
31
|
"strokeWidth",
|
|
33
32
|
"strokeDash",
|
|
34
|
-
"opacity"
|
|
33
|
+
"opacity",
|
|
34
|
+
...STROKE_STYLE_PROPERTIES
|
|
35
35
|
]);
|
|
36
36
|
|
|
37
37
|
const OFFSET_OPTIONS = Object.freeze([
|
|
@@ -101,7 +101,15 @@ function resolveErrorBarOffset(program, args, resolved, operation) {
|
|
|
101
101
|
explicit ?? {},
|
|
102
102
|
resolved.sourceLayer === undefined
|
|
103
103
|
? undefined
|
|
104
|
-
:
|
|
104
|
+
: (() => {
|
|
105
|
+
const semantic = inferred?.scale === undefined
|
|
106
|
+
? undefined
|
|
107
|
+
: findSemanticScale(program, inferred.scale);
|
|
108
|
+
return semantic !== undefined && ["paddingInner", "paddingOuter"]
|
|
109
|
+
.some(property => Object.hasOwn(semantic, property))
|
|
110
|
+
? semantic
|
|
111
|
+
: program.markConfigs[resolved.sourceLayer.id]?.[channel];
|
|
112
|
+
})(),
|
|
105
113
|
channel
|
|
106
114
|
);
|
|
107
115
|
return {
|
|
@@ -118,7 +126,8 @@ function resolveErrorBarOffset(program, args, resolved, operation) {
|
|
|
118
126
|
|
|
119
127
|
function resolveAppearance(args) {
|
|
120
128
|
return resolveErrorBarAppearance(ownOptions(args, [
|
|
121
|
-
"caps", "capSize", "stroke", "strokeWidth", "strokeDash", "opacity"
|
|
129
|
+
"caps", "capSize", "stroke", "strokeWidth", "strokeDash", "opacity",
|
|
130
|
+
...STROKE_STYLE_PROPERTIES
|
|
122
131
|
]), {
|
|
123
132
|
defaults: {
|
|
124
133
|
caps: true,
|
|
@@ -132,19 +141,19 @@ function resolveAppearance(args) {
|
|
|
132
141
|
});
|
|
133
142
|
}
|
|
134
143
|
|
|
135
|
-
export const createErrorBarCap =
|
|
144
|
+
export const createErrorBarCap = /* @__PURE__ */ closedAction(
|
|
136
145
|
{
|
|
137
146
|
op: "createErrorBarCap",
|
|
138
147
|
description: "Create one fixed-pixel error-bar cap."
|
|
139
|
-
},
|
|
140
|
-
function (args = {}) {
|
|
141
|
-
validateKeys(args, [
|
|
148
|
+
}, [
|
|
142
149
|
"id", "data", "orientation", "positionField", "positionFieldType",
|
|
143
150
|
"intervalField", "coordinate", "positionScale", "intervalScale", "positionTemporalUnit",
|
|
144
151
|
"offsetChannel", "offsetField", "offsetFieldType", "offsetScale",
|
|
145
152
|
"offsetPaddingInner", "offsetPaddingOuter",
|
|
146
|
-
"capSize", "stroke", "strokeWidth", "strokeDash", "opacity"
|
|
147
|
-
|
|
153
|
+
"capSize", "stroke", "strokeWidth", "strokeDash", "opacity",
|
|
154
|
+
...STROKE_STYLE_PROPERTIES
|
|
155
|
+
],
|
|
156
|
+
function (args = {}) {
|
|
148
157
|
if (!["vertical", "horizontal"].includes(args.orientation)) {
|
|
149
158
|
throw new Error(`Unsupported error-bar orientation "${args.orientation}".`);
|
|
150
159
|
}
|
|
@@ -161,7 +170,13 @@ export const createErrorBarCap = action(
|
|
|
161
170
|
const positionAction = vertical ? "encodeX" : "encodeY";
|
|
162
171
|
const intervalAction = vertical ? "encodeY" : "encodeX";
|
|
163
172
|
let next = this
|
|
164
|
-
.createRuleMark({
|
|
173
|
+
.createRuleMark({
|
|
174
|
+
id: args.id,
|
|
175
|
+
data: args.data,
|
|
176
|
+
...Object.fromEntries(STROKE_STYLE_PROPERTIES.flatMap(property =>
|
|
177
|
+
Object.hasOwn(args, property) ? [[property, args[property]]] : []
|
|
178
|
+
))
|
|
179
|
+
})
|
|
165
180
|
[positionAction]({
|
|
166
181
|
target: args.id,
|
|
167
182
|
field: args.positionField,
|
|
@@ -237,17 +252,22 @@ function intervalArgs(resolved, field) {
|
|
|
237
252
|
};
|
|
238
253
|
}
|
|
239
254
|
|
|
240
|
-
export const createErrorBar =
|
|
255
|
+
export const createErrorBar = /* @__PURE__ */ closedAction(
|
|
241
256
|
{
|
|
242
257
|
op: "createErrorBar",
|
|
243
258
|
description: "Create a statistical or explicit vertical or horizontal interval."
|
|
244
|
-
},
|
|
259
|
+
}, OPTIONS,
|
|
245
260
|
function (args = {}) {
|
|
246
|
-
validateKeys(args, OPTIONS, "createErrorBar");
|
|
247
261
|
const resolved = resolveErrorBar(this, args);
|
|
248
262
|
const appearance = resolveAppearance(args);
|
|
249
263
|
let next = createResolvedIntervalData(this, resolved);
|
|
250
|
-
next = next.createRuleMark({
|
|
264
|
+
next = next.createRuleMark({
|
|
265
|
+
id: resolved.id,
|
|
266
|
+
data: resolved.dataId,
|
|
267
|
+
...Object.fromEntries(STROKE_STYLE_PROPERTIES.flatMap(property =>
|
|
268
|
+
Object.hasOwn(appearance, property) ? [[property, appearance[property]]] : []
|
|
269
|
+
))
|
|
270
|
+
});
|
|
251
271
|
const positionAction = resolved.position.channel === "x" ? "encodeX" : "encodeY";
|
|
252
272
|
const intervalAction = resolved.interval.channel === "x" ? "encodeX" : "encodeY";
|
|
253
273
|
const secondaryAction = resolved.interval.channel === "x" ? "encodeX2" : "encodeY2";
|
|
@@ -303,7 +323,10 @@ export const createErrorBar = action(
|
|
|
303
323
|
stroke: appearance.stroke,
|
|
304
324
|
strokeWidth: appearance.strokeWidth,
|
|
305
325
|
strokeDash: appearance.strokeDash,
|
|
306
|
-
opacity: appearance.opacity
|
|
326
|
+
opacity: appearance.opacity,
|
|
327
|
+
...Object.fromEntries(STROKE_STYLE_PROPERTIES.flatMap(property =>
|
|
328
|
+
Object.hasOwn(appearance, property) ? [[property, appearance[property]]] : []
|
|
329
|
+
))
|
|
307
330
|
});
|
|
308
331
|
}
|
|
309
332
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { currentIntervalRoleArgs, resolveIntervalRoleScales, applyIntervalStatistics } from "../intervals/revision.js";
|
|
2
|
+
import { closedAction } from "../../core/action.js";
|
|
3
3
|
import { validateUserId } from "../../core/identifiers.js";
|
|
4
4
|
import {
|
|
5
5
|
validateKeys,
|
|
@@ -14,10 +14,8 @@ import {
|
|
|
14
14
|
validateRuleStrokeWidth
|
|
15
15
|
} from "../../grammar/ruleAppearance.js";
|
|
16
16
|
import { findLayer } from "../../selectors/layers.js";
|
|
17
|
-
import { findSemanticScale } from "../../selectors/scales.js";
|
|
18
17
|
import { resolveIntervalComposite } from "../intervals/resolve.js";
|
|
19
18
|
import {
|
|
20
|
-
resolveDistributionScalePlan,
|
|
21
19
|
setCartesianPosition,
|
|
22
20
|
updateDistributionPositions
|
|
23
21
|
} from "../distributions/revision.js";
|
|
@@ -31,17 +29,21 @@ import {
|
|
|
31
29
|
releaseIntervalRevision,
|
|
32
30
|
resolveIntervalOwner
|
|
33
31
|
} from "../data/intervalEdit.js";
|
|
32
|
+
import {
|
|
33
|
+
requestedStrokeDetails,
|
|
34
|
+
STROKE_STYLE_PROPERTIES
|
|
35
|
+
} from "../../grammar/strokeStyle.js";
|
|
34
36
|
|
|
35
37
|
export const ERROR_BAR_EDIT_OPTIONS = Object.freeze([
|
|
36
38
|
"target", "data", "x", "y", "xOffset", "yOffset", "groupBy",
|
|
37
39
|
"caps", "capSize", "stroke", "strokeWidth", "strokeDash", "opacity",
|
|
38
|
-
"statistics"
|
|
40
|
+
"statistics", ...STROKE_STYLE_PROPERTIES
|
|
39
41
|
]);
|
|
40
42
|
|
|
41
43
|
export const ERROR_BAR_APPEARANCE_OPTIONS = Object.freeze([
|
|
42
|
-
"caps", "capSize", "stroke", "strokeWidth", "strokeDash", "opacity"
|
|
44
|
+
"caps", "capSize", "stroke", "strokeWidth", "strokeDash", "opacity",
|
|
45
|
+
...STROKE_STYLE_PROPERTIES
|
|
43
46
|
]);
|
|
44
|
-
const STATISTICS_OPTIONS = Object.freeze(["center", "extent", "method", "level"]);
|
|
45
47
|
const EDIT_POLICY = Object.freeze({
|
|
46
48
|
operation: "editErrorBar",
|
|
47
49
|
resourceLabel: "error-bar",
|
|
@@ -81,7 +83,15 @@ export function resolveErrorBarAppearance(args, { defaults, operation }) {
|
|
|
81
83
|
args.opacity ?? defaults.opacity,
|
|
82
84
|
`${operation} opacity`
|
|
83
85
|
);
|
|
84
|
-
return {
|
|
86
|
+
return {
|
|
87
|
+
caps,
|
|
88
|
+
capSize,
|
|
89
|
+
stroke,
|
|
90
|
+
strokeWidth,
|
|
91
|
+
strokeDash,
|
|
92
|
+
opacity,
|
|
93
|
+
...requestedStrokeDetails({ ...defaults, ...args }, operation)
|
|
94
|
+
};
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
const REMATERIALIZE_OPTIONS = Object.freeze(["id"]);
|
|
@@ -102,45 +112,8 @@ function resolveOwner(program, requested) {
|
|
|
102
112
|
});
|
|
103
113
|
}
|
|
104
114
|
|
|
105
|
-
function currentRoleArgs(program, owner, current) {
|
|
106
|
-
const transform = findIntervalTransform(program, current.data);
|
|
107
|
-
const intervalChannel = current.orientation === "vertical" ? "y" : "x";
|
|
108
|
-
const positionChannel = intervalChannel === "x" ? "y" : "x";
|
|
109
|
-
const position = {
|
|
110
|
-
field: current.positionField,
|
|
111
|
-
fieldType: current.positionFieldType,
|
|
112
|
-
...(current.positionTemporalUnit === undefined
|
|
113
|
-
? {}
|
|
114
|
-
: { temporalUnit: current.positionTemporalUnit }),
|
|
115
|
-
scale: { id: current.positionScale }
|
|
116
|
-
};
|
|
117
|
-
const interval = transform === undefined
|
|
118
|
-
? {
|
|
119
|
-
center: current.centerField ?? owner.encoding[intervalChannel].title,
|
|
120
|
-
lower: current.lowerField,
|
|
121
|
-
upper: current.upperField,
|
|
122
|
-
scale: { id: current.intervalScale }
|
|
123
|
-
}
|
|
124
|
-
: {
|
|
125
|
-
field: transform.field,
|
|
126
|
-
center: transform.center,
|
|
127
|
-
extent: transform.extent,
|
|
128
|
-
...(transform.method === undefined ? {} : { method: transform.method }),
|
|
129
|
-
...(transform.level === undefined ? {} : { level: transform.level }),
|
|
130
|
-
scale: { id: current.intervalScale }
|
|
131
|
-
};
|
|
132
|
-
return {
|
|
133
|
-
source: current.source ?? transform?.source ?? current.data,
|
|
134
|
-
x: positionChannel === "x" ? position : interval,
|
|
135
|
-
y: positionChannel === "y" ? position : interval,
|
|
136
|
-
groupBy: current.groupField ?? transform?.groupBy?.find(
|
|
137
|
-
field => field !== current.positionField
|
|
138
|
-
)
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
115
|
function resolveRoleCandidate(program, owner, current, args) {
|
|
143
|
-
const previous =
|
|
116
|
+
const previous = currentIntervalRoleArgs(program, owner, current, true);
|
|
144
117
|
const full = {
|
|
145
118
|
data: Object.hasOwn(args, "data") ? args.data : previous.source,
|
|
146
119
|
x: Object.hasOwn(args, "x") ? args.x : previous.x,
|
|
@@ -157,65 +130,8 @@ function resolveRoleCandidate(program, owner, current, args) {
|
|
|
157
130
|
generatedFields: findIntervalTransform(program, current.data)?.as
|
|
158
131
|
};
|
|
159
132
|
let resolved = resolveIntervalComposite(program, full, policy);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
throw new TypeError("editErrorBar statistics must be a plain object.");
|
|
163
|
-
}
|
|
164
|
-
validateKeys(args.statistics, STATISTICS_OPTIONS, "editErrorBar statistics");
|
|
165
|
-
if (!STATISTICS_OPTIONS.some(key => Object.hasOwn(args.statistics, key))) {
|
|
166
|
-
throw new Error(
|
|
167
|
-
"editErrorBar statistics requires center, extent, method, or level."
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
full[resolved.interval.channel] = {
|
|
171
|
-
...full[resolved.interval.channel],
|
|
172
|
-
...args.statistics
|
|
173
|
-
};
|
|
174
|
-
resolved = resolveIntervalComposite(program, full, policy);
|
|
175
|
-
}
|
|
176
|
-
const positionRole = {
|
|
177
|
-
field: resolved.position.field,
|
|
178
|
-
fieldType: resolved.position.fieldType,
|
|
179
|
-
scale: resolved.position.scale
|
|
180
|
-
};
|
|
181
|
-
const intervalTitle = resolved.interval.mode === "statistical"
|
|
182
|
-
? resolved.interval.field
|
|
183
|
-
: resolved.interval.title;
|
|
184
|
-
const intervalRole = {
|
|
185
|
-
field: intervalTitle,
|
|
186
|
-
fieldType: "quantitative",
|
|
187
|
-
scale: resolved.interval.scale
|
|
188
|
-
};
|
|
189
|
-
const x = resolved.position.channel === "x" ? positionRole : intervalRole;
|
|
190
|
-
const y = resolved.position.channel === "y" ? positionRole : intervalRole;
|
|
191
|
-
const plan = (channel, role) => {
|
|
192
|
-
const fallback = role === intervalRole
|
|
193
|
-
? current.intervalScale
|
|
194
|
-
: current.positionScale;
|
|
195
|
-
const stored = findSemanticScale(program, fallback);
|
|
196
|
-
const compatible = role.fieldType === "temporal"
|
|
197
|
-
? stored?.type === "time"
|
|
198
|
-
: ["nominal", "ordinal"].includes(role.fieldType)
|
|
199
|
-
? ["band", "point"].includes(stored?.type)
|
|
200
|
-
: ["linear", "log", "pow", "sqrt", "symlog"].includes(stored?.type);
|
|
201
|
-
const defaultType = role.fieldType === "temporal"
|
|
202
|
-
? "time"
|
|
203
|
-
: ["nominal", "ordinal"].includes(role.fieldType) ? "band" : "linear";
|
|
204
|
-
const requested = role.scale.type !== undefined || compatible
|
|
205
|
-
? role.scale
|
|
206
|
-
: { ...role.scale, type: defaultType };
|
|
207
|
-
return resolveDistributionScalePlan(program, {
|
|
208
|
-
channel,
|
|
209
|
-
fieldType: role.fieldType,
|
|
210
|
-
requested,
|
|
211
|
-
fallback,
|
|
212
|
-
defaults: role === intervalRole
|
|
213
|
-
? EDIT_POLICY.intervalScaleDefaults
|
|
214
|
-
: EDIT_POLICY.scaleDefaults(role.fieldType)
|
|
215
|
-
});
|
|
216
|
-
};
|
|
217
|
-
const xScale = plan("x", x);
|
|
218
|
-
const yScale = plan("y", y);
|
|
133
|
+
resolved = applyIntervalStatistics(program, full, policy, args, resolved);
|
|
134
|
+
const roles = resolveIntervalRoleScales(program, resolved, current, EDIT_POLICY, owner, previous);
|
|
219
135
|
const expectedOffset = `${resolved.position.channel}Offset`;
|
|
220
136
|
const incompatibleOffset = expectedOffset === "xOffset" ? "yOffset" : "xOffset";
|
|
221
137
|
if (Object.hasOwn(args, incompatibleOffset)) {
|
|
@@ -257,19 +173,7 @@ function resolveRoleCandidate(program, owner, current, args) {
|
|
|
257
173
|
return {
|
|
258
174
|
...resolved,
|
|
259
175
|
offset: normalizedOffset,
|
|
260
|
-
|
|
261
|
-
y: { ...y, scale: yScale.id },
|
|
262
|
-
xScale,
|
|
263
|
-
yScale,
|
|
264
|
-
category: resolved.position.field,
|
|
265
|
-
categoryType: resolved.position.fieldType,
|
|
266
|
-
measure: intervalTitle,
|
|
267
|
-
previous: {
|
|
268
|
-
x: { field: previous.x.center ?? previous.x.field,
|
|
269
|
-
fieldType: owner.encoding.x.fieldType, scale: owner.encoding.x.scale },
|
|
270
|
-
y: { field: previous.y.center ?? previous.y.field,
|
|
271
|
-
fieldType: owner.encoding.y.fieldType, scale: owner.encoding.y.scale }
|
|
272
|
-
}
|
|
176
|
+
...roles
|
|
273
177
|
};
|
|
274
178
|
}
|
|
275
179
|
|
|
@@ -307,7 +211,8 @@ function capArgs(config, id, intervalField) {
|
|
|
307
211
|
stroke: config.stroke,
|
|
308
212
|
strokeWidth: config.strokeWidth,
|
|
309
213
|
strokeDash: config.strokeDash,
|
|
310
|
-
opacity: config.opacity
|
|
214
|
+
opacity: config.opacity,
|
|
215
|
+
...requestedStrokeDetails(config, "Error bar")
|
|
311
216
|
};
|
|
312
217
|
}
|
|
313
218
|
|
|
@@ -323,6 +228,7 @@ function rematerializeRuleAppearance(program, id, config, fixedSpan) {
|
|
|
323
228
|
strokeWidth: config.strokeWidth,
|
|
324
229
|
strokeDash: config.strokeDash,
|
|
325
230
|
opacity: config.opacity,
|
|
231
|
+
...requestedStrokeDetails(config, "Error bar"),
|
|
326
232
|
...(fixedSpan === undefined ? {} : { fixedSpan })
|
|
327
233
|
})
|
|
328
234
|
.rematerializeRuleMark({ id });
|
|
@@ -445,13 +351,12 @@ function updateErrorBarRoles(program, owner, current, candidate, dataId, capIds)
|
|
|
445
351
|
return next.rematerializeErrorBar({ id: owner.id });
|
|
446
352
|
}
|
|
447
353
|
|
|
448
|
-
export const rematerializeErrorBar =
|
|
354
|
+
export const rematerializeErrorBar = /* @__PURE__ */ closedAction(
|
|
449
355
|
{
|
|
450
356
|
op: "rematerializeErrorBar",
|
|
451
357
|
description: "Reconcile one error bar and its owned caps."
|
|
452
|
-
},
|
|
358
|
+
}, REMATERIALIZE_OPTIONS,
|
|
453
359
|
function (args = {}) {
|
|
454
|
-
validateKeys(args, REMATERIALIZE_OPTIONS, "rematerializeErrorBar");
|
|
455
360
|
const id = validateUserId(args.id, "Error-bar id");
|
|
456
361
|
const layer = findLayer(this, id);
|
|
457
362
|
const config = this.markConfigs[id]?.errorBar;
|
|
@@ -479,13 +384,12 @@ export const rematerializeErrorBar = action(
|
|
|
479
384
|
}
|
|
480
385
|
);
|
|
481
386
|
|
|
482
|
-
export const editErrorBar =
|
|
387
|
+
export const editErrorBar = /* @__PURE__ */ closedAction(
|
|
483
388
|
{
|
|
484
389
|
op: "editErrorBar",
|
|
485
390
|
description: "Revise one error bar's roles, statistics, and owned caps."
|
|
486
|
-
},
|
|
391
|
+
}, ERROR_BAR_EDIT_OPTIONS,
|
|
487
392
|
function (args = {}) {
|
|
488
|
-
validateKeys(args, ERROR_BAR_EDIT_OPTIONS, "editErrorBar");
|
|
489
393
|
const editable = ERROR_BAR_EDIT_OPTIONS.filter(option => option !== "target");
|
|
490
394
|
if (!editable.some(option => Object.hasOwn(args, option))) {
|
|
491
395
|
throw new Error("editErrorBar requires at least one change.");
|