react-msaview 3.1.11 → 3.2.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/bundle/index.js +32 -31
- package/dist/colorSchemes.d.ts +2 -2
- package/dist/colorSchemes.js +3 -4
- package/dist/colorSchemes.js.map +1 -1
- package/dist/components/Loading.d.ts +1 -1
- package/dist/components/Loading.js +4 -4
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/MSAView.d.ts +1 -1
- package/dist/components/MSAView.js +13 -9
- package/dist/components/MSAView.js.map +1 -1
- package/dist/components/ResizeHandles.d.ts +1 -1
- package/dist/components/ResizeHandles.js +2 -2
- package/dist/components/SequenceTextArea.js +4 -0
- package/dist/components/SequenceTextArea.js.map +1 -1
- package/dist/components/TextTrack.d.ts +1 -1
- package/dist/components/Track.d.ts +1 -1
- package/dist/components/VerticalScrollbar.d.ts +6 -0
- package/dist/components/VerticalScrollbar.js +65 -0
- package/dist/components/VerticalScrollbar.js.map +1 -0
- package/dist/components/dialogs/AddTrackDialog.d.ts +1 -1
- package/dist/components/dialogs/DomainDialog.d.ts +6 -0
- package/dist/components/dialogs/DomainDialog.js +19 -0
- package/dist/components/dialogs/DomainDialog.js.map +1 -0
- package/dist/components/dialogs/ExportSVGDialog.d.ts +1 -1
- package/dist/components/dialogs/FeatureDialog.d.ts +1 -1
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/dialogs/InterProScanDialog.d.ts +4 -4
- package/dist/components/dialogs/InterProScanDialog.js +37 -8
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
- package/dist/components/dialogs/MetadataDialog.d.ts +1 -1
- package/dist/components/dialogs/SettingsDialog.d.ts +1 -1
- package/dist/components/dialogs/SettingsDialog.js +10 -1
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/dialogs/TabPanel.d.ts +6 -0
- package/dist/components/dialogs/TabPanel.js +6 -0
- package/dist/components/dialogs/TabPanel.js.map +1 -0
- package/dist/components/dialogs/TracklistDialog.d.ts +1 -1
- package/dist/components/dialogs/UserProvidedDomainsDialog.d.ts +7 -0
- package/dist/components/dialogs/UserProvidedDomainsDialog.js +58 -0
- package/dist/components/dialogs/UserProvidedDomainsDialog.js.map +1 -0
- package/dist/components/header/Header.d.ts +1 -1
- package/dist/components/header/Header.js +8 -5
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderInfoArea.d.ts +1 -1
- package/dist/components/header/HeaderMenu.d.ts +1 -1
- package/dist/components/header/HeaderMenuExtra.d.ts +1 -1
- package/dist/components/header/HeaderMenuExtra.js +54 -41
- package/dist/components/header/HeaderMenuExtra.js.map +1 -1
- package/dist/components/header/HeaderStatusArea.d.ts +1 -1
- package/dist/components/header/HeaderStatusArea.js +2 -1
- package/dist/components/header/HeaderStatusArea.js.map +1 -1
- package/dist/components/header/MultiAlignmentSelector.d.ts +1 -1
- package/dist/components/header/ZoomControls.js +31 -1
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/import/ImportForm.d.ts +1 -1
- package/dist/components/import/ImportForm.js +1 -1
- package/dist/components/import/ImportForm.js.map +1 -1
- package/dist/components/import/ImportFormExamples.d.ts +1 -1
- package/dist/components/import/ImportFormExamples.js +10 -8
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/import/util.d.ts +2 -2
- package/dist/components/minimap/Minimap.d.ts +1 -1
- package/dist/components/minimap/Minimap.js +14 -15
- package/dist/components/minimap/Minimap.js.map +1 -1
- package/dist/components/minimap/MinimapSVG.d.ts +1 -1
- package/dist/components/minimap/MinimapSVG.js +1 -1
- package/dist/components/minimap/MinimapSVG.js.map +1 -1
- package/dist/components/msa/MSACanvas.d.ts +1 -1
- package/dist/components/msa/MSACanvas.js +3 -3
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.d.ts +3 -3
- package/dist/components/msa/MSACanvasBlock.js +4 -3
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.d.ts +2 -2
- package/dist/components/msa/MSAMouseoverCanvas.js +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/msa/MSAPanel.d.ts +1 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +1 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +2 -3
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.d.ts +2 -2
- package/dist/components/msa/renderMSABlock.js +12 -12
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.d.ts +1 -1
- package/dist/components/tree/TreeBranchMenu.d.ts +1 -1
- package/dist/components/tree/TreeCanvas.d.ts +1 -1
- package/dist/components/tree/TreeCanvas.js +13 -12
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.d.ts +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +2 -1
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.d.ts +1 -1
- package/dist/components/tree/TreeNodeMenu.js +2 -2
- package/dist/components/tree/TreeNodeMenu.js.map +1 -1
- package/dist/components/tree/TreePanel.d.ts +1 -1
- package/dist/components/tree/TreeRuler.d.ts +1 -1
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.d.ts +1 -1
- package/dist/components/tree/renderTreeCanvas.d.ts +3 -3
- package/dist/components/tree/renderTreeCanvas.js +25 -9
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/components/util.js +1 -1
- package/dist/components/util.js.map +1 -1
- package/dist/fetchUtils.d.ts +1 -1
- package/dist/fetchUtils.js.map +1 -1
- package/dist/launchInterProScan.d.ts +9 -3
- package/dist/launchInterProScan.js +57 -22
- package/dist/launchInterProScan.js.map +1 -1
- package/dist/model/DataModel.d.ts +5 -1
- package/dist/model/DataModel.js +10 -1
- package/dist/model/DataModel.js.map +1 -1
- package/dist/model/DialogQueue.d.ts +1 -1
- package/dist/model.d.ts +138 -43
- package/dist/model.js +235 -110
- package/dist/model.js.map +1 -1
- package/dist/parseNewick.js +1 -1
- package/dist/parseNewick.js.map +1 -1
- package/dist/parsers/ClustalMSA.d.ts +1 -1
- package/dist/parsers/FastaMSA.d.ts +1 -1
- package/dist/parsers/StockholmMSA.d.ts +1 -1
- package/dist/parsers/StockholmMSA.js.map +1 -1
- package/dist/renderToSvg.d.ts +2 -2
- package/dist/renderToSvg.js +3 -28
- package/dist/renderToSvg.js.map +1 -1
- package/dist/reparseTree.d.ts +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.js +0 -2
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +5 -2
- package/src/colorSchemes.ts +3 -2
- package/src/components/Checkbox2.tsx +1 -1
- package/src/components/Loading.tsx +11 -5
- package/src/components/MSAView.tsx +27 -18
- package/src/components/ResizeHandles.tsx +3 -3
- package/src/components/SequenceTextArea.tsx +8 -0
- package/src/components/TextTrack.tsx +1 -1
- package/src/components/Track.tsx +1 -1
- package/src/components/VerticalScrollbar.tsx +85 -0
- package/src/components/dialogs/AddTrackDialog.tsx +2 -2
- package/src/components/dialogs/DomainDialog.tsx +38 -0
- package/src/components/dialogs/ExportSVGDialog.tsx +1 -1
- package/src/components/dialogs/FeatureDialog.tsx +3 -3
- package/src/components/dialogs/InterProScanDialog.tsx +49 -11
- package/src/components/dialogs/MetadataDialog.tsx +1 -1
- package/src/components/dialogs/SettingsDialog.tsx +38 -3
- package/src/components/dialogs/TabPanel.tsx +19 -0
- package/src/components/dialogs/TracklistDialog.tsx +1 -1
- package/src/components/dialogs/UserProvidedDomainsDialog.tsx +133 -0
- package/src/components/header/Header.tsx +9 -6
- package/src/components/header/HeaderInfoArea.tsx +1 -1
- package/src/components/header/HeaderMenu.tsx +1 -1
- package/src/components/header/HeaderMenuExtra.tsx +65 -48
- package/src/components/header/HeaderStatusArea.tsx +3 -2
- package/src/components/header/MultiAlignmentSelector.tsx +1 -1
- package/src/components/header/ZoomControls.tsx +34 -0
- package/src/components/import/ImportForm.tsx +3 -3
- package/src/components/import/ImportFormExamples.tsx +19 -17
- package/src/components/import/util.ts +2 -2
- package/src/components/minimap/Minimap.tsx +15 -22
- package/src/components/minimap/MinimapSVG.tsx +2 -2
- package/src/components/msa/MSACanvas.tsx +11 -4
- package/src/components/msa/MSACanvasBlock.tsx +5 -4
- package/src/components/msa/MSAMouseoverCanvas.tsx +2 -6
- package/src/components/msa/MSAPanel.tsx +1 -1
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +5 -6
- package/src/components/msa/renderMSABlock.ts +37 -17
- package/src/components/msa/renderMSAMouseover.ts +1 -1
- package/src/components/tree/TreeBranchMenu.tsx +1 -1
- package/src/components/tree/TreeCanvas.tsx +15 -16
- package/src/components/tree/TreeCanvasBlock.tsx +3 -2
- package/src/components/tree/TreeNodeMenu.tsx +3 -3
- package/src/components/tree/TreePanel.tsx +1 -1
- package/src/components/tree/TreeRuler.tsx +1 -1
- package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +1 -1
- package/src/components/tree/renderTreeCanvas.ts +32 -12
- package/src/components/util.ts +1 -1
- package/src/fetchUtils.ts +2 -2
- package/src/launchInterProScan.ts +69 -24
- package/src/model/DataModel.ts +10 -0
- package/src/model/DialogQueue.ts +1 -1
- package/src/model.ts +262 -143
- package/src/parseNewick.ts +1 -1
- package/src/parsers/ClustalMSA.ts +1 -1
- package/src/parsers/FastaMSA.ts +1 -1
- package/src/parsers/StockholmMSA.ts +1 -1
- package/src/renderToSvg.tsx +6 -30
- package/src/reparseTree.ts +1 -1
- package/src/util.ts +2 -4
- package/src/version.ts +1 -1
package/dist/model.js
CHANGED
|
@@ -4,10 +4,14 @@ import { hierarchy, cluster } from 'd3-hierarchy';
|
|
|
4
4
|
import { ascending } from 'd3-array';
|
|
5
5
|
import Stockholm from 'stockholm-js';
|
|
6
6
|
import { saveAs } from 'file-saver';
|
|
7
|
+
import { ungzip } from 'pako';
|
|
7
8
|
// jbrowse
|
|
8
9
|
import { FileLocation, ElementId } from '@jbrowse/core/util/types/mst';
|
|
9
10
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
10
|
-
import { groupBy,
|
|
11
|
+
import { groupBy, notEmpty, sum } from '@jbrowse/core/util';
|
|
12
|
+
export function isGzip(buf) {
|
|
13
|
+
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
|
|
14
|
+
}
|
|
11
15
|
// locals
|
|
12
16
|
import { clamp, collapse, generateNodeIds, maxLength, setBrLength, skipBlanks, len, } from './util';
|
|
13
17
|
import { colord } from 'colord';
|
|
@@ -28,7 +32,6 @@ import { DataModelF } from './model/DataModel';
|
|
|
28
32
|
import { DialogQueueSessionMixin } from './model/DialogQueue';
|
|
29
33
|
import { TreeF } from './model/treeModel';
|
|
30
34
|
import { MSAModelF } from './model/msaModel';
|
|
31
|
-
import { launchInterProScan, loadInterProScanResults, } from './launchInterProScan';
|
|
32
35
|
/**
|
|
33
36
|
* #stateModel MsaView
|
|
34
37
|
* extends
|
|
@@ -47,7 +50,15 @@ function stateModelFactory() {
|
|
|
47
50
|
/**
|
|
48
51
|
* #property
|
|
49
52
|
*/
|
|
50
|
-
|
|
53
|
+
showDomains: false,
|
|
54
|
+
/**
|
|
55
|
+
* #property
|
|
56
|
+
*/
|
|
57
|
+
allowedGappyness: 100,
|
|
58
|
+
/**
|
|
59
|
+
* #property
|
|
60
|
+
*/
|
|
61
|
+
contrastLettering: true,
|
|
51
62
|
/**
|
|
52
63
|
* #property
|
|
53
64
|
*/
|
|
@@ -57,6 +68,18 @@ function stateModelFactory() {
|
|
|
57
68
|
* hardcoded view type
|
|
58
69
|
*/
|
|
59
70
|
type: types.literal('MsaView'),
|
|
71
|
+
/**
|
|
72
|
+
* #property
|
|
73
|
+
*/
|
|
74
|
+
drawMsaLetters: true,
|
|
75
|
+
/**
|
|
76
|
+
* #property
|
|
77
|
+
*/
|
|
78
|
+
hideGaps: true,
|
|
79
|
+
/**
|
|
80
|
+
* #property
|
|
81
|
+
*/
|
|
82
|
+
drawTreeText: true,
|
|
60
83
|
/**
|
|
61
84
|
* #property
|
|
62
85
|
* height of the div containing the view, px
|
|
@@ -105,14 +128,16 @@ function stateModelFactory() {
|
|
|
105
128
|
currentAlignment: 0,
|
|
106
129
|
/**
|
|
107
130
|
* #property
|
|
108
|
-
* array of tree parent nodes that are 'collapsed'
|
|
131
|
+
* array of tree parent nodes that are 'collapsed' (all children are
|
|
132
|
+
* hidden)
|
|
109
133
|
*/
|
|
110
134
|
collapsed: types.array(types.string),
|
|
111
135
|
/**
|
|
112
136
|
* #property
|
|
113
|
-
* array of tree leaf nodes that are 'collapsed'
|
|
137
|
+
* array of tree leaf nodes that are 'collapsed' (just that leaf node
|
|
138
|
+
* is hidden)
|
|
114
139
|
*/
|
|
115
|
-
|
|
140
|
+
collapsedLeaves: types.array(types.string),
|
|
116
141
|
/**
|
|
117
142
|
* #property
|
|
118
143
|
* focus on particular subtree
|
|
@@ -135,6 +160,13 @@ function stateModelFactory() {
|
|
|
135
160
|
featureFilters: types.map(types.boolean),
|
|
136
161
|
}))
|
|
137
162
|
.volatile(() => ({
|
|
163
|
+
/**
|
|
164
|
+
* #volatile
|
|
165
|
+
*/
|
|
166
|
+
headerHeight: 0,
|
|
167
|
+
/**
|
|
168
|
+
* #volatile
|
|
169
|
+
*/
|
|
138
170
|
status: undefined,
|
|
139
171
|
/**
|
|
140
172
|
* #volatile
|
|
@@ -153,7 +185,7 @@ function stateModelFactory() {
|
|
|
153
185
|
/**
|
|
154
186
|
* #volatile
|
|
155
187
|
*/
|
|
156
|
-
|
|
188
|
+
volatileWidth: undefined,
|
|
157
189
|
/**
|
|
158
190
|
* #volatile
|
|
159
191
|
* resize handle width between tree and msa area, px
|
|
@@ -163,7 +195,7 @@ function stateModelFactory() {
|
|
|
163
195
|
* #volatile
|
|
164
196
|
* size of blocks of content to be drawn, px
|
|
165
197
|
*/
|
|
166
|
-
blockSize:
|
|
198
|
+
blockSize: 500,
|
|
167
199
|
/**
|
|
168
200
|
* #volatile
|
|
169
201
|
* the currently mouse-hovered row
|
|
@@ -210,13 +242,27 @@ function stateModelFactory() {
|
|
|
210
242
|
* #volatile
|
|
211
243
|
*
|
|
212
244
|
*/
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* #volatile
|
|
216
|
-
*/
|
|
217
|
-
interProScanJobIds: JSON.parse(localStorageGetItem('msaview-interproscanqueries') || '[]'),
|
|
245
|
+
interProAnnotations: undefined,
|
|
218
246
|
}))
|
|
219
247
|
.actions(self => ({
|
|
248
|
+
/**
|
|
249
|
+
* #action
|
|
250
|
+
*/
|
|
251
|
+
setHideGaps(arg) {
|
|
252
|
+
self.hideGaps = arg;
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* #action
|
|
256
|
+
*/
|
|
257
|
+
setAllowedGappyness(arg) {
|
|
258
|
+
self.allowedGappyness = arg;
|
|
259
|
+
},
|
|
260
|
+
/**
|
|
261
|
+
* #action
|
|
262
|
+
*/
|
|
263
|
+
setContrastLettering(arg) {
|
|
264
|
+
self.contrastLettering = arg;
|
|
265
|
+
},
|
|
220
266
|
/**
|
|
221
267
|
* #action
|
|
222
268
|
*/
|
|
@@ -233,7 +279,7 @@ function stateModelFactory() {
|
|
|
233
279
|
* #action
|
|
234
280
|
*/
|
|
235
281
|
setWidth(arg) {
|
|
236
|
-
self.
|
|
282
|
+
self.volatileWidth = arg;
|
|
237
283
|
},
|
|
238
284
|
/**
|
|
239
285
|
* #action
|
|
@@ -260,8 +306,8 @@ function stateModelFactory() {
|
|
|
260
306
|
/**
|
|
261
307
|
* #action
|
|
262
308
|
*/
|
|
263
|
-
|
|
264
|
-
self.
|
|
309
|
+
setShowDomains(arg) {
|
|
310
|
+
self.showDomains = arg;
|
|
265
311
|
},
|
|
266
312
|
/**
|
|
267
313
|
* #action
|
|
@@ -320,11 +366,11 @@ function stateModelFactory() {
|
|
|
320
366
|
* #action
|
|
321
367
|
*/
|
|
322
368
|
toggleCollapsed2(node) {
|
|
323
|
-
if (self.
|
|
324
|
-
self.
|
|
369
|
+
if (self.collapsedLeaves.includes(node)) {
|
|
370
|
+
self.collapsedLeaves.remove(node);
|
|
325
371
|
}
|
|
326
372
|
else {
|
|
327
|
-
self.
|
|
373
|
+
self.collapsedLeaves.push(node);
|
|
328
374
|
}
|
|
329
375
|
},
|
|
330
376
|
/**
|
|
@@ -369,6 +415,29 @@ function stateModelFactory() {
|
|
|
369
415
|
setTreeMetadata(result) {
|
|
370
416
|
self.data.setTreeMetadata(result);
|
|
371
417
|
},
|
|
418
|
+
}))
|
|
419
|
+
.views(self => ({
|
|
420
|
+
/**
|
|
421
|
+
* #getter
|
|
422
|
+
*/
|
|
423
|
+
get actuallyShowDomains() {
|
|
424
|
+
return self.showDomains && !!self.interProAnnotations;
|
|
425
|
+
},
|
|
426
|
+
/**
|
|
427
|
+
* #getter
|
|
428
|
+
*/
|
|
429
|
+
get viewInitialized() {
|
|
430
|
+
return self.volatileWidth !== undefined;
|
|
431
|
+
},
|
|
432
|
+
/**
|
|
433
|
+
* #getter
|
|
434
|
+
*/
|
|
435
|
+
get width() {
|
|
436
|
+
if (self.volatileWidth === undefined) {
|
|
437
|
+
throw new Error('not initialized');
|
|
438
|
+
}
|
|
439
|
+
return self.volatileWidth;
|
|
440
|
+
},
|
|
372
441
|
}))
|
|
373
442
|
.views(self => ({
|
|
374
443
|
/**
|
|
@@ -408,13 +477,13 @@ function stateModelFactory() {
|
|
|
408
477
|
* #getter
|
|
409
478
|
*/
|
|
410
479
|
get noTree() {
|
|
411
|
-
return !!this.
|
|
480
|
+
return !!this.tree.noTree;
|
|
412
481
|
},
|
|
413
482
|
/**
|
|
414
483
|
* #getter
|
|
415
484
|
*/
|
|
416
|
-
get
|
|
417
|
-
return !self.
|
|
485
|
+
get noDomains() {
|
|
486
|
+
return !self.interProAnnotations;
|
|
418
487
|
},
|
|
419
488
|
/**
|
|
420
489
|
* #getter
|
|
@@ -437,12 +506,10 @@ function stateModelFactory() {
|
|
|
437
506
|
if (Stockholm.sniff(text)) {
|
|
438
507
|
return new StockholmMSA(text, self.currentAlignment);
|
|
439
508
|
}
|
|
440
|
-
|
|
509
|
+
if (text.startsWith('>')) {
|
|
441
510
|
return new FastaMSA(text);
|
|
442
511
|
}
|
|
443
|
-
|
|
444
|
-
return new ClustalMSA(text);
|
|
445
|
-
}
|
|
512
|
+
return new ClustalMSA(text);
|
|
446
513
|
}
|
|
447
514
|
return null;
|
|
448
515
|
},
|
|
@@ -455,7 +522,7 @@ function stateModelFactory() {
|
|
|
455
522
|
/**
|
|
456
523
|
* #getter
|
|
457
524
|
*/
|
|
458
|
-
get
|
|
525
|
+
get tree() {
|
|
459
526
|
const ret = self.data.tree
|
|
460
527
|
? generateNodeIds(parseNewick(self.data.tree))
|
|
461
528
|
: this.MSA?.getTree() || {
|
|
@@ -470,7 +537,7 @@ function stateModelFactory() {
|
|
|
470
537
|
* #getter
|
|
471
538
|
*/
|
|
472
539
|
get rowNames() {
|
|
473
|
-
return this.
|
|
540
|
+
return this.leaves.map(n => n.data.name);
|
|
474
541
|
},
|
|
475
542
|
/**
|
|
476
543
|
* #getter
|
|
@@ -483,7 +550,7 @@ function stateModelFactory() {
|
|
|
483
550
|
* #getter
|
|
484
551
|
*/
|
|
485
552
|
get root() {
|
|
486
|
-
let hier = hierarchy(this.
|
|
553
|
+
let hier = hierarchy(this.tree, d => d.branchset)
|
|
487
554
|
.sum(d => (d.branchset ? 0 : 1))
|
|
488
555
|
.sort((a, b) => ascending(a.data.length || 1, b.data.length || 1));
|
|
489
556
|
if (self.showOnly) {
|
|
@@ -493,7 +560,7 @@ function stateModelFactory() {
|
|
|
493
560
|
}
|
|
494
561
|
}
|
|
495
562
|
;
|
|
496
|
-
[...self.collapsed, ...self.
|
|
563
|
+
[...self.collapsed, ...self.collapsedLeaves]
|
|
497
564
|
.map(collapsedId => hier.find(node => node.data.id === collapsedId))
|
|
498
565
|
.filter(notEmpty)
|
|
499
566
|
.map(node => collapse(node));
|
|
@@ -516,9 +583,9 @@ function stateModelFactory() {
|
|
|
516
583
|
* #getter
|
|
517
584
|
*/
|
|
518
585
|
get blanks() {
|
|
586
|
+
const { allowedGappyness } = self;
|
|
519
587
|
const blanks = [];
|
|
520
|
-
const strs = this.
|
|
521
|
-
.leaves()
|
|
588
|
+
const strs = this.leaves
|
|
522
589
|
.map(leaf => this.MSA?.getRow(leaf.data.name))
|
|
523
590
|
.filter((item) => !!item);
|
|
524
591
|
for (let i = 0; i < strs[0]?.length; i++) {
|
|
@@ -528,7 +595,7 @@ function stateModelFactory() {
|
|
|
528
595
|
counter++;
|
|
529
596
|
}
|
|
530
597
|
}
|
|
531
|
-
if (counter
|
|
598
|
+
if (counter / strs.length >= allowedGappyness / 100) {
|
|
532
599
|
blanks.push(i);
|
|
533
600
|
}
|
|
534
601
|
}
|
|
@@ -539,8 +606,7 @@ function stateModelFactory() {
|
|
|
539
606
|
*/
|
|
540
607
|
get rows() {
|
|
541
608
|
const MSA = this.MSA;
|
|
542
|
-
return this.
|
|
543
|
-
.leaves()
|
|
609
|
+
return this.leaves
|
|
544
610
|
.map(leaf => [leaf.data.name, MSA?.getRow(leaf.data.name)])
|
|
545
611
|
.filter((f) => !!f[1]);
|
|
546
612
|
},
|
|
@@ -580,6 +646,14 @@ function stateModelFactory() {
|
|
|
580
646
|
}
|
|
581
647
|
return r;
|
|
582
648
|
},
|
|
649
|
+
/**
|
|
650
|
+
* #getter
|
|
651
|
+
*/
|
|
652
|
+
get colStatsSums() {
|
|
653
|
+
return Object.fromEntries(Object.entries(this.colStats).map(([key, val]) => {
|
|
654
|
+
return [key, sum(Object.values(val))];
|
|
655
|
+
}));
|
|
656
|
+
},
|
|
583
657
|
/**
|
|
584
658
|
* #getter
|
|
585
659
|
* generates a new tree that is clustered with x,y positions
|
|
@@ -599,6 +673,12 @@ function stateModelFactory() {
|
|
|
599
673
|
get totalHeight() {
|
|
600
674
|
return this.root.leaves().length * self.rowHeight;
|
|
601
675
|
},
|
|
676
|
+
/**
|
|
677
|
+
* #getter
|
|
678
|
+
*/
|
|
679
|
+
get leaves() {
|
|
680
|
+
return this.hierarchy.leaves();
|
|
681
|
+
},
|
|
602
682
|
}))
|
|
603
683
|
.views(self => ({
|
|
604
684
|
/**
|
|
@@ -612,7 +692,7 @@ function stateModelFactory() {
|
|
|
612
692
|
/**
|
|
613
693
|
* #getter
|
|
614
694
|
*/
|
|
615
|
-
get
|
|
695
|
+
get dataInitialized() {
|
|
616
696
|
return (self.data.msa || self.data.tree) && !self.error;
|
|
617
697
|
},
|
|
618
698
|
/**
|
|
@@ -663,29 +743,77 @@ function stateModelFactory() {
|
|
|
663
743
|
get maxScrollX() {
|
|
664
744
|
return -self.totalWidth + (self.msaAreaWidth - 100);
|
|
665
745
|
},
|
|
746
|
+
/**
|
|
747
|
+
* #getter
|
|
748
|
+
*/
|
|
749
|
+
get showMsaLetters() {
|
|
750
|
+
return self.drawMsaLetters && self.rowHeight >= 5;
|
|
751
|
+
},
|
|
752
|
+
/**
|
|
753
|
+
* #getter
|
|
754
|
+
*/
|
|
755
|
+
get showTreeText() {
|
|
756
|
+
return self.drawLabels && self.rowHeight >= 5;
|
|
757
|
+
},
|
|
666
758
|
}))
|
|
667
759
|
.actions(self => ({
|
|
668
760
|
/**
|
|
669
761
|
* #action
|
|
670
762
|
*/
|
|
671
|
-
|
|
763
|
+
setDrawMsaLetters(arg) {
|
|
764
|
+
self.drawMsaLetters = arg;
|
|
765
|
+
},
|
|
766
|
+
/**
|
|
767
|
+
* #action
|
|
768
|
+
*/
|
|
769
|
+
zoomOutHorizontal() {
|
|
770
|
+
self.colWidth = Math.max(1, Math.floor(self.colWidth * 0.75));
|
|
771
|
+
self.scrollX = clamp(self.maxScrollX, self.scrollX, 0);
|
|
772
|
+
},
|
|
773
|
+
/**
|
|
774
|
+
* #action
|
|
775
|
+
*/
|
|
776
|
+
zoomInHorizontal() {
|
|
672
777
|
self.colWidth = Math.ceil(self.colWidth * 1.5);
|
|
673
|
-
self.rowHeight = Math.ceil(self.rowHeight * 1.5);
|
|
674
778
|
self.scrollX = clamp(self.maxScrollX, self.scrollX, 0);
|
|
675
779
|
},
|
|
676
780
|
/**
|
|
677
781
|
* #action
|
|
678
782
|
*/
|
|
679
|
-
|
|
680
|
-
self.
|
|
783
|
+
zoomInVertical() {
|
|
784
|
+
self.rowHeight = Math.ceil(self.rowHeight * 1.5);
|
|
785
|
+
},
|
|
786
|
+
/**
|
|
787
|
+
* #action
|
|
788
|
+
*/
|
|
789
|
+
zoomOutVertical() {
|
|
681
790
|
self.rowHeight = Math.max(1.5, Math.floor(self.rowHeight * 0.75));
|
|
682
|
-
self.scrollX = clamp(self.maxScrollX, self.scrollX, 0);
|
|
683
791
|
},
|
|
684
792
|
/**
|
|
685
793
|
* #action
|
|
686
794
|
*/
|
|
687
|
-
|
|
688
|
-
|
|
795
|
+
zoomIn() {
|
|
796
|
+
transaction(() => {
|
|
797
|
+
self.colWidth = Math.ceil(self.colWidth * 1.5);
|
|
798
|
+
self.rowHeight = Math.ceil(self.rowHeight * 1.5);
|
|
799
|
+
self.scrollX = clamp(self.maxScrollX, self.scrollX, 0);
|
|
800
|
+
});
|
|
801
|
+
},
|
|
802
|
+
/**
|
|
803
|
+
* #action
|
|
804
|
+
*/
|
|
805
|
+
zoomOut() {
|
|
806
|
+
transaction(() => {
|
|
807
|
+
self.colWidth = Math.max(1, Math.floor(self.colWidth * 0.75));
|
|
808
|
+
self.rowHeight = Math.max(1.5, Math.floor(self.rowHeight * 0.75));
|
|
809
|
+
self.scrollX = clamp(self.maxScrollX, self.scrollX, 0);
|
|
810
|
+
});
|
|
811
|
+
},
|
|
812
|
+
/**
|
|
813
|
+
* #action
|
|
814
|
+
*/
|
|
815
|
+
setInterProAnnotations(data) {
|
|
816
|
+
self.interProAnnotations = data;
|
|
689
817
|
},
|
|
690
818
|
/**
|
|
691
819
|
* #action
|
|
@@ -716,15 +844,6 @@ function stateModelFactory() {
|
|
|
716
844
|
self.turnedOffTracks.set(id, true);
|
|
717
845
|
}
|
|
718
846
|
},
|
|
719
|
-
/**
|
|
720
|
-
* #action
|
|
721
|
-
*/
|
|
722
|
-
addInterProScanJobId(arg) {
|
|
723
|
-
self.interProScanJobIds = [
|
|
724
|
-
...self.interProScanJobIds,
|
|
725
|
-
{ jobId: arg, date: +Date.now() },
|
|
726
|
-
];
|
|
727
|
-
},
|
|
728
847
|
/**
|
|
729
848
|
* #action
|
|
730
849
|
*/
|
|
@@ -738,9 +857,9 @@ function stateModelFactory() {
|
|
|
738
857
|
*/
|
|
739
858
|
get labelsWidth() {
|
|
740
859
|
let x = 0;
|
|
741
|
-
const { rowHeight,
|
|
860
|
+
const { rowHeight, leaves, treeMetadata, fontSize } = self;
|
|
742
861
|
if (rowHeight > 5) {
|
|
743
|
-
for (const node of
|
|
862
|
+
for (const node of leaves) {
|
|
744
863
|
x = Math.max(measureTextCanvas(treeMetadata[node.data.name]?.genome || node.data.name, fontSize), x);
|
|
745
864
|
}
|
|
746
865
|
}
|
|
@@ -797,6 +916,12 @@ function stateModelFactory() {
|
|
|
797
916
|
get turnedOnTracks() {
|
|
798
917
|
return this.tracks.filter(f => !self.turnedOffTracks.has(f.model.id));
|
|
799
918
|
},
|
|
919
|
+
/**
|
|
920
|
+
* #getter
|
|
921
|
+
*/
|
|
922
|
+
get showHorizontalScrollbar() {
|
|
923
|
+
return self.msaAreaWidth < self.totalWidth;
|
|
924
|
+
},
|
|
800
925
|
/**
|
|
801
926
|
* #method
|
|
802
927
|
* return a row-specific sequence coordinate, skipping gaps, given a global
|
|
@@ -846,6 +971,15 @@ function stateModelFactory() {
|
|
|
846
971
|
},
|
|
847
972
|
}))
|
|
848
973
|
.views(self => ({
|
|
974
|
+
/**
|
|
975
|
+
* #getter
|
|
976
|
+
* widget width minus the tree area gives the space for the MSA
|
|
977
|
+
*/
|
|
978
|
+
get msaAreaHeight() {
|
|
979
|
+
return (self.height -
|
|
980
|
+
(self.showHorizontalScrollbar ? self.minimapHeight : 0) -
|
|
981
|
+
self.headerHeight);
|
|
982
|
+
},
|
|
849
983
|
/**
|
|
850
984
|
* #getter
|
|
851
985
|
* total height of track area (px)
|
|
@@ -865,11 +999,14 @@ function stateModelFactory() {
|
|
|
865
999
|
}
|
|
866
1000
|
return types;
|
|
867
1001
|
},
|
|
1002
|
+
/**
|
|
1003
|
+
* #getter
|
|
1004
|
+
*/
|
|
868
1005
|
get tidyAnnotations() {
|
|
869
1006
|
const ret = [];
|
|
870
|
-
const {
|
|
871
|
-
if (
|
|
872
|
-
for (const [id, val] of Object.entries(
|
|
1007
|
+
const { interProAnnotations } = self;
|
|
1008
|
+
if (interProAnnotations) {
|
|
1009
|
+
for (const [id, val] of Object.entries(interProAnnotations)) {
|
|
873
1010
|
for (const { signature, locations } of val.matches) {
|
|
874
1011
|
const { entry } = signature;
|
|
875
1012
|
if (entry) {
|
|
@@ -904,6 +1041,23 @@ function stateModelFactory() {
|
|
|
904
1041
|
},
|
|
905
1042
|
}))
|
|
906
1043
|
.views(self => ({
|
|
1044
|
+
/**
|
|
1045
|
+
* #getter
|
|
1046
|
+
*/
|
|
1047
|
+
get showVerticalScrollbar() {
|
|
1048
|
+
return self.msaAreaHeight < self.totalHeight;
|
|
1049
|
+
},
|
|
1050
|
+
}))
|
|
1051
|
+
.views(self => ({
|
|
1052
|
+
/**
|
|
1053
|
+
* #getter
|
|
1054
|
+
*/
|
|
1055
|
+
get verticalScrollbarWidth() {
|
|
1056
|
+
return self.showVerticalScrollbar ? 20 : 0;
|
|
1057
|
+
},
|
|
1058
|
+
/**
|
|
1059
|
+
* #getter
|
|
1060
|
+
*/
|
|
907
1061
|
get fillPalette() {
|
|
908
1062
|
const arr = [...self.tidyTypes.keys()];
|
|
909
1063
|
let i = 0;
|
|
@@ -915,6 +1069,9 @@ function stateModelFactory() {
|
|
|
915
1069
|
}
|
|
916
1070
|
return map;
|
|
917
1071
|
},
|
|
1072
|
+
/**
|
|
1073
|
+
* #getter
|
|
1074
|
+
*/
|
|
918
1075
|
get strokePalette() {
|
|
919
1076
|
return Object.fromEntries(Object.entries(this.fillPalette).map(([key, val]) => [
|
|
920
1077
|
key,
|
|
@@ -926,43 +1083,20 @@ function stateModelFactory() {
|
|
|
926
1083
|
/**
|
|
927
1084
|
* #action
|
|
928
1085
|
*/
|
|
929
|
-
|
|
930
|
-
self.
|
|
931
|
-
const ret = await loadInterProScanResults(jobId);
|
|
932
|
-
self.setStatus();
|
|
933
|
-
self.setLoadedInterProAnnotations(Object.fromEntries(ret.results.map(r => [r.xref[0].id, r])));
|
|
934
|
-
},
|
|
935
|
-
/**
|
|
936
|
-
* #action
|
|
937
|
-
*/
|
|
938
|
-
async queryInterProScan(programs) {
|
|
939
|
-
const { rows } = self;
|
|
940
|
-
if (rows.length > 140) {
|
|
941
|
-
throw new Error('Too many sequences, please run InterProScan offline');
|
|
942
|
-
}
|
|
943
|
-
const ret = await launchInterProScan({
|
|
944
|
-
algorithm: 'interproscan',
|
|
945
|
-
programs: programs,
|
|
946
|
-
seq: rows
|
|
947
|
-
.map(row => `>${row[0]}\n${row[1].replaceAll('-', '')}`)
|
|
948
|
-
.join('\n'),
|
|
949
|
-
onProgress: arg => self.setStatus(arg),
|
|
950
|
-
onJobId: jobId => self.addInterProScanJobId(jobId),
|
|
951
|
-
});
|
|
952
|
-
self.setLoadedInterProAnnotations(Object.fromEntries(ret.results.map(r => [r.xref[0].id, r])));
|
|
1086
|
+
setHeaderHeight(arg) {
|
|
1087
|
+
self.headerHeight = arg;
|
|
953
1088
|
},
|
|
954
1089
|
/**
|
|
955
1090
|
* #action
|
|
956
1091
|
*/
|
|
957
1092
|
reset() {
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
});
|
|
1093
|
+
self.setData({ tree: '', msa: '' });
|
|
1094
|
+
self.setError(undefined);
|
|
1095
|
+
self.setScrollY(0);
|
|
1096
|
+
self.setScrollX(0);
|
|
1097
|
+
self.setCurrentAlignment(0);
|
|
1098
|
+
self.setTreeFilehandle(undefined);
|
|
1099
|
+
self.setMSAFilehandle(undefined);
|
|
966
1100
|
},
|
|
967
1101
|
/**
|
|
968
1102
|
* #action
|
|
@@ -1001,22 +1135,6 @@ function stateModelFactory() {
|
|
|
1001
1135
|
this.initFilter(key);
|
|
1002
1136
|
}
|
|
1003
1137
|
}));
|
|
1004
|
-
addDisposer(self, autorun(async () => {
|
|
1005
|
-
// const res = Object.fromEntries(
|
|
1006
|
-
// await Promise.all(
|
|
1007
|
-
// self.annotationTracks.map(async f => {
|
|
1008
|
-
// const d = await jsonfetch(
|
|
1009
|
-
// `https://jbrowse.org/demos/interproscan/json/${encodeURIComponent(f)}`,
|
|
1010
|
-
// )
|
|
1011
|
-
// return [
|
|
1012
|
-
// decodeURIComponent(f).replace('.json', ''),
|
|
1013
|
-
// d.result.results[0],
|
|
1014
|
-
// ] as const
|
|
1015
|
-
// }),
|
|
1016
|
-
// ),
|
|
1017
|
-
// )
|
|
1018
|
-
// self.setLoadedInterProAnnotations(res)
|
|
1019
|
-
}));
|
|
1020
1138
|
// autorun opens treeFilehandle
|
|
1021
1139
|
addDisposer(self, autorun(async () => {
|
|
1022
1140
|
const { treeFilehandle } = self;
|
|
@@ -1057,9 +1175,11 @@ function stateModelFactory() {
|
|
|
1057
1175
|
if (msaFilehandle) {
|
|
1058
1176
|
try {
|
|
1059
1177
|
self.setLoadingMSA(true);
|
|
1060
|
-
const res = await openLocation(msaFilehandle).readFile(
|
|
1178
|
+
const res = await openLocation(msaFilehandle).readFile();
|
|
1179
|
+
const buf = isGzip(res) ? ungzip(res) : res;
|
|
1180
|
+
const txt = new TextDecoder('utf8').decode(buf);
|
|
1061
1181
|
transaction(() => {
|
|
1062
|
-
self.setMSA(
|
|
1182
|
+
self.setMSA(txt);
|
|
1063
1183
|
if (msaFilehandle.locationType === 'BlobLocation') {
|
|
1064
1184
|
// clear filehandle after loading if from a local file
|
|
1065
1185
|
self.setMSAFilehandle(undefined);
|
|
@@ -1075,15 +1195,20 @@ function stateModelFactory() {
|
|
|
1075
1195
|
}
|
|
1076
1196
|
}
|
|
1077
1197
|
}));
|
|
1198
|
+
addDisposer(self, autorun(() => {
|
|
1199
|
+
// force colStats not to go stale,
|
|
1200
|
+
// xref solution https://github.com/mobxjs/mobx/issues/266#issuecomment-222007278
|
|
1201
|
+
// xref problem https://github.com/GMOD/react-msaview/issues/75
|
|
1202
|
+
self.colStats;
|
|
1203
|
+
self.colStatsSums;
|
|
1204
|
+
self.columns;
|
|
1205
|
+
}));
|
|
1078
1206
|
// autorun synchronizes treeWidth with treeAreaWidth
|
|
1079
1207
|
addDisposer(self, autorun(async () => {
|
|
1080
1208
|
if (self.treeWidthMatchesArea) {
|
|
1081
1209
|
self.setTreeWidth(Math.max(50, self.treeAreaWidth - self.labelsWidth - 10 - self.marginLeft));
|
|
1082
1210
|
}
|
|
1083
1211
|
}));
|
|
1084
|
-
addDisposer(self, autorun(() => {
|
|
1085
|
-
localStorageSetItem('msaview-interproscanqueries', JSON.stringify(self.interProScanJobIds));
|
|
1086
|
-
}));
|
|
1087
1212
|
},
|
|
1088
1213
|
}))
|
|
1089
1214
|
.postProcessSnapshot(result => {
|