ggaction 0.0.1

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 (222) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +21 -0
  3. package/README.md +108 -0
  4. package/package.json +84 -0
  5. package/src/AGENTS.md +119 -0
  6. package/src/ChartProgram.js +10 -0
  7. package/src/actions/boxPlots/components.js +88 -0
  8. package/src/actions/boxPlots/create.js +84 -0
  9. package/src/actions/boxPlots/index.js +10 -0
  10. package/src/actions/boxPlots/materialize.js +183 -0
  11. package/src/actions/boxPlots/options.js +147 -0
  12. package/src/actions/boxPlots/resolve.js +38 -0
  13. package/src/actions/canvas/actions.js +144 -0
  14. package/src/actions/canvas/index.js +6 -0
  15. package/src/actions/coordinates/actions.js +85 -0
  16. package/src/actions/coordinates/index.js +5 -0
  17. package/src/actions/data/box.js +40 -0
  18. package/src/actions/data/create.js +33 -0
  19. package/src/actions/data/density.js +62 -0
  20. package/src/actions/data/derived.js +52 -0
  21. package/src/actions/data/filter.js +168 -0
  22. package/src/actions/data/index.js +32 -0
  23. package/src/actions/data/interval.js +69 -0
  24. package/src/actions/data/regression.js +71 -0
  25. package/src/actions/data/shared.js +25 -0
  26. package/src/actions/encodings/appearance.js +243 -0
  27. package/src/actions/encodings/barWidth.js +60 -0
  28. package/src/actions/encodings/color.js +329 -0
  29. package/src/actions/encodings/density.js +225 -0
  30. package/src/actions/encodings/histogram.js +50 -0
  31. package/src/actions/encodings/index.js +23 -0
  32. package/src/actions/encodings/offset.js +104 -0
  33. package/src/actions/encodings/position/policies/area.js +24 -0
  34. package/src/actions/encodings/position/policies/bar.js +110 -0
  35. package/src/actions/encodings/position/policies/common.js +17 -0
  36. package/src/actions/encodings/position/policies/index.js +25 -0
  37. package/src/actions/encodings/position/policies/line.js +74 -0
  38. package/src/actions/encodings/position/policies/point.js +19 -0
  39. package/src/actions/encodings/position/policies/rule.js +17 -0
  40. package/src/actions/encodings/position/resolve.js +170 -0
  41. package/src/actions/encodings/position.js +176 -0
  42. package/src/actions/encodings/ranged.js +276 -0
  43. package/src/actions/encodings/ruleAppearance.js +47 -0
  44. package/src/actions/encodings/shared.js +164 -0
  45. package/src/actions/encodings/strokeDash.js +145 -0
  46. package/src/actions/errorBands/components.js +81 -0
  47. package/src/actions/errorBands/create.js +159 -0
  48. package/src/actions/errorBands/index.js +7 -0
  49. package/src/actions/errorBands/resolve.js +28 -0
  50. package/src/actions/errorBars/components.js +62 -0
  51. package/src/actions/errorBars/create.js +144 -0
  52. package/src/actions/errorBars/index.js +7 -0
  53. package/src/actions/errorBars/resolve.js +25 -0
  54. package/src/actions/guides/axes/axes.js +204 -0
  55. package/src/actions/guides/axes/axis.js +131 -0
  56. package/src/actions/guides/axes/index.js +17 -0
  57. package/src/actions/guides/axes/labels.js +231 -0
  58. package/src/actions/guides/axes/lines.js +149 -0
  59. package/src/actions/guides/axes/policy.js +155 -0
  60. package/src/actions/guides/axes/tickGroups.js +149 -0
  61. package/src/actions/guides/axes/ticks.js +179 -0
  62. package/src/actions/guides/axes/titles.js +264 -0
  63. package/src/actions/guides/grids/grid.js +228 -0
  64. package/src/actions/guides/grids/index.js +1 -0
  65. package/src/actions/guides/grids/resolve.js +258 -0
  66. package/src/actions/guides/guides.js +138 -0
  67. package/src/actions/guides/index.js +11 -0
  68. package/src/actions/guides/legends/categorical/actions.js +329 -0
  69. package/src/actions/guides/legends/categorical/components.js +140 -0
  70. package/src/actions/guides/legends/categorical/index.js +49 -0
  71. package/src/actions/guides/legends/categorical/layout.js +445 -0
  72. package/src/actions/guides/legends/categorical/options.js +188 -0
  73. package/src/actions/guides/legends/categorical/recipes.js +120 -0
  74. package/src/actions/guides/legends/categorical/resolve.js +131 -0
  75. package/src/actions/guides/legends/categorical/symbols.js +280 -0
  76. package/src/actions/guides/legends/categorical/validation.js +27 -0
  77. package/src/actions/guides/legends/continuous/common.js +273 -0
  78. package/src/actions/guides/legends/continuous/gradient.js +363 -0
  79. package/src/actions/guides/legends/continuous/index.js +25 -0
  80. package/src/actions/guides/legends/continuous/interval.js +234 -0
  81. package/src/actions/guides/legends/continuous/opacity.js +382 -0
  82. package/src/actions/guides/legends/edit.js +314 -0
  83. package/src/actions/guides/legends/index.js +9 -0
  84. package/src/actions/guides/legends/size.js +220 -0
  85. package/src/actions/guides/tickValues.js +84 -0
  86. package/src/actions/index.js +31 -0
  87. package/src/actions/intervals/resolve.js +352 -0
  88. package/src/actions/marks/area.js +369 -0
  89. package/src/actions/marks/bar/create.js +46 -0
  90. package/src/actions/marks/bar/edit.js +90 -0
  91. package/src/actions/marks/bar/index.js +9 -0
  92. package/src/actions/marks/bar/materialize.js +130 -0
  93. package/src/actions/marks/index.js +13 -0
  94. package/src/actions/marks/line.js +248 -0
  95. package/src/actions/marks/point.js +420 -0
  96. package/src/actions/marks/rule.js +287 -0
  97. package/src/actions/marks/shared.js +112 -0
  98. package/src/actions/primitives/createGraphics.js +163 -0
  99. package/src/actions/primitives/editGraphics.js +208 -0
  100. package/src/actions/primitives/index.js +9 -0
  101. package/src/actions/primitives/semantic.js +168 -0
  102. package/src/actions/primitives/semanticValue.js +182 -0
  103. package/src/actions/regression/components.js +216 -0
  104. package/src/actions/regression/create.js +102 -0
  105. package/src/actions/regression/index.js +23 -0
  106. package/src/actions/regression/resolve.js +57 -0
  107. package/src/actions/scales/consumers.js +283 -0
  108. package/src/actions/scales/create.js +148 -0
  109. package/src/actions/scales/definitions.js +319 -0
  110. package/src/actions/scales/edit.js +290 -0
  111. package/src/actions/scales/index.js +11 -0
  112. package/src/actions/scales/materialize.js +466 -0
  113. package/src/actions/scales/quantitativeColor.js +45 -0
  114. package/src/actions/selection/actions.js +384 -0
  115. package/src/actions/selection/index.js +23 -0
  116. package/src/actions/titles/actions.js +235 -0
  117. package/src/actions/titles/index.js +19 -0
  118. package/src/actions/titles/resolve.js +321 -0
  119. package/src/core/ChartProgram.js +316 -0
  120. package/src/core/action.js +120 -0
  121. package/src/core/identifiers.js +28 -0
  122. package/src/core/immutable.js +94 -0
  123. package/src/core/specs.js +29 -0
  124. package/src/core/textMetrics.js +23 -0
  125. package/src/core/validation.js +54 -0
  126. package/src/core/vocabulary.js +58 -0
  127. package/src/extension.js +2 -0
  128. package/src/grammar/aggregate.js +259 -0
  129. package/src/grammar/areaSeries.js +217 -0
  130. package/src/grammar/bars/aggregate.js +98 -0
  131. package/src/grammar/bars/geometry.js +54 -0
  132. package/src/grammar/bars/policy.js +90 -0
  133. package/src/grammar/boxPlot.js +140 -0
  134. package/src/grammar/coordinates.js +25 -0
  135. package/src/grammar/curveCommands.js +356 -0
  136. package/src/grammar/density.js +296 -0
  137. package/src/grammar/filter.js +169 -0
  138. package/src/grammar/histogram.js +332 -0
  139. package/src/grammar/interval.js +343 -0
  140. package/src/grammar/lineSeries.js +197 -0
  141. package/src/grammar/markFilter.js +46 -0
  142. package/src/grammar/markSelection.js +326 -0
  143. package/src/grammar/palettes.js +208 -0
  144. package/src/grammar/pathCommands.js +86 -0
  145. package/src/grammar/pointShapes.js +164 -0
  146. package/src/grammar/positionCompatibility.js +32 -0
  147. package/src/grammar/regression.js +578 -0
  148. package/src/grammar/ruleAppearance.js +12 -0
  149. package/src/grammar/rules.js +90 -0
  150. package/src/grammar/scales/appearance.js +185 -0
  151. package/src/grammar/scales/color.js +349 -0
  152. package/src/grammar/scales/continuous.js +111 -0
  153. package/src/grammar/scales/definition.js +153 -0
  154. package/src/grammar/scales/discretized.js +159 -0
  155. package/src/grammar/scales/fields.js +133 -0
  156. package/src/grammar/scales/index.js +12 -0
  157. package/src/grammar/scales/mapping.js +27 -0
  158. package/src/grammar/scales/ordinal.js +221 -0
  159. package/src/grammar/scales/policies.js +50 -0
  160. package/src/grammar/scales/temporal.js +53 -0
  161. package/src/grammar/scales/transformed.js +236 -0
  162. package/src/grammar/scales/types.js +102 -0
  163. package/src/grammar/scales/validation.js +66 -0
  164. package/src/grammar/scales.js +1 -0
  165. package/src/grammar/schemas/concreteGraphic.js +73 -0
  166. package/src/grammar/schemas/graphic.js +131 -0
  167. package/src/grammar/schemas/graphicBounds.js +146 -0
  168. package/src/grammar/schemas/graphicTree.js +133 -0
  169. package/src/grammar/schemas/mark.js +4 -0
  170. package/src/grammar/schemas/semanticPath.js +174 -0
  171. package/src/grammar/seriesLayout.js +76 -0
  172. package/src/grammar/ticks.js +149 -0
  173. package/src/grammar/transforms.js +37 -0
  174. package/src/index.js +2 -0
  175. package/src/layout/canvas.js +114 -0
  176. package/src/layout/grid.js +17 -0
  177. package/src/layout/legend.js +51 -0
  178. package/src/layout/text.js +62 -0
  179. package/src/layout/title.js +107 -0
  180. package/src/materialization/bars/aggregate.js +184 -0
  181. package/src/materialization/bars/grouped.js +117 -0
  182. package/src/materialization/bars/histogram.js +163 -0
  183. package/src/materialization/bars/ranged.js +53 -0
  184. package/src/materialization/bars/resolve.js +56 -0
  185. package/src/materialization/dataProvenance.js +15 -0
  186. package/src/materialization/density.js +29 -0
  187. package/src/materialization/dependencies.js +134 -0
  188. package/src/materialization/encodings.js +50 -0
  189. package/src/materialization/graphicHierarchy.js +104 -0
  190. package/src/materialization/legends.js +20 -0
  191. package/src/materialization/marks.js +110 -0
  192. package/src/materialization/planner.js +38 -0
  193. package/src/materialization/selection/filter.js +40 -0
  194. package/src/materialization/selection/items.js +503 -0
  195. package/src/materialization/selection/path.js +37 -0
  196. package/src/materialization/selection/point.js +118 -0
  197. package/src/materialization/selection/policies/area.js +10 -0
  198. package/src/materialization/selection/policies/bar.js +10 -0
  199. package/src/materialization/selection/policies/index.js +40 -0
  200. package/src/materialization/selection/policies/line.js +10 -0
  201. package/src/materialization/selection/policies/point.js +10 -0
  202. package/src/materialization/selection/policies/rule.js +10 -0
  203. package/src/materialization/selection/state.js +67 -0
  204. package/src/materialization/selection/styles.js +183 -0
  205. package/src/renderers/canvas/circle.js +62 -0
  206. package/src/renderers/canvas/index.js +132 -0
  207. package/src/renderers/canvas/line.js +54 -0
  208. package/src/renderers/canvas/path.js +98 -0
  209. package/src/renderers/canvas/rect.js +57 -0
  210. package/src/renderers/canvas/text.js +96 -0
  211. package/src/renderers/canvas/validation.js +23 -0
  212. package/src/renderers/png.js +29 -0
  213. package/src/selectors/coordinates.js +13 -0
  214. package/src/selectors/datasets.js +13 -0
  215. package/src/selectors/index.js +4 -0
  216. package/src/selectors/layers.js +32 -0
  217. package/src/selectors/scales.js +21 -0
  218. package/src/theme/defaults.js +13 -0
  219. package/types/extension.d.ts +14 -0
  220. package/types/index.d.ts +81 -0
  221. package/types/png.d.ts +14 -0
  222. package/types/program.d.ts +1096 -0
@@ -0,0 +1,290 @@
1
+ import { action } from "../../core/action.js";
2
+ import { validateUserId } from "../../core/identifiers.js";
3
+ import { isPlainObject } from "../../core/immutable.js";
4
+ import { validateKeys } from "../../core/validation.js";
5
+ import {
6
+ isTransformedScaleType,
7
+ SCALE_ROLES,
8
+ validateColorRange,
9
+ validateDiscretizedColorDomain,
10
+ validateDiscretizedColorRange,
11
+ validateOrdinalDomain,
12
+ validateScaleDomain,
13
+ validateScaleRange,
14
+ validateScaleType,
15
+ validateScaleTypeForRole,
16
+ validateShapeRange,
17
+ validateSizeRange,
18
+ validateStrokeDashRange,
19
+ validateSequentialColorRange,
20
+ validateScaleUnknown,
21
+ isDiscretizedColorScaleType,
22
+ isDiscretePositionScaleType,
23
+ hasOrdinalDomain,
24
+ normalizeScaleDefinition
25
+ } from "../../grammar/scales.js";
26
+ import { getMarkMaterializationStep } from "../../materialization/marks.js";
27
+ import {
28
+ applyMaterializationPlan
29
+ } from "../../materialization/dependencies.js";
30
+ import {
31
+ findSemanticScale,
32
+ requireSemanticScale
33
+ } from "../../selectors/scales.js";
34
+ import { findScaleConsumers } from "./consumers.js";
35
+
36
+ const OPTIONS = Object.freeze([
37
+ "id", "type", "domain", "range", "nice", "zero", "clamp", "reverse",
38
+ "base", "exponent", "constant", "paddingInner", "paddingOuter", "padding",
39
+ "align", "interpolate", "unknown"
40
+ ]);
41
+ const EDITABLE = Object.freeze(OPTIONS.filter(option => option !== "id"));
42
+
43
+ function resolveScaleId(program, requested) {
44
+ if (requested !== undefined) {
45
+ const id = validateUserId(requested, "Scale id");
46
+ requireSemanticScale(program, id);
47
+ return id;
48
+ }
49
+ const current = program.context.currentScale;
50
+ if (
51
+ typeof current === "string" && findSemanticScale(program, current) !== undefined
52
+ ) {
53
+ return current;
54
+ }
55
+ if (program.semanticSpec.scales.length === 1) {
56
+ return program.semanticSpec.scales[0].id;
57
+ }
58
+ throw new Error(
59
+ "editScale requires id when no unique current scale can be inferred."
60
+ );
61
+ }
62
+
63
+ function normalizeChannel(channel) {
64
+ return channel === "x2" ? "x" : channel === "y2" ? "y" : channel;
65
+ }
66
+
67
+ function resolveChannel(consumers, id) {
68
+ const channels = new Set(
69
+ consumers.map(consumer => normalizeChannel(consumer.channel))
70
+ );
71
+ if (channels.size > 1) {
72
+ throw new Error(`Scale "${id}" cannot be shared across channels.`);
73
+ }
74
+ return channels.values().next().value;
75
+ }
76
+
77
+ function validateRangeForChannel(scale, channel, value) {
78
+ if (value === "auto") return value;
79
+ if (scale.type === "sequential") {
80
+ return validateSequentialColorRange(value);
81
+ }
82
+ if (isDiscretizedColorScaleType(scale.type)) {
83
+ return validateDiscretizedColorRange(value);
84
+ }
85
+ if (scale.type !== "ordinal") return validateScaleRange(value);
86
+ if (channel === "color") return validateColorRange(value);
87
+ if (channel === "shape") return validateShapeRange(value);
88
+ if (channel === "strokeDash") return validateStrokeDashRange(value);
89
+ if (channel === "size") return validateSizeRange(value);
90
+ return validateScaleRange(value);
91
+ }
92
+
93
+ function validateTypeTransition(scale, nextType, channel, consumers) {
94
+ if (nextType === scale.type) return;
95
+ validateScaleType(nextType);
96
+ if (consumers.length === 0) return;
97
+ if (nextType === "sequential" || isDiscretizedColorScaleType(nextType)) {
98
+ const discretized = isDiscretizedColorScaleType(nextType);
99
+ if (channel !== "color" || consumers.some(consumer =>
100
+ consumer.encoding.fieldType === "nominal" ||
101
+ (discretized && (
102
+ consumer.encoding.fieldType !== "quantitative" ||
103
+ consumer.layer.mark?.type !== "point"
104
+ )) ||
105
+ (!discretized && !["point", "bar"].includes(consumer.layer.mark?.type))
106
+ )) {
107
+ throw new Error(
108
+ `Scale "${scale.id}" has a consumer incompatible with type "${nextType}".`
109
+ );
110
+ }
111
+ return;
112
+ }
113
+ if (nextType === "time") {
114
+ if (
115
+ consumers.length > 0 &&
116
+ (!["x", "y"].includes(channel) ||
117
+ consumers.some(consumer => consumer.encoding.fieldType !== "temporal"))
118
+ ) {
119
+ throw new Error(
120
+ `Scale "${scale.id}" has a consumer incompatible with type "time".`
121
+ );
122
+ }
123
+ return;
124
+ }
125
+ const discrete = isDiscretePositionScaleType(nextType);
126
+ if (discrete) {
127
+ if (
128
+ consumers.length > 0 &&
129
+ (!["x", "y"].includes(channel) || consumers.some(consumer =>
130
+ !["nominal", "ordinal"].includes(consumer.encoding.fieldType)
131
+ ))
132
+ ) {
133
+ throw new Error(
134
+ `Scale "${scale.id}" has a consumer incompatible with type "${nextType}".`
135
+ );
136
+ }
137
+ if (
138
+ nextType === "point" &&
139
+ consumers.some(consumer => consumer.layer.mark?.type === "bar")
140
+ ) {
141
+ throw new Error("Point scales cannot provide bar bandwidth.");
142
+ }
143
+ return;
144
+ }
145
+ const quantitative = nextType === "linear" || isTransformedScaleType(nextType);
146
+ if (
147
+ !quantitative ||
148
+ (consumers.length > 0 && !["x", "y"].includes(channel))
149
+ ) {
150
+ throw new Error(
151
+ "editScale type transition currently requires a quantitative position scale."
152
+ );
153
+ }
154
+ validateScaleTypeForRole(nextType, SCALE_ROLES.quantitativePosition);
155
+ if (consumers.some(consumer => consumer.encoding.fieldType !== "quantitative")) {
156
+ throw new Error(
157
+ `Scale "${scale.id}" has a consumer incompatible with type "${nextType}".`
158
+ );
159
+ }
160
+ }
161
+
162
+ function validateLegendTypeTransition(program, scale, nextType) {
163
+ if (nextType === scale.type) return;
164
+ const legends = program.guideConfigs.legend ?? {};
165
+ if (
166
+ legends.gradient?.scale === scale.id &&
167
+ nextType !== "sequential"
168
+ ) {
169
+ throw new Error(
170
+ `Scale "${scale.id}" cannot change type while its gradient legend is active.`
171
+ );
172
+ }
173
+ if (
174
+ legends.interval?.scale === scale.id &&
175
+ !isDiscretizedColorScaleType(nextType)
176
+ ) {
177
+ throw new Error(
178
+ `Scale "${scale.id}" cannot change type while its interval legend is active.`
179
+ );
180
+ }
181
+ }
182
+
183
+ function normalizeDefinition(scale, channel, consumers, args) {
184
+ const type = args.type ?? scale.type;
185
+ validateTypeTransition(scale, type, channel, consumers);
186
+ const definition = normalizeScaleDefinition({
187
+ type,
188
+ previous: scale,
189
+ patch: args,
190
+ retainCoreOnTypeChange: true,
191
+ retainCompatibleOnTypeChange: true,
192
+ validateDomain: (scaleType, value) =>
193
+ isDiscretizedColorScaleType(scaleType)
194
+ ? validateDiscretizedColorDomain(scaleType, value)
195
+ : hasOrdinalDomain(scaleType)
196
+ ? validateOrdinalDomain(value)
197
+ : validateScaleDomain(value),
198
+ validateRange: (scaleType, value) =>
199
+ validateRangeForChannel({ type: scaleType }, channel, value)
200
+ });
201
+ const typeChanged = type !== scale.type;
202
+ const unknown = Object.hasOwn(args, "unknown")
203
+ ? args.unknown
204
+ : typeChanged ? undefined : scale.unknown;
205
+ if (unknown !== undefined) {
206
+ if (consumers.some(consumer => consumer.layer.mark?.type !== "point")) {
207
+ throw new Error(
208
+ "Scale unknown currently requires row-owned point consumers."
209
+ );
210
+ }
211
+ definition.unknown = consumers.length === 0
212
+ ? unknown
213
+ : validateScaleUnknown(channel, unknown);
214
+ }
215
+ return definition;
216
+ }
217
+
218
+ function sameValue(left, right) {
219
+ return JSON.stringify(left) === JSON.stringify(right);
220
+ }
221
+
222
+ function planMarkRematerialization(program, consumers) {
223
+ const plan = [];
224
+ const seen = new Set();
225
+ for (const consumer of consumers) {
226
+ const step = getMarkMaterializationStep(program, consumer.layer);
227
+ if (step === undefined || seen.has(consumer.layer.id)) continue;
228
+ const pointHandledByScale =
229
+ consumer.layer.mark?.type === "point" &&
230
+ !["size", "shape"].includes(consumer.channel) &&
231
+ program.graphicSpec.objects[consumer.layer.id]?.type !== "collection";
232
+ if (pointHandledByScale) continue;
233
+ seen.add(consumer.layer.id);
234
+ plan.push(step);
235
+ }
236
+ return plan;
237
+ }
238
+
239
+ export const editScale = action(
240
+ {
241
+ op: "editScale",
242
+ description: "Edit an existing scale and rematerialize its consumers."
243
+ },
244
+ function (args = {}) {
245
+ if (!isPlainObject(args)) {
246
+ throw new TypeError("editScale options must be a plain object.");
247
+ }
248
+ validateKeys(args, OPTIONS, "editScale");
249
+ if (!EDITABLE.some(property => Object.hasOwn(args, property))) {
250
+ throw new Error("editScale requires at least one editable property.");
251
+ }
252
+
253
+ const id = resolveScaleId(this, args.id);
254
+ const scale = requireSemanticScale(this, id);
255
+ const consumers = findScaleConsumers(this, id);
256
+ const channel = resolveChannel(consumers, id);
257
+ validateLegendTypeTransition(this, scale, args.type ?? scale.type);
258
+ const definition = normalizeDefinition(scale, channel, consumers, args);
259
+
260
+ let next = this;
261
+ for (const property of EDITABLE) {
262
+ if (
263
+ Object.hasOwn(scale, property) &&
264
+ !Object.hasOwn(definition, property)
265
+ ) {
266
+ next = next.editSemantic({
267
+ property: `scale[${id}].${property}`,
268
+ remove: true
269
+ });
270
+ }
271
+ }
272
+ for (const property of EDITABLE) {
273
+ if (
274
+ !Object.hasOwn(definition, property) ||
275
+ sameValue(scale[property], definition[property])
276
+ ) continue;
277
+ next = next.editSemantic({
278
+ property: `scale[${id}].${property}`,
279
+ value: definition[property]
280
+ });
281
+ }
282
+ if (consumers.length === 0) return next;
283
+
284
+ next = next.rematerializeScale({ id });
285
+ return applyMaterializationPlan(
286
+ next,
287
+ planMarkRematerialization(next, consumers)
288
+ );
289
+ }
290
+ );
@@ -0,0 +1,11 @@
1
+ import { createScale } from "./create.js";
2
+ import { editScale } from "./edit.js";
3
+ import { rematerializeScale } from "./materialize.js";
4
+ import { setQuantitativeColorScale } from "./quantitativeColor.js";
5
+
6
+ export function registerScaleActions(ProgramClass) {
7
+ ProgramClass.prototype.createScale = createScale;
8
+ ProgramClass.prototype.editScale = editScale;
9
+ ProgramClass.prototype.rematerializeScale = rematerializeScale;
10
+ ProgramClass.prototype.setQuantitativeColorScale = setQuantitativeColorScale;
11
+ }