@genome-spy/core 0.43.3 → 0.44.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.
- package/dist/bundle/index.es.js +5525 -5259
- package/dist/bundle/index.js +153 -104
- package/dist/schema.json +412 -43
- package/dist/src/data/sources/lazy/axisTickSource.d.ts +1 -1
- package/dist/src/data/sources/lazy/axisTickSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/axisTickSource.js +2 -2
- package/dist/src/data/sources/lazy/bigWigSource.d.ts +6 -0
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +3 -5
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.js +1 -1
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts +7 -12
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +33 -29
- package/dist/src/data/transforms/filterScoredLabels.js +1 -1
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +16 -6
- package/dist/src/genomeSpy.d.ts +1 -0
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +108 -6
- package/dist/src/gl/glslScaleGenerator.d.ts +23 -3
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/gl/glslScaleGenerator.js +137 -42
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +5 -7
- package/dist/src/marks/link.common.glsl.js +2 -0
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +19 -9
- package/dist/src/marks/link.vertex.glsl.js +1 -1
- package/dist/src/marks/mark.d.ts +19 -17
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +181 -120
- package/dist/src/marks/point.common.glsl.js +1 -1
- package/dist/src/marks/rect.common.glsl.js +2 -0
- package/dist/src/marks/rect.d.ts.map +1 -1
- package/dist/src/marks/rect.js +12 -12
- package/dist/src/marks/rect.vertex.glsl.js +1 -1
- package/dist/src/marks/rule.common.glsl.js +1 -1
- package/dist/src/marks/rule.js +2 -2
- package/dist/src/marks/text.common.glsl.js +1 -1
- package/dist/src/marks/text.js +2 -2
- package/dist/src/paramBroker.d.ts +19 -3
- package/dist/src/paramBroker.d.ts.map +1 -1
- package/dist/src/paramBroker.js +18 -2
- package/dist/src/spec/channel.d.ts +4 -3
- package/dist/src/spec/mark.d.ts +17 -25
- package/dist/src/spec/parameter.d.ts +123 -0
- package/dist/src/spec/root.d.ts +9 -0
- package/dist/src/spec/scale.d.ts +2 -1
- package/dist/src/spec/view.d.ts +1 -1
- package/dist/src/types/scaleResolutionApi.d.ts +7 -3
- package/dist/src/utils/expression.d.ts +2 -2
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/expression.js +3 -3
- package/dist/src/view/axisView.js +3 -3
- package/dist/src/view/scaleResolution.d.ts +8 -18
- package/dist/src/view/scaleResolution.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.js +220 -126
- package/dist/src/view/scaleResolution.test.js +7 -7
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +10 -3
- package/dist/src/view/view.js +2 -2
- package/package.json +2 -2
|
@@ -35,11 +35,11 @@ export default class AxisTickSource extends SingleAxisLazySource {
|
|
|
35
35
|
this.params = params;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
onDomainChanged() {
|
|
39
39
|
// Note, although this function is async, it is not awaited. Data are updated
|
|
40
40
|
// synchronously to ensure that the new ticks are available before the next frame is drawn.
|
|
41
41
|
|
|
42
|
-
const scale = this.scaleResolution.
|
|
42
|
+
const scale = this.scaleResolution.scale;
|
|
43
43
|
const axisParams = this.params.axis;
|
|
44
44
|
const axisLength = this.getAxisLength();
|
|
45
45
|
|
|
@@ -9,6 +9,12 @@ export default class BigWigSource extends SingleAxisWindowedSource {
|
|
|
9
9
|
constructor(params: import("../../../spec/data.js").BigWigData, view: import("../../../view/view.js").default);
|
|
10
10
|
params: import("../../../spec/data.js").BigWigData;
|
|
11
11
|
initializedPromise: Promise<any>;
|
|
12
|
+
/**
|
|
13
|
+
* Listen to the domain change event and update data when the covered windows change.
|
|
14
|
+
*
|
|
15
|
+
* @param {number[]} domain Linearized domain
|
|
16
|
+
*/
|
|
17
|
+
onDomainChanged(domain: number[]): Promise<void>;
|
|
12
18
|
/**
|
|
13
19
|
* @param {number[]} interval linearized domain
|
|
14
20
|
* @param {number} reductionLevel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bigWigSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/bigWigSource.js"],"names":[],"mappings":"AAGA;;GAEG;AACH;IAOI;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,UAAU,QAC1C,OAAO,uBAAuB,EAAE,OAAO,EAiDjD;IAnCG,mDAAgC;IAQhC,iCA0BE;
|
|
1
|
+
{"version":3,"file":"bigWigSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/bigWigSource.js"],"names":[],"mappings":"AAGA;;GAEG;AACH;IAOI;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,UAAU,QAC1C,OAAO,uBAAuB,EAAE,OAAO,EAiDjD;IAnCG,mDAAgC;IAQhC,iCA0BE;IAGN;;;;OAIG;IACH,wBAFW,MAAM,EAAE,iBAqBlB;IAED;;;OAGG;IAEH,uBAJW,MAAM,EAAE,kBACR,MAAM,iBA0BhB;;CACJ;qCAxHoC,+BAA+B"}
|
|
@@ -85,11 +85,9 @@ export default class BigWigSource extends SingleAxisWindowedSource {
|
|
|
85
85
|
// Using 5000 as a default to avoid too many requests.
|
|
86
86
|
const windowSize = Math.max(reductionLevel * length, 5000);
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.loadInterval(quantizedInterval, reductionLevel);
|
|
92
|
-
}
|
|
88
|
+
this.callIfWindowsChanged(domain, windowSize, (quantizedInterval) =>
|
|
89
|
+
this.loadInterval(quantizedInterval, reductionLevel)
|
|
90
|
+
);
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
/**
|
|
@@ -34,7 +34,7 @@ export default class SingleAxisLazySource extends DataSource {
|
|
|
34
34
|
* @param {import("../../../spec/genome.js").ChromosomalLocus[]} complexDomain Chrom/Pos domain
|
|
35
35
|
* @abstract
|
|
36
36
|
*/
|
|
37
|
-
onDomainChanged(domain: number[], complexDomain: import("../../../spec/genome.js").ChromosomalLocus[]):
|
|
37
|
+
onDomainChanged(domain: number[], complexDomain: import("../../../spec/genome.js").ChromosomalLocus[]): void;
|
|
38
38
|
/**
|
|
39
39
|
* Sets the loading status of the data source. The status is shown in the UI.
|
|
40
40
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleAxisLazySource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisLazySource.js"],"names":[],"mappings":"AAIA;;GAEG;AACH;IAOI;;;OAGG;IACH,kBAHW,OAAO,uBAAuB,EAAE,OAAO,WACvC,OAAO,0BAA0B,EAAE,wBAAwB,EAiDrE;IAzDD;;;OAGG;IACH,4CAAuC;IASnC,8CAAgB;IAYhB,2EAA2E;IAC3E,SADW,OAAO,0BAA0B,EAAE,wBAAwB,CAChD;IAEtB,oEAA4D;IA+BhE;;;OAGG;IACH,wBAWC;IAED;;;;OAIG;IACH,oEAEC;IAED;;;;;;OAMG;IACH,wBAJW,MAAM,EAAE,iBACR,OAAO,yBAAyB,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"singleAxisLazySource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisLazySource.js"],"names":[],"mappings":"AAIA;;GAEG;AACH;IAOI;;;OAGG;IACH,kBAHW,OAAO,uBAAuB,EAAE,OAAO,WACvC,OAAO,0BAA0B,EAAE,wBAAwB,EAiDrE;IAzDD;;;OAGG;IACH,4CAAuC;IASnC,8CAAgB;IAYhB,2EAA2E;IAC3E,SADW,OAAO,0BAA0B,EAAE,wBAAwB,CAChD;IAEtB,oEAA4D;IA+BhE;;;OAGG;IACH,wBAWC;IAED;;;;OAIG;IACH,oEAEC;IAED;;;;;;OAMG;IACH,wBAJW,MAAM,EAAE,iBACR,OAAO,yBAAyB,EAAE,gBAAgB,EAAE,QAK9D;IAED;;;;;OAKG;IACH,mCAHW,OAAO,QAKjB;IAED;;;;;OAKG;IACH,gCAGC;IAQD;;;;;OAKG;IACH,8BAHW,OAAO,mBAAmB,EAAE,KAAK,EAAE,EAAE,QAkB/C;CACJ;uBAxJsB,kBAAkB"}
|
|
@@ -98,7 +98,7 @@ export default class SingleAxisLazySource extends DataSource {
|
|
|
98
98
|
* @param {import("../../../spec/genome.js").ChromosomalLocus[]} complexDomain Chrom/Pos domain
|
|
99
99
|
* @abstract
|
|
100
100
|
*/
|
|
101
|
-
|
|
101
|
+
onDomainChanged(domain, complexDomain) {
|
|
102
102
|
// Override me
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Divides the domain into windows and loads the data for one or two consecutive windows
|
|
3
|
+
* that cover the visible interval.
|
|
4
|
+
*
|
|
2
5
|
* @abstract
|
|
3
6
|
*/
|
|
4
7
|
export default class SingleAxisWindowedSource extends SingleAxisLazySource {
|
|
@@ -19,7 +22,7 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
|
|
|
19
22
|
*
|
|
20
23
|
* @param {number[]} domain Linearized domain
|
|
21
24
|
*/
|
|
22
|
-
onDomainChanged(domain: number[]):
|
|
25
|
+
onDomainChanged(domain: number[]): void;
|
|
23
26
|
/**
|
|
24
27
|
* Listen to the domain change event and update data when the covered windows change.
|
|
25
28
|
*
|
|
@@ -39,21 +42,13 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
|
|
|
39
42
|
*/
|
|
40
43
|
protected discretizeAndLoad<T>(interval: number[], loader: (discreteInteval: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval, signal: AbortSignal) => Promise<T>): Promise<T[]>;
|
|
41
44
|
/**
|
|
42
|
-
* Returns three consecutive windows. The idea is to immediately have some data
|
|
43
|
-
* to show to the user when they pan the view. The windows are conceptually
|
|
44
|
-
* similar to "tiles" but they are never loaded separately.
|
|
45
45
|
*
|
|
46
|
-
* @param {number[]} interval
|
|
46
|
+
* @param {number[]} interval Domain
|
|
47
47
|
* @param {number} windowSize
|
|
48
|
+
* @param {function(number[]):void} callback
|
|
48
49
|
* @protected
|
|
49
50
|
*/
|
|
50
|
-
protected
|
|
51
|
-
/**
|
|
52
|
-
*
|
|
53
|
-
* @param {number[]} interval
|
|
54
|
-
* @protected
|
|
55
|
-
*/
|
|
56
|
-
protected checkAndUpdateLastInterval(interval: number[]): boolean;
|
|
51
|
+
protected callIfWindowsChanged(interval: number[], windowSize: number, callback: (arg0: number[]) => void): void;
|
|
57
52
|
#private;
|
|
58
53
|
}
|
|
59
54
|
import SingleAxisLazySource from "./singleAxisLazySource.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleAxisWindowedSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisWindowedSource.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"singleAxisWindowedSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisWindowedSource.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH;IAUI;;;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,QAmBlB;IAED;;;;;OAKG;IACH,iCAHW,MAAM,EAAE,iBAKlB;IAED;;;;;;;;;OASG;IACH,yCANW,MAAM,EAAE,4BACU,OAAO,mCAAmC,EAAE,0BAA0B,UAAU,WAAW,+BAqCvH;IAED;;;;;;OAMG;IACH,yCALW,MAAM,EAAE,cACR,MAAM,mBACG,MAAM,EAAE,KAAE,IAAI,QAyBjC;;CACJ;iCA3JgC,2BAA2B"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import SingleAxisLazySource from "./singleAxisLazySource.js";
|
|
2
|
-
import { shallowArrayEquals } from "../../../utils/arrayUtils.js";
|
|
3
2
|
import { debounce } from "@genome-spy/core/utils/debounce.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
5
|
+
* Divides the domain into windows and loads the data for one or two consecutive windows
|
|
6
|
+
* that cover the visible interval.
|
|
7
|
+
*
|
|
6
8
|
* @abstract
|
|
7
9
|
*/
|
|
8
10
|
export default class SingleAxisWindowedSource extends SingleAxisLazySource {
|
|
@@ -13,6 +15,8 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
|
|
|
13
15
|
*/
|
|
14
16
|
#lastQuantizedInterval = [0, 0];
|
|
15
17
|
|
|
18
|
+
#lastWindowSize = 0;
|
|
19
|
+
|
|
16
20
|
/**
|
|
17
21
|
* @type {{windowSize?: number}}
|
|
18
22
|
* @protected
|
|
@@ -46,21 +50,23 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
|
|
|
46
50
|
*
|
|
47
51
|
* @param {number[]} domain Linearized domain
|
|
48
52
|
*/
|
|
49
|
-
|
|
53
|
+
onDomainChanged(domain) {
|
|
50
54
|
const windowSize = this.params?.windowSize ?? -1;
|
|
51
55
|
|
|
52
56
|
if (domain[1] - domain[0] > windowSize) {
|
|
53
57
|
return;
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
this.callIfWindowsChanged(
|
|
61
|
+
domain,
|
|
62
|
+
windowSize,
|
|
63
|
+
async (quantizedInterval) => {
|
|
64
|
+
// Possible metadata must be loaded before the first request.
|
|
65
|
+
await this.initializedPromise;
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
this.loadInterval(quantizedInterval);
|
|
68
|
+
}
|
|
69
|
+
);
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
/**
|
|
@@ -118,35 +124,33 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
|
|
|
118
124
|
}
|
|
119
125
|
|
|
120
126
|
/**
|
|
121
|
-
* Returns three consecutive windows. The idea is to immediately have some data
|
|
122
|
-
* to show to the user when they pan the view. The windows are conceptually
|
|
123
|
-
* similar to "tiles" but they are never loaded separately.
|
|
124
127
|
*
|
|
125
|
-
* @param {number[]} interval
|
|
128
|
+
* @param {number[]} interval Domain
|
|
126
129
|
* @param {number} windowSize
|
|
130
|
+
* @param {function(number[]):void} callback
|
|
127
131
|
* @protected
|
|
128
132
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
callIfWindowsChanged(interval, windowSize, callback) {
|
|
134
|
+
// One or two consecutive windows that cover the given interval.
|
|
135
|
+
// The windows are conceptually similar to "tiles" but they are never loaded separately.
|
|
136
|
+
const quantizedInterval = [
|
|
137
|
+
Math.max(Math.floor(interval[0] / windowSize) * windowSize, 0),
|
|
132
138
|
Math.min(
|
|
133
|
-
Math.ceil(interval[1] / windowSize
|
|
139
|
+
Math.ceil(interval[1] / windowSize) * windowSize,
|
|
134
140
|
this.genome.totalSize // Perhaps scale domain should be used here
|
|
135
141
|
),
|
|
136
142
|
];
|
|
137
|
-
}
|
|
138
143
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
144
|
+
const last = this.#lastQuantizedInterval;
|
|
145
|
+
if (
|
|
146
|
+
windowSize !== this.#lastWindowSize ||
|
|
147
|
+
quantizedInterval[0] < last[0] ||
|
|
148
|
+
quantizedInterval[1] > last[1]
|
|
149
|
+
) {
|
|
150
|
+
this.#lastQuantizedInterval = quantizedInterval;
|
|
151
|
+
this.#lastWindowSize = windowSize;
|
|
148
152
|
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
callback(quantizedInterval);
|
|
154
|
+
}
|
|
151
155
|
}
|
|
152
156
|
}
|
|
@@ -75,7 +75,7 @@ export default class FilterScoredLabelsTransform extends FlowNode {
|
|
|
75
75
|
_filterAndPropagate() {
|
|
76
76
|
super.reset();
|
|
77
77
|
|
|
78
|
-
const scale = this.resolution.
|
|
78
|
+
const scale = this.resolution.scale;
|
|
79
79
|
const rangeSpan =
|
|
80
80
|
this.resolution.members[0].view.coords?.[
|
|
81
81
|
this.channel == "x" ? "width" : "height"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,6CAJW,OAAO,kBAAkB,EAAE,OAAO,aAClC,OAAO,oBAAoB,EAAE,QAAQ,gGAsC/C;AAED;;;;;;;GAOG;AACH,0CANW,OAAO,oBAAoB,EAAE,UAAU,SACvC,GAAG,0IAoGb;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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isDiscrete } from "vega-scale";
|
|
2
2
|
import createIndexer from "../utils/indexer.js";
|
|
3
3
|
import scaleNull from "../utils/scaleNull.js";
|
|
4
|
+
import { isExprRef } from "../marks/mark.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Creates an object that contains encoders for every channel of a mark
|
|
@@ -41,7 +42,7 @@ export default function createEncoders(mark, encoding) {
|
|
|
41
42
|
|
|
42
43
|
encoders[channel] = createEncoder(
|
|
43
44
|
encoding[channel],
|
|
44
|
-
resolution?.
|
|
45
|
+
resolution?.scale,
|
|
45
46
|
mark.unitView.getAccessor(channel),
|
|
46
47
|
channel
|
|
47
48
|
);
|
|
@@ -69,11 +70,20 @@ export function createEncoder(channelDef, scale, accessor, channel) {
|
|
|
69
70
|
let encoder;
|
|
70
71
|
|
|
71
72
|
if (isValueDef(channelDef)) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
if (isExprRef(channelDef.value)) {
|
|
74
|
+
// TODO: Should get the value expression as the accessor
|
|
75
|
+
encoder = /** @type {Encoder} */ ((datum) => undefined);
|
|
76
|
+
//encoder = /** @type {Encoder} */ (/** @type {any} */ (accessor));
|
|
77
|
+
encoder.constant = true;
|
|
78
|
+
encoder.constantValue = false;
|
|
79
|
+
encoder.accessor = accessor;
|
|
80
|
+
} else {
|
|
81
|
+
const value = channelDef.value;
|
|
82
|
+
encoder = /** @type {Encoder} */ ((datum) => value);
|
|
83
|
+
encoder.constant = true;
|
|
84
|
+
encoder.constantValue = true;
|
|
85
|
+
encoder.accessor = undefined;
|
|
86
|
+
}
|
|
77
87
|
} else if (accessor) {
|
|
78
88
|
if (channel == "text") {
|
|
79
89
|
// TODO: Define somewhere channels that don't use a scale
|
package/dist/src/genomeSpy.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export default class GenomeSpy {
|
|
|
139
139
|
renderPickingFramebuffer(): void;
|
|
140
140
|
getSearchableViews(): UnitView[];
|
|
141
141
|
getNamedScaleResolutions(): Map<string, import("./view/scaleResolution.js").default>;
|
|
142
|
+
#private;
|
|
142
143
|
}
|
|
143
144
|
/**
|
|
144
145
|
* Events that are broadcasted to all views.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AA+CA;IACI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA0FpD;IAvFG,uBAA0B;IAE1B,6BAA6B;IAC7B,uBADW,CAAC,MAAM,IAAI,CAAC,EAAE,CACM;IAM/B,sCAAsC;IACtC,wCAAgB;IAEhB,iCAA4C;IAC5C,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,QAAU,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,qEAF0B,OAAO,CAE8B;IAE/D,2CAA2C;IAC3C,mBADW,4BAA4B,CACL;IAClC,2CAA2C;IAC3C,iBADW,4BAA4B,CACP;IAEhC,oDAAoD;IACpD,6BAAgC;IAEhC;;;OAGG;IACH,eAFU;QAAE,IAAI,EAAE,OAAO,iBAAiB,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,oBAAoB,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAEpF;IAE9B,uBAA+C;IAE/C;;;OAGG;IACH,oBAFU,IAAI,MAAM,EAAE,QAAU,aAAa,KAAE,IAAI,CAAC,EAAE,CAAC,CAEpB;IAEnC;;;;;;OAMG;IACH,yCAFkC,GAAG,KAAK,IAAI,GAEd;IAEhC;;;OAGG;IACH,kDAFkC,GAAG,KAAK,IAAI,GAEL;IAEzC,oFAAoF;IACpF,iBADW,OAAO,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,2CAAyB;IAEzB,0BAAqC;IAGrC;;;;OAIG;IACH,8DAA8B;IA4GlC;;;OAGG;IACH,2CAFkB,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAaf;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAQb;IAED;;;OAGG;IACH,iCAyCC;IAED,0BA0EC;IAtEG,uBAOC;IAyCD,sCAA0D;IAS1D,yCAA6D;IAI7D,iBAA0C;IAW9C;;OAEG;IACH,gBAmBC;IAED,sCAwMC;IAED;;;OAGG;IACH,UAFa,QAAQ,OAAO,CAAC,CA6B5B;IAED,4BA6IC;IAjIe,iCAAoC;IAmIpD;;;OAGG;IACH,kBAHW,MAAM,KACN,MAAM,QAiEhB;IAED;;;;;;;OAOG;IACH,oDAHuB,QAAQ,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAYlF;IAED,sBAyCC;IAED,kBAIC;IAED,iCAOC;IAED,iCASC;IAED,qFAWC;;CACJ;;;;iCAh8BY,eAAe,GAAG,YAAY,GAAG,QAAQ,GAAG,gBAAgB;4BAlC7C,uBAAuB;4BA0BP,uBAAuB;qBAZ9C,qBAAqB;wBAIlB,yBAAyB;yCARR,yDAAyD;oBAYvD,oBAAoB;wBAMvC,kBAAkB;wBApBlB,qBAAqB;oBAVzB,uBAAuB;qBAQtB,oBAAoB"}
|
package/dist/src/genomeSpy.js
CHANGED
|
@@ -35,6 +35,8 @@ import { invalidatePrefix } from "./utils/propertyCacher.js";
|
|
|
35
35
|
import { VIEW_ROOT_NAME, ViewFactory } from "./view/viewFactory.js";
|
|
36
36
|
import { reconfigureScales } from "./view/scaleResolution.js";
|
|
37
37
|
import ParamBroker from "./paramBroker.js";
|
|
38
|
+
import { debounce } from "./utils/debounce.js";
|
|
39
|
+
import { tickStep } from "d3-array";
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
42
|
* Events that are broadcasted to all views.
|
|
@@ -137,6 +139,7 @@ export default class GenomeSpy {
|
|
|
137
139
|
this.viewRoot = undefined;
|
|
138
140
|
|
|
139
141
|
this._paramBroker = new ParamBroker();
|
|
142
|
+
this.#initializeParameters();
|
|
140
143
|
|
|
141
144
|
/**
|
|
142
145
|
* Views that are currently loading data using lazy sources.
|
|
@@ -146,6 +149,111 @@ export default class GenomeSpy {
|
|
|
146
149
|
this._loadingViews = new Map();
|
|
147
150
|
}
|
|
148
151
|
|
|
152
|
+
#initializeParameters() {
|
|
153
|
+
/** @type {import("lit-html").TemplateResult[]} */
|
|
154
|
+
const inputs = [];
|
|
155
|
+
|
|
156
|
+
for (const param of this.spec.params ?? []) {
|
|
157
|
+
const { name, value, bind } = param;
|
|
158
|
+
const setter = this._paramBroker.allocateSetter(name);
|
|
159
|
+
|
|
160
|
+
if (value != null) {
|
|
161
|
+
setter(value);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// TODO: Implement two-way data binding, e.g. when an external agent changes
|
|
165
|
+
// the parameter value, the UI components should be updated.
|
|
166
|
+
|
|
167
|
+
if (bind && "input" in bind) {
|
|
168
|
+
const debouncedSetter = bind.debounce
|
|
169
|
+
? debounce(setter, bind.debounce, false)
|
|
170
|
+
: setter;
|
|
171
|
+
|
|
172
|
+
if (bind.input == "range") {
|
|
173
|
+
// TODO: Show the value next to the slider
|
|
174
|
+
inputs.push(
|
|
175
|
+
html`<label
|
|
176
|
+
>${bind.name ?? name}
|
|
177
|
+
<input
|
|
178
|
+
type="range"
|
|
179
|
+
min=${bind.min ?? 0}
|
|
180
|
+
max=${bind.max ?? 100}
|
|
181
|
+
step=${bind.step ??
|
|
182
|
+
tickStep(bind.min, bind.max, 100)}
|
|
183
|
+
.value=${value}
|
|
184
|
+
@input=${(/** @type {any} */ e) =>
|
|
185
|
+
debouncedSetter(e.target.valueAsNumber)}
|
|
186
|
+
/></label>`
|
|
187
|
+
);
|
|
188
|
+
} else if (bind.input == "checkbox") {
|
|
189
|
+
inputs.push(
|
|
190
|
+
html`<label
|
|
191
|
+
>${bind.name ?? name}
|
|
192
|
+
<input
|
|
193
|
+
type="checkbox"
|
|
194
|
+
?checked=${value}
|
|
195
|
+
@input=${(/** @type {any} */ e) =>
|
|
196
|
+
debouncedSetter(e.target.checked)}
|
|
197
|
+
/></label>`
|
|
198
|
+
);
|
|
199
|
+
} else if (bind.input == "radio") {
|
|
200
|
+
inputs.push(
|
|
201
|
+
html`<span class="label">${bind.name ?? name}</span>
|
|
202
|
+
${bind.options.map(
|
|
203
|
+
(option, i) => html`<label>
|
|
204
|
+
<input
|
|
205
|
+
type="radio"
|
|
206
|
+
name=${name}
|
|
207
|
+
value=${option}
|
|
208
|
+
.checked=${value == option}
|
|
209
|
+
@input=${(/** @type {any} */ e) =>
|
|
210
|
+
debouncedSetter(e.target.value)}
|
|
211
|
+
/>${bind.labels?.[i] ?? option}</label
|
|
212
|
+
>`
|
|
213
|
+
)}`
|
|
214
|
+
);
|
|
215
|
+
} else if (bind.input == "select") {
|
|
216
|
+
inputs.push(
|
|
217
|
+
html`<label
|
|
218
|
+
>${bind.name ?? name}
|
|
219
|
+
<select
|
|
220
|
+
@input=${(/** @type {any} */ e) =>
|
|
221
|
+
debouncedSetter(e.target.value)}
|
|
222
|
+
>
|
|
223
|
+
${bind.options.map(
|
|
224
|
+
(option, i) => html`<option
|
|
225
|
+
value=${option}
|
|
226
|
+
?selected=${value == option}
|
|
227
|
+
>
|
|
228
|
+
${bind.labels?.[i] ?? option}
|
|
229
|
+
</option>`
|
|
230
|
+
)}
|
|
231
|
+
</select></label
|
|
232
|
+
>`
|
|
233
|
+
);
|
|
234
|
+
} else {
|
|
235
|
+
// TODO: Support other types: "text", "number", "color".
|
|
236
|
+
throw new Error("Unsupported input type: " + bind.input);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (inputs.length) {
|
|
242
|
+
const inputsDiv = document.createElement("div");
|
|
243
|
+
this.container.appendChild(inputsDiv);
|
|
244
|
+
|
|
245
|
+
// TODO: Move to css
|
|
246
|
+
// @ts-ignore
|
|
247
|
+
inputsDiv.style =
|
|
248
|
+
"position: absolute; bottom: 10px; right: 10px; background: rgba(255, 255, 255, 0.8); padding: 10px; z-index: 1; border: 1px solid lightgray";
|
|
249
|
+
|
|
250
|
+
render(
|
|
251
|
+
html`${inputs.map((input) => html`<div>${input}</div>`)}`,
|
|
252
|
+
inputsDiv
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
149
257
|
/**
|
|
150
258
|
*
|
|
151
259
|
* @param {(name: string) => any[]} provider
|
|
@@ -533,12 +641,6 @@ export default class GenomeSpy {
|
|
|
533
641
|
|
|
534
642
|
await graphicsInitialized;
|
|
535
643
|
|
|
536
|
-
this.viewRoot.visit((view) => {
|
|
537
|
-
for (const resolution of Object.values(view.resolutions.scale)) {
|
|
538
|
-
this._glHelper.createRangeTexture(resolution);
|
|
539
|
-
}
|
|
540
|
-
});
|
|
541
|
-
|
|
542
644
|
for (const view of unitViews) {
|
|
543
645
|
view.mark.finalizeGraphicsInitialization();
|
|
544
646
|
}
|
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
/// <reference types="external-typings/internmap.js" />
|
|
2
2
|
/**
|
|
3
|
+
* Generates GLSL code for a constant value.
|
|
3
4
|
*
|
|
4
5
|
* @param {Channel} channel
|
|
5
6
|
* @param {number | number[] | string | boolean} value
|
|
6
7
|
*/
|
|
7
|
-
export function
|
|
8
|
+
export function generateConstantValueGlsl(channel: Channel, value: number | number[] | string | boolean): string;
|
|
8
9
|
/**
|
|
10
|
+
* Generates GLSL code for a dynamic, parameter-driven values. These are mainly
|
|
11
|
+
* used as dynamic mark properties that map to encoding channels.
|
|
9
12
|
*
|
|
10
13
|
* @param {Channel} channel
|
|
11
|
-
|
|
14
|
+
*/
|
|
15
|
+
export function generateDynamicValueGlslAndUniform(channel: Channel): {
|
|
16
|
+
channel: import("../spec/channel.js").Channel;
|
|
17
|
+
uniformName: string;
|
|
18
|
+
uniformGlsl: string;
|
|
19
|
+
scaleGlsl: string;
|
|
20
|
+
adjuster: (x: any) => any;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param {Channel} channel
|
|
25
|
+
* @param {import("../view/scaleResolution.js").default} scaleResolution TODO: typing
|
|
12
26
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
13
27
|
* @param {Channel[]} [sharedQuantitativeChannels] Channels that share the same quantitative field
|
|
14
28
|
*/
|
|
15
|
-
export function generateScaleGlsl(channel: Channel,
|
|
29
|
+
export function generateScaleGlsl(channel: Channel, scaleResolution: import("../view/scaleResolution.js").default, channelDef: import("../spec/channel.js").ChannelDef, sharedQuantitativeChannels?: Channel[]): {
|
|
30
|
+
attributeName: string;
|
|
16
31
|
attributeGlsl: string;
|
|
32
|
+
markUniformGlsl: string;
|
|
17
33
|
glsl: string;
|
|
34
|
+
domainUniformName: string;
|
|
18
35
|
domainUniform: string;
|
|
36
|
+
rangeName: string;
|
|
37
|
+
rangeUniform: string;
|
|
19
38
|
};
|
|
20
39
|
/**
|
|
21
40
|
* True if scale needs more than 24 bits (float32) of precision.
|
|
@@ -63,6 +82,7 @@ export const RANGE_PREFIX: "range_";
|
|
|
63
82
|
export const SCALE_FUNCTION_PREFIX: "scale_";
|
|
64
83
|
export const SCALED_FUNCTION_PREFIX: "getScaled_";
|
|
65
84
|
export const RANGE_TEXTURE_PREFIX: "uRangeTexture_";
|
|
85
|
+
export function getRangeForGlsl(scale: any, channel: Channel): number[];
|
|
66
86
|
export type Channel = import("../spec/channel.js").Channel;
|
|
67
87
|
/**
|
|
68
88
|
* Turns a number or number array to float or vec[234] string.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":";AAqDA;;;;;GAKG;AACH,mDAHW,OAAO,SACP,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,UAoC9C;AAED;;;;;GAKG;AACH,4DAFW,OAAO;;;;;kBAIC,GAAG,KAAK,GAAG;EA0B7B;AAED;;;;;;GAMG;AAEH,2CANW,OAAO,mBACP,OAAO,4BAA4B,EAAE,OAAO,cAC5C,OAAO,oBAAoB,EAAE,UAAU,+BACvC,OAAO,EAAE;;;;;;;;;EAiTnB;AAgHD;;;;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;AAloBD,uCAAwC;AACxC,uCAAwC;AACxC,oCAAqC;AACrC,6CAA8C;AAC9C,kDAAmD;AACnD,oDAAqD;AA6oB9C,uCAJI,GAAG,WACH,OAAO,GACL,MAAM,EAAE,CAQF;sBA7oBN,OAAO,oBAAoB,EAAE,OAAO;;;;8BAubpC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBAsJhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BA5lBJ,WAAW"}
|