@genome-spy/core 0.42.2 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/bundle/{index-d7k3kkin.js → index-noY1e-G6.js} +365 -361
  2. package/dist/bundle/index.es.js +3348 -3223
  3. package/dist/bundle/index.js +89 -84
  4. package/dist/schema.json +251 -1
  5. package/dist/src/data/collector.d.ts.map +1 -1
  6. package/dist/src/data/collector.js +28 -2
  7. package/dist/src/data/sources/dataSourceFactory.d.ts +7 -7
  8. package/dist/src/data/sources/dataSourceFactory.d.ts.map +1 -1
  9. package/dist/src/data/sources/dataSourceFactory.js +9 -9
  10. package/dist/src/data/sources/{dynamic → lazy}/README.md +2 -2
  11. package/dist/src/data/sources/lazy/axisGenomeSource.d.ts.map +1 -0
  12. package/dist/src/data/sources/lazy/axisTickSource.d.ts.map +1 -0
  13. package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -0
  14. package/dist/src/data/sources/{dynamic → lazy}/bigBedSource.d.ts +6 -0
  15. package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -0
  16. package/dist/src/data/sources/lazy/bigBedSource.js +206 -0
  17. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -0
  18. package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -0
  19. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -0
  20. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -0
  21. package/dist/src/data/sources/{dynamic → lazy}/singleAxisLazySource.js +3 -3
  22. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -0
  23. package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -0
  24. package/dist/src/data/transforms/regexFold.d.ts.map +1 -1
  25. package/dist/src/data/transforms/regexFold.js +6 -8
  26. package/dist/src/encoder/encoder.d.ts +1 -1
  27. package/dist/src/encoder/encoder.d.ts.map +1 -1
  28. package/dist/src/gl/arrayBuilder.d.ts +11 -5
  29. package/dist/src/gl/arrayBuilder.d.ts.map +1 -1
  30. package/dist/src/gl/arrayBuilder.js +77 -40
  31. package/dist/src/gl/dataToVertices.d.ts +3 -2
  32. package/dist/src/gl/dataToVertices.d.ts.map +1 -1
  33. package/dist/src/gl/dataToVertices.js +52 -17
  34. package/dist/src/gl/glslScaleGenerator.d.ts +12 -0
  35. package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
  36. package/dist/src/gl/glslScaleGenerator.js +38 -4
  37. package/dist/src/gl/includes/scales.glsl.js +1 -1
  38. package/dist/src/marks/link.d.ts.map +1 -1
  39. package/dist/src/marks/link.js +2 -1
  40. package/dist/src/marks/mark.d.ts.map +1 -1
  41. package/dist/src/marks/mark.js +9 -1
  42. package/dist/src/spec/channel.d.ts +14 -1
  43. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  44. package/dist/src/view/flowBuilder.js +11 -4
  45. package/dist/src/view/unitView.d.ts +1 -1
  46. package/dist/src/view/unitView.d.ts.map +1 -1
  47. package/package.json +3 -3
  48. package/dist/src/data/sources/dynamic/axisGenomeSource.d.ts.map +0 -1
  49. package/dist/src/data/sources/dynamic/axisTickSource.d.ts.map +0 -1
  50. package/dist/src/data/sources/dynamic/bamSource.d.ts.map +0 -1
  51. package/dist/src/data/sources/dynamic/bigBedSource.d.ts.map +0 -1
  52. package/dist/src/data/sources/dynamic/bigBedSource.js +0 -84
  53. package/dist/src/data/sources/dynamic/bigWigSource.d.ts.map +0 -1
  54. package/dist/src/data/sources/dynamic/gff3Source.d.ts.map +0 -1
  55. package/dist/src/data/sources/dynamic/indexedFastaSource.d.ts.map +0 -1
  56. package/dist/src/data/sources/dynamic/singleAxisLazySource.d.ts.map +0 -1
  57. package/dist/src/data/sources/dynamic/singleAxisWindowedSource.d.ts.map +0 -1
  58. package/dist/src/data/sources/dynamic/tabixSource.d.ts.map +0 -1
  59. /package/dist/src/data/sources/{dynamic → lazy}/axisGenomeSource.d.ts +0 -0
  60. /package/dist/src/data/sources/{dynamic → lazy}/axisGenomeSource.js +0 -0
  61. /package/dist/src/data/sources/{dynamic → lazy}/axisTickSource.d.ts +0 -0
  62. /package/dist/src/data/sources/{dynamic → lazy}/axisTickSource.js +0 -0
  63. /package/dist/src/data/sources/{dynamic → lazy}/bamSource.d.ts +0 -0
  64. /package/dist/src/data/sources/{dynamic → lazy}/bamSource.js +0 -0
  65. /package/dist/src/data/sources/{dynamic → lazy}/bigWigSource.d.ts +0 -0
  66. /package/dist/src/data/sources/{dynamic → lazy}/bigWigSource.js +0 -0
  67. /package/dist/src/data/sources/{dynamic → lazy}/gff3Source.d.ts +0 -0
  68. /package/dist/src/data/sources/{dynamic → lazy}/gff3Source.js +0 -0
  69. /package/dist/src/data/sources/{dynamic → lazy}/indexedFastaSource.d.ts +0 -0
  70. /package/dist/src/data/sources/{dynamic → lazy}/indexedFastaSource.js +0 -0
  71. /package/dist/src/data/sources/{dynamic → lazy}/singleAxisLazySource.d.ts +0 -0
  72. /package/dist/src/data/sources/{dynamic → lazy}/singleAxisWindowedSource.d.ts +0 -0
  73. /package/dist/src/data/sources/{dynamic → lazy}/singleAxisWindowedSource.js +0 -0
  74. /package/dist/src/data/sources/{dynamic → lazy}/tabixSource.d.ts +0 -0
  75. /package/dist/src/data/sources/{dynamic → lazy}/tabixSource.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleAxisWindowedSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisWindowedSource.js"],"names":[],"mappings":"AAIA;;GAEG;AACH;IAQI;;;OAGG;IACH,kBAHU;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAC,CAGxB;IAEP;;;OAGG;IACH,0CAHW,OAAO,uBAAuB,EAAE,aAAa,QAmBvD;IAED;;;;OAIG;IACH,wBAFW,MAAM,EAAE,iBAiBlB;IAED;;;;;OAKG;IACH,iCAHW,MAAM,EAAE,iBAKlB;IAED;;;;;;;;;OASG;IACH,yCANW,MAAM,EAAE,4BACU,OAAO,mCAAmC,EAAE,0BAA0B,UAAU,WAAW,+BAqCvH;IAED;;;;;;;;OAQG;IACH,qCAJW,MAAM,EAAE,cACR,MAAM,YAWhB;IAED;;;;OAIG;IACH,+CAHW,MAAM,EAAE,WAUlB;;CACJ;iCAvJgC,2BAA2B"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabixSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/tabixSource.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH;IAII;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,SAAS,QACzC,OAAO,uBAAuB,EAAE,OAAO,EA8CjD;IAhCG,kDAAgC;IAQhC,iCAuBE;IAoCN;;;;;OAKG;IACH,gCAHW,MAAM,EAAE,GACN,CAAC,EAAE,CAKf;;CACJ;qCAvGoC,+BAA+B"}
@@ -1 +1 @@
1
- {"version":3,"file":"regexFold.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/regexFold.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH;IAKI;;OAEG;IACH,oBAFW,OAAO,yBAAyB,EAAE,eAAe,EAmI3D;IAfO,gBALO,GAAG,UAKe;CAgBpC;qBAjJsD,gBAAgB"}
1
+ {"version":3,"file":"regexFold.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/regexFold.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH;IAKI;;OAEG;IACH,oBAFW,OAAO,yBAAyB,EAAE,eAAe,EAiI3D;IAfO,gBALO,GAAG,UAKe;CAgBpC;qBA/IsD,gBAAgB"}
@@ -39,7 +39,7 @@ export default class RegexFoldTransform extends FlowNode {
39
39
  /** @type {string[]} */
40
40
  let includedColumns;
41
41
 
42
- /** @type {(datum: any, sampleId: string) => Record<string, any>} */
42
+ /** @type {(datum: any, sampleId: string, attrs: any[]) => Record<string, any>} */
43
43
  let create;
44
44
 
45
45
  /**
@@ -91,7 +91,7 @@ export default class RegexFoldTransform extends FlowNode {
91
91
  "]"
92
92
  ),
93
93
  JSON.stringify(sampleKey) + ": sampleId",
94
- ...as.map((a) => JSON.stringify(a) + ": null"),
94
+ ...as.map((a, i) => JSON.stringify(a) + `: datum[attrs[${i}]]`),
95
95
  ];
96
96
 
97
97
  // eslint-disable-next-line no-new-func
@@ -99,6 +99,7 @@ export default class RegexFoldTransform extends FlowNode {
99
99
  new Function(
100
100
  "datum",
101
101
  "sampleId",
102
+ "attrs",
102
103
  "return {\n" + props.join(",\n") + "\n};"
103
104
  )
104
105
  );
@@ -112,12 +113,9 @@ export default class RegexFoldTransform extends FlowNode {
112
113
  detectColumns(datum);
113
114
  }
114
115
 
115
- for (const [sampleId, attrs] of sampleAttrs) {
116
- const tidyRow = create(datum, sampleId);
117
- for (let i = 0; i < attrs.length; i++) {
118
- tidyRow[as[i]] = datum[attrs[i]];
119
- }
120
-
116
+ for (let i = 0; i < sampleAttrs.length; i++) {
117
+ const [sampleId, attrs] = sampleAttrs[i];
118
+ const tidyRow = create(datum, sampleId, attrs);
121
119
  this._propagate(tidyRow);
122
120
  }
123
121
  };
@@ -45,7 +45,7 @@ export function isChannelDefWithScale(channelDef: import("../spec/channel.js").C
45
45
  * @param {import("../view/unitView.js").default} view
46
46
  * @param {import("../spec/channel.js").Channel} channel
47
47
  */
48
- export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").MarkPropExprDef<import("../spec/channel.js").Type> | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").Type> | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").TypeForShape> | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").Type> | import("../spec/channel.js").PositionFieldDef<string> | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").TypeForShape>;
48
+ export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").MarkPropExprDef<import("../spec/channel.js").Type> | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").Type> | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | (import("../spec/channel.js").ChromPosDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").TypeMixins<"locus"> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DatumDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").TypeForShape> | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").Type> | import("../spec/channel.js").PositionFieldDef<string> | (import("../spec/channel.js").FieldDefBase<string> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").TypeForShape>;
49
49
  /**
50
50
  * @param {import("../spec/channel.js").ChannelDef} channelDef
51
51
  * @returns {channelDef is import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>}
@@ -1 +1 @@
1
- {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,6CAJW,OAAO,kBAAkB,EAAE,OAAO,aAClC,OAAO,oBAAoB,EAAE,QAAQ,gGAsC/C;AAED;;;;;;;GAOG;AACH,0CANW,OAAO,oBAAoB,EAAE,UAAU,SACvC,GAAG,0IA2Fb;AAED;;;;;GAKG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,4FAKjD;AAED;;;GAGG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,mEAKjD;AAED;;;GAGG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,uDAKjD;AAED;;;GAGG;AACH,kDAHW,OAAO,oBAAoB,EAAE,UAAU,kEAWjD;AAED;;;GAGG;AACH,6CAHW,OAAO,qBAAqB,EAAE,OAAO,WACrC,OAAO,oBAAoB,EAAE,OAAO,klBAS9C;AAED;;;GAGG;AACH,iDAHW,OAAO,oBAAoB,EAAE,UAAU,4FAKjD;AAED;;;GAGG;AACH,0CAHW,OAAO,oBAAoB,EAAE,UAAU,0DAKjD;AAED;;;GAGG;AACH,sCAHW,OAAO,oBAAoB,EAAE,UAAU,sDAKjD;AAoBD;;;GAGG;AACH,oDAHW,OAAO,oBAAoB,EAAE,OAAO,oEAM9C;AAED;;;GAGG;AACH,6CAHW,OAAO,oBAAoB,EAAE,OAAO,6DAM9C;AAqBD;;;GAGG;AACH,4CAFW,MAAM,WAIhB;AAED;;;;GAIG;AACH,oDAFW,OAAO,oBAAoB,EAAE,OAAO,2DAS9C;AAED;;;;;GAKG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,wCAI9C;AAED;;;;GAIG;AACH,kDAFW,OAAO,oBAAoB,EAAE,OAAO,0CAM9C;AAED;;GAEG;AACH,wCAFW,OAAO,oBAAoB,EAAE,OAAO,WAI9C;AAED;;;;GAIG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,WAI9C;AAED;;;GAGG;AACH,4CAHW,OAAO,oBAAoB,EAAE,OAAO,4DAuB9C;AAED;;;;;GAKG;AACH,0CAHW,OAAO,oBAAoB,EAAE,OAAO,GAClC,GAAG,EAAE,CAsBjB;AAED;;;GAGG;AACH,gDAHW,OAAO,oBAAoB,EAAE,OAAO,UACzB,GAAG,KAAE,MAAM,CAmBhC;AA7LD;;GAEG;AACH,wCAFU,OAAO,oBAAoB,EAAE,wBAAwB,EAAE,CAEb;AAEpD;;GAEG;AACH,0CAFU,OAAO,oBAAoB,EAAE,0BAA0B,EAAE,CAEX;AAExD;;GAEG;AACH,iCAFU,OAAO,oBAAoB,EAAE,iBAAiB,EAAE,CAKxD;AAoBF;;;;GAIG;AACH,gCAFU,QAAQ,OAAO,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,oBAAoB,EAAE,0BAA0B,CAAC,CAAC,CAKtH;AAEF;;;;GAIG;AACH,8BAFU,QAAQ,OAAO,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAAC,CAInG"}
1
+ {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,6CAJW,OAAO,kBAAkB,EAAE,OAAO,aAClC,OAAO,oBAAoB,EAAE,QAAQ,gGAsC/C;AAED;;;;;;;GAOG;AACH,0CANW,OAAO,oBAAoB,EAAE,UAAU,SACvC,GAAG,0IA2Fb;AAED;;;;;GAKG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,4FAKjD;AAED;;;GAGG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,mEAKjD;AAED;;;GAGG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,uDAKjD;AAED;;;GAGG;AACH,kDAHW,OAAO,oBAAoB,EAAE,UAAU,kEAWjD;AAED;;;GAGG;AACH,6CAHW,OAAO,qBAAqB,EAAE,OAAO,WACrC,OAAO,oBAAoB,EAAE,OAAO,27CAS9C;AAED;;;GAGG;AACH,iDAHW,OAAO,oBAAoB,EAAE,UAAU,4FAKjD;AAED;;;GAGG;AACH,0CAHW,OAAO,oBAAoB,EAAE,UAAU,0DAKjD;AAED;;;GAGG;AACH,sCAHW,OAAO,oBAAoB,EAAE,UAAU,sDAKjD;AAoBD;;;GAGG;AACH,oDAHW,OAAO,oBAAoB,EAAE,OAAO,oEAM9C;AAED;;;GAGG;AACH,6CAHW,OAAO,oBAAoB,EAAE,OAAO,6DAM9C;AAqBD;;;GAGG;AACH,4CAFW,MAAM,WAIhB;AAED;;;;GAIG;AACH,oDAFW,OAAO,oBAAoB,EAAE,OAAO,2DAS9C;AAED;;;;;GAKG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,wCAI9C;AAED;;;;GAIG;AACH,kDAFW,OAAO,oBAAoB,EAAE,OAAO,0CAM9C;AAED;;GAEG;AACH,wCAFW,OAAO,oBAAoB,EAAE,OAAO,WAI9C;AAED;;;;GAIG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,WAI9C;AAED;;;GAGG;AACH,4CAHW,OAAO,oBAAoB,EAAE,OAAO,4DAuB9C;AAED;;;;;GAKG;AACH,0CAHW,OAAO,oBAAoB,EAAE,OAAO,GAClC,GAAG,EAAE,CAsBjB;AAED;;;GAGG;AACH,gDAHW,OAAO,oBAAoB,EAAE,OAAO,UACzB,GAAG,KAAE,MAAM,CAmBhC;AA7LD;;GAEG;AACH,wCAFU,OAAO,oBAAoB,EAAE,wBAAwB,EAAE,CAEb;AAEpD;;GAEG;AACH,0CAFU,OAAO,oBAAoB,EAAE,0BAA0B,EAAE,CAEX;AAExD;;GAEG;AACH,iCAFU,OAAO,oBAAoB,EAAE,iBAAiB,EAAE,CAKxD;AAoBF;;;;GAIG;AACH,gCAFU,QAAQ,OAAO,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,oBAAoB,EAAE,0BAA0B,CAAC,CAAC,CAKtH;AAEF;;;;GAIG;AACH,8BAFU,QAAQ,OAAO,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAAC,CAInG"}
@@ -5,6 +5,7 @@
5
5
  * @prop {function(object):any} f The converter
6
6
  * @prop {number[]} [arrayReference] An optimization for fp64 mainly
7
7
  * @prop {number} [numComponents]
8
+ * @prop {typeof Uint16Array | typeof Int16Array | typeof Uint32Array | typeof Int32Array | typeof Float32Array} [targetArrayType] Defaults to Float32Array
8
9
  */
9
10
  export default class ArrayBuilder {
10
11
  /**
@@ -13,10 +14,10 @@ export default class ArrayBuilder {
13
14
  */
14
15
  constructor(size: number);
15
16
  size: number;
16
- /** @type {Object.<string, {data: number[] | Float32Array, numComponents: number, divisor?: number}>} */
17
+ /** @type {Object.<string, {data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array, numComponents: number, divisor?: number}>} */
17
18
  arrays: {
18
19
  [x: string]: {
19
- data: number[] | Float32Array;
20
+ data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array;
20
21
  numComponents: number;
21
22
  divisor?: number;
22
23
  };
@@ -26,6 +27,7 @@ export default class ArrayBuilder {
26
27
  /** @type {(function(any):void)[]} */
27
28
  dataUpdaters: ((arg0: any) => void)[];
28
29
  vertexCount: number;
30
+ configure(): void;
29
31
  /**
30
32
  *
31
33
  * @param {string} attribute
@@ -36,14 +38,13 @@ export default class ArrayBuilder {
36
38
  *
37
39
  * @param {string} attributeName
38
40
  * @param {number} numComponents
41
+ * @param {typeof Uint16Array | typeof Int16Array | typeof Uint32Array | typeof Int32Array | typeof Float32Array} [targetArrayType]
39
42
  * @param {number[]} [arrayReference]
40
43
  * @return {function(number|number[])}
41
44
  */
42
- createUpdater(attributeName: string, numComponents: number, arrayReference?: number[]): (arg0: number | number[]) => any;
43
- _unrollPushAll(): void;
45
+ createUpdater(attributeName: string, numComponents: number, targetArrayType?: typeof Uint16Array | typeof Int16Array | typeof Uint32Array | typeof Int32Array | typeof Float32Array, arrayReference?: number[]): (arg0: number | number[]) => any;
44
46
  pushAll(): void;
45
47
  /**
46
- *
47
48
  * @param {object} datum
48
49
  */
49
50
  updateFromDatum(datum: object): void;
@@ -52,6 +53,7 @@ export default class ArrayBuilder {
52
53
  * @param {object} datum
53
54
  */
54
55
  pushFromDatum(datum: object): void;
56
+ #private;
55
57
  }
56
58
  /**
57
59
  * A function that extracts a raw attribute from a datum (optionally) converts
@@ -67,5 +69,9 @@ export type ConverterMetadata = {
67
69
  */
68
70
  arrayReference?: number[];
69
71
  numComponents?: number;
72
+ /**
73
+ * Defaults to Float32Array
74
+ */
75
+ targetArrayType?: typeof Uint16Array | typeof Int16Array | typeof Uint32Array | typeof Int32Array | typeof Float32Array;
70
76
  };
71
77
  //# sourceMappingURL=arrayBuilder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"arrayBuilder.d.ts","sourceRoot":"","sources":["../../../src/gl/arrayBuilder.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH;IAGI;;;OAGG;IACH,kBAFW,MAAM,EAehB;IAZG,aAAgB;IAEhB,wGAAwG;IACxG;YADmB,MAAM,GAAE;YAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC;MACnF;IAEhB,kCAAkC;IAClC,SADW,OAAY,IAAI,CAAC,EAAE,CACb;IAEjB,qCAAqC;IACrC,cADW,QAAU,GAAG,KAAE,IAAI,CAAC,EAAE,CACX;IAEtB,oBAAoB;IAGxB;;;;OAIG;IACH,wBAHW,MAAM,YACN,iBAAiB,QAc3B;IAED;;;;;;OAMG;IACH,6BALW,MAAM,iBACN,MAAM,mBACN,MAAM,EAAE,UACE,MAAM,GAAC,MAAM,EAAE,SA8EnC;IAED,uBAsBC;IAED,gBAiBC;IAED;;;OAGG;IACH,uBAFW,MAAM,QAMhB;IAED;;;OAGG;IACH,qBAFW,MAAM,QAKhB;CACJ;;;;;;;;;cA/LkB,MAAM,KAAE,GAAG;;;;qBACpB,MAAM,EAAE;oBACR,MAAM"}
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;YADmB,MAAM,GAAE;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;MAC9H;IAEhB,kCAAkC;IAClC,SADW,OAAY,IAAI,CAAC,EAAE,CACb;IAEjB,qCAAqC;IACrC,cADW,QAAU,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,kBAAkB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,mBAAmB,mBACrG,MAAM,EAAE,UACE,MAAM,GAAC,MAAM,EAAE,SAoFnC;IAED,gBAEC;IAED;;OAEG;IACH,uBAFW,MAAM,QAIhB;IAuDD;;;OAGG;IACH,qBAFW,MAAM,QAKhB;;CACJ;;;;;;;;;cA9NkB,MAAM,KAAE,GAAG;;;;qBACpB,MAAM,EAAE;oBACR,MAAM;;;;sBACN,kBAAkB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,mBAAmB"}
@@ -1,6 +1,12 @@
1
1
  import { isNumber } from "vega-util";
2
2
  import { ATTRIBUTE_PREFIX } from "./glslScaleGenerator.js";
3
3
 
4
+ /** Unrolling appears to give a 20% performance boost on Chrome but compiling the
5
+ * dynamically generated code takes time and is thus not great for small dynamic data.
6
+ * Unrolling probably allows the JS engine to inline pusher calls.
7
+ */
8
+ const UNROLL_LIMIT = 10000;
9
+
4
10
  /**
5
11
  * @typedef {Object} ConverterMetadata
6
12
  * A function that extracts a raw attribute from a datum (optionally) converts
@@ -8,10 +14,13 @@ import { ATTRIBUTE_PREFIX } from "./glslScaleGenerator.js";
8
14
  * @prop {function(object):any} f The converter
9
15
  * @prop {number[]} [arrayReference] An optimization for fp64 mainly
10
16
  * @prop {number} [numComponents]
17
+ * @prop {typeof Uint16Array | typeof Int16Array | typeof Uint32Array | typeof Int32Array | typeof Float32Array} [targetArrayType] Defaults to Float32Array
11
18
  */
12
19
  export default class ArrayBuilder {
13
20
  // TODO: Support strided layout. May yield better performance or not. No consensus in literature.
14
21
 
22
+ #configured = false;
23
+
15
24
  /**
16
25
  *
17
26
  * @param {number} size Size if known, uses TypedArray
@@ -19,7 +28,7 @@ export default class ArrayBuilder {
19
28
  constructor(size) {
20
29
  this.size = size;
21
30
 
22
- /** @type {Object.<string, {data: number[] | Float32Array, numComponents: number, divisor?: number}>} */
31
+ /** @type {Object.<string, {data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array, numComponents: number, divisor?: number}>} */
23
32
  this.arrays = {};
24
33
 
25
34
  /** @type {(function():void)[]} */
@@ -31,6 +40,15 @@ export default class ArrayBuilder {
31
40
  this.vertexCount = 0;
32
41
  }
33
42
 
43
+ configure() {
44
+ if (this.#configured) {
45
+ throw new Error("Already configured!");
46
+ }
47
+ this.#configurePushAll();
48
+ this.#configureUpdateFromDatum();
49
+ this.#configured = true;
50
+ }
51
+
34
52
  /**
35
53
  *
36
54
  * @param {string} attribute
@@ -40,6 +58,7 @@ export default class ArrayBuilder {
40
58
  const updater = this.createUpdater(
41
59
  ATTRIBUTE_PREFIX + attribute,
42
60
  metadata.numComponents || 1,
61
+ metadata.targetArrayType ?? Float32Array,
43
62
  metadata.arrayReference
44
63
  );
45
64
  const f = metadata.f;
@@ -54,10 +73,16 @@ export default class ArrayBuilder {
54
73
  *
55
74
  * @param {string} attributeName
56
75
  * @param {number} numComponents
76
+ * @param {typeof Uint16Array | typeof Int16Array | typeof Uint32Array | typeof Int32Array | typeof Float32Array} [targetArrayType]
57
77
  * @param {number[]} [arrayReference]
58
78
  * @return {function(number|number[])}
59
79
  */
60
- createUpdater(attributeName, numComponents, arrayReference) {
80
+ createUpdater(
81
+ attributeName,
82
+ numComponents,
83
+ targetArrayType = Float32Array,
84
+ arrayReference = undefined
85
+ ) {
61
86
  if (!isNumber(this.size)) {
62
87
  throw new Error("The number of vertices must be defined!");
63
88
  }
@@ -67,7 +92,8 @@ export default class ArrayBuilder {
67
92
  let updater;
68
93
  let i = 0;
69
94
 
70
- const array = new Float32Array(this.size * numComponents);
95
+ // eslint-disable-next-line new-cap
96
+ const array = new targetArrayType(this.size * numComponents);
71
97
 
72
98
  this.arrays[attributeName] = {
73
99
  data: array,
@@ -135,37 +161,33 @@ export default class ArrayBuilder {
135
161
  return updater;
136
162
  }
137
163
 
138
- _unrollPushAll() {
139
- let preps = "";
140
- let pushs = "";
141
-
142
- for (let i = 0; i < this.pushers.length; i++) {
143
- preps += `const p${i} = that.pushers[${i}];\n`;
144
- pushs += `p${i}();\n`;
145
- }
146
-
147
- // eslint-disable-next-line no-new-func
148
- const createUnrolled = new Function(
149
- "that",
150
- `${preps}
151
-
152
- return function unrolledPushAll() {
153
- ${pushs}
154
- that.vertexCount++;
155
- };
156
- `
157
- );
164
+ pushAll() {
165
+ throw new Error("Call configure() first!");
166
+ }
158
167
 
159
- this.pushAll = createUnrolled(this);
168
+ /**
169
+ * @param {object} datum
170
+ */
171
+ updateFromDatum(datum) {
172
+ throw new Error("Call configure() first!");
160
173
  }
161
174
 
162
- pushAll() {
163
- // Unrolling appears to give a 20% performance boost on Chrome but compiling the
164
- // dynamically generated code takes time and is thus not great for small dynamic data.
165
- // Unrolling probably allows the JS engine to inline pusher calls.
166
- const unroll = this.size > 100000;
167
- if (unroll) {
168
- this._unrollPushAll();
175
+ #configurePushAll() {
176
+ if (this.size > UNROLL_LIMIT) {
177
+ const preps = this.pushers
178
+ .map((_v, i) => `const p${i} = that.pushers[${i}];`)
179
+ .join("\n");
180
+ const pushs = this.pushers.map((_v, i) => ` p${i}();`).join("\n");
181
+
182
+ // eslint-disable-next-line no-new-func
183
+ this.pushAll = new Function(
184
+ "that",
185
+ `${preps}
186
+ return function unrolledPushAll() {
187
+ ${pushs}
188
+ that.vertexCount++;
189
+ };`
190
+ )(this);
169
191
  } else {
170
192
  this.pushAll = () => {
171
193
  for (let i = 0; i < this.pushers.length; i++) {
@@ -174,17 +196,32 @@ export default class ArrayBuilder {
174
196
  this.vertexCount++;
175
197
  };
176
198
  }
177
-
178
- this.pushAll();
179
199
  }
180
200
 
181
- /**
182
- *
183
- * @param {object} datum
184
- */
185
- updateFromDatum(datum) {
186
- for (let i = 0; i < this.dataUpdaters.length; i++) {
187
- this.dataUpdaters[i](datum);
201
+ #configureUpdateFromDatum() {
202
+ if (this.size > UNROLL_LIMIT) {
203
+ const preps = this.dataUpdaters
204
+ .map((_v, i) => `const u${i} = that.dataUpdaters[${i}];`)
205
+ .join("\n");
206
+ const updates = this.dataUpdaters
207
+ .map((_v, i) => ` u${i}(datum);`)
208
+ .join("\n");
209
+
210
+ // eslint-disable-next-line no-new-func
211
+ this.updateFromDatum = new Function(
212
+ "that",
213
+ "datum",
214
+ `${preps}
215
+ return function unrolledUpdateFromDatum(datum) {
216
+ ${updates}
217
+ };`
218
+ )(this);
219
+ } else {
220
+ this.updateFromDatum = (/** @type {object} */ datum) => {
221
+ for (let i = 0; i < this.dataUpdaters.length; i++) {
222
+ this.dataUpdaters[i](datum);
223
+ }
224
+ };
188
225
  }
189
226
  }
190
227
 
@@ -63,9 +63,9 @@ export class GeometryBuilder {
63
63
  getIndex: () => import("../utils/binnedIndex.js").Lookup;
64
64
  };
65
65
  toArrays(): {
66
- /** @type {Record<string, {data: number[] | Float32Array, numComponents: number, divisor?: number}>} */
66
+ /** @type {Record<string, {data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array, numComponents: number, divisor?: number}>} */
67
67
  arrays: Record<string, {
68
- data: number[] | Float32Array;
68
+ data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array;
69
69
  numComponents: number;
70
70
  divisor?: number;
71
71
  }>;
@@ -89,6 +89,7 @@ export class RectVertexBuilder extends GeometryBuilder {
89
89
  attributes: string[];
90
90
  numItems?: number;
91
91
  });
92
+ pushAllSixTimes: any;
92
93
  }
93
94
  export class RuleVertexBuilder extends GeometryBuilder {
94
95
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH;;qBAJW,MAAM,EAAE;sBACR,MAAM;OAyEhB;IArEG,gEAAwB;IAGxB;;MAKC;IAQD,0BAAoC;IAEpC,8BAAoD;IA+CpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,IAAI,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,IAAI,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,QAyDhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IAzDO;;;MAAyB;IA2DjC;QAEQ,uGAAuG;gBAA5F,OAAO,MAAM,EAAE;YAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAEnG,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAQhB;CAkCJ;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;gCACR,MAAM;uBAEN,MAAM,EAAE;mBACR,MAAM;OAsBhB;IANG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA2CpE;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAQhB;CACJ;AAED;IACI;;;;;OAKG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAQhB;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;qBACR,OAAO,2BAA2B,EAAE,aAAa;oBACjD,OAAO,MAAM,EAAE,GAAG,CAAC;wBACnB,MAAM;sBACN,OAAO;OA4CjB;IA7BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAQ5B,qCAAqC;IACrC,sBADmB,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CA8IxE;;;;;;;;YArkBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAhBzB,mBAAmB"}
1
+ {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH;;qBAJW,MAAM,EAAE;sBACR,MAAM;OA6EhB;IAzEG,gEAAwB;IAGxB;;MAKC;IAQD,0BAAoC;IAEpC,8BAAoD;IAmDpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,IAAI,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,IAAI,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,QA+DhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IA/DO;;;MAAyB;IAiEjC;QAEQ,kJAAkJ;gBAAvI,OAAO,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;;oBAHW,MAAM,EAAE;mBACR,MAAM;OA+BhB;IAnBG,qBAkBW;CA8BlB;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;gCACR,MAAM;uBAEN,MAAM,EAAE;mBACR,MAAM;OAwBhB;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA6CpE;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAShB;CACJ;AAED;IACI;;;;;OAKG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAShB;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;qBACR,OAAO,2BAA2B,EAAE,aAAa;oBACjD,OAAO,MAAM,EAAE,GAAG,CAAC;wBACnB,MAAM;sBACN,OAAO;OA8CjB;IA/BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAQ5B,qCAAqC;IACrC,sBADmB,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CAgJxE;;;;;;;;YAvmBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAjBzB,mBAAmB"}
@@ -8,10 +8,11 @@ import { isValueDef } from "../encoder/encoder.js";
8
8
  import {
9
9
  dedupeEncodingFields,
10
10
  isHighPrecisionScale,
11
+ isLargeGenome,
11
12
  makeAttributeName,
12
- splitHighPrecision,
13
+ splitLargeHighPrecision,
13
14
  } from "./glslScaleGenerator.js";
14
- import { isContinuous } from "vega-scale";
15
+ import { isContinuous, isDiscrete } from "vega-scale";
15
16
 
16
17
  /**
17
18
  * @typedef {object} RangeEntry Represents a location of a vertex subset
@@ -54,8 +55,6 @@ export class GeometryBuilder {
54
55
  this.variableBuilder = new ArrayBuilder(numVertices);
55
56
 
56
57
  // Create converters and updaters for all variable channels.
57
- // TODO: If more than one channels use the same field with the same data type, convert the field only once.
58
-
59
58
  for (const [channel, ce] of Object.entries(this.variableEncoders)) {
60
59
  // Only add the first of the shared channels as all the rest are same
61
60
  // For example, if both x and x2 are using the same field, only x is
@@ -69,8 +68,9 @@ export class GeometryBuilder {
69
68
 
70
69
  const accessor = ce.accessor;
71
70
 
72
- const doubleArray = [0, 0];
73
71
  const hp = isHighPrecisionScale(ce.scale.type);
72
+ const largeHp = hp && isLargeGenome(ce.scale.domain());
73
+ const largeHpArray = [0, 0];
74
74
 
75
75
  const indexer = ce.indexer;
76
76
 
@@ -83,8 +83,8 @@ export class GeometryBuilder {
83
83
  */
84
84
  const f = indexer
85
85
  ? (d) => indexer(accessor(d))
86
- : hp
87
- ? (d) => splitHighPrecision(accessor(d), doubleArray)
86
+ : largeHp
87
+ ? (d) => splitLargeHighPrecision(accessor(d), largeHpArray)
88
88
  : accessor;
89
89
 
90
90
  const attributeName = sharedChannels
@@ -93,8 +93,13 @@ export class GeometryBuilder {
93
93
 
94
94
  this.variableBuilder.addConverter(attributeName, {
95
95
  f,
96
- numComponents: hp ? 2 : 1,
97
- arrayReference: hp ? doubleArray : undefined,
96
+ numComponents: largeHp ? 2 : 1,
97
+ arrayReference: largeHp ? largeHpArray : undefined,
98
+ targetArrayType: isDiscrete(ce.scale.type)
99
+ ? Uint16Array
100
+ : hp
101
+ ? Uint32Array
102
+ : Float32Array,
98
103
  });
99
104
  }
100
105
 
@@ -164,7 +169,13 @@ export class GeometryBuilder {
164
169
  this.xIndexer = undefined;
165
170
  };
166
171
 
167
- if (!data.length || hi - lo < 0) {
172
+ const channelDef = this.encoders.x?.channelDef;
173
+ if (
174
+ !("buildIndex" in channelDef) ||
175
+ !channelDef.buildIndex ||
176
+ !data.length ||
177
+ hi - lo < 0
178
+ ) {
168
179
  disable();
169
180
  return;
170
181
  }
@@ -222,7 +233,7 @@ export class GeometryBuilder {
222
233
 
223
234
  toArrays() {
224
235
  return {
225
- /** @type {Record<string, {data: number[] | Float32Array, numComponents: number, divisor?: number}>} */
236
+ /** @type {Record<string, {data: Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array, numComponents: number, divisor?: number}>} */
226
237
  arrays: this.variableBuilder.arrays,
227
238
  /** Number of vertices used */
228
239
  vertexCount: this.variableBuilder.vertexCount,
@@ -247,6 +258,29 @@ export class RectVertexBuilder extends GeometryBuilder {
247
258
  attributes,
248
259
  numVertices: numItems * 6,
249
260
  });
261
+ this.variableBuilder.configure();
262
+
263
+ const pushAll = this.variableBuilder.pushAll;
264
+
265
+ this.pushAllSixTimes =
266
+ // TODO: Don't do this stupid comparison. Instead, reuse the previous GeometryBuilder.
267
+ numItems > 500
268
+ ? // Make a new function instance where the JS engine can inline
269
+ // all pushAll calls to avoid the function call overhead.
270
+ new Function(
271
+ "pushAll",
272
+ `return function unrolledPushAllSixTimes() {
273
+ pushAll(); pushAll(); pushAll(); pushAll(); pushAll(); pushAll();
274
+ };`
275
+ )(pushAll)
276
+ : function pushAllSixTimes() {
277
+ pushAll();
278
+ pushAll();
279
+ pushAll();
280
+ pushAll();
281
+ pushAll();
282
+ pushAll();
283
+ };
250
284
  }
251
285
 
252
286
  /**
@@ -269,12 +303,7 @@ export class RectVertexBuilder extends GeometryBuilder {
269
303
 
270
304
  // Six vertices per rect. The vertex shader is using gl_VertexID to
271
305
  // determine the vertex position within the rect.
272
- this.variableBuilder.pushAll();
273
- this.variableBuilder.pushAll();
274
- this.variableBuilder.pushAll();
275
- this.variableBuilder.pushAll();
276
- this.variableBuilder.pushAll();
277
- this.variableBuilder.pushAll();
306
+ this.pushAllSixTimes();
278
307
 
279
308
  this.addToXIndex(d);
280
309
  }
@@ -314,6 +343,8 @@ export class RuleVertexBuilder extends GeometryBuilder {
314
343
 
315
344
  this.updateSide = this.variableBuilder.createUpdater("side", 1);
316
345
  this.updatePos = this.variableBuilder.createUpdater("pos", 1);
346
+
347
+ this.variableBuilder.configure();
317
348
  }
318
349
 
319
350
  /* eslint-disable complexity */
@@ -372,6 +403,7 @@ export class PointVertexBuilder extends GeometryBuilder {
372
403
  attributes,
373
404
  numVertices: numItems,
374
405
  });
406
+ this.variableBuilder.configure();
375
407
  }
376
408
  }
377
409
 
@@ -388,6 +420,7 @@ export class LinkVertexBuilder extends GeometryBuilder {
388
420
  attributes,
389
421
  numVertices: numItems,
390
422
  });
423
+ this.variableBuilder.configure();
391
424
  }
392
425
 
393
426
  toArrays() {
@@ -455,6 +488,8 @@ export class TextVertexBuilder extends GeometryBuilder {
455
488
  );
456
489
 
457
490
  this.updateWidth = this.variableBuilder.createUpdater("width", 1);
491
+
492
+ this.variableBuilder.configure();
458
493
  }
459
494
 
460
495
  /**
@@ -18,15 +18,27 @@ export function generateScaleGlsl(channel: Channel, scale: any, channelDef: impo
18
18
  domainUniform: string;
19
19
  };
20
20
  /**
21
+ * True if scale needs more than 24 bits (float32) of precision.
21
22
  *
22
23
  * @param {string} type
23
24
  */
24
25
  export function isHighPrecisionScale(type: string): boolean;
26
+ /**
27
+ * True if Uint32 cannot represent the domain.
28
+ *
29
+ * @param {number[]} domain
30
+ */
31
+ export function isLargeGenome(domain: number[]): boolean;
25
32
  /**
26
33
  * @param {number} x Must be an integer
27
34
  * @param {number[]} [arr]
28
35
  */
29
36
  export function splitHighPrecision(x: number, arr?: number[]): number[];
37
+ /**
38
+ * @param {number} x Must be an integer
39
+ * @param {number[]} [arr]
40
+ */
41
+ export function splitLargeHighPrecision(x: number, arr?: number[]): number[];
30
42
  /**
31
43
  * @param {number[]} domain
32
44
  */
@@ -1 +1 @@
1
- {"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":";AAmDA;;;;GAIG;AACH,2CAHW,OAAO,SACP,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,UAsC9C;AAED;;;;;;GAMG;AAEH,2CANW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU,+BACvC,OAAO,EAAE;;;;EAmRnB;AA+FD;;;GAGG;AACH,2CAFW,MAAM,WAIhB;AAOD;;;GAGG;AACH,sCAHW,MAAM,QACN,MAAM,EAAE,YAYlB;AAYD;;GAEG;AACH,qDAFW,MAAM,EAAE,YAIlB;AAED;;GAEG;AAEH;;;;;GAKG;AACH,+CAFW,QAAQ,OAAO,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;AAzhBD,uCAAwC;AACxC,uCAAwC;AACxC,oCAAqC;AACrC,6CAA8C;AAC9C,kDAAmD;AACnD,oDAAqD;sBAMxC,OAAO,oBAAoB,EAAE,OAAO;;;;8BAsXpC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBA8GhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BAjfJ,WAAW"}
1
+ {"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":";AAmDA;;;;GAIG;AACH,2CAHW,OAAO,SACP,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,UAsC9C;AAED;;;;;;GAMG;AAEH,2CANW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU,+BACvC,OAAO,EAAE;;;;EA8RnB;AA+FD;;;;GAIG;AACH,2CAFW,MAAM,WAIhB;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,QAAQ,OAAO,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;AA3jBD,uCAAwC;AACxC,uCAAwC;AACxC,oCAAqC;AACrC,6CAA8C;AAC9C,kDAAmD;AACnD,oDAAqD;sBAMxC,OAAO,oBAAoB,EAAE,OAAO;;;;8BAiYpC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBAqIhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BAnhBJ,WAAW"}
@@ -122,8 +122,19 @@ export function generateScaleGlsl(
122
122
  const domainUniformName = DOMAIN_PREFIX + primary;
123
123
  const rangeName = RANGE_PREFIX + primary;
124
124
 
125
+ // The attribute has discrete values
126
+ const discrete = isDiscrete(scale.type);
127
+
125
128
  const hp = isHighPrecisionScale(scale.type);
126
- const attributeType = hp ? "vec2" : "float";
129
+ const largeHp = hp && isLargeGenome(scale.domain());
130
+
131
+ const attributeType = largeHp
132
+ ? "uvec2"
133
+ : hp
134
+ ? "uint"
135
+ : discrete
136
+ ? "uint"
137
+ : "float";
127
138
 
128
139
  const domainLength = scale.domain ? scale.domain().length : undefined;
129
140
 
@@ -468,6 +479,7 @@ function makeFunctionCall(name, ...args) {
468
479
  }
469
480
 
470
481
  /**
482
+ * True if scale needs more than 24 bits (float32) of precision.
471
483
  *
472
484
  * @param {string} type
473
485
  */
@@ -475,9 +487,17 @@ export function isHighPrecisionScale(type) {
475
487
  return type == "index" || type == "locus";
476
488
  }
477
489
 
478
- // Maximum precise index number is 2^(23 + 11) ~ 17G
479
- // Higher number increases precision but makes zooming unstable
480
- const BS = 2 ** 11;
490
+ /**
491
+ * True if Uint32 cannot represent the domain.
492
+ *
493
+ * @param {number[]} domain
494
+ */
495
+ export function isLargeGenome(domain) {
496
+ return domain[1] > 2 ** 32;
497
+ }
498
+
499
+ const LOW_BITS = 12;
500
+ const BS = 2 ** LOW_BITS;
481
501
  const BM = BS - 1;
482
502
 
483
503
  /**
@@ -496,6 +516,20 @@ export function splitHighPrecision(x, arr = []) {
496
516
  return arr;
497
517
  }
498
518
 
519
+ /**
520
+ * @param {number} x Must be an integer
521
+ * @param {number[]} [arr]
522
+ */
523
+ export function splitLargeHighPrecision(x, arr = []) {
524
+ const lo = x % BS;
525
+ const hi = (x - lo) / BS;
526
+
527
+ arr[0] = hi;
528
+ arr[1] = lo;
529
+
530
+ return arr;
531
+ }
532
+
499
533
  /**
500
534
  * @param {number} x
501
535
  */
@@ -1,2 +1,2 @@
1
- const shader = "uniform highp float uZero;vec3 getDiscreteColor(sampler2D s,int index){return texelFetch(s,ivec2(index % textureSize(s,0).x,0),0).rgb;}vec3 getInterpolatedColor(sampler2D s,float unitValue){return texture(s,vec2(unitValue,0.0)).rgb;}float clampToRange(float value,vec2 range){return clamp(value,min(range[0],range[1]),max(range[0],range[1]));}float scaleIdentity(float value){return value;}float scaleLinear(float value,vec2 domain,vec2 range){float domainSpan=domain[1]-domain[0];float rangeSpan=range[1]-range[0];return(value-domain[0])/domainSpan*rangeSpan+range[0];}float scaleLog(float value,vec2 domain,vec2 range,float base){return scaleLinear(log(value)/log(base),log(domain)/log(base),range);}float symlog(float value,float constant){return sign(value)*log(abs(value/constant)+1.0);}float scaleSymlog(float value,vec2 domain,vec2 range,float constant){return scaleLinear(symlog(value,constant),vec2(symlog(domain[0],constant),symlog(domain[1],constant)),range);}float scalePow(float value,vec2 domain,vec2 range,float exponent){return scaleLinear(pow(abs(value),exponent)*sign(value),pow(abs(domain),vec2(exponent))*sign(domain),range);}float scaleBand(float value,vec2 domainExtent,vec2 range,float paddingInner,float paddingOuter,float align,float band){float start=range[0];float stop=range[1];float rangeSpan=stop-start;float n=domainExtent[1]-domainExtent[0];paddingInner=int(n)>1 ? paddingInner : 0.0;float step=rangeSpan/max(1.0,n-paddingInner+paddingOuter*2.0);start+=(rangeSpan-step*(n-paddingInner))*align;float bandwidth=step*(1.0-paddingInner);return start+(value-domainExtent[0])*step+bandwidth*band;}float scaleBandHp(vec2 value,vec3 domainExtent,vec2 range,float paddingInner,float paddingOuter,float align,float band){float start=range[0];float stop=range[1];float rangeSpan=stop-start;vec2 domainStart=domainExtent.xy;float n=domainExtent[2];float step=rangeSpan/max(1.0,n-paddingInner+paddingOuter*2.0);start+=(rangeSpan-step*(n-paddingInner))*align;float bandwidth=step*(1.0-paddingInner);float inf=1.0/uZero;float hi=max(value[0]-domainStart[0],-inf);float lo=max(value[1]-domainStart[1],-inf);return dot(vec4(start,hi,lo,bandwidth),vec4(1.0,step,step,band));}";
1
+ const shader = "uniform highp float uZero;vec3 getDiscreteColor(sampler2D s,int index){return texelFetch(s,ivec2(index % textureSize(s,0).x,0),0).rgb;}vec3 getInterpolatedColor(sampler2D s,float unitValue){return texture(s,vec2(unitValue,0.0)).rgb;}float clampToRange(float value,vec2 range){return clamp(value,min(range[0],range[1]),max(range[0],range[1]));}float scaleIdentity(float value){return value;}float scaleIdentity(uint value){return float(value);}float scaleLinear(float value,vec2 domain,vec2 range){float domainSpan=domain[1]-domain[0];float rangeSpan=range[1]-range[0];return(value-domain[0])/domainSpan*rangeSpan+range[0];}float scaleLog(float value,vec2 domain,vec2 range,float base){return scaleLinear(log(value)/log(base),log(domain)/log(base),range);}float symlog(float value,float constant){return sign(value)*log(abs(value/constant)+1.0);}float scaleSymlog(float value,vec2 domain,vec2 range,float constant){return scaleLinear(symlog(value,constant),vec2(symlog(domain[0],constant),symlog(domain[1],constant)),range);}float scalePow(float value,vec2 domain,vec2 range,float exponent){return scaleLinear(pow(abs(value),exponent)*sign(value),pow(abs(domain),vec2(exponent))*sign(domain),range);}float scaleBand(uint value,vec2 domainExtent,vec2 range,float paddingInner,float paddingOuter,float align,float band){float start=range[0];float stop=range[1];float rangeSpan=stop-start;float n=domainExtent[1]-domainExtent[0];paddingInner=int(n)>1 ? paddingInner : 0.0;float step=rangeSpan/max(1.0,n-paddingInner+paddingOuter*2.0);start+=(rangeSpan-step*(n-paddingInner))*align;float bandwidth=step*(1.0-paddingInner);return start+(float(value)-domainExtent[0])*step+bandwidth*band;}const int lowBits=12;const float lowDivisor=pow(2.0,float(lowBits));const uint lowMask=uint(lowDivisor-1.0);vec2 splitUint(uint value){uint valueLo=value&lowMask;uint valueHi=value-valueLo;return vec2(float(valueHi),float(valueLo));}/***High precision variant of scaleBand for index/locus scales*/float scaleBandHp(uint value,vec3 domainExtent,vec2 range,float paddingInner,float paddingOuter,float align,float band){float start=range[0];float stop=range[1];float rangeSpan=stop-start;vec2 domainStart=domainExtent.xy;float n=domainExtent[2];float step=rangeSpan/max(1.0,n-paddingInner+paddingOuter*2.0);start+=(rangeSpan-step*(n-paddingInner))*align;float bandwidth=step*(1.0-paddingInner);vec2 splitValue=splitUint(value);float inf=1.0/uZero;float hi=max(splitValue[0]-domainStart[0],-inf);float lo=max(splitValue[1]-domainStart[1],-inf);return dot(vec4(start,hi,lo,bandwidth),vec4(1.0,step,step,band));}/***High precision variant of scaleBand for index/locus scales for large*domains where 32bit uints are not sufficient to represent the domain.*/float scaleBandHp(uvec2 value,vec3 domainExtent,vec2 range,float paddingInner,float paddingOuter,float align,float band){float start=range[0];float stop=range[1];float rangeSpan=stop-start;vec2 domainStart=domainExtent.xy;float n=domainExtent[2];float step=rangeSpan/max(1.0,n-paddingInner+paddingOuter*2.0);start+=(rangeSpan-step*(n-paddingInner))*align;float bandwidth=step*(1.0-paddingInner);vec2 splitValue=vec2(float(value[0])*lowDivisor,float(value[1]));float inf=1.0/uZero;float hi=max(splitValue[0]-domainStart[0],-inf);float lo=max(splitValue[1]-domainStart[1],-inf);return dot(vec4(start,hi,lo,bandwidth),vec4(1.0,step,step,band));}";
2
2
  export default shader;