ggaction 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/README.md +20 -11
- package/knowledge/action-cards.json +1 -1
- package/knowledge/intent-taxonomy.json +1 -1
- package/knowledge/mcp-resources.json +1 -1
- package/package.json +8 -3
- package/src/actions/basic.js +2 -2
- package/src/actions/boxPlots/components.js +14 -4
- package/src/actions/boxPlots/edit.js +31 -5
- package/src/actions/boxPlots/materialize.js +11 -3
- package/src/actions/boxPlots/options.js +48 -16
- package/src/actions/categoryOrder/index.js +15 -4
- package/src/actions/charts/area.js +5 -1
- package/src/actions/charts/bar.js +2 -1
- package/src/actions/charts/density.js +6 -2
- package/src/actions/charts/ecdf.js +4 -1
- package/src/actions/charts/endpoints.js +25 -3
- package/src/actions/charts/heatmap.js +2 -1
- package/src/actions/charts/histogram.js +4 -3
- package/src/actions/charts/horizon.js +3 -1
- package/src/actions/charts/interval-regression.js +5 -2
- package/src/actions/charts/line.js +3 -1
- package/src/actions/charts/parallel.js +8 -2
- package/src/actions/charts/pie.js +10 -2
- package/src/actions/charts/polar.js +15 -4
- package/src/actions/charts/radar.js +8 -2
- package/src/actions/charts/radial.js +10 -2
- package/src/actions/charts/rug-strip.js +6 -2
- package/src/actions/charts/scatter.js +3 -1
- package/src/actions/composition/actions.js +13 -4
- package/src/actions/coordinates/actions.js +1 -1
- package/src/actions/coordinates/edit.js +76 -0
- package/src/actions/data/bin.js +1 -1
- package/src/actions/data/bin2d.js +57 -185
- package/src/actions/data/complete.js +26 -0
- package/src/actions/data/computed.js +2 -2
- package/src/actions/data/create.js +2 -2
- package/src/actions/data/density.js +12 -20
- package/src/actions/data/derived.js +47 -17
- package/src/actions/data/edit.js +539 -0
- package/src/actions/data/filter.js +14 -2
- package/src/actions/data/impute.js +26 -0
- package/src/actions/data/index.js +14 -0
- package/src/actions/data/normalize.js +27 -0
- package/src/actions/data/regression.js +16 -21
- package/src/actions/data/revisionBindings.js +145 -0
- package/src/actions/data/shared.js +20 -4
- package/src/actions/data/summary.js +1 -1
- package/src/actions/data/timeUnit.js +4 -1
- package/src/actions/data/window.js +1 -1
- package/src/actions/encodings/channels.js +415 -0
- package/src/actions/encodings/color/index.js +2 -1
- package/src/actions/encodings/density.js +5 -2
- package/src/actions/encodings/histogram.js +3 -2
- package/src/actions/encodings/index.js +4 -0
- package/src/actions/encodings/offset.js +20 -13
- package/src/actions/encodings/position/apply.js +53 -7
- package/src/actions/encodings/position/index.js +10 -2
- package/src/actions/encodings/position/policies/bar.js +9 -0
- package/src/actions/encodings/position/resolve.js +24 -7
- package/src/actions/encodings/remove.js +9 -4
- package/src/actions/encodings/ruleAppearance.js +1 -23
- package/src/actions/encodings/seriesLayout.js +1 -0
- package/src/actions/encodings/shared.js +82 -14
- package/src/actions/encodings/stroke.js +226 -0
- package/src/actions/errorBands/create.js +23 -3
- package/src/actions/errorBands/edit.js +21 -6
- package/src/actions/errorBars/create.js +35 -7
- package/src/actions/errorBars/edit.js +19 -4
- package/src/actions/facets/actions.js +237 -57
- package/src/actions/facets/derive.js +91 -26
- package/src/actions/gradientPlots/components.js +10 -2
- package/src/actions/gradientPlots/edit.js +14 -4
- package/src/actions/gradientPlots/materialize.js +3 -1
- package/src/actions/gradientPlots/options.js +10 -2
- package/src/actions/guides/applicability.js +8 -2
- package/src/actions/guides/axes/labels.js +58 -12
- package/src/actions/guides/axes/lines.js +6 -2
- package/src/actions/guides/axes/parallel/resolve.js +6 -2
- package/src/actions/guides/axes/tickGroups.js +2 -1
- package/src/actions/guides/axes/ticks.js +6 -2
- package/src/actions/guides/axes/titles.js +11 -3
- package/src/actions/guides/grids/resolve.js +7 -2
- package/src/actions/guides/guides.js +19 -3
- package/src/actions/guides/legends/blocks.js +426 -0
- package/src/actions/guides/legends/categorical/actions.js +134 -48
- package/src/actions/guides/legends/categorical/components.js +17 -12
- package/src/actions/guides/legends/categorical/index.js +37 -33
- package/src/actions/guides/legends/categorical/layout.js +97 -15
- package/src/actions/guides/legends/categorical/options.js +2 -2
- package/src/actions/guides/legends/categorical/recipes.js +111 -20
- package/src/actions/guides/legends/categorical/resolve.js +12 -8
- package/src/actions/guides/legends/categorical/symbols.js +85 -30
- package/src/actions/guides/legends/continuous/common.js +30 -12
- package/src/actions/guides/legends/continuous/gradient.js +10 -7
- package/src/actions/guides/legends/continuous/index.js +2 -0
- package/src/actions/guides/legends/continuous/interval.js +8 -3
- package/src/actions/guides/legends/continuous/opacity.js +8 -5
- package/src/actions/guides/legends/continuous/stroke.js +525 -0
- package/src/actions/guides/legends/creation.js +14 -1
- package/src/actions/guides/legends/edit.js +158 -59
- package/src/actions/guides/legends/index.js +2 -0
- package/src/actions/guides/legends/lane.js +54 -19
- package/src/actions/guides/legends/lifecycle.js +19 -8
- package/src/actions/guides/legends/remove.js +13 -3
- package/src/actions/guides/legends/sampling.js +140 -0
- package/src/actions/guides/legends/size.js +93 -40
- package/src/actions/guides/legends/strokeWidth.js +34 -28
- package/src/actions/guides/legends/target.js +112 -1
- package/src/actions/guides/legends/transition.js +165 -16
- package/src/actions/guides/polar/axes/facade.js +4 -4
- package/src/actions/guides/polar/axes/labels.js +24 -5
- package/src/actions/guides/polar/axes/lines.js +10 -4
- package/src/actions/guides/polar/axes/shared.js +16 -0
- package/src/actions/guides/polar/axes/ticks.js +1 -1
- package/src/actions/guides/polar/axes/titles.js +1 -1
- package/src/actions/guides/polar/grids.js +1 -1
- package/src/actions/guides/polar/resolve.js +12 -8
- package/src/actions/index.js +14 -3
- package/src/actions/marks/arc/actions.js +77 -19
- package/src/actions/marks/area/actions.js +34 -9
- package/src/actions/marks/area/materialize.js +17 -1
- package/src/actions/marks/bar/create.js +11 -2
- package/src/actions/marks/bar/edit.js +20 -3
- package/src/actions/marks/bar/materialize.js +22 -2
- package/src/actions/marks/index.js +10 -1
- package/src/actions/marks/line/actions.js +37 -14
- package/src/actions/marks/line/materialize.js +29 -10
- package/src/actions/marks/point/create.js +8 -2
- package/src/actions/marks/point/edit.js +18 -6
- package/src/actions/marks/point/materialize.js +49 -15
- package/src/actions/marks/rect/actions.js +33 -12
- package/src/actions/marks/references.js +601 -30
- package/src/actions/marks/remove.js +71 -1
- package/src/actions/marks/rule/actions.js +47 -10
- package/src/actions/marks/shared.js +1 -1
- package/src/actions/marks/text/actions.js +74 -9
- package/src/actions/marks/text/index.js +4 -0
- package/src/actions/marks/text/layout.js +154 -6
- package/src/actions/marks/text/removal.js +173 -0
- package/src/actions/marks/text/selection.js +73 -0
- package/src/actions/marks/tick/actions.js +22 -5
- package/src/actions/primitives/editGraphics.js +26 -0
- package/src/actions/primitives/semantic.js +2 -1
- package/src/actions/primitives/semanticAction.js +83 -10
- package/src/actions/primitives/semanticValidation/guide.js +1 -1
- package/src/actions/primitives/semanticValidation/index.js +9 -1
- package/src/actions/primitives/semanticValidation/layer.js +5 -0
- package/src/actions/primitives/semanticValidation/scale.js +28 -7
- package/src/actions/regression/components.js +26 -11
- package/src/actions/regression/create.js +10 -2
- package/src/actions/regression/edit.js +21 -7
- package/src/actions/resources/index.js +7 -0
- package/src/actions/resources/remove.js +172 -0
- package/src/actions/scales/channels.js +212 -0
- package/src/actions/scales/consumers/common.js +1 -1
- package/src/actions/scales/consumers/families.js +3 -2
- package/src/actions/scales/consumers/index.js +19 -2
- package/src/actions/scales/consumers/seriesLayout.js +28 -14
- package/src/actions/scales/create.js +54 -22
- package/src/actions/scales/definitions.js +94 -40
- package/src/actions/scales/edit.js +66 -11
- package/src/actions/scales/editPolicy.js +81 -11
- package/src/actions/scales/index.js +6 -0
- package/src/actions/scales/materialize.js +4 -3
- package/src/actions/scales/offset.js +48 -0
- package/src/actions/scales/parallel.js +71 -0
- package/src/actions/scales/preview.js +111 -10
- package/src/actions/selection/actions.js +154 -30
- package/src/actions/selection/index.js +3 -0
- package/src/actions/theme/actions.js +68 -13
- package/src/actions/theme/composition.js +238 -0
- package/src/actions/theme/index.js +9 -2
- package/src/actions/theme/reconcile.js +315 -67
- package/src/actions/theme/state.js +160 -0
- package/src/actions/violinPlots/create.js +5 -2
- package/src/actions/violinPlots/edit.js +1 -0
- package/src/core/action.js +10 -0
- package/src/core/compositionState.js +6 -1
- package/src/core/programState.js +20 -0
- package/src/core/resourceReferences.js +332 -0
- package/src/core/vocabulary.js +16 -3
- package/src/grammar/bars/aggregate.js +4 -1
- package/src/grammar/bars/geometry.js +44 -0
- package/src/grammar/bin.js +54 -9
- package/src/grammar/complete.js +279 -0
- package/src/grammar/computed.js +265 -64
- package/src/grammar/coordinates.js +37 -0
- package/src/grammar/density.js +239 -37
- package/src/grammar/displayLabels.js +57 -0
- package/src/grammar/facets/dependencies.js +133 -1
- package/src/grammar/facets/guides.js +3 -0
- package/src/grammar/facets/index.js +7 -47
- package/src/grammar/facets/scales.js +15 -18
- package/src/grammar/impute.js +340 -0
- package/src/grammar/markLabelSelection.js +57 -0
- package/src/grammar/markLabels.js +18 -1
- package/src/grammar/normalize.js +366 -0
- package/src/grammar/pathSeries.js +26 -8
- package/src/grammar/pointShapes.js +13 -4
- package/src/grammar/polar.js +90 -8
- package/src/grammar/regression/index.js +1 -0
- package/src/grammar/regression/parameters.js +23 -0
- package/src/grammar/roundedRect.js +180 -0
- package/src/grammar/rules.js +1 -0
- package/src/grammar/scales/colorConsumers.js +20 -1
- package/src/grammar/scales/continuous.js +2 -2
- package/src/grammar/scales/definition.js +27 -4
- package/src/grammar/scales/index.js +1 -0
- package/src/grammar/scales/ordinal.js +12 -3
- package/src/grammar/scales/policies.js +2 -2
- package/src/grammar/scales/size.js +456 -0
- package/src/grammar/schemas/concreteGraphic.js +14 -2
- package/src/grammar/schemas/graphic.js +15 -0
- package/src/grammar/schemas/graphicBounds.js +179 -30
- package/src/grammar/schemas/semanticPath.js +7 -2
- package/src/grammar/statisticalReference.js +103 -0
- package/src/grammar/strokeStyle.js +77 -0
- package/src/grammar/summary.js +78 -16
- package/src/grammar/timeUnit.js +216 -5
- package/src/grammar/transformTopology.js +4 -0
- package/src/grammar/transforms.js +394 -28
- package/src/grammar/weightedStatistics.js +374 -0
- package/src/grammar/window.js +221 -16
- package/src/layout/aspect.js +80 -0
- package/src/layout/facets.js +59 -5
- package/src/layout/labels.js +343 -0
- package/src/materialization/bars/aggregate.js +25 -2
- package/src/materialization/bars/histogram.js +84 -24
- package/src/materialization/bars/ranged.js +19 -3
- package/src/materialization/bars/resolve.js +7 -4
- package/src/materialization/composition.js +3 -1
- package/src/materialization/coordinateBounds.js +204 -0
- package/src/materialization/dependencies.js +36 -0
- package/src/materialization/facetGuides/legacyCategorical.js +3 -0
- package/src/materialization/facetGuides/placement.js +8 -2
- package/src/materialization/facetGuides/preparation.js +12 -7
- package/src/materialization/facetHeaders.js +346 -0
- package/src/materialization/facets.js +15 -65
- package/src/materialization/guides/resources.js +26 -0
- package/src/materialization/legends.js +1 -1
- package/src/materialization/marks/index.js +11 -5
- package/src/materialization/marks/policies.js +2 -1
- package/src/materialization/rect.js +25 -12
- package/src/materialization/rectConfig.js +5 -1
- package/src/materialization/scales/map.js +5 -3
- package/src/materialization/scales/policies/binnedPosition.js +2 -2
- package/src/materialization/scales/policies/offset.js +50 -8
- package/src/materialization/scales/policies/series.js +4 -1
- package/src/materialization/scales/resolve.js +22 -6
- package/src/materialization/selection/items/arc.js +28 -4
- package/src/materialization/selection/items/bar.js +30 -3
- package/src/materialization/selection/items/common.js +19 -4
- package/src/materialization/selection/items/rect.js +28 -4
- package/src/materialization/selection/path.js +1 -1
- package/src/materialization/selection/point.js +3 -1
- package/src/materialization/text.js +265 -14
- package/src/renderers/canvas/circle.js +2 -3
- package/src/renderers/canvas/line.js +2 -3
- package/src/renderers/canvas/native.js +4 -4
- package/src/renderers/canvas/path.js +2 -3
- package/src/renderers/canvas/rect.js +2 -3
- package/src/renderers/canvas/stroke.js +11 -0
- package/src/renderers/svg.js +19 -0
- package/src/selectors/datasets.js +32 -1
- package/src/selectors/layers.js +4 -0
- package/src/theme/defaults.js +101 -0
- package/types/basic.d.ts +6 -0
- package/types/index.d.ts +85 -0
- package/types/program.d.ts +910 -117
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { freezeOwned, isPlainObject } from "../core/immutable.js";
|
|
2
|
+
import {
|
|
3
|
+
requestedStrokeDetails,
|
|
4
|
+
STROKE_STYLE_PROPERTIES
|
|
5
|
+
} from "./strokeStyle.js";
|
|
6
|
+
|
|
7
|
+
export const ROUNDED_RECT_K = 4 * (Math.sqrt(2) - 1) / 3;
|
|
8
|
+
export const RECT_STYLE_PROPERTIES = Object.freeze([
|
|
9
|
+
"cornerRadius",
|
|
10
|
+
...STROKE_STYLE_PROPERTIES
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
function requireFinite(value, property) {
|
|
14
|
+
if (!Number.isFinite(value)) {
|
|
15
|
+
throw new TypeError(`Rounded rect ${property} must be a finite number.`);
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function validateCornerRadius(value, label = "Rect style") {
|
|
21
|
+
if (!Number.isFinite(value)) {
|
|
22
|
+
throw new TypeError(`${label} cornerRadius must be a finite number.`);
|
|
23
|
+
}
|
|
24
|
+
if (value < 0) {
|
|
25
|
+
throw new RangeError(`${label} cornerRadius must not be negative.`);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function requestedRectStyleDetails(request = {}, label = "Rect style") {
|
|
31
|
+
if (!isPlainObject(request)) {
|
|
32
|
+
throw new TypeError(`${label} details must be a plain object.`);
|
|
33
|
+
}
|
|
34
|
+
return freezeOwned({
|
|
35
|
+
...requestedStrokeDetails(request, label),
|
|
36
|
+
...(Object.hasOwn(request, "cornerRadius")
|
|
37
|
+
? { cornerRadius: validateCornerRadius(request.cornerRadius, label) }
|
|
38
|
+
: {})
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function normalizeRectGeometry({ x, y, width, height }) {
|
|
43
|
+
x = requireFinite(x, "x");
|
|
44
|
+
y = requireFinite(y, "y");
|
|
45
|
+
width = requireFinite(width, "width");
|
|
46
|
+
height = requireFinite(height, "height");
|
|
47
|
+
if (width < 0) {
|
|
48
|
+
x += width;
|
|
49
|
+
width = -width;
|
|
50
|
+
}
|
|
51
|
+
if (height < 0) {
|
|
52
|
+
y += height;
|
|
53
|
+
height = -height;
|
|
54
|
+
}
|
|
55
|
+
return freezeOwned({ x, y, width, height });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function resolveRoundedRectRadius(width, height, requestedRadius) {
|
|
59
|
+
requireFinite(width, "width");
|
|
60
|
+
requireFinite(height, "height");
|
|
61
|
+
validateCornerRadius(requestedRadius, "Rounded rect");
|
|
62
|
+
if (width < 0 || height < 0) {
|
|
63
|
+
throw new RangeError("Rounded rect width and height must not be negative.");
|
|
64
|
+
}
|
|
65
|
+
return Math.min(requestedRadius, width / 2, height / 2);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function roundedRectCommands({ x, y, width, height, radius }) {
|
|
69
|
+
const geometry = normalizeRectGeometry({ x, y, width, height });
|
|
70
|
+
const r = resolveRoundedRectRadius(
|
|
71
|
+
geometry.width,
|
|
72
|
+
geometry.height,
|
|
73
|
+
radius
|
|
74
|
+
);
|
|
75
|
+
if (!(r > 0)) {
|
|
76
|
+
throw new RangeError("Rounded rect commands require a positive resolved radius.");
|
|
77
|
+
}
|
|
78
|
+
const right = geometry.x + geometry.width;
|
|
79
|
+
const bottom = geometry.y + geometry.height;
|
|
80
|
+
const c = ROUNDED_RECT_K * r;
|
|
81
|
+
return freezeOwned([
|
|
82
|
+
{ op: "M", x: geometry.x + r, y: geometry.y },
|
|
83
|
+
{ op: "L", x: right - r, y: geometry.y },
|
|
84
|
+
{
|
|
85
|
+
op: "C",
|
|
86
|
+
x1: right - r + c,
|
|
87
|
+
y1: geometry.y,
|
|
88
|
+
x2: right,
|
|
89
|
+
y2: geometry.y + r - c,
|
|
90
|
+
x: right,
|
|
91
|
+
y: geometry.y + r
|
|
92
|
+
},
|
|
93
|
+
{ op: "L", x: right, y: bottom - r },
|
|
94
|
+
{
|
|
95
|
+
op: "C",
|
|
96
|
+
x1: right,
|
|
97
|
+
y1: bottom - r + c,
|
|
98
|
+
x2: right - r + c,
|
|
99
|
+
y2: bottom,
|
|
100
|
+
x: right - r,
|
|
101
|
+
y: bottom
|
|
102
|
+
},
|
|
103
|
+
{ op: "L", x: geometry.x + r, y: bottom },
|
|
104
|
+
{
|
|
105
|
+
op: "C",
|
|
106
|
+
x1: geometry.x + r - c,
|
|
107
|
+
y1: bottom,
|
|
108
|
+
x2: geometry.x,
|
|
109
|
+
y2: bottom - r + c,
|
|
110
|
+
x: geometry.x,
|
|
111
|
+
y: bottom - r
|
|
112
|
+
},
|
|
113
|
+
{ op: "L", x: geometry.x, y: geometry.y + r },
|
|
114
|
+
{
|
|
115
|
+
op: "C",
|
|
116
|
+
x1: geometry.x,
|
|
117
|
+
y1: geometry.y + r - c,
|
|
118
|
+
x2: geometry.x + r - c,
|
|
119
|
+
y2: geometry.y,
|
|
120
|
+
x: geometry.x + r,
|
|
121
|
+
y: geometry.y
|
|
122
|
+
},
|
|
123
|
+
{ op: "Z" }
|
|
124
|
+
].map(command => freezeOwned(command)));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function materializeRectItem(properties, requestedRadius = 0) {
|
|
128
|
+
if (!isPlainObject(properties)) {
|
|
129
|
+
throw new TypeError("Rounded rect item properties must be a plain object.");
|
|
130
|
+
}
|
|
131
|
+
const geometry = normalizeRectGeometry(properties);
|
|
132
|
+
const radius = resolveRoundedRectRadius(
|
|
133
|
+
geometry.width,
|
|
134
|
+
geometry.height,
|
|
135
|
+
requestedRadius
|
|
136
|
+
);
|
|
137
|
+
const appearance = Object.fromEntries(Object.entries(properties).filter(
|
|
138
|
+
([key]) => !["x", "y", "width", "height"].includes(key)
|
|
139
|
+
));
|
|
140
|
+
return radius === 0
|
|
141
|
+
? freezeOwned({
|
|
142
|
+
type: "rect",
|
|
143
|
+
properties: freezeOwned({ ...geometry, ...appearance })
|
|
144
|
+
})
|
|
145
|
+
: freezeOwned({
|
|
146
|
+
type: "path",
|
|
147
|
+
properties: freezeOwned({
|
|
148
|
+
commands: roundedRectCommands({ ...geometry, radius }),
|
|
149
|
+
...appearance
|
|
150
|
+
})
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function readRectItemGeometry(item) {
|
|
155
|
+
if (!isPlainObject(item) || !isPlainObject(item.properties)) return undefined;
|
|
156
|
+
if (item.type === "rect") {
|
|
157
|
+
try {
|
|
158
|
+
return normalizeRectGeometry(item.properties);
|
|
159
|
+
} catch {
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const commands = item.type === "path" ? item.properties.commands : undefined;
|
|
164
|
+
if (
|
|
165
|
+
!Array.isArray(commands) ||
|
|
166
|
+
commands.length !== 10 ||
|
|
167
|
+
commands.map(command => command?.op).join("") !== "MLCLCLCLCZ"
|
|
168
|
+
) return undefined;
|
|
169
|
+
const geometry = {
|
|
170
|
+
x: commands[7].x,
|
|
171
|
+
y: commands[0].y,
|
|
172
|
+
width: commands[2].x - commands[7].x,
|
|
173
|
+
height: commands[4].y - commands[0].y
|
|
174
|
+
};
|
|
175
|
+
try {
|
|
176
|
+
return normalizeRectGeometry(geometry);
|
|
177
|
+
} catch {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
package/src/grammar/rules.js
CHANGED
|
@@ -2,8 +2,27 @@ import { BAR_GRAINS, resolveBarChannels, resolveBarGrain } from "../bars/policy.
|
|
|
2
2
|
import { validateAggregate, validateAggregateFieldType } from "../aggregate.js";
|
|
3
3
|
import { isDiscretizedColorScaleType } from "./types.js";
|
|
4
4
|
|
|
5
|
-
export function validateContinuousColorConsumer(layer, encoding, scale, {
|
|
5
|
+
export function validateContinuousColorConsumer(layer, encoding, scale, {
|
|
6
|
+
inferAggregate = false,
|
|
7
|
+
channel = "color"
|
|
8
|
+
} = {}) {
|
|
6
9
|
const kind = layer.mark?.type;
|
|
10
|
+
if (channel === "stroke") {
|
|
11
|
+
if (!["point", "line", "area", "bar", "rect", "arc", "rule", "tick"].includes(kind)) {
|
|
12
|
+
throw new Error("Continuous stroke requires a supported graphical mark consumer.");
|
|
13
|
+
}
|
|
14
|
+
if (!['quantitative', 'temporal'].includes(encoding.fieldType) ||
|
|
15
|
+
(isDiscretizedColorScaleType(scale.type) && encoding.fieldType !== "quantitative")) {
|
|
16
|
+
throw new Error(`Scale type "${scale.type}" has an incompatible stroke field type.`);
|
|
17
|
+
}
|
|
18
|
+
if (encoding.aggregate !== undefined) {
|
|
19
|
+
throw new Error("Continuous stroke does not support aggregate.");
|
|
20
|
+
}
|
|
21
|
+
if (Object.hasOwn(scale, "unknown") && kind !== "point") {
|
|
22
|
+
throw new Error("Continuous stroke scale unknown currently requires a row-owned point mark.");
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
7
26
|
if (!["point", "bar", "rect"].includes(kind)) {
|
|
8
27
|
throw new Error("Continuous color requires a Point, aggregate Bar, or Rect consumer.");
|
|
9
28
|
}
|
|
@@ -94,10 +94,10 @@ export function resolveContinuousDomain({ domain, values, type, nice, zero }) {
|
|
|
94
94
|
return resolved;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export function resolveScaleRange(range, channel, bounds) {
|
|
97
|
+
export function resolveScaleRange(range, channel, bounds, polarFrame) {
|
|
98
98
|
validatePositionChannel(channel);
|
|
99
99
|
if (POLAR_POSITION_CHANNELS.includes(channel)) {
|
|
100
|
-
return resolvePolarScaleRange(range, channel, bounds);
|
|
100
|
+
return resolvePolarScaleRange(range, channel, bounds, polarFrame);
|
|
101
101
|
}
|
|
102
102
|
const validated = validateScaleRange(range);
|
|
103
103
|
if (validated !== "auto") return validated;
|
|
@@ -24,13 +24,35 @@ function retainedValue(previous, patch, defaults, property, typeChanged) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function validateBandParameters(definition, previous, patch, defaults, typeChanged) {
|
|
27
|
+
const hasPadding = Object.hasOwn(patch, "padding");
|
|
28
|
+
if (
|
|
29
|
+
hasPadding &&
|
|
30
|
+
(Object.hasOwn(patch, "paddingInner") || Object.hasOwn(patch, "paddingOuter"))
|
|
31
|
+
) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"Scale padding cannot be combined with paddingInner or paddingOuter."
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (
|
|
37
|
+
hasPadding &&
|
|
38
|
+
(!Number.isFinite(patch.padding) || patch.padding < 0 || patch.padding >= 1)
|
|
39
|
+
) {
|
|
40
|
+
throw new RangeError(
|
|
41
|
+
"Scale padding must be from 0 (inclusive) to 1 (exclusive)."
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const normalizedPatch = hasPadding
|
|
45
|
+
? { ...patch, paddingInner: patch.padding, paddingOuter: patch.padding }
|
|
46
|
+
: patch;
|
|
27
47
|
const paddingInner = retainedValue(
|
|
28
|
-
previous,
|
|
48
|
+
previous, normalizedPatch, defaults, "paddingInner", typeChanged
|
|
29
49
|
) ?? 0;
|
|
30
50
|
const paddingOuter = retainedValue(
|
|
31
|
-
previous,
|
|
51
|
+
previous, normalizedPatch, defaults, "paddingOuter", typeChanged
|
|
32
52
|
) ?? 0;
|
|
33
|
-
const align = retainedValue(
|
|
53
|
+
const align = retainedValue(
|
|
54
|
+
previous, normalizedPatch, defaults, "align", typeChanged
|
|
55
|
+
) ?? 0.5;
|
|
34
56
|
if (!Number.isFinite(paddingInner) || paddingInner < 0 || paddingInner >= 1) {
|
|
35
57
|
throw new RangeError(
|
|
36
58
|
"Scale paddingInner must be from 0 (inclusive) to 1 (exclusive)."
|
|
@@ -66,6 +88,7 @@ export function normalizeScaleDefinition({
|
|
|
66
88
|
defaults = {},
|
|
67
89
|
retainCoreOnTypeChange = false,
|
|
68
90
|
retainCompatibleOnTypeChange = false,
|
|
91
|
+
allowOrdinalBandParameters = false,
|
|
69
92
|
validateDomain,
|
|
70
93
|
validateRange
|
|
71
94
|
}) {
|
|
@@ -143,7 +166,7 @@ export function normalizeScaleDefinition({
|
|
|
143
166
|
);
|
|
144
167
|
if (midpoint !== undefined) definition.midpoint = midpoint;
|
|
145
168
|
|
|
146
|
-
if (type === "band") {
|
|
169
|
+
if (type === "band" || (type === "ordinal" && allowOrdinalBandParameters)) {
|
|
147
170
|
validateBandParameters(definition, previous, patch, defaults, typeChanged);
|
|
148
171
|
} else if (type === "point") {
|
|
149
172
|
validatePointParameters(definition, previous, patch, defaults, typeChanged);
|
|
@@ -196,6 +196,7 @@ export function resolveOrdinalOffsetScale({
|
|
|
196
196
|
parentBandwidth,
|
|
197
197
|
paddingInner = 0,
|
|
198
198
|
paddingOuter = 0,
|
|
199
|
+
align = 0.5,
|
|
199
200
|
channel = "xOffset"
|
|
200
201
|
}) {
|
|
201
202
|
const resolvedDomain = resolveOrdinalDomain(domain, values);
|
|
@@ -217,6 +218,9 @@ export function resolveOrdinalOffsetScale({
|
|
|
217
218
|
"Offset scale paddingOuter must be a non-negative finite number."
|
|
218
219
|
);
|
|
219
220
|
}
|
|
221
|
+
if (!Number.isFinite(align) || align < 0 || align > 1) {
|
|
222
|
+
throw new RangeError("Offset scale align must be between 0 and 1.");
|
|
223
|
+
}
|
|
220
224
|
validateDomainValues(resolvedDomain, values, undefined, "ordinal");
|
|
221
225
|
const denominator = Math.max(
|
|
222
226
|
1,
|
|
@@ -231,15 +235,18 @@ export function resolveOrdinalOffsetScale({
|
|
|
231
235
|
if (!Number.isFinite(bandwidth) || bandwidth <= 0) {
|
|
232
236
|
throw new Error("Offset scale padding must leave a positive bandwidth.");
|
|
233
237
|
}
|
|
238
|
+
const occupied = step * (resolvedDomain.length - paddingInner);
|
|
239
|
+
const start = resolvedRange[0] + (resolvedRange[1] - resolvedRange[0] - occupied) * align;
|
|
234
240
|
return cloneAndFreeze({
|
|
235
241
|
type: "ordinal",
|
|
236
242
|
domain: resolvedDomain,
|
|
237
243
|
range: resolvedRange,
|
|
238
244
|
step,
|
|
239
|
-
start
|
|
245
|
+
start,
|
|
240
246
|
bandwidth,
|
|
241
247
|
paddingInner,
|
|
242
|
-
paddingOuter
|
|
248
|
+
paddingOuter,
|
|
249
|
+
align
|
|
243
250
|
});
|
|
244
251
|
}
|
|
245
252
|
|
|
@@ -296,7 +303,9 @@ export function mapOrdinalOffsetValues(values, scale) {
|
|
|
296
303
|
return finitePosition(
|
|
297
304
|
direct,
|
|
298
305
|
scale,
|
|
299
|
-
(scale.paddingOuter
|
|
306
|
+
(scale.paddingOuter * 2 * scale.align +
|
|
307
|
+
index +
|
|
308
|
+
(1 - scale.paddingInner) / 2) /
|
|
300
309
|
denominator
|
|
301
310
|
);
|
|
302
311
|
}));
|
|
@@ -9,9 +9,9 @@ export function validateScaleUnknown(channel, value) {
|
|
|
9
9
|
}
|
|
10
10
|
return value;
|
|
11
11
|
}
|
|
12
|
-
if (
|
|
12
|
+
if (["color", "stroke"].includes(channel)) {
|
|
13
13
|
if (typeof value !== "string" || value.length === 0) {
|
|
14
|
-
throw new TypeError(
|
|
14
|
+
throw new TypeError(`Scale unknown for ${channel} must be a non-empty color string.`);
|
|
15
15
|
}
|
|
16
16
|
return value;
|
|
17
17
|
}
|