ggaction 0.0.3 → 0.0.4

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.
Files changed (108) hide show
  1. package/CHANGELOG.md +28 -3
  2. package/README.md +95 -83
  3. package/package.json +11 -6
  4. package/src/actions/data/regression.js +1 -1
  5. package/src/actions/encodings/appearance.js +1 -1
  6. package/src/actions/encodings/color/continuous.js +137 -0
  7. package/src/actions/encodings/color/index.js +151 -0
  8. package/src/actions/encodings/color/layout.js +91 -0
  9. package/src/actions/encodings/color/policy.js +88 -0
  10. package/src/actions/encodings/index.js +2 -2
  11. package/src/actions/encodings/offset.js +1 -1
  12. package/src/actions/encodings/{position.js → position/index.js} +6 -6
  13. package/src/actions/encodings/position/resolve.js +1 -1
  14. package/src/actions/encodings/ranged.js +2 -2
  15. package/src/actions/encodings/strokeDash.js +1 -1
  16. package/src/actions/encodings/text.js +1 -1
  17. package/src/actions/errorBands/options.js +1 -1
  18. package/src/actions/errorBars/options.js +1 -1
  19. package/src/actions/facets/actions.js +1 -1
  20. package/src/actions/facets/derive.js +2 -2
  21. package/src/actions/facets/guides.js +1 -1
  22. package/src/actions/guides/axes/labels.js +1 -1
  23. package/src/actions/guides/axes/ticks.js +1 -1
  24. package/src/actions/guides/axes/titles.js +1 -1
  25. package/src/actions/guides/grids/resolve.js +1 -1
  26. package/src/actions/guides/legends/categorical/layout.js +4 -2
  27. package/src/actions/guides/legends/continuous/interval.js +1 -1
  28. package/src/actions/guides/legends/continuous/opacity.js +1 -1
  29. package/src/actions/guides/legends/edit.js +2 -20
  30. package/src/actions/guides/legends/remove.js +2 -20
  31. package/src/actions/guides/legends/size.js +1 -1
  32. package/src/actions/guides/legends/target.js +25 -0
  33. package/src/actions/guides/polar/{axes.js → axes/index.js} +5 -5
  34. package/src/actions/guides/polar/index.js +1 -1
  35. package/src/actions/guides/polar/resolve.js +1 -1
  36. package/src/actions/guides/tickValues.js +1 -1
  37. package/src/actions/intervals/resolve.js +1 -1
  38. package/src/actions/marks/arc/actions.js +2 -2
  39. package/src/actions/marks/area/actions.js +2 -2
  40. package/src/actions/marks/bar/edit.js +1 -1
  41. package/src/actions/marks/line/actions.js +3 -3
  42. package/src/actions/marks/rect/actions.js +1 -1
  43. package/src/actions/marks/rule/actions.js +1 -1
  44. package/src/actions/marks/shared.js +1 -1
  45. package/src/actions/marks/text/actions.js +1 -1
  46. package/src/actions/primitives/semanticValue.js +1 -1
  47. package/src/actions/regression/components.js +1 -1
  48. package/src/actions/regression/create.js +1 -1
  49. package/src/actions/regression/edit.js +1 -1
  50. package/src/actions/scales/consumers/common.js +91 -0
  51. package/src/actions/scales/consumers/families.js +47 -0
  52. package/src/actions/scales/consumers/index.js +41 -0
  53. package/src/actions/scales/{consumers.js → consumers/seriesLayout.js} +10 -132
  54. package/src/actions/scales/create.js +1 -1
  55. package/src/actions/scales/definitions.js +2 -2
  56. package/src/actions/scales/edit.js +3 -3
  57. package/src/actions/scales/materialize.js +2 -2
  58. package/src/core/ChartProgram.js +22 -236
  59. package/src/core/compositionState.js +169 -0
  60. package/src/core/materializationState.js +65 -0
  61. package/src/core/programState.js +28 -0
  62. package/src/grammar/arcs.js +1 -1
  63. package/src/grammar/areaSeries.js +1 -1
  64. package/src/grammar/bars/aggregate.js +1 -1
  65. package/src/grammar/density.js +1 -1
  66. package/src/grammar/{facets.js → facets/index.js} +5 -5
  67. package/src/grammar/interval.js +2 -96
  68. package/src/grammar/lineSeries.js +1 -1
  69. package/src/grammar/palettes.js +5 -7
  70. package/src/grammar/polarLineCommands.js +1 -1
  71. package/src/grammar/regression/derive.js +97 -0
  72. package/src/grammar/regression/index.js +22 -0
  73. package/src/grammar/regression/models.js +282 -0
  74. package/src/grammar/regression/parameters.js +106 -0
  75. package/src/grammar/rules.js +1 -1
  76. package/src/grammar/scales/color.js +4 -2
  77. package/src/grammar/statistics/studentT.js +98 -0
  78. package/src/grammar/transforms.js +1 -1
  79. package/src/materialization/bars/aggregate.js +1 -1
  80. package/src/materialization/bars/grouped.js +1 -1
  81. package/src/materialization/bars/histogram.js +1 -1
  82. package/src/materialization/bars/ranged.js +1 -1
  83. package/src/materialization/density.js +1 -1
  84. package/src/materialization/dependencies.js +6 -87
  85. package/src/materialization/encodings.js +2 -2
  86. package/src/materialization/facetGuides/index.js +2 -0
  87. package/src/materialization/facetGuides/legacyCategorical.js +125 -0
  88. package/src/materialization/facetGuides/placement.js +126 -0
  89. package/src/materialization/facetGuides/preparation.js +188 -0
  90. package/src/materialization/facets.js +1 -1
  91. package/src/materialization/marks/capabilities.js +141 -0
  92. package/src/materialization/marks/index.js +105 -0
  93. package/src/materialization/marks/policies.js +87 -0
  94. package/src/materialization/rect.js +1 -1
  95. package/src/materialization/rowEncoding.js +1 -1
  96. package/src/materialization/scaleGuideDependencies.js +94 -0
  97. package/src/materialization/scales/map.js +1 -1
  98. package/src/materialization/scales/policies/series.js +1 -1
  99. package/src/materialization/scales/resolve.js +1 -1
  100. package/src/materialization/selection/items/bar.js +1 -1
  101. package/src/materialization/selection/styles.js +1 -1
  102. package/src/renderers/canvas/text.js +14 -1
  103. package/types/extension.d.ts +4 -1
  104. package/src/actions/encodings/color.js +0 -424
  105. package/src/grammar/regression.js +0 -578
  106. package/src/grammar/scales.js +0 -1
  107. package/src/materialization/facetGuides.js +0 -426
  108. package/src/materialization/marks.js +0 -316
@@ -5,7 +5,7 @@ import {
5
5
  validateNonNegativeFinite,
6
6
  validateUnitInterval
7
7
  } from "../../../core/validation.js";
8
- import { canMaterializeBar } from "../../../materialization/marks.js";
8
+ import { canMaterializeBar } from "../../../materialization/marks/index.js";
9
9
  import { DEFAULT_BAR_STROKE_WIDTH } from "../../../materialization/bars/resolve.js";
10
10
  import { resolveEligibleLayer } from "../../../selectors/layers.js";
11
11
  import { validateMarkOptions } from "../shared.js";
@@ -1,6 +1,6 @@
1
1
  import { action } from "../../../core/action.js";
2
2
  import { deriveLineSeries } from "../../../grammar/lineSeries.js";
3
- import { mapContinuousScaleValues, mapOrdinalValues } from "../../../grammar/scales.js";
3
+ import { mapContinuousScaleValues, mapOrdinalValues } from "../../../grammar/scales/index.js";
4
4
  import { validateUserId } from "../../../core/identifiers.js";
5
5
  import {
6
6
  validateNonEmptyString,
@@ -26,8 +26,8 @@ import {
26
26
  import { buildPolarLinePathCommands } from "../../../grammar/polarLineCommands.js";
27
27
  import { resolvePolarFrame } from "../../../grammar/polar.js";
28
28
  import { resolveGraphicBounds } from "../../../layout/canvas.js";
29
- import { normalizeStrokeDashPattern } from "../../../grammar/scales.js";
30
- import { canMaterializeLine } from "../../../materialization/marks.js";
29
+ import { normalizeStrokeDashPattern } from "../../../grammar/scales/index.js";
30
+ import { canMaterializeLine } from "../../../materialization/marks/index.js";
31
31
  import { resolveMarkGraphicPlacement } from
32
32
  "../../../materialization/graphicHierarchy.js";
33
33
  import { rematerializeHighlightBaseline } from "../lifecycle.js";
@@ -6,7 +6,7 @@ import {
6
6
  } from "../../../materialization/rectConfig.js";
7
7
  import {
8
8
  canMaterializeRect
9
- } from "../../../materialization/marks.js";
9
+ } from "../../../materialization/marks/index.js";
10
10
  import { resolveRectGraphicItems } from "../../../materialization/rect.js";
11
11
  import { findDataset } from "../../../selectors/datasets.js";
12
12
  import { findLayer, resolveEligibleLayer } from "../../../selectors/layers.js";
@@ -6,7 +6,7 @@ import {
6
6
  mapOrdinalPositionValues,
7
7
  mapOrdinalValues,
8
8
  normalizeStrokeDashPattern
9
- } from "../../../grammar/scales.js";
9
+ } from "../../../grammar/scales/index.js";
10
10
  import { deriveRuleValues, resolveRuleMode } from "../../../grammar/rules.js";
11
11
  import { resolveGraphicBounds } from "../../../layout/canvas.js";
12
12
  import { findDataset } from "../../../selectors/datasets.js";
@@ -6,7 +6,7 @@ import { findDataset } from "../../selectors/datasets.js";
6
6
  import { findLayer, hasLayer } from "../../selectors/layers.js";
7
7
  import { findSemanticScale } from "../../selectors/scales.js";
8
8
  import { resolveMarkPositionPolicy } from "../encodings/position/policies/index.js";
9
- import { getMarkMaterializationStep } from "../../materialization/marks.js";
9
+ import { getMarkMaterializationStep } from "../../materialization/marks/index.js";
10
10
  import {
11
11
  POLAR_POSITION_CHANNELS,
12
12
  CARTESIAN_POSITION_CHANNELS,
@@ -4,7 +4,7 @@ import {
4
4
  DEFAULT_TEXT_MARK,
5
5
  normalizeTextMarkConfig
6
6
  } from "../../../grammar/text.js";
7
- import { canMaterializeText } from "../../../materialization/marks.js";
7
+ import { canMaterializeText } from "../../../materialization/marks/index.js";
8
8
  import { resolveTextGraphicItems } from "../../../materialization/text.js";
9
9
  import { findLayer, resolveEligibleLayer } from "../../../selectors/layers.js";
10
10
  import {
@@ -22,7 +22,7 @@ import {
22
22
  validateSemanticScaleDomain,
23
23
  validateSemanticScaleRange,
24
24
  validateSemanticScaleType
25
- } from "../../grammar/scales.js";
25
+ } from "../../grammar/scales/index.js";
26
26
 
27
27
  function nonEmptyString(value, label) {
28
28
  if (typeof value !== "string" || value.length === 0) {
@@ -7,7 +7,7 @@ import { resolveEligibleLayer } from "../../selectors/layers.js";
7
7
  import {
8
8
  REGRESSION_LOWER_FIELD,
9
9
  REGRESSION_UPPER_FIELD
10
- } from "../../grammar/regression.js";
10
+ } from "../../grammar/regression/index.js";
11
11
  import { validateAreaCreateOutline } from "../marks/area/index.js";
12
12
 
13
13
  const BAND_OPTIONS = Object.freeze([
@@ -1,6 +1,6 @@
1
1
  import { action } from "../../core/action.js";
2
2
  import { validateKeys } from "../../core/validation.js";
3
- import { normalizeRegressionParameters } from "../../grammar/regression.js";
3
+ import { normalizeRegressionParameters } from "../../grammar/regression/index.js";
4
4
  import {
5
5
  findRegressionPoint,
6
6
  inferRegressionGroup,
@@ -7,7 +7,7 @@ import {
7
7
  validateNonNegativeFinite,
8
8
  validateUnitInterval
9
9
  } from "../../core/validation.js";
10
- import { normalizeRegressionParameters } from "../../grammar/regression.js";
10
+ import { normalizeRegressionParameters } from "../../grammar/regression/index.js";
11
11
  import { validateCurveInterpolation } from "../../grammar/curveCommands.js";
12
12
  import { hasDataset } from "../../selectors/index.js";
13
13
  import { findLayer } from "../../selectors/layers.js";
@@ -0,0 +1,91 @@
1
+ import {
2
+ readNominalField,
3
+ readQuantitativeField,
4
+ readScaleField,
5
+ readTemporalField
6
+ } from "../../../grammar/scales/index.js";
7
+ import { findDataset } from "../../../selectors/datasets.js";
8
+ import { requireSemanticScale } from "../../../selectors/scales.js";
9
+ import { SCALED_ENCODING_CHANNELS } from "../../../core/vocabulary.js";
10
+
11
+ export function findScale(program, id) {
12
+ return requireSemanticScale(program, id);
13
+ }
14
+
15
+ export function findScaleConsumers(program, id) {
16
+ const consumers = [];
17
+ for (const layer of program.semanticSpec.layers) {
18
+ for (const channel of SCALED_ENCODING_CHANNELS) {
19
+ const encoding = layer.encoding?.[channel];
20
+ if (encoding?.scale === id) consumers.push({ layer, channel, encoding });
21
+ }
22
+ }
23
+ return consumers;
24
+ }
25
+
26
+ export function requireConsumerDataset(program, consumer) {
27
+ const dataset = findDataset(program, consumer.layer.data);
28
+ if (dataset === undefined) {
29
+ throw new Error(
30
+ `Mark "${consumer.layer.id}" references unknown dataset "${consumer.layer.data}".`
31
+ );
32
+ }
33
+ return dataset;
34
+ }
35
+
36
+ export function isDirectCategoricalConsumer(consumer) {
37
+ return ["color", "strokeDash", "xOffset", "yOffset", "shape"].includes(
38
+ consumer.channel
39
+ ) && consumer.encoding.fieldType === "nominal";
40
+ }
41
+
42
+ export function readConsumerFieldValues(
43
+ program,
44
+ consumer,
45
+ dataset,
46
+ scale = findScale(program, consumer.encoding.scale)
47
+ ) {
48
+ const allowUnknown = Object.hasOwn(scale, "unknown");
49
+ if (isDirectCategoricalConsumer(consumer)) {
50
+ return allowUnknown
51
+ ? readScaleField(
52
+ dataset.values,
53
+ consumer.encoding.field,
54
+ consumer.encoding.fieldType,
55
+ { allowUnknown: true }
56
+ )
57
+ : readNominalField(dataset.values, consumer.encoding.field);
58
+ }
59
+ if (consumer.encoding.fieldType === "temporal") {
60
+ return allowUnknown
61
+ ? readScaleField(dataset.values, consumer.encoding.field, "temporal", {
62
+ allowUnknown: true
63
+ })
64
+ : readTemporalField(dataset.values, consumer.encoding.field);
65
+ }
66
+ if (["nominal", "ordinal"].includes(consumer.encoding.fieldType)) {
67
+ if (!["ordinal", "band", "point"].includes(scale.type)) {
68
+ throw new Error(
69
+ `Scale materialization requires a quantitative encoding on mark "${consumer.layer.id}".`
70
+ );
71
+ }
72
+ return allowUnknown
73
+ ? readScaleField(
74
+ dataset.values,
75
+ consumer.encoding.field,
76
+ consumer.encoding.fieldType,
77
+ { allowUnknown: true }
78
+ )
79
+ : readNominalField(dataset.values, consumer.encoding.field);
80
+ }
81
+ if (consumer.encoding.fieldType !== "quantitative") {
82
+ throw new Error(
83
+ `Scale materialization requires a quantitative encoding on mark "${consumer.layer.id}".`
84
+ );
85
+ }
86
+ return allowUnknown
87
+ ? readScaleField(dataset.values, consumer.encoding.field, "quantitative", {
88
+ allowUnknown: true
89
+ })
90
+ : readQuantitativeField(dataset.values, consumer.encoding.field);
91
+ }
@@ -0,0 +1,47 @@
1
+ import { deriveBarAggregates } from "../../../grammar/bars/aggregate.js";
2
+ import {
3
+ BAR_GRAINS,
4
+ resolveBarGrain
5
+ } from "../../../grammar/bars/policy.js";
6
+ import { deriveLineSeries } from "../../../grammar/lineSeries.js";
7
+ import { isAggregate } from "../../../grammar/aggregate.js";
8
+ import {
9
+ resolveRectConsumerValues
10
+ } from "../../../materialization/rect.js";
11
+
12
+ export function resolveMarkFamilyConsumerValues(consumer, dataset) {
13
+ if (consumer.layer.mark?.type === "rect") {
14
+ return {
15
+ matched: true,
16
+ values: resolveRectConsumerValues(
17
+ consumer.layer,
18
+ dataset,
19
+ consumer.channel
20
+ )
21
+ };
22
+ }
23
+ if (
24
+ consumer.layer.mark?.type === "line" &&
25
+ isAggregate(consumer.layer.encoding?.y?.aggregate)
26
+ ) {
27
+ const derived = deriveLineSeries(dataset.values, consumer.layer);
28
+ return {
29
+ matched: true,
30
+ values: consumer.channel === "x" ? derived.xValues : derived.yValues
31
+ };
32
+ }
33
+ if (resolveBarGrain(consumer.layer) === BAR_GRAINS.aggregate) {
34
+ const derived = deriveBarAggregates(dataset.values, consumer.layer);
35
+ if (consumer.channel === "color") {
36
+ return {
37
+ matched: true,
38
+ values: derived.values.map(value => value.color)
39
+ };
40
+ }
41
+ return {
42
+ matched: true,
43
+ values: consumer.channel === "x" ? derived.xValues : derived.yValues
44
+ };
45
+ }
46
+ return { matched: false };
47
+ }
@@ -0,0 +1,41 @@
1
+ import { normalizeRuleDatum } from "../../../grammar/rules.js";
2
+ import {
3
+ findScale,
4
+ isDirectCategoricalConsumer,
5
+ readConsumerFieldValues,
6
+ requireConsumerDataset
7
+ } from "./common.js";
8
+ import { resolveMarkFamilyConsumerValues } from "./families.js";
9
+
10
+ export { findScale, findScaleConsumers } from "./common.js";
11
+ export {
12
+ resolveHistogramCountValues,
13
+ resolveSeriesLayoutScaleValues
14
+ } from "./seriesLayout.js";
15
+
16
+ export function resolveConsumerValues(program, consumer) {
17
+ const dataset = requireConsumerDataset(program, consumer);
18
+ if (Object.hasOwn(consumer.encoding, "datum")) {
19
+ return [normalizeRuleDatum(
20
+ consumer.encoding.datum,
21
+ consumer.encoding.fieldType,
22
+ consumer.channel
23
+ )];
24
+ }
25
+ if (
26
+ consumer.channel === "strokeDash" &&
27
+ !["line", "rule"].includes(consumer.layer.mark?.type)
28
+ ) {
29
+ throw new Error(
30
+ "strokeDash scale materialization requires a line mark or rule mark."
31
+ );
32
+ }
33
+ const scale = findScale(program, consumer.encoding.scale);
34
+ if (isDirectCategoricalConsumer(consumer)) {
35
+ return readConsumerFieldValues(program, consumer, dataset, scale);
36
+ }
37
+ const family = resolveMarkFamilyConsumerValues(consumer, dataset);
38
+ return family.matched
39
+ ? family.values
40
+ : readConsumerFieldValues(program, consumer, dataset, scale);
41
+ }
@@ -1,144 +1,26 @@
1
- import { deriveBarAggregates } from "../../grammar/bars/aggregate.js";
1
+ import { deriveBarAggregates } from "../../../grammar/bars/aggregate.js";
2
2
  import {
3
3
  BAR_GRAINS,
4
4
  resolveBarChannels,
5
5
  resolveBarColorLayout,
6
6
  resolveBarGrain
7
- } from "../../grammar/bars/policy.js";
7
+ } from "../../../grammar/bars/policy.js";
8
8
  import {
9
9
  countHistogramBins,
10
10
  findHistogramBinIndex,
11
11
  resolveHistogramBins
12
- } from "../../grammar/histogram.js";
13
- import { deriveDensityAreaSeries } from "../../grammar/areaSeries.js";
14
- import { deriveLineSeries } from "../../grammar/lineSeries.js";
15
- import { resolveSeriesLayoutDomainValues } from "../../grammar/seriesLayout.js";
12
+ } from "../../../grammar/histogram.js";
13
+ import { deriveDensityAreaSeries } from "../../../grammar/areaSeries.js";
14
+ import {
15
+ resolveSeriesLayoutDomainValues
16
+ } from "../../../grammar/seriesLayout.js";
16
17
  import {
17
18
  readNominalField,
18
19
  readQuantitativeField,
19
- readScaleField,
20
- readTemporalField,
21
20
  resolveOrdinalDomain
22
- } from "../../grammar/scales.js";
23
- import { findDataset } from "../../selectors/datasets.js";
24
- import { requireSemanticScale } from "../../selectors/scales.js";
25
- import { isAggregate } from "../../grammar/aggregate.js";
26
- import { normalizeRuleDatum } from "../../grammar/rules.js";
27
- import { SCALED_ENCODING_CHANNELS } from "../../core/vocabulary.js";
28
- import { resolveRectConsumerValues } from "../../materialization/rect.js";
29
-
30
- export function findScale(program, id) {
31
- return requireSemanticScale(program, id);
32
- }
33
-
34
- export function findScaleConsumers(program, id) {
35
- const consumers = [];
36
- for (const layer of program.semanticSpec.layers) {
37
- for (const channel of SCALED_ENCODING_CHANNELS) {
38
- const encoding = layer.encoding?.[channel];
39
- if (encoding?.scale === id) consumers.push({ layer, channel, encoding });
40
- }
41
- }
42
- return consumers;
43
- }
44
-
45
- export function resolveConsumerValues(program, consumer) {
46
- const dataset = findDataset(program, consumer.layer.data);
47
- if (dataset === undefined) {
48
- throw new Error(
49
- `Mark "${consumer.layer.id}" references unknown dataset "${consumer.layer.data}".`
50
- );
51
- }
52
-
53
- if (Object.hasOwn(consumer.encoding, "datum")) {
54
- return [normalizeRuleDatum(
55
- consumer.encoding.datum,
56
- consumer.encoding.fieldType,
57
- consumer.channel
58
- )];
59
- }
60
-
61
- if (
62
- consumer.channel === "strokeDash" &&
63
- !["line", "rule"].includes(consumer.layer.mark?.type)
64
- ) {
65
- throw new Error("strokeDash scale materialization requires a line mark or rule mark.");
66
- }
67
- const scale = findScale(program, consumer.encoding.scale);
68
- const allowUnknown = Object.hasOwn(scale, "unknown");
69
- if (consumer.layer.mark?.type === "rect") {
70
- return resolveRectConsumerValues(
71
- consumer.layer,
72
- dataset,
73
- consumer.channel
74
- );
75
- }
76
-
77
- if (
78
- ["color", "strokeDash", "xOffset", "yOffset", "shape"].includes(consumer.channel) &&
79
- consumer.encoding.fieldType === "nominal"
80
- ) {
81
- return allowUnknown
82
- ? readScaleField(
83
- dataset.values,
84
- consumer.encoding.field,
85
- consumer.encoding.fieldType,
86
- { allowUnknown: true }
87
- )
88
- : readNominalField(dataset.values, consumer.encoding.field);
89
- }
90
-
91
- if (
92
- consumer.layer.mark?.type === "line" &&
93
- isAggregate(consumer.layer.encoding?.y?.aggregate)
94
- ) {
95
- const derived = deriveLineSeries(dataset.values, consumer.layer);
96
- return consumer.channel === "x" ? derived.xValues : derived.yValues;
97
- }
98
-
99
- if (
100
- resolveBarGrain(consumer.layer) === BAR_GRAINS.aggregate
101
- ) {
102
- const derived = deriveBarAggregates(dataset.values, consumer.layer);
103
- if (consumer.channel === "color") {
104
- return derived.values.map(value => value.color);
105
- }
106
- return consumer.channel === "x" ? derived.xValues : derived.yValues;
107
- }
108
-
109
- if (consumer.encoding.fieldType === "temporal") {
110
- return allowUnknown
111
- ? readScaleField(dataset.values, consumer.encoding.field, "temporal", {
112
- allowUnknown: true
113
- })
114
- : readTemporalField(dataset.values, consumer.encoding.field);
115
- }
116
- if (["nominal", "ordinal"].includes(consumer.encoding.fieldType)) {
117
- if (!["ordinal", "band", "point"].includes(scale.type)) {
118
- throw new Error(
119
- `Scale materialization requires a quantitative encoding on mark "${consumer.layer.id}".`
120
- );
121
- }
122
- return allowUnknown
123
- ? readScaleField(
124
- dataset.values,
125
- consumer.encoding.field,
126
- consumer.encoding.fieldType,
127
- { allowUnknown: true }
128
- )
129
- : readNominalField(dataset.values, consumer.encoding.field);
130
- }
131
- if (consumer.encoding.fieldType !== "quantitative") {
132
- throw new Error(
133
- `Scale materialization requires a quantitative encoding on mark "${consumer.layer.id}".`
134
- );
135
- }
136
- return allowUnknown
137
- ? readScaleField(dataset.values, consumer.encoding.field, "quantitative", {
138
- allowUnknown: true
139
- })
140
- : readQuantitativeField(dataset.values, consumer.encoding.field);
141
- }
21
+ } from "../../../grammar/scales/index.js";
22
+ import { findDataset } from "../../../selectors/datasets.js";
23
+ import { findScale } from "./common.js";
142
24
 
143
25
  export function resolveHistogramCountValues(program, consumer) {
144
26
  const xEncoding = consumer.layer.encoding?.x;
@@ -146,7 +28,6 @@ export function resolveHistogramCountValues(program, consumer) {
146
28
  ? undefined
147
29
  : findScale(program, xEncoding.scale);
148
30
  const dataset = findDataset(program, consumer.layer.data);
149
-
150
31
  if (xEncoding?.bin === undefined || xScale === undefined) {
151
32
  throw new Error(
152
33
  `Histogram mark "${consumer.layer.id}" requires a binned x scale.`
@@ -157,7 +38,6 @@ export function resolveHistogramCountValues(program, consumer) {
157
38
  `Histogram mark "${consumer.layer.id}" requires an existing dataset.`
158
39
  );
159
40
  }
160
-
161
41
  const xValues = readQuantitativeField(dataset.values, xEncoding.field);
162
42
  const bins = resolveHistogramBins({
163
43
  values: xValues,
@@ -186,7 +66,6 @@ function resolveHistogramPartitions(program, consumer) {
186
66
  if (colorEncoding?.scale === undefined) {
187
67
  return countHistogramBins(xValues, bins.boundaries).map(value => [value]);
188
68
  }
189
-
190
69
  const colorScale = findScale(program, colorEncoding.scale);
191
70
  const colorValues = readNominalField(dataset.values, colorEncoding.field);
192
71
  const colorDomain = resolveOrdinalDomain(colorScale.domain, colorValues);
@@ -224,7 +103,6 @@ function resolveAggregatePartitions(program, consumer) {
224
103
  ]));
225
104
  return categoryDomain.map(value => [byCategory.get(value) ?? 0]);
226
105
  }
227
-
228
106
  const colorScale = findScale(program, colorEncoding.scale);
229
107
  const colorValues = readNominalField(dataset.values, colorEncoding.field);
230
108
  const colorDomain = resolveOrdinalDomain(colorScale.domain, colorValues);
@@ -15,7 +15,7 @@ import {
15
15
  isContinuousColorScaleType,
16
16
  isDiscretizedColorScaleType,
17
17
  normalizeScaleDefinition
18
- } from "../../grammar/scales.js";
18
+ } from "../../grammar/scales/index.js";
19
19
  import { findSemanticScale } from "../../selectors/scales.js";
20
20
 
21
21
  const CREATE_SCALE_OPTIONS = Object.freeze([
@@ -22,12 +22,12 @@ import {
22
22
  validateScalePropertyForType,
23
23
  validateScaleTypeForRole,
24
24
  isDiscretePositionScaleType
25
- } from "../../grammar/scales.js";
25
+ } from "../../grammar/scales/index.js";
26
26
  import {
27
27
  validateRadialRange,
28
28
  validateThetaRange
29
29
  } from "../../grammar/polar.js";
30
- import { withScaleUnknown } from "../../grammar/scales.js";
30
+ import { withScaleUnknown } from "../../grammar/scales/index.js";
31
31
  import { findSemanticScale } from "../../selectors/scales.js";
32
32
 
33
33
  const BASE_OPTIONS = Object.freeze(["id", "type", "domain", "range"]);
@@ -21,12 +21,12 @@ import {
21
21
  isDiscretePositionScaleType,
22
22
  hasOrdinalDomain,
23
23
  normalizeScaleDefinition
24
- } from "../../grammar/scales.js";
24
+ } from "../../grammar/scales/index.js";
25
25
  import {
26
26
  validateRadialRange,
27
27
  validateThetaRange
28
28
  } from "../../grammar/polar.js";
29
- import { getMarkMaterializationStep } from "../../materialization/marks.js";
29
+ import { getMarkMaterializationStep } from "../../materialization/marks/index.js";
30
30
  import {
31
31
  applyMaterializationPlan
32
32
  } from "../../materialization/dependencies.js";
@@ -34,7 +34,7 @@ import {
34
34
  findSemanticScale,
35
35
  requireSemanticScale
36
36
  } from "../../selectors/scales.js";
37
- import { findScaleConsumers } from "./consumers.js";
37
+ import { findScaleConsumers } from "./consumers/index.js";
38
38
  import { normalizePositionScaleChannel } from "../../core/vocabulary.js";
39
39
 
40
40
  const OPTIONS = Object.freeze([
@@ -11,7 +11,7 @@ import {
11
11
  canDeferScaleConsumerApplication,
12
12
  getMarkRematerializationStep,
13
13
  getScaleConsumerMaterializationMode
14
- } from "../../materialization/marks.js";
14
+ } from "../../materialization/marks/index.js";
15
15
  import { mapScaleConsumerValues } from
16
16
  "../../materialization/scales/map.js";
17
17
  import { resolveScaleMaterialization } from
@@ -21,7 +21,7 @@ import {
21
21
  findScaleConsumers,
22
22
  resolveConsumerValues,
23
23
  resolveSeriesLayoutScaleValues
24
- } from "./consumers.js";
24
+ } from "./consumers/index.js";
25
25
 
26
26
  const OPTIONS = Object.freeze(["id", "guides", "marks"]);
27
27