@genome-spy/core 0.14.0 → 0.16.0

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 (67) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +16 -0
  3. package/dist/genome-spy-schema.json +4068 -0
  4. package/dist/index.js +42 -42
  5. package/dist/style.css +1 -1
  6. package/package.json +5 -4
  7. package/src/data/sources/dataUtils.js +50 -3
  8. package/src/data/sources/dynamicCallbackSource.js +2 -1
  9. package/src/data/sources/dynamicSource.js +2 -1
  10. package/src/data/sources/inlineSource.js +3 -5
  11. package/src/data/sources/namedSource.js +3 -7
  12. package/src/data/sources/urlSource.js +1 -1
  13. package/src/data/transforms/aggregate.js +1 -0
  14. package/src/data/transforms/flattenDelimited.js +6 -0
  15. package/src/data/transforms/regexFold.js +1 -1
  16. package/src/data/transforms/stack.js +3 -3
  17. package/src/embedApi.d.ts +59 -0
  18. package/src/encoder/accessor.js +6 -6
  19. package/src/encoder/encoder.js +47 -22
  20. package/src/genome/scaleIndex.d.ts +38 -0
  21. package/src/genome/scaleIndex.js +18 -52
  22. package/src/genome/scaleLocus.d.ts +11 -0
  23. package/src/genome/scaleLocus.js +12 -16
  24. package/src/genomeSpy.js +2 -5
  25. package/src/gl/dataToVertices.js +14 -6
  26. package/src/gl/includes/fp64-utils.js +10 -0
  27. package/src/gl/includes/scales.glsl +2 -0
  28. package/src/gl/webGLHelper.js +3 -1
  29. package/src/index.js +9 -35
  30. package/src/marks/link.js +1 -12
  31. package/src/marks/mark.js +27 -5
  32. package/src/marks/markUtils.js +41 -25
  33. package/src/marks/pointMark.js +5 -2
  34. package/src/marks/rule.js +11 -2
  35. package/src/scale/glslScaleGenerator.js +16 -29
  36. package/src/scale/scale.js +10 -0
  37. package/src/scale/ticks.js +11 -6
  38. package/src/spec/channel.d.ts +343 -43
  39. package/src/spec/data.d.ts +14 -3
  40. package/src/spec/scale.d.ts +18 -1
  41. package/src/spec/view.d.ts +12 -6
  42. package/src/tooltip/refseqGeneTooltipHandler.js +1 -0
  43. package/src/types/filetypes.d.ts +10 -0
  44. package/src/types/internmap.d.ts +22 -0
  45. package/src/types/vega-loader.d.ts +1 -0
  46. package/src/utils/arrayUtils.js +12 -6
  47. package/src/utils/cloner.js +5 -3
  48. package/src/utils/concatIterables.js +2 -2
  49. package/src/utils/domainArray.js +0 -8
  50. package/src/utils/propertyCoalescer.js +9 -4
  51. package/src/view/axisResolution.js +11 -6
  52. package/src/view/axisView.js +8 -5
  53. package/src/view/decoratorView.js +6 -3
  54. package/src/view/facetView.js +3 -0
  55. package/src/view/flowBuilder.js +2 -1
  56. package/src/view/renderingContext/svgViewRenderingContext.js +7 -3
  57. package/src/view/scaleResolution.js +52 -32
  58. package/src/view/testUtils.js +7 -4
  59. package/src/view/unitView.js +15 -9
  60. package/src/view/view.js +10 -8
  61. package/src/view/viewFactory.js +2 -0
  62. package/src/view/viewUtils.js +4 -4
  63. package/src/options.d.ts +0 -9
  64. package/src/utils/fisheye.js +0 -60
  65. package/src/utils/html.js +0 -23
  66. package/src/utils/html.test.js +0 -13
  67. package/src/view/channel.js +0 -5
package/src/marks/rule.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  import VERTEX_SHADER from "../gl/rule.vertex.glsl";
9
9
  import FRAGMENT_SHADER from "../gl/rule.fragment.glsl";
10
10
  import { RuleVertexBuilder } from "../gl/dataToVertices";
11
+ import { isChannelDefWithScale } from "../encoder/encoder.js";
11
12
 
12
13
  export default class RuleMark extends Mark {
13
14
  /**
@@ -89,10 +90,18 @@ export default class RuleMark extends Mark {
89
90
  // Limited horizontal rule
90
91
  encoding.y2 = encoding.y;
91
92
  } else if (encoding.y && encoding.x) {
92
- if (!encoding.x2 && encoding.y.type == "quantitative") {
93
+ if (
94
+ !encoding.x2 &&
95
+ isChannelDefWithScale(encoding.y) &&
96
+ encoding.y.type == "quantitative"
97
+ ) {
93
98
  encoding.x2 = encoding.x;
94
99
  encoding.y2 = { datum: 0 };
95
- } else if (!encoding.y2 && encoding.x.type == "quantitative") {
100
+ } else if (
101
+ !encoding.y2 &&
102
+ isChannelDefWithScale(encoding.x) &&
103
+ encoding.x.type == "quantitative"
104
+ ) {
96
105
  encoding.y2 = encoding.y;
97
106
  encoding.x2 = { datum: 0 };
98
107
  } else {
@@ -4,7 +4,6 @@ import {
4
4
  isDiscretizing,
5
5
  isInterpolating,
6
6
  } from "vega-scale";
7
- import { fp64ify } from "../gl/includes/fp64-utils";
8
7
  import { isArray, isBoolean, isNumber, isString } from "vega-util";
9
8
  import { color as d3color } from "d3-color";
10
9
 
@@ -14,6 +13,7 @@ import {
14
13
  isDatumDef,
15
14
  isDiscreteChannel,
16
15
  getPrimaryChannel,
16
+ isValueDef,
17
17
  } from "../encoder/encoder";
18
18
  import { peek } from "../utils/arrayUtils";
19
19
 
@@ -93,11 +93,17 @@ ${vec.type} ${SCALED_FUNCTION_PREFIX}${channel}() {
93
93
  /**
94
94
  *
95
95
  * @param {Channel} channel
96
- * @param {any} scale
97
- * @param {import("../spec/channel").ChannelDef} encoding
96
+ * @param {any} scale TODO: typing
97
+ * @param {import("../spec/channel").ChannelDef} channelDef
98
98
  */
99
99
  // eslint-disable-next-line complexity
100
- export function generateScaleGlsl(channel, scale, encoding) {
100
+ export function generateScaleGlsl(channel, scale, channelDef) {
101
+ if (isValueDef(channelDef)) {
102
+ throw new Error(
103
+ `Cannot create scale for "value": ${JSON.stringify(channelDef)}`
104
+ );
105
+ }
106
+
101
107
  const primary = getPrimaryChannel(channel);
102
108
  const attributeName = ATTRIBUTE_PREFIX + channel;
103
109
  const domainUniformName = DOMAIN_PREFIX + primary;
@@ -184,7 +190,8 @@ export function generateScaleGlsl(channel, scale, encoding) {
184
190
  scale.paddingInner(),
185
191
  scale.paddingOuter(),
186
192
  scale.align(),
187
- encoding.band ?? 0.5
193
+ // @ts-expect-error TODO: fix typing
194
+ channelDef.band ?? 0.5
188
195
  );
189
196
  break;
190
197
 
@@ -204,7 +211,7 @@ export function generateScaleGlsl(channel, scale, encoding) {
204
211
  throw new Error(
205
212
  `Unsupported scale type: ${
206
213
  scale.type
207
- }! ${channel}: ${JSON.stringify(encoding)}`
214
+ }! ${channel}: ${JSON.stringify(channelDef)}`
208
215
  );
209
216
  }
210
217
 
@@ -228,20 +235,6 @@ export function generateScaleGlsl(channel, scale, encoding) {
228
235
  );
229
236
  }
230
237
 
231
- /** @type {number} */
232
- let datum;
233
- if (isDatumDef(encoding)) {
234
- if (isNumber(encoding.datum)) {
235
- datum = encoding.datum;
236
- } else {
237
- throw new Error(
238
- `Only quantitative datums are currently supported in the encoding definition: ${JSON.stringify(
239
- encoding
240
- )}`
241
- );
242
- }
243
- }
244
-
245
238
  const returnType = isColorChannel(channel) ? "vec3" : "float";
246
239
 
247
240
  /**
@@ -269,14 +262,8 @@ export function generateScaleGlsl(channel, scale, encoding) {
269
262
  interpolate = `getDiscreteColor(${textureUniformName}, int(transformed)).r`;
270
263
  }
271
264
 
272
- // Declare the data: a variable or a constant datum (in domain).
273
- if (datum !== undefined) {
274
- // TODO: Datums could also be provided as uniforms, allowing for modifications
275
- glsl.push(
276
- `const highp ${attributeType} ${attributeName} = ${vectorize(
277
- fp64 ? fp64ify(datum) : datum
278
- )};`
279
- );
265
+ if (isDatumDef(channelDef)) {
266
+ glsl.push(`uniform highp ${attributeType} ${attributeName};`);
280
267
  } else {
281
268
  glsl.push(`in highp ${attributeType} ${attributeName};`);
282
269
  }
@@ -329,7 +316,7 @@ export function generateScaleGlsl(channel, scale, encoding) {
329
316
  }
330
317
 
331
318
  // 3. clamp
332
- if (scale.clamp && scale.clamp()) {
319
+ if ("clamp" in scale && scale.clamp()) {
333
320
  scaleBody.push(
334
321
  `transformed = clampToRange(transformed, ${vectorizeRange(range)});`
335
322
  );
@@ -9,6 +9,10 @@
9
9
  */
10
10
 
11
11
  /* eslint-disable */
12
+ // @ts-nocheck
13
+
14
+ // This file is a mess
15
+ // TODO: Fix types, etc.
12
16
 
13
17
  import { tickCount } from "./ticks";
14
18
  import {
@@ -131,6 +135,12 @@ export function configureScale(_, scale, logger) {
131
135
  );
132
136
  }
133
137
 
138
+ /**
139
+ *
140
+ * @param {import("../spec/scale").Scale} _
141
+ * @param {*} logger
142
+ * @returns {import("../encoder/encoder").VegaScale}
143
+ */
134
144
  export default function createScale(_, logger) {
135
145
  const key = scaleKey(_);
136
146
  const scale = getScale(key);
@@ -9,6 +9,10 @@
9
9
  */
10
10
 
11
11
  /* eslint-disable */
12
+ // @ts-nocheck
13
+
14
+ // This file is a mess
15
+ // TODO: Fix types, etc.
12
16
 
13
17
  import { isLogarithmic } from "vega-scale";
14
18
  import { error, isNumber, isObject, isString, peek, span } from "vega-util";
@@ -16,8 +20,9 @@ import { format as numberFormat, formatSpecifier } from "d3-format";
16
20
 
17
21
  /**
18
22
  * Determine the tick count or interval function.
19
- * @param {Scale} scale - The scale for which to generate tick values.
20
- * @param {*} count - The desired tick count or interval specifier.
23
+ *
24
+ * @param {import("../encoder/encoder").VegaScale} scale - The scale for which to generate tick values.
25
+ * @param {number | {step: number, interval: number}} count - The desired tick count or interval specifier.
21
26
  * @param {number} minStep - The desired minimum step between tick values.
22
27
  * @return {*} - The tick count or interval function.
23
28
  */
@@ -39,7 +44,7 @@ export function tickCount(scale, count, minStep) {
39
44
  /**
40
45
  * Filter a set of candidate tick values, ensuring that only tick values
41
46
  * that lie within the scale range are included.
42
- * @param {Scale} scale - The scale for which to generate tick values.
47
+ * @param {import("../encoder/encoder").VegaScale} scale - The scale for which to generate tick values.
43
48
  * @param {Array<*>} ticks - The candidate tick values.
44
49
  * @param {*} count - The tick count or interval function.
45
50
  * @return {Array<*>} - The filtered tick values.
@@ -80,9 +85,9 @@ export function validTicks(scale, ticks, count) {
80
85
  * interval value. If the scale has a 'ticks' method, it will be used to
81
86
  * generate the ticks, with the count argument passed as a parameter. If the
82
87
  * scale lacks a 'ticks' method, the full scale domain will be returned.
83
- * @param {Scale} scale - The scale for which to generate tick values.
88
+ * @param {import("../encoder/encoder").VegaScale} scale - The scale for which to generate tick values.
84
89
  * @param {*} [count] - The approximate number of desired ticks.
85
- * @return {Array<*>} - The generated tick values.
90
+ * @return {any[]} - The generated tick values.
86
91
  */
87
92
  export function tickValues(scale, count) {
88
93
  return scale.bins
@@ -117,7 +122,7 @@ function binValues(bins, count) {
117
122
  * If the input scale is a logarithmic scale and the format specifier does not
118
123
  * indicate a desired decimal precision, a special variable precision formatter
119
124
  * that automatically trims trailing zeroes will be generated.
120
- * @param {Scale} scale - The scale for which to generate the label formatter.
125
+ * @param {import("../encoder/encoder").VegaScale} scale - The scale for which to generate the label formatter.
121
126
  * @param {*} [count] - The approximate number of desired ticks.
122
127
  * @param {string} [specifier] - The format specifier. Must be a legal d3
123
128
  * specifier string (see https://github.com/d3/d3-format#formatSpecifier).
@@ -1,16 +1,31 @@
1
+ /*!
2
+ * Partially based on
3
+ * https://github.com/vega/vega-lite/blob/master/src/channeldef.ts
4
+ *
5
+ * Copyright (c) 2015-2018, University of Washington Interactive Data Lab
6
+ * All rights reserved.
7
+ *
8
+ * BSD-3-Clause License: https://github.com/vega/vega-lite/blob/master/LICENSE
9
+ */
10
+
1
11
  import { Scale } from "./scale";
2
12
  import { Axis } from "./axis";
3
13
 
4
14
  export type Scalar = string | number | boolean;
5
- export type FieldName = string;
15
+ export type Value = Scalar | null;
6
16
 
7
- export type PositionalChannel = "x" | "y";
17
+ export type FieldName = string;
18
+ export type Field = FieldName;
8
19
 
20
+ export type PrimaryPositionalChannel = "x" | "y";
9
21
  export type SecondaryPositionalChannel = "x2" | "y2";
10
22
 
23
+ export type PositionalChannel =
24
+ | PrimaryPositionalChannel
25
+ | SecondaryPositionalChannel;
26
+
11
27
  export type Channel =
12
28
  | PositionalChannel
13
- | SecondaryPositionalChannel
14
29
  | "color"
15
30
  | "fill"
16
31
  | "stroke"
@@ -21,8 +36,6 @@ export type Channel =
21
36
  | "size"
22
37
  | "shape"
23
38
  | "text"
24
- | "size2"
25
- | "color2"
26
39
  | "angle"
27
40
  | "sample"
28
41
  | "uniqueId"
@@ -30,63 +43,198 @@ export type Channel =
30
43
  | "facetIndex"
31
44
  | "semanticScore"
32
45
  | "dx"
33
- | "dy";
46
+ | "dy"
47
+ | "uniqueId";
48
+
49
+ // TODO
50
+ export type FacetFieldDef = any;
34
51
 
35
- export interface ChannelDefBase {
52
+ // TODO: Belongs to "guide"
53
+ export interface TitleMixins {
54
+ /**
55
+ * A title for the field. If `null`, the title will be removed.
56
+ */
36
57
  title?: string | null;
37
58
  }
38
59
 
39
- export interface ValueDef extends ChannelDefBase {
40
- /** A constant value in the context of the range */
41
- value: Scalar;
60
+ export interface BandMixins {
61
+ /**
62
+ * Relative position on band scale. For example, the marks will be positioned at the beginning of the band if set to `0`, and at the middle of the band if set to `0.5`.
63
+ *
64
+ * @minimum 0
65
+ * @maximum 1
66
+ */
67
+ // TODO: rename to bandPosition: https://github.com/vega/vega-lite/pull/7190
68
+ // bandPosition?: number;
69
+ band?: number;
70
+ }
71
+
72
+ export interface FormatMixins {
73
+ /**
74
+ * When used with the default `"number"` format type, the text formatting pattern for labels of guides (axes, legends, headers) and text marks.
75
+ *
76
+ * - If the format type is `"number"` (e.g., for quantitative fields), this is D3's [number format pattern](https://github.com/d3/d3-format#locale_format).
77
+ *
78
+ * See the [format documentation](https://vega.github.io/vega-lite/docs/format.html) for more examples.
79
+ */
80
+ format?: string;
42
81
  }
43
82
 
44
- export interface ChannelDefWithScale extends ChannelDefBase {
45
- type: string;
83
+ export type StringDatumDef = DatumDef & FormatMixins;
46
84
 
85
+ export type Type = "quantitative" | "ordinal" | "nominal" | "index" | "locus";
86
+
87
+ export type TypeForShape = "ordinal" | "nominal";
88
+
89
+ export interface TypeMixins<T extends Type> {
90
+ type: T;
91
+ }
92
+
93
+ export interface FieldDefBase<F> {
47
94
  /**
48
- * Offset within a band of a band scale, [0, 1]
95
+ * __Required.__ A string defining the name of the field from which to pull a data value
96
+ * or an object defining iterated values from the [`repeat`](https://vega.github.io/vega-lite/docs/repeat.html) operator.
97
+ *
98
+ * __See also:__ [`field`](https://vega.github.io/vega-lite/docs/field.html) documentation.
49
99
  *
50
- * TODO: rename to bandPosition: https://github.com/vega/vega-lite/pull/7190
100
+ * __Notes:__
101
+ * 1) Dots (`.`) and brackets (`[` and `]`) can be used to access nested objects (e.g., `"field": "foo.bar"` and `"field": "foo['bar']"`).
102
+ * If field names contain dots or brackets but are not nested, you can use `\\` to escape dots and brackets (e.g., `"a\\.b"` and `"a\\[0\\]"`).
103
+ * See more details about escaping in the [field documentation](https://vega.github.io/vega-lite/docs/field.html).
104
+ * 2) `field` is not required if `aggregate` is `count`.
51
105
  */
52
- band?: number;
106
+ field?: F;
107
+ }
53
108
 
54
- scale?: Scale;
55
- axis?: Axis | null;
109
+ export type TypedFieldDef<
110
+ F extends Field,
111
+ T extends Type = any
112
+ > = FieldDefBase<F> & TitleMixins & TypeMixins<T>;
56
113
 
57
- format?: string;
114
+ export type ScaleFieldDef<F extends Field, T extends Type> = TypedFieldDef<
115
+ F,
116
+ T
117
+ > &
118
+ ScaleMixins;
58
119
 
120
+ export type FieldDefWithoutScale<F extends Field> = FieldDefBase<F> &
121
+ TitleMixins;
122
+
123
+ export interface ScaleMixins {
59
124
  /**
60
- * Use emulated 64 bit floating points to increase precision of scales
61
- * computed on the GPU. By default, 32 bit floats are used.
125
+ * An object defining properties of the channel's scale, which is the function that transforms values in the data domain (numbers, dates, strings, etc) to visual values (pixels, colors, sizes) of the encoding channels.
126
+ *
127
+ * If `null`, the scale will be [disabled and the data value will be directly encoded](https://vega.github.io/vega-lite/docs/scale.html#disable).
128
+ *
129
+ * __Default value:__ If undefined, default [scale properties](https://vega.github.io/vega-lite/docs/scale.html) are applied.
130
+ *
131
+ * __See also:__ [`scale`](https://vega.github.io/vega-lite/docs/scale.html) documentation.
62
132
  */
63
- fp64?: boolean;
133
+ scale?: Scale | null;
64
134
 
65
135
  /**
66
- * Use an alternative channel for scale resolution.
136
+ * An alternative channel for scale resolution.
67
137
  *
68
- * This is mainly for internal use and allows using `color` channel to resolve
69
- * `fill` and `stroke` channels under certain circumstances.
138
+ * This is mainly for internal use and allows using `color` channel to resolve `fill` and `stroke` channels under certain circumstances.
70
139
  */
71
140
  resolutionChannel?: Channel;
72
141
  }
73
142
 
74
- export interface FieldDef extends ChannelDefWithScale {
75
- field: FieldName;
143
+ export interface ValueDef<V extends Value = Scalar> {
144
+ /**
145
+ * A constant value in visual domain (e.g., `"red"` / `"#0099ff"`, values between `0` to `1` for opacity).
146
+ */
147
+ value: V;
76
148
  }
77
149
 
78
- export interface DatumDef extends ChannelDefWithScale {
79
- /** A constant value on the data domain */
80
- datum: Scalar;
150
+ export interface DatumDef extends TitleMixins {
151
+ /**
152
+ * A constant value in data domain.
153
+ */
154
+ datum?: Scalar;
81
155
  }
82
156
 
83
- export interface ExprDef extends ChannelDefWithScale {
157
+ export interface ExprDef {
84
158
  /** An expression. Properties of the data can be accessed through the `datum` object. */
85
159
  expr: string;
86
160
  }
87
- export interface ChromPosDef extends ChannelDefWithScale {
88
- type: "locus";
89
161
 
162
+ /**
163
+ * Field definition of a mark property, which can contain a legend.
164
+ */
165
+ export type MarkPropFieldDef<
166
+ F extends Field,
167
+ T extends Type = Type
168
+ > = ScaleFieldDef<F, T> & LegendMixins;
169
+
170
+ export type MarkPropExprDef<T extends Type = Type> = ExprDef &
171
+ TypeMixins<T> &
172
+ ScaleMixins;
173
+
174
+ export type MarkPropDatumDef<T extends Type> = LegendMixins &
175
+ ScaleDatumDef &
176
+ TypeMixins<T>;
177
+
178
+ export type MarkPropFieldOrDatumOrExprDef<
179
+ F extends Field,
180
+ T extends Type = Type
181
+ > = MarkPropFieldDef<F, T> | MarkPropDatumDef<T> | MarkPropExprDef;
182
+
183
+ export interface LegendMixins {
184
+ /**
185
+ * An object defining properties of the legend.
186
+ * If `null`, the legend for the encoding channel will be removed.
187
+ *
188
+ * __Default value:__ If undefined, default [legend properties](https://vega.github.io/vega-lite/docs/legend.html) are applied.
189
+ *
190
+ * __See also:__ [`legend`](https://vega.github.io/vega-lite/docs/legend.html) documentation.
191
+ */
192
+ // TODO: legend?: Legend<ExprRef | SignalRef> | null;
193
+ }
194
+
195
+ export type MarkPropDef<
196
+ F extends Field,
197
+ V extends Value,
198
+ T extends Type = Type
199
+ > = MarkPropFieldOrDatumOrExprDef<F, T> | ValueDef<V>;
200
+
201
+ export type ColorDef<F extends Field> = MarkPropDef<F, string | null>;
202
+
203
+ export type SecondaryFieldDef<F extends Field> = FieldDefBase<F> & TitleMixins;
204
+
205
+ export type NumericValueDef = ValueDef<number>;
206
+
207
+ export type ScaleDatumDef = ScaleMixins & DatumDef;
208
+
209
+ export type PositionDatumDefBase = ScaleDatumDef & TypeMixins<Type>;
210
+
211
+ export type PositionFieldDef<F extends Field> = PositionFieldDefBase<F> &
212
+ PositionMixins;
213
+
214
+ export type PositionDatumDef = PositionDatumDefBase & PositionMixins;
215
+
216
+ export type PositionExprDef = ExprDef &
217
+ PositionMixins &
218
+ BandMixins &
219
+ TypeMixins<Type>;
220
+
221
+ export type PositionValueDef = NumericValueDef;
222
+
223
+ export interface PositionMixins extends BandMixins {
224
+ /**
225
+ * An object defining properties of axis's gridlines, ticks and labels.
226
+ * If `null`, the axis for the encoding channel will be removed.
227
+ *
228
+ * __Default value:__ If undefined, default [axis properties](https://vega.github.io/vega-lite/docs/axis.html) are applied.
229
+ *
230
+ * __See also:__ [`axis`](https://vega.github.io/vega-lite/docs/axis.html) documentation.
231
+ */
232
+ axis?: Axis | null;
233
+ }
234
+
235
+ export type PositionFieldDefBase<F extends Field> = ScaleFieldDef<F, Type>;
236
+
237
+ export interface ChromPosDefBase extends BandMixins {
90
238
  /**
91
239
  * The field having the chromosome or contig.
92
240
  */
@@ -111,17 +259,169 @@ export interface ChromPosDef extends ChannelDefWithScale {
111
259
  offset?: number;
112
260
  }
113
261
 
114
- export interface FacetFieldDef extends ChannelDefBase {
115
- field: FieldName;
116
- spacing?: number;
117
- }
262
+ export type SecondaryChromPosDef = ChromPosDefBase &
263
+ TitleMixins &
264
+ PositionMixins;
265
+
266
+ export type ChromPosDef = SecondaryChromPosDef &
267
+ TypeMixins<"locus"> &
268
+ ScaleMixins;
118
269
 
119
- export type ChannelDef =
120
- | FieldDef
121
- | DatumDef
122
- | ValueDef
123
- | ExprDef
270
+ export type PositionDef<F extends Field> =
271
+ | PositionFieldDef<F>
124
272
  | ChromPosDef
125
- | FacetFieldDef;
273
+ | PositionDatumDef
274
+ | PositionExprDef
275
+ | PositionValueDef;
276
+
277
+ export type Position2Def<F extends Field> =
278
+ | (SecondaryFieldDef<F> & BandMixins)
279
+ | SecondaryChromPosDef
280
+ | (DatumDef & BandMixins)
281
+ | (ExprDef & BandMixins)
282
+ | PositionValueDef;
283
+
284
+ export type NumericMarkPropDef<F extends Field> = MarkPropDef<F, number>;
285
+
286
+ export type ShapeDef<F extends Field> = MarkPropDef<
287
+ F,
288
+ string | null,
289
+ TypeForShape
290
+ >;
291
+
292
+ export interface StringFieldDef<F extends Field>
293
+ extends FieldDefWithoutScale<F>,
294
+ FormatMixins {}
126
295
 
127
- export type Encoding = Partial<Record<Channel, ChannelDef | null>>;
296
+ export type TextDef<F extends Field> = StringFieldDef<F> | StringDatumDef;
297
+
298
+ export type ChannelDef<F extends Field = string> =
299
+ Encoding<F>[keyof Encoding<F>];
300
+
301
+ // TODO: Does this make sense?
302
+ export type ChannelDefWithScale = ScaleMixins & TypeMixins<Type>;
303
+
304
+ export interface Encoding<F extends Field = string> {
305
+ /**
306
+ * X coordinates of the marks.
307
+ *
308
+ * The `value` of this channel can be a number between zero and one.
309
+ */
310
+ x?: PositionDef<F>;
311
+
312
+ /**
313
+ * Y coordinates of the marks.
314
+ *
315
+ * The `value` of this channel can be a number between zero and one.
316
+ */
317
+ y?: PositionDef<F>;
318
+
319
+ /**
320
+ * X2 coordinates of the marks.
321
+ *
322
+ * The `value` of this channel can be a number between zero and one.
323
+ */
324
+ x2?: Position2Def<F>;
325
+
326
+ /**
327
+ * Y2 coordinates of the marks.
328
+ *
329
+ * The `value` of this channel can be a number between zero and one.
330
+ */
331
+ y2?: Position2Def<F>;
332
+
333
+ dx?: NumericMarkPropDef<F>;
334
+ dy?: NumericMarkPropDef<F>;
335
+
336
+ /**
337
+ * Color of the marks – either fill or stroke color based on the `filled` property of mark definition.
338
+ *
339
+ * _Note:_
340
+ * 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. The `fill` or `stroke` encodings have higher precedence than `color`, thus may override the `color` encoding if conflicting encodings are specified.
341
+ * 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme).
342
+ */
343
+ color?: ColorDef<F>;
344
+
345
+ /**
346
+ * Fill color of the marks.
347
+ *
348
+ * _Note:_ The `fill` encoding has higher precedence than `color`, thus may override the `color` encoding if conflicting encodings are specified.
349
+ */
350
+ fill?: ColorDef<F>;
351
+
352
+ /**
353
+ * Stroke color of the marks.
354
+ *
355
+ * _Note:_ The `stroke` encoding has higher precedence than `color`, thus may override the `color` encoding if conflicting encodings are specified.
356
+ */
357
+
358
+ stroke?: ColorDef<F>;
359
+
360
+ /**
361
+ * Opacity of the marks.
362
+ */
363
+ opacity?: NumericMarkPropDef<F>;
364
+
365
+ /**
366
+ * Fill opacity of the marks.
367
+ */
368
+ fillOpacity?: NumericMarkPropDef<F>;
369
+
370
+ /**
371
+ * Stroke opacity of the marks.
372
+ */
373
+ strokeOpacity?: NumericMarkPropDef<F>;
374
+
375
+ /**
376
+ * Stroke width of the marks.
377
+ */
378
+ strokeWidth?: NumericMarkPropDef<F>;
379
+
380
+ /**
381
+ * Size of the mark.
382
+ * - For `"point"` – the symbol size, or pixel area of the mark.
383
+ * - For `"text"` – the text's font size.
384
+ */
385
+ size?: NumericMarkPropDef<F>;
386
+
387
+ /**
388
+ * Rotation angle of point and text marks.
389
+ */
390
+ angle?: NumericMarkPropDef<F>;
391
+
392
+ /**
393
+ * Shape of the mark.
394
+ *
395
+ * For `point` marks the supported values include:
396
+ * - plotting shapes: `"circle"`, `"square"`, `"cross"`, `"diamond"`, `"triangle-up"`, `"triangle-down"`, `"triangle-right"`, or `"triangle-left"`.
397
+ * - centered directional shape `"triangle"`
398
+ */
399
+ shape?: ShapeDef<F>;
400
+
401
+ /**
402
+ * Text of the `text` mark.
403
+ */
404
+ text?: TextDef<F>;
405
+
406
+ /**
407
+ * Facet identifier for interactive filtering, sorting, and grouping in the App.
408
+ */
409
+ sample?: FieldDefWithoutScale<F>;
410
+
411
+ /**
412
+ * For internal use
413
+ */
414
+ // TODO: proper type
415
+ uniqueId?: FieldDefWithoutScale<F>;
416
+
417
+ // TODO: proper type
418
+ search?: FieldDefWithoutScale<F>;
419
+
420
+ /**
421
+ * For internal use
422
+ */
423
+ // TODO: proper type
424
+ facetIndex?: FieldDefWithoutScale<F>;
425
+
426
+ semanticScore?: FieldDefWithoutScale<F>;
427
+ }
@@ -42,7 +42,7 @@ export interface DataFormatBase {
42
42
  * __Default value:__ The default format type is determined by the extension of the file URL.
43
43
  * If no extension is detected, `"json"` will be used by default.
44
44
  */
45
- type?: "csv" | "tsv" | "dsv" | "json";
45
+ type?: DataFormatType;
46
46
  }
47
47
 
48
48
  export interface CsvDataFormat extends DataFormatBase {
@@ -73,9 +73,20 @@ export interface JsonDataFormat extends DataFormatBase {
73
73
  property?: string;
74
74
  }
75
75
 
76
- export type DataFormat = CsvDataFormat | DsvDataFormat | JsonDataFormat;
76
+ /**
77
+ * Other data format, such as `"fasta"`
78
+ */
79
+ export interface OtherDataFormat {
80
+ type: string;
81
+ }
82
+
83
+ export type DataFormat =
84
+ | CsvDataFormat
85
+ | DsvDataFormat
86
+ | JsonDataFormat
87
+ | OtherDataFormat;
77
88
 
78
- export type DataFormatType = "json" | "csv" | "tsv" | "dsv";
89
+ export type DataFormatType = "json" | "csv" | "tsv" | "dsv" | string;
79
90
 
80
91
  export type DataSource =
81
92
  | UrlData