@genome-spy/core 0.61.1 → 0.62.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.
package/dist/schema.json CHANGED
@@ -2510,6 +2510,10 @@
2510
2510
  "FilterScoredLabelsParams": {
2511
2511
  "additionalProperties": false,
2512
2512
  "properties": {
2513
+ "asMidpoint": {
2514
+ "description": "Outputs the average of pos and pos2 as the midpoint of the element. This is useful for elements that have a width, such as transcripts. The midpoint is clamped to the visible region of the element.",
2515
+ "type": "string"
2516
+ },
2513
2517
  "channel": {
2514
2518
  "description": "**Default:** `\"x\"`",
2515
2519
  "enum": [
@@ -2520,7 +2524,7 @@
2520
2524
  },
2521
2525
  "lane": {
2522
2526
  "$ref": "#/definitions/Field",
2523
- "description": "An optional field representing element's lane, e.g., if transcripts are shown using a piled up layout."
2527
+ "description": "An optional field representing element's lane, e.g., if transcripts are shown using a piled up layout. Each line is processed separately."
2524
2528
  },
2525
2529
  "padding": {
2526
2530
  "description": "Padding (in pixels) around the element.\n\n**Default:** `0`",
@@ -2528,7 +2532,11 @@
2528
2532
  },
2529
2533
  "pos": {
2530
2534
  "$ref": "#/definitions/Field",
2531
- "description": "The field representing element's position on the domain."
2535
+ "description": "The field representing element's start position on the domain."
2536
+ },
2537
+ "pos2": {
2538
+ "$ref": "#/definitions/Field",
2539
+ "description": "The field representing element's end position on the domain. If not specified, the `pos` field is used."
2532
2540
  },
2533
2541
  "score": {
2534
2542
  "$ref": "#/definitions/Field",
@@ -2541,7 +2549,7 @@
2541
2549
  },
2542
2550
  "width": {
2543
2551
  "$ref": "#/definitions/Field",
2544
- "description": "The field representing element's width in pixels"
2552
+ "description": "The field representing element's width in pixels."
2545
2553
  }
2546
2554
  },
2547
2555
  "required": [
@@ -4554,7 +4562,14 @@
4554
4562
  "$ref": "#/definitions/Field"
4555
4563
  },
4556
4564
  "fontSize": {
4557
- "type": "number"
4565
+ "anyOf": [
4566
+ {
4567
+ "type": "number"
4568
+ },
4569
+ {
4570
+ "$ref": "#/definitions/ExprRef"
4571
+ }
4572
+ ]
4558
4573
  },
4559
4574
  "type": {
4560
4575
  "const": "measureText",
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/data/collector.js"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH;IAkCI;;OAEG;IACH,qBAFW,OAAO,sBAAsB,EAAE,aAAa,EAetD;IAVG,qDAA2C;IAE3C,2CAA2C;IAC3C,WADW,CAAC,CAAS,IAAS,EAAT,SAAS,KAAE,IAAI,CAAC,EAAE,CACpB;IAGnB,yFAAyF;IACzF,cADW,GAAG,CAAC,OAAO,oBAAoB,EAAE,MAAM,EAAE,+BAAO,CACN;IAwHzD;;OAEG;IACH,WAFa,QAAQ,+BAAO,CAqB3B;IAED;;;OAGG;IACH,mBAFW,CAAC,KAAK,+BAAO,KAAK,IAAI,QAUhC;IAED;;OAEG;IACH,uBAMC;IA8CD;;;;OAIG;IACH,8BAFW,MAAM,iCA4BhB;;CACJ;qBAhTyD,eAAe"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/data/collector.js"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH;IAuCI;;OAEG;IACH,qBAFW,OAAO,sBAAsB,EAAE,aAAa,EAiBtD;IAZG,qDAA2C;IAE3C,2CAA2C;IAC3C,WADW,CAAC,CAAS,IAAS,EAAT,SAAS,KAAE,IAAI,CAAC,EAAE,CACpB;IAGnB,yFAAyF;IACzF,cADW,GAAG,CAAC,OAAO,oBAAoB,EAAE,MAAM,EAAE,+BAAO,CACN;IAgHzD;;OAEG;IACH,WAFa,QAAQ,+BAAO,CAqB3B;IAED;;;OAGG;IACH,mBAFW,CAAC,KAAK,+BAAO,KAAK,IAAI,QAUhC;IAED;;OAEG;IACH,uBAMC;IA8CD;;;;OAIG;IACH,8BAFW,MAAM,iCA4BhB;;CACJ;qBA7SyD,eAAe"}
@@ -40,6 +40,11 @@ export default class Collector extends FlowNode {
40
40
  */
41
41
  #facetIndices;
42
42
 
43
+ /**
44
+ * @type {(a: Datum, b: Datum) => number}
45
+ */
46
+ #comparator;
47
+
43
48
  get behavior() {
44
49
  return BEHAVIOR_COLLECTS;
45
50
  }
@@ -63,6 +68,8 @@ export default class Collector extends FlowNode {
63
68
  /** @type {Map<import("../spec/channel.js").Scalar[], Data>} TODO: proper type for key */
64
69
  this.facetBatches = new InternMap([], JSON.stringify);
65
70
 
71
+ this.#comparator = makeComparator(this.params?.sort);
72
+
66
73
  this.#init();
67
74
  }
68
75
 
@@ -100,18 +107,6 @@ export default class Collector extends FlowNode {
100
107
  // Free some memory
101
108
  this.#buffer = [];
102
109
 
103
- const sort = this.params?.sort;
104
- // Vega's "compare" function is incredibly slow (uses megamorphic field accessor)
105
- // TODO: Implement a replacement for static data types
106
- const comparator = sort ? compare(sort.field, sort.order) : undefined;
107
-
108
- /** @param {any[]} data */
109
- const sortData = (data) => {
110
- if (comparator) {
111
- data.sort(comparator);
112
- }
113
- };
114
-
115
110
  if (this.params.groupby?.length) {
116
111
  if (this.facetBatches.size > 1) {
117
112
  throw new Error("TODO: Support faceted data!");
@@ -137,9 +132,11 @@ export default class Collector extends FlowNode {
137
132
  }
138
133
  }
139
134
 
140
- for (const data of this.facetBatches.values()) {
141
- // TODO: Only sort if not already sorted
142
- sortData(data);
135
+ if (this.#comparator) {
136
+ for (const data of this.facetBatches.values()) {
137
+ // TODO: Only sort if not already sorted
138
+ data.sort(this.#comparator);
139
+ }
143
140
  }
144
141
 
145
142
  this.#buildUniqueIdIndex();
@@ -329,3 +326,31 @@ function groupBy(data, accessor) {
329
326
  }
330
327
  return groups;
331
328
  }
329
+
330
+ /**
331
+ * Creates a comparator function based on the provided sort parameters.
332
+ *
333
+ * @param {import("../spec/transform.js").CompareParams} sort
334
+ * @returns {(a: Datum, b: Datum) => number}
335
+ */
336
+ function makeComparator(sort) {
337
+ // For simple cases, create a simple comparator.
338
+ // For more complex cases, use Vega's compare function. However,
339
+ // is uses megamorphic field accessors, which makes it slow.
340
+ if (sort?.field) {
341
+ const fields = asArray(sort.field);
342
+ if (fields.length == 1 && !fields[0].includes(".")) {
343
+ const order = asArray(sort.order)[0] ?? "ascending";
344
+ const fieldName = JSON.stringify(fields[0]);
345
+ return /** @type {(a: Datum, b: Datum) => number} */ (
346
+ new Function(
347
+ "a",
348
+ "b",
349
+ `return a[${fieldName}] ${order === "ascending" ? "-" : "+"} b[${fieldName}];`
350
+ )
351
+ );
352
+ }
353
+
354
+ return compare(sort.field, sort.order);
355
+ }
356
+ }
@@ -9,8 +9,10 @@ export default class FilterScoredLabelsTransform extends Transform {
9
9
  /** @type {any[]} */
10
10
  _data: any[];
11
11
  channel: "x" | "y";
12
- posAccessor: import("vega-util").AccessorFn<any>;
13
- posBisector: import("d3-array").Bisector<any, any>;
12
+ startPosAccessor: import("vega-util").AccessorFn<any>;
13
+ endPosAccessor: import("vega-util").AccessorFn<any>;
14
+ startPosBisector: import("d3-array").Bisector<any, any>;
15
+ endPosBisector: import("d3-array").Bisector<any, any>;
14
16
  scoreAccessor: import("vega-util").AccessorFn<any>;
15
17
  widthAccessor: import("vega-util").AccessorFn<any>;
16
18
  /** @type {function(any):any} */
@@ -20,7 +22,6 @@ export default class FilterScoredLabelsTransform extends Transform {
20
22
  reservationMaps: Map<any, ReservationMap>;
21
23
  resolution: import("../../view/scaleResolution.js").default;
22
24
  schedule: () => void;
23
- _scores: any[];
24
25
  _filterAndPropagate(): void;
25
26
  groups: Map<any, any>;
26
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"filterScoredLabels.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/filterScoredLabels.js"],"names":[],"mappings":"AAOA;IAKI;;;;OAIG;IACH,oBAHW,OAAO,yBAAyB,EAAE,wBAAwB,QAC1D,OAAO,oBAAoB,EAAE,OAAO,EA2C9C;IAtCG,mEAAoB;IAEpB,oBAAoB;IACpB,OADW,GAAG,EAAE,CACD;IAEf,mBAAoC;IAMpC,iDAAyC;IACzC,mDAA6C;IAC7C,mDAA6C;IAC7C,mDAA6C;IAC7C,gCAAgC;IAChC,cADW,CAAS,IAAG,EAAH,GAAG,KAAE,GAAG,CAGd;IACd,gBAAuC;IAEvC,uCAAuC;IACvC,iBADW,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CACH;IAEhC,4DAAuD;IAIvD,qBAAuE;IAgBvE,eAAiD;IAWrD,4BAyCC;IAKG,sBAAuB;CAU9B;sBA9HqB,gBAAgB;2BAFX,+BAA+B"}
1
+ {"version":3,"file":"filterScoredLabels.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/filterScoredLabels.js"],"names":[],"mappings":"AAOA;IAKI;;;;OAIG;IACH,oBAHW,OAAO,yBAAyB,EAAE,wBAAwB,QAC1D,OAAO,oBAAoB,EAAE,OAAO,EA6C9C;IAxCG,mEAAoB;IAEpB,oBAAoB;IACpB,OADW,GAAG,EAAE,CACD;IAEf,mBAAoC;IAMpC,sDAA8C;IAC9C,oDAAgE;IAChE,wDAAuD;IACvD,sDAAmD;IACnD,mDAA6C;IAC7C,mDAA6C;IAC7C,gCAAgC;IAChC,cADW,CAAS,IAAG,EAAH,GAAG,KAAE,GAAG,CAGd;IACd,gBAAuC;IAEvC,uCAAuC;IACvC,iBADW,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CACH;IAEhC,4DAAuD;IAIvD,qBAAuE;IAyB3E,4BAsEC;IAKG,sBAAuB;CAU9B;sBA3JqB,gBAAgB;2BAFX,+BAA+B"}
@@ -1,6 +1,6 @@
1
1
  import { bisector } from "d3-array";
2
2
  import { BEHAVIOR_COLLECTS } from "../flowNode.js";
3
- import { topKSlice } from "../../utils/topK.js";
3
+ import { topK } from "../../utils/topK.js";
4
4
  import ReservationMap from "../../utils/reservationMap.js";
5
5
  import { field } from "../../utils/field.js";
6
6
  import Transform from "./transform.js";
@@ -29,8 +29,10 @@ export default class FilterScoredLabelsTransform extends Transform {
29
29
  throw new Error("Invalid channel: " + this.channel);
30
30
  }
31
31
 
32
- this.posAccessor = field(this.params.pos);
33
- this.posBisector = bisector(this.posAccessor);
32
+ this.startPosAccessor = field(this.params.pos);
33
+ this.endPosAccessor = field(this.params.pos2 ?? this.params.pos);
34
+ this.startPosBisector = bisector(this.startPosAccessor);
35
+ this.endPosBisector = bisector(this.endPosAccessor);
34
36
  this.scoreAccessor = field(this.params.score);
35
37
  this.widthAccessor = field(this.params.width);
36
38
  /** @type {function(any):any} */
@@ -59,10 +61,8 @@ export default class FilterScoredLabelsTransform extends Transform {
59
61
  }
60
62
 
61
63
  complete() {
62
- const posAccessor = this.posAccessor;
63
- this._data.sort((a, b) => posAccessor(a) - posAccessor(b));
64
-
65
- this._scores = this._data.map(this.scoreAccessor);
64
+ const startPosAccessor = this.startPosAccessor;
65
+ this._data.sort((a, b) => startPosAccessor(a) - startPosAccessor(b));
66
66
 
67
67
  for (const lane of new Set(this._data.map(this.laneAccessor))) {
68
68
  this.reservationMaps.set(lane, new ReservationMap(200));
@@ -91,25 +91,54 @@ export default class FilterScoredLabelsTransform extends Transform {
91
91
  const k = 70; // TODO: Configurable
92
92
 
93
93
  // Find the maximum of k elements from the visible domain in priority order
94
- const topIndices = topKSlice(
95
- this._scores,
94
+ const topElements = topK(
95
+ this._data,
96
96
  k,
97
- this.posBisector.left(this._data, domain[0]),
98
- this.posBisector.right(this._data, domain[1])
97
+ this.scoreAccessor,
98
+ this.endPosBisector.left(this._data, domain[0]),
99
+ this.startPosBisector.right(this._data, domain[1])
99
100
  );
100
101
 
101
102
  // Try to fit the elements on the available lanes and propagate if there was room
102
- for (const i of topIndices) {
103
- const datum = this._data[i];
104
- const pos = scale(this.posAccessor(datum)) * rangeSpan;
105
- const halfWidth = this.widthAccessor(datum) / 2 + this.padding;
103
+ for (const datum of topElements) {
104
+ let startPos = scale(this.startPosAccessor(datum)) * rangeSpan;
105
+ let endPos = scale(this.endPosAccessor(datum)) * rangeSpan;
106
+
107
+ const span = endPos - startPos;
108
+ const width = this.widthAccessor(datum) + this.padding * 2;
109
+
110
+ let midpoint = (startPos + endPos) / 2;
111
+
112
+ // How much extra space we have for adjusting the position so that the
113
+ // text stays inside the range.
114
+ const extra = Math.max(0.0, (span - width) / 2.0);
115
+ if (extra > 0.0) {
116
+ const leftOver = Math.max(0.0, width / 2 - midpoint);
117
+ midpoint += Math.min(leftOver, extra);
118
+
119
+ const rightOver = Math.max(
120
+ 0.0,
121
+ width / 2 + midpoint - rangeSpan
122
+ );
123
+ midpoint -= Math.min(rightOver, extra);
124
+ }
106
125
 
107
126
  if (
108
127
  this.reservationMaps
109
128
  .get(this.laneAccessor(datum))
110
- .reserve(pos - halfWidth, pos + halfWidth)
129
+ .reserve(midpoint - width / 2, midpoint + width / 2)
111
130
  ) {
112
- this._propagate(datum);
131
+ if (this.params.asMidpoint) {
132
+ // Clone the datum to avoid side effects
133
+ const clonedDatum = Object.assign({}, datum);
134
+ // @ts-ignore
135
+ clonedDatum[this.params.asMidpoint] = scale.invert(
136
+ midpoint / rangeSpan
137
+ );
138
+ this._propagate(clonedDatum);
139
+ } else {
140
+ this._propagate(datum);
141
+ }
113
142
  }
114
143
  }
115
144
 
@@ -1,13 +1,13 @@
1
1
  /**
2
- * Measures text length. This is mainly intended for reading-direction arrows
3
- * in gene annotations.
2
+ * Measures text length. This is mainly intended for strand arrows in gene annotations.
4
3
  */
5
4
  export default class MeasureTextTransform extends Transform {
6
5
  /**
7
6
  *
8
7
  * @param {import("../../spec/transform.js").MeasureTextParams} params
8
+ * @param {import("../flowNode.js").ParamMediatorProvider} paramMediatorProvider
9
9
  */
10
- constructor(params: import("../../spec/transform.js").MeasureTextParams);
10
+ constructor(params: import("../../spec/transform.js").MeasureTextParams, paramMediatorProvider: import("../flowNode.js").ParamMediatorProvider);
11
11
  params: import("../../spec/transform.js").MeasureTextParams;
12
12
  /**
13
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"measureText.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/measureText.js"],"names":[],"mappings":"AAMA;;;GAGG;AACH;IAKI;;;OAGG;IACH,oBAFW,OAAO,yBAAyB,EAAE,iBAAiB,EA0B7D;IArBG,4DAAoB;IAQpB;;;OAGG;IACH,gBAFW,GAAG,UAUb;CAER;sBAxCqB,gBAAgB"}
1
+ {"version":3,"file":"measureText.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/measureText.js"],"names":[],"mappings":"AAOA;;GAEG;AACH;IAKI;;;;OAIG;IACH,oBAHW,OAAO,yBAAyB,EAAE,iBAAiB,yBACnD,OAAO,gBAAgB,EAAE,qBAAqB,EA0CxD;IArCG,4DAAoB;IAwBpB;;;OAGG;IACH,gBAFW,GAAG,UAUb;CAER;sBAzDqB,gBAAgB"}
@@ -3,10 +3,10 @@ import fontMetadata from "../../fonts/Lato-Regular.json" with { type: "json" };
3
3
  import getMetrics from "../../fonts/bmFontMetrics.js";
4
4
  import { field } from "../../utils/field.js";
5
5
  import Transform from "./transform.js";
6
+ import { isExprRef } from "../../view/paramMediator.js";
6
7
 
7
8
  /**
8
- * Measures text length. This is mainly intended for reading-direction arrows
9
- * in gene annotations.
9
+ * Measures text length. This is mainly intended for strand arrows in gene annotations.
10
10
  */
11
11
  export default class MeasureTextTransform extends Transform {
12
12
  get behavior() {
@@ -16,8 +16,9 @@ export default class MeasureTextTransform extends Transform {
16
16
  /**
17
17
  *
18
18
  * @param {import("../../spec/transform.js").MeasureTextParams} params
19
+ * @param {import("../flowNode.js").ParamMediatorProvider} paramMediatorProvider
19
20
  */
20
- constructor(params) {
21
+ constructor(params, paramMediatorProvider) {
21
22
  super(params);
22
23
 
23
24
  this.params = params;
@@ -26,7 +27,23 @@ export default class MeasureTextTransform extends Transform {
26
27
  const accessor = field(params.field);
27
28
  const as = params.as;
28
29
  // TODO: Support custom fonts.
29
- const size = params.fontSize;
30
+
31
+ let size = 0;
32
+
33
+ // TODO: Refactor this into reusable code.
34
+ if (isExprRef(params.fontSize)) {
35
+ const sizeExpr =
36
+ paramMediatorProvider.paramMediator.createExpression(
37
+ params.fontSize.expr
38
+ );
39
+ size = sizeExpr();
40
+ sizeExpr.addListener(() => {
41
+ size = sizeExpr();
42
+ this.repropagate();
43
+ });
44
+ } else {
45
+ size = params.fontSize;
46
+ }
30
47
 
31
48
  /**
32
49
  *
@@ -1 +1 @@
1
- {"version":3,"file":"arrayBuilder.d.ts","sourceRoot":"","sources":["../../../src/gl/arrayBuilder.js"],"names":[],"mappings":"AASA;;;;;;;;GAQG;AACH;IAKI;;;OAGG;IACH,kBAFW,MAAM,EAehB;IAZG,aAAgB;IAEhB,mJAAmJ;IACnJ;;kBADkC,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY;2BAAiB,MAAM;sBAAY,MAAM;;MAC7H;IAEhB,kCAAkC;IAClC,SADW,CAAC,MAAW,IAAI,CAAC,EAAE,CACb;IAEjB,qCAAqC;IACrC,cADW,CAAC,CAAS,IAAG,EAAH,GAAG,KAAE,IAAI,CAAC,EAAE,CACX;IAEtB,oBAAoB;IAGxB,kBAOC;IAED;;;;OAIG;IACH,wBAHW,MAAM,YACN,iBAAiB,QAe3B;IAED;;;;;;;OAOG;IACH,6BANW,MAAM,iBACN,MAAM,oBACN,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,YAAY,mBACrG,MAAM,EAAE,GACP,CAAS,IAAe,EAAf,MAAM,GAAC,MAAM,EAAE,QAAC,CAoFpC;IAED,gBAEC;IAED;;OAEG;IACH,uBAFW,MAAM,QAIhB;IAuDD;;;OAGG;IACH,qBAFW,MAAM,QAKhB;;CACJ;;;;;;;;;OA9NS,CAAS,IAAM,EAAN,MAAM,KAAE,GAAG;;;;qBACpB,MAAM,EAAE;oBACR,MAAM;;;;sBACN,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,YAAY"}
1
+ {"version":3,"file":"arrayBuilder.d.ts","sourceRoot":"","sources":["../../../src/gl/arrayBuilder.js"],"names":[],"mappings":"AAQA;;;;;;;;GAQG;AACH;IAKI;;;OAGG;IACH,kBAFW,MAAM,EAehB;IAZG,aAAgB;IAEhB,mJAAmJ;IACnJ;;kBADkC,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY;2BAAiB,MAAM;sBAAY,MAAM;;MAC7H;IAEhB,kCAAkC;IAClC,SADW,CAAC,MAAW,IAAI,CAAC,EAAE,CACb;IAEjB,qCAAqC;IACrC,cADW,CAAC,CAAS,IAAG,EAAH,GAAG,KAAE,IAAI,CAAC,EAAE,CACX;IAEtB,oBAAoB;IAGxB,kBAOC;IAED;;;;OAIG;IACH,wBAHW,MAAM,YACN,iBAAiB,QAe3B;IAED;;;;;;;OAOG;IACH,6BANW,MAAM,iBACN,MAAM,oBACN,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,YAAY,mBACrG,MAAM,EAAE,GACP,CAAS,IAAe,EAAf,MAAM,GAAC,MAAM,EAAE,QAAC,CAoFpC;IAED,gBAEC;IAED;;OAEG;IACH,uBAFW,MAAM,QAIhB;IAuDD;;;OAGG;IACH,qBAFW,MAAM,QAKhB;;CACJ;;;;;;;;;OA9NS,CAAS,IAAM,EAAN,MAAM,KAAE,GAAG;;;;qBACpB,MAAM,EAAE;oBACR,MAAM;;;;sBACN,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,WAAW,GAAG,OAAO,UAAU,GAAG,OAAO,YAAY"}
@@ -1,5 +1,4 @@
1
1
  import { isNumber } from "vega-util";
2
- import { ATTRIBUTE_PREFIX } from "./glslScaleGenerator.js";
3
2
 
4
3
  /** Unrolling appears to give a 20% performance boost on Chrome but compiling the
5
4
  * dynamically generated code takes time and is thus not great for small dynamic data.
@@ -56,7 +55,7 @@ export default class ArrayBuilder {
56
55
  */
57
56
  addConverter(attribute, metadata) {
58
57
  const updater = this.createUpdater(
59
- ATTRIBUTE_PREFIX + attribute,
58
+ attribute,
60
59
  metadata.numComponents || 1,
61
60
  metadata.targetArrayType ?? Float32Array,
62
61
  metadata.arrayReference
@@ -1 +1 @@
1
- {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH,mDALG;QAAsE,QAAQ,EAAtE,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,wCAAU;QACnC,UAAU,GAA5B,MAAM,EAAE;QACQ,WAAW,GAA3B,MAAM;KAEhB,EAuFA;IArFG,8FAAwB;IAIxB,sGAQK;IAQL,0BAAoC;IAEpC,8BAAoD;IA2DpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCAYlB;IAED;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,IAAI,OAClC,MAAM,OACN,MAAM,QAgEhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IAhEO;;;MAAyB;IAkEjC;QAEQ,kJAAkJ;gBAAvI,MAAM,CAAC,MAAM,EAAE;YAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAE9I,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EA8BA;IAnBG,qBAkBW;CA8BlB;AAED;IACI;;;;;;;;;OASG;IACH,sFAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,qBAAqB,GAArC,MAAM;QAEY,YAAY,GAA9B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAuBA;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA6CpE;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CACJ;AAED;IACI;;;;;OAKG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH,+EAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACkD,WAAW,EAArE,OAAO,2BAA2B,EAAE,aAAa;QACrB,UAAU,EAAtC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;QACH,aAAa,GAA7B,MAAM;QACW,WAAW,GAA5B,OAAO;KAAsB,EA6CvC;IA9BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAO5B,qCAAqC;IACrC,cADW,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CAgJxE;;;;;;;;YAnnBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAjBzB,mBAAmB"}
1
+ {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH,mDALG;QAAsE,QAAQ,EAAtE,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,wCAAU;QACnC,UAAU,GAA5B,MAAM,EAAE;QACQ,WAAW,GAA3B,MAAM;KAEhB,EAqFA;IAnFG,8FAAwB;IAIxB,sGAQK;IAQL,0BAAoC;IAEpC,8BAAoD;IAyDpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCAYlB;IAED;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,IAAI,OAClC,MAAM,OACN,MAAM,QAgEhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IAhEO;;;MAAyB;IAkEjC;QAEQ,kJAAkJ;gBAAvI,MAAM,CAAC,MAAM,EAAE;YAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAE9I,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EA8BA;IAnBG,qBAkBW;CA8BlB;AAED;IACI;;;;;;;;;OASG;IACH,sFAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,qBAAqB,GAArC,MAAM;QAEY,YAAY,GAA9B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAuBA;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA6CpE;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CACJ;AAED;IACI;;;;;OAKG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH,+EAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACkD,WAAW,EAArE,OAAO,2BAA2B,EAAE,aAAa;QACrB,UAAU,EAAtC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;QACH,aAAa,GAA7B,MAAM;QACW,WAAW,GAA5B,OAAO;KAAsB,EA6CvC;IA9BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAO5B,qCAAqC;IACrC,cADW,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CAgJxE;;;;;;;;YAjnBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAjBzB,mBAAmB"}
@@ -103,9 +103,7 @@ export class GeometryBuilder {
103
103
  splitLargeHighPrecision(numberAccessor(d), largeHpArray)
104
104
  : numberAccessor;
105
105
 
106
- const attributeName = sharedChannels
107
- ? makeAttributeName(sharedChannels)
108
- : channel;
106
+ const attributeName = makeAttributeName(sharedChannels ?? channel);
109
107
 
110
108
  this.variableBuilder.addConverter(attributeName, {
111
109
  f,
@@ -1 +1 @@
1
- {"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":"AAsDA;;;;;GAKG;AACH,kDAJW,OAAO,mBACP,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,mDALW,OAAO,mBACP,MAAM,SACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,GAClC,aAAa,CA4CzB;AAED;;;;;;;GAOG;AACH,4DAJW,OAAO,mBACP,MAAM,GACJ,aAAa,CAkCzB;AAED;;;;;;GAMG;AACH,0CANW,OAAO,SACP,GAAG,mBACH,MAAM,+BACN,OAAO,EAAE,GACP,aAAa,CA+BzB;AACD;;;;;GAKG;AACH,qDALW,OAAO,SACP,GAAG,mBACH,MAAM,GACJ,aAAa,CAyBzB;AAED;;;;;GAKG;AAEH,2CALW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU;;;;;;EAwQjD;AAED;;;;GAIG;AACH,wDAHW,OAAO,aACP,OAAO,qBAAqB,EAAE,QAAQ,EAAE,UA+BlD;AAmED;;GAEG;AACH,qDAFW,OAAO,6BAQjB;AAuCD;;;;GAIG;AACH,iDAHW,OAAO,qBAAqB,EAAE,SAAS,WACvC,OAAO,oBAAoB,EAAE,OAAO;mBAQjB,MAAM;sBAAoB,sBAAsB,GAAG,sBAAsB,GAAG,uBAAuB;;;;;;EAkBhI;AAED;;;;GAIG;AACH,2CAFW,MAAM,6BAIhB;AAED;;;;GAIG;AACH,sCAFW,MAAM,EAAE,WAIlB;AAMD;;;GAGG;AACH,sCAHW,MAAM,QACN,MAAM,EAAE,YAYlB;AAED;;;GAGG;AACH,2CAHW,MAAM,QACN,MAAM,EAAE,YAUlB;AAYD;;GAEG;AACH,qDAFW,MAAM,EAAE,YAIlB;AAED;;GAEG;AAEH;;;;;GAKG;AACH,+CAFW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAAC,+DA4BtG;AAED;;GAEG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,GAAG,OAAO,oBAAoB,EAAE,OAAO,EAAE,UAIvF;AAwBD;;;;GAIG;AACH,uCAJW,MAAM,EAAE,cACR,MAAM,EAAE,GACN,MAAM,CAgClB;AAt0BD,+BAAgC,OAAO,CAAC;AACxC,4BAA6B,UAAU,CAAC;AACxC,2BAA4B,QAAQ,CAAC;AACrC,uCAAwC,WAAW,CAAC;AACpD,oCAAqC,QAAQ,CAAC;AAC9C,qCAAsC,YAAY,CAAC;AACnD,mCAAoC,gBAAgB,CAAC;AACrD,2BAA4B,SAAS,CAAC;AACtC,uCAAwC,iBAAiB,CAAC;AAmxBnD,uCAJI,GAAG,WACH,OAAO,GACL,MAAM,EAAE,CAQA;sBAnxBR,OAAO,oBAAoB,EAAE,OAAO;;aA+BvC,OAAO;kBACP,MAAM;0BACN,MAAM;oBACN,MAAM;oBACN,MAAM;kBACN,MAAM;kBACN,MAAM;eACN,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG;;;;;8BAqfZ,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBAwLhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BAtuBJ,WAAW"}
1
+ {"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":"AAsDA;;;;;GAKG;AACH,kDAJW,OAAO,mBACP,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,mDALW,OAAO,mBACP,MAAM,SACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,GAClC,aAAa,CA4CzB;AAED;;;;;;;GAOG;AACH,4DAJW,OAAO,mBACP,MAAM,GACJ,aAAa,CAkCzB;AAED;;;;;;GAMG;AACH,0CANW,OAAO,SACP,GAAG,mBACH,MAAM,+BACN,OAAO,EAAE,GACP,aAAa,CA8BzB;AACD;;;;;GAKG;AACH,qDALW,OAAO,SACP,GAAG,mBACH,MAAM,GACJ,aAAa,CAyBzB;AAED;;;;;GAKG;AAEH,2CALW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU;;;;;;EAwQjD;AAED;;;;GAIG;AACH,wDAHW,OAAO,aACP,OAAO,qBAAqB,EAAE,QAAQ,EAAE,UA+BlD;AAmED;;GAEG;AACH,qDAFW,OAAO,6BAQjB;AAuCD;;;;GAIG;AACH,iDAHW,OAAO,qBAAqB,EAAE,SAAS,WACvC,OAAO,oBAAoB,EAAE,OAAO;mBAQjB,MAAM;sBAAoB,sBAAsB,GAAG,sBAAsB,GAAG,uBAAuB;;;;;;EAkBhI;AAED;;;;GAIG;AACH,2CAFW,MAAM,6BAIhB;AAED;;;;GAIG;AACH,sCAFW,MAAM,EAAE,WAIlB;AAMD;;;GAGG;AACH,sCAHW,MAAM,QACN,MAAM,EAAE,YAYlB;AAED;;;GAGG;AACH,2CAHW,MAAM,QACN,MAAM,EAAE,YAUlB;AAYD;;GAEG;AACH,qDAFW,MAAM,EAAE,YAIlB;AAED;;GAEG;AAEH;;;;;GAKG;AACH,+CAFW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAAC,+DA4BtG;AAED;;GAEG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,GAAG,OAAO,oBAAoB,EAAE,OAAO,EAAE,UAIvF;AAwBD;;;;GAIG;AACH,uCAJW,MAAM,EAAE,cACR,MAAM,EAAE,GACN,MAAM,CAgClB;AAr0BD,+BAAgC,OAAO,CAAC;AACxC,4BAA6B,UAAU,CAAC;AACxC,2BAA4B,QAAQ,CAAC;AACrC,uCAAwC,WAAW,CAAC;AACpD,oCAAqC,QAAQ,CAAC;AAC9C,qCAAsC,YAAY,CAAC;AACnD,mCAAoC,gBAAgB,CAAC;AACrD,2BAA4B,SAAS,CAAC;AACtC,uCAAwC,iBAAiB,CAAC;AAkxBnD,uCAJI,GAAG,WACH,OAAO,GACL,MAAM,EAAE,CAQA;sBAlxBR,OAAO,oBAAoB,EAAE,OAAO;;aA+BvC,OAAO;kBACP,MAAM;0BACN,MAAM;oBACN,MAAM;oBACN,MAAM;kBACN,MAAM;kBACN,MAAM;eACN,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG;;;;;8BAofZ,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBAwLhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BAruBJ,WAAW"}
@@ -182,8 +182,7 @@ export function generateDataGlsl(
182
182
  sharedQuantitativeChannels = [channel]
183
183
  ) {
184
184
  const { attributeType } = getAttributeAndArrayTypes(scale, channel);
185
- const attributeName =
186
- ATTRIBUTE_PREFIX + makeAttributeName(sharedQuantitativeChannels);
185
+ const attributeName = makeAttributeName(sharedQuantitativeChannels);
187
186
 
188
187
  const attributeGlsl = `in highp ${attributeType} ${attributeName};`;
189
188
 
@@ -215,7 +214,7 @@ export function generateDatumGlslAndUniform(channel, scale, conditionNumber) {
215
214
  const { attributeType } = getAttributeAndArrayTypes(scale, channel);
216
215
 
217
216
  // TODO: Use uniform prefix
218
- const uniformName = ATTRIBUTE_PREFIX + makeAttributeName(channel);
217
+ const uniformName = makeAttributeName(channel);
219
218
  const uniformGlsl = ` uniform highp ${attributeType} ${uniformName};`;
220
219
 
221
220
  const accessorFunctionName = makeAccessorFunctionName(
@@ -797,7 +796,7 @@ export function dedupeEncodingFields(encoders) {
797
796
  * @param {import("../spec/channel.js").Channel | import("../spec/channel.js").Channel[]} channel
798
797
  */
799
798
  export function makeAttributeName(channel) {
800
- return asArray(channel).join("_");
799
+ return ATTRIBUTE_PREFIX + asArray(channel).toSorted().join("_");
801
800
  }
802
801
 
803
802
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
@@ -34,8 +34,8 @@ import {
34
34
  generateDatumGlslAndUniform,
35
35
  generateConditionalEncoderGlsl,
36
36
  PARAM_PREFIX,
37
- ATTRIBUTE_PREFIX,
38
37
  SELECTION_CHECKER_PREFIX,
38
+ makeAttributeName,
39
39
  } from "../gl/glslScaleGenerator.js";
40
40
  import GLSL_COMMON from "../gl/includes/common.glsl.js";
41
41
  import GLSL_SCALES from "../gl/includes/scales.glsl.js";
@@ -493,7 +493,7 @@ export default class Mark {
493
493
  );
494
494
  }
495
495
 
496
- const uniqueIdAttr = ATTRIBUTE_PREFIX + "uniqueId";
496
+ const uniqueIdAttr = makeAttributeName("uniqueId");
497
497
 
498
498
  if (isSinglePointSelection(selection)) {
499
499
  // Register a mark uniform for each param. The uniform will have
@@ -611,20 +611,30 @@ export default class Mark {
611
611
  { expr: param },
612
612
  (
613
613
  /** @type {import("../types/selectionTypes.js").IntervalSelection} */ selection
614
- ) =>
615
- selection.intervals[channel] ?? [
616
- Infinity,
617
- -Infinity,
618
- ]
614
+ ) => selection.intervals[channel] ?? [1, 0]
619
615
  );
620
616
  });
621
617
 
622
- const c = ATTRIBUTE_PREFIX + channel;
618
+ const getAttributeName = (
619
+ /** @type {Channel} */ channel
620
+ ) => {
621
+ for (const [
622
+ k,
623
+ channels,
624
+ ] of dedupedEncodingFields.entries()) {
625
+ if (k[1] && channels.includes(channel)) {
626
+ return makeAttributeName(channels);
627
+ }
628
+ }
629
+ return makeAttributeName(channel);
630
+ };
631
+
632
+ const c = getAttributeName(channel);
623
633
  const u = uniformName + "[0]";
624
634
  const u2 = uniformName + "[1]";
625
635
  const secondaryChannel = getSecondaryChannel(channel);
626
636
  if (this.encoding[secondaryChannel]) {
627
- const c2 = ATTRIBUTE_PREFIX + secondaryChannel;
637
+ const c2 = getAttributeName(secondaryChannel);
628
638
  const mode = this.defaultHitTestMode;
629
639
  if (mode == "endpoints") {
630
640
  testSnippets.push(
@@ -737,7 +747,7 @@ export default class Mark {
737
747
  );
738
748
  });
739
749
  } else if (isFieldDef(channelDef)) {
740
- const fields = dedupedEncodingFields.get([
750
+ const dedupedChannels = dedupedEncodingFields.get([
741
751
  channelDef.field,
742
752
  true,
743
753
  ]);
@@ -745,7 +755,9 @@ export default class Mark {
745
755
  channel,
746
756
  scale,
747
757
  conditionNumber,
748
- fields?.includes(channel) ? fields : undefined
758
+ dedupedChannels?.includes(channel)
759
+ ? dedupedChannels
760
+ : undefined
749
761
  );
750
762
  attributeCode.add(attributeGlsl);
751
763
  scaleCode.push(accessorGlsl);
@@ -1,4 +1,5 @@
1
1
  import { PositionalChannel } from "./channel.js";
2
+ import { ExprRef } from "./parameter.js";
2
3
 
3
4
  /**
4
5
  * The name of the field or a JavaScript expression for accessing nested properties.
@@ -425,7 +426,7 @@ export interface MeasureTextParams extends TransformParamsBase {
425
426
 
426
427
  field: Field;
427
428
 
428
- fontSize: number;
429
+ fontSize: number | ExprRef;
429
430
 
430
431
  as: string;
431
432
 
@@ -484,18 +485,31 @@ export interface FilterScoredLabelsParams extends TransformParamsBase {
484
485
  score: Field;
485
486
 
486
487
  /**
487
- * The field representing element's width in pixels
488
+ * The field representing element's width in pixels.
488
489
  */
489
490
  width: Field;
490
491
 
491
492
  /**
492
- * The field representing element's position on the domain.
493
+ * The field representing element's start position on the domain.
493
494
  */
494
495
  pos: Field;
495
496
 
497
+ /**
498
+ * The field representing element's end position on the domain.
499
+ * If not specified, the `pos` field is used.
500
+ */
501
+ pos2?: Field;
502
+
503
+ /**
504
+ * Outputs the average of pos and pos2 as the midpoint of the element.
505
+ * This is useful for elements that have a width, such as transcripts.
506
+ * The midpoint is clamped to the visible region of the element.
507
+ */
508
+ asMidpoint?: string;
509
+
496
510
  /**
497
511
  * An optional field representing element's lane, e.g., if transcripts
498
- * are shown using a piled up layout.
512
+ * are shown using a piled up layout. Each line is processed separately.
499
513
  */
500
514
  lane?: Field;
501
515
 
@@ -1,22 +1,13 @@
1
1
  /**
2
- * Finds the top k
3
- *
4
- * Based on ideas at https://lemire.me/blog/2017/06/21/top-speed-for-top-k-queries/
2
+ * Finds the top k elements in a slice of the data array, using a priority accessor.
5
3
  *
6
4
  * @param {T[]} data
7
5
  * @param {number} k
8
6
  * @param {(datum: T) => number} priorityAccessor
9
- * @template T
10
- */
11
- export function topK<T>(data: T[], k: number, priorityAccessor: (datum: T) => number): T[];
12
- /**
13
- * Takes an array of priorities and returns the top k indices from the
14
- * specified slice
15
- *
16
- * @param {number[]} priorities An array of priorities
17
- * @param {number} k
18
7
  * @param {number} [start] Default: 0
19
- * @param {number} [end] Exclusive. Default: priorities.length
8
+ * @param {number} [end] Exclusive. Default: data.length
9
+ * @template T
10
+ * @returns {T[]}
20
11
  */
21
- export function topKSlice(priorities: number[], k: number, start?: number, end?: number): number[];
12
+ export function topK<T>(data: T[], k: number, priorityAccessor?: (datum: T) => number, start?: number, end?: number): T[];
22
13
  //# sourceMappingURL=topK.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"topK.d.ts","sourceRoot":"","sources":["../../../src/utils/topK.js"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,qBAFa,CAAC,QAHH,CAAC,EAAE,KACH,MAAM,oBACN,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,OA4B9B;AAED;;;;;;;;GAQG;AACH,sCALW,MAAM,EAAE,KACR,MAAM,UACN,MAAM,QACN,MAAM,YA6BhB"}
1
+ {"version":3,"file":"topK.d.ts","sourceRoot":"","sources":["../../../src/utils/topK.js"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,qBAHa,CAAC,QALH,CAAC,EAAE,KACH,MAAM,qBACN,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,UACpB,MAAM,QACN,MAAM,GAEJ,CAAC,EAAE,CAiCf"}