react-msaview 5.0.7 → 5.0.16
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 +135 -35
- package/bundle/index.js.LICENSE.txt +1 -1
- 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/SequenceTextArea.js +4 -4
- package/dist/components/SequenceTextArea.js.map +1 -1
- 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 +22 -20
- 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 +55 -22
- 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 +29 -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 +118 -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/SequenceTextArea.tsx +4 -4
- 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 +38 -35
- 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.test.ts +205 -0
- package/src/components/tree/renderTreeCanvas.ts +64 -27
- 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 +221 -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 +180 -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
|
*/
|
|
@@ -256,11 +237,8 @@ function stateModelFactory() {
|
|
|
256
237
|
/**
|
|
257
238
|
* #volatile
|
|
258
239
|
*/
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
259
241
|
error: undefined,
|
|
260
|
-
/**
|
|
261
|
-
* #volatile
|
|
262
|
-
*/
|
|
263
|
-
annotPos: undefined,
|
|
264
242
|
/**
|
|
265
243
|
* #volatile
|
|
266
244
|
*/
|
|
@@ -285,24 +263,12 @@ function stateModelFactory() {
|
|
|
285
263
|
setAllowedGappyness(arg) {
|
|
286
264
|
self.allowedGappyness = arg;
|
|
287
265
|
},
|
|
288
|
-
/**
|
|
289
|
-
* #action
|
|
290
|
-
*/
|
|
291
|
-
setContrastLettering(arg) {
|
|
292
|
-
self.contrastLettering = arg;
|
|
293
|
-
},
|
|
294
266
|
/**
|
|
295
267
|
* #action
|
|
296
268
|
*/
|
|
297
269
|
setLoadingMSA(arg) {
|
|
298
270
|
self.loadingMSA = arg;
|
|
299
271
|
},
|
|
300
|
-
/**
|
|
301
|
-
* #action
|
|
302
|
-
*/
|
|
303
|
-
setShowZoomStar(arg) {
|
|
304
|
-
self.showZoomStar = arg;
|
|
305
|
-
},
|
|
306
272
|
/**
|
|
307
273
|
* #action
|
|
308
274
|
*/
|
|
@@ -346,14 +312,12 @@ function stateModelFactory() {
|
|
|
346
312
|
self.hoveredTreeNode = undefined;
|
|
347
313
|
return;
|
|
348
314
|
}
|
|
349
|
-
|
|
350
|
-
const node = self.hierarchy.find(n => n.data.id === nodeId);
|
|
315
|
+
const node = find(self.hierarchy, n => n.data.id === nodeId);
|
|
351
316
|
if (!node) {
|
|
352
317
|
self.hoveredTreeNode = undefined;
|
|
353
318
|
return;
|
|
354
319
|
}
|
|
355
|
-
|
|
356
|
-
const descendantNames = node.leaves().map(leaf => leaf.data.name);
|
|
320
|
+
const descendantNames = leaves(node).map(leaf => leaf.data.name);
|
|
357
321
|
self.hoveredTreeNode = { nodeId, descendantNames };
|
|
358
322
|
},
|
|
359
323
|
/**
|
|
@@ -422,17 +386,6 @@ function stateModelFactory() {
|
|
|
422
386
|
self.collapsed.push(node);
|
|
423
387
|
}
|
|
424
388
|
},
|
|
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
389
|
/**
|
|
437
390
|
* #action
|
|
438
391
|
*/
|
|
@@ -489,9 +442,7 @@ function stateModelFactory() {
|
|
|
489
442
|
*/
|
|
490
443
|
get hideGapsEffective() {
|
|
491
444
|
return (self.hideGaps &&
|
|
492
|
-
(self.collapsed.length > 0 ||
|
|
493
|
-
self.collapsedLeaves.length > 0 ||
|
|
494
|
-
self.allowedGappyness < 100));
|
|
445
|
+
(self.collapsed.length > 0 || self.allowedGappyness < 100));
|
|
495
446
|
},
|
|
496
447
|
/**
|
|
497
448
|
* #getter
|
|
@@ -505,9 +456,6 @@ function stateModelFactory() {
|
|
|
505
456
|
get actuallyShowDomains() {
|
|
506
457
|
return self.showDomains && !!self.interProAnnotations;
|
|
507
458
|
},
|
|
508
|
-
/**
|
|
509
|
-
* #getter
|
|
510
|
-
*/
|
|
511
459
|
get viewInitialized() {
|
|
512
460
|
return self.volatileWidth !== undefined;
|
|
513
461
|
},
|
|
@@ -539,7 +487,7 @@ function stateModelFactory() {
|
|
|
539
487
|
* #getter
|
|
540
488
|
*/
|
|
541
489
|
get header() {
|
|
542
|
-
return this.MSA?.getHeader() || {};
|
|
490
|
+
return (this.MSA?.getHeader() || {});
|
|
543
491
|
},
|
|
544
492
|
/**
|
|
545
493
|
* #getter
|
|
@@ -553,15 +501,9 @@ function stateModelFactory() {
|
|
|
553
501
|
get noTree() {
|
|
554
502
|
return !!this.tree.noTree;
|
|
555
503
|
},
|
|
556
|
-
/**
|
|
557
|
-
* #getter
|
|
558
|
-
*/
|
|
559
504
|
get noDomains() {
|
|
560
505
|
return !self.interProAnnotations;
|
|
561
506
|
},
|
|
562
|
-
/**
|
|
563
|
-
* #getter
|
|
564
|
-
*/
|
|
565
507
|
menuItems() {
|
|
566
508
|
return [];
|
|
567
509
|
},
|
|
@@ -576,24 +518,9 @@ function stateModelFactory() {
|
|
|
576
518
|
*/
|
|
577
519
|
get MSA() {
|
|
578
520
|
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;
|
|
521
|
+
// uses parseMSA so the named MSAParserType return type is portable
|
|
522
|
+
// to downstream consumers (avoids TS2883 with default exports)
|
|
523
|
+
return text ? parseMSA(text, self.currentAlignment) : null;
|
|
597
524
|
},
|
|
598
525
|
/**
|
|
599
526
|
* #getter
|
|
@@ -606,7 +533,7 @@ function stateModelFactory() {
|
|
|
606
533
|
*/
|
|
607
534
|
get tree() {
|
|
608
535
|
const text = self.data.tree;
|
|
609
|
-
return
|
|
536
|
+
return text
|
|
610
537
|
? generateNodeIds(text.startsWith('BioTreeContainer')
|
|
611
538
|
? flatToTree(parseAsn1(text))
|
|
612
539
|
: parseNewick(text.startsWith('SEQ') ? parseEmfTree(text).tree : text))
|
|
@@ -615,7 +542,7 @@ function stateModelFactory() {
|
|
|
615
542
|
children: [],
|
|
616
543
|
id: 'empty',
|
|
617
544
|
name: 'empty',
|
|
618
|
-
}
|
|
545
|
+
};
|
|
619
546
|
},
|
|
620
547
|
/**
|
|
621
548
|
* #getter
|
|
@@ -661,25 +588,27 @@ function stateModelFactory() {
|
|
|
661
588
|
* #getter
|
|
662
589
|
*/
|
|
663
590
|
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));
|
|
591
|
+
let hier = hierarchy(this.tree, d => d.children);
|
|
592
|
+
hierarchySum(hier, d => (d.children.length > 0 ? 0 : 1));
|
|
593
|
+
sort(hier, (a, b) => (a.data.length ?? 1) - (b.data.length ?? 1));
|
|
670
594
|
if (self.showOnly) {
|
|
671
|
-
const res =
|
|
595
|
+
const res = find(hier, n => n.data.id === self.showOnly);
|
|
672
596
|
if (res) {
|
|
673
597
|
hier = res;
|
|
674
598
|
}
|
|
675
599
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
600
|
+
for (const collapsedId of self.collapsed) {
|
|
601
|
+
const node = find(hier, n => n.data.id === collapsedId);
|
|
602
|
+
if (!node) {
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
if (node.children) {
|
|
606
|
+
collapse(node);
|
|
607
|
+
}
|
|
608
|
+
else if (node.parent?.children) {
|
|
609
|
+
node.parent.children = node.parent.children.filter(c => c.data.id !== collapsedId);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
683
612
|
return hier;
|
|
684
613
|
},
|
|
685
614
|
/**
|
|
@@ -1072,30 +1001,28 @@ function stateModelFactory() {
|
|
|
1072
1001
|
*/
|
|
1073
1002
|
get hierarchy() {
|
|
1074
1003
|
const r = this.root;
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
clust(r);
|
|
1079
|
-
setBrLength(r, (r.data.length = 0), self.treeWidth / maxLength(r));
|
|
1004
|
+
clusterLayout(r, this.totalHeight, self.treeWidth);
|
|
1005
|
+
r.data.length = 0;
|
|
1006
|
+
setBrLength(r, 0, self.treeWidth / maxLength(r));
|
|
1080
1007
|
return r;
|
|
1081
1008
|
},
|
|
1082
1009
|
/**
|
|
1083
1010
|
* #getter
|
|
1084
1011
|
*/
|
|
1085
1012
|
get totalHeight() {
|
|
1086
|
-
return this.root
|
|
1013
|
+
return leaves(this.root).length * self.rowHeight;
|
|
1087
1014
|
},
|
|
1088
1015
|
/**
|
|
1089
1016
|
* #getter
|
|
1090
1017
|
*/
|
|
1091
1018
|
get leaves() {
|
|
1092
|
-
return this.hierarchy
|
|
1019
|
+
return leaves(this.hierarchy);
|
|
1093
1020
|
},
|
|
1094
1021
|
/**
|
|
1095
1022
|
* #getter
|
|
1096
1023
|
*/
|
|
1097
1024
|
get allBranchesLength0() {
|
|
1098
|
-
return this.hierarchy
|
|
1025
|
+
return links(this.hierarchy).every(s => !s.source.data.length);
|
|
1099
1026
|
},
|
|
1100
1027
|
/**
|
|
1101
1028
|
* #getter
|
|
@@ -1148,13 +1075,7 @@ function stateModelFactory() {
|
|
|
1148
1075
|
* #getter
|
|
1149
1076
|
*/
|
|
1150
1077
|
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;
|
|
1078
|
+
return self.blocksY.flatMap(by => self.blocksX.map(bx => [bx, by]));
|
|
1158
1079
|
},
|
|
1159
1080
|
/**
|
|
1160
1081
|
* #getter
|
|
@@ -1257,14 +1178,17 @@ function stateModelFactory() {
|
|
|
1257
1178
|
/**
|
|
1258
1179
|
* #action
|
|
1259
1180
|
*/
|
|
1181
|
+
doScrollY(deltaY) {
|
|
1182
|
+
self.scrollY = clamp(self.scrollY + deltaY, -self.totalHeight + 10, 0);
|
|
1183
|
+
},
|
|
1260
1184
|
setInterProAnnotations(data) {
|
|
1261
1185
|
self.interProAnnotations = data;
|
|
1262
1186
|
},
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
self.
|
|
1187
|
+
applyGFFText(gffText) {
|
|
1188
|
+
const gffRecords = parseGFF(gffText);
|
|
1189
|
+
const interProResults = gffToInterProResults(gffRecords);
|
|
1190
|
+
self.interProAnnotations = interProResults;
|
|
1191
|
+
self.setShowDomains(true);
|
|
1268
1192
|
},
|
|
1269
1193
|
/**
|
|
1270
1194
|
* #action
|
|
@@ -1301,14 +1225,11 @@ function stateModelFactory() {
|
|
|
1301
1225
|
* #getter
|
|
1302
1226
|
*/
|
|
1303
1227
|
get labelsWidth() {
|
|
1304
|
-
let x = 0;
|
|
1305
1228
|
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
|
-
}
|
|
1229
|
+
if (rowHeight <= 5) {
|
|
1230
|
+
return 0;
|
|
1310
1231
|
}
|
|
1311
|
-
return
|
|
1232
|
+
return leaves.reduce((max, node) => Math.max(max, measureTextCanvas(treeMetadata[node.data.name]?.genome || node.data.name, fontSize)), 0);
|
|
1312
1233
|
},
|
|
1313
1234
|
/**
|
|
1314
1235
|
* #getter
|
|
@@ -1327,16 +1248,19 @@ function stateModelFactory() {
|
|
|
1327
1248
|
*/
|
|
1328
1249
|
get adapterTrackModels() {
|
|
1329
1250
|
const { rowHeight, MSA, hideGapsEffective, blanks } = self;
|
|
1330
|
-
|
|
1331
|
-
|
|
1251
|
+
const tracks = (MSA?.tracks ?? []);
|
|
1252
|
+
return tracks
|
|
1253
|
+
.filter(t => !!t.data)
|
|
1332
1254
|
.map(t => ({
|
|
1333
1255
|
model: {
|
|
1334
1256
|
...t,
|
|
1335
|
-
data: hideGapsEffective
|
|
1257
|
+
data: hideGapsEffective && t.data
|
|
1258
|
+
? skipBlanks(blanks, t.data)
|
|
1259
|
+
: t.data,
|
|
1336
1260
|
height: rowHeight,
|
|
1337
1261
|
},
|
|
1338
1262
|
ReactComponent: TextTrack,
|
|
1339
|
-
}))
|
|
1263
|
+
}));
|
|
1340
1264
|
},
|
|
1341
1265
|
/**
|
|
1342
1266
|
* #getter
|
|
@@ -1500,53 +1424,30 @@ function stateModelFactory() {
|
|
|
1500
1424
|
get totalTrackAreaHeight() {
|
|
1501
1425
|
return sum(self.turnedOnTracks.map(r => r.model.height));
|
|
1502
1426
|
},
|
|
1503
|
-
/**
|
|
1504
|
-
* #getter
|
|
1505
|
-
*/
|
|
1506
1427
|
get tidyInterProAnnotationTypes() {
|
|
1507
|
-
|
|
1508
|
-
for (const annot of this.tidyInterProAnnotations) {
|
|
1509
|
-
types.set(annot.accession, annot);
|
|
1510
|
-
}
|
|
1511
|
-
return types;
|
|
1428
|
+
return new Map(this.tidyInterProAnnotations.map(annot => [annot.accession, annot]));
|
|
1512
1429
|
},
|
|
1513
|
-
/**
|
|
1514
|
-
* #getter
|
|
1515
|
-
*/
|
|
1516
1430
|
get tidyInterProAnnotations() {
|
|
1517
|
-
const ret = [];
|
|
1518
1431
|
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
|
-
}
|
|
1432
|
+
if (!interProAnnotations) {
|
|
1433
|
+
return [];
|
|
1538
1434
|
}
|
|
1539
|
-
return
|
|
1435
|
+
return Object.entries(interProAnnotations)
|
|
1436
|
+
.flatMap(([id, val]) => val.matches.flatMap(({ signature, locations }) => signature.entry
|
|
1437
|
+
? locations.map(({ start, end }) => ({
|
|
1438
|
+
id,
|
|
1439
|
+
name: signature.entry.name,
|
|
1440
|
+
accession: signature.entry.accession,
|
|
1441
|
+
description: signature.entry.description,
|
|
1442
|
+
start,
|
|
1443
|
+
end,
|
|
1444
|
+
}))
|
|
1445
|
+
: []))
|
|
1446
|
+
.toSorted((a, b) => len(b) - len(a));
|
|
1540
1447
|
},
|
|
1541
|
-
/**
|
|
1542
|
-
* #getter
|
|
1543
|
-
*/
|
|
1544
1448
|
get tidyFilteredInterProAnnotations() {
|
|
1545
1449
|
return this.tidyInterProAnnotations.filter(r => self.featureFilters.get(r.accession));
|
|
1546
1450
|
},
|
|
1547
|
-
/**
|
|
1548
|
-
* #getter
|
|
1549
|
-
*/
|
|
1550
1451
|
get tidyFilteredGatheredInterProAnnotations() {
|
|
1551
1452
|
return groupBy(this.tidyFilteredInterProAnnotations, r => r.id);
|
|
1552
1453
|
},
|
|
@@ -1566,15 +1467,9 @@ function stateModelFactory() {
|
|
|
1566
1467
|
get verticalScrollbarWidth() {
|
|
1567
1468
|
return self.showVerticalScrollbar ? 20 : 0;
|
|
1568
1469
|
},
|
|
1569
|
-
/**
|
|
1570
|
-
* #getter
|
|
1571
|
-
*/
|
|
1572
1470
|
get fillPalette() {
|
|
1573
1471
|
return createPaletteMap([...self.tidyInterProAnnotationTypes.keys()]);
|
|
1574
1472
|
},
|
|
1575
|
-
/**
|
|
1576
|
-
* #getter
|
|
1577
|
-
*/
|
|
1578
1473
|
get strokePalette() {
|
|
1579
1474
|
return Object.fromEntries(Object.entries(this.fillPalette).map(([key, val]) => [
|
|
1580
1475
|
key,
|
|
@@ -1619,6 +1514,9 @@ function stateModelFactory() {
|
|
|
1619
1514
|
self.setCurrentAlignment(0);
|
|
1620
1515
|
self.setTreeFilehandle(undefined);
|
|
1621
1516
|
self.setMSAFilehandle(undefined);
|
|
1517
|
+
self.setGFFFilehandle(undefined);
|
|
1518
|
+
self.setInterProAnnotations({});
|
|
1519
|
+
self.setShowDomains(false);
|
|
1622
1520
|
},
|
|
1623
1521
|
/**
|
|
1624
1522
|
* #action
|
|
@@ -1636,18 +1534,12 @@ function stateModelFactory() {
|
|
|
1636
1534
|
incrementRef() {
|
|
1637
1535
|
self.nref++;
|
|
1638
1536
|
},
|
|
1639
|
-
/**
|
|
1640
|
-
* #action
|
|
1641
|
-
*/
|
|
1642
1537
|
initFilter(arg) {
|
|
1643
1538
|
const ret = self.featureFilters.get(arg);
|
|
1644
1539
|
if (ret === undefined) {
|
|
1645
1540
|
self.featureFilters.set(arg, true);
|
|
1646
1541
|
}
|
|
1647
1542
|
},
|
|
1648
|
-
/**
|
|
1649
|
-
* #action
|
|
1650
|
-
*/
|
|
1651
1543
|
setFilter(arg, flag) {
|
|
1652
1544
|
self.featureFilters.set(arg, flag);
|
|
1653
1545
|
},
|
|
@@ -1680,10 +1572,6 @@ function stateModelFactory() {
|
|
|
1680
1572
|
this.initFilter(key);
|
|
1681
1573
|
}
|
|
1682
1574
|
}));
|
|
1683
|
-
// autorun saves local settings
|
|
1684
|
-
addDisposer(self, autorun(() => {
|
|
1685
|
-
localStorageSetBoolean(showZoomStarKey, self.showZoomStar);
|
|
1686
|
-
}));
|
|
1687
1575
|
// autorun opens treeFilehandle
|
|
1688
1576
|
addDisposer(self, autorun(async () => {
|
|
1689
1577
|
const { treeFilehandle } = self;
|
|
@@ -1718,16 +1606,26 @@ function stateModelFactory() {
|
|
|
1718
1606
|
}
|
|
1719
1607
|
}
|
|
1720
1608
|
}));
|
|
1609
|
+
// autorun parses inline gff text from data.gff
|
|
1610
|
+
addDisposer(self, autorun(() => {
|
|
1611
|
+
const gffText = self.data.gff;
|
|
1612
|
+
if (gffText) {
|
|
1613
|
+
try {
|
|
1614
|
+
self.applyGFFText(gffText);
|
|
1615
|
+
}
|
|
1616
|
+
catch (e) {
|
|
1617
|
+
console.error(e);
|
|
1618
|
+
self.setError(e);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
}));
|
|
1721
1622
|
// autorun opens gffFilehandle for InterProScan domains
|
|
1722
1623
|
addDisposer(self, autorun(async () => {
|
|
1723
1624
|
const { gffFilehandle } = self;
|
|
1724
1625
|
if (gffFilehandle) {
|
|
1725
1626
|
try {
|
|
1726
1627
|
const gffText = await fetchAndMaybeUnzipText(openLocation(gffFilehandle));
|
|
1727
|
-
|
|
1728
|
-
const interProResults = gffToInterProResults(gffRecords);
|
|
1729
|
-
self.setInterProAnnotations(interProResults);
|
|
1730
|
-
self.setShowDomains(true);
|
|
1628
|
+
self.applyGFFText(gffText);
|
|
1731
1629
|
if (gffFilehandle.locationType === 'BlobLocation') {
|
|
1732
1630
|
self.setGFFFilehandle(undefined);
|
|
1733
1631
|
}
|
|
@@ -1777,10 +1675,8 @@ function stateModelFactory() {
|
|
|
1777
1675
|
self.columns;
|
|
1778
1676
|
}));
|
|
1779
1677
|
// autorun synchronizes treeWidth with treeAreaWidth
|
|
1780
|
-
addDisposer(self, autorun(
|
|
1781
|
-
|
|
1782
|
-
self.setTreeWidth(Math.max(50, self.treeAreaWidth - self.labelsWidth - 10 - self.marginLeft));
|
|
1783
|
-
}
|
|
1678
|
+
addDisposer(self, autorun(() => {
|
|
1679
|
+
self.setTreeWidth(Math.max(50, self.treeAreaWidth - self.labelsWidth - 10 - self.marginLeft));
|
|
1784
1680
|
}));
|
|
1785
1681
|
},
|
|
1786
1682
|
}))
|
|
@@ -1788,15 +1684,38 @@ function stateModelFactory() {
|
|
|
1788
1684
|
const snap = result;
|
|
1789
1685
|
const { data: { tree, msa, treeMetadata },
|
|
1790
1686
|
// Main model properties
|
|
1791
|
-
showDomains, hideGaps, allowedGappyness,
|
|
1687
|
+
showDomains, hideGaps, allowedGappyness, subFeatureRows, drawMsaLetters, height, rowHeight, scrollY, scrollX, colWidth, currentAlignment, collapsed, showOnly, turnedOffTracks, featureFilters, relativeTo,
|
|
1792
1688
|
// MSA model properties
|
|
1793
1689
|
bgColor, colorSchemeName,
|
|
1794
1690
|
// Tree model properties
|
|
1795
|
-
drawLabels, labelsAlignRight, treeAreaWidth, treeWidth,
|
|
1691
|
+
drawLabels, labelsAlignRight, treeAreaWidth, treeWidth, showBranchLen, drawTree, drawNodeBubbles,
|
|
1796
1692
|
// Always include
|
|
1797
1693
|
...rest } = snap;
|
|
1798
|
-
|
|
1799
|
-
|
|
1694
|
+
const defaults = {
|
|
1695
|
+
showDomains: defaultShowDomains,
|
|
1696
|
+
hideGaps: defaultHideGaps,
|
|
1697
|
+
allowedGappyness: defaultAllowedGappyness,
|
|
1698
|
+
subFeatureRows: defaultSubFeatureRows,
|
|
1699
|
+
drawMsaLetters: defaultDrawMsaLetters,
|
|
1700
|
+
height: defaultHeight,
|
|
1701
|
+
rowHeight: defaultRowHeight,
|
|
1702
|
+
scrollY: defaultScrollY,
|
|
1703
|
+
scrollX: defaultScrollX,
|
|
1704
|
+
colWidth: defaultColWidth,
|
|
1705
|
+
currentAlignment: defaultCurrentAlignment,
|
|
1706
|
+
bgColor: defaultBgColor,
|
|
1707
|
+
colorSchemeName: defaultColorSchemeName,
|
|
1708
|
+
drawLabels: defaultDrawLabels,
|
|
1709
|
+
labelsAlignRight: defaultLabelsAlignRight,
|
|
1710
|
+
treeAreaWidth: defaultTreeAreaWidth,
|
|
1711
|
+
treeWidth: defaultTreeWidth,
|
|
1712
|
+
showBranchLen: defaultShowBranchLen,
|
|
1713
|
+
drawTree: defaultDrawTree,
|
|
1714
|
+
drawNodeBubbles: defaultDrawNodeBubbles,
|
|
1715
|
+
};
|
|
1716
|
+
const nonDefaults = Object.fromEntries(Object.entries(defaults)
|
|
1717
|
+
.filter(([key, def]) => snap[key] !== def)
|
|
1718
|
+
.map(([key]) => [key, snap[key]]));
|
|
1800
1719
|
return {
|
|
1801
1720
|
...rest,
|
|
1802
1721
|
data: {
|
|
@@ -1804,29 +1723,9 @@ function stateModelFactory() {
|
|
|
1804
1723
|
...(result.msaFilehandle ? {} : { msa }),
|
|
1805
1724
|
...(result.treeMetadataFilehandle ? {} : { treeMetadata }),
|
|
1806
1725
|
},
|
|
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
|
-
: {}),
|
|
1726
|
+
...nonDefaults,
|
|
1826
1727
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1827
1728
|
...(collapsed?.length ? { collapsed } : {}),
|
|
1828
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1829
|
-
...(collapsedLeaves?.length ? { collapsedLeaves } : {}),
|
|
1830
1729
|
...(showOnly !== undefined ? { showOnly } : {}),
|
|
1831
1730
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1832
1731
|
...(turnedOffTracks && Object.keys(turnedOffTracks).length > 0
|
|
@@ -1837,26 +1736,6 @@ function stateModelFactory() {
|
|
|
1837
1736
|
? { featureFilters }
|
|
1838
1737
|
: {}),
|
|
1839
1738
|
...(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
1739
|
};
|
|
1861
1740
|
});
|
|
1862
1741
|
}
|