react-msaview 5.0.7 → 5.0.13
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 +25 -25
- package/bundle/index.js.map +1 -1
- package/dist/components/Checkbox2.js +3 -6
- package/dist/components/Checkbox2.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +14 -0
- package/dist/components/MSAViewer.js +34 -0
- package/dist/components/MSAViewer.js.map +1 -0
- package/dist/components/Track.js +5 -24
- package/dist/components/Track.js.map +1 -1
- package/dist/components/dialogs/DomainDialog.js +2 -5
- package/dist/components/dialogs/DomainDialog.js.map +1 -1
- package/dist/components/dialogs/InterProScanDialog.js +7 -7
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.js +3 -19
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/header/ColorSchemeMenu.d.ts +6 -0
- package/dist/components/header/ColorSchemeMenu.js +19 -0
- package/dist/components/header/ColorSchemeMenu.js.map +1 -0
- package/dist/components/header/{ZoomStar.d.ts → FileMenu.d.ts} +2 -2
- package/dist/components/header/FileMenu.js +71 -0
- package/dist/components/header/FileMenu.js.map +1 -0
- package/dist/components/header/Header.js +8 -6
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderMenu.js +3 -145
- package/dist/components/header/HeaderMenu.js.map +1 -1
- package/dist/components/header/MSASettingsMenu.d.ts +6 -0
- package/dist/components/header/MSASettingsMenu.js +36 -0
- package/dist/components/header/MSASettingsMenu.js.map +1 -0
- package/dist/components/header/SettingsMenu.js +1 -21
- package/dist/components/header/SettingsMenu.js.map +1 -1
- package/dist/components/header/TreeSettingsMenu.d.ts +6 -0
- package/dist/components/header/TreeSettingsMenu.js +74 -0
- package/dist/components/header/TreeSettingsMenu.js.map +1 -0
- package/dist/components/header/ZoomMenu.js +0 -8
- package/dist/components/header/ZoomMenu.js.map +1 -1
- package/dist/components/header/getDomainsMenu.d.ts +31 -0
- package/dist/components/header/getDomainsMenu.js +75 -0
- package/dist/components/header/getDomainsMenu.js.map +1 -0
- package/dist/components/import/ImportFormExamples.js +21 -19
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/msa/MSACanvas.js +13 -84
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +1 -3
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.js +2 -4
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +1 -7
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/tree/TreeCanvas.js +14 -91
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.js +5 -16
- package/dist/components/tree/TreeNodeMenu.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.js +4 -12
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/constants.js.map +1 -1
- package/dist/fetchUtils.d.ts +0 -1
- package/dist/fetchUtils.js +0 -4
- package/dist/fetchUtils.js.map +1 -1
- package/dist/flatToTree.d.ts +0 -5
- package/dist/flatToTree.js +13 -30
- package/dist/flatToTree.js.map +1 -1
- package/dist/hierarchy.d.ts +28 -0
- package/dist/hierarchy.js +164 -0
- package/dist/hierarchy.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/launchInterProScan.d.ts +0 -5
- package/dist/launchInterProScan.js +5 -3
- package/dist/launchInterProScan.js.map +1 -1
- package/dist/model/DataModel.d.ts +9 -0
- package/dist/model/DataModel.js +12 -1
- package/dist/model/DataModel.js.map +1 -1
- package/dist/model/msaModel.d.ts +3 -0
- package/dist/model/msaModel.js +0 -1
- package/dist/model/msaModel.js.map +1 -1
- package/dist/model/treeModel.d.ts +3 -6
- package/dist/model/treeModel.js +3 -15
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +24 -77
- package/dist/model.js +117 -239
- package/dist/model.js.map +1 -1
- package/dist/neighborJoining.js +38 -629
- package/dist/neighborJoining.js.map +1 -1
- package/dist/parseAsn1.d.ts +0 -12
- package/dist/parseAsn1.js +125 -332
- package/dist/parseAsn1.js.map +1 -1
- package/dist/useWheelScroll.d.ts +8 -0
- package/dist/useWheelScroll.js +93 -0
- package/dist/useWheelScroll.js.map +1 -0
- package/dist/util.d.ts +1 -6
- package/dist/util.js +5 -34
- package/dist/util.js.map +1 -1
- package/dist/vendor/copyToClipboard.d.ts +1 -10
- package/dist/vendor/copyToClipboard.js +14 -109
- package/dist/vendor/copyToClipboard.js.map +1 -1
- package/dist/vendor/fileSaver.d.ts +1 -11
- package/dist/vendor/fileSaver.js +7 -76
- package/dist/vendor/fileSaver.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 +10 -13
- package/src/collapseLogic.test.ts +115 -0
- package/src/components/Checkbox2.tsx +9 -18
- package/src/components/MSAViewer.tsx +67 -0
- package/src/components/Track.tsx +10 -26
- package/src/components/dialogs/DomainDialog.tsx +4 -5
- package/src/components/dialogs/InterProScanDialog.tsx +7 -7
- package/src/components/dialogs/SettingsDialog.tsx +0 -37
- package/src/components/header/ColorSchemeMenu.tsx +35 -0
- package/src/components/header/FileMenu.tsx +84 -0
- package/src/components/header/Header.tsx +8 -6
- package/src/components/header/HeaderMenu.tsx +4 -155
- package/src/components/header/MSASettingsMenu.tsx +48 -0
- package/src/components/header/SettingsMenu.tsx +0 -23
- package/src/components/header/TreeSettingsMenu.tsx +96 -0
- package/src/components/header/ZoomMenu.tsx +0 -8
- package/src/components/header/getDomainsMenu.ts +83 -0
- package/src/components/import/ImportFormExamples.tsx +37 -34
- package/src/components/msa/MSACanvas.tsx +21 -91
- package/src/components/msa/MSACanvasBlock.tsx +1 -3
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +1 -1
- package/src/components/msa/renderMSABlock.ts +2 -5
- package/src/components/msa/renderMSAMouseover.ts +0 -6
- package/src/components/tree/TreeCanvas.tsx +35 -100
- package/src/components/tree/TreeNodeMenu.tsx +5 -14
- package/src/components/tree/renderTreeCanvas.ts +8 -21
- package/src/constants.ts +0 -2
- package/src/fetchUtils.ts +0 -5
- package/src/flatToTree.ts +20 -38
- package/src/hierarchy.test.ts +120 -0
- package/src/hierarchy.ts +220 -0
- package/src/index.ts +2 -0
- package/src/launchInterProScan.ts +4 -3
- package/src/model/DataModel.ts +12 -1
- package/src/model/msaModel.ts +0 -2
- package/src/model/treeModel.ts +2 -18
- package/src/model.ts +179 -278
- package/src/neighborJoining.ts +38 -628
- package/src/parseAsn1.test.ts +4 -1
- package/src/parseAsn1.ts +135 -405
- package/src/useWheelScroll.ts +109 -0
- package/src/util.ts +5 -50
- package/src/vendor/copyToClipboard.ts +14 -122
- package/src/vendor/fileSaver.ts +8 -105
- package/src/version.ts +1 -1
- package/dist/components/dialogs/AddTrackDialog.d.ts +0 -8
- package/dist/components/dialogs/AddTrackDialog.js +0 -30
- package/dist/components/dialogs/AddTrackDialog.js.map +0 -1
- package/dist/components/dialogs/TabPanel.d.ts +0 -6
- package/dist/components/dialogs/TabPanel.js +0 -6
- package/dist/components/dialogs/TabPanel.js.map +0 -1
- package/dist/components/header/ZoomStar.js +0 -40
- package/dist/components/header/ZoomStar.js.map +0 -1
- package/dist/layout.d.ts +0 -26
- package/dist/layout.js +0 -74
- package/dist/layout.js.map +0 -1
- package/dist/reparseTree.d.ts +0 -2
- package/dist/reparseTree.js +0 -15
- package/dist/reparseTree.js.map +0 -1
- package/src/components/dialogs/AddTrackDialog.tsx +0 -85
- package/src/components/dialogs/TabPanel.tsx +0 -19
- package/src/components/header/ZoomStar.tsx +0 -74
- package/src/createPaletteMap.test.ts +0 -57
- package/src/layout.ts +0 -118
- package/src/reparseTree.ts +0 -18
package/dist/model.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { clamp, fetchAndMaybeUnzipText, groupBy,
|
|
1
|
+
import { clamp, fetchAndMaybeUnzipText, groupBy, notEmpty, sum, } from '@jbrowse/core/util';
|
|
2
2
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
3
3
|
import { ElementId, FileLocation } from '@jbrowse/core/util/types/mst';
|
|
4
4
|
import { addDisposer, cast, types } from '@jbrowse/mobx-state-tree';
|
|
5
5
|
import { colord } from 'colord';
|
|
6
|
-
import { ascending } from 'd3-array';
|
|
7
|
-
import { cluster, hierarchy } from 'd3-hierarchy';
|
|
8
6
|
import { autorun, transaction } from 'mobx';
|
|
9
|
-
import {
|
|
7
|
+
import { generateNodeIds, gffToInterProResults, parseEmfTree, parseGFF, parseMSA, parseNewick, } from 'msa-parsers';
|
|
10
8
|
import { blocksX, blocksY } from "./calculateBlocks.js";
|
|
11
9
|
import colorSchemes from "./colorSchemes.js";
|
|
12
10
|
import ConservationTrack from "./components/ConservationTrack.js";
|
|
13
11
|
import TextTrack from "./components/TextTrack.js";
|
|
14
|
-
import { defaultAllowedGappyness, defaultBgColor, defaultColWidth, defaultColorSchemeName,
|
|
12
|
+
import { defaultAllowedGappyness, defaultBgColor, defaultColWidth, defaultColorSchemeName, defaultCurrentAlignment, defaultDrawLabels, defaultDrawMsaLetters, defaultDrawNodeBubbles, defaultDrawTree, defaultHeight, defaultHideGaps, defaultLabelsAlignRight, defaultRowHeight, defaultScrollX, defaultScrollY, defaultShowBranchLen, defaultShowDomains, defaultSubFeatureRows, defaultTreeAreaWidth, defaultTreeWidth, } from "./constants.js";
|
|
15
13
|
import { createPaletteMap } from "./createPaletteMap.js";
|
|
16
14
|
import { flatToTree } from "./flatToTree.js";
|
|
15
|
+
import { clusterLayout, collapse, find, hierarchy, leaves, links, maxLength, setBrLength, sort, sum as hierarchySum, } from "./hierarchy.js";
|
|
17
16
|
import { measureTextCanvas } from "./measureTextCanvas.js";
|
|
18
17
|
import { DataModelF } from "./model/DataModel.js";
|
|
19
18
|
import { DialogQueueSessionMixin } from "./model/DialogQueue.js";
|
|
@@ -21,12 +20,10 @@ import { MSAModelF } from "./model/msaModel.js";
|
|
|
21
20
|
import { TreeModelF } from "./model/treeModel.js";
|
|
22
21
|
import { calculateNeighborJoiningTree } from "./neighborJoining.js";
|
|
23
22
|
import { parseAsn1 } from "./parseAsn1.js";
|
|
24
|
-
import { reparseTree } from "./reparseTree.js";
|
|
25
23
|
import { globalColToVisibleCol, visibleColToGlobalCol, visibleColToSeqPosForRow, } from "./rowCoordinateCalculations.js";
|
|
26
24
|
import { seqPosToGlobalCol } from "./seqPosToGlobalCol.js";
|
|
27
|
-
import {
|
|
25
|
+
import { len, skipBlanks } from "./util.js";
|
|
28
26
|
import { saveAs } from "./vendor/fileSaver.js";
|
|
29
|
-
const showZoomStarKey = 'msa-showZoomStar';
|
|
30
27
|
/**
|
|
31
28
|
* #stateModel MsaView
|
|
32
29
|
* extends
|
|
@@ -54,10 +51,6 @@ function stateModelFactory() {
|
|
|
54
51
|
* #property
|
|
55
52
|
*/
|
|
56
53
|
allowedGappyness: defaultAllowedGappyness,
|
|
57
|
-
/**
|
|
58
|
-
* #property
|
|
59
|
-
*/
|
|
60
|
-
contrastLettering: defaultContrastLettering,
|
|
61
54
|
/**
|
|
62
55
|
* #property
|
|
63
56
|
*/
|
|
@@ -119,7 +112,6 @@ function stateModelFactory() {
|
|
|
119
112
|
gffFilehandle: types.maybe(FileLocation),
|
|
120
113
|
/**
|
|
121
114
|
* #property
|
|
122
|
-
*
|
|
123
115
|
*/
|
|
124
116
|
currentAlignment: defaultCurrentAlignment,
|
|
125
117
|
/**
|
|
@@ -128,12 +120,6 @@ function stateModelFactory() {
|
|
|
128
120
|
* hidden)
|
|
129
121
|
*/
|
|
130
122
|
collapsed: types.array(types.string),
|
|
131
|
-
/**
|
|
132
|
-
* #property
|
|
133
|
-
* array of tree leaf nodes that are 'collapsed' (just that leaf node
|
|
134
|
-
* is hidden)
|
|
135
|
-
*/
|
|
136
|
-
collapsedLeaves: types.array(types.string),
|
|
137
123
|
/**
|
|
138
124
|
* #property
|
|
139
125
|
* focus on particular subtree
|
|
@@ -178,11 +164,6 @@ function stateModelFactory() {
|
|
|
178
164
|
* screens
|
|
179
165
|
*/
|
|
180
166
|
highResScaleFactor: 2,
|
|
181
|
-
/**
|
|
182
|
-
* #volatile
|
|
183
|
-
* obtained from localStorage
|
|
184
|
-
*/
|
|
185
|
-
showZoomStar: localStorageGetBoolean(showZoomStarKey, false),
|
|
186
167
|
/**
|
|
187
168
|
* #volatile
|
|
188
169
|
*/
|
|
@@ -257,10 +238,6 @@ function stateModelFactory() {
|
|
|
257
238
|
* #volatile
|
|
258
239
|
*/
|
|
259
240
|
error: undefined,
|
|
260
|
-
/**
|
|
261
|
-
* #volatile
|
|
262
|
-
*/
|
|
263
|
-
annotPos: undefined,
|
|
264
241
|
/**
|
|
265
242
|
* #volatile
|
|
266
243
|
*/
|
|
@@ -285,24 +262,12 @@ function stateModelFactory() {
|
|
|
285
262
|
setAllowedGappyness(arg) {
|
|
286
263
|
self.allowedGappyness = arg;
|
|
287
264
|
},
|
|
288
|
-
/**
|
|
289
|
-
* #action
|
|
290
|
-
*/
|
|
291
|
-
setContrastLettering(arg) {
|
|
292
|
-
self.contrastLettering = arg;
|
|
293
|
-
},
|
|
294
265
|
/**
|
|
295
266
|
* #action
|
|
296
267
|
*/
|
|
297
268
|
setLoadingMSA(arg) {
|
|
298
269
|
self.loadingMSA = arg;
|
|
299
270
|
},
|
|
300
|
-
/**
|
|
301
|
-
* #action
|
|
302
|
-
*/
|
|
303
|
-
setShowZoomStar(arg) {
|
|
304
|
-
self.showZoomStar = arg;
|
|
305
|
-
},
|
|
306
271
|
/**
|
|
307
272
|
* #action
|
|
308
273
|
*/
|
|
@@ -346,14 +311,12 @@ function stateModelFactory() {
|
|
|
346
311
|
self.hoveredTreeNode = undefined;
|
|
347
312
|
return;
|
|
348
313
|
}
|
|
349
|
-
|
|
350
|
-
const node = self.hierarchy.find(n => n.data.id === nodeId);
|
|
314
|
+
const node = find(self.hierarchy, n => n.data.id === nodeId);
|
|
351
315
|
if (!node) {
|
|
352
316
|
self.hoveredTreeNode = undefined;
|
|
353
317
|
return;
|
|
354
318
|
}
|
|
355
|
-
|
|
356
|
-
const descendantNames = node.leaves().map(leaf => leaf.data.name);
|
|
319
|
+
const descendantNames = leaves(node).map(leaf => leaf.data.name);
|
|
357
320
|
self.hoveredTreeNode = { nodeId, descendantNames };
|
|
358
321
|
},
|
|
359
322
|
/**
|
|
@@ -422,17 +385,6 @@ function stateModelFactory() {
|
|
|
422
385
|
self.collapsed.push(node);
|
|
423
386
|
}
|
|
424
387
|
},
|
|
425
|
-
/**
|
|
426
|
-
* #action
|
|
427
|
-
*/
|
|
428
|
-
toggleCollapsedLeaf(node) {
|
|
429
|
-
if (self.collapsedLeaves.includes(node)) {
|
|
430
|
-
self.collapsedLeaves.remove(node);
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
self.collapsedLeaves.push(node);
|
|
434
|
-
}
|
|
435
|
-
},
|
|
436
388
|
/**
|
|
437
389
|
* #action
|
|
438
390
|
*/
|
|
@@ -489,9 +441,7 @@ function stateModelFactory() {
|
|
|
489
441
|
*/
|
|
490
442
|
get hideGapsEffective() {
|
|
491
443
|
return (self.hideGaps &&
|
|
492
|
-
(self.collapsed.length > 0 ||
|
|
493
|
-
self.collapsedLeaves.length > 0 ||
|
|
494
|
-
self.allowedGappyness < 100));
|
|
444
|
+
(self.collapsed.length > 0 || self.allowedGappyness < 100));
|
|
495
445
|
},
|
|
496
446
|
/**
|
|
497
447
|
* #getter
|
|
@@ -505,9 +455,6 @@ function stateModelFactory() {
|
|
|
505
455
|
get actuallyShowDomains() {
|
|
506
456
|
return self.showDomains && !!self.interProAnnotations;
|
|
507
457
|
},
|
|
508
|
-
/**
|
|
509
|
-
* #getter
|
|
510
|
-
*/
|
|
511
458
|
get viewInitialized() {
|
|
512
459
|
return self.volatileWidth !== undefined;
|
|
513
460
|
},
|
|
@@ -539,7 +486,7 @@ function stateModelFactory() {
|
|
|
539
486
|
* #getter
|
|
540
487
|
*/
|
|
541
488
|
get header() {
|
|
542
|
-
return this.MSA?.getHeader() || {};
|
|
489
|
+
return (this.MSA?.getHeader() || {});
|
|
543
490
|
},
|
|
544
491
|
/**
|
|
545
492
|
* #getter
|
|
@@ -553,15 +500,9 @@ function stateModelFactory() {
|
|
|
553
500
|
get noTree() {
|
|
554
501
|
return !!this.tree.noTree;
|
|
555
502
|
},
|
|
556
|
-
/**
|
|
557
|
-
* #getter
|
|
558
|
-
*/
|
|
559
503
|
get noDomains() {
|
|
560
504
|
return !self.interProAnnotations;
|
|
561
505
|
},
|
|
562
|
-
/**
|
|
563
|
-
* #getter
|
|
564
|
-
*/
|
|
565
506
|
menuItems() {
|
|
566
507
|
return [];
|
|
567
508
|
},
|
|
@@ -576,24 +517,9 @@ function stateModelFactory() {
|
|
|
576
517
|
*/
|
|
577
518
|
get MSA() {
|
|
578
519
|
const text = self.data.msa;
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
else if (A3mMSA.sniff(text)) {
|
|
584
|
-
return new A3mMSA(text);
|
|
585
|
-
}
|
|
586
|
-
else if (text.startsWith('>')) {
|
|
587
|
-
return new FastaMSA(text);
|
|
588
|
-
}
|
|
589
|
-
else if (text.startsWith('SEQ')) {
|
|
590
|
-
return new EmfMSA(text);
|
|
591
|
-
}
|
|
592
|
-
else {
|
|
593
|
-
return new ClustalMSA(text);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
return null;
|
|
520
|
+
// uses parseMSA so the named MSAParserType return type is portable
|
|
521
|
+
// to downstream consumers (avoids TS2883 with default exports)
|
|
522
|
+
return text ? parseMSA(text, self.currentAlignment) : null;
|
|
597
523
|
},
|
|
598
524
|
/**
|
|
599
525
|
* #getter
|
|
@@ -606,7 +532,7 @@ function stateModelFactory() {
|
|
|
606
532
|
*/
|
|
607
533
|
get tree() {
|
|
608
534
|
const text = self.data.tree;
|
|
609
|
-
return
|
|
535
|
+
return text
|
|
610
536
|
? generateNodeIds(text.startsWith('BioTreeContainer')
|
|
611
537
|
? flatToTree(parseAsn1(text))
|
|
612
538
|
: parseNewick(text.startsWith('SEQ') ? parseEmfTree(text).tree : text))
|
|
@@ -615,7 +541,7 @@ function stateModelFactory() {
|
|
|
615
541
|
children: [],
|
|
616
542
|
id: 'empty',
|
|
617
543
|
name: 'empty',
|
|
618
|
-
}
|
|
544
|
+
};
|
|
619
545
|
},
|
|
620
546
|
/**
|
|
621
547
|
* #getter
|
|
@@ -661,25 +587,27 @@ function stateModelFactory() {
|
|
|
661
587
|
* #getter
|
|
662
588
|
*/
|
|
663
589
|
get root() {
|
|
664
|
-
let hier = hierarchy(this.tree, d => d.children)
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
.sum(d => (d.children ? 0 : 1))
|
|
668
|
-
// eslint-disable-next-line unicorn/no-array-sort
|
|
669
|
-
.sort((a, b) => ascending(a.data.length || 1, b.data.length || 1));
|
|
590
|
+
let hier = hierarchy(this.tree, d => d.children);
|
|
591
|
+
hierarchySum(hier, d => (d.children.length > 0 ? 0 : 1));
|
|
592
|
+
sort(hier, (a, b) => (a.data.length ?? 1) - (b.data.length ?? 1));
|
|
670
593
|
if (self.showOnly) {
|
|
671
|
-
const res =
|
|
594
|
+
const res = find(hier, n => n.data.id === self.showOnly);
|
|
672
595
|
if (res) {
|
|
673
596
|
hier = res;
|
|
674
597
|
}
|
|
675
598
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
599
|
+
for (const collapsedId of self.collapsed) {
|
|
600
|
+
const node = find(hier, n => n.data.id === collapsedId);
|
|
601
|
+
if (!node) {
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
if (node.children) {
|
|
605
|
+
collapse(node);
|
|
606
|
+
}
|
|
607
|
+
else if (node.parent?.children) {
|
|
608
|
+
node.parent.children = node.parent.children.filter(c => c.data.id !== collapsedId);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
683
611
|
return hier;
|
|
684
612
|
},
|
|
685
613
|
/**
|
|
@@ -1072,30 +1000,28 @@ function stateModelFactory() {
|
|
|
1072
1000
|
*/
|
|
1073
1001
|
get hierarchy() {
|
|
1074
1002
|
const r = this.root;
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
clust(r);
|
|
1079
|
-
setBrLength(r, (r.data.length = 0), self.treeWidth / maxLength(r));
|
|
1003
|
+
clusterLayout(r, this.totalHeight, self.treeWidth);
|
|
1004
|
+
r.data.length = 0;
|
|
1005
|
+
setBrLength(r, 0, self.treeWidth / maxLength(r));
|
|
1080
1006
|
return r;
|
|
1081
1007
|
},
|
|
1082
1008
|
/**
|
|
1083
1009
|
* #getter
|
|
1084
1010
|
*/
|
|
1085
1011
|
get totalHeight() {
|
|
1086
|
-
return this.root
|
|
1012
|
+
return leaves(this.root).length * self.rowHeight;
|
|
1087
1013
|
},
|
|
1088
1014
|
/**
|
|
1089
1015
|
* #getter
|
|
1090
1016
|
*/
|
|
1091
1017
|
get leaves() {
|
|
1092
|
-
return this.hierarchy
|
|
1018
|
+
return leaves(this.hierarchy);
|
|
1093
1019
|
},
|
|
1094
1020
|
/**
|
|
1095
1021
|
* #getter
|
|
1096
1022
|
*/
|
|
1097
1023
|
get allBranchesLength0() {
|
|
1098
|
-
return this.hierarchy
|
|
1024
|
+
return links(this.hierarchy).every(s => !s.source.data.length);
|
|
1099
1025
|
},
|
|
1100
1026
|
/**
|
|
1101
1027
|
* #getter
|
|
@@ -1148,13 +1074,7 @@ function stateModelFactory() {
|
|
|
1148
1074
|
* #getter
|
|
1149
1075
|
*/
|
|
1150
1076
|
get blocks2d() {
|
|
1151
|
-
|
|
1152
|
-
for (const by of self.blocksY) {
|
|
1153
|
-
for (const bx of self.blocksX) {
|
|
1154
|
-
ret.push([bx, by]);
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
return ret;
|
|
1077
|
+
return self.blocksY.flatMap(by => self.blocksX.map(bx => [bx, by]));
|
|
1158
1078
|
},
|
|
1159
1079
|
/**
|
|
1160
1080
|
* #getter
|
|
@@ -1257,14 +1177,17 @@ function stateModelFactory() {
|
|
|
1257
1177
|
/**
|
|
1258
1178
|
* #action
|
|
1259
1179
|
*/
|
|
1180
|
+
doScrollY(deltaY) {
|
|
1181
|
+
self.scrollY = clamp(self.scrollY + deltaY, -self.totalHeight + 10, 0);
|
|
1182
|
+
},
|
|
1260
1183
|
setInterProAnnotations(data) {
|
|
1261
1184
|
self.interProAnnotations = data;
|
|
1262
1185
|
},
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
self.
|
|
1186
|
+
applyGFFText(gffText) {
|
|
1187
|
+
const gffRecords = parseGFF(gffText);
|
|
1188
|
+
const interProResults = gffToInterProResults(gffRecords);
|
|
1189
|
+
self.interProAnnotations = interProResults;
|
|
1190
|
+
self.setShowDomains(true);
|
|
1268
1191
|
},
|
|
1269
1192
|
/**
|
|
1270
1193
|
* #action
|
|
@@ -1301,14 +1224,11 @@ function stateModelFactory() {
|
|
|
1301
1224
|
* #getter
|
|
1302
1225
|
*/
|
|
1303
1226
|
get labelsWidth() {
|
|
1304
|
-
let x = 0;
|
|
1305
1227
|
const { rowHeight, leaves, treeMetadata, fontSize } = self;
|
|
1306
|
-
if (rowHeight
|
|
1307
|
-
|
|
1308
|
-
x = Math.max(measureTextCanvas(treeMetadata[node.data.name]?.genome || node.data.name, fontSize), x);
|
|
1309
|
-
}
|
|
1228
|
+
if (rowHeight <= 5) {
|
|
1229
|
+
return 0;
|
|
1310
1230
|
}
|
|
1311
|
-
return
|
|
1231
|
+
return leaves.reduce((max, node) => Math.max(max, measureTextCanvas(treeMetadata[node.data.name]?.genome || node.data.name, fontSize)), 0);
|
|
1312
1232
|
},
|
|
1313
1233
|
/**
|
|
1314
1234
|
* #getter
|
|
@@ -1327,16 +1247,19 @@ function stateModelFactory() {
|
|
|
1327
1247
|
*/
|
|
1328
1248
|
get adapterTrackModels() {
|
|
1329
1249
|
const { rowHeight, MSA, hideGapsEffective, blanks } = self;
|
|
1330
|
-
|
|
1331
|
-
|
|
1250
|
+
const tracks = (MSA?.tracks ?? []);
|
|
1251
|
+
return tracks
|
|
1252
|
+
.filter(t => !!t.data)
|
|
1332
1253
|
.map(t => ({
|
|
1333
1254
|
model: {
|
|
1334
1255
|
...t,
|
|
1335
|
-
data: hideGapsEffective
|
|
1256
|
+
data: hideGapsEffective && t.data
|
|
1257
|
+
? skipBlanks(blanks, t.data)
|
|
1258
|
+
: t.data,
|
|
1336
1259
|
height: rowHeight,
|
|
1337
1260
|
},
|
|
1338
1261
|
ReactComponent: TextTrack,
|
|
1339
|
-
}))
|
|
1262
|
+
}));
|
|
1340
1263
|
},
|
|
1341
1264
|
/**
|
|
1342
1265
|
* #getter
|
|
@@ -1500,53 +1423,30 @@ function stateModelFactory() {
|
|
|
1500
1423
|
get totalTrackAreaHeight() {
|
|
1501
1424
|
return sum(self.turnedOnTracks.map(r => r.model.height));
|
|
1502
1425
|
},
|
|
1503
|
-
/**
|
|
1504
|
-
* #getter
|
|
1505
|
-
*/
|
|
1506
1426
|
get tidyInterProAnnotationTypes() {
|
|
1507
|
-
|
|
1508
|
-
for (const annot of this.tidyInterProAnnotations) {
|
|
1509
|
-
types.set(annot.accession, annot);
|
|
1510
|
-
}
|
|
1511
|
-
return types;
|
|
1427
|
+
return new Map(this.tidyInterProAnnotations.map(annot => [annot.accession, annot]));
|
|
1512
1428
|
},
|
|
1513
|
-
/**
|
|
1514
|
-
* #getter
|
|
1515
|
-
*/
|
|
1516
1429
|
get tidyInterProAnnotations() {
|
|
1517
|
-
const ret = [];
|
|
1518
1430
|
const { interProAnnotations } = self;
|
|
1519
|
-
if (interProAnnotations) {
|
|
1520
|
-
|
|
1521
|
-
for (const { signature, locations } of val.matches) {
|
|
1522
|
-
const { entry } = signature;
|
|
1523
|
-
if (entry) {
|
|
1524
|
-
const { name, accession, description } = entry;
|
|
1525
|
-
for (const { start, end } of locations) {
|
|
1526
|
-
ret.push({
|
|
1527
|
-
id,
|
|
1528
|
-
name,
|
|
1529
|
-
accession,
|
|
1530
|
-
description,
|
|
1531
|
-
start,
|
|
1532
|
-
end,
|
|
1533
|
-
});
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1431
|
+
if (!interProAnnotations) {
|
|
1432
|
+
return [];
|
|
1538
1433
|
}
|
|
1539
|
-
return
|
|
1434
|
+
return Object.entries(interProAnnotations)
|
|
1435
|
+
.flatMap(([id, val]) => val.matches.flatMap(({ signature, locations }) => signature.entry
|
|
1436
|
+
? locations.map(({ start, end }) => ({
|
|
1437
|
+
id,
|
|
1438
|
+
name: signature.entry.name,
|
|
1439
|
+
accession: signature.entry.accession,
|
|
1440
|
+
description: signature.entry.description,
|
|
1441
|
+
start,
|
|
1442
|
+
end,
|
|
1443
|
+
}))
|
|
1444
|
+
: []))
|
|
1445
|
+
.toSorted((a, b) => len(b) - len(a));
|
|
1540
1446
|
},
|
|
1541
|
-
/**
|
|
1542
|
-
* #getter
|
|
1543
|
-
*/
|
|
1544
1447
|
get tidyFilteredInterProAnnotations() {
|
|
1545
1448
|
return this.tidyInterProAnnotations.filter(r => self.featureFilters.get(r.accession));
|
|
1546
1449
|
},
|
|
1547
|
-
/**
|
|
1548
|
-
* #getter
|
|
1549
|
-
*/
|
|
1550
1450
|
get tidyFilteredGatheredInterProAnnotations() {
|
|
1551
1451
|
return groupBy(this.tidyFilteredInterProAnnotations, r => r.id);
|
|
1552
1452
|
},
|
|
@@ -1566,15 +1466,9 @@ function stateModelFactory() {
|
|
|
1566
1466
|
get verticalScrollbarWidth() {
|
|
1567
1467
|
return self.showVerticalScrollbar ? 20 : 0;
|
|
1568
1468
|
},
|
|
1569
|
-
/**
|
|
1570
|
-
* #getter
|
|
1571
|
-
*/
|
|
1572
1469
|
get fillPalette() {
|
|
1573
1470
|
return createPaletteMap([...self.tidyInterProAnnotationTypes.keys()]);
|
|
1574
1471
|
},
|
|
1575
|
-
/**
|
|
1576
|
-
* #getter
|
|
1577
|
-
*/
|
|
1578
1472
|
get strokePalette() {
|
|
1579
1473
|
return Object.fromEntries(Object.entries(this.fillPalette).map(([key, val]) => [
|
|
1580
1474
|
key,
|
|
@@ -1619,6 +1513,9 @@ function stateModelFactory() {
|
|
|
1619
1513
|
self.setCurrentAlignment(0);
|
|
1620
1514
|
self.setTreeFilehandle(undefined);
|
|
1621
1515
|
self.setMSAFilehandle(undefined);
|
|
1516
|
+
self.setGFFFilehandle(undefined);
|
|
1517
|
+
self.setInterProAnnotations({});
|
|
1518
|
+
self.setShowDomains(false);
|
|
1622
1519
|
},
|
|
1623
1520
|
/**
|
|
1624
1521
|
* #action
|
|
@@ -1636,18 +1533,12 @@ function stateModelFactory() {
|
|
|
1636
1533
|
incrementRef() {
|
|
1637
1534
|
self.nref++;
|
|
1638
1535
|
},
|
|
1639
|
-
/**
|
|
1640
|
-
* #action
|
|
1641
|
-
*/
|
|
1642
1536
|
initFilter(arg) {
|
|
1643
1537
|
const ret = self.featureFilters.get(arg);
|
|
1644
1538
|
if (ret === undefined) {
|
|
1645
1539
|
self.featureFilters.set(arg, true);
|
|
1646
1540
|
}
|
|
1647
1541
|
},
|
|
1648
|
-
/**
|
|
1649
|
-
* #action
|
|
1650
|
-
*/
|
|
1651
1542
|
setFilter(arg, flag) {
|
|
1652
1543
|
self.featureFilters.set(arg, flag);
|
|
1653
1544
|
},
|
|
@@ -1680,10 +1571,6 @@ function stateModelFactory() {
|
|
|
1680
1571
|
this.initFilter(key);
|
|
1681
1572
|
}
|
|
1682
1573
|
}));
|
|
1683
|
-
// autorun saves local settings
|
|
1684
|
-
addDisposer(self, autorun(() => {
|
|
1685
|
-
localStorageSetBoolean(showZoomStarKey, self.showZoomStar);
|
|
1686
|
-
}));
|
|
1687
1574
|
// autorun opens treeFilehandle
|
|
1688
1575
|
addDisposer(self, autorun(async () => {
|
|
1689
1576
|
const { treeFilehandle } = self;
|
|
@@ -1718,16 +1605,26 @@ function stateModelFactory() {
|
|
|
1718
1605
|
}
|
|
1719
1606
|
}
|
|
1720
1607
|
}));
|
|
1608
|
+
// autorun parses inline gff text from data.gff
|
|
1609
|
+
addDisposer(self, autorun(() => {
|
|
1610
|
+
const gffText = self.data.gff;
|
|
1611
|
+
if (gffText) {
|
|
1612
|
+
try {
|
|
1613
|
+
self.applyGFFText(gffText);
|
|
1614
|
+
}
|
|
1615
|
+
catch (e) {
|
|
1616
|
+
console.error(e);
|
|
1617
|
+
self.setError(e);
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
}));
|
|
1721
1621
|
// autorun opens gffFilehandle for InterProScan domains
|
|
1722
1622
|
addDisposer(self, autorun(async () => {
|
|
1723
1623
|
const { gffFilehandle } = self;
|
|
1724
1624
|
if (gffFilehandle) {
|
|
1725
1625
|
try {
|
|
1726
1626
|
const gffText = await fetchAndMaybeUnzipText(openLocation(gffFilehandle));
|
|
1727
|
-
|
|
1728
|
-
const interProResults = gffToInterProResults(gffRecords);
|
|
1729
|
-
self.setInterProAnnotations(interProResults);
|
|
1730
|
-
self.setShowDomains(true);
|
|
1627
|
+
self.applyGFFText(gffText);
|
|
1731
1628
|
if (gffFilehandle.locationType === 'BlobLocation') {
|
|
1732
1629
|
self.setGFFFilehandle(undefined);
|
|
1733
1630
|
}
|
|
@@ -1777,10 +1674,8 @@ function stateModelFactory() {
|
|
|
1777
1674
|
self.columns;
|
|
1778
1675
|
}));
|
|
1779
1676
|
// autorun synchronizes treeWidth with treeAreaWidth
|
|
1780
|
-
addDisposer(self, autorun(
|
|
1781
|
-
|
|
1782
|
-
self.setTreeWidth(Math.max(50, self.treeAreaWidth - self.labelsWidth - 10 - self.marginLeft));
|
|
1783
|
-
}
|
|
1677
|
+
addDisposer(self, autorun(() => {
|
|
1678
|
+
self.setTreeWidth(Math.max(50, self.treeAreaWidth - self.labelsWidth - 10 - self.marginLeft));
|
|
1784
1679
|
}));
|
|
1785
1680
|
},
|
|
1786
1681
|
}))
|
|
@@ -1788,15 +1683,38 @@ function stateModelFactory() {
|
|
|
1788
1683
|
const snap = result;
|
|
1789
1684
|
const { data: { tree, msa, treeMetadata },
|
|
1790
1685
|
// Main model properties
|
|
1791
|
-
showDomains, hideGaps, allowedGappyness,
|
|
1686
|
+
showDomains, hideGaps, allowedGappyness, subFeatureRows, drawMsaLetters, height, rowHeight, scrollY, scrollX, colWidth, currentAlignment, collapsed, showOnly, turnedOffTracks, featureFilters, relativeTo,
|
|
1792
1687
|
// MSA model properties
|
|
1793
1688
|
bgColor, colorSchemeName,
|
|
1794
1689
|
// Tree model properties
|
|
1795
|
-
drawLabels, labelsAlignRight, treeAreaWidth, treeWidth,
|
|
1690
|
+
drawLabels, labelsAlignRight, treeAreaWidth, treeWidth, showBranchLen, drawTree, drawNodeBubbles,
|
|
1796
1691
|
// Always include
|
|
1797
1692
|
...rest } = snap;
|
|
1798
|
-
|
|
1799
|
-
|
|
1693
|
+
const defaults = {
|
|
1694
|
+
showDomains: defaultShowDomains,
|
|
1695
|
+
hideGaps: defaultHideGaps,
|
|
1696
|
+
allowedGappyness: defaultAllowedGappyness,
|
|
1697
|
+
subFeatureRows: defaultSubFeatureRows,
|
|
1698
|
+
drawMsaLetters: defaultDrawMsaLetters,
|
|
1699
|
+
height: defaultHeight,
|
|
1700
|
+
rowHeight: defaultRowHeight,
|
|
1701
|
+
scrollY: defaultScrollY,
|
|
1702
|
+
scrollX: defaultScrollX,
|
|
1703
|
+
colWidth: defaultColWidth,
|
|
1704
|
+
currentAlignment: defaultCurrentAlignment,
|
|
1705
|
+
bgColor: defaultBgColor,
|
|
1706
|
+
colorSchemeName: defaultColorSchemeName,
|
|
1707
|
+
drawLabels: defaultDrawLabels,
|
|
1708
|
+
labelsAlignRight: defaultLabelsAlignRight,
|
|
1709
|
+
treeAreaWidth: defaultTreeAreaWidth,
|
|
1710
|
+
treeWidth: defaultTreeWidth,
|
|
1711
|
+
showBranchLen: defaultShowBranchLen,
|
|
1712
|
+
drawTree: defaultDrawTree,
|
|
1713
|
+
drawNodeBubbles: defaultDrawNodeBubbles,
|
|
1714
|
+
};
|
|
1715
|
+
const nonDefaults = Object.fromEntries(Object.entries(defaults)
|
|
1716
|
+
.filter(([key, def]) => snap[key] !== def)
|
|
1717
|
+
.map(([key]) => [key, snap[key]]));
|
|
1800
1718
|
return {
|
|
1801
1719
|
...rest,
|
|
1802
1720
|
data: {
|
|
@@ -1804,29 +1722,9 @@ function stateModelFactory() {
|
|
|
1804
1722
|
...(result.msaFilehandle ? {} : { msa }),
|
|
1805
1723
|
...(result.treeMetadataFilehandle ? {} : { treeMetadata }),
|
|
1806
1724
|
},
|
|
1807
|
-
|
|
1808
|
-
...(showDomains !== defaultShowDomains ? { showDomains } : {}),
|
|
1809
|
-
...(hideGaps !== defaultHideGaps ? { hideGaps } : {}),
|
|
1810
|
-
...(allowedGappyness !== defaultAllowedGappyness
|
|
1811
|
-
? { allowedGappyness }
|
|
1812
|
-
: {}),
|
|
1813
|
-
...(contrastLettering !== defaultContrastLettering
|
|
1814
|
-
? { contrastLettering }
|
|
1815
|
-
: {}),
|
|
1816
|
-
...(subFeatureRows !== defaultSubFeatureRows ? { subFeatureRows } : {}),
|
|
1817
|
-
...(drawMsaLetters !== defaultDrawMsaLetters ? { drawMsaLetters } : {}),
|
|
1818
|
-
...(height !== defaultHeight ? { height } : {}),
|
|
1819
|
-
...(rowHeight !== defaultRowHeight ? { rowHeight } : {}),
|
|
1820
|
-
...(scrollY !== defaultScrollY ? { scrollY } : {}),
|
|
1821
|
-
...(scrollX !== defaultScrollX ? { scrollX } : {}),
|
|
1822
|
-
...(colWidth !== defaultColWidth ? { colWidth } : {}),
|
|
1823
|
-
...(currentAlignment !== defaultCurrentAlignment
|
|
1824
|
-
? { currentAlignment }
|
|
1825
|
-
: {}),
|
|
1725
|
+
...nonDefaults,
|
|
1826
1726
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1827
1727
|
...(collapsed?.length ? { collapsed } : {}),
|
|
1828
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1829
|
-
...(collapsedLeaves?.length ? { collapsedLeaves } : {}),
|
|
1830
1728
|
...(showOnly !== undefined ? { showOnly } : {}),
|
|
1831
1729
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1832
1730
|
...(turnedOffTracks && Object.keys(turnedOffTracks).length > 0
|
|
@@ -1837,26 +1735,6 @@ function stateModelFactory() {
|
|
|
1837
1735
|
? { featureFilters }
|
|
1838
1736
|
: {}),
|
|
1839
1737
|
...(relativeTo !== undefined ? { relativeTo } : {}),
|
|
1840
|
-
// MSA model - only include non-default values
|
|
1841
|
-
...(bgColor !== defaultBgColor ? { bgColor } : {}),
|
|
1842
|
-
...(colorSchemeName !== defaultColorSchemeName
|
|
1843
|
-
? { colorSchemeName }
|
|
1844
|
-
: {}),
|
|
1845
|
-
// Tree model - only include non-default values
|
|
1846
|
-
...(drawLabels !== defaultDrawLabels ? { drawLabels } : {}),
|
|
1847
|
-
...(labelsAlignRight !== defaultLabelsAlignRight
|
|
1848
|
-
? { labelsAlignRight }
|
|
1849
|
-
: {}),
|
|
1850
|
-
...(treeAreaWidth !== defaultTreeAreaWidth ? { treeAreaWidth } : {}),
|
|
1851
|
-
...(treeWidth !== defaultTreeWidth ? { treeWidth } : {}),
|
|
1852
|
-
...(treeWidthMatchesArea !== defaultTreeWidthMatchesArea
|
|
1853
|
-
? { treeWidthMatchesArea }
|
|
1854
|
-
: {}),
|
|
1855
|
-
...(showBranchLen !== defaultShowBranchLen ? { showBranchLen } : {}),
|
|
1856
|
-
...(drawTree !== defaultDrawTree ? { drawTree } : {}),
|
|
1857
|
-
...(drawNodeBubbles !== defaultDrawNodeBubbles
|
|
1858
|
-
? { drawNodeBubbles }
|
|
1859
|
-
: {}),
|
|
1860
1738
|
};
|
|
1861
1739
|
});
|
|
1862
1740
|
}
|