ggaction 0.0.11 → 0.0.13

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 (289) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +3 -2
  3. package/knowledge/action-card.schema.json +1 -1
  4. package/knowledge/action-cards.json +1 -1
  5. package/knowledge/action-cards.schema.json +1 -1
  6. package/knowledge/extension-authoring.md +2 -1
  7. package/knowledge/intent-taxonomy.json +1 -1
  8. package/knowledge/mcp-resources.json +1 -1
  9. package/knowledge/task-resolver.js +1 -1
  10. package/package.json +4 -2
  11. package/src/actions/basic.js +2 -0
  12. package/src/actions/boxPlots/materialize.js +2 -1
  13. package/src/actions/canvas/actions.js +3 -1
  14. package/src/actions/canvas/fitting.js +211 -0
  15. package/src/actions/canvas/index.js +2 -0
  16. package/src/actions/categoryOrder/index.js +3 -2
  17. package/src/actions/charts/area.js +47 -0
  18. package/src/actions/charts/bar.js +11 -5
  19. package/src/actions/charts/beeswarm.js +70 -0
  20. package/src/actions/charts/density.js +44 -0
  21. package/src/actions/charts/ecdf.js +183 -0
  22. package/src/actions/charts/endpoints.js +451 -0
  23. package/src/actions/charts/heatmap.js +2 -2
  24. package/src/actions/charts/histogram.js +1 -1
  25. package/src/actions/charts/horizon.js +71 -0
  26. package/src/actions/charts/index.js +37 -0
  27. package/src/actions/charts/interval-regression.js +169 -0
  28. package/src/actions/charts/line.js +5 -5
  29. package/src/actions/charts/parallel.js +1 -1
  30. package/src/actions/charts/pie.js +44 -0
  31. package/src/actions/charts/polar.js +123 -0
  32. package/src/actions/charts/radar.js +299 -0
  33. package/src/actions/charts/radial.js +42 -0
  34. package/src/actions/charts/raincloud.js +422 -0
  35. package/src/actions/charts/rug-strip.js +279 -0
  36. package/src/actions/charts/scatter.js +9 -3
  37. package/src/actions/charts/shared.js +69 -10
  38. package/src/actions/composition/actions.js +118 -1
  39. package/src/actions/data/bin.js +29 -0
  40. package/src/actions/data/computed.js +24 -0
  41. package/src/actions/data/derived.js +66 -0
  42. package/src/actions/data/ecdf.js +38 -0
  43. package/src/actions/data/filter.js +212 -28
  44. package/src/actions/data/fold.js +24 -0
  45. package/src/actions/data/index.js +24 -0
  46. package/src/actions/data/interval.js +2 -0
  47. package/src/actions/data/intervalEdit.js +86 -4
  48. package/src/actions/data/regression.js +5 -2
  49. package/src/actions/data/stack.js +26 -0
  50. package/src/actions/data/summary.js +26 -0
  51. package/src/actions/data/timeUnit.js +1 -1
  52. package/src/actions/encodings/appearance.js +32 -13
  53. package/src/actions/encodings/barWidth.js +8 -0
  54. package/src/actions/encodings/basic.js +2 -0
  55. package/src/actions/encodings/color/continuous.js +19 -59
  56. package/src/actions/encodings/color/index.js +28 -22
  57. package/src/actions/encodings/color/layout.js +3 -97
  58. package/src/actions/encodings/color/policy.js +5 -8
  59. package/src/actions/encodings/density/resolve.js +37 -5
  60. package/src/actions/encodings/density.js +120 -33
  61. package/src/actions/encodings/horizon/resolve.js +8 -4
  62. package/src/actions/encodings/horizon.js +18 -8
  63. package/src/actions/encodings/index.js +2 -0
  64. package/src/actions/encodings/offset.js +33 -27
  65. package/src/actions/encodings/parallel.js +2 -8
  66. package/src/actions/encodings/position/apply.js +40 -4
  67. package/src/actions/encodings/position/index.js +43 -5
  68. package/src/actions/encodings/position/policies/arc.js +37 -2
  69. package/src/actions/encodings/position/policies/area.js +4 -42
  70. package/src/actions/encodings/position/policies/bar.js +48 -13
  71. package/src/actions/encodings/position/resolve.js +79 -24
  72. package/src/actions/encodings/ranged.js +123 -97
  73. package/src/actions/encodings/remove.js +37 -32
  74. package/src/actions/encodings/ruleAppearance.js +23 -9
  75. package/src/actions/encodings/seriesLayout.js +104 -0
  76. package/src/actions/encodings/shared.js +25 -23
  77. package/src/actions/encodings/strokeDash.js +9 -6
  78. package/src/actions/encodings/temporal.js +7 -0
  79. package/src/actions/encodings/text.js +30 -15
  80. package/src/actions/errorBands/create.js +18 -5
  81. package/src/actions/errorBands/edit.js +341 -21
  82. package/src/actions/errorBars/create.js +153 -11
  83. package/src/actions/errorBars/edit.js +365 -19
  84. package/src/actions/facets/actions.js +410 -12
  85. package/src/actions/facets/derive.js +57 -8
  86. package/src/actions/gradientPlots/components.js +33 -11
  87. package/src/actions/gradientPlots/materialize.js +5 -7
  88. package/src/actions/guides/applicability.js +20 -17
  89. package/src/actions/guides/axes/axes.js +4 -3
  90. package/src/actions/guides/axes/axis.js +18 -18
  91. package/src/actions/guides/axes/components.js +43 -0
  92. package/src/actions/guides/axes/edit.js +16 -51
  93. package/src/actions/guides/axes/labels.js +129 -19
  94. package/src/actions/guides/axes/lines.js +7 -5
  95. package/src/actions/guides/axes/parallel/lifecycle.js +117 -0
  96. package/src/actions/guides/axes/parallel/policy.js +137 -0
  97. package/src/actions/guides/axes/parallel/resolve.js +44 -23
  98. package/src/actions/guides/axes/parallel.js +93 -217
  99. package/src/actions/guides/axes/policy.js +21 -67
  100. package/src/actions/guides/axes/tickGroups.js +14 -8
  101. package/src/actions/guides/axes/ticks.js +5 -4
  102. package/src/actions/guides/axes/titles.js +21 -8
  103. package/src/actions/guides/basic.js +2 -0
  104. package/src/actions/guides/facade.js +106 -0
  105. package/src/actions/guides/facadeAxes.js +200 -0
  106. package/src/actions/guides/facadeLegend.js +63 -0
  107. package/src/actions/guides/grids/grid.js +37 -33
  108. package/src/actions/guides/grids/resolve.js +10 -2
  109. package/src/actions/guides/guides.js +35 -28
  110. package/src/actions/guides/legends/categorical/actions.js +193 -249
  111. package/src/actions/guides/legends/categorical/components.js +4 -5
  112. package/src/actions/guides/legends/categorical/layout.js +36 -349
  113. package/src/actions/guides/legends/categorical/options.js +30 -14
  114. package/src/actions/guides/legends/categorical/recipes.js +14 -0
  115. package/src/actions/guides/legends/categorical/resolve.js +21 -10
  116. package/src/actions/guides/legends/categorical/symbols.js +2 -3
  117. package/src/actions/guides/legends/continuous/common.js +69 -14
  118. package/src/actions/guides/legends/continuous/gradient.js +111 -83
  119. package/src/actions/guides/legends/continuous/index.js +6 -2
  120. package/src/actions/guides/legends/continuous/interval.js +71 -92
  121. package/src/actions/guides/legends/continuous/opacity.js +105 -84
  122. package/src/actions/guides/legends/creation.js +27 -0
  123. package/src/actions/guides/legends/edit.js +198 -66
  124. package/src/actions/guides/legends/focused.js +2 -2
  125. package/src/actions/guides/legends/lane.js +98 -86
  126. package/src/actions/guides/legends/lifecycle.js +132 -0
  127. package/src/actions/guides/legends/remove.js +31 -76
  128. package/src/actions/guides/legends/size.js +149 -105
  129. package/src/actions/guides/legends/strokeWidth.js +106 -64
  130. package/src/actions/guides/legends/target.js +12 -0
  131. package/src/actions/guides/legends/transition.js +43 -0
  132. package/src/actions/guides/polar/axes/facade.js +77 -62
  133. package/src/actions/guides/polar/axes/labels.js +5 -4
  134. package/src/actions/guides/polar/axes/lines.js +2 -1
  135. package/src/actions/guides/polar/axes/shared.js +6 -0
  136. package/src/actions/guides/polar/axes/ticks.js +5 -4
  137. package/src/actions/guides/polar/axes/titles.js +5 -4
  138. package/src/actions/guides/polar/grids.js +7 -7
  139. package/src/actions/guides/reuse.js +44 -0
  140. package/src/actions/guides/tickValues.js +19 -21
  141. package/src/actions/index.js +2 -0
  142. package/src/actions/intervals/resolve.js +35 -15
  143. package/src/actions/marks/arc/actions.js +1 -1
  144. package/src/actions/marks/area/actions.js +18 -4
  145. package/src/actions/marks/area/materialize.js +5 -2
  146. package/src/actions/marks/bar/materialize.js +11 -7
  147. package/src/actions/marks/index.js +5 -0
  148. package/src/actions/marks/line/actions.js +43 -108
  149. package/src/actions/marks/line/materialize.js +34 -52
  150. package/src/actions/marks/point/edit.js +11 -15
  151. package/src/actions/marks/point/index.js +1 -0
  152. package/src/actions/marks/point/jitter.js +3 -0
  153. package/src/actions/marks/point/materialize.js +138 -14
  154. package/src/actions/marks/point/packing.js +68 -0
  155. package/src/actions/marks/references.js +87 -0
  156. package/src/actions/marks/remove.js +17 -4
  157. package/src/actions/marks/rule/actions.js +60 -4
  158. package/src/actions/marks/rule/appearance.js +26 -0
  159. package/src/actions/marks/shared.js +12 -12
  160. package/src/actions/marks/text/actions.js +224 -6
  161. package/src/actions/marks/text/layout.js +2 -2
  162. package/src/actions/primitives/createGraphics.js +3 -1
  163. package/src/actions/primitives/semantic.js +1 -1
  164. package/src/actions/primitives/semanticAction.js +39 -2
  165. package/src/actions/primitives/semanticValidation/guide.js +10 -0
  166. package/src/actions/primitives/semanticValidation/layer.js +18 -1
  167. package/src/actions/primitives/semanticValidation/scale.js +10 -1
  168. package/src/actions/regression/create.js +1 -1
  169. package/src/actions/regression/edit.js +19 -6
  170. package/src/actions/regression/resolve.js +1 -1
  171. package/src/actions/scales/consumers/common.js +20 -53
  172. package/src/actions/scales/consumers/families.js +27 -14
  173. package/src/actions/scales/consumers/index.js +23 -2
  174. package/src/actions/scales/consumers/seriesLayout.js +33 -2
  175. package/src/actions/scales/create.js +4 -4
  176. package/src/actions/scales/definitions.js +19 -3
  177. package/src/actions/scales/edit.js +46 -34
  178. package/src/actions/scales/editPolicy.js +21 -31
  179. package/src/actions/scales/materialize.js +10 -46
  180. package/src/actions/scales/patch.js +1 -1
  181. package/src/actions/scales/preview.js +39 -0
  182. package/src/actions/scales/quantitativeColor.js +9 -5
  183. package/src/actions/theme/actions.js +43 -0
  184. package/src/actions/theme/index.js +9 -0
  185. package/src/actions/theme/reconcile.js +882 -0
  186. package/src/actions/titles/actions.js +11 -10
  187. package/src/actions/titles/resolve.js +1 -40
  188. package/src/actions/violinPlots/create.js +86 -42
  189. package/src/actions/violinPlots/edit.js +191 -0
  190. package/src/actions/violinPlots/index.js +2 -0
  191. package/src/core/ChartProgram.js +7 -0
  192. package/src/core/action.js +22 -2
  193. package/src/core/compositionState.js +136 -8
  194. package/src/core/vocabulary.js +2 -2
  195. package/src/grammar/aggregate.js +66 -23
  196. package/src/grammar/arcs.js +213 -65
  197. package/src/grammar/areaEndpoints.js +46 -0
  198. package/src/grammar/areaSeries.js +87 -41
  199. package/src/grammar/bars/aggregate.js +33 -12
  200. package/src/grammar/bars/policy.js +9 -7
  201. package/src/grammar/bin.js +181 -0
  202. package/src/grammar/categoryOrder.js +34 -0
  203. package/src/grammar/computed.js +150 -0
  204. package/src/grammar/ecdf.js +198 -0
  205. package/src/grammar/facets/index.js +117 -6
  206. package/src/grammar/fold.js +123 -0
  207. package/src/grammar/horizon.js +6 -4
  208. package/src/grammar/interval.js +37 -20
  209. package/src/grammar/lineSeries.js +20 -63
  210. package/src/grammar/markFilter.js +22 -4
  211. package/src/grammar/markLabels.js +93 -0
  212. package/src/grammar/parallelAxisTitles.js +16 -0
  213. package/src/grammar/pathSeries.js +91 -0
  214. package/src/grammar/pointPacking.js +183 -0
  215. package/src/grammar/positionCompatibility.js +1 -1
  216. package/src/grammar/positionDatum.js +12 -0
  217. package/src/grammar/rects.js +9 -1
  218. package/src/grammar/regression/derive.js +4 -0
  219. package/src/grammar/regression/index.js +7 -2
  220. package/src/grammar/regression/models.js +22 -7
  221. package/src/grammar/regression/parameters.js +40 -13
  222. package/src/grammar/rotation.js +29 -0
  223. package/src/grammar/rules.js +9 -21
  224. package/src/grammar/scales/color.js +23 -1
  225. package/src/grammar/scales/colorConsumers.js +38 -0
  226. package/src/grammar/scales/definition.js +15 -1
  227. package/src/grammar/scales/discretized.js +11 -5
  228. package/src/grammar/scales/fields.js +38 -8
  229. package/src/grammar/scales/mapping.js +2 -0
  230. package/src/grammar/scales/ordinal.js +23 -0
  231. package/src/grammar/scales/radial.js +55 -0
  232. package/src/grammar/scales/types.js +1 -0
  233. package/src/grammar/schemas/semanticPath.js +17 -3
  234. package/src/grammar/stack.js +170 -0
  235. package/src/grammar/statistics/confidenceInterval.js +101 -0
  236. package/src/grammar/summary.js +183 -0
  237. package/src/grammar/text.js +22 -16
  238. package/src/grammar/timeUnit.js +21 -11
  239. package/src/grammar/transformTopology.js +6 -0
  240. package/src/grammar/transforms.js +36 -0
  241. package/src/grammar/valueFormat.js +112 -0
  242. package/src/grammar/window.js +13 -7
  243. package/src/layout/facets.js +86 -23
  244. package/src/layout/guideCollisions.js +12 -0
  245. package/src/layout/legend.js +2 -10
  246. package/src/layout/legendItems.js +102 -0
  247. package/src/layout/legendLane.js +100 -11
  248. package/src/materialization/bars/aggregate.js +38 -152
  249. package/src/materialization/bars/histogram.js +24 -0
  250. package/src/materialization/categorySlotOffset.js +40 -0
  251. package/src/materialization/compositionSnapshot.js +1 -1
  252. package/src/materialization/dependencies.js +57 -16
  253. package/src/materialization/encodings.js +1 -1
  254. package/src/materialization/facetGuides/legacyCategorical.js +7 -1
  255. package/src/materialization/facetGuides/placement.js +16 -1
  256. package/src/materialization/facetGuides/preparation.js +26 -1
  257. package/src/materialization/facets.js +11 -2
  258. package/src/materialization/guides/layout.js +57 -0
  259. package/src/materialization/guides/resources.js +2 -2
  260. package/src/materialization/legends.js +10 -1
  261. package/src/materialization/marks/capabilities.js +30 -7
  262. package/src/materialization/marks/grouping.js +52 -0
  263. package/src/materialization/marks/index.js +63 -25
  264. package/src/materialization/marks/policies.js +2 -0
  265. package/src/materialization/rect.js +33 -33
  266. package/src/materialization/rowEncoding.js +70 -14
  267. package/src/materialization/scaleGuideDependencies.js +8 -5
  268. package/src/materialization/scales/map.js +1 -0
  269. package/src/materialization/scales/policies/arc.js +42 -0
  270. package/src/materialization/scales/policies/bar.js +0 -43
  271. package/src/materialization/scales/policies/binnedPosition.js +7 -4
  272. package/src/materialization/scales/policies/offset.js +54 -0
  273. package/src/materialization/scales/policies/series.js +2 -1
  274. package/src/materialization/scales/resolve.js +48 -18
  275. package/src/materialization/selection/compatibility.js +11 -0
  276. package/src/materialization/selection/items/bar.js +12 -68
  277. package/src/materialization/selection/items/common.js +8 -2
  278. package/src/materialization/selection/items/path.js +3 -13
  279. package/src/materialization/selection/items/rect.js +7 -4
  280. package/src/materialization/text.js +64 -5
  281. package/src/mcp/adapter.js +2 -2
  282. package/src/selectors/datasets.js +13 -0
  283. package/src/selectors/layers.js +3 -2
  284. package/src/selectors/scales.js +6 -0
  285. package/src/theme/defaults.js +39 -0
  286. package/types/basic.d.ts +11 -2
  287. package/types/index.d.ts +126 -0
  288. package/types/program.d.ts +1327 -124
  289. package/src/materialization/bars/grouped.js +0 -144
@@ -1,7 +1,16 @@
1
1
  import { action } from "../../core/action.js";
2
- import { validateKeys } from "../../core/validation.js";
2
+ import {
3
+ validateKeys,
4
+ validateOptionObject
5
+ } from "../../core/validation.js";
3
6
  import { findLayer } from "../../selectors/layers.js";
7
+ import { findDataset } from "../../selectors/datasets.js";
4
8
  import { DEFAULT_COLORS } from "../../theme/defaults.js";
9
+ import {
10
+ readNominalField,
11
+ validateCategoricalFieldType
12
+ } from "../../grammar/scales/index.js";
13
+ import { normalizeOffsetPadding } from "../../grammar/bars/geometry.js";
5
14
  import { createResolvedIntervalData, ownOptions } from
6
15
  "../data/intervalEdit.js";
7
16
  import { resolveIntervalComposite } from "../intervals/resolve.js";
@@ -13,6 +22,8 @@ const OPTIONS = Object.freeze([
13
22
  "data",
14
23
  "x",
15
24
  "y",
25
+ "xOffset",
26
+ "yOffset",
16
27
  "groupBy",
17
28
  "coordinate",
18
29
  "caps",
@@ -23,30 +34,88 @@ const OPTIONS = Object.freeze([
23
34
  "opacity"
24
35
  ]);
25
36
 
26
- const ERROR_BAR_POLICY = Object.freeze({
37
+ const OFFSET_OPTIONS = Object.freeze([
38
+ "field", "fieldType", "scale", "paddingInner", "paddingOuter"
39
+ ]);
40
+
41
+ export const ERROR_BAR_POLICY = Object.freeze({
27
42
  operation: "createErrorBar",
28
43
  resourceLabel: "error-bar",
29
44
  defaultId: "errorBar",
30
45
  ownerLabel: "Error-bar id",
31
- positionTypes: Object.freeze(["nominal", "ordinal", "temporal"]),
46
+ positionTypes: Object.freeze([
47
+ "quantitative", "nominal", "ordinal", "temporal"
48
+ ]),
32
49
  defaultPositionType: "nominal",
33
50
  defaultIntervalChannel: "y",
34
51
  scaleDefaults: () => ({}),
35
52
  intervalScaleDefaults: Object.freeze({ nice: true, zero: false }),
36
53
  allowExplicitGrouping: false,
37
54
  ambiguousMessage:
38
- "createErrorBar requires one quantitative interval axis and one nominal, ordinal, or temporal position axis."
55
+ "createErrorBar requires one quantitative interval axis and one compatible position axis; use interval options to disambiguate two quantitative channels."
39
56
  });
40
57
 
41
- function resolveErrorBar(program, args) {
42
- const resolved = resolveIntervalComposite(program, args, ERROR_BAR_POLICY);
58
+ export function resolveErrorBar(program, args, policy = ERROR_BAR_POLICY) {
59
+ const resolved = resolveIntervalComposite(program, args, policy);
60
+ const offset = resolveErrorBarOffset(program, args, resolved, policy.operation);
61
+ const groupBy = resolved.interval.mode === "statistical" && offset !== undefined
62
+ ? [...new Set([...resolved.groupBy, offset.field])]
63
+ : resolved.groupBy;
43
64
  return {
44
65
  ...resolved,
66
+ groupBy,
67
+ offset,
45
68
  lowerCapId: `${resolved.id}LowerCap`,
46
69
  upperCapId: `${resolved.id}UpperCap`
47
70
  };
48
71
  }
49
72
 
73
+ function resolveErrorBarOffset(program, args, resolved, operation) {
74
+ const channel = `${resolved.position.channel}Offset`;
75
+ const incompatible = channel === "xOffset" ? "yOffset" : "xOffset";
76
+ if (args[incompatible] !== undefined) {
77
+ throw new Error(
78
+ `${operation} ${incompatible} does not match the ${resolved.orientation} interval orientation.`
79
+ );
80
+ }
81
+ const explicit = args[channel] === undefined
82
+ ? undefined
83
+ : validateOptionObject(args[channel], OFFSET_OPTIONS, `${operation} ${channel}`);
84
+ const inferred = resolved.sourceLayer?.encoding?.[channel];
85
+ if (explicit === undefined && inferred === undefined) return undefined;
86
+ if (!["nominal", "ordinal"].includes(resolved.position.fieldType)) {
87
+ throw new Error(
88
+ `${operation} ${channel} requires a categorical ${resolved.position.channel} position.`
89
+ );
90
+ }
91
+ const field = explicit?.field ?? inferred?.field;
92
+ if (typeof field !== "string" || field.length === 0) {
93
+ throw new TypeError(`${operation} ${channel} field must be a non-empty string.`);
94
+ }
95
+ const fieldType = validateCategoricalFieldType(
96
+ explicit?.fieldType ?? inferred?.fieldType ?? "nominal"
97
+ );
98
+ const dataset = findDataset(program, resolved.source);
99
+ readNominalField(dataset.values, field);
100
+ const padding = normalizeOffsetPadding(
101
+ explicit ?? {},
102
+ resolved.sourceLayer === undefined
103
+ ? undefined
104
+ : program.markConfigs[resolved.sourceLayer.id]?.[channel],
105
+ channel
106
+ );
107
+ return {
108
+ channel,
109
+ field,
110
+ fieldType,
111
+ scale: {
112
+ ...(inferred?.scale === undefined ? {} : { id: inferred.scale }),
113
+ ...(explicit?.scale ?? {})
114
+ },
115
+ ...padding
116
+ };
117
+ }
118
+
50
119
  function resolveAppearance(args) {
51
120
  return resolveErrorBarAppearance(ownOptions(args, [
52
121
  "caps", "capSize", "stroke", "strokeWidth", "strokeDash", "opacity"
@@ -71,21 +140,33 @@ export const createErrorBarCap = action(
71
140
  function (args = {}) {
72
141
  validateKeys(args, [
73
142
  "id", "data", "orientation", "positionField", "positionFieldType",
74
- "intervalField", "coordinate", "positionScale", "intervalScale",
143
+ "intervalField", "coordinate", "positionScale", "intervalScale", "positionTemporalUnit",
144
+ "offsetChannel", "offsetField", "offsetFieldType", "offsetScale",
145
+ "offsetPaddingInner", "offsetPaddingOuter",
75
146
  "capSize", "stroke", "strokeWidth", "strokeDash", "opacity"
76
147
  ], "createErrorBarCap");
77
148
  if (!["vertical", "horizontal"].includes(args.orientation)) {
78
149
  throw new Error(`Unsupported error-bar orientation "${args.orientation}".`);
79
150
  }
80
151
  const vertical = args.orientation === "vertical";
152
+ const expectedOffset = vertical ? "xOffset" : "yOffset";
153
+ if (
154
+ args.offsetChannel !== undefined &&
155
+ args.offsetChannel !== expectedOffset
156
+ ) {
157
+ throw new Error(
158
+ `createErrorBarCap requires ${expectedOffset} for ${args.orientation} intervals.`
159
+ );
160
+ }
81
161
  const positionAction = vertical ? "encodeX" : "encodeY";
82
162
  const intervalAction = vertical ? "encodeY" : "encodeX";
83
- return this
163
+ let next = this
84
164
  .createRuleMark({ id: args.id, data: args.data })
85
165
  [positionAction]({
86
166
  target: args.id,
87
167
  field: args.positionField,
88
168
  fieldType: args.positionFieldType,
169
+ ...(args.positionTemporalUnit === undefined ? {} : { temporalUnit: args.positionTemporalUnit }),
89
170
  coordinate: args.coordinate,
90
171
  scale: { id: args.positionScale }
91
172
  })
@@ -95,7 +176,21 @@ export const createErrorBarCap = action(
95
176
  fieldType: "quantitative",
96
177
  coordinate: args.coordinate,
97
178
  scale: { id: args.intervalScale }
98
- })
179
+ });
180
+ if (args.offsetChannel !== undefined) {
181
+ const offsetAction = args.offsetChannel === "xOffset"
182
+ ? "encodeXOffset"
183
+ : "encodeYOffset";
184
+ next = next[offsetAction]({
185
+ target: args.id,
186
+ field: args.offsetField,
187
+ fieldType: args.offsetFieldType,
188
+ scale: { id: args.offsetScale },
189
+ paddingInner: args.offsetPaddingInner,
190
+ paddingOuter: args.offsetPaddingOuter
191
+ });
192
+ }
193
+ return next
99
194
  .encodeStroke({ target: args.id, value: args.stroke })
100
195
  .encodeStrokeWidth({ target: args.id, value: args.strokeWidth })
101
196
  .encodeStrokeDash({ target: args.id, value: args.strokeDash })
@@ -113,11 +208,25 @@ function positionArgs(resolved) {
113
208
  target: resolved.id,
114
209
  field: resolved.position.field,
115
210
  fieldType: resolved.position.fieldType,
211
+ ...(resolved.position.temporalUnit === undefined ? {} : { temporalUnit: resolved.position.temporalUnit }),
116
212
  coordinate: resolved.coordinate,
117
213
  scale: resolved.position.scale
118
214
  };
119
215
  }
120
216
 
217
+ function offsetArgs(resolved) {
218
+ return resolved.offset === undefined
219
+ ? undefined
220
+ : {
221
+ target: resolved.id,
222
+ field: resolved.offset.field,
223
+ fieldType: resolved.offset.fieldType,
224
+ scale: resolved.offset.scale,
225
+ paddingInner: resolved.offset.paddingInner,
226
+ paddingOuter: resolved.offset.paddingOuter
227
+ };
228
+ }
229
+
121
230
  function intervalArgs(resolved, field) {
122
231
  return {
123
232
  target: resolved.id,
@@ -154,8 +263,14 @@ export const createErrorBar = action(
154
263
  target: resolved.id,
155
264
  field: resolved.fields.upper,
156
265
  fieldType: "quantitative"
157
- })
158
- .encodeStroke({ target: resolved.id, value: appearance.stroke })
266
+ });
267
+ if (resolved.offset !== undefined) {
268
+ const offsetAction = resolved.offset.channel === "xOffset"
269
+ ? "encodeXOffset"
270
+ : "encodeYOffset";
271
+ next = next[offsetAction](offsetArgs(resolved));
272
+ }
273
+ next = next.encodeStroke({ target: resolved.id, value: appearance.stroke })
159
274
  .encodeStrokeWidth({ target: resolved.id, value: appearance.strokeWidth })
160
275
  .encodeStrokeDash({ target: resolved.id, value: appearance.strokeDash })
161
276
  .encodeOpacity({ target: resolved.id, value: appearance.opacity });
@@ -169,10 +284,21 @@ export const createErrorBar = action(
169
284
  orientation: resolved.orientation,
170
285
  positionField: resolved.position.field,
171
286
  positionFieldType: resolved.position.fieldType,
287
+ ...(resolved.position.temporalUnit === undefined ? {} : { positionTemporalUnit: resolved.position.temporalUnit }),
172
288
  intervalField: field,
173
289
  coordinate: resolved.coordinate,
174
290
  positionScale: intervalLayer.encoding[resolved.position.channel].scale,
175
291
  intervalScale: intervalLayer.encoding[resolved.interval.channel].scale,
292
+ ...(resolved.offset === undefined
293
+ ? {}
294
+ : {
295
+ offsetChannel: resolved.offset.channel,
296
+ offsetField: resolved.offset.field,
297
+ offsetFieldType: resolved.offset.fieldType,
298
+ offsetScale: intervalLayer.encoding[resolved.offset.channel].scale,
299
+ offsetPaddingInner: resolved.offset.paddingInner,
300
+ offsetPaddingOuter: resolved.offset.paddingOuter
301
+ }),
176
302
  capSize: appearance.capSize,
177
303
  stroke: appearance.stroke,
178
304
  strokeWidth: appearance.strokeWidth,
@@ -184,15 +310,31 @@ export const createErrorBar = action(
184
310
  return next._withMarkConfig(resolved.id, {
185
311
  ...next.markConfigs[resolved.id],
186
312
  errorBar: {
313
+ source: resolved.source,
314
+ intervalMode: resolved.interval.mode,
315
+ ...(resolved.interval.mode === "statistical"
316
+ ? { intervalField: resolved.interval.field }
317
+ : { centerField: resolved.fields.center }),
318
+ groupField: resolved.groupField,
319
+ groupBy: resolved.groupBy,
187
320
  data: resolved.dataId,
188
321
  orientation: resolved.orientation,
189
322
  positionField: resolved.position.field,
190
323
  positionFieldType: resolved.position.fieldType,
324
+ ...(resolved.position.temporalUnit === undefined ? {} : { positionTemporalUnit: resolved.position.temporalUnit }),
191
325
  lowerField: resolved.fields.lower,
192
326
  upperField: resolved.fields.upper,
193
327
  coordinate: resolved.coordinate,
194
328
  positionScale: intervalLayer.encoding[resolved.position.channel].scale,
195
329
  intervalScale: intervalLayer.encoding[resolved.interval.channel].scale,
330
+ ...(resolved.offset === undefined
331
+ ? {}
332
+ : {
333
+ offset: {
334
+ ...resolved.offset,
335
+ scale: intervalLayer.encoding[resolved.offset.channel].scale
336
+ }
337
+ }),
196
338
  lowerCapId: resolved.lowerCapId,
197
339
  upperCapId: resolved.upperCapId,
198
340
  ...appearance