@genome-spy/core 0.54.0 → 0.56.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 (120) hide show
  1. package/dist/bundle/index.es.js +3867 -3671
  2. package/dist/bundle/index.js +99 -86
  3. package/dist/schema.json +4 -0
  4. package/dist/src/data/collector.d.ts.map +1 -1
  5. package/dist/src/data/collector.js +4 -0
  6. package/dist/src/data/flowNode.d.ts +14 -5
  7. package/dist/src/data/flowNode.d.ts.map +1 -1
  8. package/dist/src/data/flowNode.js +30 -7
  9. package/dist/src/data/sources/dataSource.d.ts +1 -2
  10. package/dist/src/data/sources/dataSource.d.ts.map +1 -1
  11. package/dist/src/data/sources/dataSource.js +0 -1
  12. package/dist/src/data/sources/inlineSource.d.ts +4 -0
  13. package/dist/src/data/sources/inlineSource.d.ts.map +1 -1
  14. package/dist/src/data/sources/inlineSource.js +18 -0
  15. package/dist/src/data/sources/lazy/axisGenomeSource.d.ts.map +1 -1
  16. package/dist/src/data/sources/lazy/axisGenomeSource.js +4 -0
  17. package/dist/src/data/sources/lazy/axisTickSource.d.ts.map +1 -1
  18. package/dist/src/data/sources/lazy/axisTickSource.js +4 -0
  19. package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -1
  20. package/dist/src/data/sources/lazy/bamSource.js +4 -0
  21. package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
  22. package/dist/src/data/sources/lazy/bigBedSource.js +4 -0
  23. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
  24. package/dist/src/data/sources/lazy/bigWigSource.js +4 -0
  25. package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
  26. package/dist/src/data/sources/lazy/gff3Source.js +4 -0
  27. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
  28. package/dist/src/data/sources/lazy/indexedFastaSource.js +4 -0
  29. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +2 -0
  30. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
  31. package/dist/src/data/sources/lazy/singleAxisLazySource.js +2 -0
  32. package/dist/src/data/sources/namedSource.d.ts.map +1 -1
  33. package/dist/src/data/sources/namedSource.js +4 -0
  34. package/dist/src/data/sources/sequenceSource.d.ts.map +1 -1
  35. package/dist/src/data/sources/sequenceSource.js +4 -0
  36. package/dist/src/data/sources/urlSource.d.ts.map +1 -1
  37. package/dist/src/data/sources/urlSource.js +4 -0
  38. package/dist/src/data/transforms/aggregate.d.ts +2 -2
  39. package/dist/src/data/transforms/aggregate.d.ts.map +1 -1
  40. package/dist/src/data/transforms/aggregate.js +4 -3
  41. package/dist/src/data/transforms/clone.d.ts +2 -2
  42. package/dist/src/data/transforms/clone.d.ts.map +1 -1
  43. package/dist/src/data/transforms/clone.js +4 -3
  44. package/dist/src/data/transforms/coverage.d.ts +2 -2
  45. package/dist/src/data/transforms/coverage.d.ts.map +1 -1
  46. package/dist/src/data/transforms/coverage.js +4 -3
  47. package/dist/src/data/transforms/filter.d.ts +2 -2
  48. package/dist/src/data/transforms/filter.d.ts.map +1 -1
  49. package/dist/src/data/transforms/filter.js +3 -3
  50. package/dist/src/data/transforms/filterScoredLabels.d.ts +2 -2
  51. package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
  52. package/dist/src/data/transforms/filterScoredLabels.js +4 -3
  53. package/dist/src/data/transforms/flatten.d.ts +3 -2
  54. package/dist/src/data/transforms/flatten.d.ts.map +1 -1
  55. package/dist/src/data/transforms/flatten.js +6 -3
  56. package/dist/src/data/transforms/flattenCompressedExons.d.ts +2 -2
  57. package/dist/src/data/transforms/flattenCompressedExons.d.ts.map +1 -1
  58. package/dist/src/data/transforms/flattenCompressedExons.js +4 -3
  59. package/dist/src/data/transforms/flattenDelimited.d.ts +2 -2
  60. package/dist/src/data/transforms/flattenDelimited.d.ts.map +1 -1
  61. package/dist/src/data/transforms/flattenDelimited.js +4 -3
  62. package/dist/src/data/transforms/flattenSequence.d.ts +3 -2
  63. package/dist/src/data/transforms/flattenSequence.d.ts.map +1 -1
  64. package/dist/src/data/transforms/flattenSequence.js +6 -3
  65. package/dist/src/data/transforms/formula.d.ts +2 -2
  66. package/dist/src/data/transforms/formula.d.ts.map +1 -1
  67. package/dist/src/data/transforms/formula.js +4 -3
  68. package/dist/src/data/transforms/identifier.d.ts +2 -2
  69. package/dist/src/data/transforms/identifier.d.ts.map +1 -1
  70. package/dist/src/data/transforms/identifier.js +4 -3
  71. package/dist/src/data/transforms/linearizeGenomicCoordinate.d.ts +3 -2
  72. package/dist/src/data/transforms/linearizeGenomicCoordinate.d.ts.map +1 -1
  73. package/dist/src/data/transforms/linearizeGenomicCoordinate.js +11 -4
  74. package/dist/src/data/transforms/measureText.d.ts +5 -4
  75. package/dist/src/data/transforms/measureText.d.ts.map +1 -1
  76. package/dist/src/data/transforms/measureText.js +11 -8
  77. package/dist/src/data/transforms/pileup.d.ts +2 -2
  78. package/dist/src/data/transforms/pileup.d.ts.map +1 -1
  79. package/dist/src/data/transforms/pileup.js +4 -3
  80. package/dist/src/data/transforms/project.d.ts +3 -2
  81. package/dist/src/data/transforms/project.d.ts.map +1 -1
  82. package/dist/src/data/transforms/project.js +6 -3
  83. package/dist/src/data/transforms/regexExtract.d.ts +3 -2
  84. package/dist/src/data/transforms/regexExtract.d.ts.map +1 -1
  85. package/dist/src/data/transforms/regexExtract.js +6 -3
  86. package/dist/src/data/transforms/regexFold.d.ts +3 -2
  87. package/dist/src/data/transforms/regexFold.d.ts.map +1 -1
  88. package/dist/src/data/transforms/regexFold.js +6 -3
  89. package/dist/src/data/transforms/sample.d.ts +3 -2
  90. package/dist/src/data/transforms/sample.d.ts.map +1 -1
  91. package/dist/src/data/transforms/sample.js +5 -3
  92. package/dist/src/data/transforms/stack.d.ts +2 -2
  93. package/dist/src/data/transforms/stack.d.ts.map +1 -1
  94. package/dist/src/data/transforms/stack.js +4 -3
  95. package/dist/src/data/transforms/transform.d.ts +10 -0
  96. package/dist/src/data/transforms/transform.d.ts.map +1 -0
  97. package/dist/src/data/transforms/transform.js +22 -0
  98. package/dist/src/gl/glslScaleGenerator.d.ts +1 -0
  99. package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
  100. package/dist/src/gl/glslScaleGenerator.js +3 -10
  101. package/dist/src/gl/includes/common.glsl.js +1 -1
  102. package/dist/src/gl/webGLHelper.d.ts +8 -0
  103. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  104. package/dist/src/gl/webGLHelper.js +40 -0
  105. package/dist/src/marks/mark.d.ts +8 -0
  106. package/dist/src/marks/mark.d.ts.map +1 -1
  107. package/dist/src/marks/mark.js +86 -19
  108. package/dist/src/marks/rule.d.ts.map +1 -1
  109. package/dist/src/marks/rule.js +23 -22
  110. package/dist/src/selection/selection.d.ts +24 -0
  111. package/dist/src/selection/selection.d.ts.map +1 -1
  112. package/dist/src/selection/selection.js +73 -2
  113. package/dist/src/spec/parameter.d.ts +3 -2
  114. package/dist/src/types/selectionTypes.d.ts +2 -2
  115. package/dist/src/view/axisView.js +2 -2
  116. package/dist/src/view/paramMediator.d.ts.map +1 -1
  117. package/dist/src/view/paramMediator.js +14 -8
  118. package/dist/src/view/unitView.d.ts.map +1 -1
  119. package/dist/src/view/unitView.js +46 -10
  120. package/package.json +2 -2
@@ -12,12 +12,13 @@ export function sampleIterable<T, R>(n: number, iterable: Iterable<T>, accessor:
12
12
  /**
13
13
  * A reservoir sampler, based on: https://www.wikiwand.com/en/Reservoir_sampling
14
14
  */
15
- export default class SampleTransform extends FlowNode {
15
+ export default class SampleTransform extends Transform {
16
16
  /**
17
17
  *
18
18
  * @param {import("../../spec/transform.js").SampleParams} params
19
19
  */
20
20
  constructor(params: import("../../spec/transform.js").SampleParams);
21
+ params: import("../../spec/transform.js").SampleParams;
21
22
  k: number;
22
23
  /** @type {any[]} */
23
24
  reservoir: any[];
@@ -38,5 +39,5 @@ export default class SampleTransform extends FlowNode {
38
39
  _finalIngester(item: any): void;
39
40
  _setNextStop(): void;
40
41
  }
41
- import FlowNode from "../flowNode.js";
42
+ import Transform from "./transform.js";
42
43
  //# sourceMappingURL=sample.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sample.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/sample.js"],"names":[],"mappings":"AA6EA;;;;;;;;;GASG;AACH,wCAPW,MAAM,wDAkBhB;AAhGD;;GAEG;AACH;IACI;;;OAGG;IACH,oBAFW,OAAO,yBAAyB,EAAE,YAAY,EAOxD;IAFG,UAA2B;IAO3B,oBAAoB;IACpB,WADW,GAAG,EAAE,CACG;IACnB,qBAAqB;IACrB,GADW,MAAM,CACC;IAClB,kBAKO,GAAG,qBAgBH,GAAG,WArB2B;IAGzC;;;OAGG;IACH,uBAFW,GAAG,QAYb;IALO,UAAe;IACf,aAAkB;IAM1B;;;OAGG;IACH,qBAFW,GAAG,QAQb;IAED,qBAGC;CAiBJ;qBA3EoB,gBAAgB"}
1
+ {"version":3,"file":"sample.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/sample.js"],"names":[],"mappings":"AA+EA;;;;;;;;;GASG;AACH,wCAPW,MAAM,wDAkBhB;AAlGD;;GAEG;AACH;IACI;;;OAGG;IACH,oBAFW,OAAO,yBAAyB,EAAE,YAAY,EASxD;IAJG,uDAAoB;IAEpB,UAA2B;IAO3B,oBAAoB;IACpB,WADW,GAAG,EAAE,CACG;IACnB,qBAAqB;IACrB,GADW,MAAM,CACC;IAClB,kBAKO,GAAG,qBAgBH,GAAG,WArB2B;IAGzC;;;OAGG;IACH,uBAFW,GAAG,QAYb;IALO,UAAe;IACf,aAAkB;IAM1B;;;OAGG;IACH,qBAFW,GAAG,QAQb;IAED,qBAGC;CAiBJ;sBA7EqB,gBAAgB"}
@@ -1,15 +1,17 @@
1
- import FlowNode from "../flowNode.js";
1
+ import Transform from "./transform.js";
2
2
 
3
3
  /**
4
4
  * A reservoir sampler, based on: https://www.wikiwand.com/en/Reservoir_sampling
5
5
  */
6
- export default class SampleTransform extends FlowNode {
6
+ export default class SampleTransform extends Transform {
7
7
  /**
8
8
  *
9
9
  * @param {import("../../spec/transform.js").SampleParams} params
10
10
  */
11
11
  constructor(params) {
12
- super();
12
+ super(params);
13
+
14
+ this.params = params;
13
15
 
14
16
  this.k = params.size || 500;
15
17
  this.reset();
@@ -1,4 +1,4 @@
1
- export default class StackTransform extends FlowNode {
1
+ export default class StackTransform extends Transform {
2
2
  /**
3
3
  * @param {import("../../spec/transform.js").StackParams} params
4
4
  */
@@ -7,5 +7,5 @@ export default class StackTransform extends FlowNode {
7
7
  /** @type {any[]} */
8
8
  buffer: any[];
9
9
  }
10
- import FlowNode from "../flowNode.js";
10
+ import Transform from "./transform.js";
11
11
  //# sourceMappingURL=stack.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/stack.js"],"names":[],"mappings":"AAKA;IAKI;;OAEG;IACH,oBAFW,OAAO,yBAAyB,EAAE,WAAW,EAQvD;IAJG,sDAAoB;IAEpB,oBAAoB;IACpB,QADW,GAAG,EAAE,CACA;CAmHvB;qBAnI2C,gBAAgB"}
1
+ {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/stack.js"],"names":[],"mappings":"AAMA;IAKI;;OAEG;IACH,oBAFW,OAAO,yBAAyB,EAAE,WAAW,EAQvD;IAJG,sDAAoB;IAEpB,oBAAoB;IACpB,QADW,GAAG,EAAE,CACA;CAmHvB;sBAlIqB,gBAAgB"}
@@ -1,9 +1,10 @@
1
1
  import { compare } from "vega-util";
2
2
  import { groups as d3groups, sum as d3sum } from "d3-array";
3
- import FlowNode, { BEHAVIOR_MODIFIES } from "../flowNode.js";
3
+ import { BEHAVIOR_MODIFIES } from "../flowNode.js";
4
4
  import { field } from "../../utils/field.js";
5
+ import Transform from "./transform.js";
5
6
 
6
- export default class StackTransform extends FlowNode {
7
+ export default class StackTransform extends Transform {
7
8
  get behavior() {
8
9
  return BEHAVIOR_MODIFIES;
9
10
  }
@@ -12,7 +13,7 @@ export default class StackTransform extends FlowNode {
12
13
  * @param {import("../../spec/transform.js").StackParams} params
13
14
  */
14
15
  constructor(params) {
15
- super();
16
+ super(params);
16
17
  this.params = params;
17
18
 
18
19
  /** @type {any[]} */
@@ -0,0 +1,10 @@
1
+ export default class Transform extends FlowNode {
2
+ /**
3
+ * @param {import("../../spec/transform.js").TransformParamsBase} params
4
+ * @param {import("../flowNode.js").ParamMediatorProvider} [paramMediatorProvider]
5
+ */
6
+ constructor(params: import("../../spec/transform.js").TransformParamsBase, paramMediatorProvider?: import("../flowNode.js").ParamMediatorProvider);
7
+ #private;
8
+ }
9
+ import FlowNode from "../flowNode.js";
10
+ //# sourceMappingURL=transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/transform.js"],"names":[],"mappings":"AAEA;IAII;;;OAGG;IACH,oBAHW,OAAO,yBAAyB,EAAE,mBAAmB,0BACrD,OAAO,gBAAgB,EAAE,qBAAqB,EAKxD;;CAQJ;qBArBoB,gBAAgB"}
@@ -0,0 +1,22 @@
1
+ import FlowNode from "../flowNode.js";
2
+
3
+ export default class Transform extends FlowNode {
4
+ /** @type {string} */
5
+ #label;
6
+
7
+ /**
8
+ * @param {import("../../spec/transform.js").TransformParamsBase} params
9
+ * @param {import("../flowNode.js").ParamMediatorProvider} [paramMediatorProvider]
10
+ */
11
+ constructor(params, paramMediatorProvider) {
12
+ super(paramMediatorProvider);
13
+ this.#label = params.type;
14
+ }
15
+
16
+ /**
17
+ * @returns {string}
18
+ */
19
+ get label() {
20
+ return this.#label;
21
+ }
22
+ }
@@ -141,6 +141,7 @@ export const SCALE_FUNCTION_PREFIX: "scale_";
141
141
  export const SCALED_FUNCTION_PREFIX: "getScaled_";
142
142
  export const RANGE_TEXTURE_PREFIX: "uRangeTexture_";
143
143
  export const PARAM_PREFIX: "uParam_";
144
+ export const SELECTION_CHECKER_PREFIX: "checkSelection_";
144
145
  export function getRangeForGlsl(scale: any, channel: Channel): number[];
145
146
  export type Channel = import("../spec/channel.js").Channel;
146
147
  export type AccessorParts = {
@@ -1 +1 @@
1
- {"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":";AAqDA;;;;;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,UAuClD;AAmED;;GAEG;AACH,qDAFW,OAAO,6BAQjB;AA+CD;;;;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,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;AAwBD;;;;GAIG;AACH,uCAJW,MAAM,EAAE,cACR,MAAM,EAAE,GACN,MAAM,CAgClB;AAr1BD,uCAAwC;AACxC,uCAAwC;AACxC,oCAAqC;AACrC,mDAAoD;AACpD,6CAA8C;AAC9C,kDAAmD;AACnD,oDAAqD;AACrD,qCAAsC;AAmyB/B,uCAJI,GAAG,WACH,OAAO,GACL,MAAM,EAAE,CAQF;sBAnyBN,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;;;;;8BA6fZ,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBAgMhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BApvBJ,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,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;AA+CD;;;;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,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;AAwBD;;;;GAIG;AACH,uCAJW,MAAM,EAAE,cACR,MAAM,EAAE,GACN,MAAM,CAgClB;AA90BD,uCAAwC;AACxC,uCAAwC;AACxC,oCAAqC;AACrC,mDAAoD;AACpD,6CAA8C;AAC9C,kDAAmD;AACnD,oDAAqD;AACrD,qCAAsC;AACtC,yDAA0D;AA2xBnD,uCAJI,GAAG,WACH,OAAO,GACL,MAAM,EAAE,CAQF;sBA3xBN,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;;;;uBAgMhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BA7uBJ,WAAW"}
@@ -16,7 +16,7 @@ import {
16
16
  } from "../encoder/encoder.js";
17
17
  import { asArray, peek } from "../utils/arrayUtils.js";
18
18
  import { InternMap } from "internmap";
19
- import { isExprRef, validateParameterName } from "../view/paramMediator.js";
19
+ import { isExprRef } from "../view/paramMediator.js";
20
20
  import scaleNull from "../utils/scaleNull.js";
21
21
 
22
22
  export const ATTRIBUTE_PREFIX = "attr_";
@@ -27,6 +27,7 @@ export const SCALE_FUNCTION_PREFIX = "scale_";
27
27
  export const SCALED_FUNCTION_PREFIX = "getScaled_";
28
28
  export const RANGE_TEXTURE_PREFIX = "uRangeTexture_";
29
29
  export const PARAM_PREFIX = "uParam_";
30
+ export const SELECTION_CHECKER_PREFIX = "checkSelection_";
30
31
 
31
32
  // https://stackoverflow.com/a/47543127
32
33
  const FLT_MAX = 3.402823466e38;
@@ -523,16 +524,8 @@ export function generateConditionalEncoderGlsl(channel, accessors) {
523
524
  const accessorFunctionName = makeAccessorFunctionName(channel, i);
524
525
  const { param, empty } = accessor.predicate;
525
526
 
526
- const paramUniform = PARAM_PREFIX + validateParameterName(param);
527
- const idAttribute = ATTRIBUTE_PREFIX + "uniqueId";
528
-
529
- // Hardcoded condition for single point selection ... for now.
530
527
  conditions.push(
531
- param
532
- ? `${idAttribute} == ${paramUniform}${
533
- empty ? ` || ${paramUniform} == uint(0)` : ""
534
- }`
535
- : null
528
+ param ? `${SELECTION_CHECKER_PREFIX}${param}(${!!empty})` : null
536
529
  );
537
530
 
538
531
  statements.push(
@@ -1,2 +1,2 @@
1
- const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}/***Calculates a gamma for antialiasing opacity based on the color.*/float getGammaForColor(vec3 rgb){return mix(1.25,0.75,smoothstep(0.0,1.0,dot(rgb,vec3(0.299,0.587,0.114))));}/***Specialized linearstep for doing antialiasing*/float distanceToRatio(float d){return clamp(d*uDevicePixelRatio+0.5,0.0,1.0);}vec4 distanceToColor(float d,vec4 fill,vec4 stroke,float halfStrokeWidth){if(halfStrokeWidth>0.0){float sd=abs(d)-halfStrokeWidth;return mix(stroke,d<=0.0 ? fill : vec4(0.0),distanceToRatio(sd));}else{return fill*distanceToRatio(-d);}}";
1
+ const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}bool isEmptyBinarySearchTexture(highp usampler2D s){return textureSize(s,0).x==1&&texelFetch(s,ivec2(0,0),0).r==0u;}bool binarySearchTexture(highp usampler2D s,uint value){int texSize=textureSize(s,0).x;int left=0;int right=texSize-1;while(left<=right){int mid=left+(right-left)/2;uint midValue=texelFetch(s,ivec2(mid,0),0).r;if(midValue==value){return true;}if(midValue<value){left=mid+1;}else{right=mid-1;}}return false;}/***Calculates a gamma for antialiasing opacity based on the color.*/float getGammaForColor(vec3 rgb){return mix(1.25,0.75,smoothstep(0.0,1.0,dot(rgb,vec3(0.299,0.587,0.114))));}/***Specialized linearstep for doing antialiasing*/float distanceToRatio(float d){return clamp(d*uDevicePixelRatio+0.5,0.0,1.0);}vec4 distanceToColor(float d,vec4 fill,vec4 stroke,float halfStrokeWidth){if(halfStrokeWidth>0.0){float sd=abs(d)-halfStrokeWidth;return mix(stroke,d<=0.0 ? fill : vec4(0.0),distanceToRatio(sd));}else{return fill*distanceToRatio(-d);}}";
2
2
  export default shader;
@@ -40,6 +40,10 @@ export default class WebGLHelper {
40
40
  _shaderCache: Map<string, WebGLShader>;
41
41
  /** @type {WeakMap<import("../view/scaleResolution.js").default, WebGLTexture>} */
42
42
  rangeTextures: WeakMap<import("../view/scaleResolution.js").default, WebGLTexture>;
43
+ /**
44
+ * @type {WeakMap<import("../types/selectionTypes.js").MultiPointSelection, WebGLTexture>}
45
+ */
46
+ selectionTextures: WeakMap<import("../types/selectionTypes.js").MultiPointSelection, WebGLTexture>;
43
47
  canvas: HTMLCanvasElement;
44
48
  gl: WebGL2RenderingContext;
45
49
  /** @type {import("twgl.js").AttachmentOptions[]} */
@@ -100,5 +104,9 @@ export default class WebGLHelper {
100
104
  * @param {boolean} update Update the texture if it exists already.
101
105
  */
102
106
  createRangeTexture(resolution: import("../view/scaleResolution.js").default, update?: boolean): void;
107
+ /**
108
+ * @param {import("../types/selectionTypes.js").MultiPointSelection} selection
109
+ */
110
+ createSelectionTexture(selection: import("../types/selectionTypes.js").MultiPointSelection, update?: boolean): void;
103
111
  }
104
112
  //# sourceMappingURL=webGLHelper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"AAmaA;;;;GAIG;AACH,kCAJW,sBAAsB,gBACtB,WAAW,kBACX,WAAW;;;;;;EA8CrB;AAED;;;;;GAKG;AACH,0CALW,qBAAqB,WACrB,KAAK,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,OAC7C,MAAM,EAAE,GAAG,eAAe,YAC1B,YAAY,gBAYtB;AAxcD;IACI;;;;;;;;OAQG;IACH,uBAPW,WAAW,eACX,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,eAGrC,MAAM,2BACN,sBAAsB,EAyFhC;IAjFG,wBAA2B;IAC3B;;;MAKO;IAEP,uCAAuC;IACvC,cADW,IAAI,MAAM,EAAE,WAAW,CAAC,CACN;IAE7B,kFAAkF;IAClF,eADW,QAAQ,OAAO,4BAA4B,EAAE,OAAO,EAAE,YAAY,CAAC,CAC5C;IAwClC,0BAAoB;IACpB,2BAAY;IAGZ,oDAAoD;IACpD,2BADW,OAAO,SAAS,EAAE,iBAAiB,EAAE,CAQ/C;IACD,sDAGC;IAOD,+CAA+C;IAC/C,aADW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CACZ;IAOnC,uBAIC;IAHG;;;MAAmC;IAKvC,mBAEC;IADG,YAAkC;IAGtC;;;;;OAKG;IACH,oBAHW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,eA2B3B;IAED,iBAcC;IAED,iBAEC;IAED;;;;OAIG;IACH,oCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;;MAQ3C;IAED;;OAEG;IACH;;;MAuBC;IAED;;;;OAIG;IACH,oBAHW,MAAM,KACN,MAAM,cAwBhB;IAED,iBAOC;IAED;;;;;;;;;OASG;IACH,+BAHW,OAAO,4BAA4B,EAAE,OAAO,WAC5C,OAAO,QA0GjB;CACJ"}
1
+ {"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"AA2cA;;;;GAIG;AACH,kCAJW,sBAAsB,gBACtB,WAAW,kBACX,WAAW;;;;;;EA8CrB;AAED;;;;;GAKG;AACH,0CALW,qBAAqB,WACrB,KAAK,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,OAC7C,MAAM,EAAE,GAAG,eAAe,YAC1B,YAAY,gBAYtB;AA/eD;IACI;;;;;;;;OAQG;IACH,uBAPW,WAAW,eACX,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,eAGrC,MAAM,2BACN,sBAAsB,EA8FhC;IAtFG,wBAA2B;IAC3B;;;MAKO;IAEP,uCAAuC;IACvC,cADW,IAAI,MAAM,EAAE,WAAW,CAAC,CACN;IAE7B,kFAAkF;IAClF,eADW,QAAQ,OAAO,4BAA4B,EAAE,OAAO,EAAE,YAAY,CAAC,CAC5C;IAElC;;OAEG;IACH,mBAFU,QAAQ,OAAO,4BAA4B,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAEnD;IAwCtC,0BAAoB;IACpB,2BAAY;IAGZ,oDAAoD;IACpD,2BADW,OAAO,SAAS,EAAE,iBAAiB,EAAE,CAQ/C;IACD,sDAGC;IAOD,+CAA+C;IAC/C,aADW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CACZ;IAOnC,uBAIC;IAHG;;;MAAmC;IAKvC,mBAEC;IADG,YAAkC;IAGtC;;;;;OAKG;IACH,oBAHW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,eA2B3B;IAED,iBAcC;IAED,iBAEC;IAED;;;;OAIG;IACH,oCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;;MAQ3C;IAED;;OAEG;IACH;;;MAuBC;IAED;;;;OAIG;IACH,oBAHW,MAAM,KACN,MAAM,cAwBhB;IAED,iBAOC;IAED;;;;;;;;;OASG;IACH,+BAHW,OAAO,4BAA4B,EAAE,OAAO,WAC5C,OAAO,QA0GjB;IAED;;OAEG;IACH,kCAFW,OAAO,4BAA4B,EAAE,mBAAmB,0BA+BlE;CACJ"}
@@ -27,6 +27,7 @@ import {
27
27
  isDiscreteChannel,
28
28
  } from "../encoder/encoder.js";
29
29
  import { color } from "d3-color";
30
+ import { isMultiPointSelection } from "../selection/selection.js";
30
31
 
31
32
  export default class WebGLHelper {
32
33
  /**
@@ -58,6 +59,11 @@ export default class WebGLHelper {
58
59
  /** @type {WeakMap<import("../view/scaleResolution.js").default, WebGLTexture>} */
59
60
  this.rangeTextures = new WeakMap();
60
61
 
62
+ /**
63
+ * @type {WeakMap<import("../types/selectionTypes.js").MultiPointSelection, WebGLTexture>}
64
+ */
65
+ this.selectionTextures = new WeakMap();
66
+
61
67
  // --------------------------------------------------------
62
68
 
63
69
  const canvas = document.createElement("canvas");
@@ -384,6 +390,40 @@ export default class WebGLHelper {
384
390
  }
385
391
  }
386
392
  }
393
+
394
+ /**
395
+ * @param {import("../types/selectionTypes.js").MultiPointSelection} selection
396
+ */
397
+ createSelectionTexture(selection, update = true) {
398
+ if (!isMultiPointSelection(selection)) {
399
+ throw new Error(
400
+ "Not a multi-point selection, cannot create texture"
401
+ );
402
+ }
403
+
404
+ const keys = Array.from(selection.data.keys());
405
+ // Zero is a special value for no selection. The minimum texture size is 1.
406
+ const uniqueIds = keys.length > 0 ? keys.sort((a, b) => a - b) : [0];
407
+
408
+ const existingTexture = this.selectionTextures.get(selection);
409
+
410
+ const gl = this.gl;
411
+ const texture = createOrUpdateTexture(
412
+ this.gl,
413
+ {
414
+ level: 0,
415
+ minMag: gl.NEAREST,
416
+ format: gl.RED_INTEGER,
417
+ internalFormat: gl.R32UI,
418
+ height: 1,
419
+ width: uniqueIds.length,
420
+ },
421
+ new Uint32Array(uniqueIds),
422
+ update ? existingTexture : false
423
+ );
424
+
425
+ this.selectionTextures.set(selection, texture);
426
+ }
387
427
  }
388
428
 
389
429
  /**
@@ -1,6 +1,7 @@
1
1
  /// <reference types="external-typings/internmap.js" />
2
2
  export const SAMPLE_FACET_UNIFORM: "SAMPLE_FACET_UNIFORM";
3
3
  export const SAMPLE_FACET_TEXTURE: "SAMPLE_FACET_TEXTURE";
4
+ export const SELECTION_TEXTURE_PREFIX: "uSelectionTexture_";
4
5
  /**
5
6
  *
6
7
  * @typedef {import("../types/rendering.js").RenderingOptions} RenderingOptions
@@ -69,6 +70,13 @@ export default class Mark<P extends import("../spec/mark.js").MarkProps = import
69
70
  * @protected
70
71
  */
71
72
  protected markUniformsAltered: boolean;
73
+ /**
74
+ * Functions that set textures for multi-selection parameters.
75
+ *
76
+ * @type {(() => void)[]}
77
+ * @private
78
+ */
79
+ private selectionTextureOps;
72
80
  /** @type {RangeMap<any>} keep track of facet locations within the vertex array */
73
81
  rangeMap: RangeMap<any>;
74
82
  defaultProperties: P;
@@ -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,6 +34,7 @@ import {
34
34
  generateConditionalEncoderGlsl,
35
35
  PARAM_PREFIX,
36
36
  ATTRIBUTE_PREFIX,
37
+ SELECTION_CHECKER_PREFIX,
37
38
  } from "../gl/glslScaleGenerator.js";
38
39
  import GLSL_COMMON from "../gl/includes/common.glsl.js";
39
40
  import GLSL_SCALES from "../gl/includes/scales.glsl.js";
@@ -48,11 +49,16 @@ import { InternMap } from "internmap";
48
49
  import ViewError from "../view/viewError.js";
49
50
  import { isExprRef, validateParameterName } from "../view/paramMediator.js";
50
51
  import { UNIQUE_ID_KEY } from "../data/transforms/identifier.js";
51
- import { isSinglePointSelection } from "../selection/selection.js";
52
+ import {
53
+ isMultiPointSelection,
54
+ isSinglePointSelection,
55
+ } from "../selection/selection.js";
52
56
 
53
57
  export const SAMPLE_FACET_UNIFORM = "SAMPLE_FACET_UNIFORM";
54
58
  export const SAMPLE_FACET_TEXTURE = "SAMPLE_FACET_TEXTURE";
55
59
 
60
+ export const SELECTION_TEXTURE_PREFIX = "uSelectionTexture_";
61
+
56
62
  /**
57
63
  *
58
64
  * @typedef {import("../types/rendering.js").RenderingOptions} RenderingOptions
@@ -146,6 +152,14 @@ export default class Mark {
146
152
  */
147
153
  this.markUniformsAltered = true;
148
154
 
155
+ /**
156
+ * Functions that set textures for multi-selection parameters.
157
+ *
158
+ * @type {(() => void)[]}
159
+ * @private
160
+ */
161
+ this.selectionTextureOps = [];
162
+
149
163
  /** @type {RangeMap<any>} keep track of facet locations within the vertex array */
150
164
  this.rangeMap = new RangeMap();
151
165
 
@@ -456,7 +470,8 @@ export default class Mark {
456
470
 
457
471
  for (const predicate of paramPredicates) {
458
472
  const param = predicate.param;
459
- const selection = this.unitView.paramMediator.getValue(param);
473
+ const paramMediator = this.unitView.paramMediator;
474
+ const selection = paramMediator.getValue(param);
460
475
 
461
476
  // The selection is supposed to have an empty value at this point
462
477
  // so that we can figure out the type of the selection.
@@ -466,6 +481,8 @@ export default class Mark {
466
481
  );
467
482
  }
468
483
 
484
+ const uniqueIdAttr = ATTRIBUTE_PREFIX + "uniqueId";
485
+
469
486
  if (isSinglePointSelection(selection)) {
470
487
  // Register a mark uniform for each param. The uniform will have
471
488
  // the value of uniqueId of the selected datum.
@@ -487,13 +504,63 @@ export default class Mark {
487
504
  ) => selection.uniqueId ?? 0
488
505
  );
489
506
  });
507
+ scaleCode.push(
508
+ `bool ${SELECTION_CHECKER_PREFIX}${param}(bool empty) {\n` +
509
+ ` return ${PARAM_PREFIX}${param} == ${uniqueIdAttr} || (empty && ${PARAM_PREFIX}${param} == 0u);\n` +
510
+ `}`
511
+ );
512
+ }
513
+ } else if (isMultiPointSelection(selection)) {
514
+ // We need a texture for each multi-selection parameter.
515
+ // The texture contains the uniqueIds of the selected data objects sorted
516
+ // in ascending order, which allows for binary search.
517
+ if (!selectionParameterUniforms.has(param)) {
518
+ selectionParameterUniforms.set(param, "multi");
519
+
520
+ const uniformName =
521
+ SELECTION_TEXTURE_PREFIX + validateParameterName(param);
522
+ scaleCode.push(
523
+ `// Selection texture\nuniform highp usampler2D ${uniformName};`
524
+ );
525
+
526
+ const glHelper = this.getContext().glHelper;
527
+ const selectionTextures = glHelper.selectionTextures;
528
+
529
+ this.selectionTextureOps.push(() => {
530
+ // Texture is set in the prepareRender method
531
+ const selection = paramMediator.getValue(param);
532
+ const texture = selectionTextures.get(selection);
533
+ if (!texture) {
534
+ throw new Error(
535
+ `Bug: no selection texture found for "${param}"!`
536
+ );
537
+ }
538
+
539
+ setUniforms(this.programInfo, {
540
+ [uniformName]: texture,
541
+ });
542
+ });
543
+
544
+ const texName = SELECTION_TEXTURE_PREFIX + param;
545
+ scaleCode.push(
546
+ `bool ${SELECTION_CHECKER_PREFIX}${param}(bool empty) {\n` +
547
+ ` return binarySearchTexture(${texName}, ${uniqueIdAttr}) || (empty && isEmptyBinarySearchTexture(${texName}));\n` +
548
+ `}`
549
+ );
550
+
551
+ // Create the initial texture
552
+ glHelper.createSelectionTexture(selection);
553
+
554
+ const fn = paramMediator.createExpression(param);
555
+ fn.addListener(() => {
556
+ const selection =
557
+ /** @type {import("../types/selectionTypes.js").MultiPointSelection} */ (
558
+ fn(null)
559
+ );
560
+ glHelper.createSelectionTexture(selection);
561
+ this.getContext().animator.requestRender();
562
+ });
490
563
  }
491
- } else {
492
- throw new Error(
493
- `Unsupported selection (${param}) in condition: ${JSON.stringify(
494
- selection
495
- )}`
496
- );
497
564
  }
498
565
  }
499
566
 
@@ -686,18 +753,16 @@ export default class Mark {
686
753
  }
687
754
 
688
755
  // Generate a function that checks if the datum is subject to any point selection
689
- const conditions = [...selectionParameterUniforms.entries()]
690
- .filter(([, v]) => v == "single")
691
- .map(
692
- ([param]) =>
693
- `${PARAM_PREFIX}${param} == ${ATTRIBUTE_PREFIX}uniqueId`
694
- );
756
+ const conditions = [...selectionParameterUniforms.keys()].map(
757
+ (param) => `${SELECTION_CHECKER_PREFIX}${param}(false)`
758
+ );
759
+
695
760
  scaleCode.push(
696
- "bool isPointSelected() {",
697
- this.encoders.uniqueId && conditions.length > 0
698
- ? ` return ${conditions.join(" || ")};`
699
- : " return false;",
700
- "}"
761
+ "bool isPointSelected() {\n" +
762
+ (this.encoders.uniqueId && conditions.length > 0
763
+ ? ` return ${conditions.join(" || ")};`
764
+ : " return false;") +
765
+ "\n}"
701
766
  );
702
767
 
703
768
  const vertexPrecision = "precision highp float;\nprecision highp int;";
@@ -1046,6 +1111,8 @@ export default class Mark {
1046
1111
  }
1047
1112
  }
1048
1113
 
1114
+ ops.push(...this.selectionTextureOps);
1115
+
1049
1116
  if (this.getSampleFacetMode() == SAMPLE_FACET_TEXTURE) {
1050
1117
  ops.push(() => {
1051
1118
  /** @type {WebGLTexture} */
@@ -1 +1 @@
1
- {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../src/marks/rule.js"],"names":[],"mappings":"AAcA;;GAEG;AACH;IACI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EAoB/C;IAfG,wBAAwB;IA4GpB,0BAOE;CAgGb;iBA3OgB,WAAW"}
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../src/marks/rule.js"],"names":[],"mappings":"AAcA;;GAEG;AACH;IACI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EAoB/C;IAfG,wBAAwB;IAyGxB,0BAQE;CA+FT;iBAxOgB,WAAW"}
@@ -125,21 +125,18 @@ export default class RuleMark extends Mark {
125
125
  async initializeGraphics() {
126
126
  await super.initializeGraphics();
127
127
 
128
- if (this.properties.strokeDash) {
129
- const gl = this.gl;
130
- const textureData = createDashTextureArray(
131
- this.properties.strokeDash
132
- );
133
- this.dashTexture = createTexture(gl, {
134
- mag: gl.NEAREST,
135
- min: gl.NEAREST,
136
- internalFormat: gl.R8,
137
- format: gl.RED,
138
- src: textureData,
139
- height: 1,
140
- });
141
- this.dashTextureSize = textureData.length; // Not needed with WebGL2
142
- }
128
+ const gl = this.gl;
129
+ const textureData = createDashTextureArray(this.properties.strokeDash);
130
+ this.dashTexture = createTexture(gl, {
131
+ level: 0,
132
+ mag: gl.NEAREST,
133
+ min: gl.NEAREST,
134
+ internalFormat: gl.R8,
135
+ format: gl.RED,
136
+ src: textureData,
137
+ height: 1,
138
+ });
139
+ this.dashTextureSize = textureData.length; // Not needed with WebGL2
143
140
 
144
141
  this.createAndLinkShaders(VERTEX_SHADER, FRAGMENT_SHADER, [
145
142
  COMMON_SHADER,
@@ -196,13 +193,13 @@ export default class RuleMark extends Mark {
196
193
 
197
194
  ops.push(() => this.bindOrSetMarkUniformBlock());
198
195
 
199
- if (this.dashTexture) {
200
- ops.push(() =>
201
- setUniforms(this.programInfo, {
202
- uDashTexture: this.dashTexture,
203
- })
204
- );
205
- }
196
+ ops.push(() =>
197
+ // Dash texture must be set always. Otherwise the texture unit may have
198
+ // an incompatible texture from an earlier program.
199
+ setUniforms(this.programInfo, {
200
+ uDashTexture: this.dashTexture,
201
+ })
202
+ );
206
203
 
207
204
  ops.push(() =>
208
205
  setBuffersAndAttributes(
@@ -240,6 +237,10 @@ export default class RuleMark extends Mark {
240
237
  * @param {number[]} pattern
241
238
  */
242
239
  function createDashTextureArray(pattern) {
240
+ if (!pattern) {
241
+ return new Uint8Array(0);
242
+ }
243
+
243
244
  if (
244
245
  pattern.length == 0 ||
245
246
  pattern.length % 2 ||
@@ -3,6 +3,20 @@
3
3
  * @returns {import("../types/selectionTypes.js").SinglePointSelection}
4
4
  */
5
5
  export function createSinglePointSelection(datum: import("../data/flowNode.js").Datum): import("../types/selectionTypes.js").SinglePointSelection;
6
+ /**
7
+ * @param {import("../data/flowNode.js").Datum[]} [data]
8
+ * @returns {import("../types/selectionTypes.js").MultiPointSelection}
9
+ */
10
+ export function createMultiPointSelection(data?: import("../data/flowNode.js").Datum[]): import("../types/selectionTypes.js").MultiPointSelection;
11
+ /**
12
+ * Updates the backing data and returns a new instance of the selection object.
13
+ * A new instance is required to trigger reactivity in parameters.
14
+ *
15
+ * @param {import("../types/selectionTypes.js").MultiPointSelection} selection
16
+ * @param {Partial<Record<"add" | "remove" | "toggle", Iterable<import("../data/flowNode.js").Datum>>>} update
17
+ * @returns {import("../types/selectionTypes.js").MultiPointSelection}
18
+ */
19
+ export function updateMultiPointSelection(selection: import("../types/selectionTypes.js").MultiPointSelection, { add, remove, toggle }: Partial<Record<"add" | "remove" | "toggle", Iterable<import("../data/flowNode.js").Datum>>>): import("../types/selectionTypes.js").MultiPointSelection;
6
20
  /**
7
21
  * @param {import("../types/selectionTypes.js").Selection} selection
8
22
  * @param {import("../data/flowNode.js").Datum} datum
@@ -36,4 +50,14 @@ export function isMultiPointSelection(selection: import("../types/selectionTypes
36
50
  * @returns {selection is import("../types/selectionTypes.js").ProjectedSelection}
37
51
  */
38
52
  export function isProjectedSelection(selection: import("../types/selectionTypes.js").Selection): selection is import("../types/selectionTypes.js").ProjectedSelection;
53
+ /**
54
+ * @param {any} config
55
+ * @returns {config is import("../spec/parameter.js").PointSelectionConfig}
56
+ */
57
+ export function isPointSelectionConfig(config: any): config is import("../spec/parameter.js").PointSelectionConfig;
58
+ /**
59
+ * @param {string | import("../spec/parameter.js").PointSelectionConfig} config
60
+ * @returns {boolean}
61
+ */
62
+ export function isTogglingEnabledInPointSelectionConfig(config: string | import("../spec/parameter.js").PointSelectionConfig): boolean;
39
63
  //# sourceMappingURL=selection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/selection/selection.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,kDAHW,OAAO,qBAAqB,EAAE,KAAK,GACjC,OAAO,4BAA4B,EAAE,oBAAoB,CAQrE;AAED;;;;GAIG;AACH,yCAJW,OAAO,4BAA4B,EAAE,SAAS,SAC9C,OAAO,qBAAqB,EAAE,KAAK,UACnC,OAAO,WAkBjB;AAED;;GAEG;AACH,oDAFW;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,UAM1C;AAED;;;GAGG;AACH,4CAHW,OAAO,4BAA4B,EAAE,SAAS,oEAKxD;AAED;;;GAGG;AACH,kDAHW,OAAO,4BAA4B,EAAE,SAAS,0EAKxD;AAED;;;GAGG;AACH,iDAHW,OAAO,4BAA4B,EAAE,SAAS,yEAKxD;AAED;;;GAGG;AACH,gDAHW,OAAO,4BAA4B,EAAE,SAAS,wEAKxD"}
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/selection/selection.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,kDAHW,OAAO,qBAAqB,EAAE,KAAK,GACjC,OAAO,4BAA4B,EAAE,oBAAoB,CAQrE;AAED;;;GAGG;AACH,iDAHW,OAAO,qBAAqB,EAAE,KAAK,EAAE,GACnC,OAAO,4BAA4B,EAAE,mBAAmB,CAQpE;AAED;;;;;;;GAOG;AACH,qDAJW,OAAO,4BAA4B,EAAE,mBAAmB,2BACxD,QAAQ,OAAO,KAAK,GAAG,QAAQ,GAAG,QAAQ,EAAE,SAAS,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,GACzF,OAAO,4BAA4B,EAAE,mBAAmB,CA2BpE;AAED;;;;GAIG;AACH,yCAJW,OAAO,4BAA4B,EAAE,SAAS,SAC9C,OAAO,qBAAqB,EAAE,KAAK,UACnC,OAAO,WAkBjB;AAED;;GAEG;AACH,oDAFW;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,UAM1C;AAED;;;GAGG;AACH,4CAHW,OAAO,4BAA4B,EAAE,SAAS,oEAKxD;AAED;;;GAGG;AACH,kDAHW,OAAO,4BAA4B,EAAE,SAAS,0EAKxD;AAED;;;GAGG;AACH,iDAHW,OAAO,4BAA4B,EAAE,SAAS,yEAKxD;AAED;;;GAGG;AACH,gDAHW,OAAO,4BAA4B,EAAE,SAAS,wEAKxD;AAED;;;GAGG;AACH,+CAHW,GAAG,iEAUb;AAED;;;GAGG;AACH,gEAHW,MAAM,GAAG,OAAO,sBAAsB,EAAE,oBAAoB,GAC1D,OAAO,CAOnB"}