ggaction 0.0.12 → 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 +127 -0
- package/README.md +20 -11
- package/knowledge/action-card.schema.json +1 -1
- package/knowledge/action-cards.json +1 -1
- package/knowledge/action-cards.schema.json +1 -1
- package/knowledge/extension-authoring.md +2 -1
- package/knowledge/intent-taxonomy.json +1 -1
- package/knowledge/mcp-resources.json +1 -1
- package/knowledge/task-resolver.js +1 -1
- package/package.json +10 -3
- package/src/actions/basic.js +4 -2
- package/src/actions/boxPlots/components.js +14 -4
- package/src/actions/boxPlots/edit.js +31 -5
- package/src/actions/boxPlots/materialize.js +13 -4
- package/src/actions/boxPlots/options.js +48 -16
- package/src/actions/canvas/actions.js +3 -1
- package/src/actions/canvas/fitting.js +211 -0
- package/src/actions/canvas/index.js +2 -0
- package/src/actions/categoryOrder/index.js +18 -6
- package/src/actions/charts/area.js +51 -0
- package/src/actions/charts/bar.js +13 -6
- package/src/actions/charts/beeswarm.js +70 -0
- package/src/actions/charts/density.js +48 -0
- package/src/actions/charts/ecdf.js +186 -0
- package/src/actions/charts/endpoints.js +473 -0
- package/src/actions/charts/heatmap.js +4 -3
- package/src/actions/charts/histogram.js +5 -4
- package/src/actions/charts/horizon.js +73 -0
- package/src/actions/charts/index.js +37 -0
- package/src/actions/charts/interval-regression.js +172 -0
- package/src/actions/charts/line.js +8 -6
- package/src/actions/charts/parallel.js +8 -2
- package/src/actions/charts/pie.js +52 -0
- package/src/actions/charts/polar.js +134 -0
- package/src/actions/charts/radar.js +305 -0
- package/src/actions/charts/radial.js +50 -0
- package/src/actions/charts/raincloud.js +422 -0
- package/src/actions/charts/rug-strip.js +283 -0
- package/src/actions/charts/scatter.js +11 -3
- package/src/actions/charts/shared.js +69 -10
- package/src/actions/composition/actions.js +129 -3
- package/src/actions/coordinates/actions.js +1 -1
- package/src/actions/coordinates/edit.js +76 -0
- package/src/actions/data/bin.js +29 -0
- package/src/actions/data/bin2d.js +57 -185
- package/src/actions/data/complete.js +26 -0
- package/src/actions/data/computed.js +24 -0
- package/src/actions/data/create.js +2 -2
- package/src/actions/data/density.js +12 -20
- package/src/actions/data/derived.js +111 -15
- package/src/actions/data/ecdf.js +38 -0
- package/src/actions/data/edit.js +539 -0
- package/src/actions/data/filter.js +226 -30
- package/src/actions/data/fold.js +24 -0
- package/src/actions/data/impute.js +26 -0
- package/src/actions/data/index.js +38 -0
- package/src/actions/data/interval.js +2 -0
- package/src/actions/data/intervalEdit.js +86 -4
- package/src/actions/data/normalize.js +27 -0
- package/src/actions/data/regression.js +19 -21
- package/src/actions/data/revisionBindings.js +145 -0
- package/src/actions/data/shared.js +20 -4
- package/src/actions/data/stack.js +26 -0
- package/src/actions/data/summary.js +26 -0
- package/src/actions/data/timeUnit.js +4 -1
- package/src/actions/data/window.js +1 -1
- package/src/actions/encodings/appearance.js +32 -13
- package/src/actions/encodings/barWidth.js +8 -0
- package/src/actions/encodings/basic.js +2 -0
- package/src/actions/encodings/channels.js +415 -0
- package/src/actions/encodings/color/continuous.js +19 -59
- package/src/actions/encodings/color/index.js +30 -23
- package/src/actions/encodings/color/layout.js +3 -97
- package/src/actions/encodings/color/policy.js +5 -8
- package/src/actions/encodings/density/resolve.js +37 -5
- package/src/actions/encodings/density.js +124 -34
- package/src/actions/encodings/histogram.js +3 -2
- package/src/actions/encodings/horizon/resolve.js +8 -4
- package/src/actions/encodings/horizon.js +18 -8
- package/src/actions/encodings/index.js +6 -0
- package/src/actions/encodings/offset.js +30 -29
- package/src/actions/encodings/parallel.js +2 -8
- package/src/actions/encodings/position/apply.js +63 -11
- package/src/actions/encodings/position/index.js +52 -6
- package/src/actions/encodings/position/policies/arc.js +14 -0
- package/src/actions/encodings/position/policies/area.js +4 -42
- package/src/actions/encodings/position/policies/bar.js +57 -13
- package/src/actions/encodings/position/resolve.js +88 -26
- package/src/actions/encodings/ranged.js +123 -97
- package/src/actions/encodings/remove.js +44 -34
- package/src/actions/encodings/ruleAppearance.js +24 -32
- package/src/actions/encodings/seriesLayout.js +105 -0
- package/src/actions/encodings/shared.js +107 -37
- package/src/actions/encodings/stroke.js +226 -0
- package/src/actions/encodings/strokeDash.js +9 -6
- package/src/actions/encodings/temporal.js +7 -0
- package/src/actions/encodings/text.js +30 -15
- package/src/actions/errorBands/create.js +41 -8
- package/src/actions/errorBands/edit.js +360 -25
- package/src/actions/errorBars/create.js +56 -17
- package/src/actions/errorBars/edit.js +372 -21
- package/src/actions/facets/actions.js +619 -41
- package/src/actions/facets/derive.js +139 -25
- package/src/actions/gradientPlots/components.js +43 -13
- package/src/actions/gradientPlots/edit.js +14 -4
- package/src/actions/gradientPlots/materialize.js +8 -8
- package/src/actions/gradientPlots/options.js +10 -2
- package/src/actions/guides/applicability.js +28 -19
- package/src/actions/guides/axes/axes.js +4 -3
- package/src/actions/guides/axes/axis.js +18 -18
- package/src/actions/guides/axes/components.js +43 -0
- package/src/actions/guides/axes/edit.js +16 -51
- package/src/actions/guides/axes/labels.js +184 -28
- package/src/actions/guides/axes/lines.js +13 -7
- package/src/actions/guides/axes/parallel/lifecycle.js +117 -0
- package/src/actions/guides/axes/parallel/policy.js +137 -0
- package/src/actions/guides/axes/parallel/resolve.js +50 -25
- package/src/actions/guides/axes/parallel.js +93 -217
- package/src/actions/guides/axes/policy.js +21 -67
- package/src/actions/guides/axes/tickGroups.js +15 -8
- package/src/actions/guides/axes/ticks.js +11 -6
- package/src/actions/guides/axes/titles.js +32 -11
- package/src/actions/guides/basic.js +2 -0
- package/src/actions/guides/facade.js +106 -0
- package/src/actions/guides/facadeAxes.js +200 -0
- package/src/actions/guides/facadeLegend.js +63 -0
- package/src/actions/guides/grids/grid.js +37 -33
- package/src/actions/guides/grids/resolve.js +17 -4
- package/src/actions/guides/guides.js +54 -31
- package/src/actions/guides/legends/blocks.js +426 -0
- package/src/actions/guides/legends/categorical/actions.js +309 -279
- package/src/actions/guides/legends/categorical/components.js +21 -17
- package/src/actions/guides/legends/categorical/index.js +37 -33
- package/src/actions/guides/legends/categorical/layout.js +123 -354
- package/src/actions/guides/legends/categorical/options.js +32 -16
- package/src/actions/guides/legends/categorical/recipes.js +114 -9
- package/src/actions/guides/legends/categorical/resolve.js +30 -15
- package/src/actions/guides/legends/categorical/symbols.js +87 -33
- package/src/actions/guides/legends/continuous/common.js +99 -26
- package/src/actions/guides/legends/continuous/gradient.js +120 -89
- package/src/actions/guides/legends/continuous/index.js +8 -2
- package/src/actions/guides/legends/continuous/interval.js +79 -95
- package/src/actions/guides/legends/continuous/opacity.js +113 -89
- package/src/actions/guides/legends/continuous/stroke.js +525 -0
- package/src/actions/guides/legends/creation.js +40 -0
- package/src/actions/guides/legends/edit.js +321 -90
- package/src/actions/guides/legends/focused.js +2 -2
- package/src/actions/guides/legends/index.js +2 -0
- package/src/actions/guides/legends/lane.js +149 -102
- package/src/actions/guides/legends/lifecycle.js +143 -0
- package/src/actions/guides/legends/remove.js +43 -78
- package/src/actions/guides/legends/sampling.js +140 -0
- package/src/actions/guides/legends/size.js +213 -116
- package/src/actions/guides/legends/strokeWidth.js +121 -73
- package/src/actions/guides/legends/target.js +123 -0
- package/src/actions/guides/legends/transition.js +192 -0
- package/src/actions/guides/polar/axes/facade.js +81 -66
- package/src/actions/guides/polar/axes/labels.js +28 -8
- package/src/actions/guides/polar/axes/lines.js +12 -5
- package/src/actions/guides/polar/axes/shared.js +22 -0
- package/src/actions/guides/polar/axes/ticks.js +6 -5
- package/src/actions/guides/polar/axes/titles.js +6 -5
- package/src/actions/guides/polar/grids.js +8 -8
- package/src/actions/guides/polar/resolve.js +12 -8
- package/src/actions/guides/reuse.js +44 -0
- package/src/actions/guides/tickValues.js +19 -21
- package/src/actions/index.js +15 -2
- package/src/actions/intervals/resolve.js +35 -15
- package/src/actions/marks/arc/actions.js +78 -20
- package/src/actions/marks/area/actions.js +51 -12
- package/src/actions/marks/area/materialize.js +22 -3
- 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 +33 -9
- package/src/actions/marks/index.js +14 -0
- package/src/actions/marks/line/actions.js +71 -113
- package/src/actions/marks/line/materialize.js +57 -56
- package/src/actions/marks/point/create.js +8 -2
- package/src/actions/marks/point/edit.js +29 -21
- package/src/actions/marks/point/index.js +1 -0
- package/src/actions/marks/point/jitter.js +3 -0
- package/src/actions/marks/point/materialize.js +154 -16
- package/src/actions/marks/point/packing.js +68 -0
- package/src/actions/marks/rect/actions.js +33 -12
- package/src/actions/marks/references.js +658 -0
- package/src/actions/marks/remove.js +87 -4
- package/src/actions/marks/rule/actions.js +77 -9
- package/src/actions/marks/rule/appearance.js +26 -0
- package/src/actions/marks/shared.js +13 -13
- package/src/actions/marks/text/actions.js +296 -13
- package/src/actions/marks/text/index.js +4 -0
- package/src/actions/marks/text/layout.js +156 -8
- 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/createGraphics.js +3 -1
- package/src/actions/primitives/editGraphics.js +26 -0
- package/src/actions/primitives/semantic.js +3 -2
- package/src/actions/primitives/semanticAction.js +120 -10
- package/src/actions/primitives/semanticValidation/guide.js +10 -0
- package/src/actions/primitives/semanticValidation/index.js +9 -1
- package/src/actions/primitives/semanticValidation/layer.js +23 -1
- package/src/actions/primitives/semanticValidation/scale.js +38 -8
- package/src/actions/regression/components.js +26 -11
- package/src/actions/regression/create.js +11 -3
- package/src/actions/regression/edit.js +40 -13
- package/src/actions/regression/resolve.js +1 -1
- 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 +21 -54
- package/src/actions/scales/consumers/families.js +28 -14
- package/src/actions/scales/consumers/index.js +42 -4
- package/src/actions/scales/consumers/seriesLayout.js +57 -12
- package/src/actions/scales/create.js +58 -26
- package/src/actions/scales/definitions.js +109 -39
- package/src/actions/scales/edit.js +101 -34
- package/src/actions/scales/editPolicy.js +95 -35
- package/src/actions/scales/index.js +6 -0
- package/src/actions/scales/materialize.js +14 -49
- package/src/actions/scales/offset.js +48 -0
- package/src/actions/scales/parallel.js +71 -0
- package/src/actions/scales/patch.js +1 -1
- package/src/actions/scales/preview.js +140 -0
- package/src/actions/scales/quantitativeColor.js +9 -5
- package/src/actions/selection/actions.js +154 -30
- package/src/actions/selection/index.js +3 -0
- package/src/actions/theme/actions.js +98 -0
- package/src/actions/theme/composition.js +238 -0
- package/src/actions/theme/index.js +16 -0
- package/src/actions/theme/reconcile.js +1130 -0
- package/src/actions/theme/state.js +160 -0
- package/src/actions/titles/actions.js +11 -10
- package/src/actions/titles/resolve.js +1 -40
- package/src/actions/violinPlots/create.js +90 -43
- package/src/actions/violinPlots/edit.js +192 -0
- package/src/actions/violinPlots/index.js +2 -0
- package/src/core/ChartProgram.js +7 -0
- package/src/core/action.js +32 -2
- package/src/core/compositionState.js +141 -8
- package/src/core/programState.js +20 -0
- package/src/core/resourceReferences.js +332 -0
- package/src/core/vocabulary.js +16 -3
- package/src/grammar/aggregate.js +66 -23
- package/src/grammar/arcs.js +58 -1
- package/src/grammar/areaEndpoints.js +46 -0
- package/src/grammar/areaSeries.js +87 -41
- package/src/grammar/bars/aggregate.js +37 -13
- package/src/grammar/bars/geometry.js +44 -0
- package/src/grammar/bars/policy.js +9 -7
- package/src/grammar/bin.js +226 -0
- package/src/grammar/categoryOrder.js +34 -0
- package/src/grammar/complete.js +279 -0
- package/src/grammar/computed.js +351 -0
- package/src/grammar/coordinates.js +37 -0
- package/src/grammar/density.js +239 -37
- package/src/grammar/displayLabels.js +57 -0
- package/src/grammar/ecdf.js +198 -0
- package/src/grammar/facets/dependencies.js +133 -1
- package/src/grammar/facets/guides.js +3 -0
- package/src/grammar/facets/index.js +123 -52
- package/src/grammar/facets/scales.js +15 -18
- package/src/grammar/fold.js +123 -0
- package/src/grammar/horizon.js +6 -4
- package/src/grammar/impute.js +340 -0
- package/src/grammar/interval.js +37 -20
- package/src/grammar/lineSeries.js +20 -63
- package/src/grammar/markFilter.js +22 -4
- package/src/grammar/markLabelSelection.js +57 -0
- package/src/grammar/markLabels.js +110 -0
- package/src/grammar/normalize.js +366 -0
- package/src/grammar/parallelAxisTitles.js +16 -0
- package/src/grammar/pathSeries.js +109 -0
- package/src/grammar/pointPacking.js +183 -0
- package/src/grammar/pointShapes.js +13 -4
- package/src/grammar/polar.js +90 -8
- package/src/grammar/positionDatum.js +12 -0
- package/src/grammar/rects.js +9 -1
- package/src/grammar/regression/derive.js +4 -0
- package/src/grammar/regression/index.js +8 -2
- package/src/grammar/regression/models.js +22 -7
- package/src/grammar/regression/parameters.js +63 -13
- package/src/grammar/rotation.js +29 -0
- package/src/grammar/roundedRect.js +180 -0
- package/src/grammar/rules.js +8 -21
- package/src/grammar/scales/color.js +23 -1
- package/src/grammar/scales/colorConsumers.js +57 -0
- package/src/grammar/scales/continuous.js +2 -2
- package/src/grammar/scales/definition.js +42 -5
- package/src/grammar/scales/discretized.js +11 -5
- package/src/grammar/scales/fields.js +38 -8
- package/src/grammar/scales/index.js +1 -0
- package/src/grammar/scales/mapping.js +2 -0
- package/src/grammar/scales/ordinal.js +12 -3
- package/src/grammar/scales/policies.js +2 -2
- package/src/grammar/scales/radial.js +55 -0
- package/src/grammar/scales/size.js +456 -0
- package/src/grammar/scales/types.js +1 -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 +23 -4
- package/src/grammar/stack.js +170 -0
- package/src/grammar/statisticalReference.js +103 -0
- package/src/grammar/statistics/confidenceInterval.js +101 -0
- package/src/grammar/strokeStyle.js +77 -0
- package/src/grammar/summary.js +245 -0
- package/src/grammar/text.js +22 -16
- package/src/grammar/timeUnit.js +234 -13
- package/src/grammar/transformTopology.js +10 -0
- package/src/grammar/transforms.js +418 -16
- package/src/grammar/valueFormat.js +112 -0
- package/src/grammar/weightedStatistics.js +374 -0
- package/src/grammar/window.js +232 -21
- package/src/layout/aspect.js +80 -0
- package/src/layout/facets.js +100 -12
- package/src/layout/guideCollisions.js +12 -0
- package/src/layout/labels.js +343 -0
- package/src/layout/legend.js +2 -10
- package/src/layout/legendItems.js +102 -0
- package/src/layout/legendLane.js +100 -11
- package/src/materialization/bars/aggregate.js +56 -147
- package/src/materialization/bars/histogram.js +104 -20
- package/src/materialization/bars/ranged.js +19 -3
- package/src/materialization/bars/resolve.js +7 -4
- package/src/materialization/categorySlotOffset.js +40 -0
- package/src/materialization/composition.js +3 -1
- package/src/materialization/compositionSnapshot.js +1 -1
- package/src/materialization/coordinateBounds.js +204 -0
- package/src/materialization/dependencies.js +93 -16
- package/src/materialization/encodings.js +1 -1
- 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 +23 -66
- package/src/materialization/guides/layout.js +57 -0
- package/src/materialization/guides/resources.js +28 -2
- package/src/materialization/legends.js +11 -2
- package/src/materialization/marks/capabilities.js +20 -5
- package/src/materialization/marks/grouping.js +52 -0
- package/src/materialization/marks/index.js +68 -27
- package/src/materialization/marks/policies.js +4 -1
- package/src/materialization/rect.js +55 -42
- package/src/materialization/rectConfig.js +5 -1
- package/src/materialization/rowEncoding.js +13 -13
- package/src/materialization/scaleGuideDependencies.js +8 -5
- package/src/materialization/scales/map.js +6 -3
- package/src/materialization/scales/policies/arc.js +42 -0
- package/src/materialization/scales/policies/binnedPosition.js +7 -4
- package/src/materialization/scales/policies/offset.js +50 -8
- package/src/materialization/scales/policies/series.js +5 -1
- package/src/materialization/scales/resolve.js +65 -17
- package/src/materialization/selection/compatibility.js +11 -0
- package/src/materialization/selection/items/arc.js +28 -4
- package/src/materialization/selection/items/bar.js +42 -71
- package/src/materialization/selection/items/common.js +27 -6
- package/src/materialization/selection/items/path.js +3 -13
- package/src/materialization/selection/items/rect.js +35 -8
- package/src/materialization/selection/path.js +1 -1
- package/src/materialization/selection/point.js +3 -1
- package/src/materialization/text.js +324 -14
- package/src/mcp/adapter.js +2 -2
- 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 +44 -0
- package/src/selectors/layers.js +7 -2
- package/src/selectors/scales.js +6 -0
- package/src/theme/defaults.js +140 -0
- package/types/basic.d.ts +17 -2
- package/types/index.d.ts +211 -0
- package/types/program.d.ts +2182 -204
- package/src/materialization/bars/grouped.js +0 -144
|
@@ -7,9 +7,12 @@ import {
|
|
|
7
7
|
} from "../../../core/validation.js";
|
|
8
8
|
import { deriveArcSectors } from "../../../grammar/arcs.js";
|
|
9
9
|
import { buildAnnularSectorCommands } from "../../../grammar/polarPaths.js";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import {
|
|
11
|
+
mapOrdinalValues,
|
|
12
|
+
readScaleField
|
|
13
|
+
} from "../../../grammar/scales/index.js";
|
|
14
|
+
import { resolveCoordinatePolarFrame } from
|
|
15
|
+
"../../../materialization/coordinateBounds.js";
|
|
13
16
|
import {
|
|
14
17
|
canMaterializeArc,
|
|
15
18
|
getSourceDependentMarkSteps
|
|
@@ -19,7 +22,10 @@ import { findLayer, resolveEligibleLayer } from "../../../selectors/layers.js";
|
|
|
19
22
|
import { DEFAULT_COLORS } from "../../../theme/defaults.js";
|
|
20
23
|
import { resolveMarkGraphicPlacement } from
|
|
21
24
|
"../../../materialization/graphicHierarchy.js";
|
|
25
|
+
import { rematerializeExistingLegend } from "../../encodings/shared.js";
|
|
22
26
|
import { rematerializeHighlightBaseline } from "../lifecycle.js";
|
|
27
|
+
import { mapScaleConsumerValues } from
|
|
28
|
+
"../../../materialization/scales/map.js";
|
|
23
29
|
import {
|
|
24
30
|
assertMarkAvailable,
|
|
25
31
|
applyLayeredMarkInheritance,
|
|
@@ -30,13 +36,18 @@ import {
|
|
|
30
36
|
resolveMarkId,
|
|
31
37
|
validateMarkOptions
|
|
32
38
|
} from "../shared.js";
|
|
39
|
+
import {
|
|
40
|
+
requestedStrokeDetails,
|
|
41
|
+
STROKE_STYLE_PROPERTIES
|
|
42
|
+
} from "../../../grammar/strokeStyle.js";
|
|
33
43
|
|
|
34
44
|
const ARC_OPTIONS = Object.freeze([
|
|
35
|
-
"innerRadius", "padAngle", "fill", "opacity", "stroke", "strokeWidth"
|
|
45
|
+
"innerRadius", "padAngle", "fill", "opacity", "stroke", "strokeWidth",
|
|
46
|
+
...STROKE_STYLE_PROPERTIES
|
|
36
47
|
]);
|
|
37
48
|
const CREATE_OPTIONS = Object.freeze(["id", "data", ...ARC_OPTIONS]);
|
|
38
49
|
const EDIT_OPTIONS = Object.freeze(["target", ...ARC_OPTIONS]);
|
|
39
|
-
const REMATERIALIZE_OPTIONS = Object.freeze(["id"]);
|
|
50
|
+
const REMATERIALIZE_OPTIONS = Object.freeze(["id", "scales"]);
|
|
40
51
|
|
|
41
52
|
function validateInnerRadius(value) {
|
|
42
53
|
if (!Number.isFinite(value) || value < 0 || value >= 1) {
|
|
@@ -47,11 +58,16 @@ function validateInnerRadius(value) {
|
|
|
47
58
|
return value;
|
|
48
59
|
}
|
|
49
60
|
|
|
50
|
-
function normalizeConfig(
|
|
61
|
+
function normalizeConfig(
|
|
62
|
+
args,
|
|
63
|
+
previous = {},
|
|
64
|
+
{ allowStrokeRemoval = false, strokeDetails = {} } = {}
|
|
65
|
+
) {
|
|
51
66
|
let config = {
|
|
52
67
|
...previous,
|
|
68
|
+
...strokeDetails,
|
|
53
69
|
...(Object.hasOwn(args, "innerRadius")
|
|
54
|
-
? { innerRadius: validateInnerRadius(args.innerRadius) }
|
|
70
|
+
? { innerRadius: validateInnerRadius(args.innerRadius), innerRadiusExplicit: true }
|
|
55
71
|
: {}),
|
|
56
72
|
...(Object.hasOwn(args, "padAngle")
|
|
57
73
|
? { padAngle: validateNonNegativeFinite(args.padAngle, "Arc padAngle") }
|
|
@@ -93,6 +109,7 @@ const createArcMark = action(
|
|
|
93
109
|
},
|
|
94
110
|
function (args = {}) {
|
|
95
111
|
validateMarkOptions(args, CREATE_OPTIONS, "createArcMark");
|
|
112
|
+
const strokeDetails = requestedStrokeDetails(args, "createArcMark");
|
|
96
113
|
const id = resolveMarkId(this, args.id, {
|
|
97
114
|
defaultId: "arc",
|
|
98
115
|
label: "Arc mark id",
|
|
@@ -112,7 +129,7 @@ const createArcMark = action(
|
|
|
112
129
|
opacity: 1,
|
|
113
130
|
stroke: "#ffffff",
|
|
114
131
|
strokeWidth: 1
|
|
115
|
-
});
|
|
132
|
+
}, { strokeDetails });
|
|
116
133
|
let created = this
|
|
117
134
|
.editSemantic({ property: `layer[${id}].mark.type`, value: "arc" })
|
|
118
135
|
.editSemantic({ property: `layer[${id}].data`, value: data });
|
|
@@ -148,6 +165,9 @@ const rematerializeArcMark = action(
|
|
|
148
165
|
},
|
|
149
166
|
function (args = {}) {
|
|
150
167
|
validateMarkOptions(args, REMATERIALIZE_OPTIONS, "rematerializeArcMark");
|
|
168
|
+
if (args.scales !== undefined && typeof args.scales !== "boolean") {
|
|
169
|
+
throw new TypeError("rematerializeArcMark scales must be a boolean.");
|
|
170
|
+
}
|
|
151
171
|
const id = validateUserId(args.id, "Arc mark id");
|
|
152
172
|
const highlighted = rematerializeHighlightBaseline(this, {
|
|
153
173
|
target: id,
|
|
@@ -163,15 +183,21 @@ const rematerializeArcMark = action(
|
|
|
163
183
|
const thetaScaleId = layer.encoding.theta.scale;
|
|
164
184
|
const radiusScaleId = layer.encoding?.radius?.scale;
|
|
165
185
|
const colorScaleId = layer.encoding?.color?.scale;
|
|
166
|
-
|
|
167
|
-
|
|
186
|
+
const strokeScaleId = layer.encoding?.stroke?.scale;
|
|
187
|
+
let resolved = args.scales === false
|
|
188
|
+
? this
|
|
189
|
+
: this.rematerializeScale({ id: thetaScaleId });
|
|
190
|
+
if (radiusScaleId !== undefined && args.scales !== false) {
|
|
168
191
|
resolved = resolved.rematerializeScale({ id: radiusScaleId });
|
|
169
192
|
}
|
|
170
|
-
if (colorScaleId !== undefined) {
|
|
193
|
+
if (colorScaleId !== undefined && args.scales !== false) {
|
|
171
194
|
resolved = resolved.rematerializeScale({ id: colorScaleId });
|
|
172
195
|
}
|
|
196
|
+
if (strokeScaleId !== undefined && args.scales !== false) {
|
|
197
|
+
resolved = resolved.rematerializeScale({ id: strokeScaleId });
|
|
198
|
+
}
|
|
173
199
|
const config = resolved.markConfigs[id] ?? {};
|
|
174
|
-
const frame =
|
|
200
|
+
const frame = resolveCoordinatePolarFrame(resolved, layer.coordinate);
|
|
175
201
|
const derived = deriveArcSectors(dataset.values, layer, {
|
|
176
202
|
thetaScale: resolved.resolvedScales[thetaScaleId],
|
|
177
203
|
...(radiusScaleId === undefined
|
|
@@ -195,14 +221,37 @@ const rematerializeArcMark = action(
|
|
|
195
221
|
resolved.resolvedScales[colorScaleId].domain,
|
|
196
222
|
resolved.resolvedScales[colorScaleId].range
|
|
197
223
|
);
|
|
224
|
+
const strokeEncoding = layer.encoding?.stroke;
|
|
225
|
+
const strokeValues = strokeEncoding === undefined ? undefined : derived.sectors.map(
|
|
226
|
+
sector => {
|
|
227
|
+
const values = readScaleField(
|
|
228
|
+
sector.sourceIndices.map(index => dataset.values[index]),
|
|
229
|
+
strokeEncoding.field,
|
|
230
|
+
strokeEncoding.fieldType,
|
|
231
|
+
{ temporalUnit: strokeEncoding.temporalUnit }
|
|
232
|
+
);
|
|
233
|
+
if (new Set(values).size !== 1) {
|
|
234
|
+
throw new Error("Arc stroke requires one value within each sector.");
|
|
235
|
+
}
|
|
236
|
+
return values[0];
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
const strokes = strokeValues === undefined ? undefined : mapScaleConsumerValues(
|
|
240
|
+
strokeValues,
|
|
241
|
+
resolved.resolvedScales[strokeScaleId],
|
|
242
|
+
"stroke"
|
|
243
|
+
);
|
|
198
244
|
return editMarkGraphic(resolved, id, {
|
|
199
245
|
length: commands.length,
|
|
200
246
|
commands,
|
|
201
247
|
fill: fills,
|
|
202
248
|
opacity: config.opacity ?? 1,
|
|
203
|
-
stroke:
|
|
249
|
+
stroke: strokes ?? (
|
|
250
|
+
config.stroke === false ? "transparent" : config.stroke ?? "#ffffff"
|
|
251
|
+
),
|
|
204
252
|
strokeWidth: config.stroke === false ? 0 : config.strokeWidth ?? 1,
|
|
205
|
-
strokeDash: commands.map(() => [])
|
|
253
|
+
strokeDash: commands.map(() => []),
|
|
254
|
+
...requestedStrokeDetails(config, "Arc mark")
|
|
206
255
|
});
|
|
207
256
|
}
|
|
208
257
|
);
|
|
@@ -214,6 +263,7 @@ const editArcMark = action(
|
|
|
214
263
|
},
|
|
215
264
|
function (args = {}) {
|
|
216
265
|
validateMarkOptions(args, EDIT_OPTIONS, "editArcMark");
|
|
266
|
+
const strokeDetails = requestedStrokeDetails(args, "editArcMark");
|
|
217
267
|
if (Object.keys(args).every(key => key === "target")) {
|
|
218
268
|
throw new Error(
|
|
219
269
|
"editArcMark requires innerRadius, padAngle, fill, opacity, stroke, or strokeWidth."
|
|
@@ -230,6 +280,11 @@ const editArcMark = action(
|
|
|
230
280
|
if (Object.hasOwn(args, "fill") && layer.encoding?.color !== undefined) {
|
|
231
281
|
throw new Error("editArcMark fill cannot be combined with a color encoding.");
|
|
232
282
|
}
|
|
283
|
+
if (Object.hasOwn(args, "stroke") && layer.encoding?.stroke !== undefined) {
|
|
284
|
+
throw new Error(
|
|
285
|
+
"editArcMark stroke conflicts with a field encoding; use encodeStroke with value to replace it."
|
|
286
|
+
);
|
|
287
|
+
}
|
|
233
288
|
if (args.stroke === false && Object.hasOwn(args, "strokeWidth")) {
|
|
234
289
|
throw new Error(
|
|
235
290
|
"editArcMark cannot set strokeWidth while removing stroke."
|
|
@@ -245,15 +300,18 @@ const editArcMark = action(
|
|
|
245
300
|
const next = this._withMarkConfig(
|
|
246
301
|
layer.id,
|
|
247
302
|
normalizeConfig(args, this.markConfigs[layer.id], {
|
|
248
|
-
allowStrokeRemoval: true
|
|
303
|
+
allowStrokeRemoval: true,
|
|
304
|
+
strokeDetails
|
|
249
305
|
})
|
|
250
306
|
);
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
307
|
+
let materialized = next;
|
|
308
|
+
if (canMaterializeArc(next, layer)) {
|
|
309
|
+
materialized = next.rematerializeArcMark({ id: layer.id });
|
|
310
|
+
for (const step of getSourceDependentMarkSteps(materialized, layer.id)) {
|
|
311
|
+
materialized = materialized[step.op](step.args);
|
|
312
|
+
}
|
|
255
313
|
}
|
|
256
|
-
return
|
|
314
|
+
return rematerializeExistingLegend(materialized);
|
|
257
315
|
}
|
|
258
316
|
);
|
|
259
317
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateAreaMissing } from "../../../grammar/areaEndpoints.js";
|
|
1
2
|
import { action } from "../../../core/action.js";
|
|
2
3
|
import { validateUserId } from "../../../core/identifiers.js";
|
|
3
4
|
import {
|
|
@@ -21,17 +22,23 @@ import { findLayer } from "../../../selectors/layers.js";
|
|
|
21
22
|
import { validateCurveInterpolation } from "../../../grammar/curveCommands.js";
|
|
22
23
|
import { resolveEligibleLayer } from "../../../selectors/layers.js";
|
|
23
24
|
import { canMaterializeArea } from "../../../materialization/marks/index.js";
|
|
25
|
+
import { rematerializeExistingLegend } from "../../encodings/shared.js";
|
|
24
26
|
import { findUpstreamTransform } from "../../../materialization/dataProvenance.js";
|
|
25
27
|
import { resolveMarkGraphicPlacement } from
|
|
26
28
|
"../../../materialization/graphicHierarchy.js";
|
|
27
29
|
import { rematerializeHighlightBaseline } from "../lifecycle.js";
|
|
28
30
|
import { resolveAreaMaterialization } from "./materialize.js";
|
|
31
|
+
import {
|
|
32
|
+
requestedStrokeDetails,
|
|
33
|
+
STROKE_STYLE_PROPERTIES
|
|
34
|
+
} from "../../../grammar/strokeStyle.js";
|
|
29
35
|
|
|
30
36
|
const AREA_OPTIONS = Object.freeze([
|
|
31
|
-
"fill", "opacity", "stroke", "strokeWidth", "curve"
|
|
37
|
+
"fill", "opacity", "stroke", "strokeWidth", "curve",
|
|
38
|
+
...STROKE_STYLE_PROPERTIES
|
|
32
39
|
]);
|
|
33
|
-
const CREATE_OPTIONS = Object.freeze(["id", "data", ...AREA_OPTIONS]);
|
|
34
|
-
const EDIT_OPTIONS = Object.freeze(["target", ...AREA_OPTIONS]);
|
|
40
|
+
const CREATE_OPTIONS = Object.freeze(["id", "data", "missing", ...AREA_OPTIONS]);
|
|
41
|
+
const EDIT_OPTIONS = Object.freeze(["target", "missing", ...AREA_OPTIONS]);
|
|
35
42
|
const REMATERIALIZE_OPTIONS = Object.freeze(["id", "scales"]);
|
|
36
43
|
const STROKE_FROM_FILL_OPTIONS = Object.freeze(["id", "strokeWidth"]);
|
|
37
44
|
|
|
@@ -57,6 +64,7 @@ const createAreaMark = action(
|
|
|
57
64
|
},
|
|
58
65
|
function (args = {}) {
|
|
59
66
|
validateMarkOptions(args, CREATE_OPTIONS, "createAreaMark");
|
|
67
|
+
const strokeDetails = requestedStrokeDetails(args, "createAreaMark");
|
|
60
68
|
const id = resolveMarkId(this, args.id, {
|
|
61
69
|
defaultId: "area",
|
|
62
70
|
label: "Area mark id",
|
|
@@ -69,6 +77,10 @@ const createAreaMark = action(
|
|
|
69
77
|
...(args.data === undefined && this.context.currentData === undefined &&
|
|
70
78
|
inherited?.data !== undefined ? { data: inherited.data } : {})
|
|
71
79
|
});
|
|
80
|
+
const missing = validateAreaMissing(args.missing);
|
|
81
|
+
if (missing === "break" && ["density", "horizon"].some(type => findUpstreamTransform(this, findDataset(this, data), type))) {
|
|
82
|
+
throw new Error("Area missing:break does not reinterpret density or horizon data.");
|
|
83
|
+
}
|
|
72
84
|
const fill = validateNonEmptyString(args.fill ?? DEFAULT_COLORS.mark, "Area fill");
|
|
73
85
|
const opacity = validateUnitInterval(args.opacity ?? 0.2, "Area opacity");
|
|
74
86
|
const curve = validateCurveInterpolation(args.curve ?? "linear");
|
|
@@ -77,6 +89,7 @@ const createAreaMark = action(
|
|
|
77
89
|
let created = this
|
|
78
90
|
.editSemantic({ property: `layer[${id}].mark.type`, value: "area" })
|
|
79
91
|
.editSemantic({ property: `layer[${id}].data`, value: data });
|
|
92
|
+
if (Object.hasOwn(args, "missing")) created = created.editSemantic({ property: `layer[${id}].mark.missing`, value: missing });
|
|
80
93
|
created = applyLayeredMarkInheritance(created, id, inherited);
|
|
81
94
|
created = created
|
|
82
95
|
.createGraphics({
|
|
@@ -89,7 +102,8 @@ const createAreaMark = action(
|
|
|
89
102
|
fill,
|
|
90
103
|
opacity,
|
|
91
104
|
...(Object.hasOwn(args, "curve") ? { curve } : {}),
|
|
92
|
-
...(stroke === undefined ? {} : { stroke, strokeWidth })
|
|
105
|
+
...(stroke === undefined ? {} : { stroke, strokeWidth }),
|
|
106
|
+
...strokeDetails
|
|
93
107
|
});
|
|
94
108
|
return materializeInheritedMark(created, id);
|
|
95
109
|
}
|
|
@@ -173,6 +187,7 @@ const rematerializeAreaMark = action(
|
|
|
173
187
|
);
|
|
174
188
|
}
|
|
175
189
|
const colorEncoding = layer.encoding?.color;
|
|
190
|
+
const strokeEncoding = layer.encoding?.stroke;
|
|
176
191
|
let resolved = args.scales === false
|
|
177
192
|
? this
|
|
178
193
|
: this
|
|
@@ -181,8 +196,11 @@ const rematerializeAreaMark = action(
|
|
|
181
196
|
if (args.scales !== false && colorEncoding?.scale !== undefined) {
|
|
182
197
|
resolved = resolved.rematerializeScale({ id: colorEncoding.scale });
|
|
183
198
|
}
|
|
199
|
+
if (args.scales !== false && strokeEncoding?.scale !== undefined) {
|
|
200
|
+
resolved = resolved.rematerializeScale({ id: strokeEncoding.scale });
|
|
201
|
+
}
|
|
184
202
|
const config = this.markConfigs[id];
|
|
185
|
-
const { paths, fills } = resolveAreaMaterialization({
|
|
203
|
+
const { paths, fills, strokes } = resolveAreaMaterialization({
|
|
186
204
|
rows: dataset.values,
|
|
187
205
|
layer,
|
|
188
206
|
densityTransform,
|
|
@@ -190,7 +208,8 @@ const rematerializeAreaMark = action(
|
|
|
190
208
|
config
|
|
191
209
|
});
|
|
192
210
|
const existingChildren = resolved.graphicSpec.objects[id].items ?? [];
|
|
193
|
-
const hasOutline =
|
|
211
|
+
const hasOutline = strokes !== undefined || config.stroke !== undefined ||
|
|
212
|
+
config.strokeFromFill === true;
|
|
194
213
|
const removesOutline = !hasOutline && existingChildren.some(
|
|
195
214
|
child => child.properties.stroke !== undefined
|
|
196
215
|
);
|
|
@@ -204,9 +223,10 @@ const rematerializeAreaMark = action(
|
|
|
204
223
|
fill: fills,
|
|
205
224
|
opacity: config.opacity,
|
|
206
225
|
...(hasOutline ? {
|
|
207
|
-
stroke: config.strokeFromFill === true ? fills : config.stroke,
|
|
208
|
-
strokeWidth: config.strokeWidth
|
|
209
|
-
} : {})
|
|
226
|
+
stroke: strokes ?? (config.strokeFromFill === true ? fills : config.stroke),
|
|
227
|
+
strokeWidth: config.strokeWidth ?? (strokes === undefined ? undefined : 1)
|
|
228
|
+
} : {}),
|
|
229
|
+
...requestedStrokeDetails(config, "Area mark")
|
|
210
230
|
});
|
|
211
231
|
}
|
|
212
232
|
);
|
|
@@ -218,7 +238,11 @@ const editAreaMark = action(
|
|
|
218
238
|
},
|
|
219
239
|
function (args = {}) {
|
|
220
240
|
validateMarkOptions(args, EDIT_OPTIONS, "editAreaMark");
|
|
221
|
-
const
|
|
241
|
+
const strokeDetails = requestedStrokeDetails(args, "editAreaMark");
|
|
242
|
+
const changes = [
|
|
243
|
+
"fill", "opacity", "stroke", "strokeWidth", "curve", "missing",
|
|
244
|
+
...STROKE_STYLE_PROPERTIES
|
|
245
|
+
];
|
|
222
246
|
if (!changes.some(key => Object.hasOwn(args, key))) {
|
|
223
247
|
throw new Error(
|
|
224
248
|
"editAreaMark requires fill, opacity, stroke, strokeWidth, or curve."
|
|
@@ -237,13 +261,20 @@ const editAreaMark = action(
|
|
|
237
261
|
"editAreaMark fill cannot be combined with a color encoding."
|
|
238
262
|
);
|
|
239
263
|
}
|
|
264
|
+
if (Object.hasOwn(args, "stroke") && layer.encoding?.stroke !== undefined) {
|
|
265
|
+
throw new Error(
|
|
266
|
+
"editAreaMark stroke conflicts with a field encoding; use encodeStroke with value to replace it."
|
|
267
|
+
);
|
|
268
|
+
}
|
|
240
269
|
if (args.stroke === false && Object.hasOwn(args, "strokeWidth")) {
|
|
241
270
|
throw new Error("editAreaMark cannot set strokeWidth while removing stroke.");
|
|
242
271
|
}
|
|
243
272
|
|
|
244
273
|
let config = { ...this.markConfigs[layer.id] };
|
|
274
|
+
Object.assign(config, strokeDetails);
|
|
245
275
|
if (Object.hasOwn(args, "fill")) {
|
|
246
276
|
config.fill = validateNonEmptyString(args.fill, "Area fill");
|
|
277
|
+
if (config.errorBand !== undefined) config.errorBand = { ...config.errorBand, fill: config.fill };
|
|
247
278
|
}
|
|
248
279
|
if (Object.hasOwn(args, "opacity")) {
|
|
249
280
|
config.opacity = validateUnitInterval(args.opacity, "Area opacity");
|
|
@@ -283,10 +314,18 @@ const editAreaMark = action(
|
|
|
283
314
|
);
|
|
284
315
|
}
|
|
285
316
|
|
|
286
|
-
|
|
287
|
-
|
|
317
|
+
let next = this._withMarkConfig(layer.id, config);
|
|
318
|
+
if (Object.hasOwn(args, "missing")) {
|
|
319
|
+
const missing = validateAreaMissing(args.missing);
|
|
320
|
+
if (missing === "break" && ["density", "horizon"].some(type => findUpstreamTransform(this, findDataset(this, layer.data), type))) {
|
|
321
|
+
throw new Error("Area missing:break does not reinterpret density or horizon data.");
|
|
322
|
+
}
|
|
323
|
+
next = next.editSemantic({ property: `layer[${layer.id}].mark.missing`, value: missing });
|
|
324
|
+
}
|
|
325
|
+
const materialized = canMaterializeArea(next, layer)
|
|
288
326
|
? next.rematerializeAreaMark({ id: layer.id })
|
|
289
327
|
: next;
|
|
328
|
+
return rematerializeExistingLegend(materialized);
|
|
290
329
|
}
|
|
291
330
|
);
|
|
292
331
|
|
|
@@ -8,12 +8,15 @@ import {
|
|
|
8
8
|
mapContinuousScaleValues,
|
|
9
9
|
mapOrdinalValues
|
|
10
10
|
} from "../../../grammar/scales/index.js";
|
|
11
|
+
import { mapScaleConsumerValues } from
|
|
12
|
+
"../../../materialization/scales/map.js";
|
|
11
13
|
import { buildAreaCurvePathCommands } from
|
|
12
14
|
"../../../grammar/curveCommands.js";
|
|
13
15
|
import { buildLinearPathCommands } from
|
|
14
16
|
"../../../grammar/pathCommands.js";
|
|
15
17
|
import { buildCategoricalDensityPaths } from
|
|
16
18
|
"../../../grammar/categoricalDensity.js";
|
|
19
|
+
import { derivePathSeriesFieldValues } from "../../../grammar/pathSeries.js";
|
|
17
20
|
|
|
18
21
|
function resolveAreaPaths({
|
|
19
22
|
derived,
|
|
@@ -135,7 +138,7 @@ export function resolveAreaMaterialization({
|
|
|
135
138
|
: deriveAreaSeries(rows, layer)
|
|
136
139
|
: deriveDensityAreaSeries(rows, layer, densityTransform);
|
|
137
140
|
const colorEncoding = layer.encoding?.color;
|
|
138
|
-
const layout = colorEncoding?.layout ?? "overlay";
|
|
141
|
+
const layout = layer.layout?.mode ?? colorEncoding?.layout ?? "overlay";
|
|
139
142
|
const categoricalDensity = densityTransform?.placement?.type === "category";
|
|
140
143
|
const derived = densityTransform === undefined || categoricalDensity
|
|
141
144
|
? rawDerived
|
|
@@ -164,9 +167,25 @@ export function resolveAreaMaterialization({
|
|
|
164
167
|
: colorEncoding?.scale === undefined
|
|
165
168
|
? paths.map(() => config.fill)
|
|
166
169
|
: mapOrdinalValues(
|
|
167
|
-
|
|
170
|
+
densityTransform !== undefined || centered
|
|
171
|
+
? derived.series.map(series => series.key[colorEncoding.field])
|
|
172
|
+
: derivePathSeriesFieldValues(rows, derived.series, colorEncoding.field, "color"),
|
|
168
173
|
resolvedScales[colorEncoding.scale].domain,
|
|
169
174
|
resolvedScales[colorEncoding.scale].range
|
|
170
175
|
);
|
|
171
|
-
|
|
176
|
+
const strokeEncoding = layer.encoding?.stroke;
|
|
177
|
+
const strokes = strokeEncoding?.scale === undefined
|
|
178
|
+
? undefined
|
|
179
|
+
: mapScaleConsumerValues(
|
|
180
|
+
derivePathSeriesFieldValues(
|
|
181
|
+
rows,
|
|
182
|
+
derived.series,
|
|
183
|
+
strokeEncoding.field,
|
|
184
|
+
"stroke",
|
|
185
|
+
strokeEncoding
|
|
186
|
+
),
|
|
187
|
+
resolvedScales[strokeEncoding.scale],
|
|
188
|
+
"stroke"
|
|
189
|
+
);
|
|
190
|
+
return { paths, fills, strokes };
|
|
172
191
|
}
|
|
@@ -10,9 +10,14 @@ import {
|
|
|
10
10
|
} from "../shared.js";
|
|
11
11
|
import { resolveMarkGraphicPlacement } from
|
|
12
12
|
"../../../materialization/graphicHierarchy.js";
|
|
13
|
+
import { requestedRectStyleDetails } from
|
|
14
|
+
"../../../grammar/roundedRect.js";
|
|
15
|
+
import { STROKE_STYLE_PROPERTIES } from
|
|
16
|
+
"../../../grammar/strokeStyle.js";
|
|
13
17
|
|
|
14
18
|
const CREATE_OPTIONS = Object.freeze([
|
|
15
|
-
"id", "data", "fill", "opacity", "stroke", "strokeWidth"
|
|
19
|
+
"id", "data", "fill", "opacity", "stroke", "strokeWidth",
|
|
20
|
+
"cornerRadius", ...STROKE_STYLE_PROPERTIES
|
|
16
21
|
]);
|
|
17
22
|
|
|
18
23
|
export const createBarMark = action(
|
|
@@ -22,6 +27,7 @@ export const createBarMark = action(
|
|
|
22
27
|
},
|
|
23
28
|
function (args = {}) {
|
|
24
29
|
validateMarkOptions(args, CREATE_OPTIONS, "createBarMark");
|
|
30
|
+
requestedRectStyleDetails(args, "createBarMark");
|
|
25
31
|
const id = resolveMarkId(this, args.id, {
|
|
26
32
|
defaultId: "bar",
|
|
27
33
|
label: "Bar mark id",
|
|
@@ -56,7 +62,10 @@ export const createBarMark = action(
|
|
|
56
62
|
});
|
|
57
63
|
created = materializeInheritedMark(created, id);
|
|
58
64
|
const appearance = Object.fromEntries(
|
|
59
|
-
[
|
|
65
|
+
[
|
|
66
|
+
"fill", "opacity", "stroke", "strokeWidth", "cornerRadius",
|
|
67
|
+
...STROKE_STYLE_PROPERTIES
|
|
68
|
+
]
|
|
60
69
|
.filter(property => Object.hasOwn(args, property))
|
|
61
70
|
.map(property => [property, args[property]])
|
|
62
71
|
);
|
|
@@ -9,9 +9,15 @@ import { canMaterializeBar } from "../../../materialization/marks/index.js";
|
|
|
9
9
|
import { DEFAULT_BAR_STROKE_WIDTH } from "../../../materialization/bars/resolve.js";
|
|
10
10
|
import { resolveEligibleLayer } from "../../../selectors/layers.js";
|
|
11
11
|
import { validateMarkOptions } from "../shared.js";
|
|
12
|
+
import { requestedRectStyleDetails } from
|
|
13
|
+
"../../../grammar/roundedRect.js";
|
|
14
|
+
import { STROKE_STYLE_PROPERTIES } from
|
|
15
|
+
"../../../grammar/strokeStyle.js";
|
|
16
|
+
import { rematerializeExistingLegend } from "../../encodings/shared.js";
|
|
12
17
|
|
|
13
18
|
const EDIT_OPTIONS = Object.freeze([
|
|
14
|
-
"target", "fill", "opacity", "stroke", "strokeWidth"
|
|
19
|
+
"target", "fill", "opacity", "stroke", "strokeWidth", "cornerRadius",
|
|
20
|
+
...STROKE_STYLE_PROPERTIES
|
|
15
21
|
]);
|
|
16
22
|
|
|
17
23
|
export const editBarMark = action(
|
|
@@ -21,7 +27,11 @@ export const editBarMark = action(
|
|
|
21
27
|
},
|
|
22
28
|
function (args = {}) {
|
|
23
29
|
validateMarkOptions(args, EDIT_OPTIONS, "editBarMark");
|
|
24
|
-
const
|
|
30
|
+
const styleDetails = requestedRectStyleDetails(args, "editBarMark");
|
|
31
|
+
const changes = [
|
|
32
|
+
"fill", "opacity", "stroke", "strokeWidth", "cornerRadius",
|
|
33
|
+
...STROKE_STYLE_PROPERTIES
|
|
34
|
+
];
|
|
25
35
|
if (!changes.some(key => Object.hasOwn(args, key))) {
|
|
26
36
|
throw new Error(
|
|
27
37
|
"editBarMark requires fill, opacity, stroke, or strokeWidth."
|
|
@@ -40,6 +50,11 @@ export const editBarMark = action(
|
|
|
40
50
|
"editBarMark fill cannot be combined with a color encoding."
|
|
41
51
|
);
|
|
42
52
|
}
|
|
53
|
+
if (Object.hasOwn(args, "stroke") && layer.encoding?.stroke !== undefined) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
"editBarMark stroke conflicts with a field encoding; use encodeStroke with value to replace it."
|
|
56
|
+
);
|
|
57
|
+
}
|
|
43
58
|
if (args.stroke === false && Object.hasOwn(args, "strokeWidth")) {
|
|
44
59
|
throw new Error(
|
|
45
60
|
"editBarMark cannot set strokeWidth while removing stroke."
|
|
@@ -48,6 +63,7 @@ export const editBarMark = action(
|
|
|
48
63
|
|
|
49
64
|
const config = { ...this.markConfigs[layer.id] };
|
|
50
65
|
const appearance = { ...config.barAppearance };
|
|
66
|
+
Object.assign(appearance, styleDetails);
|
|
51
67
|
if (Object.hasOwn(args, "fill")) {
|
|
52
68
|
appearance.fill = validateNonEmptyString(args.fill, "Bar fill");
|
|
53
69
|
}
|
|
@@ -83,8 +99,9 @@ export const editBarMark = action(
|
|
|
83
99
|
...config,
|
|
84
100
|
barAppearance: appearance
|
|
85
101
|
});
|
|
86
|
-
|
|
102
|
+
const materialized = canMaterializeBar(next, layer)
|
|
87
103
|
? next.rematerializeBarMark({ id: layer.id })
|
|
88
104
|
: next;
|
|
105
|
+
return rematerializeExistingLegend(materialized);
|
|
89
106
|
}
|
|
90
107
|
);
|
|
@@ -10,10 +10,28 @@ import {
|
|
|
10
10
|
resolveBarOffsetChannel
|
|
11
11
|
} from "../../../grammar/bars/policy.js";
|
|
12
12
|
import { rematerializeHighlightBaseline } from "../lifecycle.js";
|
|
13
|
+
import { offsetCategoryRectangles } from
|
|
14
|
+
"../../../materialization/categorySlotOffset.js";
|
|
15
|
+
import { materializeRectItem } from "../../../grammar/roundedRect.js";
|
|
16
|
+
import { STROKE_STYLE_PROPERTIES } from
|
|
17
|
+
"../../../grammar/strokeStyle.js";
|
|
18
|
+
import { replaceGraphicItems } from "../../primitives/editGraphics.js";
|
|
13
19
|
|
|
14
20
|
const REMATERIALIZE_OPTIONS = Object.freeze(["id", "scales"]);
|
|
15
21
|
|
|
16
22
|
function editRectangles(program, id, rectangles) {
|
|
23
|
+
const appearance = program.markConfigs[id]?.barAppearance ?? {};
|
|
24
|
+
const hasShapeStyle = ["cornerRadius", ...STROKE_STYLE_PROPERTIES]
|
|
25
|
+
.some(property => Object.hasOwn(appearance, property));
|
|
26
|
+
if (hasShapeStyle) {
|
|
27
|
+
const radius = appearance.cornerRadius ?? 0;
|
|
28
|
+
return replaceGraphicItems(
|
|
29
|
+
program,
|
|
30
|
+
id,
|
|
31
|
+
"rect",
|
|
32
|
+
rectangles.map(rectangle => materializeRectItem(rectangle, radius))
|
|
33
|
+
);
|
|
34
|
+
}
|
|
17
35
|
let next = program
|
|
18
36
|
.editGraphics({ target: id, property: "length", value: rectangles.length })
|
|
19
37
|
.editGraphics({
|
|
@@ -79,8 +97,8 @@ export const rematerializeBarMark = action(
|
|
|
79
97
|
const highlighted = rematerializeHighlightBaseline(this, {
|
|
80
98
|
target: id,
|
|
81
99
|
operation: "rematerializeBarMark",
|
|
82
|
-
resetProperty: "
|
|
83
|
-
resetValue:
|
|
100
|
+
resetProperty: "items",
|
|
101
|
+
resetValue: []
|
|
84
102
|
});
|
|
85
103
|
if (highlighted !== undefined) return highlighted;
|
|
86
104
|
const required = requireCompleteBar(this, id);
|
|
@@ -95,6 +113,10 @@ export const rematerializeBarMark = action(
|
|
|
95
113
|
if (colorScaleId !== undefined && args.scales !== false) {
|
|
96
114
|
resolved = resolved.rematerializeScale({ id: colorScaleId });
|
|
97
115
|
}
|
|
116
|
+
const strokeScaleId = required.layer.encoding?.stroke?.scale;
|
|
117
|
+
if (strokeScaleId !== undefined && args.scales !== false) {
|
|
118
|
+
resolved = resolved.rematerializeScale({ id: strokeScaleId });
|
|
119
|
+
}
|
|
98
120
|
|
|
99
121
|
if (required.materialization === "aggregate") {
|
|
100
122
|
const offsetChannel = resolveBarOffsetChannel(required.layer);
|
|
@@ -103,22 +125,24 @@ export const rematerializeBarMark = action(
|
|
|
103
125
|
resolved = resolved.rematerializeScale({ id: offsetScaleId });
|
|
104
126
|
}
|
|
105
127
|
const width = resolved.markConfigs[id]?.barWidth;
|
|
106
|
-
return editRectangles(
|
|
107
|
-
resolved,
|
|
108
|
-
|
|
109
|
-
deriveAggregateRectangles(required, resolved, width)
|
|
110
|
-
);
|
|
128
|
+
return editRectangles(resolved, id, offsetCategoryRectangles(
|
|
129
|
+
resolved, required.layer, deriveAggregateRectangles(required, resolved, width)
|
|
130
|
+
));
|
|
111
131
|
}
|
|
112
132
|
|
|
113
133
|
if (required.materialization === BAR_GRAINS.ranged) {
|
|
114
134
|
const width = resolved.markConfigs[id]?.barWidth;
|
|
115
|
-
return editRectangles(resolved, id,
|
|
135
|
+
return editRectangles(resolved, id, offsetCategoryRectangles(
|
|
136
|
+
resolved, required.layer, deriveRangedRectangles(required, resolved, width)
|
|
137
|
+
));
|
|
116
138
|
}
|
|
117
139
|
|
|
118
140
|
return editRectangles(
|
|
119
141
|
resolved,
|
|
120
142
|
id,
|
|
121
|
-
|
|
143
|
+
offsetCategoryRectangles(
|
|
144
|
+
resolved, required.layer, deriveHistogramRectangles(required, resolved)
|
|
145
|
+
)
|
|
122
146
|
);
|
|
123
147
|
}
|
|
124
148
|
);
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { removeMark } from "./remove.js";
|
|
2
|
+
import {
|
|
3
|
+
createReferenceLine,
|
|
4
|
+
createReferenceBand,
|
|
5
|
+
materializeStatisticalReferenceData,
|
|
6
|
+
rematerializeStatisticalReference
|
|
7
|
+
} from "./references.js";
|
|
2
8
|
import { registerRuleMarkActions } from "./rule/index.js";
|
|
3
9
|
import { registerAreaMarkActions } from "./area/index.js";
|
|
4
10
|
import { registerTickMarkActions } from "./tick/index.js";
|
|
@@ -8,6 +14,7 @@ import { registerArcMarkActions } from "./arc/index.js";
|
|
|
8
14
|
import { registerRectMarkActions } from "./rect/index.js";
|
|
9
15
|
import {
|
|
10
16
|
registerPointJitterActions,
|
|
17
|
+
registerPointPackingActions,
|
|
11
18
|
registerPointMarkActions
|
|
12
19
|
} from "./point/index.js";
|
|
13
20
|
import { registerTextMarkActions } from "./text/index.js";
|
|
@@ -15,6 +22,7 @@ import { registerTextMarkActions } from "./text/index.js";
|
|
|
15
22
|
export function registerMarkActions(ProgramClass) {
|
|
16
23
|
registerPointMarkActions(ProgramClass);
|
|
17
24
|
registerPointJitterActions(ProgramClass);
|
|
25
|
+
registerPointPackingActions(ProgramClass);
|
|
18
26
|
registerRectMarkActions(ProgramClass);
|
|
19
27
|
registerAreaMarkActions(ProgramClass);
|
|
20
28
|
registerArcMarkActions(ProgramClass);
|
|
@@ -24,4 +32,10 @@ export function registerMarkActions(ProgramClass) {
|
|
|
24
32
|
registerTextMarkActions(ProgramClass);
|
|
25
33
|
registerTickMarkActions(ProgramClass);
|
|
26
34
|
ProgramClass.prototype.removeMark = removeMark;
|
|
35
|
+
ProgramClass.prototype.createReferenceLine = createReferenceLine;
|
|
36
|
+
ProgramClass.prototype.createReferenceBand = createReferenceBand;
|
|
37
|
+
ProgramClass.prototype.materializeStatisticalReferenceData =
|
|
38
|
+
materializeStatisticalReferenceData;
|
|
39
|
+
ProgramClass.prototype.rematerializeStatisticalReference =
|
|
40
|
+
rematerializeStatisticalReference;
|
|
27
41
|
}
|