@genome-spy/core 0.64.0 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/bundle/{index-CCJIjehY.js → AbortablePromiseCache-CcuMrnn7.js} +22 -91
  2. package/dist/bundle/browser-txUcLy2H.js +123 -0
  3. package/dist/bundle/index-BQpbYrv4.js +1712 -0
  4. package/dist/bundle/index-BhtHKLUo.js +73 -0
  5. package/dist/bundle/index-C0llXMqm.js +280 -0
  6. package/dist/bundle/index-CCe8rnZz.js +716 -0
  7. package/dist/bundle/index-CD7FLu9x.js +269 -0
  8. package/dist/bundle/{index-C08YCM2T.js → index-D-w7Mmt9.js} +246 -126
  9. package/dist/bundle/index-D74H8TTz.js +508 -0
  10. package/dist/bundle/index-DhcU-Gk-.js +1487 -0
  11. package/dist/bundle/index.es.js +4878 -4680
  12. package/dist/bundle/index.js +151 -167
  13. package/dist/bundle/inflate-DRgHi_KK.js +1050 -0
  14. package/dist/schema.json +9 -1
  15. package/dist/src/data/collector.d.ts +7 -2
  16. package/dist/src/data/collector.d.ts.map +1 -1
  17. package/dist/src/data/collector.js +13 -2
  18. package/dist/src/data/dataFlow.d.ts +20 -42
  19. package/dist/src/data/dataFlow.d.ts.map +1 -1
  20. package/dist/src/data/dataFlow.js +57 -80
  21. package/dist/src/data/dataFlow.test.js +35 -2
  22. package/dist/src/data/flowHandle.d.ts +15 -0
  23. package/dist/src/data/flowHandle.d.ts.map +1 -0
  24. package/dist/src/data/flowHandle.js +13 -0
  25. package/dist/src/data/flowInit.d.ts +85 -0
  26. package/dist/src/data/flowInit.d.ts.map +1 -0
  27. package/dist/src/data/flowInit.js +238 -0
  28. package/dist/src/data/flowInit.test.d.ts +2 -0
  29. package/dist/src/data/flowInit.test.d.ts.map +1 -0
  30. package/dist/src/data/flowInit.test.js +413 -0
  31. package/dist/src/data/flowOptimizer.d.ts +6 -4
  32. package/dist/src/data/flowOptimizer.d.ts.map +1 -1
  33. package/dist/src/data/flowOptimizer.js +29 -14
  34. package/dist/src/data/flowOptimizer.test.js +20 -15
  35. package/dist/src/data/sources/lazy/bamSource.js +1 -1
  36. package/dist/src/data/sources/lazy/bigBedSource.js +1 -1
  37. package/dist/src/data/sources/lazy/bigWigSource.js +1 -1
  38. package/dist/src/data/sources/lazy/gff3Source.d.ts +2 -6
  39. package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
  40. package/dist/src/data/sources/lazy/gff3Source.js +4 -8
  41. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
  42. package/dist/src/data/sources/lazy/indexedFastaSource.js +17 -17
  43. package/dist/src/data/sources/lazy/tabixSource.js +1 -1
  44. package/dist/src/genomeSpy.d.ts +1 -1
  45. package/dist/src/genomeSpy.d.ts.map +1 -1
  46. package/dist/src/genomeSpy.js +18 -61
  47. package/dist/src/marks/mark.d.ts +1 -0
  48. package/dist/src/marks/mark.d.ts.map +1 -1
  49. package/dist/src/marks/mark.js +22 -1
  50. package/dist/src/spec/sampleView.d.ts +3 -2
  51. package/dist/src/types/viewContext.d.ts +1 -1
  52. package/dist/src/view/axisResolution.d.ts +5 -0
  53. package/dist/src/view/axisResolution.d.ts.map +1 -1
  54. package/dist/src/view/axisResolution.js +16 -1
  55. package/dist/src/view/facetView.d.ts.map +1 -1
  56. package/dist/src/view/facetView.js +1 -0
  57. package/dist/src/view/flowBuilder.d.ts +2 -2
  58. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  59. package/dist/src/view/flowBuilder.js +21 -4
  60. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  61. package/dist/src/view/gridView/gridView.js +13 -0
  62. package/dist/src/view/gridView/selectionRect.d.ts +8 -4
  63. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  64. package/dist/src/view/gridView/selectionRect.js +28 -3
  65. package/dist/src/view/gridView/selectionRect.test.d.ts +2 -0
  66. package/dist/src/view/gridView/selectionRect.test.d.ts.map +1 -0
  67. package/dist/src/view/gridView/selectionRect.test.js +87 -0
  68. package/dist/src/view/paramMediator.d.ts +2 -1
  69. package/dist/src/view/paramMediator.d.ts.map +1 -1
  70. package/dist/src/view/paramMediator.js +13 -1
  71. package/dist/src/view/paramMediator.test.js +22 -0
  72. package/dist/src/view/scaleResolution.d.ts +5 -0
  73. package/dist/src/view/scaleResolution.d.ts.map +1 -1
  74. package/dist/src/view/scaleResolution.js +10 -0
  75. package/dist/src/view/testUtils.d.ts.map +1 -1
  76. package/dist/src/view/testUtils.js +16 -4
  77. package/dist/src/view/unitView.d.ts.map +1 -1
  78. package/dist/src/view/unitView.js +58 -8
  79. package/dist/src/view/view.d.ts +17 -1
  80. package/dist/src/view/view.d.ts.map +1 -1
  81. package/dist/src/view/view.js +57 -1
  82. package/dist/src/view/viewDispose.test.d.ts +2 -0
  83. package/dist/src/view/viewDispose.test.d.ts.map +1 -0
  84. package/dist/src/view/viewDispose.test.js +110 -0
  85. package/dist/src/view/viewUtils.d.ts +4 -4
  86. package/dist/src/view/viewUtils.d.ts.map +1 -1
  87. package/dist/src/view/viewUtils.js +19 -15
  88. package/dist/src/view/viewUtils.test.d.ts +2 -0
  89. package/dist/src/view/viewUtils.test.d.ts.map +1 -0
  90. package/dist/src/view/viewUtils.test.js +87 -0
  91. package/package.json +10 -10
  92. package/dist/bundle/__vite-browser-external-C--ziKoh.js +0 -8
  93. package/dist/bundle/_commonjsHelpers-DjF3Plf2.js +0 -26
  94. package/dist/bundle/index-5ajWdKly.js +0 -1319
  95. package/dist/bundle/index-B03-Om4z.js +0 -274
  96. package/dist/bundle/index-BftNdA0O.js +0 -27
  97. package/dist/bundle/index-Bg7C4Xat.js +0 -2750
  98. package/dist/bundle/index-C3QR8Lv6.js +0 -2131
  99. package/dist/bundle/index-DTcHjAHp.js +0 -505
  100. package/dist/bundle/index-DnIkxb0L.js +0 -1025
  101. package/dist/bundle/index-Ww3TAo6_.js +0 -71
  102. package/dist/bundle/index-g8iXgW0W.js +0 -651
  103. package/dist/bundle/long-B-FASCSo.js +0 -2387
  104. package/dist/bundle/remoteFile-BuaqFGWk.js +0 -94
@@ -82,30 +82,43 @@ export function combineAndPullCollectorsUp() {
82
82
  // --F--G
83
83
 
84
84
  /**
85
- * @param {import("./dataFlow.js").default<any>} dataFlow
85
+ * @param {import("./dataFlow.js").default} dataFlow
86
+ * @returns {Map<import("./sources/dataSource.js").default, import("./sources/dataSource.js").default>}
86
87
  */
87
88
  export function combineIdenticalDataSources(dataFlow) {
88
- const dataSourceEntries = [...dataFlow._dataSourcesByHost.entries()];
89
+ const dataSources = dataFlow.dataSources;
89
90
 
90
91
  /** @type {Map<string, import("./sources/dataSource.js").default>} */
91
92
  const sourcesByIdentifiers = new Map();
92
- for (const e of dataSourceEntries) {
93
- const ds = e[1];
93
+ for (const ds of dataSources) {
94
94
  if (ds.identifier && !sourcesByIdentifiers.has(ds.identifier)) {
95
95
  sourcesByIdentifiers.set(ds.identifier, ds);
96
96
  }
97
97
  }
98
98
 
99
- dataFlow._dataSourcesByHost.clear();
100
-
101
- for (let [key, dataSource] of dataSourceEntries) {
102
- const target = sourcesByIdentifiers.get(dataSource.identifier);
103
- if (target) {
104
- target.adoptChildrenOf(dataSource);
105
- dataSource = target;
99
+ /** @type {Set<import("./sources/dataSource.js").default>} */
100
+ const mergedSources = new Set();
101
+ /** @type {Map<import("./sources/dataSource.js").default, import("./sources/dataSource.js").default>} */
102
+ const canonicalBySource = new Map();
103
+
104
+ for (const dataSource of dataSources) {
105
+ if (dataSource.identifier) {
106
+ const target = sourcesByIdentifiers.get(dataSource.identifier);
107
+ if (target) {
108
+ if (target !== dataSource) {
109
+ target.adoptChildrenOf(dataSource);
110
+ }
111
+ mergedSources.add(target);
112
+ canonicalBySource.set(dataSource, target);
113
+ }
114
+ } else {
115
+ mergedSources.add(dataSource);
116
+ canonicalBySource.set(dataSource, dataSource);
106
117
  }
107
- dataFlow.addDataSource(dataSource, key);
108
118
  }
119
+
120
+ dataFlow.replaceDataSources(mergedSources);
121
+ return canonicalBySource;
109
122
  }
110
123
 
111
124
  /**
@@ -122,11 +135,13 @@ export function optimizeFlowGraph(root) {
122
135
  }
123
136
 
124
137
  /**
125
- * @param {import("./dataFlow.js").default<any>} dataFlow
138
+ * @param {import("./dataFlow.js").default} dataFlow
139
+ * @returns {Map<import("./sources/dataSource.js").default, import("./sources/dataSource.js").default>}
126
140
  */
127
141
  export function optimizeDataFlow(dataFlow) {
128
- combineIdenticalDataSources(dataFlow);
142
+ const canonicalBySource = combineIdenticalDataSources(dataFlow);
129
143
  for (const dataSource of dataFlow.dataSources) {
130
144
  optimizeFlowGraph(dataSource);
131
145
  }
146
+ return canonicalBySource;
132
147
  }
@@ -142,7 +142,7 @@ const viewStub = /** @type {any} */ (
142
142
 
143
143
  describe("Merge indentical data sources", () => {
144
144
  test("Merges correctly", () => {
145
- /** @type {DataFlow<string>} */
145
+ /** @type {DataFlow} */
146
146
  const dataFlow = new DataFlow();
147
147
 
148
148
  const a = new UrlSource({ url: "http://genomespy.app/" }, viewStub);
@@ -157,21 +157,25 @@ describe("Merge indentical data sources", () => {
157
157
  const cc = new Collector();
158
158
  c.addChild(cc);
159
159
 
160
- dataFlow.addDataSource(a, "a");
161
- dataFlow.addDataSource(b, "b");
162
- dataFlow.addDataSource(c, "c");
160
+ dataFlow.addDataSource(a);
161
+ dataFlow.addDataSource(b);
162
+ dataFlow.addDataSource(c);
163
163
 
164
- dataFlow.addCollector(ac, "a");
165
- dataFlow.addCollector(bc, "b");
166
- dataFlow.addCollector(cc, "c");
164
+ dataFlow.addCollector(ac);
165
+ dataFlow.addCollector(bc);
166
+ dataFlow.addCollector(cc);
167
167
 
168
168
  combineIdenticalDataSources(dataFlow);
169
169
 
170
170
  expect(dataFlow.dataSources.length).toEqual(2);
171
171
 
172
- expect(dataFlow.findDataSourceByKey("a")).toBe(a);
173
- expect(dataFlow.findDataSourceByKey("b")).toBe(a); // Merged!
174
- expect(dataFlow.findDataSourceByKey("c")).toBe(c);
172
+ const entries = dataFlow.dataSources;
173
+ const sharedIdentifier = a.identifier;
174
+ expect(entries).toContain(a);
175
+ expect(entries).toContain(c);
176
+ expect(
177
+ entries.filter((source) => source.identifier == sharedIdentifier)
178
+ ).toEqual([a]);
175
179
 
176
180
  expect(new Set(a.children)).toEqual(new Set([ac, bc]));
177
181
  expect(c.children[0]).toBe(cc);
@@ -187,18 +191,19 @@ describe("Merge indentical data sources", () => {
187
191
  });
188
192
 
189
193
  test("Does not merge those with undefined identifier", () => {
190
- /** @type {DataFlow<string>} */
194
+ /** @type {DataFlow} */
191
195
  const dataFlow = new DataFlow();
192
196
 
193
197
  const a = new InlineSource({ values: [1, 2, 3] }, viewStub);
194
198
  const b = new InlineSource({ values: [1, 2, 3] }, viewStub);
195
199
 
196
- dataFlow.addDataSource(a, "a");
197
- dataFlow.addDataSource(b, "b");
200
+ dataFlow.addDataSource(a);
201
+ dataFlow.addDataSource(b);
198
202
 
199
203
  combineIdenticalDataSources(dataFlow);
200
204
 
201
- expect(dataFlow.findDataSourceByKey("a")).toBe(a);
202
- expect(dataFlow.findDataSourceByKey("b")).toBe(b);
205
+ const entries = dataFlow.dataSources;
206
+ expect(entries).toContain(a);
207
+ expect(entries).toContain(b);
203
208
  });
204
209
  });
@@ -43,7 +43,7 @@ export default class BamSource extends SingleAxisWindowedSource {
43
43
  this.initializedPromise = new Promise((resolve) => {
44
44
  Promise.all([
45
45
  import("@gmod/bam"),
46
- import("generic-filehandle"),
46
+ import("generic-filehandle2"),
47
47
  ]).then(([{ BamFile }, { RemoteFile }]) => {
48
48
  const withBase = (/** @type {string} */ uri) =>
49
49
  new RemoteFile(addBaseUrl(uri, this.view.getBaseUrl()));
@@ -63,7 +63,7 @@ export default class BigBedSource extends SingleAxisWindowedSource {
63
63
  Promise.all([
64
64
  import("@gmod/bed"),
65
65
  import("@gmod/bbi"),
66
- import("generic-filehandle"),
66
+ import("generic-filehandle2"),
67
67
  ]).then(([bed, { BigBed }, { RemoteFile }]) => {
68
68
  const BED = bed.default;
69
69
 
@@ -62,7 +62,7 @@ export default class BigWigSource extends SingleAxisWindowedSource {
62
62
  this.initializedPromise = new Promise((resolve, reject) => {
63
63
  Promise.all([
64
64
  import("@gmod/bbi"),
65
- import("generic-filehandle"),
65
+ import("generic-filehandle2"),
66
66
  ]).then(([{ BigWig }, { RemoteFile }]) => {
67
67
  this.#bbi = new BigWig({
68
68
  filehandle: new RemoteFile(
@@ -1,12 +1,8 @@
1
1
  /**
2
- * @extends {TabixSource<import("@gmod/gff").GFF3Feature>}
2
+ * @extends {TabixSource<import("gff-nostream").GFF3Feature>}
3
3
  */
4
- export default class Gff3Source extends TabixSource<import("@gmod/gff").GFF3Feature> {
4
+ export default class Gff3Source extends TabixSource<import("gff-nostream").GFF3Feature> {
5
5
  constructor(params: import("../../../spec/data.js").TabixData, view: import("../../../view/view.js").default);
6
- /**
7
- * @param {string[]} lines
8
- */
9
- _parseFeatures(lines: string[]): any;
10
6
  #private;
11
7
  }
12
8
  import TabixSource from "./tabixSource.js";
@@ -1 +1 @@
1
- {"version":3,"file":"gff3Source.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/gff3Source.js"],"names":[],"mappings":"AAEA;;GAEG;AACH;;IAeI;;OAEG;IACH,sBAFW,MAAM,EAAE,OAUlB;;CACJ;wBAhCuB,kBAAkB"}
1
+ {"version":3,"file":"gff3Source.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/gff3Source.js"],"names":[],"mappings":"AAEA;;GAEG;AACH;;;CAuBC;wBA5BuB,kBAAkB"}
@@ -1,10 +1,10 @@
1
1
  import TabixSource from "./tabixSource.js";
2
2
 
3
3
  /**
4
- * @extends {TabixSource<import("@gmod/gff").GFF3Feature>}
4
+ * @extends {TabixSource<import("gff-nostream").GFF3Feature>}
5
5
  */
6
6
  export default class Gff3Source extends TabixSource {
7
- /** @type {import("@gmod/gff").default} */
7
+ /** @type {import("gff-nostream")} */
8
8
  #gff;
9
9
 
10
10
  get label() {
@@ -15,18 +15,14 @@ export default class Gff3Source extends TabixSource {
15
15
  * @param {string} header
16
16
  */
17
17
  async _handleHeader(header) {
18
- this.#gff = (await import("@gmod/gff")).default;
18
+ this.#gff = await import("gff-nostream");
19
19
  }
20
20
 
21
21
  /**
22
22
  * @param {string[]} lines
23
23
  */
24
24
  _parseFeatures(lines) {
25
- // Hmm. It's silly that we have to first collect individual lines and then join them.
26
- // eslint-disable-next-line no-sync
27
- const features = this.#gff?.parseStringSync(lines.join("\n"), {
28
- parseSequences: false,
29
- });
25
+ const features = this.#gff?.parseArraySync(lines);
30
26
 
31
27
  return features;
32
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"indexedFastaSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/indexedFastaSource.js"],"names":[],"mappings":"AAGA;IACI;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,gBAAgB,QAChD,OAAO,uBAAuB,EAAE,OAAO,EA+CjD;IAjCG,yDAAgC;IAQhC,iCAwBE;IATM,iDAKE;CAiCjB;qCAhFoC,+BAA+B"}
1
+ {"version":3,"file":"indexedFastaSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/indexedFastaSource.js"],"names":[],"mappings":"AAGA;IACI;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,gBAAgB,QAChD,OAAO,uBAAuB,EAAE,OAAO,EAwCjD;IA1BG,yDAAgC;IAQhC,iCAiBE;IATM,iDAKE;CAwCjB;qCAhFoC,+BAA+B"}
@@ -28,16 +28,9 @@ export default class IndexedFastaSource extends SingleAxisWindowedSource {
28
28
 
29
29
  this.initializedPromise = new Promise((resolve) => {
30
30
  Promise.all([
31
- import("buffer"),
32
31
  import("@gmod/indexedfasta"),
33
- import("generic-filehandle"),
34
- ]).then(([{ Buffer }, { IndexedFasta }, { RemoteFile }]) => {
35
- // Hack needed by @gmod/indexedfasta
36
- // TODO: Submit a PR to @gmod/indexedfasta to make this unnecessary
37
- if (typeof window !== "undefined") {
38
- window.Buffer ??= Buffer;
39
- }
40
-
32
+ import("generic-filehandle2"),
33
+ ]).then(([{ IndexedFasta }, { RemoteFile }]) => {
41
34
  const withBase = (/** @type {string} */ uri) =>
42
35
  new RemoteFile(addBaseUrl(uri, this.view.getBaseUrl()));
43
36
 
@@ -68,15 +61,22 @@ export default class IndexedFastaSource extends SingleAxisWindowedSource {
68
61
  .getSequence(d.chrom, d.startPos, d.endPos, {
69
62
  signal,
70
63
  })
71
- .then((sequence) => ({
72
- chrom: d.chrom,
73
- start: d.startPos,
74
- sequence,
75
- }))
64
+ .then((sequence) => {
65
+ if (sequence != undefined) {
66
+ return {
67
+ chrom: d.chrom,
68
+ start: d.startPos,
69
+ sequence,
70
+ };
71
+ } else {
72
+ console.log(
73
+ `No sequence found for interval ${d.chrom}:${d.startPos}-${d.endPos}`
74
+ );
75
+ return undefined;
76
+ }
77
+ })
76
78
  );
77
79
 
78
- if (features) {
79
- this.publishData([features]);
80
- }
80
+ this.publishData([features.filter((f) => f !== undefined)]);
81
81
  }
82
82
  }
@@ -37,7 +37,7 @@ export default class TabixSource extends SingleAxisWindowedSource {
37
37
  this.initializedPromise = new Promise((resolve) => {
38
38
  Promise.all([
39
39
  import("@gmod/tabix"),
40
- import("generic-filehandle"),
40
+ import("generic-filehandle2"),
41
41
  ]).then(async ([{ TabixIndexedFile }, { RemoteFile }]) => {
42
42
  const withBase = (/** @type {string} */ uri) =>
43
43
  new RemoteFile(addBaseUrl(uri, this.view.getBaseUrl()));
@@ -162,7 +162,7 @@ export default class GenomeSpy {
162
162
  /**
163
163
  * Events that are broadcasted to all views.
164
164
  */
165
- export type BroadcastEventType = "dataFlowBuilt" | "dataLoaded" | "layout" | "layoutComputed";
165
+ export type BroadcastEventType = "dataFlowBuilt" | "layout" | "layoutComputed" | "subtreeDataReady";
166
166
  import { ViewFactory } from "./view/viewFactory.js";
167
167
  import Animator from "./utils/animator.js";
168
168
  import GenomeStore from "./genome/genomeStore.js";
@@ -1 +1 @@
1
- {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"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"}
@@ -10,7 +10,9 @@ import {
10
10
  checkForDuplicateScaleNames,
11
11
  setImplicitScaleNames,
12
12
  calculateCanvasSize,
13
+ finalizeSubtreeGraphics,
13
14
  } from "./view/viewUtils.js";
15
+ import { initializeViewSubtree, loadViewSubtreeData } from "./data/flowInit.js";
14
16
  import UnitView from "./view/unitView.js";
15
17
 
16
18
  import WebGLHelper, {
@@ -24,8 +26,6 @@ import InteractionEvent from "./utils/interactionEvent.js";
24
26
  import Point from "./view/layout/point.js";
25
27
  import Animator from "./utils/animator.js";
26
28
  import DataFlow from "./data/dataFlow.js";
27
- import { buildDataFlow } from "./view/flowBuilder.js";
28
- import { optimizeDataFlow } from "./data/flowOptimizer.js";
29
29
  import GenomeStore from "./genome/genomeStore.js";
30
30
  import BmFontManager from "./fonts/bmFontManager.js";
31
31
  import fasta from "./data/formats/fasta.js";
@@ -35,14 +35,13 @@ import refseqGeneTooltipHandler from "./tooltip/refseqGeneTooltipHandler.js";
35
35
  import dataTooltipHandler from "./tooltip/dataTooltipHandler.js";
36
36
  import { invalidatePrefix } from "./utils/propertyCacher.js";
37
37
  import { VIEW_ROOT_NAME, ViewFactory } from "./view/viewFactory.js";
38
- import { reconfigureScales } from "./view/scaleResolution.js";
39
38
  import createBindingInputs from "./utils/inputBinding.js";
40
39
  import { isStillZooming } from "./view/zoom.js";
41
40
  import { createFramebufferInfo } from "twgl.js";
42
41
 
43
42
  /**
44
43
  * Events that are broadcasted to all views.
45
- * @typedef {"dataFlowBuilt" | "dataLoaded" | "layout" | "layoutComputed"} BroadcastEventType
44
+ * @typedef {"dataFlowBuilt" | "layout" | "layoutComputed" | "subtreeDataReady"} BroadcastEventType
46
45
  */
47
46
 
48
47
  vegaFormats("fasta", fasta);
@@ -229,7 +228,6 @@ export default class GenomeSpy {
229
228
  }
230
229
 
231
230
  namedSource.dataSource.updateDynamicData(data);
232
- reconfigureScales(namedSource.hosts);
233
231
 
234
232
  this.animator.requestRender();
235
233
  }
@@ -517,6 +515,9 @@ export default class GenomeSpy {
517
515
  highlightView: (view) => {
518
516
  this.container.querySelector(".view-highlight")?.remove();
519
517
  if (view) {
518
+ if (!view.isConfiguredVisible()) {
519
+ return;
520
+ }
520
521
  const coords = view.coords;
521
522
  if (coords) {
522
523
  const div = document.createElement("div");
@@ -572,42 +573,11 @@ export default class GenomeSpy {
572
573
  this._glHelper.invalidateSize();
573
574
  this.#setupDpr();
574
575
 
575
- // Collect all unit views to a list because they need plenty of initialization
576
- const unitViews = /** @type {UnitView[]} */ (
577
- views.filter((view) => view instanceof UnitView)
578
- );
579
-
580
- // Build the data flow based on the view hierarchy
581
- const flow = buildDataFlow(this.viewRoot, context.dataFlow);
582
- optimizeDataFlow(flow);
583
- this.broadcast("dataFlowBuilt", flow);
584
-
585
- // @ts-expect-error
586
- if (import.meta.env?.DEV) {
587
- flow.dataSources.forEach((ds) => console.log(ds.subtreeToString()));
588
- }
589
-
590
- // Create encoders (accessors, scales and related metadata)
591
- unitViews.forEach((view) => view.mark.initializeEncoders());
592
-
593
- // Compile shaders, create or load textures, etc.
594
- const graphicsInitialized = Promise.all(
595
- unitViews.map((view) => view.mark.initializeGraphics())
576
+ const { dataFlow, graphicsPromises } = initializeViewSubtree(
577
+ this.viewRoot,
578
+ context.dataFlow
596
579
  );
597
-
598
- for (const view of unitViews) {
599
- flow.addObserver((collector) => {
600
- view.mark.initializeData();
601
- try {
602
- // Update WebGL buffers
603
- view.mark.updateGraphicsData();
604
- } catch (e) {
605
- e.view = view;
606
- throw e;
607
- }
608
- context.animator.requestRender();
609
- }, view);
610
- }
580
+ this.broadcast("dataFlowBuilt", dataFlow);
611
581
 
612
582
  // Have to wait until asynchronous font loading is complete.
613
583
  // Text mark's geometry builder needs font metrics before data can be
@@ -615,28 +585,10 @@ export default class GenomeSpy {
615
585
  // TODO: Make updateGraphicsData async and await font loading there.
616
586
  await context.fontManager.waitUntilReady();
617
587
 
618
- // Find all data sources and initiate loading
619
- flow.initialize();
620
- await Promise.all(
621
- flow.dataSources.map((dataSource) => dataSource.load())
622
- );
623
-
624
- // Now that all data have been loaded, the domains may need adjusting
625
- // IMPORTANT TODO: Check that discrete domains and indexers match!!!!!!!!!
626
- reconfigureScales(this.viewRoot);
588
+ // Find all data sources and initiate loading.
589
+ await loadViewSubtreeData(this.viewRoot, new Set(dataFlow.dataSources));
627
590
 
628
- // This event is needed by SampleView so that it can extract the sample ids
629
- // from the data once they are loaded.
630
- // TODO: It would be great if this could be attached to the data flow,
631
- // because now this is somewhat a hack and is incompatible with dynamic data
632
- // loading in the future.
633
- this.broadcast("dataLoaded");
634
-
635
- await graphicsInitialized;
636
-
637
- for (const view of unitViews) {
638
- view.mark.finalizeGraphicsInitialization();
639
- }
591
+ await finalizeSubtreeGraphics(graphicsPromises);
640
592
 
641
593
  // Allow layout computation
642
594
  // eslint-disable-next-line require-atomic-updates
@@ -872,6 +824,11 @@ export default class GenomeSpy {
872
824
  canvas.addEventListener("dragstart", (event) =>
873
825
  event.stopPropagation()
874
826
  );
827
+
828
+ canvas.addEventListener("mouseout", () => {
829
+ this.tooltip.clear();
830
+ this._currentHover = null;
831
+ });
875
832
  }
876
833
 
877
834
  /**
@@ -200,6 +200,7 @@ export default class Mark<P extends import("../spec/mark.js").MarkProps = import
200
200
  * Delete WebGL buffers etc.
201
201
  */
202
202
  deleteGraphicsData(): void;
203
+ dispose(): void;
203
204
  /**
204
205
  *
205
206
  * @param {any} vertexData TODO: Extract type from VertexBuilder
@@ -1 +1 @@
1
- {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
@@ -95,6 +95,11 @@ export default class Mark {
95
95
  */
96
96
  #callAfterShaderCompilation = [];
97
97
 
98
+ /**
99
+ * @type {{expr: import("../view/paramMediator.js").ExprRefFunction, listener: () => void}[]}
100
+ */
101
+ #exprListeners = [];
102
+
98
103
  /**
99
104
  * @param {import("../view/unitView.js").default} unitView
100
105
  */
@@ -1034,6 +1039,7 @@ export default class Mark {
1034
1039
 
1035
1040
  // Register a listener ...
1036
1041
  fn.addListener(set);
1042
+ this.#exprListeners.push({ expr: fn, listener: set });
1037
1043
  // ... and set the initial value
1038
1044
  set();
1039
1045
  } else {
@@ -1045,7 +1051,14 @@ export default class Mark {
1045
1051
  * Delete WebGL buffers etc.
1046
1052
  */
1047
1053
  deleteGraphicsData() {
1048
- const gl = this.gl;
1054
+ const glHelper = this.glHelper;
1055
+ if (!glHelper) {
1056
+ this.vertexArrayInfo = undefined;
1057
+ this.bufferInfo = undefined;
1058
+ return;
1059
+ }
1060
+
1061
+ const gl = glHelper.gl;
1049
1062
 
1050
1063
  if (this.vertexArrayInfo) {
1051
1064
  this.gl.bindVertexArray(null);
@@ -1070,6 +1083,14 @@ export default class Mark {
1070
1083
  }
1071
1084
  }
1072
1085
 
1086
+ dispose() {
1087
+ for (const { expr, listener } of this.#exprListeners) {
1088
+ expr.removeListener(listener);
1089
+ }
1090
+ this.#exprListeners.length = 0;
1091
+ this.deleteGraphicsData();
1092
+ }
1093
+
1073
1094
  /**
1074
1095
  *
1075
1096
  * @param {any} vertexData TODO: Extract type from VertexBuilder
@@ -1,4 +1,3 @@
1
- import { Type } from "./channel.js";
2
1
  import { Data } from "./data.js";
3
2
  import { Align, FontStyle, FontWeight } from "./font.js";
4
3
  import { Scale } from "./scale.js";
@@ -31,11 +30,13 @@ export interface SampleSpec extends ViewSpecBase {
31
30
  stickySummaries?: boolean;
32
31
  }
33
32
 
33
+ export type SampleAttributeType = "nominal" | "ordinal" | "quantitative";
34
+
34
35
  export interface SampleAttributeDef {
35
36
  /**
36
37
  * The attribute type. One of `"nominal"`, `"ordinal"`, or `"quantitative"`.
37
38
  */
38
- type?: Type; // TODO: Omit index/locus from available types
39
+ type?: SampleAttributeType;
39
40
 
40
41
  /**
41
42
  * Scale definition for the (default) color channel
@@ -22,7 +22,7 @@ export type DataLoadingStatus = "loading" | "complete" | "error";
22
22
  * ViewContext provides essential data and interfaces to View classes.
23
23
  */
24
24
  export default interface ViewContext {
25
- dataFlow: DataFlow<View>;
25
+ dataFlow: DataFlow;
26
26
  glHelper: WebGLHelper;
27
27
  animator: Animator;
28
28
  genomeStore?: GenomeStore;
@@ -26,6 +26,11 @@ export default class AxisResolution {
26
26
  * @param {AxisResolutionMember} newMember
27
27
  */
28
28
  addMember(newMember: AxisResolutionMember): void;
29
+ /**
30
+ * @param {UnitView} view
31
+ * @returns {boolean}
32
+ */
33
+ removeMembersByView(view: import("./unitView.js").default): boolean;
29
34
  getAxisProps(): import("../spec/axis.js").GenomeAxis;
30
35
  getTitle(): string;
31
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"axisResolution.d.ts","sourceRoot":"","sources":["../../../src/view/axisResolution.js"],"names":[],"mappings":"AAeA;;;;;;;GAOG;AACH;IACI;;;OAGG;IAEH;;OAEG;IACH,qBAFW,OAAO,oBAAoB,EAAE,wBAAwB,EAM/D;IAHG,+DAAsB;IACtB,wDAAwD;IACxD,SADW,oBAAoB,EAAE,CAChB;IAGrB,8DAEC;IAED;;;;;OAKG;IACH,qBAFW,oBAAoB,QAwB9B;IAED,qDAuBC;IAED,mBAyDC;CACJ;iCA3I6D,CAAC,SAAlD,OAAQ,oBAAoB,EAAE,iBAAkB;UAGnD,OAAO,eAAe,EAAE,OAAO;aAC/B,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB"}
1
+ {"version":3,"file":"axisResolution.d.ts","sourceRoot":"","sources":["../../../src/view/axisResolution.js"],"names":[],"mappings":"AAeA;;;;;;;GAOG;AACH;IACI;;;OAGG;IAEH;;OAEG;IACH,qBAFW,OAAO,oBAAoB,EAAE,wBAAwB,EAM/D;IAHG,+DAAsB;IACtB,wDAAwD;IACxD,SADW,oBAAoB,EAAE,CAChB;IAGrB,8DAEC;IAED;;;;;OAKG;IACH,qBAFW,oBAAoB,QAyB9B;IAED;;;OAGG;IACH,4DAFa,OAAO,CAUnB;IAED,qDAuBC;IAED,mBAyDC;CACJ;iCA1J6D,CAAC,SAAlD,OAAQ,oBAAoB,EAAE,iBAAkB;UAGnD,OAAO,eAAe,EAAE,OAAO;aAC/B,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB"}
@@ -11,7 +11,7 @@ import { peek } from "../utils/arrayUtils.js";
11
11
  import coalesce from "../utils/coalesce.js";
12
12
 
13
13
  import mergeObjects from "../utils/mergeObjects.js";
14
- import { getCachedOrCall } from "../utils/propertyCacher.js";
14
+ import { getCachedOrCall, invalidate } from "../utils/propertyCacher.js";
15
15
 
16
16
  /**
17
17
  * @template {import("../spec/channel.js").PositionalChannel}[T=PositionalChannel]
@@ -68,6 +68,21 @@ export default class AxisResolution {
68
68
  }
69
69
 
70
70
  this.members.push(newMember);
71
+ invalidate(this, "axisProps");
72
+ }
73
+
74
+ /**
75
+ * @param {UnitView} view
76
+ * @returns {boolean}
77
+ */
78
+ removeMembersByView(view) {
79
+ const before = this.members.length;
80
+ this.members = this.members.filter((member) => member.view !== view);
81
+ if (this.members.length !== before) {
82
+ invalidate(this, "axisProps");
83
+ return true;
84
+ }
85
+ return false;
71
86
  }
72
87
 
73
88
  getAxisProps() {
@@ -1 +1 @@
1
- {"version":3,"file":"facetView.d.ts","sourceRoot":"","sources":["../../../src/view/facetView.js"],"names":[],"mappings":"AAmDA;;;;;;;;;;;;;;GAcG;AACH;IACI;;;;;;;OAOG;IACH;;;;;;OAMG;IACH,kBALW,OAAO,gBAAgB,EAAE,SAAS,WAClC,OAAO,gBAAgB,EAAE,WAAW,UACpC,aAAa,QACb,MAAM,EA8BhB;IAzBG,UAAgB;IAEhB,WAEC;IAED;;;;OAIG;IACH,aAFU,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAYvC;IAED,oDAAoD;IACpD,kBADY,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CACa;IA2BjE,sBAIC;IAED;;;OAGG;IACH,qBAFW,KAAK,GAAG,QAAQ,OAwB1B;IAED,qBAyCC;IAED,qBASC;IA6BD,kDAgBC;IAOD;;;;OAIG;IACH,gBAJW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,WAAW,EAAE,gBAAgB,QA2L9C;IA3KO,wBAA0B;CA4KrC;2BA/bY,QAAQ,GAAG,KAAK;;;;;;aA4CnB,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE;;;0BA1Df,oBAAoB;qBACzB,eAAe"}
1
+ {"version":3,"file":"facetView.d.ts","sourceRoot":"","sources":["../../../src/view/facetView.js"],"names":[],"mappings":"AAmDA;;;;;;;;;;;;;;GAcG;AACH;IACI;;;;;;;OAOG;IACH;;;;;;OAMG;IACH,kBALW,OAAO,gBAAgB,EAAE,SAAS,WAClC,OAAO,gBAAgB,EAAE,WAAW,UACpC,aAAa,QACb,MAAM,EA8BhB;IAzBG,UAAgB;IAEhB,WAEC;IAED;;;;OAIG;IACH,aAFU,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAYvC;IAED,oDAAoD;IACpD,kBADY,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CACa;IA4BjE,sBAIC;IAED;;;OAGG;IACH,qBAFW,KAAK,GAAG,QAAQ,OAwB1B;IAED,qBAyCC;IAED,qBASC;IA6BD,kDAgBC;IAOD;;;;OAIG;IACH,gBAJW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,WAAW,EAAE,gBAAgB,QA2L9C;IA3KO,wBAA0B;CA4KrC;2BAhcY,QAAQ,GAAG,KAAK;;;;;;aA4CnB,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE;;;0BA1Df,oBAAoB;qBACzB,eAAe"}
@@ -129,6 +129,7 @@ export default class FacetView extends ContainerView {
129
129
  throw new Error("Not my child!");
130
130
  }
131
131
 
132
+ child.disposeSubtree();
132
133
  this.child = /** @type {UnitView | LayerView | DecoratorView} */ (
133
134
  replacement
134
135
  );
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * @param {View} root
3
- * @param {DataFlow<View>} [existingFlow] Add data flow
3
+ * @param {DataFlow} [existingFlow] Add data flow
4
4
  * graphs to an existing DataFlow object.
5
5
  */
6
- export function buildDataFlow(root: import("./view.js").default, existingFlow?: DataFlow<import("./view.js").default>): DataFlow<import("./view.js").default>;
6
+ export function buildDataFlow(root: import("./view.js").default, existingFlow?: DataFlow): DataFlow;
7
7
  /**
8
8
  * Changes the ChromPos channelDefs into FieldDefs and returns
9
9
  * LinearizeGenomicCoordinate transform(s) that should be inserted into