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
|
@@ -2,42 +2,191 @@ import { isDiscretizedColorScaleType } from "../../../grammar/scales/types.js";
|
|
|
2
2
|
import { normalizeContinuousLegend } from "./continuous/common.js";
|
|
3
3
|
import { DEFAULT_GRADIENT_SIZE } from "./continuous/gradient.js";
|
|
4
4
|
import { normalizeIntervalLegend } from "./continuous/interval.js";
|
|
5
|
+
import {
|
|
6
|
+
describeLegendBlock,
|
|
7
|
+
legendBlockDescriptors,
|
|
8
|
+
resolveLegendBlock
|
|
9
|
+
} from "./target.js";
|
|
10
|
+
import { validateLegendBlockOverride } from "./blocks.js";
|
|
5
11
|
|
|
6
|
-
const family = type => type === "sequential"
|
|
7
|
-
|
|
12
|
+
const family = (channel, type) => type === "sequential"
|
|
13
|
+
? channel === "stroke" ? "strokeGradient" : "gradient"
|
|
14
|
+
: isDiscretizedColorScaleType(type)
|
|
15
|
+
? channel === "stroke" ? "strokeInterval" : "interval"
|
|
16
|
+
: type === "ordinal"
|
|
17
|
+
? channel === "stroke" ? "stroke" : "color"
|
|
18
|
+
: undefined;
|
|
8
19
|
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
9
20
|
|
|
10
|
-
|
|
11
|
-
const
|
|
21
|
+
function categoricalFamilyCustom(program, kind, stored) {
|
|
22
|
+
const side = ["left", "right"].includes(stored.position);
|
|
23
|
+
const direction = side ? "vertical" : "horizontal";
|
|
24
|
+
const itemGap = side ? 28 : stored.position === "top" ? 24 : 20;
|
|
25
|
+
const order = program.semanticSpec.guides.legend?.[kind]?.order;
|
|
26
|
+
return stored.inferredSymbol !== true ||
|
|
27
|
+
stored.direction !== direction ||
|
|
28
|
+
(stored.columns !== undefined && !(side && stored.columns === 1)) ||
|
|
29
|
+
stored.itemGap !== itemGap || stored.layout !== "edge" ||
|
|
30
|
+
order !== undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function planChannelLegendTransition(program, scale, nextType, channel) {
|
|
34
|
+
const from = family(channel, scale.type), to = family(channel, nextType);
|
|
12
35
|
if (from === undefined || to === undefined || from === to) return undefined;
|
|
13
36
|
const stored = program.guideConfigs.legend?.[from];
|
|
14
|
-
if (stored?.scale !== scale.id) return undefined;
|
|
37
|
+
if ((stored?.scale ?? stored?.scales?.[0]) !== scale.id) return undefined;
|
|
38
|
+
const oldDescriptor = describeLegendBlock(program, from, stored);
|
|
39
|
+
const overrideKeys = Object.keys(stored.blockOverrides ?? {});
|
|
40
|
+
if (overrideKeys.some(key => key !== oldDescriptor.key)) {
|
|
41
|
+
throw new Error(`${channel} legend transition found stale legend block overrides.`);
|
|
42
|
+
}
|
|
43
|
+
const blockOverride = stored.blockOverrides?.[oldDescriptor.key];
|
|
15
44
|
const side = ["left", "right"].includes(stored.position);
|
|
16
|
-
const
|
|
45
|
+
const categorical = ["color", "stroke"].includes(from);
|
|
46
|
+
const gradientFamily = from.toLowerCase().endsWith("gradient");
|
|
47
|
+
const defaults = gradientFamily ? normalizeContinuousLegend({ position: stored.position }, "gradient")
|
|
17
48
|
: normalizeIntervalLegend({ position: stored.position });
|
|
18
|
-
const
|
|
49
|
+
const comparableSymbol = channel === "stroke" && stored.inferredStrokeWidth === true
|
|
50
|
+
? { ...stored.symbol, strokeWidth: defaults.symbol?.strokeWidth }
|
|
51
|
+
: stored.symbol;
|
|
52
|
+
const custom = categorical
|
|
53
|
+
? categoricalFamilyCustom(program, from, stored)
|
|
54
|
+
: gradientFamily
|
|
19
55
|
? stored.count !== defaults.count || !same(stored.gradient, DEFAULT_GRADIENT_SIZE) || stored.itemGap !== defaults.itemGap
|
|
20
|
-
: !same(
|
|
56
|
+
: !same(comparableSymbol, defaults.symbol) || stored.itemGap !== defaults.itemGap ||
|
|
21
57
|
stored.direction !== defaults.direction || (stored.columns !== undefined && !(side && stored.columns === 1));
|
|
22
58
|
if (custom) {
|
|
23
|
-
throw new Error(
|
|
59
|
+
throw new Error(`${channel} legend transition cannot discard custom family settings; remove and recreate the legend explicitly.`);
|
|
60
|
+
}
|
|
61
|
+
if (blockOverride?.title !== undefined) {
|
|
62
|
+
throw new Error(`${channel} legend transition cannot distribute a legend block title; edit the destination block explicitly.`);
|
|
63
|
+
}
|
|
64
|
+
if (blockOverride?.labelMap !== undefined) {
|
|
65
|
+
throw new Error(`${channel} legend transition cannot distribute a legend block labelMap; edit the destination block explicitly.`);
|
|
66
|
+
}
|
|
67
|
+
if (blockOverride?.symbol !== undefined && ["gradient", "strokeGradient"].includes(to)) {
|
|
68
|
+
throw new Error(`${channel} legend transition cannot apply symbol overrides to a gradient block.`);
|
|
24
69
|
}
|
|
25
70
|
const args = {
|
|
26
|
-
target: stored.target, channels: [
|
|
71
|
+
target: stored.target, channels: [channel], position: stored.position,
|
|
27
72
|
labels: stored.labels, titleStyle: stored.titleStyle, border: stored.border,
|
|
28
73
|
align: stored.align, offset: stored.offset, titlePosition: stored.titlePosition,
|
|
29
74
|
...(stored.inferredTitle ? {} : { title: stored.title })
|
|
30
75
|
};
|
|
31
76
|
try {
|
|
32
|
-
if (
|
|
33
|
-
|
|
77
|
+
if (["interval", "strokeInterval"].includes(to)) {
|
|
78
|
+
normalizeIntervalLegend({ ...args, channels: undefined });
|
|
79
|
+
}
|
|
80
|
+
else if (["gradient", "strokeGradient"].includes(to)) {
|
|
81
|
+
normalizeContinuousLegend(args, "gradient");
|
|
82
|
+
}
|
|
34
83
|
} catch (error) {
|
|
35
|
-
throw new Error(
|
|
84
|
+
throw new Error(`${channel} legend transition has incompatible layout or style: ${error.message}`);
|
|
36
85
|
}
|
|
37
|
-
return { args, titleVisible: stored.titleVisible !== false };
|
|
86
|
+
return { args, channel, titleVisible: stored.titleVisible !== false, blockOverride };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function planColorLegendTransitions(program, scale, nextType) {
|
|
90
|
+
return ["color", "stroke"].flatMap(channel => {
|
|
91
|
+
const plan = planChannelLegendTransition(program, scale, nextType, channel);
|
|
92
|
+
return plan === undefined ? [] : [plan];
|
|
93
|
+
});
|
|
38
94
|
}
|
|
39
95
|
|
|
40
96
|
export function applyColorLegendTransition(program, plan) {
|
|
41
|
-
|
|
42
|
-
|
|
97
|
+
let next = program.createLegend(plan.args);
|
|
98
|
+
if (!plan.titleVisible) {
|
|
99
|
+
next = next.editLegend({ target: plan.args.target, title: false });
|
|
100
|
+
}
|
|
101
|
+
if (plan.blockOverride === undefined) return next;
|
|
102
|
+
const descriptor = resolveLegendBlock(next, {
|
|
103
|
+
target: plan.args.target,
|
|
104
|
+
channel: plan.channel
|
|
105
|
+
}, `${plan.channel} legend transition`);
|
|
106
|
+
validateLegendBlockOverride(descriptor, plan.blockOverride);
|
|
107
|
+
next = next._withLegendConfig(descriptor.kind, {
|
|
108
|
+
...descriptor.config,
|
|
109
|
+
blockOverrides: { [descriptor.key]: plan.blockOverride }
|
|
110
|
+
});
|
|
111
|
+
return next.rematerializeLegend();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function intersects(left, right) {
|
|
115
|
+
return left.channels.some(channel => right.channels.includes(channel));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function explicitOrder(program, descriptor) {
|
|
119
|
+
if (descriptor.family !== "categorical") return undefined;
|
|
120
|
+
return program.semanticSpec.guides.legend?.[descriptor.kind]?.order;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function sameBlockValue(left, right) {
|
|
124
|
+
if (Object.is(left, right)) return true;
|
|
125
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
126
|
+
return left.length === right.length &&
|
|
127
|
+
left.every((value, index) => sameBlockValue(value, right[index]));
|
|
128
|
+
}
|
|
129
|
+
if (left !== null && right !== null &&
|
|
130
|
+
typeof left === "object" && typeof right === "object" &&
|
|
131
|
+
!Array.isArray(left) && !Array.isArray(right)) {
|
|
132
|
+
const leftKeys = Object.keys(left).sort();
|
|
133
|
+
const rightKeys = Object.keys(right).sort();
|
|
134
|
+
return leftKeys.length === rightKeys.length &&
|
|
135
|
+
leftKeys.every((key, index) => key === rightKeys[index] &&
|
|
136
|
+
sameBlockValue(left[key], right[key]));
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function transitionError(target, oldDescriptors, nextDescriptor, field) {
|
|
142
|
+
const oldKeys = oldDescriptors.map(item => item.key).join(", ");
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Legend block transition for target "${target}" from ${oldKeys} to ${nextDescriptor.key} conflicts on ${field}.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function withoutBlockOverrides(config) {
|
|
149
|
+
const { blockOverrides: _removed, ...rest } = config;
|
|
150
|
+
return rest;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function planLegendBlockTransitions(program, target, plans) {
|
|
154
|
+
const oldDescriptors = legendBlockDescriptors(program, target);
|
|
155
|
+
const nextDescriptors = plans.map(plan =>
|
|
156
|
+
describeLegendBlock(program, plan.kind, plan.config));
|
|
157
|
+
return plans.map((plan, index) => {
|
|
158
|
+
const descriptor = nextDescriptors[index];
|
|
159
|
+
const incoming = oldDescriptors.filter(old => intersects(old, descriptor));
|
|
160
|
+
let override;
|
|
161
|
+
if (incoming.length === 1 && incoming[0].key === descriptor.key) {
|
|
162
|
+
override = incoming[0].config.blockOverrides?.[incoming[0].key];
|
|
163
|
+
} else if (incoming.length === 1) {
|
|
164
|
+
const old = incoming[0];
|
|
165
|
+
override = old.config.blockOverrides?.[old.key];
|
|
166
|
+
if (override?.title !== undefined) {
|
|
167
|
+
transitionError(target, incoming, descriptor, "title");
|
|
168
|
+
}
|
|
169
|
+
if (override?.labelMap !== undefined) {
|
|
170
|
+
transitionError(target, incoming, descriptor, "labelMap");
|
|
171
|
+
}
|
|
172
|
+
} else if (incoming.length > 1) {
|
|
173
|
+
const overrides = incoming.map(old => old.config.blockOverrides?.[old.key]);
|
|
174
|
+
if (!overrides.every(value => sameBlockValue(value, overrides[0]))) {
|
|
175
|
+
transitionError(target, incoming, descriptor, "block override");
|
|
176
|
+
}
|
|
177
|
+
const orders = incoming.map(old => explicitOrder(program, old));
|
|
178
|
+
if (!orders.every(value => sameBlockValue(value, orders[0]))) {
|
|
179
|
+
transitionError(target, incoming, descriptor, "order");
|
|
180
|
+
}
|
|
181
|
+
override = overrides[0];
|
|
182
|
+
}
|
|
183
|
+
if (override !== undefined) validateLegendBlockOverride(descriptor, override);
|
|
184
|
+
const config = withoutBlockOverrides(plan.config);
|
|
185
|
+
return {
|
|
186
|
+
...plan,
|
|
187
|
+
config: override === undefined
|
|
188
|
+
? config
|
|
189
|
+
: { ...config, blockOverrides: { [descriptor.key]: override } }
|
|
190
|
+
};
|
|
191
|
+
});
|
|
43
192
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
validateEnabledAxisComponents
|
|
9
9
|
} from "../../axes/components.js";
|
|
10
10
|
import {
|
|
11
|
-
|
|
11
|
+
labelEditOptions,
|
|
12
12
|
LINE_EDIT_OPTIONS,
|
|
13
13
|
prefix,
|
|
14
14
|
resolveAngle,
|
|
@@ -54,7 +54,7 @@ export function validatePolarAxisArgs(kind, args, operation) {
|
|
|
54
54
|
if (Object.hasOwn(args.ticksAndLabels, "labels")) {
|
|
55
55
|
validateObject(
|
|
56
56
|
args.ticksAndLabels.labels,
|
|
57
|
-
|
|
57
|
+
labelEditOptions(kind).filter(key => !["count", "values"].includes(key)),
|
|
58
58
|
`${operation}.ticksAndLabels.labels`
|
|
59
59
|
);
|
|
60
60
|
}
|
|
@@ -131,7 +131,7 @@ function validateAxisEditArgs(kind, args, operation) {
|
|
|
131
131
|
validateModeOptions(args.ticks, `${operation}.ticks`);
|
|
132
132
|
}
|
|
133
133
|
if (Object.hasOwn(args, "labels") && args.labels !== false) {
|
|
134
|
-
validateObject(args.labels,
|
|
134
|
+
validateObject(args.labels, labelEditOptions(kind), `${operation}.labels`);
|
|
135
135
|
validateModeOptions(args.labels, `${operation}.labels`);
|
|
136
136
|
}
|
|
137
137
|
if (args.ticksAndLabels !== undefined &&
|
|
@@ -155,7 +155,7 @@ function validateAxisEditArgs(kind, args, operation) {
|
|
|
155
155
|
if (args.ticksAndLabels.labels !== undefined) {
|
|
156
156
|
validateObject(
|
|
157
157
|
args.ticksAndLabels.labels,
|
|
158
|
-
|
|
158
|
+
labelEditOptions(kind).filter(key => !["count", "values"].includes(key)),
|
|
159
159
|
`${operation}.ticksAndLabels.labels`
|
|
160
160
|
);
|
|
161
161
|
}
|
|
@@ -228,7 +228,7 @@ function makeEditAxis(kind) {
|
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
export const createThetaAxis = makeCreateAxis("theta");
|
|
232
|
-
export const createRadialAxis = makeCreateAxis("radius");
|
|
233
|
-
export const editThetaAxis = makeEditAxis("theta");
|
|
234
|
-
export const editRadialAxis = makeEditAxis("radius");
|
|
231
|
+
export const createThetaAxis = /* @__PURE__ */ makeCreateAxis("theta");
|
|
232
|
+
export const createRadialAxis = /* @__PURE__ */ makeCreateAxis("radius");
|
|
233
|
+
export const editThetaAxis = /* @__PURE__ */ makeEditAxis("theta");
|
|
234
|
+
export const editRadialAxis = /* @__PURE__ */ makeEditAxis("radius");
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
} from "../resolve.js";
|
|
21
21
|
import {
|
|
22
22
|
componentResources,
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
labelCreateOptions,
|
|
24
|
+
labelEditOptions,
|
|
25
25
|
operations,
|
|
26
26
|
prefix,
|
|
27
27
|
resolveAngle,
|
|
@@ -30,9 +30,11 @@ import {
|
|
|
30
30
|
validateObject,
|
|
31
31
|
withAxisSemantics
|
|
32
32
|
} from "./shared.js";
|
|
33
|
+
import { normalizeDisplayLabelMap } from
|
|
34
|
+
"../../../../grammar/displayLabels.js";
|
|
33
35
|
|
|
34
36
|
function labelGeometry(program, kind, config, angle = resolveAngle(program, kind, {})) {
|
|
35
|
-
const frame = resolvePolarFrameForProgram(program);
|
|
37
|
+
const frame = resolvePolarFrameForProgram(program, config.coordinate);
|
|
36
38
|
const mapped = mapPolarGuideValues(program, config);
|
|
37
39
|
const text = formatPolarGuideValues(program, config, mapped.values);
|
|
38
40
|
const geometry = {
|
|
@@ -64,7 +66,7 @@ function labelGeometry(program, kind, config, angle = resolveAngle(program, kind
|
|
|
64
66
|
textAlign: geometry.textAlign[index],
|
|
65
67
|
textBaseline: geometry.textBaseline[index]
|
|
66
68
|
}))
|
|
67
|
-
});
|
|
69
|
+
}, program.materializationConfigs.textMetrics);
|
|
68
70
|
return geometry;
|
|
69
71
|
}
|
|
70
72
|
|
|
@@ -115,6 +117,23 @@ function resolveLabelConfig(program, kind, args, resources, previous) {
|
|
|
115
117
|
fontWeight: args.fontWeight ?? previous?.fontWeight ??
|
|
116
118
|
POLAR_AXIS_DEFAULTS.labels.fontWeight
|
|
117
119
|
};
|
|
120
|
+
const labelScale = program.resolvedScales[resources.scale];
|
|
121
|
+
if (Object.hasOwn(args, "labelMap")) {
|
|
122
|
+
if (kind !== "theta" || !["ordinal", "band", "point"].includes(labelScale?.type)) {
|
|
123
|
+
throw new Error(`${prefix(kind)} axis labelMap requires a categorical theta scale.`);
|
|
124
|
+
}
|
|
125
|
+
if (args.labelMap === "auto") delete config.labelMap;
|
|
126
|
+
else {
|
|
127
|
+
config.labelMap = normalizeDisplayLabelMap(
|
|
128
|
+
args.labelMap,
|
|
129
|
+
`${prefix(kind)} axis labelMap`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (config.labelMap !== undefined &&
|
|
134
|
+
(kind !== "theta" || !["ordinal", "band", "point"].includes(labelScale?.type))) {
|
|
135
|
+
throw new Error(`${prefix(kind)} axis labelMap requires a categorical theta scale.`);
|
|
136
|
+
}
|
|
118
137
|
validatePolarTickConfig(config, `${kind}-axis labels`);
|
|
119
138
|
validateNonNegativeFinite(config.offset, "Polar axis label offset");
|
|
120
139
|
validatePolarLabelFormat(config.format);
|
|
@@ -128,7 +147,7 @@ function makeEditLabels(kind) {
|
|
|
128
147
|
op: operation.edit,
|
|
129
148
|
description: `Edit the Polar ${kind}-axis labels.`
|
|
130
149
|
}, function (args = {}) {
|
|
131
|
-
validateObject(args,
|
|
150
|
+
validateObject(args, labelEditOptions(kind), operation.edit);
|
|
132
151
|
validateModeOptions(args, operation.edit);
|
|
133
152
|
const names = polarGuideNames(kind);
|
|
134
153
|
const previous = this.guideConfigs.axis?.[kind]?.labels;
|
|
@@ -172,7 +191,7 @@ function makeCreateLabels(kind) {
|
|
|
172
191
|
op: operation.create,
|
|
173
192
|
description: `Create the Polar ${kind}-axis labels.`
|
|
174
193
|
}, function (args = {}) {
|
|
175
|
-
validateComponentCreateArgs(kind, args,
|
|
194
|
+
validateComponentCreateArgs(kind, args, labelCreateOptions(kind), operation.create);
|
|
176
195
|
validateModeOptions(args, operation.create);
|
|
177
196
|
const names = polarGuideNames(kind);
|
|
178
197
|
if (this.graphicSpec.objects[names.labels] !== undefined) {
|
|
@@ -199,7 +218,7 @@ function makeCreateLabels(kind) {
|
|
|
199
218
|
});
|
|
200
219
|
}
|
|
201
220
|
|
|
202
|
-
export const createThetaAxisLabels = makeCreateLabels("theta");
|
|
203
|
-
export const createRadialAxisLabels = makeCreateLabels("radius");
|
|
204
|
-
export const editThetaAxisLabels = makeEditLabels("theta");
|
|
205
|
-
export const editRadialAxisLabels = makeEditLabels("radius");
|
|
221
|
+
export const createThetaAxisLabels = /* @__PURE__ */ makeCreateLabels("theta");
|
|
222
|
+
export const createRadialAxisLabels = /* @__PURE__ */ makeCreateLabels("radius");
|
|
223
|
+
export const editThetaAxisLabels = /* @__PURE__ */ makeEditLabels("theta");
|
|
224
|
+
export const editRadialAxisLabels = /* @__PURE__ */ makeEditLabels("radius");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { editGraphicProperties } from "../../../primitives/graphicProperties.js";
|
|
1
2
|
import { action } from "../../../../core/action.js";
|
|
2
3
|
import {
|
|
3
4
|
buildPolarCircleCommands,
|
|
@@ -23,8 +24,8 @@ import {
|
|
|
23
24
|
withAxisSemantics
|
|
24
25
|
} from "./shared.js";
|
|
25
26
|
|
|
26
|
-
function lineGeometry(program, kind, angle, scale) {
|
|
27
|
-
const frame = resolvePolarFrameForProgram(program);
|
|
27
|
+
function lineGeometry(program, kind, angle, scale, coordinate) {
|
|
28
|
+
const frame = resolvePolarFrameForProgram(program, coordinate);
|
|
28
29
|
if (kind === "theta") {
|
|
29
30
|
return { commands: buildPolarCircleCommands(frame, frame.availableRadius) };
|
|
30
31
|
}
|
|
@@ -52,22 +53,21 @@ function makeEditLine(kind) {
|
|
|
52
53
|
const config = { ...previous, ...args };
|
|
53
54
|
validatePolarLineStyle(config, `${prefix(kind)} axis line`);
|
|
54
55
|
const angle = resolveAngle(this, kind, {});
|
|
55
|
-
const geometry = lineGeometry(
|
|
56
|
+
const geometry = lineGeometry(
|
|
57
|
+
this,
|
|
58
|
+
kind,
|
|
59
|
+
angle,
|
|
60
|
+
previous.scale,
|
|
61
|
+
previous.coordinate
|
|
62
|
+
);
|
|
56
63
|
let next = this._withGuideConfig(kind, "line", config);
|
|
57
64
|
for (const [property, value] of Object.entries(geometry)) {
|
|
58
65
|
next = next.editGraphics({ target: names.line, property, value });
|
|
59
66
|
}
|
|
60
|
-
return next
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
value: config.color
|
|
65
|
-
})
|
|
66
|
-
.editGraphics({
|
|
67
|
-
target: names.line,
|
|
68
|
-
property: "strokeWidth",
|
|
69
|
-
value: config.lineWidth
|
|
70
|
-
});
|
|
67
|
+
return editGraphicProperties(next, names.line, {
|
|
68
|
+
stroke: config.color,
|
|
69
|
+
strokeWidth: config.lineWidth
|
|
70
|
+
});
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -91,7 +91,7 @@ function makeCreateLine(kind) {
|
|
|
91
91
|
lineWidth: args.lineWidth ?? POLAR_AXIS_DEFAULTS.line.lineWidth
|
|
92
92
|
};
|
|
93
93
|
validatePolarLineStyle(config, `${prefix(kind)} axis line`);
|
|
94
|
-
lineGeometry(this, kind, angle, resources.scale);
|
|
94
|
+
lineGeometry(this, kind, angle, resources.scale, resources.coordinate);
|
|
95
95
|
let next = withAxisSemantics(this, kind, resources);
|
|
96
96
|
if (kind === "radius" &&
|
|
97
97
|
next.guideConfigs.axis?.radius?.layout === undefined) {
|
|
@@ -108,7 +108,7 @@ function makeCreateLine(kind) {
|
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
export const createThetaAxisLine = makeCreateLine("theta");
|
|
112
|
-
export const createRadialAxisLine = makeCreateLine("radius");
|
|
113
|
-
export const editThetaAxisLine = makeEditLine("theta");
|
|
114
|
-
export const editRadialAxisLine = makeEditLine("radius");
|
|
111
|
+
export const createThetaAxisLine = /* @__PURE__ */ makeCreateLine("theta");
|
|
112
|
+
export const createRadialAxisLine = /* @__PURE__ */ makeCreateLine("radius");
|
|
113
|
+
export const editThetaAxisLine = /* @__PURE__ */ makeEditLine("theta");
|
|
114
|
+
export const editRadialAxisLine = /* @__PURE__ */ makeEditLine("radius");
|
|
@@ -26,6 +26,22 @@ export const LABEL_EDIT_OPTIONS = Object.freeze([
|
|
|
26
26
|
"count", "values", "offset", "format", "color", "fontSize",
|
|
27
27
|
"fontFamily", "fontWeight"
|
|
28
28
|
]);
|
|
29
|
+
const THETA_LABEL_CREATE_OPTIONS = Object.freeze([
|
|
30
|
+
...LABEL_CREATE_OPTIONS,
|
|
31
|
+
"labelMap"
|
|
32
|
+
]);
|
|
33
|
+
const THETA_LABEL_EDIT_OPTIONS = Object.freeze([
|
|
34
|
+
...LABEL_EDIT_OPTIONS,
|
|
35
|
+
"labelMap"
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
export function labelCreateOptions(kind) {
|
|
39
|
+
return kind === "theta" ? THETA_LABEL_CREATE_OPTIONS : LABEL_CREATE_OPTIONS;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function labelEditOptions(kind) {
|
|
43
|
+
return kind === "theta" ? THETA_LABEL_EDIT_OPTIONS : LABEL_EDIT_OPTIONS;
|
|
44
|
+
}
|
|
29
45
|
export const TITLE_CREATE_OPTIONS = Object.freeze([
|
|
30
46
|
"scale", "coordinate", "angle", "text", "offset", "color", "fontSize",
|
|
31
47
|
"fontFamily", "fontWeight", "position"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { editGraphicProperties } from "../../../primitives/graphicProperties.js";
|
|
1
2
|
import { action } from "../../../../core/action.js";
|
|
2
3
|
import { validateNonNegativeFinite } from "../../../../core/validation.js";
|
|
3
4
|
import {
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
} from "./shared.js";
|
|
30
31
|
|
|
31
32
|
function tickGeometry(program, kind, config, angle = resolveAngle(program, kind, {})) {
|
|
32
|
-
const frame = resolvePolarFrameForProgram(program);
|
|
33
|
+
const frame = resolvePolarFrameForProgram(program, config.coordinate);
|
|
33
34
|
const mapped = mapPolarGuideValues(program, config);
|
|
34
35
|
return {
|
|
35
36
|
values: mapped.values,
|
|
@@ -112,17 +113,10 @@ function makeEditTicks(kind) {
|
|
|
112
113
|
value: geometry[property]
|
|
113
114
|
});
|
|
114
115
|
}
|
|
115
|
-
return next
|
|
116
|
-
.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
value: config.color
|
|
120
|
-
})
|
|
121
|
-
.editGraphics({
|
|
122
|
-
target: names.ticks,
|
|
123
|
-
property: "strokeWidth",
|
|
124
|
-
value: config.lineWidth
|
|
125
|
-
});
|
|
116
|
+
return editGraphicProperties(next, names.ticks, {
|
|
117
|
+
stroke: config.color,
|
|
118
|
+
strokeWidth: config.lineWidth
|
|
119
|
+
});
|
|
126
120
|
});
|
|
127
121
|
}
|
|
128
122
|
|
|
@@ -159,7 +153,7 @@ function makeCreateTicks(kind) {
|
|
|
159
153
|
});
|
|
160
154
|
}
|
|
161
155
|
|
|
162
|
-
export const createThetaAxisTicks = makeCreateTicks("theta");
|
|
163
|
-
export const createRadialAxisTicks = makeCreateTicks("radius");
|
|
164
|
-
export const editThetaAxisTicks = makeEditTicks("theta");
|
|
165
|
-
export const editRadialAxisTicks = makeEditTicks("radius");
|
|
156
|
+
export const createThetaAxisTicks = /* @__PURE__ */ makeCreateTicks("theta");
|
|
157
|
+
export const createRadialAxisTicks = /* @__PURE__ */ makeCreateTicks("radius");
|
|
158
|
+
export const editThetaAxisTicks = /* @__PURE__ */ makeEditTicks("theta");
|
|
159
|
+
export const editRadialAxisTicks = /* @__PURE__ */ makeEditTicks("radius");
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
} from "./shared.js";
|
|
31
31
|
|
|
32
32
|
function titleGeometry(program, kind, config, angle = resolveAngle(program, kind, {})) {
|
|
33
|
-
const frame = resolvePolarFrameForProgram(program);
|
|
33
|
+
const frame = resolvePolarFrameForProgram(program, config.coordinate);
|
|
34
34
|
return kind === "theta"
|
|
35
35
|
? resolveThetaAxisTitle({ frame, offset: config.offset })
|
|
36
36
|
: resolveRadialAxisTitle({
|
|
@@ -52,7 +52,7 @@ function validateTitleGeometry(program, kind, config, geometry, text) {
|
|
|
52
52
|
fontFamily: config.fontFamily,
|
|
53
53
|
fontWeight: config.fontWeight
|
|
54
54
|
}]
|
|
55
|
-
});
|
|
55
|
+
}, program.materializationConfigs.textMetrics);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
function resolveTitleConfig(kind, args, resources, previous) {
|
|
@@ -177,7 +177,7 @@ function makeCreateTitle(kind) {
|
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
export const createThetaAxisTitle = makeCreateTitle("theta");
|
|
181
|
-
export const createRadialAxisTitle = makeCreateTitle("radius");
|
|
182
|
-
export const editThetaAxisTitle = makeEditTitle("theta");
|
|
183
|
-
export const editRadialAxisTitle = makeEditTitle("radius");
|
|
180
|
+
export const createThetaAxisTitle = /* @__PURE__ */ makeCreateTitle("theta");
|
|
181
|
+
export const createRadialAxisTitle = /* @__PURE__ */ makeCreateTitle("radius");
|
|
182
|
+
export const editThetaAxisTitle = /* @__PURE__ */ makeEditTitle("theta");
|
|
183
|
+
export const editRadialAxisTitle = /* @__PURE__ */ makeEditTitle("radius");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { editGraphicProperties } from "../../primitives/graphicProperties.js";
|
|
1
2
|
import { action } from "../../../core/action.js";
|
|
2
3
|
import {
|
|
3
4
|
noOptions,
|
|
@@ -103,7 +104,7 @@ function resolveConfig(program, kind, args, resources, previous) {
|
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
function resolveGeometry(program, kind, config) {
|
|
106
|
-
const frame = resolvePolarFrameForProgram(program);
|
|
107
|
+
const frame = resolvePolarFrameForProgram(program, config.coordinate);
|
|
107
108
|
const mapped = mapPolarGuideValues(program, config);
|
|
108
109
|
if (kind === "theta") {
|
|
109
110
|
return { values: mapped.values, ...resolveThetaSpokes({
|
|
@@ -139,13 +140,10 @@ function editConcrete(program, kind, config, geometry) {
|
|
|
139
140
|
for (const [property, value] of Object.entries(properties)) {
|
|
140
141
|
next = next.editGraphics({ target: graphic, property, value });
|
|
141
142
|
}
|
|
142
|
-
return next
|
|
143
|
-
|
|
144
|
-
.
|
|
145
|
-
|
|
146
|
-
property: "strokeWidth",
|
|
147
|
-
value: config.lineWidth
|
|
148
|
-
})
|
|
143
|
+
return editGraphicProperties(next, graphic, {
|
|
144
|
+
stroke: config.color,
|
|
145
|
+
strokeWidth: config.lineWidth
|
|
146
|
+
})
|
|
149
147
|
.editGraphics({
|
|
150
148
|
target: graphic,
|
|
151
149
|
property: "strokeDash",
|
|
@@ -239,12 +237,12 @@ function makeEdit(kind) {
|
|
|
239
237
|
});
|
|
240
238
|
}
|
|
241
239
|
|
|
242
|
-
const createThetaGrid = makeCreate("theta");
|
|
243
|
-
const createRadialGrid = makeCreate("radial");
|
|
244
|
-
const editThetaGrid = makeEdit("theta");
|
|
245
|
-
const editRadialGrid = makeEdit("radial");
|
|
246
|
-
const rematerializeThetaGrid = makeRematerialize("theta");
|
|
247
|
-
const rematerializeRadialGrid = makeRematerialize("radial");
|
|
240
|
+
const createThetaGrid = /* @__PURE__ */ makeCreate("theta");
|
|
241
|
+
const createRadialGrid = /* @__PURE__ */ makeCreate("radial");
|
|
242
|
+
const editThetaGrid = /* @__PURE__ */ makeEdit("theta");
|
|
243
|
+
const editRadialGrid = /* @__PURE__ */ makeEdit("radial");
|
|
244
|
+
const rematerializeThetaGrid = /* @__PURE__ */ makeRematerialize("theta");
|
|
245
|
+
const rematerializeRadialGrid = /* @__PURE__ */ makeRematerialize("radial");
|
|
248
246
|
|
|
249
247
|
export function registerPolarGridActions(ProgramClass) {
|
|
250
248
|
ProgramClass.prototype.createThetaGrid = createThetaGrid;
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
validateNonNegativeFinite,
|
|
6
6
|
validatePositiveFinite
|
|
7
7
|
} from "../../../core/validation.js";
|
|
8
|
-
import { resolvePolarFrame } from "../../../grammar/polar.js";
|
|
9
8
|
import {
|
|
10
9
|
formatTransformedTick,
|
|
11
10
|
isTransformedScaleType,
|
|
@@ -13,7 +12,8 @@ import {
|
|
|
13
12
|
mapOrdinalPositionValues
|
|
14
13
|
} from "../../../grammar/scales/index.js";
|
|
15
14
|
import { formatTimeTick, formatTimeTicks } from "../../../grammar/ticks.js";
|
|
16
|
-
import {
|
|
15
|
+
import { resolveCoordinatePolarFrame } from
|
|
16
|
+
"../../../materialization/coordinateBounds.js";
|
|
17
17
|
import { findCoordinate } from "../../../selectors/coordinates.js";
|
|
18
18
|
import { DEFAULT_COLORS, DEFAULT_FONT_FAMILY } from
|
|
19
19
|
"../../../theme/defaults.js";
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from "../../../grammar/schemas/graphicTree.js";
|
|
24
24
|
import { valuesFromTickConfig } from "../tickValues.js";
|
|
25
25
|
import { formatAxisValue, validateAxisFormat } from "../axes/policy.js";
|
|
26
|
+
import { resolveDisplayLabel } from "../../../grammar/displayLabels.js";
|
|
26
27
|
|
|
27
28
|
export const POLAR_AXIS_DEFAULTS = Object.freeze({
|
|
28
29
|
angle: 90,
|
|
@@ -160,12 +161,8 @@ export function resolvePolarGuideResources(program, kind, args, operation) {
|
|
|
160
161
|
});
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
export function resolvePolarFrameForProgram(program) {
|
|
164
|
-
|
|
165
|
-
if (bounds === undefined) {
|
|
166
|
-
throw new Error("Polar guides require graphical Canvas bounds.");
|
|
167
|
-
}
|
|
168
|
-
return resolvePolarFrame(bounds);
|
|
164
|
+
export function resolvePolarFrameForProgram(program, coordinate) {
|
|
165
|
+
return resolveCoordinatePolarFrame(program, coordinate);
|
|
169
166
|
}
|
|
170
167
|
|
|
171
168
|
export function resolvePolarTickValues(program, config) {
|
|
@@ -203,6 +200,13 @@ export function mapPolarGuideValues(program, config) {
|
|
|
203
200
|
|
|
204
201
|
export function formatPolarGuideValues(program, config, values) {
|
|
205
202
|
const scale = program.resolvedScales[config.scale];
|
|
203
|
+
if (["ordinal", "band", "point"].includes(scale.type)) {
|
|
204
|
+
return values.map(value => resolveDisplayLabel(
|
|
205
|
+
value,
|
|
206
|
+
config.labelMap,
|
|
207
|
+
String
|
|
208
|
+
));
|
|
209
|
+
}
|
|
206
210
|
if (scale.type === "time" && config.format === "auto") {
|
|
207
211
|
return formatTimeTicks(values, scale.domain);
|
|
208
212
|
}
|
package/src/actions/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { registerTextMetricActions } from "./textMetrics/index.js";
|
|
1
2
|
import { registerPrimitiveActions } from "./primitives/index.js";
|
|
2
3
|
import { registerSelectionActions } from "./selection/index.js";
|
|
3
4
|
import { registerDataActions } from "./data/index.js";
|
|
@@ -5,7 +6,8 @@ import { registerCategoryOrderActions } from "./categoryOrder/index.js";
|
|
|
5
6
|
import { registerEncodingActions } from "./encodings/index.js";
|
|
6
7
|
import { registerScaleActions } from "./scales/index.js";
|
|
7
8
|
import { registerMarkActions } from "./marks/index.js";
|
|
8
|
-
import {
|
|
9
|
+
import { registerBasicCoordinateActions } from "./coordinates/actions.js";
|
|
10
|
+
import { registerCoordinateEditActions } from "./coordinates/edit.js";
|
|
9
11
|
import { registerFacetActions } from "./facets/index.js";
|
|
10
12
|
import { registerCompositionActions } from "./composition/index.js";
|
|
11
13
|
import { registerTitleActions } from "./titles/index.js";
|
|
@@ -19,9 +21,17 @@ import { registerViolinPlotActions } from "./violinPlots/index.js";
|
|
|
19
21
|
import { registerErrorBandActions } from "./errorBands/index.js";
|
|
20
22
|
import { registerChartActions } from "./charts/index.js";
|
|
21
23
|
import { registerThemeActions } from "./theme/index.js";
|
|
24
|
+
import { registerResourceActions } from "./resources/index.js";
|
|
25
|
+
import {
|
|
26
|
+
applyCompositionTheme,
|
|
27
|
+
removeCompositionTheme
|
|
28
|
+
} from "./theme/composition.js";
|
|
22
29
|
|
|
23
30
|
export function registerActions(ProgramClass) {
|
|
24
|
-
registerThemeActions(ProgramClass
|
|
31
|
+
registerThemeActions(ProgramClass, {
|
|
32
|
+
apply: applyCompositionTheme,
|
|
33
|
+
remove: removeCompositionTheme
|
|
34
|
+
});
|
|
25
35
|
registerPrimitiveActions(ProgramClass);
|
|
26
36
|
registerCompositionActions(ProgramClass);
|
|
27
37
|
registerFacetActions(ProgramClass);
|
|
@@ -30,7 +40,8 @@ export function registerActions(ProgramClass) {
|
|
|
30
40
|
registerMarkActions(ProgramClass);
|
|
31
41
|
registerScaleActions(ProgramClass);
|
|
32
42
|
registerEncodingActions(ProgramClass);
|
|
33
|
-
|
|
43
|
+
registerBasicCoordinateActions(ProgramClass);
|
|
44
|
+
registerCoordinateEditActions(ProgramClass);
|
|
34
45
|
registerGuideActions(ProgramClass);
|
|
35
46
|
registerTitleActions(ProgramClass);
|
|
36
47
|
registerRegressionActions(ProgramClass);
|
|
@@ -42,4 +53,6 @@ export function registerActions(ProgramClass) {
|
|
|
42
53
|
registerChartActions(ProgramClass);
|
|
43
54
|
registerCategoryOrderActions(ProgramClass);
|
|
44
55
|
registerSelectionActions(ProgramClass);
|
|
56
|
+
registerResourceActions(ProgramClass);
|
|
57
|
+
registerTextMetricActions(ProgramClass);
|
|
45
58
|
}
|