@genome-spy/core 0.41.0 → 0.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/index--cKb-dKG.js +615 -0
- package/dist/bundle/{index-gn8bhQ8w.js → index-d7k3kkin.js} +365 -366
- package/dist/bundle/index.es.js +4225 -4040
- package/dist/bundle/index.js +122 -79
- package/dist/schema.json +58 -6
- package/dist/src/data/sources/dynamic/axisGenomeSource.js +1 -1
- package/dist/src/data/sources/dynamic/axisTickSource.js +3 -3
- package/dist/src/data/sources/dynamic/bamSource.d.ts +3 -21
- package/dist/src/data/sources/dynamic/bamSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/bamSource.js +38 -55
- package/dist/src/data/sources/dynamic/bigBedSource.d.ts +2 -38
- package/dist/src/data/sources/dynamic/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/bigBedSource.js +14 -71
- package/dist/src/data/sources/dynamic/bigWigSource.d.ts +4 -42
- package/dist/src/data/sources/dynamic/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/bigWigSource.js +23 -60
- package/dist/src/data/sources/dynamic/gff3Source.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/gff3Source.js +1 -0
- package/dist/src/data/sources/dynamic/indexedFastaSource.d.ts +2 -20
- package/dist/src/data/sources/dynamic/indexedFastaSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/indexedFastaSource.js +23 -41
- package/dist/src/data/sources/dynamic/singleAxisLazySource.d.ts +23 -4
- package/dist/src/data/sources/dynamic/singleAxisLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/singleAxisLazySource.js +29 -4
- package/dist/src/data/sources/dynamic/singleAxisWindowedSource.d.ts +60 -0
- package/dist/src/data/sources/dynamic/singleAxisWindowedSource.d.ts.map +1 -0
- package/dist/src/data/sources/dynamic/singleAxisWindowedSource.js +152 -0
- package/dist/src/data/sources/dynamic/tabixSource.d.ts +6 -40
- package/dist/src/data/sources/dynamic/tabixSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/tabixSource.js +29 -78
- package/dist/src/data/transforms/regexFold.d.ts.map +1 -1
- package/dist/src/data/transforms/regexFold.js +8 -0
- package/dist/src/data/transforms/regexFold.test.js +28 -0
- package/dist/src/encoder/encoder.d.ts +6 -1
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +10 -0
- package/dist/src/genomeSpy.d.ts +14 -0
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +114 -8
- package/dist/src/gl/arrayBuilder.js +1 -1
- package/dist/src/gl/colorUtils.d.ts.map +1 -0
- package/dist/src/{scale → gl}/colorUtils.js +1 -1
- package/dist/src/gl/dataToVertices.d.ts +1 -9
- package/dist/src/gl/dataToVertices.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.js +33 -73
- package/dist/src/{scale → gl}/glslScaleGenerator.d.ts +23 -1
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -0
- package/dist/src/{scale → gl}/glslScaleGenerator.js +59 -8
- package/dist/src/gl/webGLHelper.d.ts +6 -21
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +8 -39
- package/dist/src/img/90-ring-with-bg.svg +1 -0
- package/dist/src/img/README.md +5 -0
- package/dist/src/marks/link.d.ts +7 -0
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +74 -39
- package/dist/src/marks/mark.d.ts +2 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +31 -2
- package/dist/src/marks/{pointMark.d.ts → point.d.ts} +1 -1
- package/dist/src/marks/point.d.ts.map +1 -0
- package/dist/src/marks/{pointMark.js → point.js} +3 -3
- package/dist/src/marks/{rectMark.d.ts → rect.d.ts} +1 -1
- package/dist/src/marks/rect.d.ts.map +1 -0
- package/dist/src/marks/{rectMark.js → rect.js} +2 -3
- package/dist/src/marks/rect.vertex.glsl.js +2 -0
- package/dist/src/marks/rule.js +3 -3
- package/dist/src/marks/text.d.ts.map +1 -1
- package/dist/src/marks/text.js +19 -20
- package/dist/src/spec/data.d.ts +28 -13
- package/dist/src/spec/mark.d.ts +0 -8
- package/dist/src/styles/genome-spy.css.d.ts +1 -1
- package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
- package/dist/src/styles/genome-spy.css.js +33 -4
- package/dist/src/styles/genome-spy.scss +40 -4
- package/dist/src/types/viewContext.d.ts +9 -0
- package/dist/src/utils/binnedIndex.d.ts +2 -0
- package/dist/src/utils/binnedIndex.d.ts.map +1 -1
- package/dist/src/utils/binnedIndex.js +59 -10
- package/dist/src/utils/binnedIndex.test.js +46 -0
- package/dist/src/utils/indexer.d.ts.map +1 -1
- package/dist/src/utils/indexer.js +10 -1
- package/dist/src/utils/indexer.test.js +2 -0
- package/dist/src/view/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView.js +2 -0
- package/dist/src/view/layerView.d.ts.map +1 -1
- package/dist/src/view/layerView.js +2 -0
- package/dist/src/view/unitView.d.ts +1 -7
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +4 -11
- package/dist/src/view/view.d.ts +6 -0
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +11 -0
- package/dist/src/view/view.test.js +1 -1
- package/package.json +3 -3
- package/dist/bundle/index-Cbz74kpR.js +0 -638
- package/dist/src/data/sources/dynamic/windowedMixin.d.ts +0 -32
- package/dist/src/data/sources/dynamic/windowedMixin.d.ts.map +0 -1
- package/dist/src/data/sources/dynamic/windowedMixin.js +0 -53
- package/dist/src/gl/rect.vertex.glsl.js +0 -2
- package/dist/src/marks/pointMark.d.ts.map +0 -1
- package/dist/src/marks/rectMark.d.ts.map +0 -1
- package/dist/src/scale/colorUtils.d.ts.map +0 -1
- package/dist/src/scale/glslScaleGenerator.d.ts.map +0 -1
- /package/dist/src/{scale → gl}/colorUtils.d.ts +0 -0
- /package/dist/src/{gl → marks}/link.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/link.vertex.glsl.js +0 -0
- /package/dist/src/{gl → marks}/point.common.glsl.js +0 -0
- /package/dist/src/{gl → marks}/point.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/point.vertex.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rect.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rule.common.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rule.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rule.vertex.glsl.js +0 -0
- /package/dist/src/{gl → marks}/text.common.glsl.js +0 -0
- /package/dist/src/{gl → marks}/text.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/text.vertex.glsl.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
|
package/dist/src/marks/mark.js
CHANGED
|
@@ -14,6 +14,7 @@ import createEncoders, {
|
|
|
14
14
|
isChannelDefWithScale,
|
|
15
15
|
isChannelWithScale,
|
|
16
16
|
isDatumDef,
|
|
17
|
+
isFieldDef,
|
|
17
18
|
isValueDef,
|
|
18
19
|
} from "../encoder/encoder.js";
|
|
19
20
|
import {
|
|
@@ -25,7 +26,8 @@ import {
|
|
|
25
26
|
isHighPrecisionScale,
|
|
26
27
|
toHighPrecisionDomainUniform,
|
|
27
28
|
splitHighPrecision,
|
|
28
|
-
|
|
29
|
+
dedupeEncodingFields,
|
|
30
|
+
} from "../gl/glslScaleGenerator.js";
|
|
29
31
|
import GLSL_COMMON from "../gl/includes/common.glsl.js";
|
|
30
32
|
import GLSL_SCALES from "../gl/includes/scales.glsl.js";
|
|
31
33
|
import GLSL_SAMPLE_FACET from "../gl/includes/sampleFacet.glsl.js";
|
|
@@ -316,6 +318,7 @@ export default class Mark {
|
|
|
316
318
|
* @param {string} vertexShader
|
|
317
319
|
* @param {string} fragmentShader
|
|
318
320
|
* @param {string[]} [extraHeaders]
|
|
321
|
+
* @protected
|
|
319
322
|
*/
|
|
320
323
|
createAndLinkShaders(vertexShader, fragmentShader, extraHeaders = []) {
|
|
321
324
|
const attributes = this.getAttributes();
|
|
@@ -330,6 +333,15 @@ export default class Mark {
|
|
|
330
333
|
/** @type {string[]} */
|
|
331
334
|
let scaleCode = [];
|
|
332
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Attribute definitions. Using set to prevent duplicates caused by
|
|
338
|
+
* multiple channels using the same shared quantitative field.
|
|
339
|
+
* @type {Set<string>}
|
|
340
|
+
*/
|
|
341
|
+
const attributeCode = new Set();
|
|
342
|
+
|
|
343
|
+
const dedupedEncodingFields = dedupeEncodingFields(this.encoders);
|
|
344
|
+
|
|
333
345
|
const sampleFacetMode = this.getSampleFacetMode();
|
|
334
346
|
if (sampleFacetMode) {
|
|
335
347
|
extraHeaders.push(`#define ${sampleFacetMode}`);
|
|
@@ -364,12 +376,28 @@ export default class Mark {
|
|
|
364
376
|
.getScale()
|
|
365
377
|
: scaleNull();
|
|
366
378
|
|
|
367
|
-
|
|
379
|
+
// Channels that share the same quantitative field
|
|
380
|
+
// TODO: It should be ok to share a categorical field if the channels
|
|
381
|
+
// share the same scale, e.g., primary and secondary positional channels
|
|
382
|
+
const sharedChannels =
|
|
383
|
+
isFieldDef(channelDef) && !isDiscrete(scale.type)
|
|
384
|
+
? dedupedEncodingFields.get([channelDef.field, true])
|
|
385
|
+
: [channel];
|
|
386
|
+
|
|
387
|
+
const generated = generateScaleGlsl(
|
|
388
|
+
channel,
|
|
389
|
+
scale,
|
|
390
|
+
channelDef,
|
|
391
|
+
sharedChannels
|
|
392
|
+
);
|
|
368
393
|
|
|
369
394
|
scaleCode.push(generated.glsl);
|
|
370
395
|
if (generated.domainUniform) {
|
|
371
396
|
this.domainUniforms.push(generated.domainUniform);
|
|
372
397
|
}
|
|
398
|
+
if (generated.attributeGlsl) {
|
|
399
|
+
attributeCode.add(generated.attributeGlsl);
|
|
400
|
+
}
|
|
373
401
|
}
|
|
374
402
|
}
|
|
375
403
|
|
|
@@ -388,6 +416,7 @@ export default class Mark {
|
|
|
388
416
|
GLSL_COMMON,
|
|
389
417
|
GLSL_SCALES,
|
|
390
418
|
domainUniformBlock,
|
|
419
|
+
[...attributeCode].join("\n"),
|
|
391
420
|
...scaleCode,
|
|
392
421
|
GLSL_SAMPLE_FACET,
|
|
393
422
|
GLSL_PICKING_VERTEX,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/marks/point.js"],"names":[],"mappings":"AAkBA;IAsGY,oCAMC;IA2CT,mCAQC;IAED;;OAEG;IACH,wDASC;IAED,+BAoBC;CAiDJ;iBA3PgB,WAAW"}
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
} from "twgl.js";
|
|
6
6
|
import { quantileSorted } from "d3-array";
|
|
7
7
|
import { PointVertexBuilder } from "../gl/dataToVertices.js";
|
|
8
|
-
import VERTEX_SHADER from "
|
|
9
|
-
import FRAGMENT_SHADER from "
|
|
10
|
-
import COMMON_SHADER from "
|
|
8
|
+
import VERTEX_SHADER from "./point.vertex.glsl.js";
|
|
9
|
+
import FRAGMENT_SHADER from "./point.fragment.glsl.js";
|
|
10
|
+
import COMMON_SHADER from "./point.common.glsl.js";
|
|
11
11
|
|
|
12
12
|
import Mark from "./mark.js";
|
|
13
13
|
import { sampleIterable } from "../data/transforms/sample.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rect.d.ts","sourceRoot":"","sources":["../../../src/marks/rect.js"],"names":[],"mappings":"AAYA;IA0NI;;;;;;;;;;OAUG;IACH,8BALW,GAAG,KACH,OAAO,oBAAoB,EAAE,MAAM,GACjC,GAAG,CAyBf;;CACJ;iBAnQgB,WAAW"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { drawBufferInfo, setBuffersAndAttributes } from "twgl.js";
|
|
2
|
-
import VERTEX_SHADER from "
|
|
3
|
-
import FRAGMENT_SHADER from "
|
|
2
|
+
import VERTEX_SHADER from "./rect.vertex.glsl.js";
|
|
3
|
+
import FRAGMENT_SHADER from "./rect.fragment.glsl.js";
|
|
4
4
|
import { RectVertexBuilder } from "../gl/dataToVertices.js";
|
|
5
5
|
|
|
6
6
|
import Mark from "./mark.js";
|
|
@@ -179,7 +179,6 @@ export default class RectMark extends Mark {
|
|
|
179
179
|
const collector = this.unitView.getCollector();
|
|
180
180
|
const numItems = collector.getItemCount();
|
|
181
181
|
|
|
182
|
-
// TODO: Disable tessellation on SimpleTrack - no need for it
|
|
183
182
|
const builder = new RectVertexBuilder({
|
|
184
183
|
encoders: this.encoders,
|
|
185
184
|
attributes: this.getAttributes(),
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const shader = "uniform Mark{uniform float uMinWidth;uniform float uMinHeight;uniform float uMinOpacity;uniform float uCornerRadiusTopRight;uniform float uCornerRadiusBottomRight;uniform float uCornerRadiusTopLeft;uniform float uCornerRadiusBottomLeft;};out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out float vHalfStrokeWidth;out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED)\nout vec2 vPosInPixels;\n#endif\nout vec2 vHalfSizeInPixels;/***Clamps the minimumSize and returns an opacity that reflects the amount of clamping.*/float clampMinSize(inout float pos,float frac,float size,float minSize){if(minSize>0.0&&abs(size)<minSize){pos+=(frac-0.5)*(minSize*sign(size)-size);return abs(size)/minSize;}return 1.0;}void sort(inout float a,inout float b){if(a>b){float tmp=b;b=a;a=tmp;}}/***The vertex position wrt the rectangle specified by(x,x2,y,y2).*[0,0]=[x,y],[1,1]=[x2,y2].*The x or y component may contain fractional values if the rectangle*have been tessellated.*/vec2 getVertexPos(){int index=gl_VertexID % 6;return vec2(index==0||index==1||index==3 ? 0.0 : 1.0,index==0||index==1||index==2 ? 0.0 : 1.0);}void main(void){vec2 frac=getVertexPos();vec2 normalizedMinSize=vec2(uMinWidth,uMinHeight)/uViewportSize;vec4 cornerRadii=vec4(uCornerRadiusTopRight,uCornerRadiusBottomRight,uCornerRadiusBottomLeft,uCornerRadiusTopLeft);float x=getScaled_x();float x2=getScaled_x2();float y=getScaled_y();float y2=getScaled_y2();sort(x,x2);sort(y,y2);float clampMargin=1.0;vec2 pos1=vec2(clamp(x,0.0-clampMargin,1.0+clampMargin),y);vec2 pos2=vec2(clamp(x2,0.0-clampMargin,1.0+clampMargin),y2);vec2 size=pos2-pos1;if(size.x<=0.0||size.y<=0.0){gl_Position=vec4(0.0,0.0,0.0,1.0);return;}vec2 pos=pos1+frac*size;size.y*=getSampleFacetHeight(pos);float opaFactor=uViewOpacity*max(uMinOpacity,clampMinSize(pos.x,frac.x,size.x,normalizedMinSize.x)*clampMinSize(pos.y,frac.y,size.y,normalizedMinSize.y));pos=applySampleFacet(pos);\n#if defined(ROUNDED_CORNERS) || defined(STROKED)\nfloat aaPadding=1.0/uDevicePixelRatio;float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding)/uViewportSize;pos+=expand;vec2 sizeInPixels=size*uViewportSize;vPosInPixels=(centeredFrac+expand/size)*sizeInPixels;vHalfSizeInPixels=sizeInPixels/2.0;vCornerRadii=min(cornerRadii,min(vHalfSizeInPixels.x,vHalfSizeInPixels.y));vHalfStrokeWidth=strokeWidth/2.0;vStrokeColor=vec4(getScaled_stroke()*strokeOpacity,strokeOpacity);\n#endif\ngl_Position=unitToNdc(pos);float fillOpacity=getScaled_fillOpacity()*opaFactor;vFillColor=vec4(getScaled_fill()*fillOpacity,fillOpacity);setupPicking();}";
|
|
2
|
+
export default shader;
|
package/dist/src/marks/rule.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
setBuffersAndAttributes,
|
|
7
7
|
setUniforms,
|
|
8
8
|
} from "twgl.js";
|
|
9
|
-
import VERTEX_SHADER from "
|
|
10
|
-
import FRAGMENT_SHADER from "
|
|
11
|
-
import COMMON_SHADER from "
|
|
9
|
+
import VERTEX_SHADER from "./rule.vertex.glsl.js";
|
|
10
|
+
import FRAGMENT_SHADER from "./rule.fragment.glsl.js";
|
|
11
|
+
import COMMON_SHADER from "./rule.common.glsl.js";
|
|
12
12
|
import { RuleVertexBuilder } from "../gl/dataToVertices.js";
|
|
13
13
|
import { isChannelDefWithScale } from "../encoder/encoder.js";
|
|
14
14
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/marks/text.js"],"names":[],"mappings":"AAgCA;;;;;;;GAOG;AACH;IAsDQ,oDAMmD;
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/marks/text.js"],"names":[],"mappings":"AAgCA;;;;;;;GAOG;AACH;IAsDQ,oDAMmD;CAgM1D;iBAvRgB,WAAW"}
|
package/dist/src/marks/text.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
setBuffersAndAttributes,
|
|
7
7
|
setUniforms,
|
|
8
8
|
} from "twgl.js";
|
|
9
|
-
import VERTEX_SHADER from "
|
|
10
|
-
import FRAGMENT_SHADER from "
|
|
11
|
-
import COMMON_SHADER from "
|
|
9
|
+
import VERTEX_SHADER from "./text.vertex.glsl.js";
|
|
10
|
+
import FRAGMENT_SHADER from "./text.fragment.glsl.js";
|
|
11
|
+
import COMMON_SHADER from "./text.common.glsl.js";
|
|
12
12
|
import { TextVertexBuilder } from "../gl/dataToVertices.js";
|
|
13
13
|
|
|
14
14
|
import Mark from "./mark.js";
|
|
@@ -160,6 +160,22 @@ export default class TextMark extends Mark {
|
|
|
160
160
|
|
|
161
161
|
const props = this.properties;
|
|
162
162
|
|
|
163
|
+
this.registerMarkUniform(
|
|
164
|
+
"uSdfNumerator",
|
|
165
|
+
/** @type {import("../spec/mark.js").ExprRef | number} */
|
|
166
|
+
({ expr: "devicePixelRatio" }),
|
|
167
|
+
(dpr) => {
|
|
168
|
+
let q = 0.35; // TODO: Ensure that this makes sense. Now chosen by trial & error
|
|
169
|
+
if (this.properties.logoLetters) {
|
|
170
|
+
// Adjust to make stretched letters a bit less blurry
|
|
171
|
+
// A proper solution would probably be to compute gradients in the fragment shader
|
|
172
|
+
// to find a suitable divisor.
|
|
173
|
+
q /= 2;
|
|
174
|
+
}
|
|
175
|
+
return this.font.metrics.common.base / (dpr / q);
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
|
|
163
179
|
// TODO: Use uniform block.
|
|
164
180
|
setBlockUniforms(this.markUniformInfo, {
|
|
165
181
|
uPaddingX: props.paddingX,
|
|
@@ -237,24 +253,7 @@ export default class TextMark extends Mark {
|
|
|
237
253
|
prepareRender(options) {
|
|
238
254
|
const ops = super.prepareRender(options);
|
|
239
255
|
|
|
240
|
-
let q = 0.35; // TODO: Ensure that this makes sense. Now chosen by trial & error
|
|
241
|
-
if (this.properties.logoLetters) {
|
|
242
|
-
// Adjust to make stretched letters a bit less blurry
|
|
243
|
-
// A proper solution would probably be to compute gradients in the fragment shader
|
|
244
|
-
// to find a suitable divisor.
|
|
245
|
-
q /= 2;
|
|
246
|
-
}
|
|
247
|
-
const uSdfNumerator =
|
|
248
|
-
this.font.metrics.common.base /
|
|
249
|
-
(this.unitView.context.devicePixelRatio / q);
|
|
250
|
-
|
|
251
256
|
ops.push(() => {
|
|
252
|
-
// TODO: only set if dpr changed
|
|
253
|
-
setBlockUniforms(this.markUniformInfo, {
|
|
254
|
-
uSdfNumerator,
|
|
255
|
-
});
|
|
256
|
-
this.markUniformsAltered = true;
|
|
257
|
-
|
|
258
257
|
setUniforms(this.programInfo, {
|
|
259
258
|
uTexture: this.font.texture,
|
|
260
259
|
});
|
package/dist/src/spec/data.d.ts
CHANGED
|
@@ -202,6 +202,29 @@ export type LazyDataParams =
|
|
|
202
202
|
| BamData
|
|
203
203
|
| Gff3Data;
|
|
204
204
|
|
|
205
|
+
export interface DebouncedData {
|
|
206
|
+
/**
|
|
207
|
+
* Debounce time for data updates, in milliseconds. Debouncing prevents
|
|
208
|
+
* excessive data updates when the user is zooming or panning around.
|
|
209
|
+
*
|
|
210
|
+
* __Default value:__ `200`
|
|
211
|
+
*/
|
|
212
|
+
debounce?: number;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The debounce mode for data updates. If set to `"domain"`, domain change
|
|
216
|
+
* events (panning and zooming) will be debounced. If set to `"window"`,
|
|
217
|
+
* the data fetches initiated by the changes to the visible window (or tile)
|
|
218
|
+
* will be debounced. If your data is small, the `"window"` is better as
|
|
219
|
+
* it will start fetching data while the user is still panning around,
|
|
220
|
+
* resulting in a shorter perceived latency.
|
|
221
|
+
*
|
|
222
|
+
* __Default value:__ `"window"`
|
|
223
|
+
*
|
|
224
|
+
*/
|
|
225
|
+
debounceMode?: "domain" | "window";
|
|
226
|
+
}
|
|
227
|
+
|
|
205
228
|
export interface AxisTicksData {
|
|
206
229
|
type: "axisTicks";
|
|
207
230
|
|
|
@@ -219,7 +242,7 @@ export interface AxisGenomeData {
|
|
|
219
242
|
channel: PrimaryPositionalChannel;
|
|
220
243
|
}
|
|
221
244
|
|
|
222
|
-
export interface IndexedFastaData {
|
|
245
|
+
export interface IndexedFastaData extends DebouncedData {
|
|
223
246
|
type: "indexedFasta";
|
|
224
247
|
|
|
225
248
|
/**
|
|
@@ -250,7 +273,7 @@ export interface IndexedFastaData {
|
|
|
250
273
|
windowSize?: number;
|
|
251
274
|
}
|
|
252
275
|
|
|
253
|
-
export interface BigWigData {
|
|
276
|
+
export interface BigWigData extends DebouncedData {
|
|
254
277
|
type: "bigwig";
|
|
255
278
|
|
|
256
279
|
/**
|
|
@@ -273,7 +296,7 @@ export interface BigWigData {
|
|
|
273
296
|
pixelsPerBin?: number;
|
|
274
297
|
}
|
|
275
298
|
|
|
276
|
-
export interface BigBedData {
|
|
299
|
+
export interface BigBedData extends DebouncedData {
|
|
277
300
|
type: "bigbed";
|
|
278
301
|
|
|
279
302
|
/**
|
|
@@ -297,7 +320,7 @@ export interface BigBedData {
|
|
|
297
320
|
windowSize?: number;
|
|
298
321
|
}
|
|
299
322
|
|
|
300
|
-
export interface BamData {
|
|
323
|
+
export interface BamData extends DebouncedData {
|
|
301
324
|
type: "bam";
|
|
302
325
|
|
|
303
326
|
/**
|
|
@@ -328,7 +351,7 @@ export interface BamData {
|
|
|
328
351
|
windowSize?: number;
|
|
329
352
|
}
|
|
330
353
|
|
|
331
|
-
export interface TabixData {
|
|
354
|
+
export interface TabixData extends DebouncedData {
|
|
332
355
|
/**
|
|
333
356
|
* Which channel's scale domain to monitor.
|
|
334
357
|
*
|
|
@@ -355,14 +378,6 @@ export interface TabixData {
|
|
|
355
378
|
* __Default value:__ `30000000`
|
|
356
379
|
*/
|
|
357
380
|
windowSize?: number;
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* The debounce time for domain changes, in milliseconds. Debouncing prevents
|
|
361
|
-
* data fetches while the user is still panning around.
|
|
362
|
-
*
|
|
363
|
-
* __Default value:__ `200`
|
|
364
|
-
*/
|
|
365
|
-
debounceDomainChange?: number;
|
|
366
381
|
}
|
|
367
382
|
|
|
368
383
|
export interface Gff3Data extends TabixData {
|
package/dist/src/spec/mark.d.ts
CHANGED
|
@@ -472,14 +472,6 @@ export interface MarkConfig
|
|
|
472
472
|
* This property is intended for internal use.
|
|
473
473
|
*/
|
|
474
474
|
minBufferSize?: number;
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Builds and index for efficient rendering of subsets of the data.
|
|
478
|
-
* The data must be sorted by the x coordinate.
|
|
479
|
-
*
|
|
480
|
-
* TODO: This should be enabled automatically if the data are sorted.
|
|
481
|
-
*/
|
|
482
|
-
buildIndex?: boolean;
|
|
483
475
|
}
|
|
484
476
|
|
|
485
477
|
export interface MarkConfigAndType extends MarkConfig {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export default css;
|
|
2
|
-
declare const css: ".genome-spy {\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n position: relative;\n}\n.genome-spy canvas {\n transform: scale(1, 1);\n opacity: 1;\n transition: transform 0.6s, opacity 0.6s;\n}\n.genome-spy .loading-message {\n position: absolute;\n
|
|
2
|
+
declare const css: ".genome-spy {\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n position: relative;\n}\n.genome-spy canvas {\n transform: scale(1, 1);\n opacity: 1;\n transition: transform 0.6s, opacity 0.6s;\n}\n.genome-spy .loading-message {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-message .message {\n color: #666;\n opacity: 0;\n transition: opacity 0.7s;\n}\n.genome-spy.loading canvas {\n transform: scale(0.95, 0.95);\n opacity: 0;\n}\n.genome-spy.loading .loading-message .message {\n opacity: 1;\n}\n.genome-spy.loading .ellipsis {\n animation: blinker 1s linear infinite;\n}\n@keyframes blinker {\n 50% {\n opacity: 0;\n }\n}\n.genome-spy .loading-indicators {\n position: absolute;\n inset: 0;\n user-select: none;\n pointer-events: none;\n}\n.genome-spy .loading-indicators div {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-indicators div > div {\n font-size: 11px;\n transition: opacity 0.2s;\n background: white;\n padding: 2px 5px;\n display: flex;\n border-radius: 3px;\n gap: 0.5em;\n opacity: 0;\n}\n.genome-spy .loading-indicators div > div.loading {\n opacity: 0.5;\n}\n.genome-spy .loading-indicators div > div > * {\n display: block;\n}\n.genome-spy .loading-indicators div > div img {\n width: 1.5em;\n height: 1.5em;\n}\n.genome-spy .tooltip {\n position: absolute;\n max-width: 450px;\n overflow: hidden;\n background: #f6f6f6;\n padding: 10px;\n font-size: 13px;\n box-shadow: 0px 3px 15px 0px rgba(0, 0, 0, 0.21);\n pointer-events: none;\n z-index: 100;\n}\n.genome-spy .tooltip > :last-child {\n margin-bottom: 0;\n}\n.genome-spy .tooltip > .title {\n padding-bottom: 5px;\n margin-bottom: 5px;\n border-bottom: 1px dashed #b6b6b6;\n}\n.genome-spy .tooltip .summary {\n font-size: 12px;\n}\n.genome-spy .tooltip table {\n border-collapse: collapse;\n}\n.genome-spy .tooltip table:first-child {\n margin-top: 0;\n}\n.genome-spy .tooltip table th,\n.genome-spy .tooltip table td {\n padding: 2px 0.4em;\n vertical-align: top;\n}\n.genome-spy .tooltip table th:first-child,\n.genome-spy .tooltip table td:first-child {\n padding-left: 0;\n}\n.genome-spy .tooltip table th {\n text-align: left;\n font-weight: bold;\n}\n.genome-spy .tooltip .color-legend {\n display: inline-block;\n width: 0.8em;\n height: 0.8em;\n margin-left: 0.4em;\n box-shadow: 0px 0px 3px 1px white;\n}\n.genome-spy .tooltip .attributes .hovered {\n background-color: #e0e0e0;\n}\n.genome-spy .tooltip .na {\n color: #aaa;\n font-style: italic;\n font-size: 80%;\n}\n.genome-spy .gene-track-tooltip .summary {\n font-size: 90%;\n}\n.genome-spy .message-box {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: 0;\n height: 100%;\n width: 100%;\n}\n.genome-spy .message-box > div {\n border: 1px solid red;\n padding: 10px;\n background: #fff0f0;\n}";
|
|
3
3
|
//# sourceMappingURL=genome-spy.css.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,0jGA4IG"}
|
|
@@ -9,10 +9,7 @@ const css = `.genome-spy {
|
|
|
9
9
|
}
|
|
10
10
|
.genome-spy .loading-message {
|
|
11
11
|
position: absolute;
|
|
12
|
-
|
|
13
|
-
bottom: 0;
|
|
14
|
-
left: 0;
|
|
15
|
-
right: 0;
|
|
12
|
+
inset: 0;
|
|
16
13
|
display: flex;
|
|
17
14
|
align-items: center;
|
|
18
15
|
justify-content: center;
|
|
@@ -37,6 +34,38 @@ const css = `.genome-spy {
|
|
|
37
34
|
opacity: 0;
|
|
38
35
|
}
|
|
39
36
|
}
|
|
37
|
+
.genome-spy .loading-indicators {
|
|
38
|
+
position: absolute;
|
|
39
|
+
inset: 0;
|
|
40
|
+
user-select: none;
|
|
41
|
+
pointer-events: none;
|
|
42
|
+
}
|
|
43
|
+
.genome-spy .loading-indicators div {
|
|
44
|
+
position: absolute;
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
}
|
|
49
|
+
.genome-spy .loading-indicators div > div {
|
|
50
|
+
font-size: 11px;
|
|
51
|
+
transition: opacity 0.2s;
|
|
52
|
+
background: white;
|
|
53
|
+
padding: 2px 5px;
|
|
54
|
+
display: flex;
|
|
55
|
+
border-radius: 3px;
|
|
56
|
+
gap: 0.5em;
|
|
57
|
+
opacity: 0;
|
|
58
|
+
}
|
|
59
|
+
.genome-spy .loading-indicators div > div.loading {
|
|
60
|
+
opacity: 0.5;
|
|
61
|
+
}
|
|
62
|
+
.genome-spy .loading-indicators div > div > * {
|
|
63
|
+
display: block;
|
|
64
|
+
}
|
|
65
|
+
.genome-spy .loading-indicators div > div img {
|
|
66
|
+
width: 1.5em;
|
|
67
|
+
height: 1.5em;
|
|
68
|
+
}
|
|
40
69
|
.genome-spy .tooltip {
|
|
41
70
|
position: absolute;
|
|
42
71
|
max-width: 450px;
|
|
@@ -18,10 +18,7 @@ $font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
|
|
18
18
|
|
|
19
19
|
.loading-message {
|
|
20
20
|
position: absolute;
|
|
21
|
-
|
|
22
|
-
bottom: 0;
|
|
23
|
-
left: 0;
|
|
24
|
-
right: 0;
|
|
21
|
+
inset: 0;
|
|
25
22
|
display: flex;
|
|
26
23
|
|
|
27
24
|
align-items: center;
|
|
@@ -55,6 +52,45 @@ $font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
|
|
55
|
+
.loading-indicators {
|
|
56
|
+
position: absolute;
|
|
57
|
+
inset: 0;
|
|
58
|
+
|
|
59
|
+
user-select: none;
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
|
|
62
|
+
div {
|
|
63
|
+
position: absolute;
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
|
|
68
|
+
> div {
|
|
69
|
+
font-size: 11px;
|
|
70
|
+
transition: opacity 0.2s;
|
|
71
|
+
background: white;
|
|
72
|
+
padding: 2px 5px;
|
|
73
|
+
display: flex;
|
|
74
|
+
border-radius: 3px;
|
|
75
|
+
gap: 0.5em;
|
|
76
|
+
opacity: 0;
|
|
77
|
+
|
|
78
|
+
&.loading {
|
|
79
|
+
opacity: 0.5;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
> * {
|
|
83
|
+
display: block;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
img {
|
|
87
|
+
width: 1.5em;
|
|
88
|
+
height: 1.5em;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
58
94
|
.tooltip {
|
|
59
95
|
position: absolute;
|
|
60
96
|
|
|
@@ -70,6 +70,15 @@ export default interface ViewContext {
|
|
|
70
70
|
|
|
71
71
|
getNamedDataFromProvider: (name: string) => any[];
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Allows lazy data sources to signal that they are loading data.
|
|
75
|
+
* The status is shown in the UI somewhere within or near the view.
|
|
76
|
+
*
|
|
77
|
+
* @param view The view where the data source is located.
|
|
78
|
+
* @param status true if loading, false if not loading.
|
|
79
|
+
*/
|
|
80
|
+
setDataLoadingStatus: (view: View, status: boolean) => void;
|
|
81
|
+
|
|
73
82
|
/**
|
|
74
83
|
* Returns true if the view is configured to be visible.
|
|
75
84
|
* N.B. This does NOT consider ancestors' visibility.
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* A binned index for (overlapping) ranges that are sorted by their start position.
|
|
10
10
|
* Each indexed range is associated with respective vertex indices.
|
|
11
11
|
*
|
|
12
|
+
* The indexing scheme is somewhat similar to Tabix (https://academic.oup.com/bioinformatics/article/27/5/718/262743).
|
|
13
|
+
*
|
|
12
14
|
* @param {number} size Number of bins
|
|
13
15
|
* @param {[number, number]} domain Domain of positions
|
|
14
16
|
* @param {(datum: T) => number} accessor Accessor for range's start position
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binnedIndex.d.ts","sourceRoot":"","sources":["../../../src/utils/binnedIndex.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH
|
|
1
|
+
{"version":3,"file":"binnedIndex.d.ts","sourceRoot":"","sources":["../../../src/utils/binnedIndex.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,mDANW,MAAM,UACN,CAAC,MAAM,EAAE,MAAM,CAAC,0BACF,MAAM,4BACN,MAAM;iCA2ChB,MAAM,kBACN,MAAM;oBAsHJ,MAAM;EA+BtB;6BAhNU,MAAM,OACN,MAAM,QACN,CAAC,MAAM,EAAE,MAAM,CAAC,KACd,CAAC,MAAM,EAAE,MAAM,CAAC"}
|
|
@@ -15,6 +15,8 @@ const MIN_INTEGER = -(2 ** 31);
|
|
|
15
15
|
* A binned index for (overlapping) ranges that are sorted by their start position.
|
|
16
16
|
* Each indexed range is associated with respective vertex indices.
|
|
17
17
|
*
|
|
18
|
+
* The indexing scheme is somewhat similar to Tabix (https://academic.oup.com/bioinformatics/article/27/5/718/262743).
|
|
19
|
+
*
|
|
18
20
|
* @param {number} size Number of bins
|
|
19
21
|
* @param {[number, number]} domain Domain of positions
|
|
20
22
|
* @param {(datum: T) => number} accessor Accessor for range's start position
|
|
@@ -27,13 +29,15 @@ export function createBinningRangeIndexer(
|
|
|
27
29
|
accessor,
|
|
28
30
|
accessor2 = accessor
|
|
29
31
|
) {
|
|
30
|
-
const startIndices = new
|
|
32
|
+
const startIndices = new Array(size);
|
|
31
33
|
startIndices.fill(MAX_INTEGER);
|
|
32
34
|
|
|
33
35
|
let lastIndex = MIN_INTEGER;
|
|
36
|
+
let lastStart = -Infinity;
|
|
34
37
|
let unordered = false;
|
|
35
38
|
|
|
36
|
-
const endIndices = new
|
|
39
|
+
const endIndices = new Array(size);
|
|
40
|
+
endIndices.fill(0);
|
|
37
41
|
|
|
38
42
|
const start = domain[0];
|
|
39
43
|
const domainLength = domain[1] - domain[0];
|
|
@@ -63,17 +67,33 @@ export function createBinningRangeIndexer(
|
|
|
63
67
|
* @param {number} endVertexIndex
|
|
64
68
|
*/
|
|
65
69
|
function binningIndexer(datum, startVertexIndex, endVertexIndex) {
|
|
70
|
+
if (unordered) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
if (startVertexIndex > lastIndex) {
|
|
67
75
|
lastIndex = startVertexIndex;
|
|
68
|
-
} else
|
|
76
|
+
} else {
|
|
69
77
|
unordered = true;
|
|
70
78
|
// TODO: Contextual info like view path
|
|
71
79
|
console.debug(
|
|
72
80
|
"Items are not ordered properly. Disabling binned index."
|
|
73
81
|
);
|
|
82
|
+
return;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
const value = accessor(datum);
|
|
86
|
+
|
|
87
|
+
if (value < lastStart) {
|
|
88
|
+
unordered = true;
|
|
89
|
+
// TODO: Contextual info like view path
|
|
90
|
+
console.debug(
|
|
91
|
+
"Items are not ordered properly. Disabling binned index."
|
|
92
|
+
);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
lastStart = value;
|
|
96
|
+
|
|
77
97
|
const bin = getBin(value, false);
|
|
78
98
|
|
|
79
99
|
if (startIndices[bin] > startVertexIndex) {
|
|
@@ -93,18 +113,42 @@ export function createBinningRangeIndexer(
|
|
|
93
113
|
* @param {number} endVertexIndex
|
|
94
114
|
*/
|
|
95
115
|
function binningRangeIndexer(datum, startVertexIndex, endVertexIndex) {
|
|
116
|
+
if (unordered) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
96
120
|
if (startVertexIndex > lastIndex) {
|
|
97
121
|
lastIndex = startVertexIndex;
|
|
98
|
-
} else
|
|
122
|
+
} else {
|
|
99
123
|
unordered = true;
|
|
100
124
|
// TODO: Contextual info like view path
|
|
101
125
|
console.debug(
|
|
102
|
-
"Items are not ordered properly. Disabling binned index."
|
|
126
|
+
"Items (vertices) are not ordered properly. Disabling binned index."
|
|
103
127
|
);
|
|
128
|
+
return;
|
|
104
129
|
}
|
|
105
130
|
|
|
106
131
|
const start = accessor(datum);
|
|
107
132
|
const end = accessor2(datum);
|
|
133
|
+
|
|
134
|
+
if (start < lastStart) {
|
|
135
|
+
unordered = true;
|
|
136
|
+
// TODO: Contextual info like view path
|
|
137
|
+
console.debug(
|
|
138
|
+
"Items are not ordered properly. Disabling binned index."
|
|
139
|
+
);
|
|
140
|
+
return;
|
|
141
|
+
} else if (end < start) {
|
|
142
|
+
unordered = true;
|
|
143
|
+
// TODO: Contextual info like view path
|
|
144
|
+
console.debug(
|
|
145
|
+
"End index is less than start index. Disabling binned index. Datum: ",
|
|
146
|
+
datum
|
|
147
|
+
);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
lastStart = start;
|
|
151
|
+
|
|
108
152
|
const startBin = getBin(start, false);
|
|
109
153
|
const endBin = getBin(end, true);
|
|
110
154
|
|
|
@@ -135,7 +179,16 @@ export function createBinningRangeIndexer(
|
|
|
135
179
|
return arr;
|
|
136
180
|
};
|
|
137
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Finalizes the index and returns a lookup function.
|
|
184
|
+
*
|
|
185
|
+
* @returns {Lookup}
|
|
186
|
+
*/
|
|
138
187
|
const getIndex = () => {
|
|
188
|
+
if (unordered) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
|
|
139
192
|
for (let i = 1; i < endIndices.length; i++) {
|
|
140
193
|
if (endIndices[i] < endIndices[i - 1]) {
|
|
141
194
|
endIndices[i] = endIndices[i - 1];
|
|
@@ -159,9 +212,5 @@ export function createBinningRangeIndexer(
|
|
|
159
212
|
binningIndexer.getIndex = getIndex;
|
|
160
213
|
binningRangeIndexer.getIndex = getIndex;
|
|
161
214
|
|
|
162
|
-
|
|
163
|
-
return undefined;
|
|
164
|
-
} else {
|
|
165
|
-
return accessor == accessor2 ? binningIndexer : binningRangeIndexer;
|
|
166
|
-
}
|
|
215
|
+
return accessor == accessor2 ? binningIndexer : binningRangeIndexer;
|
|
167
216
|
}
|