ggaction 0.0.15 → 0.0.17
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 +88 -0
- package/README.md +23 -2
- 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 +40 -7
- package/src/BasicChartProgram.js +3 -1
- package/src/ChartProgram.js +2 -0
- package/src/accessibility.js +157 -0
- package/src/actions/boxPlots/components.js +6 -8
- package/src/actions/boxPlots/create.js +4 -5
- package/src/actions/boxPlots/edit.js +3 -4
- package/src/actions/boxPlots/materialize.js +1 -1
- package/src/actions/canvas/actions.js +3 -3
- package/src/actions/canvas/fitting.js +1 -1
- package/src/actions/categoryOrder/index.js +6 -8
- package/src/actions/charts/area.js +1 -1
- package/src/actions/charts/bar.js +1 -1
- package/src/actions/charts/beeswarm.js +1 -1
- package/src/actions/charts/density.js +1 -1
- package/src/actions/charts/ecdf.js +2 -2
- package/src/actions/charts/endpoints.js +4 -4
- package/src/actions/charts/heatmap.js +1 -1
- package/src/actions/charts/histogram.js +1 -1
- package/src/actions/charts/horizon.js +1 -1
- package/src/actions/charts/interval-regression.js +2 -2
- package/src/actions/charts/line.js +1 -1
- package/src/actions/charts/parallel.js +1 -1
- package/src/actions/charts/pie.js +1 -1
- package/src/actions/charts/polar.js +2 -2
- package/src/actions/charts/radar.js +1 -1
- package/src/actions/charts/radial.js +2 -2
- package/src/actions/charts/raincloud.js +2 -2
- package/src/actions/charts/rug-strip.js +2 -2
- package/src/actions/charts/scatter.js +1 -1
- package/src/actions/composition/actions.js +20 -24
- package/src/actions/coordinates/actions.js +1 -1
- package/src/actions/coordinates/edit.js +1 -1
- package/src/actions/data/basicBin2d.js +4 -5
- package/src/actions/data/bin.js +3 -3
- package/src/actions/data/bin2d.js +6 -8
- package/src/actions/data/bin2dMaterialize.js +4 -5
- package/src/actions/data/box.js +4 -4
- package/src/actions/data/complete.js +2 -2
- package/src/actions/data/computed.js +2 -2
- package/src/actions/data/create.js +23 -17
- package/src/actions/data/density.js +4 -4
- package/src/actions/data/derived.js +25 -15
- package/src/actions/data/ecdf.js +2 -2
- package/src/actions/data/edit.js +54 -29
- package/src/actions/data/filter.js +29 -24
- 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 +2 -2
- package/src/actions/data/index.js +58 -54
- package/src/actions/data/interval.js +4 -2
- package/src/actions/data/intervalEdit.js +26 -18
- package/src/actions/data/normalize.js +2 -2
- package/src/actions/data/regression.js +9 -7
- package/src/actions/data/revise.js +80 -0
- package/src/actions/data/revisionBindings.js +13 -33
- package/src/actions/data/shared.js +30 -2
- package/src/actions/data/sort.js +21 -0
- package/src/actions/data/stack.js +2 -2
- package/src/actions/data/summary.js +3 -3
- package/src/actions/data/timeUnit.js +2 -2
- package/src/actions/data/window.js +2 -2
- package/src/actions/encodings/angle.js +5 -2
- package/src/actions/encodings/appearance.js +10 -6
- package/src/actions/encodings/barWidth.js +1 -1
- package/src/actions/encodings/channels.js +2 -2
- package/src/actions/encodings/color/continuous.js +4 -1
- package/src/actions/encodings/color/index.js +5 -2
- package/src/actions/encodings/density.js +2 -2
- package/src/actions/encodings/histogram.js +1 -1
- package/src/actions/encodings/horizon.js +6 -8
- package/src/actions/encodings/offset.js +6 -3
- package/src/actions/encodings/parallel.js +4 -5
- package/src/actions/encodings/pathOrder.js +6 -11
- package/src/actions/encodings/position/index.js +4 -4
- package/src/actions/encodings/position/resolve.js +6 -1
- package/src/actions/encodings/ranged.js +11 -6
- package/src/actions/encodings/remove.js +4 -5
- package/src/actions/encodings/ruleAppearance.js +5 -2
- package/src/actions/encodings/seriesLayout.js +1 -1
- package/src/actions/encodings/stroke.js +5 -2
- package/src/actions/encodings/strokeDash.js +8 -3
- package/src/actions/encodings/text.js +7 -2
- package/src/actions/errorBands/create.js +11 -17
- package/src/actions/errorBands/edit.js +13 -131
- package/src/actions/errorBars/create.js +8 -13
- package/src/actions/errorBars/edit.js +10 -121
- package/src/actions/facets/actions.js +30 -16
- package/src/actions/facets/derive.js +8 -2
- package/src/actions/facets/guides.js +4 -5
- package/src/actions/facets/replay.js +4 -5
- package/src/actions/gradientPlots/components.js +5 -6
- package/src/actions/gradientPlots/create.js +4 -5
- package/src/actions/gradientPlots/edit.js +4 -5
- package/src/actions/gradientPlots/materialize.js +2 -2
- package/src/actions/gradientPlots/rebind.js +4 -5
- 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 +9 -9
- package/src/actions/guides/axes/lines.js +9 -7
- package/src/actions/guides/axes/parallel/lifecycle.js +13 -13
- 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 +4 -4
- package/src/actions/guides/axes/ticks.js +13 -4
- package/src/actions/guides/axes/titles.js +10 -10
- package/src/actions/guides/grids/grid.js +18 -29
- package/src/actions/guides/guides.js +1 -1
- package/src/actions/guides/legends/blocks.js +1 -1
- package/src/actions/guides/legends/categorical/actions.js +4 -4
- package/src/actions/guides/legends/categorical/components.js +38 -33
- package/src/actions/guides/legends/categorical/layout.js +1 -1
- package/src/actions/guides/legends/categorical/symbols.js +27 -30
- package/src/actions/guides/legends/continuous/common.js +46 -8
- package/src/actions/guides/legends/continuous/gradient.js +89 -155
- package/src/actions/guides/legends/continuous/interval.js +13 -13
- package/src/actions/guides/legends/continuous/opacity.js +30 -79
- package/src/actions/guides/legends/continuous/stroke.js +22 -322
- package/src/actions/guides/legends/edit.js +1 -1
- package/src/actions/guides/legends/focused.js +5 -5
- package/src/actions/guides/legends/lane.js +6 -6
- package/src/actions/guides/legends/remove.js +4 -5
- package/src/actions/guides/legends/size.js +21 -82
- package/src/actions/guides/legends/strokeWidth.js +17 -77
- package/src/actions/guides/polar/axes/facade.js +4 -4
- package/src/actions/guides/polar/axes/labels.js +5 -5
- package/src/actions/guides/polar/axes/lines.js +9 -15
- package/src/actions/guides/polar/axes/ticks.js +9 -15
- package/src/actions/guides/polar/axes/titles.js +5 -5
- package/src/actions/guides/polar/grids.js +11 -13
- package/src/actions/index.js +2 -0
- package/src/actions/intervals/revision.js +126 -0
- package/src/actions/marks/arc/actions.js +3 -3
- package/src/actions/marks/area/actions.js +4 -4
- package/src/actions/marks/bar/create.js +9 -2
- package/src/actions/marks/bar/edit.js +13 -6
- package/src/actions/marks/bar/materialize.js +12 -38
- package/src/actions/marks/line/actions.js +3 -3
- package/src/actions/marks/point/create.js +9 -2
- package/src/actions/marks/point/edit.js +13 -6
- package/src/actions/marks/point/jitter.js +6 -8
- package/src/actions/marks/point/materialize.js +20 -26
- package/src/actions/marks/point/packing.js +6 -8
- package/src/actions/marks/rect/actions.js +26 -11
- package/src/actions/marks/references.js +8 -10
- package/src/actions/marks/remove.js +5 -49
- package/src/actions/marks/rule/actions.js +28 -12
- package/src/actions/marks/text/actions.js +30 -11
- package/src/actions/marks/text/layout.js +12 -20
- package/src/actions/marks/text/removal.js +1 -1
- package/src/actions/marks/text/selection.js +4 -5
- package/src/actions/marks/tick/actions.js +26 -11
- package/src/actions/primitives/createGraphics.js +5 -4
- package/src/actions/primitives/editGraphics.js +5 -4
- package/src/actions/primitives/graphicProperties.js +6 -0
- package/src/actions/primitives/semantic.js +10 -3
- package/src/actions/primitives/semanticAction.js +44 -7
- package/src/actions/primitives/semanticValidation/dataset.js +14 -4
- package/src/actions/primitives/semanticValidation/layer.js +22 -2
- package/src/actions/primitives/semanticValidation/scale.js +6 -0
- package/src/actions/regression/components.js +10 -14
- package/src/actions/regression/create.js +28 -8
- package/src/actions/regression/edit.js +50 -16
- package/src/actions/regression/follow.js +22 -0
- package/src/actions/resources/remove.js +12 -11
- package/src/actions/scales/channels.js +11 -11
- package/src/actions/scales/consumers/common.js +2 -1
- package/src/actions/scales/create.js +3 -2
- package/src/actions/scales/definitions.js +1 -1
- package/src/actions/scales/edit.js +2 -2
- package/src/actions/scales/materialize.js +1 -1
- package/src/actions/scales/offset.js +2 -2
- package/src/actions/scales/parallel.js +2 -2
- package/src/actions/scales/patch.js +1 -1
- package/src/actions/scales/preview.js +28 -1
- package/src/actions/scales/quantitativeColor.js +4 -5
- package/src/actions/selection/actions.js +25 -36
- package/src/actions/textMetrics/index.js +56 -0
- package/src/actions/theme/actions.js +2 -2
- package/src/actions/theme/reconcile.js +67 -121
- package/src/actions/titles/actions.js +8 -8
- package/src/actions/titles/resolve.js +3 -3
- package/src/actions/violinPlots/create.js +1 -1
- package/src/actions/violinPlots/edit.js +1 -1
- package/src/core/action.js +109 -36
- 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 +6 -2
- package/src/core/resourceReferences.js +15 -6
- package/src/core/textMetricProfile.js +28 -0
- package/src/core/textMetrics.js +24 -3
- package/src/core/validation.js +22 -10
- package/src/diagnostics.js +1 -0
- package/src/grammar/bin.js +39 -10
- package/src/grammar/datasetSchema.js +386 -0
- package/src/grammar/density.js +53 -5
- package/src/grammar/filter.js +133 -39
- package/src/grammar/impute.js +3 -2
- package/src/grammar/interval.js +32 -1
- package/src/grammar/itemMissing.js +59 -0
- package/src/grammar/regression/derive.js +57 -16
- package/src/grammar/regression/index.js +1 -0
- package/src/grammar/regression/models.js +51 -22
- package/src/grammar/regression/parameters.js +56 -4
- package/src/grammar/scales/definition.js +7 -0
- package/src/grammar/scales/types.js +8 -0
- package/src/grammar/schemas/graphicBounds.js +11 -11
- package/src/grammar/schemas/semanticPath.js +3 -2
- package/src/grammar/sort.js +88 -0
- package/src/grammar/summary.js +117 -19
- package/src/grammar/transformTopology.js +1 -0
- package/src/grammar/transforms.js +21 -11
- package/src/inspection.js +495 -0
- package/src/inspectionDescriptors.js +3 -0
- package/src/layout/labels.js +11 -10
- 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/resolve.js +4 -2
- package/src/materialization/facetGuides/placement.js +1 -1
- package/src/materialization/facetGuides/preparation.js +1 -1
- package/src/materialization/facetHeaders.js +11 -10
- package/src/materialization/guides/layout.js +3 -3
- package/src/materialization/revisionIdentity.js +19 -0
- package/src/materialization/scaleGuideDependencies.js +10 -0
- package/src/materialization/scales/resolve.js +67 -4
- package/src/materialization/selection/items/common.js +1 -1
- package/src/materialization/text.js +6 -4
- 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 +147 -0
- package/src/renderers/canvas/index.js +5 -4
- 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 +10 -14
- package/src/renderers/text.js +1 -11
- package/src/selectors/coordinates.js +3 -1
- package/src/selectors/datasets.js +8 -6
- package/src/selectors/layers.js +6 -4
- package/src/selectors/markOwners.js +46 -0
- package/src/selectors/scales.js +6 -4
- package/src/theme/defaults.js +2 -1
- package/src/version.js +2 -0
- package/types/accessibility.d.ts +37 -0
- package/types/basic.d.ts +4 -2
- package/types/diagnostics.d.ts +15 -0
- package/types/index.d.ts +5 -0
- package/types/inspection.d.ts +17 -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 +181 -28
|
@@ -8,14 +8,14 @@ const OPTIONS = Object.freeze([
|
|
|
8
8
|
"id", "source", "fields", "groupBy", "sortBy", "method", "value", "edges", "maxGap"
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
|
-
export const materializeImputedData = derivedMaterializer(
|
|
11
|
+
export const materializeImputedData = /* @__PURE__ */ derivedMaterializer(
|
|
12
12
|
"materializeImputedData",
|
|
13
13
|
"Materialize one immutable missing-value dataset.",
|
|
14
14
|
"impute",
|
|
15
15
|
deriveImputedRows
|
|
16
16
|
);
|
|
17
17
|
|
|
18
|
-
export const createImputedData = derivedCreator(
|
|
18
|
+
export const createImputedData = /* @__PURE__ */ derivedCreator(
|
|
19
19
|
"createImputedData",
|
|
20
20
|
"Replace explicit missing cells within independent groups.",
|
|
21
21
|
OPTIONS,
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
materializeBin2DData
|
|
36
36
|
} from "./bin2d.js";
|
|
37
37
|
import { createData } from "./create.js";
|
|
38
|
+
import { reviseData } from "./revise.js";
|
|
38
39
|
import { createWindowData, materializeWindowData } from "./window.js";
|
|
39
40
|
import { createSummaryData, materializeSummaryData } from "./summary.js";
|
|
40
41
|
import { createBinData, materializeBinData } from "./bin.js";
|
|
@@ -47,62 +48,65 @@ import {
|
|
|
47
48
|
import { createCompleteData, materializeCompleteData } from "./complete.js";
|
|
48
49
|
import { createImputedData, materializeImputedData } from "./impute.js";
|
|
49
50
|
import { createStackData, materializeStackData } from "./stack.js";
|
|
51
|
+
import { createSortedData, materializeSortedData } from "./sort.js";
|
|
50
52
|
import { EDIT_DERIVED_DATA_ACTIONS } from "./edit.js";
|
|
51
53
|
import { createBoxSummaryData, createBoxOutlierData, materializeBoxSummaryData, materializeBoxOutlierData } from "./box.js";
|
|
52
54
|
|
|
53
55
|
export function registerDataActions(ProgramClass) {
|
|
54
|
-
Object.assign(ProgramClass.prototype, EDIT_DERIVED_DATA_ACTIONS
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
createCategoricalDensityData
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
56
|
+
Object.assign(ProgramClass.prototype, EDIT_DERIVED_DATA_ACTIONS, {
|
|
57
|
+
createData,
|
|
58
|
+
reviseData,
|
|
59
|
+
createDerivedData,
|
|
60
|
+
bindMarkData,
|
|
61
|
+
releaseDerivedData,
|
|
62
|
+
rebindLayerData,
|
|
63
|
+
createDensityData,
|
|
64
|
+
createCategoricalDensityData,
|
|
65
|
+
materializeFilteredData,
|
|
66
|
+
materializeMarkFilteredData,
|
|
67
|
+
filterData,
|
|
68
|
+
filterMarks,
|
|
69
|
+
materializeEmptyMark,
|
|
70
|
+
removeMarkFilter,
|
|
71
|
+
materializeRegressionData,
|
|
72
|
+
materializeDensityData,
|
|
73
|
+
createGradientProfileData,
|
|
74
|
+
materializeGradientProfileData,
|
|
75
|
+
createRegressionData,
|
|
76
|
+
materializeIntervalData,
|
|
77
|
+
createIntervalData,
|
|
78
|
+
createECDFData,
|
|
79
|
+
materializeECDFData,
|
|
80
|
+
createHorizonData,
|
|
81
|
+
materializeHorizonData,
|
|
82
|
+
createWindowData,
|
|
83
|
+
materializeWindowData,
|
|
84
|
+
createSummaryData,
|
|
85
|
+
materializeSummaryData,
|
|
86
|
+
createBinData,
|
|
87
|
+
materializeBinData,
|
|
88
|
+
createFoldData,
|
|
89
|
+
materializeFoldData,
|
|
90
|
+
createComputedData,
|
|
91
|
+
materializeComputedData,
|
|
92
|
+
createNormalizedData,
|
|
93
|
+
materializeNormalizedData,
|
|
94
|
+
createCompleteData,
|
|
95
|
+
materializeCompleteData,
|
|
96
|
+
createImputedData,
|
|
97
|
+
materializeImputedData,
|
|
98
|
+
createStackData,
|
|
99
|
+
materializeStackData,
|
|
100
|
+
createSortedData,
|
|
101
|
+
materializeSortedData,
|
|
102
|
+
createTimeUnitData,
|
|
103
|
+
materializeTimeUnitData,
|
|
104
|
+
createBin2DData,
|
|
105
|
+
editBin2DData,
|
|
106
|
+
materializeBin2DData,
|
|
107
|
+
createBoxSummaryData,
|
|
108
|
+
createBoxOutlierData,
|
|
109
|
+
materializeBoxSummaryData,
|
|
110
|
+
materializeBoxOutlierData
|
|
111
|
+
});
|
|
108
112
|
}
|
|
@@ -13,17 +13,18 @@ const OPTIONS = Object.freeze([
|
|
|
13
13
|
"extent",
|
|
14
14
|
"method",
|
|
15
15
|
"level",
|
|
16
|
+
"missing",
|
|
16
17
|
"as"
|
|
17
18
|
]);
|
|
18
19
|
|
|
19
|
-
export const materializeIntervalData = derivedMaterializer(
|
|
20
|
+
export const materializeIntervalData = /* @__PURE__ */ derivedMaterializer(
|
|
20
21
|
"materializeIntervalData",
|
|
21
22
|
"Materialize one grouped interval-summary dataset.",
|
|
22
23
|
"interval",
|
|
23
24
|
deriveInterval
|
|
24
25
|
);
|
|
25
26
|
|
|
26
|
-
export const createIntervalData = derivedCreator(
|
|
27
|
+
export const createIntervalData = /* @__PURE__ */ derivedCreator(
|
|
27
28
|
"createIntervalData",
|
|
28
29
|
"Create immutable grouped interval-summary values.",
|
|
29
30
|
OPTIONS,
|
|
@@ -42,6 +43,7 @@ export const createIntervalData = derivedCreator(
|
|
|
42
43
|
extent: args.extent,
|
|
43
44
|
method: args.method,
|
|
44
45
|
level: args.level,
|
|
46
|
+
missing: args.missing,
|
|
45
47
|
as
|
|
46
48
|
});
|
|
47
49
|
},
|
|
@@ -138,13 +138,7 @@ export function planIntervalRoleData(program, {
|
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
export function
|
|
142
|
-
owner,
|
|
143
|
-
data,
|
|
144
|
-
consumers,
|
|
145
|
-
statistics,
|
|
146
|
-
operation
|
|
147
|
-
}) {
|
|
141
|
+
export function validateIntervalStatistics(statistics, operation) {
|
|
148
142
|
if (!isPlainObject(statistics)) {
|
|
149
143
|
throw new TypeError(`${operation} statistics must be a plain object.`);
|
|
150
144
|
}
|
|
@@ -154,16 +148,9 @@ export function planIntervalEdit(program, {
|
|
|
154
148
|
`${operation} statistics requires center, extent, method, or level.`
|
|
155
149
|
);
|
|
156
150
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
: undefined;
|
|
161
|
-
if (transform?.type !== "interval") {
|
|
162
|
-
throw new Error(
|
|
163
|
-
`${operation} statistics requires a statistical interval owner; ` +
|
|
164
|
-
"explicit interval fields cannot be converted by edit."
|
|
165
|
-
);
|
|
166
|
-
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function mergeIntervalStatistics(transform, statistics) {
|
|
167
154
|
const center = Object.hasOwn(statistics, "center")
|
|
168
155
|
? statistics.center
|
|
169
156
|
: transform.center;
|
|
@@ -181,7 +168,28 @@ export function planIntervalEdit(program, {
|
|
|
181
168
|
} else if (extent === "ci" && transform.extent === "ci") {
|
|
182
169
|
raw.level = transform.level;
|
|
183
170
|
}
|
|
184
|
-
|
|
171
|
+
return normalizeIntervalParameters(raw);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function planIntervalEdit(program, {
|
|
175
|
+
owner,
|
|
176
|
+
data,
|
|
177
|
+
consumers,
|
|
178
|
+
statistics,
|
|
179
|
+
operation
|
|
180
|
+
}) {
|
|
181
|
+
validateIntervalStatistics(statistics, operation);
|
|
182
|
+
const previous = findDataset(program, data);
|
|
183
|
+
const transform = previous?.transform?.length === 1
|
|
184
|
+
? previous.transform[0]
|
|
185
|
+
: undefined;
|
|
186
|
+
if (transform?.type !== "interval") {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`${operation} statistics requires a statistical interval owner; ` +
|
|
189
|
+
"explicit interval fields cannot be converted by edit."
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
const parameters = mergeIntervalStatistics(transform, statistics);
|
|
185
193
|
const current = {
|
|
186
194
|
center: transform.center,
|
|
187
195
|
extent: transform.extent,
|
|
@@ -9,14 +9,14 @@ const OPTIONS = Object.freeze([
|
|
|
9
9
|
"variance", "zeroDenominator", "baseline", "sortBy"
|
|
10
10
|
]);
|
|
11
11
|
|
|
12
|
-
export const materializeNormalizedData = derivedMaterializer(
|
|
12
|
+
export const materializeNormalizedData = /* @__PURE__ */ derivedMaterializer(
|
|
13
13
|
"materializeNormalizedData",
|
|
14
14
|
"Materialize one immutable grouped normalization dataset.",
|
|
15
15
|
"normalize",
|
|
16
16
|
deriveNormalizedRows
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
export const createNormalizedData = derivedCreator(
|
|
19
|
+
export const createNormalizedData = /* @__PURE__ */ derivedCreator(
|
|
20
20
|
"createNormalizedData",
|
|
21
21
|
"Create a row-preserving grouped normalization dataset.",
|
|
22
22
|
OPTIONS,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { closedAction } from "../../core/action.js";
|
|
2
2
|
import { validateUserId } from "../../core/identifiers.js";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import {
|
|
5
5
|
deriveRegression,
|
|
6
6
|
normalizeRegressionTransform
|
|
@@ -11,9 +11,10 @@ import { derivedMaterializer } from "./shared.js";
|
|
|
11
11
|
const OPTIONS = Object.freeze([
|
|
12
12
|
"id", "source", "x", "y", "groupBy", "method", "degree", "span",
|
|
13
13
|
"confidenceMethod", "level", "confidence", "interval"
|
|
14
|
+
, "predict", "missing"
|
|
14
15
|
]);
|
|
15
16
|
|
|
16
|
-
export const materializeRegressionData = derivedMaterializer(
|
|
17
|
+
export const materializeRegressionData = /* @__PURE__ */ derivedMaterializer(
|
|
17
18
|
"materializeRegressionData",
|
|
18
19
|
"Materialize one regression derived dataset.",
|
|
19
20
|
"regression",
|
|
@@ -27,14 +28,15 @@ export const materializeRegressionData = derivedMaterializer(
|
|
|
27
28
|
confidenceMethod: transform.confidenceMethod,
|
|
28
29
|
level: transform.level,
|
|
29
30
|
confidence: transform.confidence,
|
|
30
|
-
interval: transform.interval
|
|
31
|
+
interval: transform.interval,
|
|
32
|
+
predict: transform.predict
|
|
33
|
+
, missing: transform.missing
|
|
31
34
|
})
|
|
32
35
|
);
|
|
33
36
|
|
|
34
|
-
export const createRegressionData =
|
|
35
|
-
{ op: "createRegressionData", description: "Create grouped regression values and optional interval bounds." },
|
|
37
|
+
export const createRegressionData = /* @__PURE__ */ closedAction(
|
|
38
|
+
{ op: "createRegressionData", description: "Create grouped regression values and optional interval bounds." }, OPTIONS,
|
|
36
39
|
function (args = {}) {
|
|
37
|
-
validateKeys(args, OPTIONS, "createRegressionData");
|
|
38
40
|
const id = validateUserId(args.id, "Regression dataset id");
|
|
39
41
|
const requestedSource = validateUserId(
|
|
40
42
|
args.source ?? this.context.currentData,
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { closedAction } from "../../core/action.js";
|
|
2
|
+
import { validateUserId } from "../../core/identifiers.js";
|
|
3
|
+
|
|
4
|
+
import { requireDataset } from "../../selectors/datasets.js";
|
|
5
|
+
import { requireLayer } from "../../selectors/layers.js";
|
|
6
|
+
import { applyRevisionPlan, buildSourceRevisionPlan } from "./edit.js";
|
|
7
|
+
import { resolveStoredSelection } from "../../materialization/selection/state.js";
|
|
8
|
+
import { withGuideLayoutTransaction } from "../../materialization/guides/layout.js";
|
|
9
|
+
import { assertFieldsAvailable } from "../../grammar/datasetSchema.js";
|
|
10
|
+
|
|
11
|
+
let reviseFacet;
|
|
12
|
+
|
|
13
|
+
function layerInputFields(layer) {
|
|
14
|
+
const fields = [];
|
|
15
|
+
const add = value => {
|
|
16
|
+
if (typeof value === "string" && value.length > 0) fields.push(value);
|
|
17
|
+
};
|
|
18
|
+
for (const encoding of Object.values(layer.encoding ?? {})) {
|
|
19
|
+
if (!encoding || typeof encoding !== "object") continue;
|
|
20
|
+
add(encoding.field);
|
|
21
|
+
add(encoding.weight);
|
|
22
|
+
add(encoding.key);
|
|
23
|
+
add(encoding.pathOrder?.field);
|
|
24
|
+
add(encoding.categoryOrder?.by?.field);
|
|
25
|
+
for (const field of encoding.fields ?? []) add(field);
|
|
26
|
+
for (const dimension of encoding.dimensions ?? []) add(dimension.field);
|
|
27
|
+
}
|
|
28
|
+
return [...new Set(fields)];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function registerFacetDataRevision(handler) {
|
|
32
|
+
reviseFacet = handler;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function reviseUnitData(program, { source, id, values, schema }) {
|
|
36
|
+
const plan = buildSourceRevisionPlan(program, source, id);
|
|
37
|
+
const original = requireDataset(program, source);
|
|
38
|
+
const inheritedSchema = schema ?? (original.schema?.origin === "declared"
|
|
39
|
+
? { fields: original.schema.fields.map(({ name, storageType, nullable, optional }) => ({
|
|
40
|
+
name, storageType, nullable, optional
|
|
41
|
+
})) }
|
|
42
|
+
: undefined);
|
|
43
|
+
const created = program.createData({ id, values, ...(inheritedSchema === undefined ? {} : { schema: inheritedSchema }) });
|
|
44
|
+
const revisedSource = requireDataset(created, id);
|
|
45
|
+
for (const layer of program.semanticSpec.layers.filter(layer => layer.data === source)) {
|
|
46
|
+
assertFieldsAvailable(revisedSource.schema, layerInputFields(layer), {
|
|
47
|
+
data: id,
|
|
48
|
+
operation: "reviseData"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const next = withGuideLayoutTransaction(created, candidate =>
|
|
52
|
+
applyRevisionPlan(candidate, undefined, plan, { retain: new Set([source]) }));
|
|
53
|
+
for (const [selection, config] of Object.entries(next.materializationConfigs.selections ?? {})) {
|
|
54
|
+
if (plan.replacements.has(requireLayer(program, config.target).data)) {
|
|
55
|
+
resolveStoredSelection(next, selection);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { program: next, plan };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const reviseData = /* @__PURE__ */ closedAction(
|
|
62
|
+
{ op: "reviseData", description: "Revise source data and its dependent chart.", scope: "any" }, ["source", "id", "values", "schema"],
|
|
63
|
+
function (args = {}) {
|
|
64
|
+
const source = validateUserId(args.source, "Source dataset id");
|
|
65
|
+
const id = validateUserId(args.id, "Revision dataset id");
|
|
66
|
+
if (this.compositionSpec !== undefined && this.compositionSpec.type !== "facet") {
|
|
67
|
+
throw new Error("Revise an explicit child, then use replaceCompositionChild for concat.");
|
|
68
|
+
}
|
|
69
|
+
const original = requireDataset(this, source);
|
|
70
|
+
if (original.source !== undefined || !Array.isArray(original.values)) {
|
|
71
|
+
throw new Error(`Source "${source}" must be a materialized original dataset.`);
|
|
72
|
+
}
|
|
73
|
+
const apply = this.compositionSpec === undefined
|
|
74
|
+
? program => reviseUnitData(program, { source, id, values: args.values, schema: args.schema }).program
|
|
75
|
+
: program => reviseFacet(program, { source, id, values: args.values, schema: args.schema });
|
|
76
|
+
// The entire dependent materialization must succeed before returning a revision.
|
|
77
|
+
apply(this);
|
|
78
|
+
return apply(this);
|
|
79
|
+
}
|
|
80
|
+
);
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { collectDataOwnerReferences, collectMarkConfigReferences } from "../../core/resourceReferences.js";
|
|
2
2
|
import { datasetTransformOutputRoles } from "../../grammar/transforms.js";
|
|
3
3
|
import { requireLayer } from "../../selectors/layers.js";
|
|
4
4
|
|
|
5
|
-
const DATA_REFERENCE_KEYS = new Set([
|
|
6
|
-
"data", "dataset", "dataId", "filteredData", "originalData",
|
|
7
|
-
"outlierDataId", "profileId", "source", "summaryId"
|
|
8
|
-
]);
|
|
9
5
|
|
|
10
6
|
export function outputFieldChanges(previous, next) {
|
|
11
7
|
const before = datasetTransformOutputRoles(previous);
|
|
@@ -107,39 +103,23 @@ export function rebindLayerOutputFields(program, id, changes) {
|
|
|
107
103
|
return next;
|
|
108
104
|
}
|
|
109
105
|
|
|
110
|
-
function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return next;
|
|
117
|
-
});
|
|
118
|
-
return changed ? items : value;
|
|
119
|
-
}
|
|
120
|
-
if (!isPlainObject(value)) {
|
|
121
|
-
return DATA_REFERENCE_KEYS.has(key) && replacements.has(value)
|
|
122
|
-
? replacements.get(value)
|
|
123
|
-
: value;
|
|
124
|
-
}
|
|
125
|
-
let changed = false;
|
|
126
|
-
const result = {};
|
|
127
|
-
for (const [childKey, child] of Object.entries(value)) {
|
|
128
|
-
const next = replaceReferences(child, replacements, childKey);
|
|
129
|
-
changed ||= next !== child;
|
|
130
|
-
result[childKey] = next;
|
|
131
|
-
}
|
|
132
|
-
return changed ? result : value;
|
|
106
|
+
function replaceAtPath(value, [key, ...rest], replacement) {
|
|
107
|
+
const result = Array.isArray(value) ? [...value] : { ...value };
|
|
108
|
+
Object.defineProperty(result, key, { value: rest.length === 0
|
|
109
|
+
? replacement : replaceAtPath(value[key], rest, replacement),
|
|
110
|
+
enumerable: true, configurable: true, writable: true });
|
|
111
|
+
return result;
|
|
133
112
|
}
|
|
134
113
|
|
|
135
114
|
export function rebindMaterializationDataReferences(program, replacements) {
|
|
136
115
|
if (replacements.size === 0) return program;
|
|
137
116
|
let next = program;
|
|
138
|
-
for (const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
117
|
+
for (const ref of [...collectMarkConfigReferences(program), ...collectDataOwnerReferences(program)]) {
|
|
118
|
+
if (ref.kind !== "data" || !replacements.has(ref.id)) continue;
|
|
119
|
+
const path = ref.ownerKind === "markConfig" ? ["marks", ref.ownerId, ...ref.path] : ref.path;
|
|
120
|
+
const [root, ...rest] = path;
|
|
121
|
+
next = next._withMaterializationConfig([root],
|
|
122
|
+
replaceAtPath(next.materializationConfigs[root], rest, replacements.get(ref.id)));
|
|
143
123
|
}
|
|
144
124
|
return next;
|
|
145
125
|
}
|
|
@@ -5,6 +5,12 @@ import {
|
|
|
5
5
|
findDataset,
|
|
6
6
|
resolveDatasetReference
|
|
7
7
|
} from "../../selectors/datasets.js";
|
|
8
|
+
import {
|
|
9
|
+
assertFieldsAvailable,
|
|
10
|
+
deriveTransformSchema,
|
|
11
|
+
transformInputFields,
|
|
12
|
+
validateRowsAgainstSchema
|
|
13
|
+
} from "../../grammar/datasetSchema.js";
|
|
8
14
|
|
|
9
15
|
export const MATERIALIZE_OPTIONS = Object.freeze(["id"]);
|
|
10
16
|
|
|
@@ -37,17 +43,39 @@ export function derivedMaterializer(op, description, type, derive, resolve) {
|
|
|
37
43
|
args.id,
|
|
38
44
|
type
|
|
39
45
|
);
|
|
46
|
+
assertFieldsAvailable(source.schema, transformInputFields(transform), {
|
|
47
|
+
data: source.id,
|
|
48
|
+
operation: op
|
|
49
|
+
});
|
|
40
50
|
const result = derive(source.values, transform);
|
|
51
|
+
const values = Array.isArray(result) ? result : result.values;
|
|
52
|
+
const schema = deriveTransformSchema(source.schema, transform, values, {
|
|
53
|
+
sourceId: source.id,
|
|
54
|
+
ownerId: id
|
|
55
|
+
});
|
|
56
|
+
validateRowsAgainstSchema(values, schema, `Derived dataset "${id}"`);
|
|
41
57
|
const program = resolve === undefined
|
|
42
58
|
? this
|
|
43
59
|
: this.editSemantic({
|
|
44
60
|
property: `dataset[${id}].transform`,
|
|
45
61
|
value: resolve(result, transform)
|
|
46
62
|
});
|
|
47
|
-
|
|
63
|
+
let next = program.editSemantic({
|
|
48
64
|
property: `dataset[${id}].values`,
|
|
49
|
-
value:
|
|
65
|
+
value: values
|
|
50
66
|
});
|
|
67
|
+
if (!Array.isArray(result) && result.report !== undefined) {
|
|
68
|
+
const report = {
|
|
69
|
+
...result.report,
|
|
70
|
+
owner: { kind: "data", id },
|
|
71
|
+
inputs: [{ kind: "data", id: source.id }]
|
|
72
|
+
};
|
|
73
|
+
next = next._withMaterializationConfig(
|
|
74
|
+
["calculations", "datasets", id],
|
|
75
|
+
report
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return next;
|
|
51
79
|
});
|
|
52
80
|
}
|
|
53
81
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { deriveSortedRows, normalizeSortTransform } from "../../grammar/sort.js";
|
|
2
|
+
import { derivedCreator, derivedMaterializer } from "./shared.js";
|
|
3
|
+
|
|
4
|
+
const OPTIONS = Object.freeze(["id", "source", "sortBy"]);
|
|
5
|
+
|
|
6
|
+
export const materializeSortedData = /* @__PURE__ */ derivedMaterializer(
|
|
7
|
+
"materializeSortedData",
|
|
8
|
+
"Materialize one immutable stable sorted dataset.",
|
|
9
|
+
"sort",
|
|
10
|
+
deriveSortedRows
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
export const createSortedData = /* @__PURE__ */ derivedCreator(
|
|
14
|
+
"createSortedData",
|
|
15
|
+
"Create reusable rows in a stable explicit order.",
|
|
16
|
+
OPTIONS,
|
|
17
|
+
"Sorted dataset id",
|
|
18
|
+
"Sorted source dataset id",
|
|
19
|
+
normalizeSortTransform,
|
|
20
|
+
"materializeSortedData"
|
|
21
|
+
);
|
|
@@ -8,14 +8,14 @@ const OPTIONS = Object.freeze([
|
|
|
8
8
|
"id", "source", "category", "group", "value", "mode", "as"
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
|
-
export const materializeStackData = derivedMaterializer(
|
|
11
|
+
export const materializeStackData = /* @__PURE__ */ derivedMaterializer(
|
|
12
12
|
"materializeStackData",
|
|
13
13
|
"Materialize one immutable category/series stack dataset.",
|
|
14
14
|
"stack",
|
|
15
15
|
deriveStackRows
|
|
16
16
|
);
|
|
17
17
|
|
|
18
|
-
export const createStackData = derivedCreator(
|
|
18
|
+
export const createStackData = /* @__PURE__ */ derivedCreator(
|
|
19
19
|
"createStackData",
|
|
20
20
|
"Create reusable start, end, value, and share stack rows.",
|
|
21
21
|
OPTIONS,
|
|
@@ -5,17 +5,17 @@ import {
|
|
|
5
5
|
import { derivedCreator, derivedMaterializer } from "./shared.js";
|
|
6
6
|
|
|
7
7
|
const OPTIONS = Object.freeze([
|
|
8
|
-
"id", "source", "groupBy", "aggregates", "members", "weight"
|
|
8
|
+
"id", "source", "groupBy", "aggregates", "members", "weight", "missing", "empty"
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
|
-
export const materializeSummaryData = derivedMaterializer(
|
|
11
|
+
export const materializeSummaryData = /* @__PURE__ */ derivedMaterializer(
|
|
12
12
|
"materializeSummaryData",
|
|
13
13
|
"Materialize one immutable grouped summary dataset.",
|
|
14
14
|
"summary",
|
|
15
15
|
deriveSummaryRows
|
|
16
16
|
);
|
|
17
17
|
|
|
18
|
-
export const createSummaryData = derivedCreator(
|
|
18
|
+
export const createSummaryData = /* @__PURE__ */ derivedCreator(
|
|
19
19
|
"createSummaryData",
|
|
20
20
|
"Create reusable grouped aggregate values and provenance.",
|
|
21
21
|
OPTIONS,
|
|
@@ -9,14 +9,14 @@ const OPTIONS = Object.freeze([
|
|
|
9
9
|
"weekStartsOn", "weekRule"
|
|
10
10
|
]);
|
|
11
11
|
|
|
12
|
-
export const materializeTimeUnitData = derivedMaterializer(
|
|
12
|
+
export const materializeTimeUnitData = /* @__PURE__ */ derivedMaterializer(
|
|
13
13
|
"materializeTimeUnitData",
|
|
14
14
|
"Materialize one immutable UTC time-unit dataset.",
|
|
15
15
|
"timeUnit",
|
|
16
16
|
deriveTimeUnitRows
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
export const createTimeUnitData = derivedCreator(
|
|
19
|
+
export const createTimeUnitData = /* @__PURE__ */ derivedCreator(
|
|
20
20
|
"createTimeUnitData",
|
|
21
21
|
"Create immutable UTC calendar bucket values.",
|
|
22
22
|
OPTIONS,
|
|
@@ -8,14 +8,14 @@ const OPTIONS = Object.freeze([
|
|
|
8
8
|
"id", "source", "partitionBy", "sortBy", "operations", "temporalUnit"
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
|
-
export const materializeWindowData = derivedMaterializer(
|
|
11
|
+
export const materializeWindowData = /* @__PURE__ */ derivedMaterializer(
|
|
12
12
|
"materializeWindowData",
|
|
13
13
|
"Materialize one immutable window-derived dataset.",
|
|
14
14
|
"window",
|
|
15
15
|
deriveWindowRows
|
|
16
16
|
);
|
|
17
17
|
|
|
18
|
-
export const createWindowData = derivedCreator(
|
|
18
|
+
export const createWindowData = /* @__PURE__ */ derivedCreator(
|
|
19
19
|
"createWindowData",
|
|
20
20
|
"Create immutable partitioned window values.",
|
|
21
21
|
OPTIONS,
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
setEncodingProperties,
|
|
6
6
|
validateOptions
|
|
7
7
|
} from "./shared.js";
|
|
8
|
+
import { applyRequestedItemMissingPolicy } from
|
|
9
|
+
"../../grammar/itemMissing.js";
|
|
8
10
|
|
|
9
11
|
const OPTIONS = Object.freeze(["target", "value", "field", "fieldType"]);
|
|
10
12
|
|
|
@@ -14,7 +16,7 @@ function rematerialize(program, layer, target) {
|
|
|
14
16
|
: program.rematerializePointMark({ id: target });
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
export const encodeAngle = action(
|
|
19
|
+
export const encodeAngle = /* @__PURE__ */ action(
|
|
18
20
|
{
|
|
19
21
|
op: "encodeAngle",
|
|
20
22
|
description: "Assign direct clockwise degree rotation to point or Tick glyphs."
|
|
@@ -29,7 +31,7 @@ export const encodeAngle = action(
|
|
|
29
31
|
if (hasValue && args.fieldType !== undefined) {
|
|
30
32
|
throw new Error("Constant angle does not accept fieldType.");
|
|
31
33
|
}
|
|
32
|
-
const { id: target, dataset, layer } = resolveTarget(
|
|
34
|
+
const { id: target, dataset: sourceDataset, layer } = resolveTarget(
|
|
33
35
|
this,
|
|
34
36
|
args.target,
|
|
35
37
|
["point", "tick"],
|
|
@@ -39,6 +41,7 @@ export const encodeAngle = action(
|
|
|
39
41
|
throw new TypeError("encodeAngle value must be finite degrees.");
|
|
40
42
|
}
|
|
41
43
|
if (hasField) {
|
|
44
|
+
const dataset = applyRequestedItemMissingPolicy(layer, sourceDataset, args.field);
|
|
42
45
|
const fieldType = args.fieldType ?? "quantitative";
|
|
43
46
|
if (fieldType !== "quantitative") {
|
|
44
47
|
throw new Error("encodeAngle requires a quantitative field.");
|