@genome-spy/core 0.75.0 → 0.76.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/{esm-CgfVIRJ-.js → esm-BimDEpBb.js} +1 -1
- package/dist/bundle/{esm-DtE8VqAv.js → esm-Bvlm1uVk.js} +1 -1
- package/dist/bundle/{esm-sIoQYZ21.js → esm-CngqBe45.js} +17 -17
- package/dist/bundle/{esm-DQiq2Zhd.js → esm-D_euN86T.js} +43 -43
- package/dist/bundle/index.es.js +3253 -3137
- package/dist/bundle/index.js +97 -96
- package/dist/schema.json +352 -0
- package/dist/src/config/defaults/markDefaults.d.ts.map +1 -1
- package/dist/src/config/defaults/markDefaults.js +1 -12
- package/dist/src/config/defaults/scaleDefaults.d.ts.map +1 -1
- package/dist/src/config/defaults/scaleDefaults.js +1 -0
- package/dist/src/config/markConfig.d.ts.map +1 -1
- package/dist/src/config/markConfig.js +16 -8
- package/dist/src/config/themes.d.ts.map +1 -1
- package/dist/src/config/themes.js +15 -2
- package/dist/src/data/sources/lazy/registerBuiltInLazySources.js +2 -2
- package/dist/src/data/sources/lazy/registerCoreLazySources.d.ts +2 -0
- package/dist/src/data/sources/lazy/registerCoreLazySources.d.ts.map +1 -0
- package/dist/src/data/sources/lazy/registerCoreLazySources.js +2 -0
- package/dist/src/data/sources/lazy/tabixSource.d.ts +7 -0
- package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/tabixSource.js +18 -0
- package/dist/src/data/sources/lazy/tabixTsvSource.d.ts +37 -0
- package/dist/src/data/sources/lazy/tabixTsvSource.d.ts.map +1 -0
- package/dist/src/data/sources/lazy/tabixTsvSource.js +163 -0
- package/dist/src/genomeSpyBase.d.ts.map +1 -1
- package/dist/src/genomeSpyBase.js +4 -1
- package/dist/src/gl/webGLHelper.d.ts +5 -2
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +20 -3
- package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +1082 -0
- package/dist/src/marks/link.vertex.glsl.js +1 -1
- package/dist/src/minimal.d.ts.map +1 -1
- package/dist/src/minimal.js +5 -4
- package/dist/src/scale/scale.js +10 -2
- package/dist/src/scales/domainPlanner.js +1 -1
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +9 -3
- package/dist/src/scales/selectionDomainUtils.d.ts +10 -0
- package/dist/src/scales/selectionDomainUtils.d.ts.map +1 -1
- package/dist/src/scales/selectionDomainUtils.js +32 -3
- package/dist/src/spec/channel.d.ts +30 -0
- package/dist/src/spec/data.d.ts +40 -0
- package/dist/src/spec/parameter.d.ts +6 -0
- package/dist/src/spec/transform.d.ts +6 -0
- package/dist/src/view/axisGridView.d.ts.map +1 -1
- package/dist/src/view/axisGridView.js +2 -1
- package/dist/src/view/axisView.d.ts.map +1 -1
- package/dist/src/view/axisView.js +2 -1
- package/dist/src/view/facetView.d.ts.map +1 -1
- package/dist/src/view/facetView.js +2 -1
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +9 -1
- package/dist/src/view/gridView/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView/gridView.js +198 -32
- package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
- package/dist/src/view/gridView/scrollbar.js +5 -1
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
- package/dist/src/view/gridView/selectionRect.js +5 -1
- package/dist/src/view/gridView/separatorView.d.ts.map +1 -1
- package/dist/src/view/gridView/separatorView.js +5 -1
- package/dist/src/view/testUtils.d.ts +30 -3
- package/dist/src/view/testUtils.d.ts.map +1 -1
- package/dist/src/view/testUtils.js +51 -2
- package/dist/src/view/viewSelectors.d.ts +38 -10
- package/dist/src/view/viewSelectors.d.ts.map +1 -1
- package/dist/src/view/viewSelectors.js +67 -2
- package/dist/src/view/viewUtilTypes.d.ts +15 -0
- package/dist/src/view/viewUtils.d.ts.map +1 -1
- package/dist/src/view/viewUtils.js +10 -0
- package/package.json +2 -2
- package/LICENSE +0 -21
- /package/dist/bundle/{esm-BDFRLEuD.js → esm-C49STiCR.js} +0 -0
- /package/dist/bundle/{esm-CGX-qz1d.js → esm-CuVa5T98.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markDefaults.d.ts","sourceRoot":"","sources":["../../../../src/config/defaults/markDefaults.js"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,4BADW,OAAO,sBAAsB,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"markDefaults.d.ts","sourceRoot":"","sources":["../../../../src/config/defaults/markDefaults.js"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,4BADW,OAAO,sBAAsB,EAAE,UAAU,CAMlD;AAEF,yDAAyD;AACzD,kCADW,OAAO,sBAAsB,EAAE,WAAW,CAgBnD;AAEF,wDAAwD;AACxD,iCADW,OAAO,sBAAsB,EAAE,UAAU,CAUlD;AAEF,wDAAwD;AACxD,iCADW,OAAO,sBAAsB,EAAE,UAAU,CASlD;AAEF,wDAAwD;AACxD,iCADW,OAAO,sBAAsB,EAAE,UAAU,CAQlD;AAEF,wDAAwD;AACxD,iCADW,OAAO,sBAAsB,EAAE,UAAU,CA+BlD;AAEF,wDAAwD;AACxD,iCADW,OAAO,sBAAsB,EAAE,UAAU,CAiBlD"}
|
|
@@ -3,15 +3,14 @@ export const MARK_DEFAULTS = {
|
|
|
3
3
|
xOffset: 0,
|
|
4
4
|
yOffset: 0,
|
|
5
5
|
minBufferSize: 0,
|
|
6
|
+
opacity: 1.0,
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
/** @type {import("../../spec/config.js").PointConfig} */
|
|
9
10
|
export const POINT_MARK_DEFAULTS = {
|
|
10
11
|
x: 0.5,
|
|
11
12
|
y: 0.5,
|
|
12
|
-
color: "#4c78a8",
|
|
13
13
|
filled: true,
|
|
14
|
-
opacity: 1.0,
|
|
15
14
|
size: 100.0,
|
|
16
15
|
semanticScore: 0.0,
|
|
17
16
|
shape: "circle",
|
|
@@ -30,8 +29,6 @@ export const RECT_MARK_DEFAULTS = {
|
|
|
30
29
|
x2: undefined,
|
|
31
30
|
y2: undefined,
|
|
32
31
|
filled: true,
|
|
33
|
-
color: "#4c78a8",
|
|
34
|
-
opacity: 1.0,
|
|
35
32
|
strokeWidth: 3,
|
|
36
33
|
cornerRadius: 0.0,
|
|
37
34
|
minWidth: 0.5,
|
|
@@ -44,8 +41,6 @@ export const RULE_MARK_DEFAULTS = {
|
|
|
44
41
|
x2: undefined,
|
|
45
42
|
y2: undefined,
|
|
46
43
|
size: 1,
|
|
47
|
-
color: "black",
|
|
48
|
-
opacity: 1.0,
|
|
49
44
|
minLength: 0.0,
|
|
50
45
|
strokeDash: null,
|
|
51
46
|
strokeDashOffset: 0,
|
|
@@ -54,8 +49,6 @@ export const RULE_MARK_DEFAULTS = {
|
|
|
54
49
|
|
|
55
50
|
/** @type {import("../../spec/config.js").TickConfig} */
|
|
56
51
|
export const TICK_MARK_DEFAULTS = {
|
|
57
|
-
color: "black",
|
|
58
|
-
opacity: 1.0,
|
|
59
52
|
minLength: 0.0,
|
|
60
53
|
strokeDash: null,
|
|
61
54
|
strokeDashOffset: 0,
|
|
@@ -72,8 +65,6 @@ export const TEXT_MARK_DEFAULTS = {
|
|
|
72
65
|
y2: undefined,
|
|
73
66
|
text: "",
|
|
74
67
|
size: 11.0,
|
|
75
|
-
color: "black",
|
|
76
|
-
opacity: 1.0,
|
|
77
68
|
font: undefined,
|
|
78
69
|
fontStyle: undefined,
|
|
79
70
|
fontWeight: undefined,
|
|
@@ -106,8 +97,6 @@ export const LINK_MARK_DEFAULTS = {
|
|
|
106
97
|
y: 0.0,
|
|
107
98
|
y2: undefined,
|
|
108
99
|
size: 1.0,
|
|
109
|
-
color: "black",
|
|
110
|
-
opacity: 1.0,
|
|
111
100
|
segments: 101,
|
|
112
101
|
arcHeightFactor: 1.0,
|
|
113
102
|
minArcHeight: 1.5,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaleDefaults.d.ts","sourceRoot":"","sources":["../../../../src/config/defaults/scaleDefaults.js"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,6BADW,OAAO,sBAAsB,EAAE,WAAW,CAUnD;AAEF,yDAAyD;AACzD,6BADW,OAAO,sBAAsB,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"scaleDefaults.d.ts","sourceRoot":"","sources":["../../../../src/config/defaults/scaleDefaults.js"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,6BADW,OAAO,sBAAsB,EAAE,WAAW,CAUnD;AAEF,yDAAyD;AACzD,6BADW,OAAO,sBAAsB,EAAE,WAAW,CAMnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markConfig.d.ts","sourceRoot":"","sources":["../../../src/config/markConfig.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,kDALW,OAAO,mBAAmB,EAAE,eAAe,EAAE,YAC7C,OAAO,iBAAiB,EAAE,QAAQ,SAClC,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAC3B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"markConfig.d.ts","sourceRoot":"","sources":["../../../src/config/markConfig.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,kDALW,OAAO,mBAAmB,EAAE,eAAe,EAAE,YAC7C,OAAO,iBAAiB,EAAE,QAAQ,SAClC,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAC3B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA2B/B"}
|
|
@@ -12,16 +12,24 @@ export function getConfiguredMarkDefaults(scopes, markType, style) {
|
|
|
12
12
|
// part of style resolution, and explicit mark.style entries augment it.
|
|
13
13
|
const styles = [markType, ...normalizeStyle(style)];
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
const genericBuckets = scopes.map(
|
|
16
|
+
(scope) => /** @type {Record<string, any> | undefined} */ (scope.mark)
|
|
17
|
+
);
|
|
18
|
+
const markTypeBuckets = scopes.map(
|
|
19
|
+
(scope) =>
|
|
20
|
+
/** @type {Record<string, any> | undefined} */ (scope[markType])
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return mergeConfigScopes([
|
|
24
|
+
...genericBuckets,
|
|
25
|
+
...markTypeBuckets,
|
|
26
|
+
...scopes.flatMap((scope) =>
|
|
27
|
+
styles.map(
|
|
20
28
|
(styleName) =>
|
|
21
29
|
/** @type {Record<string, any> | undefined} */ (
|
|
22
30
|
scope.style?.[styleName]
|
|
23
31
|
)
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
);
|
|
32
|
+
)
|
|
33
|
+
),
|
|
34
|
+
]);
|
|
27
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../../src/config/themes.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../../src/config/themes.js"],"names":[],"mappings":"AA4RA;;;GAGG;AACH,gDAHW,OAAO,mBAAmB,EAAE,gBAAgB,GAC1C,MAAM,GAAG,SAAS,CAI9B;AAED;;;GAGG;AACH,iDAHW,OAAO,mBAAmB,EAAE,gBAAgB,GAAG,OAAO,mBAAmB,EAAE,gBAAgB,EAAE,GAAG,SAAS,GACvG,OAAO,mBAAmB,EAAE,eAAe,GAAG,SAAS,CAWnE;AA1BD;;GAEG;AACH,iCAFU,OAAO,mBAAmB,EAAE,gBAAgB,CAER"}
|
|
@@ -39,7 +39,7 @@ const VEGALITE_THEME = {
|
|
|
39
39
|
quantitativeColorScheme: "blues",
|
|
40
40
|
},
|
|
41
41
|
range: {
|
|
42
|
-
heatmap: "
|
|
42
|
+
heatmap: "yellowgreenblue",
|
|
43
43
|
ramp: "blues",
|
|
44
44
|
diverging: "blueorange",
|
|
45
45
|
},
|
|
@@ -59,7 +59,20 @@ const VEGALITE_THEME = {
|
|
|
59
59
|
* @type {Record<import("../spec/config.js").BuiltInThemeName, import("../spec/config.js").GenomeSpyConfig & { background?: string}>}
|
|
60
60
|
*/
|
|
61
61
|
const BUILT_IN_THEME_DEFINITIONS = {
|
|
62
|
-
genomespy: {
|
|
62
|
+
genomespy: {
|
|
63
|
+
mark: {
|
|
64
|
+
color: "#4c78a8",
|
|
65
|
+
},
|
|
66
|
+
rule: {
|
|
67
|
+
color: "black",
|
|
68
|
+
},
|
|
69
|
+
text: {
|
|
70
|
+
color: "black",
|
|
71
|
+
},
|
|
72
|
+
link: {
|
|
73
|
+
color: "black",
|
|
74
|
+
},
|
|
75
|
+
},
|
|
63
76
|
vegalite: VEGALITE_THEME,
|
|
64
77
|
quartz: mergeConfigScopes([
|
|
65
78
|
VEGALITE_THEME,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./axisGenomeSource.js";
|
|
1
|
+
import "./registerCoreLazySources.js";
|
|
3
2
|
import "./indexedFastaSource.js";
|
|
4
3
|
import "./bigWigSource.js";
|
|
5
4
|
import "./bigBedSource.js";
|
|
6
5
|
import "./bamSource.js";
|
|
6
|
+
import "./tabixTsvSource.js";
|
|
7
7
|
import "./gff3Source.js";
|
|
8
8
|
import "./vcfSource.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerCoreLazySources.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/registerCoreLazySources.js"],"names":[],"mappings":""}
|
|
@@ -14,6 +14,13 @@ export default class TabixSource<T> extends SingleAxisWindowedSource {
|
|
|
14
14
|
* @protected
|
|
15
15
|
*/
|
|
16
16
|
protected _handleHeader(header: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Read a prefix of the Tabix file and decode it as text.
|
|
19
|
+
*
|
|
20
|
+
* @returns {Promise<string>}
|
|
21
|
+
* @protected
|
|
22
|
+
*/
|
|
23
|
+
protected _readFilePrefix(): Promise<string>;
|
|
17
24
|
/**
|
|
18
25
|
* @abstract
|
|
19
26
|
* @protected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabixSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/tabixSource.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tabixSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/tabixSource.js"],"names":[],"mappings":"AAQA;;;GAGG;AACH,iCAHa,CAAC;IAOV;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,SAAS,QACzC,OAAO,uBAAuB,EAAE,OAAO,EAyCjD;IAzBG,kDAgBC;IA0FL;;;OAGG;IACH,gCAHW,MAAM,iBAKhB;IAED;;;;;OAKG;IACH,6BAHa,OAAO,CAAC,MAAM,CAAC,CAY3B;IAED;;;;;OAKG;IACH,gCAHW,MAAM,EAAE,GACN,CAAC,EAAE,CAKf;;CACJ;qCAzKoC,+BAA+B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { unzip } from "@gmod/bgzf-filehandle";
|
|
1
2
|
import {
|
|
2
3
|
activateExprRefProps,
|
|
3
4
|
withoutExprRef,
|
|
@@ -145,6 +146,23 @@ export default class TabixSource extends SingleAxisWindowedSource {
|
|
|
145
146
|
//
|
|
146
147
|
}
|
|
147
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Read a prefix of the Tabix file and decode it as text.
|
|
151
|
+
*
|
|
152
|
+
* @returns {Promise<string>}
|
|
153
|
+
* @protected
|
|
154
|
+
*/
|
|
155
|
+
async _readFilePrefix() {
|
|
156
|
+
const { maxBlockSize } = await this.#tbiIndex.getMetadata();
|
|
157
|
+
const tbiIndex = /** @type {any} */ (this.#tbiIndex);
|
|
158
|
+
const compressedPrefix = await tbiIndex.filehandle.read(
|
|
159
|
+
maxBlockSize,
|
|
160
|
+
0
|
|
161
|
+
);
|
|
162
|
+
const bytes = await unzip(compressedPrefix);
|
|
163
|
+
return new TextDecoder("utf-8").decode(bytes);
|
|
164
|
+
}
|
|
165
|
+
|
|
148
166
|
/**
|
|
149
167
|
* @abstract
|
|
150
168
|
* @protected
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract a TSV header from a tabix file header.
|
|
3
|
+
*
|
|
4
|
+
* Tabix headers commonly end with a commented column line such as
|
|
5
|
+
* `#chrom\tstart\tend\tvalue`.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} header
|
|
8
|
+
* @returns {string[] | undefined}
|
|
9
|
+
*/
|
|
10
|
+
export function extractTabixTsvColumns(header: string): string[] | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Extract a TSV header from the first line of a plain tabix file prefix.
|
|
13
|
+
*
|
|
14
|
+
* This is used when the file does not have a commented header line, but the
|
|
15
|
+
* first physical line still contains column names.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} text
|
|
18
|
+
* @returns {string[] | undefined}
|
|
19
|
+
*/
|
|
20
|
+
export function extractTabixTsvColumnsFromFirstLine(text: string): string[] | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Parse tabix TSV records into plain objects.
|
|
23
|
+
*
|
|
24
|
+
* @param {string[]} lines
|
|
25
|
+
* @param {string[]} columns
|
|
26
|
+
* @param {import("../../../spec/data.js").Parse | null | undefined} [parse]
|
|
27
|
+
*/
|
|
28
|
+
export function parseTabixTsvLines(lines: string[], columns: string[], parse?: import("../../../spec/data.js").Parse | null | undefined): Record<string, any>[];
|
|
29
|
+
/**
|
|
30
|
+
* @extends {TabixSource<Record<string, any>>}
|
|
31
|
+
*/
|
|
32
|
+
export default class TabixTsvSource extends TabixSource<Record<string, any>> {
|
|
33
|
+
constructor(params: import("../../../spec/data.js").TabixData, view: import("../../../view/view.js").default);
|
|
34
|
+
#private;
|
|
35
|
+
}
|
|
36
|
+
import TabixSource from "./tabixSource.js";
|
|
37
|
+
//# sourceMappingURL=tabixTsvSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabixTsvSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/tabixTsvSource.js"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,+CAHW,MAAM,GACJ,MAAM,EAAE,GAAG,SAAS,CAsBhC;AAED;;;;;;;;GAQG;AACH,0DAHW,MAAM,GACJ,MAAM,EAAE,GAAG,SAAS,CAkBhC;AAED;;;;;;GAMG;AACH,0CAJW,MAAM,EAAE,WACR,MAAM,EAAE,UACR,OAAO,uBAAuB,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,yBAgClE;AAED;;GAEG;AACH;;;CA8CC;wBApJuB,kBAAkB"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { read } from "vega-loader";
|
|
2
|
+
import { withoutExprRef } from "../../../paramRuntime/paramUtils.js";
|
|
3
|
+
import { toVegaLoaderFormat } from "../dataUtils.js";
|
|
4
|
+
import { registerBuiltInLazyDataSource } from "./lazyDataSourceRegistry.js";
|
|
5
|
+
import TabixSource from "./tabixSource.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extract a TSV header from a tabix file header.
|
|
9
|
+
*
|
|
10
|
+
* Tabix headers commonly end with a commented column line such as
|
|
11
|
+
* `#chrom\tstart\tend\tvalue`.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} header
|
|
14
|
+
* @returns {string[] | undefined}
|
|
15
|
+
*/
|
|
16
|
+
export function extractTabixTsvColumns(header) {
|
|
17
|
+
const lines = header.split(/\r?\n/);
|
|
18
|
+
|
|
19
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
20
|
+
const line = lines[i].trimEnd().replace(/\r$/, "");
|
|
21
|
+
|
|
22
|
+
if (!line || line.startsWith("##")) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!line.startsWith("#")) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const columns = line.slice(1).split("\t");
|
|
31
|
+
|
|
32
|
+
if (columns.length > 1) {
|
|
33
|
+
return columns;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Extract a TSV header from the first line of a plain tabix file prefix.
|
|
40
|
+
*
|
|
41
|
+
* This is used when the file does not have a commented header line, but the
|
|
42
|
+
* first physical line still contains column names.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} text
|
|
45
|
+
* @returns {string[] | undefined}
|
|
46
|
+
*/
|
|
47
|
+
export function extractTabixTsvColumnsFromFirstLine(text) {
|
|
48
|
+
const lines = text.split(/\r?\n/);
|
|
49
|
+
|
|
50
|
+
const firstLine = lines.find((line) => {
|
|
51
|
+
const trimmed = line.trimStart();
|
|
52
|
+
return trimmed !== "" && !trimmed.startsWith("#");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (!firstLine) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const columns = firstLine.trimEnd().replace(/\r$/, "").split("\t");
|
|
60
|
+
if (columns.length > 1) {
|
|
61
|
+
return columns;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Parse tabix TSV records into plain objects.
|
|
67
|
+
*
|
|
68
|
+
* @param {string[]} lines
|
|
69
|
+
* @param {string[]} columns
|
|
70
|
+
* @param {import("../../../spec/data.js").Parse | null | undefined} [parse]
|
|
71
|
+
*/
|
|
72
|
+
export function parseTabixTsvLines(lines, columns, parse) {
|
|
73
|
+
if (lines.length == 0) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @type {any} */
|
|
78
|
+
const format = {
|
|
79
|
+
type: "tsv",
|
|
80
|
+
columns,
|
|
81
|
+
parse: parse ?? "auto",
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** @type {Record<string, any>[]} */
|
|
85
|
+
const data = read(lines.join("\n"), toVegaLoaderFormat(format));
|
|
86
|
+
|
|
87
|
+
const chromField = columns[0];
|
|
88
|
+
/** @type {unknown} */
|
|
89
|
+
let prev = null;
|
|
90
|
+
let stringChrom = "";
|
|
91
|
+
|
|
92
|
+
for (const datum of data) {
|
|
93
|
+
const value = datum[chromField];
|
|
94
|
+
if (value != prev) {
|
|
95
|
+
prev = value;
|
|
96
|
+
stringChrom = String(value);
|
|
97
|
+
}
|
|
98
|
+
datum[chromField] = stringChrom;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return data;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @extends {TabixSource<Record<string, any>>}
|
|
106
|
+
*/
|
|
107
|
+
export default class TabixTsvSource extends TabixSource {
|
|
108
|
+
/** @type {string[] | undefined} */
|
|
109
|
+
#columns;
|
|
110
|
+
|
|
111
|
+
get label() {
|
|
112
|
+
return "tabixSource";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {string} header
|
|
117
|
+
*/
|
|
118
|
+
async _handleHeader(header) {
|
|
119
|
+
const params =
|
|
120
|
+
/** @type {import("../../../spec/data.js").TabixTsvData} */ (
|
|
121
|
+
this.params
|
|
122
|
+
);
|
|
123
|
+
const columns = withoutExprRef(params.columns);
|
|
124
|
+
this.#columns = columns ?? extractTabixTsvColumns(header);
|
|
125
|
+
|
|
126
|
+
if (!this.#columns?.length) {
|
|
127
|
+
this.#columns = extractTabixTsvColumnsFromFirstLine(
|
|
128
|
+
await this._readFilePrefix()
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!this.#columns?.length) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
"No columns available for Tabix TSV source. Provide data.lazy.columns or a tabix header line such as #chrom\\tstart\\tend, or a plain first row such as chrom\\tstart\\tend."
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param {string[]} lines
|
|
141
|
+
*/
|
|
142
|
+
_parseFeatures(lines) {
|
|
143
|
+
const params =
|
|
144
|
+
/** @type {import("../../../spec/data.js").TabixTsvData} */ (
|
|
145
|
+
this.params
|
|
146
|
+
);
|
|
147
|
+
return parseTabixTsvLines(
|
|
148
|
+
lines,
|
|
149
|
+
this.#columns ?? [],
|
|
150
|
+
withoutExprRef(params.parse)
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @param {import("../../../spec/data.js").LazyDataParams} params
|
|
157
|
+
* @returns {params is import("../../../spec/data.js").TabixTsvData}
|
|
158
|
+
*/
|
|
159
|
+
function isTabixTsvSource(params) {
|
|
160
|
+
return params?.type == "tabix";
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
registerBuiltInLazyDataSource(isTabixTsvSource, TabixTsvSource);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genomeSpyBase.d.ts","sourceRoot":"","sources":["../../src/genomeSpyBase.js"],"names":[],"mappings":"AA8CA;;;GAGG;AAEH;IAoBI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA0CpD;IAvCG,uBAA0B;IAC1B,oDAAsB;IAItB,sCAAsC;IACtC,wCAAgB;IAEhB,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,CAAC,CAAS,IAAM,EAAN,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,yBAFU,CAAC,IAAI,qEAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,8EAAyB;IAIzB,YAAkC;IAatC;;;OAGG;IACH,oCAFW,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAYf;IAED;;;OAGG;IACH,uBAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;OAGG;IACH,0BAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAMb;
|
|
1
|
+
{"version":3,"file":"genomeSpyBase.d.ts","sourceRoot":"","sources":["../../src/genomeSpyBase.js"],"names":[],"mappings":"AA8CA;;;GAGG;AAEH;IAoBI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA0CpD;IAvCG,uBAA0B;IAC1B,oDAAsB;IAItB,sCAAsC;IACtC,wCAAgB;IAEhB,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,CAAC,CAAS,IAAM,EAAN,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,yBAFU,CAAC,IAAI,qEAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,8EAAyB;IAIzB,YAAkC;IAatC;;;OAGG;IACH,oCAFW,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAYf;IAED;;;OAGG;IACH,uBAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;OAGG;IACH,0BAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAMb;IAmEG,iDAAsB;IAQ1B;;OAEG;IACH,gBAqBC;IAyND;;;OAGG;IACH,UAFa,OAAO,CAAC,OAAO,CAAC,CAyC5B;IAED,2CAiBC;IAED;;;;;OAKG;IACH,8BAFW,WAAW,iBAerB;IAED;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAKlF;IAED;;;;;;;;OAQG;IACH,4BANW,MAAM,kBACN,MAAM,qBACN,MAAM,eACN,MAAM,UAuBhB;IAED;;;MAEC;IAED;eACwB,MAAM,GAAG,SAAS;gBAAU,MAAM,GAAG,SAAS;MAcrE;IAED,sBAGC;IAED,kBAEC;IAED,iCAEC;IAED,oEAYC;IAED,uFAWC;;CACJ;;;;iCA/oBY,eAAe,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB;4BAtBnC,uBAAuB;qBAP9C,qBAAqB;wBAElB,yBAAyB;qBAL5B,oBAAoB"}
|
|
@@ -256,7 +256,10 @@ export default class GenomeSpy {
|
|
|
256
256
|
this.viewRoot
|
|
257
257
|
? calculateCanvasSize(this.viewRoot)
|
|
258
258
|
: { width: undefined, height: undefined },
|
|
259
|
-
{ powerPreference: this.options.powerPreference ?? "default" }
|
|
259
|
+
{ powerPreference: this.options.powerPreference ?? "default" },
|
|
260
|
+
// Physical backing-store changes do not affect layout, but they
|
|
261
|
+
// clear the canvas and require repainting the existing render batch.
|
|
262
|
+
() => this.#renderCoordinator?.renderAll()
|
|
260
263
|
);
|
|
261
264
|
|
|
262
265
|
canvasWrapper.appendChild(loadingIndicatorsElement);
|
|
@@ -40,11 +40,12 @@ export default class WebGLHelper {
|
|
|
40
40
|
* A function that returns the content size. If a dimension is undefined,
|
|
41
41
|
* the canvas fills the container, otherwise the canvas is adjusted to the content size.
|
|
42
42
|
* @param {WebGLContextAttributes} [webglContextAttributes]
|
|
43
|
+
* @param {() => void} [onCanvasResize]
|
|
43
44
|
*/
|
|
44
45
|
constructor(container: HTMLElement, sizeSource?: () => {
|
|
45
46
|
width: number;
|
|
46
47
|
height: number;
|
|
47
|
-
}, webglContextAttributes?: WebGLContextAttributes);
|
|
48
|
+
}, webglContextAttributes?: WebGLContextAttributes, onCanvasResize?: () => void);
|
|
48
49
|
/**
|
|
49
50
|
* @type {CanvasSizeHelper}
|
|
50
51
|
*/
|
|
@@ -58,6 +59,8 @@ export default class WebGLHelper {
|
|
|
58
59
|
physicalWidth: number;
|
|
59
60
|
physicalHeight: number;
|
|
60
61
|
} | undefined;
|
|
62
|
+
/** @type {() => void} */
|
|
63
|
+
_onCanvasResize: () => void;
|
|
61
64
|
/** @type {Map<string, WebGLShader>} */
|
|
62
65
|
_shaderCache: Map<string, WebGLShader>;
|
|
63
66
|
/** @type {WeakMap<import("../types/encoder.js").VegaScale, WebGLTexture>} */
|
|
@@ -79,7 +82,7 @@ export default class WebGLHelper {
|
|
|
79
82
|
* @param {string | string[]} glsl
|
|
80
83
|
*/
|
|
81
84
|
compileShader(type: number, glsl: string | string[]): WebGLShader;
|
|
82
|
-
adjustGl():
|
|
85
|
+
adjustGl(): boolean;
|
|
83
86
|
finalize(): void;
|
|
84
87
|
/**
|
|
85
88
|
* Returns the canvas size in true display pixels
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"AA0cA;;;;GAIG;AACH,kCAJW,sBAAsB,gBACtB,WAAW,kBACX,WAAW;;;;;;EA8CrB;AAED;;;;;GAKG;AACH,0CALW,qBAAqB,WACrB,IAAI,CAAC,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,OAC7C,MAAM,EAAE,GAAG,eAAe,YAC1B,YAAY,gBAYtB;AAED;;;;;;GAMG;AACH,qCALW,sBAAsB,mBACtB,OAAO,SAAS,EAAE,eAAe,KACjC,MAAM,KACN,MAAM,2BAWhB;AAED;;;;;GAKG;AACH,yCAJW,sBAAsB,mBACtB,OAAO,SAAS,EAAE,eAAe,SACjC,MAAM,UA4BhB;AA9hBD;IACI;;;;;;;;OAQG;IACH,uBAPW,WAAW,eACX,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,2BAGrC,sBAAsB,mBACtB,MAAM,IAAI,EAoHpB;IArGG;;OAEG;IACH,mBAFU,gBAAgB,CAEQ;IAElC;;OAEG;IACH,oBAFU;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAEjF;IAEnC,yBAAyB;IACzB,iBADW,MAAM,IAAI,CAC8B;IAEnD,uCAAuC;IACvC,cADW,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CACN;IAE7B,6EAA6E;IAC7E,eADW,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,EAAE,YAAY,CAAC,CACvC;IAElC;;OAEG;IACH,mBAFU,OAAO,CAAC,OAAO,4BAA4B,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAEnD;IA8CtC,0BAAoB;IACpB,2BAAY;IAGZ,oDAAoD;IACpD,2BADW,OAAO,SAAS,EAAE,iBAAiB,EAAE,CAQ/C;IACD,sDAGC;IAmBL,uBAGC;IAED;;;;;OAKG;IACH,oBAHW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,eA2B3B;IAED,oBAkCC;IAED,iBAGC;IAED;;;;OAIG;IACH,oCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;;MAI3C;IAED;;;;OAIG;IACH,kCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,UAI3C;IAED;;;OAGG;IACH;;;MAEC;IAED;;;;;;;;;OASG;IACH,+BAHW,OAAO,8BAA8B,EAAE,OAAO,WAC9C,OAAO,QA2GjB;IAED;;OAEG;IACH,kCAFW,OAAO,4BAA4B,EAAE,mBAAmB,0BAwClE;CACJ;6BAxY4B,uBAAuB"}
|
|
@@ -41,8 +41,14 @@ export default class WebGLHelper {
|
|
|
41
41
|
* A function that returns the content size. If a dimension is undefined,
|
|
42
42
|
* the canvas fills the container, otherwise the canvas is adjusted to the content size.
|
|
43
43
|
* @param {WebGLContextAttributes} [webglContextAttributes]
|
|
44
|
+
* @param {() => void} [onCanvasResize]
|
|
44
45
|
*/
|
|
45
|
-
constructor(
|
|
46
|
+
constructor(
|
|
47
|
+
container,
|
|
48
|
+
sizeSource,
|
|
49
|
+
webglContextAttributes = {},
|
|
50
|
+
onCanvasResize
|
|
51
|
+
) {
|
|
46
52
|
const resolvedSizeSource =
|
|
47
53
|
sizeSource ??
|
|
48
54
|
(() => ({
|
|
@@ -60,6 +66,9 @@ export default class WebGLHelper {
|
|
|
60
66
|
*/
|
|
61
67
|
this._appliedCanvasSize = undefined;
|
|
62
68
|
|
|
69
|
+
/** @type {() => void} */
|
|
70
|
+
this._onCanvasResize = onCanvasResize ?? (() => {});
|
|
71
|
+
|
|
63
72
|
/** @type {Map<string, WebGLShader>} */
|
|
64
73
|
this._shaderCache = new Map();
|
|
65
74
|
|
|
@@ -138,7 +147,13 @@ export default class WebGLHelper {
|
|
|
138
147
|
container,
|
|
139
148
|
canvas,
|
|
140
149
|
resolvedSizeSource,
|
|
141
|
-
() =>
|
|
150
|
+
() => {
|
|
151
|
+
// Assigning canvas.width/height clears the WebGL drawing buffer.
|
|
152
|
+
// The observer may fire after layout/render, so repaint immediately.
|
|
153
|
+
if (this.adjustGl()) {
|
|
154
|
+
this._onCanvasResize();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
142
157
|
);
|
|
143
158
|
|
|
144
159
|
this.adjustGl();
|
|
@@ -193,7 +208,7 @@ export default class WebGLHelper {
|
|
|
193
208
|
this._appliedCanvasSize.physicalWidth == physicalSize.width &&
|
|
194
209
|
this._appliedCanvasSize.physicalHeight == physicalSize.height
|
|
195
210
|
) {
|
|
196
|
-
return;
|
|
211
|
+
return false;
|
|
197
212
|
}
|
|
198
213
|
|
|
199
214
|
this.canvas.style.width = `${logicalSize.width}px`;
|
|
@@ -214,6 +229,8 @@ export default class WebGLHelper {
|
|
|
214
229
|
physicalWidth: physicalSize.width,
|
|
215
230
|
physicalHeight: physicalSize.height,
|
|
216
231
|
};
|
|
232
|
+
|
|
233
|
+
return true;
|
|
217
234
|
}
|
|
218
235
|
|
|
219
236
|
finalize() {
|