ggaction 0.0.11 → 0.0.12

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 (32) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +2 -1
  3. package/knowledge/action-cards.json +1 -1
  4. package/knowledge/intent-taxonomy.json +1 -1
  5. package/knowledge/mcp-resources.json +1 -1
  6. package/knowledge/task-resolver.js +1 -1
  7. package/package.json +1 -1
  8. package/src/actions/encodings/offset.js +33 -21
  9. package/src/actions/encodings/position/apply.js +30 -0
  10. package/src/actions/encodings/position/policies/arc.js +23 -2
  11. package/src/actions/encodings/position/resolve.js +12 -2
  12. package/src/actions/errorBars/create.js +138 -7
  13. package/src/actions/errorBars/edit.js +10 -0
  14. package/src/actions/marks/point/materialize.js +33 -13
  15. package/src/actions/marks/rule/actions.js +26 -1
  16. package/src/core/vocabulary.js +2 -2
  17. package/src/grammar/arcs.js +156 -65
  18. package/src/grammar/positionCompatibility.js +1 -1
  19. package/src/grammar/rules.js +2 -0
  20. package/src/grammar/scales/ordinal.js +23 -0
  21. package/src/layout/facets.js +45 -16
  22. package/src/materialization/facetGuides/legacyCategorical.js +7 -1
  23. package/src/materialization/facetGuides/placement.js +16 -1
  24. package/src/materialization/facetGuides/preparation.js +26 -1
  25. package/src/materialization/facets.js +3 -1
  26. package/src/materialization/marks/capabilities.js +10 -2
  27. package/src/materialization/marks/index.js +5 -2
  28. package/src/materialization/rowEncoding.js +57 -1
  29. package/src/materialization/scales/policies/bar.js +0 -43
  30. package/src/materialization/scales/policies/offset.js +54 -0
  31. package/src/materialization/scales/resolve.js +2 -4
  32. package/types/program.d.ts +18 -0
@@ -1,4 +1,3 @@
1
- import { normalizeOffsetPadding } from "../../../grammar/bars/geometry.js";
2
1
  import {
3
2
  BAR_GRAINS,
4
3
  resolveBarChannels,
@@ -8,48 +7,6 @@ import {
8
7
  interpolateNumber,
9
8
  inverseLerp
10
9
  } from "../../../grammar/numeric.js";
11
- export function resolveOffsetScalePolicy({
12
- consumers,
13
- resolvedScales,
14
- markConfigs,
15
- id,
16
- channel
17
- }) {
18
- const parentChannel = channel === "xOffset" ? "x" : "y";
19
- const bandwidths = consumers.map(consumer => {
20
- if (parentChannel === "x" && consumer.layer.encoding?.x?.bin !== undefined) {
21
- return 1;
22
- }
23
- const parentScaleId = consumer.layer.encoding?.[parentChannel]?.scale;
24
- return resolvedScales[parentScaleId]?.bandwidth;
25
- });
26
- if (
27
- bandwidths.some(value => !Number.isFinite(value)) ||
28
- new Set(bandwidths).size !== 1
29
- ) {
30
- throw new Error(
31
- `${channel} scale "${id}" requires one shared resolved ${parentChannel} bandwidth.`
32
- );
33
- }
34
- const paddings = consumers.map(consumer => normalizeOffsetPadding(
35
- markConfigs[consumer.layer.id]?.[channel],
36
- undefined,
37
- channel
38
- ));
39
- const signatures = new Set(
40
- paddings.map(padding => JSON.stringify(padding))
41
- );
42
- if (signatures.size !== 1) {
43
- throw new Error(
44
- `${channel} scale "${id}" requires one shared padding policy.`
45
- );
46
- }
47
- return {
48
- parentBandwidth: bandwidths[0],
49
- ...paddings[0]
50
- };
51
- }
52
-
53
10
  export function resolveTemporalBarBand(valuesByConsumer, domain, range) {
54
11
  const temporalBars = valuesByConsumer.filter(({ consumer }) => {
55
12
  const channels = resolveBarChannels(consumer.layer);
@@ -0,0 +1,54 @@
1
+ import { normalizeOffsetPadding } from "../../../grammar/bars/geometry.js";
2
+
3
+ function resolveParentSlot(consumer, resolvedScales, parentChannel) {
4
+ if (parentChannel === "x" && consumer.layer.encoding?.x?.bin !== undefined) {
5
+ return 1;
6
+ }
7
+ const parentScaleId = consumer.layer.encoding?.[parentChannel]?.scale;
8
+ const parentScale = resolvedScales[parentScaleId];
9
+ if (Number.isFinite(parentScale?.bandwidth) && parentScale.bandwidth > 0) {
10
+ return parentScale.bandwidth;
11
+ }
12
+ if (parentScale?.type === "point" && Number.isFinite(parentScale.step)) {
13
+ return Math.abs(parentScale.step);
14
+ }
15
+ return undefined;
16
+ }
17
+
18
+ export function resolveOffsetScalePolicy({
19
+ consumers,
20
+ resolvedScales,
21
+ markConfigs,
22
+ id,
23
+ channel
24
+ }) {
25
+ const parentChannel = channel === "xOffset" ? "x" : "y";
26
+ const slots = consumers.map(consumer =>
27
+ resolveParentSlot(consumer, resolvedScales, parentChannel)
28
+ );
29
+ if (
30
+ slots.some(value => !Number.isFinite(value) || value <= 0) ||
31
+ new Set(slots).size !== 1
32
+ ) {
33
+ throw new Error(
34
+ `${channel} scale "${id}" requires one shared resolved ${parentChannel} categorical slot.`
35
+ );
36
+ }
37
+ const paddings = consumers.map(consumer => normalizeOffsetPadding(
38
+ markConfigs[consumer.layer.id]?.[channel],
39
+ undefined,
40
+ channel
41
+ ));
42
+ const signatures = new Set(
43
+ paddings.map(padding => JSON.stringify(padding))
44
+ );
45
+ if (signatures.size !== 1) {
46
+ throw new Error(
47
+ `${channel} scale "${id}" requires one shared padding policy.`
48
+ );
49
+ }
50
+ return {
51
+ parentBandwidth: slots[0],
52
+ ...paddings[0]
53
+ };
54
+ }
@@ -27,10 +27,8 @@ import {
27
27
  validateTimeScaleType
28
28
  } from "../../grammar/scales/index.js";
29
29
  import { resolveArcAutoPositionRange } from "./policies/arc.js";
30
- import {
31
- resolveOffsetScalePolicy,
32
- resolveTemporalBarBand
33
- } from "./policies/bar.js";
30
+ import { resolveTemporalBarBand } from "./policies/bar.js";
31
+ import { resolveOffsetScalePolicy } from "./policies/offset.js";
34
32
  import { resolveBinnedPositionDomain } from "./policies/binnedPosition.js";
35
33
  import { resolveSeriesLayoutDomain } from "./policies/series.js";
36
34
  import { OFFSET_POSITION_CHANNELS } from "../../core/vocabulary.js";
@@ -1116,6 +1116,10 @@ export interface RadiusScaleOptions {
1116
1116
  }
1117
1117
 
1118
1118
  export interface ThetaEncodingOptions {
1119
+ /**
1120
+ * Arc marks interpret an aggregate-free quantitative field as per-row sector
1121
+ * weights. Categorical arc theta retains the count and weighted-sum modes.
1122
+ */
1119
1123
  field: string;
1120
1124
  target?: string;
1121
1125
  fieldType?: FieldType;
@@ -1366,6 +1370,10 @@ export type ErrorBarPositionChannel = { field?: string } & (
1366
1370
  fieldType: "temporal";
1367
1371
  scale?: NonPointTemporalPositionScaleOptions;
1368
1372
  }
1373
+ | {
1374
+ fieldType: "quantitative";
1375
+ scale?: NonPointQuantitativePositionScaleOptions;
1376
+ }
1369
1377
  );
1370
1378
 
1371
1379
  export interface ErrorBarStatisticalIntervalChannel {
@@ -1387,12 +1395,22 @@ export type ErrorBarIntervalChannel =
1387
1395
  | ErrorBarStatisticalIntervalChannel
1388
1396
  | ErrorBarExplicitIntervalChannel;
1389
1397
 
1398
+ export interface ErrorBarOffsetChannel {
1399
+ field?: string;
1400
+ fieldType?: "nominal" | "ordinal";
1401
+ scale?: OffsetScaleOptions;
1402
+ paddingInner?: number;
1403
+ paddingOuter?: number;
1404
+ }
1405
+
1390
1406
  export interface ErrorBarOptions {
1391
1407
  id?: string;
1392
1408
  target?: string;
1393
1409
  data?: string;
1394
1410
  x?: ErrorBarPositionChannel | ErrorBarIntervalChannel;
1395
1411
  y?: ErrorBarPositionChannel | ErrorBarIntervalChannel;
1412
+ xOffset?: ErrorBarOffsetChannel;
1413
+ yOffset?: ErrorBarOffsetChannel;
1396
1414
  groupBy?: string;
1397
1415
  coordinate?: string;
1398
1416
  caps?: boolean;