ggaction 0.0.16 → 0.0.18
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 +66 -0
- package/README.md +3 -2
- package/knowledge/action-card.schema.json +1 -1
- package/knowledge/action-cards.json +1 -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 -4
- package/src/BasicChartProgram.js +1 -1
- package/src/accessibility.js +3 -2
- package/src/actions/boxPlots/create.js +14 -4
- package/src/actions/boxPlots/edit.js +39 -33
- package/src/actions/boxPlots/materialize.js +7 -3
- package/src/actions/boxPlots/options.js +37 -11
- package/src/actions/canvas/actions.js +70 -95
- package/src/actions/canvas/fitting.js +16 -1
- package/src/actions/canvas/index.js +3 -0
- package/src/actions/canvas/plotBorder.js +28 -0
- package/src/actions/charts/area.js +2 -2
- package/src/actions/charts/bar.js +34 -7
- package/src/actions/charts/ecdf.js +4 -18
- package/src/actions/charts/endpoints.js +4 -18
- package/src/actions/charts/heatmap.js +4 -4
- package/src/actions/charts/index.js +2 -0
- package/src/actions/charts/interval-regression.js +2 -2
- package/src/actions/charts/line.js +1 -1
- package/src/actions/charts/pie.js +3 -47
- package/src/actions/charts/radial.js +34 -12
- package/src/actions/charts/scatter.js +16 -2
- package/src/actions/charts/shared.js +2 -2
- package/src/actions/charts/text.js +35 -0
- package/src/actions/composition/actions.js +6 -2
- package/src/actions/data/bin.js +1 -1
- package/src/actions/data/box.js +2 -1
- package/src/actions/data/create.js +18 -5
- package/src/actions/data/density.js +1 -1
- package/src/actions/data/derived.js +15 -1
- package/src/actions/data/edit.js +20 -7
- package/src/actions/data/filter.js +15 -4
- package/src/actions/data/index.js +3 -0
- package/src/actions/data/interval.js +2 -0
- package/src/actions/data/regression.js +6 -2
- package/src/actions/data/revise.js +37 -5
- package/src/actions/data/shared.js +33 -4
- package/src/actions/data/sort.js +21 -0
- package/src/actions/data/stack.js +3 -1
- package/src/actions/data/summary.js +1 -1
- package/src/actions/encodings/angle.js +4 -1
- package/src/actions/encodings/appearance.js +43 -31
- package/src/actions/encodings/barWidth.js +36 -11
- package/src/actions/encodings/channels.js +0 -1
- package/src/actions/encodings/color/continuous.js +5 -2
- package/src/actions/encodings/color/index.js +5 -2
- package/src/actions/encodings/color/policy.js +10 -3
- package/src/actions/encodings/density/resolve.js +1 -6
- package/src/actions/encodings/offset.js +4 -1
- package/src/actions/encodings/position/policies/arc.js +12 -10
- package/src/actions/encodings/position/policies/area.js +3 -3
- package/src/actions/encodings/position/policies/bar.js +15 -6
- package/src/actions/encodings/position/policies/line.js +17 -6
- package/src/actions/encodings/position/resolve.js +9 -3
- package/src/actions/encodings/ranged.js +23 -1
- package/src/actions/encodings/remove.js +3 -2
- package/src/actions/encodings/ruleAppearance.js +4 -1
- package/src/actions/encodings/seriesLayout.js +1 -0
- package/src/actions/encodings/stroke.js +4 -1
- package/src/actions/encodings/strokeDash.js +6 -1
- package/src/actions/encodings/text.js +12 -4
- package/src/actions/errorBands/create.js +2 -2
- package/src/actions/errorBands/edit.js +2 -1
- package/src/actions/facets/actions.js +158 -240
- package/src/actions/gradientPlots/resolve.js +2 -17
- package/src/actions/guides/applicability.js +1 -1
- package/src/actions/guides/axes/axis.js +16 -4
- package/src/actions/guides/axes/edit.js +4 -4
- package/src/actions/guides/axes/labels.js +120 -46
- package/src/actions/guides/axes/lines.js +6 -5
- package/src/actions/guides/axes/parallel/lifecycle.js +1 -1
- package/src/actions/guides/axes/parallel/policy.js +8 -7
- package/src/actions/guides/axes/remove.js +3 -2
- package/src/actions/guides/axes/tickGroups.js +5 -2
- package/src/actions/guides/axes/ticks.js +6 -3
- package/src/actions/guides/axes/titles.js +71 -26
- package/src/actions/guides/basic.js +2 -0
- package/src/actions/guides/facadeLegend.js +10 -2
- package/src/actions/guides/grids/grid.js +7 -1
- package/src/actions/guides/grids/resolve.js +59 -12
- package/src/actions/guides/legends/blocks.js +3 -1
- package/src/actions/guides/legends/categorical/actions.js +70 -17
- package/src/actions/guides/legends/categorical/components.js +12 -8
- package/src/actions/guides/legends/categorical/index.js +6 -0
- package/src/actions/guides/legends/categorical/layout.js +37 -8
- package/src/actions/guides/legends/categorical/options.js +31 -20
- package/src/actions/guides/legends/categorical/resolve.js +2 -2
- package/src/actions/guides/legends/categorical/symbols.js +18 -12
- package/src/actions/guides/legends/categorical/validation.js +1 -6
- package/src/actions/guides/legends/continuous/colorSymbols.js +1 -0
- package/src/actions/guides/legends/continuous/common.js +1 -447
- package/src/actions/guides/legends/continuous/gradient.js +47 -34
- package/src/actions/guides/legends/continuous/interval.js +4 -4
- package/src/actions/guides/legends/continuous/opacity.js +19 -12
- package/src/actions/guides/legends/edit.js +1 -604
- package/src/actions/guides/legends/focused.js +2 -2
- package/src/actions/guides/legends/group.js +1 -0
- package/src/actions/guides/legends/lane.js +1 -516
- package/src/actions/guides/legends/remove.js +3 -0
- package/src/actions/guides/legends/sampling.js +1 -1
- package/src/actions/guides/legends/size.js +51 -43
- package/src/actions/guides/legends/strokeWidth.js +11 -29
- package/src/actions/guides/legends/target.js +3 -3
- package/src/actions/guides/legends/transition.js +21 -7
- package/src/actions/guides/polar/axes/labels.js +4 -2
- package/src/actions/guides/polar/axes/titles.js +7 -5
- package/src/actions/guides/polar/resolve.js +6 -14
- package/src/actions/index.js +16 -16
- package/src/actions/marks/arc/actions.js +3 -10
- package/src/actions/marks/area/actions.js +8 -5
- package/src/actions/marks/area/materialize.js +8 -9
- package/src/actions/marks/bar/create.js +17 -4
- package/src/actions/marks/bar/edit.js +18 -7
- package/src/actions/marks/bar/materialize.js +9 -6
- package/src/actions/marks/line/actions.js +11 -4
- package/src/actions/marks/line/materialize.js +9 -5
- package/src/actions/marks/point/create.js +8 -1
- package/src/actions/marks/point/edit.js +13 -6
- package/src/actions/marks/point/materialize.js +4 -2
- package/src/actions/marks/rect/actions.js +26 -11
- package/src/actions/marks/remove.js +2 -0
- package/src/actions/marks/rule/actions.js +31 -12
- package/src/actions/marks/text/actions.js +42 -11
- package/src/actions/marks/text/layout.js +3 -0
- package/src/actions/marks/tick/actions.js +23 -8
- package/src/actions/primitives/semanticAction.js +37 -3
- package/src/actions/primitives/semanticValidation/dataset.js +13 -1
- package/src/actions/primitives/semanticValidation/layer.js +26 -2
- package/src/actions/primitives/semanticValidation/scale.js +6 -0
- package/src/actions/regression/create.js +26 -5
- package/src/actions/regression/edit.js +50 -15
- package/src/actions/regression/follow.js +22 -0
- package/src/actions/regression/resolve.js +2 -6
- package/src/actions/scales/channels.js +20 -15
- package/src/actions/scales/consumers/common.js +2 -1
- package/src/actions/scales/consumers/families.js +16 -5
- package/src/actions/scales/create.js +10 -4
- package/src/actions/scales/definitions.js +1 -425
- package/src/actions/scales/edit.js +3 -3
- package/src/actions/scales/editPolicy.js +9 -3
- package/src/actions/scales/materialize.js +1 -1
- package/src/actions/scales/parallel.js +1 -1
- package/src/actions/scales/patch.js +1 -1
- package/src/actions/scales/preview.js +49 -2
- package/src/actions/scales/quantitativeColor.js +3 -3
- package/src/actions/selection/actions.js +1 -13
- package/src/actions/theme/reconcile.js +83 -27
- package/src/actions/theme/state.js +12 -0
- package/src/actions/titles/actions.js +5 -18
- package/src/actions/titles/resolve.js +41 -19
- package/src/actions/violinPlots/edit.js +3 -20
- package/src/core/action.js +3 -2
- package/src/core/compositionState.js +4 -1
- package/src/core/font.js +9 -2
- package/src/core/optionRequirements.js +1 -0
- package/src/core/programState.js +5 -1
- package/src/core/resourceReferences.js +3 -0
- package/src/core/textMetricProfile.js +3 -2
- package/src/core/textMetrics.js +41 -4
- package/src/core/validation.js +26 -0
- package/src/core/vocabulary.js +4 -0
- package/src/grammar/aggregate.js +4 -18
- package/src/grammar/arcs.js +1 -386
- package/src/grammar/areaPaint.js +10 -0
- package/src/grammar/areaSeries.js +18 -10
- package/src/grammar/bars/geometry.js +30 -3
- package/src/grammar/bars/policy.js +12 -1
- package/src/grammar/bin.js +41 -22
- package/src/grammar/bin2d.js +1 -6
- package/src/grammar/boxPlot.js +56 -9
- package/src/grammar/categoryOrder.js +1 -6
- package/src/grammar/complete.js +15 -19
- package/src/grammar/computed.js +92 -25
- package/src/grammar/curveCommands.js +29 -16
- package/src/grammar/datasetSchema.js +382 -0
- package/src/grammar/density.js +53 -5
- package/src/grammar/displayLabels.js +28 -0
- package/src/grammar/ecdf.js +2 -9
- package/src/grammar/facets/dependencies.js +6 -2
- package/src/grammar/facets/guides.js +5 -0
- package/src/grammar/facets/index.js +2 -5
- package/src/grammar/filter.js +133 -39
- package/src/grammar/fold.js +2 -12
- package/src/grammar/gradientProfile.js +1 -6
- package/src/grammar/impute.js +21 -48
- package/src/grammar/interval.js +34 -10
- package/src/grammar/itemMissing.js +59 -0
- package/src/grammar/legendGradient.js +18 -0
- package/src/grammar/legendGroups.js +1 -0
- package/src/grammar/legendTitleStyle.js +22 -0
- package/src/grammar/lineSeries.js +32 -17
- package/src/grammar/markLabels.js +5 -2
- package/src/grammar/normalize.js +4 -54
- package/src/grammar/numeric.js +1 -290
- package/src/grammar/parallelCoordinates.js +1 -6
- package/src/grammar/parseTime.js +41 -0
- package/src/grammar/pathCommands.js +11 -4
- package/src/grammar/polar.js +1 -184
- package/src/grammar/positionCompatibility.js +3 -3
- package/src/grammar/regression/derive.js +63 -16
- package/src/grammar/regression/index.js +1 -0
- package/src/grammar/regression/models.js +116 -59
- package/src/grammar/regression/parameters.js +69 -6
- package/src/grammar/roundedRect.js +42 -54
- package/src/grammar/scales/appearance.js +1 -206
- package/src/grammar/scales/color.js +1 -382
- package/src/grammar/scales/colorConsumers.js +5 -2
- package/src/grammar/scales/definition.js +1 -190
- package/src/grammar/scales/discretized.js +1 -195
- package/src/grammar/scales/size.js +1 -456
- package/src/grammar/scales/temporal.js +2 -13
- package/src/grammar/scales/transformed.js +1 -383
- package/src/grammar/scales/types.js +1 -1
- package/src/grammar/scales/validation.js +1 -66
- package/src/grammar/schemas/concreteGraphic.js +11 -0
- package/src/grammar/schemas/graphic.js +3 -0
- package/src/grammar/schemas/semanticPath.js +5 -3
- package/src/grammar/sort.js +88 -0
- package/src/grammar/stack.js +2 -10
- package/src/grammar/statisticalReference.js +1 -6
- package/src/grammar/summary.js +120 -45
- package/src/grammar/text.js +19 -0
- package/src/grammar/timeUnit.js +16 -7
- package/src/grammar/transformKeys.js +47 -0
- package/src/grammar/transformTopology.js +1 -0
- package/src/grammar/transforms.js +25 -12
- package/src/grammar/valueFormat.js +17 -5
- package/src/grammar/weightedStatistics.js +1 -6
- package/src/grammar/window.js +4 -58
- package/src/inspection.js +495 -0
- package/src/inspectionDescriptors.js +3 -0
- package/src/layout/canvas.js +1 -110
- package/src/layout/facets.js +1 -244
- package/src/layout/labels.js +1 -0
- package/src/layout/legend.js +13 -0
- package/src/layout/legendGroup.js +1 -0
- package/src/layout/legendItems.js +59 -15
- package/src/layout/legendLane.js +1 -441
- package/src/layout/legendText.js +1 -0
- package/src/layout/title.js +35 -13
- package/src/materialization/bars/aggregate.js +11 -5
- package/src/materialization/bars/histogram.js +4 -1
- package/src/materialization/bars/ranged.js +19 -6
- package/src/materialization/bars/resolve.js +26 -3
- package/src/materialization/coordinateBounds.js +8 -0
- package/src/materialization/dependencies.js +4 -44
- package/src/materialization/facetGuides/layout.js +1 -0
- package/src/materialization/facetGuides/placement.js +19 -8
- package/src/materialization/facetGuides/preparation.js +15 -7
- package/src/materialization/facetHeaders.js +1 -347
- package/src/materialization/facets.js +1 -185
- package/src/materialization/graphicHierarchy.js +1 -1
- package/src/materialization/guides/layout.js +1 -57
- package/src/materialization/guides/resources.js +1 -123
- package/src/materialization/layout.js +53 -0
- package/src/materialization/legendGroups.js +1 -0
- package/src/materialization/legendText.js +1 -0
- package/src/materialization/legends.js +1 -1
- package/src/materialization/marks/capabilities.js +5 -6
- package/src/materialization/rect.js +1 -1
- package/src/materialization/revisionIdentity.js +19 -0
- package/src/materialization/scaleGuideDependencies.js +1 -1
- package/src/materialization/scales/map.js +3 -0
- package/src/materialization/scales/policies/arc.js +8 -7
- package/src/materialization/scales/policies/bar.js +19 -7
- package/src/materialization/scales/policies/series.js +2 -1
- package/src/materialization/scales/resolve.js +72 -7
- package/src/materialization/selection/items/arc.js +1 -1
- package/src/materialization/selection/items/bar.js +7 -6
- package/src/materialization/selection/items/path.js +7 -6
- package/src/materialization/selection/items/rect.js +2 -2
- package/src/materialization/text.js +17 -6
- package/src/materialization/textLines.js +15 -0
- package/src/persistence/codec.js +37 -6
- package/src/persistence/validation.js +47 -0
- package/src/persistence.js +94 -8
- package/src/renderers/canvas/circle.js +6 -3
- package/src/renderers/canvas/fill.js +7 -1
- package/src/renderers/canvas/index.js +2 -1
- package/src/renderers/canvas/line.js +1 -0
- package/src/renderers/canvas/path.js +1 -1
- package/src/renderers/canvas/rect.js +11 -8
- package/src/renderers/canvas/stroke.js +2 -1
- package/src/renderers/canvas/text.js +5 -3
- package/src/renderers/svg.js +4 -1
- package/src/selectors/layers.js +19 -0
- package/src/theme/defaults.js +8 -2
- package/src/version.js +1 -1
- package/types/basic.d.ts +1 -0
- package/types/index.d.ts +7 -0
- package/types/inspection.d.ts +17 -0
- package/types/program.d.ts +494 -112
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveGraphicBounds } from "../../layout/canvas.js";
|
|
1
2
|
import { action, closedAction } from "../../core/action.js";
|
|
2
3
|
import { registerFacetDataRevision, reviseUnitData } from "../data/revise.js";
|
|
3
4
|
import { freezeOwned, isPlainObject } from "../../core/immutable.js";
|
|
@@ -38,16 +39,16 @@ import {
|
|
|
38
39
|
} from "../../materialization/facetHeaders.js";
|
|
39
40
|
|
|
40
41
|
const FACET_OPTIONS = Object.freeze([
|
|
41
|
-
"id", "field", "data", "values", "columns", "gap", "align", "padding", "scales",
|
|
42
|
-
"guides"
|
|
42
|
+
"id", "field", "data", "values", "columns", "gap", "spacing", "align", "padding", "scales",
|
|
43
|
+
"guides", "headers"
|
|
43
44
|
]);
|
|
44
45
|
const FACET_GRID_OPTIONS = Object.freeze([
|
|
45
|
-
"id", "data", "rows", "columns", "combinations", "gap", "align",
|
|
46
|
-
"padding", "scales", "guides"
|
|
46
|
+
"id", "data", "rows", "columns", "combinations", "gap", "spacing", "align",
|
|
47
|
+
"padding", "scales", "guides", "headers"
|
|
47
48
|
]);
|
|
48
49
|
const REPEAT_OPTIONS = Object.freeze([
|
|
49
|
-
"id", "target", "channel", "fields", "columns", "gap", "align",
|
|
50
|
-
"padding", "scales", "guides"
|
|
50
|
+
"id", "target", "channel", "fields", "columns", "gap", "spacing", "align",
|
|
51
|
+
"padding", "scales", "guides", "headers"
|
|
51
52
|
]);
|
|
52
53
|
const SOURCE_EDIT_OPTIONS = Object.freeze(["program"]);
|
|
53
54
|
const GUIDE_OPTIONS = Object.freeze(["axes", "legend"]);
|
|
@@ -184,65 +185,149 @@ function rederiveFacet(program, { scales, guides }) {
|
|
|
184
185
|
}, compositionSpec.children);
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
|
|
188
|
-
{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
188
|
+
function resolveEditedFacetHeaders(currentHeaders, args, grid, operation = "editFacetHeaders") {
|
|
189
|
+
validateOptionObject(args, HEADER_OPTIONS, operation, {
|
|
190
|
+
allowEmpty: false,
|
|
191
|
+
emptyMessage: `${operation} requires at least one change.`
|
|
192
|
+
});
|
|
193
|
+
const role = args.role ?? "all";
|
|
194
|
+
if (!["all", "row", "column"].includes(role)) {
|
|
195
|
+
throw new Error(`Unknown facet header role "${role}".`);
|
|
196
|
+
}
|
|
197
|
+
if (role === "all" && Object.hasOwn(args, "side")) {
|
|
198
|
+
throw new Error(`${operation} side requires an explicit row or column role.`);
|
|
199
|
+
}
|
|
200
|
+
if (role === "row" && grid === undefined) {
|
|
201
|
+
throw new Error(`${operation} row role requires a row-column facet grid.`);
|
|
202
|
+
}
|
|
203
|
+
if (Object.hasOwn(args, "side")) {
|
|
204
|
+
const sides = role === "row" ? ["left", "right"]
|
|
205
|
+
: grid === undefined
|
|
206
|
+
? ["top", "bottom", "left", "right"] : ["top", "bottom"];
|
|
207
|
+
if (!sides.includes(args.side)) {
|
|
208
|
+
throw new Error(`${operation} ${role} side must be ${sides.join(" or ")}.`);
|
|
197
209
|
}
|
|
198
|
-
const scalePolicies = normalizeFacetScalePolicies(
|
|
199
|
-
this.semanticSpec,
|
|
200
|
-
args.scales ?? {}
|
|
201
|
-
);
|
|
202
|
-
const derived = deriveFacetChildren(this, definition, {
|
|
203
|
-
closeInheritedAction: true,
|
|
204
|
-
stripTitle: true,
|
|
205
|
-
scales: args.scales ?? {}
|
|
206
|
-
});
|
|
207
|
-
const preflight = resolveFacetLayout({
|
|
208
|
-
children: definition.cells.map(cell => ({
|
|
209
|
-
...compositionChildDescriptor(cell.id, derived.children[cell.id]),
|
|
210
|
-
value: cell.value
|
|
211
|
-
})),
|
|
212
|
-
...(Object.hasOwn(args, "columns") ? { columns: args.columns } : {}),
|
|
213
|
-
...(Object.hasOwn(args, "gap") ? { gap: args.gap } : {}),
|
|
214
|
-
...(Object.hasOwn(args, "align") ? { align: args.align } : {}),
|
|
215
|
-
...(Object.hasOwn(args, "padding") ? { padding: args.padding } : {}),
|
|
216
|
-
sharedLegend: guides.legend === "shared"
|
|
217
|
-
});
|
|
218
|
-
const compositionSpec = {
|
|
219
|
-
id: definition.id,
|
|
220
|
-
type: "facet",
|
|
221
|
-
children: definition.cells.map(cell => cell.id),
|
|
222
|
-
columns: preflight.columns,
|
|
223
|
-
gap: preflight.gap,
|
|
224
|
-
align: preflight.align,
|
|
225
|
-
padding: preflight.padding,
|
|
226
|
-
facet: {
|
|
227
|
-
data: definition.data,
|
|
228
|
-
field: definition.field,
|
|
229
|
-
values: definition.values,
|
|
230
|
-
scales: scalePolicies.channels,
|
|
231
|
-
guides
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
return applyCompositionState(
|
|
235
|
-
this._withMaterializationConfig(["facets", definition.id], {
|
|
236
|
-
headers: createDefaultFacetHeaders()
|
|
237
|
-
}),
|
|
238
|
-
{
|
|
239
|
-
children: derived.children,
|
|
240
|
-
compositionSpec
|
|
241
|
-
},
|
|
242
|
-
compositionSpec.children
|
|
243
|
-
);
|
|
244
210
|
}
|
|
245
|
-
)
|
|
211
|
+
if (Object.hasOwn(args, "align") &&
|
|
212
|
+
!["start", "center", "end"].includes(args.align)) {
|
|
213
|
+
throw new Error(`${operation} align must be start, center, or end.`);
|
|
214
|
+
}
|
|
215
|
+
if (role === "all" && Object.keys(args).every(key => key === "role")) {
|
|
216
|
+
throw new Error(`${operation} requires at least one change.`);
|
|
217
|
+
}
|
|
218
|
+
const current = normalizeFacetHeadersConfig(currentHeaders);
|
|
219
|
+
const owner = role === "all" ? "common" : role;
|
|
220
|
+
const patch = { ...current[owner] };
|
|
221
|
+
for (const key of HEADER_STYLE_OPTIONS) {
|
|
222
|
+
if (Object.hasOwn(args, key)) patch[key] = args[key];
|
|
223
|
+
}
|
|
224
|
+
if (Object.hasOwn(args, "side")) patch.side = args.side;
|
|
225
|
+
if (Object.hasOwn(args, "labelMap")) {
|
|
226
|
+
if (args.labelMap === "auto") delete patch.labelMap;
|
|
227
|
+
else {
|
|
228
|
+
patch.labelMap = normalizeDisplayLabelMap(
|
|
229
|
+
args.labelMap,
|
|
230
|
+
`${operation} ${role} labelMap`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const headers = {
|
|
235
|
+
...current,
|
|
236
|
+
...(role === "all" ? {} : { mode: "roles" }),
|
|
237
|
+
[owner]: patch
|
|
238
|
+
};
|
|
239
|
+
for (const headerRole of ["all", "row", "column"]) {
|
|
240
|
+
const resolved = resolveFacetHeaderConfig(headers, headerRole);
|
|
241
|
+
validatePositiveFinite(resolved.fontSize, `Facet ${headerRole} header fontSize`);
|
|
242
|
+
validateNonEmptyString(resolved.fontFamily, `Facet ${headerRole} header fontFamily`);
|
|
243
|
+
validateNonEmptyString(resolved.color, `Facet ${headerRole} header color`);
|
|
244
|
+
validateNonNegativeFinite(resolved.offset, `Facet ${headerRole} header offset`);
|
|
245
|
+
if (!(
|
|
246
|
+
(typeof resolved.fontWeight === "string" && resolved.fontWeight.length > 0) ||
|
|
247
|
+
Number.isFinite(resolved.fontWeight)
|
|
248
|
+
)) {
|
|
249
|
+
throw new TypeError(
|
|
250
|
+
`Facet ${headerRole} header fontWeight must be a non-empty string or number.`
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
if (!["start", "center", "end"].includes(resolved.align)) {
|
|
254
|
+
throw new Error(`Facet ${headerRole} header align must be start, center, or end.`);
|
|
255
|
+
}
|
|
256
|
+
if (resolved.labelMap !== undefined) {
|
|
257
|
+
normalizeDisplayLabelMap(
|
|
258
|
+
resolved.labelMap,
|
|
259
|
+
`Facet ${headerRole} header labelMap`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return headers;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function initialFacetHeaders(value, grid) {
|
|
267
|
+
let headers = createDefaultFacetHeaders();
|
|
268
|
+
if (value === undefined) return headers;
|
|
269
|
+
validateOptionObject(value, [...HEADER_STYLE_OPTIONS, "labelMap", "row", "column"], "facet.headers");
|
|
270
|
+
const { row, column, ...common } = value;
|
|
271
|
+
if (Object.keys(common).length > 0) headers = resolveEditedFacetHeaders(headers, common, grid, "facet.headers");
|
|
272
|
+
for (const [role, patch] of [["row", row], ["column", column]]) {
|
|
273
|
+
if (patch === undefined) continue;
|
|
274
|
+
validateOptionObject(patch, HEADER_OPTIONS.filter(key => key !== "role"), `facet.headers.${role}`);
|
|
275
|
+
headers = resolveEditedFacetHeaders(headers, { ...patch, role }, grid, `facet.headers.${role}`);
|
|
276
|
+
}
|
|
277
|
+
return headers;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function composeDerivedFacet(program, args, { definition, derived, guides, scalePolicies, facet }) {
|
|
281
|
+
const headers = initialFacetHeaders(args.headers, definition.grid);
|
|
282
|
+
const preflight = resolveFacetLayout({
|
|
283
|
+
spacing: args.spacing,
|
|
284
|
+
plots: Object.entries(derived.children).map(([id, child]) => ({ id, ...resolveGraphicBounds(child) })),
|
|
285
|
+
children: definition.cells.map(cell => ({
|
|
286
|
+
...compositionChildDescriptor(cell.id, derived.children[cell.id]), value: cell.value,
|
|
287
|
+
...(definition.grid === undefined ? {} : { row: cell.row, column: cell.column })
|
|
288
|
+
})),
|
|
289
|
+
columns: definition.grid?.columns.values.length ?? args.columns,
|
|
290
|
+
gap: args.gap, align: args.align, padding: args.padding,
|
|
291
|
+
sharedLegend: guides.legend === "shared"
|
|
292
|
+
});
|
|
293
|
+
const compositionSpec = {
|
|
294
|
+
id: definition.id, type: "facet", children: definition.cells.map(cell => cell.id),
|
|
295
|
+
columns: preflight.columns, gap: preflight.gap, align: preflight.align, padding: preflight.padding,
|
|
296
|
+
...(preflight.spacing === undefined ? {} : { spacing: preflight.spacing }),
|
|
297
|
+
facet: { data: definition.data, ...facet, scales: scalePolicies.channels, guides }
|
|
298
|
+
};
|
|
299
|
+
return applyCompositionState(
|
|
300
|
+
program._withMaterializationConfig(["facets", definition.id], { headers }),
|
|
301
|
+
{ children: derived.children, compositionSpec }, compositionSpec.children
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function partitionFacetAction(op, description, definitionResolver) {
|
|
306
|
+
return closedAction({ op, description }, op === "facet" ? FACET_OPTIONS : FACET_GRID_OPTIONS,
|
|
307
|
+
function (args = {}) {
|
|
308
|
+
const guides = normalizeGuides(args.guides);
|
|
309
|
+
const definition = definitionResolver(this.semanticSpec, args);
|
|
310
|
+
if (definition.family !== "cartesian" && guides.axes === "outer") {
|
|
311
|
+
throw new Error("Polar and Parallel facets do not support outer axes.");
|
|
312
|
+
}
|
|
313
|
+
const scalePolicies = normalizeFacetScalePolicies(this.semanticSpec, args.scales ?? {});
|
|
314
|
+
const derived = deriveFacetChildren(this, definition, {
|
|
315
|
+
closeInheritedAction: true, stripTitle: true, scales: args.scales ?? {}
|
|
316
|
+
});
|
|
317
|
+
const facet = definition.grid === undefined
|
|
318
|
+
? { field: definition.field, values: definition.values }
|
|
319
|
+
: { values: definition.cells.map(cell => cell.value), grid: {
|
|
320
|
+
...definition.grid, cells: definition.cells.map(cell => ({
|
|
321
|
+
id: cell.id, row: cell.row, column: cell.column,
|
|
322
|
+
rowValue: cell.rowValue, columnValue: cell.columnValue, empty: cell.empty
|
|
323
|
+
}))
|
|
324
|
+
} };
|
|
325
|
+
return composeDerivedFacet(this, args, { definition, derived, guides, scalePolicies, facet });
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export const facet = /* @__PURE__ */ partitionFacetAction("facet",
|
|
330
|
+
"Repeat one direct-source chart by field value.", resolveFacetDefinition);
|
|
246
331
|
|
|
247
332
|
function resolveRepeatDefinition(program, args) {
|
|
248
333
|
if (!isPlainObject(args)) {
|
|
@@ -453,115 +538,16 @@ export const repeatCharts = /* @__PURE__ */ closedAction(
|
|
|
453
538
|
requestedScales,
|
|
454
539
|
true
|
|
455
540
|
);
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
})),
|
|
461
|
-
...(Object.hasOwn(args, "columns") ? { columns: args.columns } : {}),
|
|
462
|
-
...(Object.hasOwn(args, "gap") ? { gap: args.gap } : {}),
|
|
463
|
-
...(Object.hasOwn(args, "align") ? { align: args.align } : {}),
|
|
464
|
-
...(Object.hasOwn(args, "padding") ? { padding: args.padding } : {}),
|
|
465
|
-
sharedLegend: guides.legend === "shared"
|
|
541
|
+
return composeDerivedFacet(this, args, {
|
|
542
|
+
definition, derived, guides, scalePolicies,
|
|
543
|
+
facet: { values: definition.fields,
|
|
544
|
+
repeat: { target: definition.target, channel: definition.channel, fields: definition.fields } }
|
|
466
545
|
});
|
|
467
|
-
const compositionSpec = {
|
|
468
|
-
id: definition.id,
|
|
469
|
-
type: "facet",
|
|
470
|
-
children: definition.cells.map(cell => cell.id),
|
|
471
|
-
columns: preflight.columns,
|
|
472
|
-
gap: preflight.gap,
|
|
473
|
-
align: preflight.align,
|
|
474
|
-
padding: preflight.padding,
|
|
475
|
-
facet: {
|
|
476
|
-
data: definition.data,
|
|
477
|
-
values: definition.fields,
|
|
478
|
-
repeat: {
|
|
479
|
-
target: definition.target,
|
|
480
|
-
channel: definition.channel,
|
|
481
|
-
fields: definition.fields
|
|
482
|
-
},
|
|
483
|
-
scales: scalePolicies.channels,
|
|
484
|
-
guides
|
|
485
|
-
}
|
|
486
|
-
};
|
|
487
|
-
return applyCompositionState(
|
|
488
|
-
this._withMaterializationConfig(["facets", definition.id], {
|
|
489
|
-
headers: createDefaultFacetHeaders()
|
|
490
|
-
}),
|
|
491
|
-
{ children: derived.children, compositionSpec },
|
|
492
|
-
compositionSpec.children
|
|
493
|
-
);
|
|
494
546
|
}
|
|
495
547
|
);
|
|
496
548
|
|
|
497
|
-
export const facetGrid = /* @__PURE__ */
|
|
498
|
-
|
|
499
|
-
op: "facetGrid",
|
|
500
|
-
description: "Repeat one direct-source Cartesian chart across a row and column field grid."
|
|
501
|
-
}, FACET_GRID_OPTIONS,
|
|
502
|
-
function (args = {}) {
|
|
503
|
-
const guides = normalizeGuides(args.guides);
|
|
504
|
-
const definition = resolveFacetGridDefinition(this.semanticSpec, args);
|
|
505
|
-
if (definition.family !== "cartesian" && guides.axes === "outer") {
|
|
506
|
-
throw new Error("Polar and Parallel facets do not support outer axes.");
|
|
507
|
-
}
|
|
508
|
-
const scalePolicies = normalizeFacetScalePolicies(
|
|
509
|
-
this.semanticSpec,
|
|
510
|
-
args.scales ?? {}
|
|
511
|
-
);
|
|
512
|
-
const derived = deriveFacetChildren(this, definition, {
|
|
513
|
-
closeInheritedAction: true,
|
|
514
|
-
stripTitle: true,
|
|
515
|
-
scales: args.scales ?? {}
|
|
516
|
-
});
|
|
517
|
-
const preflight = resolveFacetLayout({
|
|
518
|
-
children: definition.cells.map(cell => ({
|
|
519
|
-
...compositionChildDescriptor(cell.id, derived.children[cell.id]),
|
|
520
|
-
value: cell.value,
|
|
521
|
-
row: cell.row,
|
|
522
|
-
column: cell.column
|
|
523
|
-
})),
|
|
524
|
-
columns: definition.grid.columns.values.length,
|
|
525
|
-
...(Object.hasOwn(args, "gap") ? { gap: args.gap } : {}),
|
|
526
|
-
...(Object.hasOwn(args, "align") ? { align: args.align } : {}),
|
|
527
|
-
...(Object.hasOwn(args, "padding") ? { padding: args.padding } : {}),
|
|
528
|
-
sharedLegend: guides.legend === "shared"
|
|
529
|
-
});
|
|
530
|
-
const compositionSpec = {
|
|
531
|
-
id: definition.id,
|
|
532
|
-
type: "facet",
|
|
533
|
-
children: definition.cells.map(cell => cell.id),
|
|
534
|
-
columns: preflight.columns,
|
|
535
|
-
gap: preflight.gap,
|
|
536
|
-
align: preflight.align,
|
|
537
|
-
padding: preflight.padding,
|
|
538
|
-
facet: {
|
|
539
|
-
data: definition.data,
|
|
540
|
-
values: definition.cells.map(cell => cell.value),
|
|
541
|
-
grid: {
|
|
542
|
-
...definition.grid,
|
|
543
|
-
cells: definition.cells.map(cell => ({
|
|
544
|
-
id: cell.id,
|
|
545
|
-
row: cell.row,
|
|
546
|
-
column: cell.column,
|
|
547
|
-
rowValue: cell.rowValue,
|
|
548
|
-
columnValue: cell.columnValue,
|
|
549
|
-
empty: cell.empty
|
|
550
|
-
}))
|
|
551
|
-
},
|
|
552
|
-
scales: scalePolicies.channels,
|
|
553
|
-
guides
|
|
554
|
-
}
|
|
555
|
-
};
|
|
556
|
-
return applyCompositionState(
|
|
557
|
-
this._withMaterializationConfig(["facets", definition.id], {
|
|
558
|
-
headers: createDefaultFacetHeaders()
|
|
559
|
-
}),
|
|
560
|
-
{ children: derived.children, compositionSpec },
|
|
561
|
-
compositionSpec.children
|
|
562
|
-
);
|
|
563
|
-
}
|
|
564
|
-
);
|
|
549
|
+
export const facetGrid = /* @__PURE__ */ partitionFacetAction("facetGrid",
|
|
550
|
+
"Repeat one direct-source Cartesian chart across a row and column field grid.", resolveFacetGridDefinition);
|
|
565
551
|
|
|
566
552
|
export const editFacetHeaders = /* @__PURE__ */ action(
|
|
567
553
|
{
|
|
@@ -576,78 +562,7 @@ export const editFacetHeaders = /* @__PURE__ */ action(
|
|
|
576
562
|
if (!isPlainObject(config?.headers)) {
|
|
577
563
|
throw new Error(`Facet "${id}" requires header configuration.`);
|
|
578
564
|
}
|
|
579
|
-
|
|
580
|
-
allowEmpty: false,
|
|
581
|
-
emptyMessage: "editFacetHeaders requires at least one change."
|
|
582
|
-
});
|
|
583
|
-
const role = args.role ?? "all";
|
|
584
|
-
if (!["all", "row", "column"].includes(role)) {
|
|
585
|
-
throw new Error(`Unknown facet header role "${role}".`);
|
|
586
|
-
}
|
|
587
|
-
if (role === "all" && Object.hasOwn(args, "side")) {
|
|
588
|
-
throw new Error("editFacetHeaders side requires an explicit row or column role.");
|
|
589
|
-
}
|
|
590
|
-
if (role === "row" && this.compositionSpec.facet.grid === undefined) {
|
|
591
|
-
throw new Error("editFacetHeaders row role requires a row-column facet grid.");
|
|
592
|
-
}
|
|
593
|
-
if (Object.hasOwn(args, "side")) {
|
|
594
|
-
const sides = role === "row" ? ["left", "right"] : ["top", "bottom"];
|
|
595
|
-
if (!sides.includes(args.side)) {
|
|
596
|
-
throw new Error(`editFacetHeaders ${role} side must be ${sides.join(" or ")}.`);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
if (Object.hasOwn(args, "align") &&
|
|
600
|
-
!["start", "center", "end"].includes(args.align)) {
|
|
601
|
-
throw new Error("editFacetHeaders align must be start, center, or end.");
|
|
602
|
-
}
|
|
603
|
-
if (role === "all" && Object.keys(args).every(key => key === "role")) {
|
|
604
|
-
throw new Error("editFacetHeaders requires at least one change.");
|
|
605
|
-
}
|
|
606
|
-
const current = normalizeFacetHeadersConfig(config.headers);
|
|
607
|
-
const owner = role === "all" ? "common" : role;
|
|
608
|
-
const patch = { ...current[owner] };
|
|
609
|
-
for (const key of HEADER_STYLE_OPTIONS) {
|
|
610
|
-
if (Object.hasOwn(args, key)) patch[key] = args[key];
|
|
611
|
-
}
|
|
612
|
-
if (Object.hasOwn(args, "side")) patch.side = args.side;
|
|
613
|
-
if (Object.hasOwn(args, "labelMap")) {
|
|
614
|
-
if (args.labelMap === "auto") delete patch.labelMap;
|
|
615
|
-
else {
|
|
616
|
-
patch.labelMap = normalizeDisplayLabelMap(
|
|
617
|
-
args.labelMap,
|
|
618
|
-
`editFacetHeaders ${role} labelMap`
|
|
619
|
-
);
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
const headers = {
|
|
623
|
-
...current,
|
|
624
|
-
...(role === "all" ? {} : { mode: "roles" }),
|
|
625
|
-
[owner]: patch
|
|
626
|
-
};
|
|
627
|
-
for (const headerRole of ["all", "row", "column"]) {
|
|
628
|
-
const resolved = resolveFacetHeaderConfig(headers, headerRole);
|
|
629
|
-
validatePositiveFinite(resolved.fontSize, `Facet ${headerRole} header fontSize`);
|
|
630
|
-
validateNonEmptyString(resolved.fontFamily, `Facet ${headerRole} header fontFamily`);
|
|
631
|
-
validateNonEmptyString(resolved.color, `Facet ${headerRole} header color`);
|
|
632
|
-
validateNonNegativeFinite(resolved.offset, `Facet ${headerRole} header offset`);
|
|
633
|
-
if (!(
|
|
634
|
-
(typeof resolved.fontWeight === "string" && resolved.fontWeight.length > 0) ||
|
|
635
|
-
Number.isFinite(resolved.fontWeight)
|
|
636
|
-
)) {
|
|
637
|
-
throw new TypeError(
|
|
638
|
-
`Facet ${headerRole} header fontWeight must be a non-empty string or number.`
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
if (!["start", "center", "end"].includes(resolved.align)) {
|
|
642
|
-
throw new Error(`Facet ${headerRole} header align must be start, center, or end.`);
|
|
643
|
-
}
|
|
644
|
-
if (resolved.labelMap !== undefined) {
|
|
645
|
-
normalizeDisplayLabelMap(
|
|
646
|
-
resolved.labelMap,
|
|
647
|
-
`Facet ${headerRole} header labelMap`
|
|
648
|
-
);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
565
|
+
const headers = resolveEditedFacetHeaders(config.headers, args, this.compositionSpec.facet.grid);
|
|
651
566
|
return this
|
|
652
567
|
._withMaterializationConfig(["facets", id], { ...config, headers })
|
|
653
568
|
.materializeComposition();
|
|
@@ -783,6 +698,7 @@ export const editFacetSource = /* @__PURE__ */ closedAction(
|
|
|
783
698
|
columns: current.facet.grid.columns,
|
|
784
699
|
combinations: current.facet.grid.combinations,
|
|
785
700
|
gap: current.gap,
|
|
701
|
+
...(current.spacing === undefined ? {} : { spacing: current.spacing }),
|
|
786
702
|
align: current.align,
|
|
787
703
|
padding: current.padding,
|
|
788
704
|
scales,
|
|
@@ -794,6 +710,7 @@ export const editFacetSource = /* @__PURE__ */ closedAction(
|
|
|
794
710
|
...current.facet.repeat,
|
|
795
711
|
columns: current.columns,
|
|
796
712
|
gap: current.gap,
|
|
713
|
+
...(current.spacing === undefined ? {} : { spacing: current.spacing }),
|
|
797
714
|
align: current.align,
|
|
798
715
|
padding: current.padding,
|
|
799
716
|
scales,
|
|
@@ -807,6 +724,7 @@ export const editFacetSource = /* @__PURE__ */ closedAction(
|
|
|
807
724
|
values: current.facet.values,
|
|
808
725
|
columns: current.columns,
|
|
809
726
|
gap: current.gap,
|
|
727
|
+
...(current.spacing === undefined ? {} : { spacing: current.spacing }),
|
|
810
728
|
align: current.align,
|
|
811
729
|
padding: current.padding,
|
|
812
730
|
scales,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveOptionalUserId, validateUserId } from "../../core/identifiers.js";
|
|
2
|
-
import { findLayer, hasLayer } from "../../selectors/layers.js";
|
|
2
|
+
import { findLayer, hasLayer, resolveConfiguredOwner } from "../../selectors/layers.js";
|
|
3
3
|
|
|
4
4
|
const CATEGORICAL = Object.freeze(["nominal", "ordinal"]);
|
|
5
5
|
|
|
@@ -62,20 +62,5 @@ export function resolveGradientPlotId(program, requested) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export function resolveGradientOwner(program, requested, operation) {
|
|
65
|
-
|
|
66
|
-
layer => program.markConfigs[layer.id]?.gradientPlot?.materialized === true
|
|
67
|
-
);
|
|
68
|
-
if (requested !== undefined) {
|
|
69
|
-
const id = validateUserId(requested, "Gradient-plot owner id");
|
|
70
|
-
const layer = findLayer(program, id);
|
|
71
|
-
if (layer === undefined || !eligible.includes(layer)) {
|
|
72
|
-
throw new Error(`Unknown gradient-plot owner "${id}".`);
|
|
73
|
-
}
|
|
74
|
-
return layer;
|
|
75
|
-
}
|
|
76
|
-
const current = findLayer(program, program.context.currentMark);
|
|
77
|
-
if (current !== undefined && eligible.includes(current)) return current;
|
|
78
|
-
if (eligible.length === 1) return eligible[0];
|
|
79
|
-
if (eligible.length === 0) throw new Error(`${operation} requires a gradient plot.`);
|
|
80
|
-
throw new Error(`${operation} target is ambiguous; provide target.`);
|
|
65
|
+
return resolveConfiguredOwner(program, requested, { config: "gradientPlot", operation, kind: "gradient", materialized: true }, validateUserId);
|
|
81
66
|
}
|
|
@@ -56,7 +56,7 @@ export function hasInferableLegend(program, layers = program.semanticSpec.layers
|
|
|
56
56
|
(layer.mark?.type === "point" &&
|
|
57
57
|
layer.encoding?.color?.scale !== undefined &&
|
|
58
58
|
(layer.encoding?.shape?.scale !== undefined ||
|
|
59
|
-
["sequential", "quantize", "quantile", "threshold"].includes(
|
|
59
|
+
["sequential", "log", "sqrt", "symlog", "quantize", "quantile", "threshold"].includes(
|
|
60
60
|
findSemanticScale(program, layer.encoding.color.scale)?.type
|
|
61
61
|
))) ||
|
|
62
62
|
(layer.mark?.type === "line" &&
|
|
@@ -6,6 +6,8 @@ import { validateUserId } from "../../../core/identifiers.js";
|
|
|
6
6
|
import { validateKeys } from "../../../core/validation.js";
|
|
7
7
|
import { hasCoordinate } from "../../../selectors/index.js";
|
|
8
8
|
import { validateEnabledAxisComponents } from "./components.js";
|
|
9
|
+
import { requireSemanticScale } from "../../../selectors/scales.js";
|
|
10
|
+
import { requireCoordinate } from "../../../selectors/coordinates.js";
|
|
9
11
|
|
|
10
12
|
const TOP_OPTIONS = Object.freeze([
|
|
11
13
|
"scale",
|
|
@@ -100,16 +102,26 @@ function makeCreateAxis(channel) {
|
|
|
100
102
|
if (!exists) {
|
|
101
103
|
throw new Error(`Unknown coordinate "${coordinate}".`);
|
|
102
104
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
);
|
|
105
|
+
const standalone = !hasConsumer;
|
|
106
|
+
if (standalone && (!Object.hasOwn(args, "scale") ||
|
|
107
|
+
next.semanticSpec.layers.some(layer => Object.values(layer.encoding ?? {}).some(encoding => encoding?.scale === scale)))) {
|
|
108
|
+
throw new Error(`${operation.create} found no ${channel} encoding for coordinate "${coordinate}" and scale "${scale}"; standalone binding requires an explicit unused scale.`);
|
|
109
|
+
}
|
|
110
|
+
if (standalone) {
|
|
111
|
+
const definition = requireSemanticScale(next, scale);
|
|
112
|
+
if (!Array.isArray(definition.domain) || definition.domain.length === 0 ||
|
|
113
|
+
requireCoordinate(next, coordinate).type !== "cartesian") {
|
|
114
|
+
throw new Error("Standalone axes require a Cartesian coordinate and explicit nonempty scale domain.");
|
|
115
|
+
}
|
|
107
116
|
}
|
|
108
117
|
|
|
109
118
|
next = next.editSemantic({
|
|
110
119
|
property: `guide.axis.${channel}.coordinate`,
|
|
111
120
|
value: coordinate
|
|
112
121
|
});
|
|
122
|
+
if (standalone) next = next._withGuideConfig(channel, "binding", { standalone: true })
|
|
123
|
+
.editSemantic({ property: `guide.axis.${channel}.scale`, value: scale })
|
|
124
|
+
.rematerializeScale({ id: scale, guides: false, marks: false });
|
|
113
125
|
}
|
|
114
126
|
|
|
115
127
|
for (const component of ["line", "ticksAndLabels", "title"]) {
|
|
@@ -16,12 +16,12 @@ const OPTIONS = Object.freeze([
|
|
|
16
16
|
]);
|
|
17
17
|
const LINE_OPTIONS = Object.freeze(["color", "lineWidth"]);
|
|
18
18
|
const TICK_OPTIONS = Object.freeze([
|
|
19
|
-
"count", "values", "length", "color", "lineWidth"
|
|
19
|
+
"count", "values", "length", "color", "lineWidth", "alongOffset"
|
|
20
20
|
]);
|
|
21
21
|
const LABEL_OPTIONS = Object.freeze([
|
|
22
22
|
"count", "values", "offset", "format", "color", "fontSize",
|
|
23
23
|
"fontFamily", "fontWeight", "rotation", "maxWidth", "wrap",
|
|
24
|
-
"lineHeight", "overlap"
|
|
24
|
+
"lineHeight", "overlap", "alongOffset", "labelMap", "flush", "colorMap"
|
|
25
25
|
]);
|
|
26
26
|
const GROUP_OPTIONS = Object.freeze(["count", "values", "ticks", "labels"]);
|
|
27
27
|
const TITLE_OPTIONS = Object.freeze([
|
|
@@ -59,12 +59,12 @@ function validateArgs(args, operation) {
|
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
if (args.ticksAndLabels !== false && args.ticksAndLabels?.ticks !== undefined) {
|
|
62
|
-
validateNested(args.ticksAndLabels, "ticks", ["length", "color", "lineWidth"], `${operation}.ticksAndLabels`);
|
|
62
|
+
validateNested(args.ticksAndLabels, "ticks", ["length", "color", "lineWidth", "alongOffset"], `${operation}.ticksAndLabels`);
|
|
63
63
|
}
|
|
64
64
|
if (args.ticksAndLabels !== false && args.ticksAndLabels?.labels !== undefined) {
|
|
65
65
|
validateNested(args.ticksAndLabels, "labels", [
|
|
66
66
|
"offset", "format", "color", "fontSize", "fontFamily", "fontWeight",
|
|
67
|
-
"rotation", "maxWidth", "wrap", "lineHeight", "overlap"
|
|
67
|
+
"rotation", "maxWidth", "wrap", "lineHeight", "overlap", "alongOffset", "labelMap", "flush", "colorMap"
|
|
68
68
|
], `${operation}.ticksAndLabels`);
|
|
69
69
|
}
|
|
70
70
|
}
|