react-msaview 3.0.0 → 3.0.1
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 +31 -31
- package/dist/components/Header.js +4 -9
- package/dist/components/Header.js.map +1 -1
- package/dist/components/HeaderInfoArea.d.ts +6 -0
- package/dist/components/HeaderInfoArea.js +12 -0
- package/dist/components/HeaderInfoArea.js.map +1 -0
- package/dist/components/MSAPanel/Loading.d.ts +2 -0
- package/dist/components/MSAPanel/Loading.js +12 -0
- package/dist/components/MSAPanel/Loading.js.map +1 -0
- package/dist/components/MSAPanel/MSACanvas.js +1 -10
- package/dist/components/MSAPanel/MSACanvas.js.map +1 -1
- package/dist/components/MSAPanel/MSAMouseoverCanvas.js +1 -22
- package/dist/components/MSAPanel/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/MSAPanel/renderMSABlock.js +0 -1
- package/dist/components/MSAPanel/renderMSABlock.js.map +1 -1
- package/dist/components/MSAPanel/renderMSAMouseover.d.ts +5 -0
- package/dist/components/MSAPanel/renderMSAMouseover.js +24 -0
- package/dist/components/MSAPanel/renderMSAMouseover.js.map +1 -0
- package/dist/components/Minimap.js +13 -13
- package/dist/components/Minimap.js.map +1 -1
- package/dist/components/TreePanel/TreeCanvasBlock.js +8 -4
- package/dist/components/TreePanel/TreeCanvasBlock.js.map +1 -1
- package/dist/components/TreePanel/{TreeMenu.d.ts → TreeNodeMenu.d.ts} +1 -0
- package/dist/components/TreePanel/{TreeMenu.js → TreeNodeMenu.js} +8 -4
- package/dist/components/TreePanel/TreeNodeMenu.js.map +1 -0
- package/dist/components/TreePanel/dialogs/{TreeNodeInfoDlg.js → TreeNodeInfoDialog.js} +2 -2
- package/dist/components/TreePanel/dialogs/TreeNodeInfoDialog.js.map +1 -0
- package/dist/components/TreePanel/renderTreeCanvas.d.ts +8 -3
- package/dist/components/TreePanel/renderTreeCanvas.js +8 -7
- package/dist/components/TreePanel/renderTreeCanvas.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.js +31 -22
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/model.d.ts +120 -62
- package/dist/model.js +176 -124
- package/dist/model.js.map +1 -1
- package/dist/parsers/ClustalMSA.d.ts +1 -1
- package/dist/parsers/ClustalMSA.js +1 -1
- package/dist/parsers/ClustalMSA.js.map +1 -1
- package/dist/parsers/FastaMSA.d.ts +1 -1
- package/dist/parsers/FastaMSA.js +2 -2
- package/dist/parsers/FastaMSA.js.map +1 -1
- package/dist/parsers/StockholmMSA.d.ts +1 -1
- package/dist/parsers/StockholmMSA.js +2 -2
- package/dist/parsers/StockholmMSA.js.map +1 -1
- package/dist/util.d.ts +1 -0
- package/dist/util.js +15 -7
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/components/Header.tsx +5 -11
- package/src/components/HeaderInfoArea.tsx +21 -0
- package/src/components/MSAPanel/Loading.tsx +16 -0
- package/src/components/MSAPanel/MSACanvas.tsx +1 -16
- package/src/components/MSAPanel/MSAMouseoverCanvas.tsx +2 -50
- package/src/components/MSAPanel/renderMSABlock.ts +0 -2
- package/src/components/MSAPanel/renderMSAMouseover.ts +51 -0
- package/src/components/Minimap.tsx +15 -15
- package/src/components/TreePanel/TreeCanvasBlock.tsx +8 -3
- package/src/components/TreePanel/{TreeMenu.tsx → TreeNodeMenu.tsx} +12 -3
- package/src/components/TreePanel/dialogs/{TreeNodeInfoDlg.tsx → TreeNodeInfoDialog.tsx} +1 -1
- package/src/components/TreePanel/renderTreeCanvas.ts +13 -4
- package/src/components/dialogs/SettingsDialog.tsx +61 -44
- package/src/model.ts +279 -154
- package/src/parsers/ClustalMSA.ts +1 -1
- package/src/parsers/FastaMSA.ts +1 -1
- package/src/parsers/StockholmMSA.ts +1 -1
- package/src/util.ts +19 -6
- package/src/version.ts +1 -1
- package/dist/components/OverviewRubberband.d.ts +0 -8
- package/dist/components/OverviewRubberband.js +0 -185
- package/dist/components/OverviewRubberband.js.map +0 -1
- package/dist/components/Rubberband.d.ts +0 -8
- package/dist/components/Rubberband.js +0 -185
- package/dist/components/Rubberband.js.map +0 -1
- package/dist/components/TreePanel/TreeMenu.js.map +0 -1
- package/dist/components/TreePanel/dialogs/TreeNodeInfoDlg.js.map +0 -1
- package/dist/components/dialogs/AnnotationDialog.d.ts +0 -11
- package/dist/components/dialogs/AnnotationDialog.js +0 -65
- package/dist/components/dialogs/AnnotationDialog.js.map +0 -1
- package/src/components/OverviewRubberband.tsx +0 -283
- package/src/components/Rubberband.tsx +0 -283
- package/src/components/dialogs/AnnotationDialog.tsx +0 -144
- /package/dist/components/TreePanel/dialogs/{TreeNodeInfoDlg.d.ts → TreeNodeInfoDialog.d.ts} +0 -0
package/dist/model.js
CHANGED
|
@@ -2,13 +2,14 @@ import { autorun } from 'mobx';
|
|
|
2
2
|
import { cast, types, addDisposer } from 'mobx-state-tree';
|
|
3
3
|
import { hierarchy, cluster } from 'd3-hierarchy';
|
|
4
4
|
import { ascending } from 'd3-array';
|
|
5
|
+
import Stockholm from 'stockholm-js';
|
|
6
|
+
// jbrowse
|
|
5
7
|
import { FileLocation, ElementId } from '@jbrowse/core/util/types/mst';
|
|
6
8
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
7
|
-
import { measureText, sum } from '@jbrowse/core/util';
|
|
9
|
+
import { measureText, notEmpty, sum } from '@jbrowse/core/util';
|
|
8
10
|
import BaseViewModel from '@jbrowse/core/pluggableElementTypes/models/BaseViewModel';
|
|
9
|
-
import Stockholm from 'stockholm-js';
|
|
10
11
|
// locals
|
|
11
|
-
import { collapse, generateNodeIds, maxLength, setBrLength, skipBlanks,
|
|
12
|
+
import { clamp, collapse, filterHiddenLeafNodes, generateNodeIds, maxLength, setBrLength, skipBlanks, } from './util';
|
|
12
13
|
import TextTrack from './components/TextTrack';
|
|
13
14
|
import BoxTrack from './components/BoxTrack';
|
|
14
15
|
import ClustalMSA from './parsers/ClustalMSA';
|
|
@@ -21,140 +22,157 @@ import { StructureModel } from './StructureModel';
|
|
|
21
22
|
import { DialogQueueSessionMixin } from './DialogQueue';
|
|
22
23
|
/**
|
|
23
24
|
* #stateModel MsaView
|
|
25
|
+
* extends
|
|
26
|
+
* - BaseViewModel
|
|
27
|
+
* - DialogQueueSessionMixin
|
|
24
28
|
*/
|
|
25
29
|
function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
26
30
|
const model = types
|
|
27
31
|
.compose(BaseViewModel, DialogQueueSessionMixin(), types.model('MsaView', {
|
|
28
32
|
/**
|
|
29
33
|
* #property
|
|
34
|
+
* id of view, randomly generated if not provided
|
|
30
35
|
*/
|
|
31
36
|
id: ElementId,
|
|
32
37
|
/**
|
|
33
38
|
* #property
|
|
39
|
+
* hardcoded view type
|
|
34
40
|
*/
|
|
35
41
|
type: types.literal('MsaView'),
|
|
36
42
|
/**
|
|
37
43
|
* #property
|
|
44
|
+
* height of the div containing the view, px
|
|
38
45
|
*/
|
|
39
46
|
height: types.optional(types.number, 550),
|
|
40
47
|
/**
|
|
41
48
|
* #property
|
|
49
|
+
* width of the area the tree is drawn in, px
|
|
42
50
|
*/
|
|
43
51
|
treeAreaWidth: types.optional(types.number, 400),
|
|
44
52
|
/**
|
|
45
53
|
* #property
|
|
54
|
+
* width of the tree within the treeArea, px
|
|
46
55
|
*/
|
|
47
56
|
treeWidth: types.optional(types.number, 300),
|
|
48
57
|
/**
|
|
49
58
|
* #getter
|
|
59
|
+
* synchronization that matches treeWidth to treeAreaWidth
|
|
50
60
|
*/
|
|
51
61
|
treeWidthMatchesArea: true,
|
|
52
62
|
/**
|
|
53
63
|
* #property
|
|
64
|
+
* height of each row, px
|
|
54
65
|
*/
|
|
55
66
|
rowHeight: 20,
|
|
56
67
|
/**
|
|
57
68
|
* #property
|
|
69
|
+
* scroll position, Y-offset, px
|
|
58
70
|
*/
|
|
59
71
|
scrollY: 0,
|
|
60
72
|
/**
|
|
61
73
|
* #property
|
|
74
|
+
* scroll position, X-offset, px
|
|
62
75
|
*/
|
|
63
76
|
scrollX: 0,
|
|
64
77
|
/**
|
|
65
78
|
* #property
|
|
66
|
-
|
|
67
|
-
resizeHandleWidth: 5,
|
|
68
|
-
/**
|
|
69
|
-
* #property
|
|
70
|
-
*/
|
|
71
|
-
blockSize: 1000,
|
|
72
|
-
/**
|
|
73
|
-
* #property
|
|
74
|
-
*/
|
|
75
|
-
mouseRow: types.maybe(types.number),
|
|
76
|
-
/**
|
|
77
|
-
* #property
|
|
78
|
-
*/
|
|
79
|
-
mouseCol: types.maybe(types.number),
|
|
80
|
-
/**
|
|
81
|
-
* #property
|
|
79
|
+
* currently "selected" structures, generally PDB 3-D protein structures
|
|
82
80
|
*/
|
|
83
81
|
selectedStructures: types.array(StructureModel),
|
|
84
82
|
/**
|
|
85
83
|
* #property
|
|
84
|
+
* right-align the labels
|
|
86
85
|
*/
|
|
87
86
|
labelsAlignRight: false,
|
|
88
87
|
/**
|
|
89
88
|
* #property
|
|
89
|
+
* width of columns, px
|
|
90
90
|
*/
|
|
91
91
|
colWidth: 16,
|
|
92
92
|
/**
|
|
93
93
|
* #property
|
|
94
|
+
* use "branch length" e.g. evolutionary distance to draw tree branch
|
|
95
|
+
* lengths. if false, the layout is a "cladogram" that does not take into
|
|
96
|
+
* account evolutionary distances
|
|
94
97
|
*/
|
|
95
98
|
showBranchLen: true,
|
|
96
99
|
/**
|
|
97
100
|
* #property
|
|
101
|
+
* draw MSA tiles with a background color
|
|
98
102
|
*/
|
|
99
103
|
bgColor: true,
|
|
100
104
|
/**
|
|
101
105
|
* #property
|
|
106
|
+
* draw tree, boolean
|
|
102
107
|
*/
|
|
103
108
|
drawTree: true,
|
|
104
109
|
/**
|
|
105
110
|
* #property
|
|
111
|
+
* draw clickable node bubbles on the tree
|
|
106
112
|
*/
|
|
107
113
|
drawNodeBubbles: true,
|
|
108
114
|
/**
|
|
109
115
|
* #property
|
|
116
|
+
* high resolution scale factor, helps make canvas look better on hi-dpi
|
|
117
|
+
* screens
|
|
110
118
|
*/
|
|
111
119
|
highResScaleFactor: 2,
|
|
112
120
|
/**
|
|
113
121
|
* #property
|
|
122
|
+
* default color scheme name
|
|
114
123
|
*/
|
|
115
124
|
colorSchemeName: 'maeditor',
|
|
116
125
|
/**
|
|
117
126
|
* #property
|
|
127
|
+
* filehandle object for the tree
|
|
118
128
|
*/
|
|
119
129
|
treeFilehandle: types.maybe(FileLocation),
|
|
120
130
|
/**
|
|
121
131
|
* #property
|
|
132
|
+
* filehandle object for the MSA (which could contain a tree e.g. with
|
|
133
|
+
* stockholm files)
|
|
122
134
|
*/
|
|
123
135
|
msaFilehandle: types.maybe(FileLocation),
|
|
124
136
|
/**
|
|
125
137
|
* #property
|
|
138
|
+
* filehandle object for tree metadata
|
|
126
139
|
*/
|
|
127
140
|
treeMetadataFilehandle: types.maybe(FileLocation),
|
|
128
141
|
/**
|
|
129
142
|
* #property
|
|
143
|
+
*
|
|
130
144
|
*/
|
|
131
145
|
currentAlignment: 0,
|
|
132
146
|
/**
|
|
133
147
|
* #property
|
|
148
|
+
* array of tree nodes that are 'collapsed'
|
|
134
149
|
*/
|
|
135
150
|
collapsed: types.array(types.string),
|
|
136
151
|
/**
|
|
137
152
|
* #property
|
|
153
|
+
* array of leaf nodes that are 'hidden', similar to collapsed but for leaf nodes
|
|
138
154
|
*/
|
|
139
|
-
|
|
155
|
+
hidden: types.array(types.string),
|
|
140
156
|
/**
|
|
141
157
|
* #property
|
|
158
|
+
* focus on particular subtree
|
|
142
159
|
*/
|
|
143
|
-
|
|
160
|
+
showOnly: types.maybe(types.string),
|
|
144
161
|
/**
|
|
145
162
|
* #property
|
|
163
|
+
* a list of "tracks" to display, as box-like glyphs (e.g. protein
|
|
164
|
+
* domains)
|
|
146
165
|
*/
|
|
147
|
-
|
|
166
|
+
boxTracks: types.array(UniprotTrack),
|
|
148
167
|
/**
|
|
149
168
|
* #property
|
|
169
|
+
* turned off tracks
|
|
150
170
|
*/
|
|
151
|
-
|
|
152
|
-
start: types.number,
|
|
153
|
-
end: types.number,
|
|
154
|
-
attributes: types.frozen(),
|
|
155
|
-
})),
|
|
171
|
+
turnedOffTracks: types.map(types.boolean),
|
|
156
172
|
/**
|
|
157
173
|
* #property
|
|
174
|
+
* data from the loaded tree/msa/treeMetadata, generally loaded by
|
|
175
|
+
* autorun
|
|
158
176
|
*/
|
|
159
177
|
data: types.optional(types
|
|
160
178
|
.model({
|
|
@@ -175,6 +193,26 @@ const model = types
|
|
|
175
193
|
})), { tree: '', msa: '' }),
|
|
176
194
|
}))
|
|
177
195
|
.volatile(() => ({
|
|
196
|
+
/**
|
|
197
|
+
* #volatile
|
|
198
|
+
* resize handle width between tree and msa area, px
|
|
199
|
+
*/
|
|
200
|
+
resizeHandleWidth: 5,
|
|
201
|
+
/**
|
|
202
|
+
* #volatile
|
|
203
|
+
* size of blocks of content to be drawn, px
|
|
204
|
+
*/
|
|
205
|
+
blockSize: 1000,
|
|
206
|
+
/**
|
|
207
|
+
* #volatile
|
|
208
|
+
* the currently mouse-hovered row
|
|
209
|
+
*/
|
|
210
|
+
mouseRow: undefined,
|
|
211
|
+
/**
|
|
212
|
+
* #volatile
|
|
213
|
+
* the currently mouse-hovered column
|
|
214
|
+
*/
|
|
215
|
+
mouseCol: undefined,
|
|
178
216
|
/**
|
|
179
217
|
* #volatile
|
|
180
218
|
* a dummy variable that is incremented when ref changes so autorun for
|
|
@@ -204,18 +242,21 @@ const model = types
|
|
|
204
242
|
.actions(self => ({
|
|
205
243
|
/**
|
|
206
244
|
* #action
|
|
245
|
+
* set the height of the view in px
|
|
207
246
|
*/
|
|
208
247
|
setHeight(height) {
|
|
209
248
|
self.height = height;
|
|
210
249
|
},
|
|
211
250
|
/**
|
|
212
251
|
* #action
|
|
252
|
+
* add to the selected structures
|
|
213
253
|
*/
|
|
214
254
|
addStructureToSelection(elt) {
|
|
215
255
|
self.selectedStructures.push(elt);
|
|
216
256
|
},
|
|
217
257
|
/**
|
|
218
258
|
* #action
|
|
259
|
+
* remove from the selected structures
|
|
219
260
|
*/
|
|
220
261
|
removeStructureFromSelection(elt) {
|
|
221
262
|
const r = self.selectedStructures.find(node => node.id === elt.id);
|
|
@@ -225,6 +266,7 @@ const model = types
|
|
|
225
266
|
},
|
|
226
267
|
/**
|
|
227
268
|
* #action
|
|
269
|
+
* toggle a structure from the selected structures list
|
|
228
270
|
*/
|
|
229
271
|
toggleStructureSelection(elt) {
|
|
230
272
|
const r = self.selectedStructures.find(node => node.id === elt.id);
|
|
@@ -237,18 +279,21 @@ const model = types
|
|
|
237
279
|
},
|
|
238
280
|
/**
|
|
239
281
|
* #action
|
|
282
|
+
* clear all selected structures
|
|
240
283
|
*/
|
|
241
284
|
clearSelectedStructures() {
|
|
242
285
|
self.selectedStructures = cast([]);
|
|
243
286
|
},
|
|
244
287
|
/**
|
|
245
288
|
* #action
|
|
289
|
+
* set error state
|
|
246
290
|
*/
|
|
247
291
|
setError(error) {
|
|
248
292
|
self.error = error;
|
|
249
293
|
},
|
|
250
294
|
/**
|
|
251
295
|
* #action
|
|
296
|
+
* set mouse position (row, column) in the MSA
|
|
252
297
|
*/
|
|
253
298
|
setMousePos(col, row) {
|
|
254
299
|
self.mouseCol = col;
|
|
@@ -256,48 +301,56 @@ const model = types
|
|
|
256
301
|
},
|
|
257
302
|
/**
|
|
258
303
|
* #action
|
|
304
|
+
* set row height (px)
|
|
259
305
|
*/
|
|
260
306
|
setRowHeight(n) {
|
|
261
307
|
self.rowHeight = n;
|
|
262
308
|
},
|
|
263
309
|
/**
|
|
264
310
|
* #action
|
|
311
|
+
* set col width (px)
|
|
265
312
|
*/
|
|
266
313
|
setColWidth(n) {
|
|
267
314
|
self.colWidth = n;
|
|
268
315
|
},
|
|
269
316
|
/**
|
|
270
317
|
* #action
|
|
318
|
+
* set color scheme name
|
|
271
319
|
*/
|
|
272
320
|
setColorSchemeName(name) {
|
|
273
321
|
self.colorSchemeName = name;
|
|
274
322
|
},
|
|
275
323
|
/**
|
|
276
324
|
* #action
|
|
325
|
+
* synchronize the treewidth and treeareawidth
|
|
277
326
|
*/
|
|
278
327
|
setTreeWidthMatchesArea(arg) {
|
|
279
328
|
self.treeWidthMatchesArea = arg;
|
|
280
329
|
},
|
|
281
330
|
/**
|
|
282
331
|
* #action
|
|
332
|
+
* set scroll Y-offset (px)
|
|
283
333
|
*/
|
|
284
334
|
setScrollY(n) {
|
|
285
335
|
self.scrollY = n;
|
|
286
336
|
},
|
|
287
337
|
/**
|
|
288
338
|
* #action
|
|
339
|
+
* set tree area width (px)
|
|
289
340
|
*/
|
|
290
341
|
setTreeAreaWidth(n) {
|
|
291
342
|
self.treeAreaWidth = n;
|
|
292
343
|
},
|
|
293
344
|
/**
|
|
294
345
|
* #action
|
|
346
|
+
* set tree width (px)
|
|
295
347
|
*/
|
|
296
348
|
setTreeWidth(n) {
|
|
297
349
|
self.treeWidth = n;
|
|
298
350
|
},
|
|
299
351
|
/**
|
|
300
352
|
* #action
|
|
353
|
+
*
|
|
301
354
|
*/
|
|
302
355
|
setCurrentAlignment(n) {
|
|
303
356
|
self.currentAlignment = n;
|
|
@@ -314,6 +367,18 @@ const model = types
|
|
|
314
367
|
setDrawTree(arg) {
|
|
315
368
|
self.drawTree = arg;
|
|
316
369
|
},
|
|
370
|
+
/**
|
|
371
|
+
* #action
|
|
372
|
+
*/
|
|
373
|
+
hideNode(arg) {
|
|
374
|
+
self.hidden.push(arg);
|
|
375
|
+
},
|
|
376
|
+
/**
|
|
377
|
+
* #action
|
|
378
|
+
*/
|
|
379
|
+
clearHidden() {
|
|
380
|
+
self.hidden.clear();
|
|
381
|
+
},
|
|
317
382
|
/**
|
|
318
383
|
* #action
|
|
319
384
|
*/
|
|
@@ -482,7 +547,12 @@ const model = types
|
|
|
482
547
|
const matches = name.match(/\S+\/(\d+)-(\d+)/);
|
|
483
548
|
return {
|
|
484
549
|
data: ((_a = this.MSA) === null || _a === void 0 ? void 0 : _a.getRowData(name)) || {},
|
|
485
|
-
...(matches && {
|
|
550
|
+
...(matches && {
|
|
551
|
+
range: {
|
|
552
|
+
start: +matches[1],
|
|
553
|
+
end: +matches[2],
|
|
554
|
+
},
|
|
555
|
+
}),
|
|
486
556
|
};
|
|
487
557
|
},
|
|
488
558
|
/**
|
|
@@ -502,7 +572,7 @@ const model = types
|
|
|
502
572
|
* #getter
|
|
503
573
|
*/
|
|
504
574
|
get noTree() {
|
|
505
|
-
return !!this.
|
|
575
|
+
return !!this._tree.noTree;
|
|
506
576
|
},
|
|
507
577
|
/**
|
|
508
578
|
* #getter
|
|
@@ -544,7 +614,7 @@ const model = types
|
|
|
544
614
|
/**
|
|
545
615
|
* #getter
|
|
546
616
|
*/
|
|
547
|
-
get
|
|
617
|
+
get _tree() {
|
|
548
618
|
var _a;
|
|
549
619
|
return self.data.tree
|
|
550
620
|
? generateNodeIds(parseNewick(self.data.tree))
|
|
@@ -563,7 +633,8 @@ const model = types
|
|
|
563
633
|
},
|
|
564
634
|
/**
|
|
565
635
|
* #getter
|
|
566
|
-
*/
|
|
636
|
+
*/
|
|
637
|
+
get mouseOverRowName() {
|
|
567
638
|
return self.mouseRow !== undefined
|
|
568
639
|
? this.rowNames[self.mouseRow]
|
|
569
640
|
: undefined;
|
|
@@ -578,7 +649,7 @@ const model = types
|
|
|
578
649
|
* #getter
|
|
579
650
|
*/
|
|
580
651
|
get root() {
|
|
581
|
-
let hier = hierarchy(this.
|
|
652
|
+
let hier = hierarchy(this._tree, d => d.branchset)
|
|
582
653
|
.sum(d => (d.branchset ? 0 : 1))
|
|
583
654
|
.sort((a, b) => ascending(a.data.length || 1, b.data.length || 1));
|
|
584
655
|
if (self.showOnly) {
|
|
@@ -590,9 +661,15 @@ const model = types
|
|
|
590
661
|
if (self.collapsed.length) {
|
|
591
662
|
self.collapsed
|
|
592
663
|
.map(collapsedId => hier.find(node => node.data.id === collapsedId))
|
|
593
|
-
.filter(
|
|
664
|
+
.filter(notEmpty)
|
|
594
665
|
.map(node => collapse(node));
|
|
595
666
|
}
|
|
667
|
+
if (self.hidden.length) {
|
|
668
|
+
self.hidden
|
|
669
|
+
.map(hiddenId => hier.find(node => node.data.id === hiddenId))
|
|
670
|
+
.filter(notEmpty)
|
|
671
|
+
.map(node => filterHiddenLeafNodes(node.parent, node.id));
|
|
672
|
+
}
|
|
596
673
|
return hier;
|
|
597
674
|
},
|
|
598
675
|
/**
|
|
@@ -610,6 +687,7 @@ const model = types
|
|
|
610
687
|
},
|
|
611
688
|
/**
|
|
612
689
|
* #getter
|
|
690
|
+
* widget width minus the tree area gives the space for the MSA
|
|
613
691
|
*/
|
|
614
692
|
get msaAreaWidth() {
|
|
615
693
|
return self.width - self.treeAreaWidth;
|
|
@@ -622,7 +700,7 @@ const model = types
|
|
|
622
700
|
const blanks = [];
|
|
623
701
|
const strs = this.hierarchy
|
|
624
702
|
.leaves()
|
|
625
|
-
.map(
|
|
703
|
+
.map(leaf => { var _a; return (_a = this.MSA) === null || _a === void 0 ? void 0 : _a.getRow(leaf.data.name); })
|
|
626
704
|
.filter((item) => !!item);
|
|
627
705
|
for (let i = 0; i < ((_a = strs[0]) === null || _a === void 0 ? void 0 : _a.length); i++) {
|
|
628
706
|
let counter = 0;
|
|
@@ -641,9 +719,10 @@ const model = types
|
|
|
641
719
|
* #getter
|
|
642
720
|
*/
|
|
643
721
|
get rows() {
|
|
722
|
+
const MSA = this.MSA;
|
|
644
723
|
return this.hierarchy
|
|
645
724
|
.leaves()
|
|
646
|
-
.map(
|
|
725
|
+
.map(leaf => [leaf.data.name, MSA === null || MSA === void 0 ? void 0 : MSA.getRow(leaf.data.name)])
|
|
647
726
|
.filter((f) => !!f[1]);
|
|
648
727
|
},
|
|
649
728
|
/**
|
|
@@ -687,13 +766,13 @@ const model = types
|
|
|
687
766
|
* generates a new tree that is clustered with x,y positions
|
|
688
767
|
*/
|
|
689
768
|
get hierarchy() {
|
|
690
|
-
const
|
|
769
|
+
const r = this.root;
|
|
691
770
|
const clust = cluster()
|
|
692
771
|
.size([this.totalHeight, self.treeWidth])
|
|
693
772
|
.separation(() => 1);
|
|
694
|
-
clust(
|
|
695
|
-
setBrLength(
|
|
696
|
-
return
|
|
773
|
+
clust(r);
|
|
774
|
+
setBrLength(r, (r.data.length = 0), self.treeWidth / maxLength(r));
|
|
775
|
+
return r;
|
|
697
776
|
},
|
|
698
777
|
/**
|
|
699
778
|
* #getter
|
|
@@ -781,9 +860,7 @@ const model = types
|
|
|
781
860
|
const { rowHeight, hierarchy, treeMetadata, fontSize } = self;
|
|
782
861
|
if (rowHeight > 5) {
|
|
783
862
|
for (const node of hierarchy.leaves()) {
|
|
784
|
-
|
|
785
|
-
const displayName = ((_a = treeMetadata[name]) === null || _a === void 0 ? void 0 : _a.genome) || name;
|
|
786
|
-
x = Math.max(measureText(displayName, fontSize), x);
|
|
863
|
+
x = Math.max(measureText(((_a = treeMetadata[node.data.name]) === null || _a === void 0 ? void 0 : _a.genome) || node.data.name, fontSize), x);
|
|
787
864
|
}
|
|
788
865
|
}
|
|
789
866
|
return x;
|
|
@@ -819,62 +896,33 @@ const model = types
|
|
|
819
896
|
/**
|
|
820
897
|
* #getter
|
|
821
898
|
*/
|
|
822
|
-
get
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
.filter(track => !!self.rows.some(row => row[0] === track.name))
|
|
899
|
+
get adapterTrackModels() {
|
|
900
|
+
var _a;
|
|
901
|
+
return (((_a = self.MSA) === null || _a === void 0 ? void 0 : _a.tracks.map(t => ({
|
|
902
|
+
model: {
|
|
903
|
+
...t,
|
|
904
|
+
data: t.data ? skipBlanks(self.blanks, t.data) : undefined,
|
|
905
|
+
height: self.rowHeight,
|
|
906
|
+
},
|
|
907
|
+
ReactComponent: TextTrack,
|
|
908
|
+
}))) || []);
|
|
909
|
+
},
|
|
910
|
+
/**
|
|
911
|
+
* #getter
|
|
912
|
+
*/
|
|
913
|
+
get boxTrackModels() {
|
|
914
|
+
return self.boxTracks
|
|
915
|
+
.filter(track => self.rows.some(row => row[0] === track.name))
|
|
840
916
|
.map(track => ({
|
|
841
917
|
model: track,
|
|
842
918
|
ReactComponent: BoxTrack,
|
|
843
919
|
}));
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
id: 'annotations',
|
|
851
|
-
name: 'User-created annotations',
|
|
852
|
-
data: self.annotatedRegions
|
|
853
|
-
.map(region => {
|
|
854
|
-
const attrs = region.attributes
|
|
855
|
-
? Object.entries(region.attributes)
|
|
856
|
-
.map(([k, v]) => `${k}=${v.join(',')}`)
|
|
857
|
-
.join(';')
|
|
858
|
-
: '.';
|
|
859
|
-
return [
|
|
860
|
-
'MSA_refcoord',
|
|
861
|
-
'.',
|
|
862
|
-
'.',
|
|
863
|
-
region.start,
|
|
864
|
-
region.end,
|
|
865
|
-
'.',
|
|
866
|
-
'.',
|
|
867
|
-
'.',
|
|
868
|
-
attrs,
|
|
869
|
-
].join('\t');
|
|
870
|
-
})
|
|
871
|
-
.join('\n'),
|
|
872
|
-
},
|
|
873
|
-
ReactComponent: BoxTrack,
|
|
874
|
-
},
|
|
875
|
-
]
|
|
876
|
-
: [];
|
|
877
|
-
return [...adapterTracks, ...boxTracks, ...annotationTracks];
|
|
920
|
+
},
|
|
921
|
+
/**
|
|
922
|
+
* #getter
|
|
923
|
+
*/
|
|
924
|
+
get tracks() {
|
|
925
|
+
return [...this.adapterTrackModels, ...this.boxTrackModels];
|
|
878
926
|
},
|
|
879
927
|
/**
|
|
880
928
|
* #getter
|
|
@@ -954,6 +1002,28 @@ const model = types
|
|
|
954
1002
|
}
|
|
955
1003
|
return 0;
|
|
956
1004
|
},
|
|
1005
|
+
/**
|
|
1006
|
+
* #method
|
|
1007
|
+
*/
|
|
1008
|
+
relativePxToBp2(rowName, position) {
|
|
1009
|
+
const { rowNames, rows } = self;
|
|
1010
|
+
const index = rowNames.indexOf(rowName);
|
|
1011
|
+
if (index !== -1) {
|
|
1012
|
+
const row = rows[index][1];
|
|
1013
|
+
let k = 0;
|
|
1014
|
+
let i = 0;
|
|
1015
|
+
for (; k < position; i++) {
|
|
1016
|
+
if (row[i] !== '-') {
|
|
1017
|
+
k++;
|
|
1018
|
+
}
|
|
1019
|
+
else if (k >= position) {
|
|
1020
|
+
break;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
return i;
|
|
1024
|
+
}
|
|
1025
|
+
return 0;
|
|
1026
|
+
},
|
|
957
1027
|
/**
|
|
958
1028
|
* #method
|
|
959
1029
|
*/
|
|
@@ -967,47 +1037,26 @@ const model = types
|
|
|
967
1037
|
}
|
|
968
1038
|
return j;
|
|
969
1039
|
},
|
|
970
|
-
}))
|
|
971
|
-
.actions(self => ({
|
|
972
|
-
/**
|
|
973
|
-
* #action
|
|
974
|
-
*/
|
|
975
|
-
addAnnotation(start, end, attributes) {
|
|
976
|
-
self.annotatedRegions.push({
|
|
977
|
-
start: self.getPos(start),
|
|
978
|
-
end: self.getPos(end),
|
|
979
|
-
attributes,
|
|
980
|
-
});
|
|
981
|
-
},
|
|
982
|
-
/**
|
|
983
|
-
* #action
|
|
984
|
-
*/
|
|
985
|
-
setAnnotationClickBoundaries(left, right) {
|
|
986
|
-
self.annotPos = { left, right };
|
|
987
|
-
},
|
|
988
|
-
/**
|
|
989
|
-
* #action
|
|
990
|
-
*/
|
|
991
|
-
clearAnnotationClickBoundaries() {
|
|
992
|
-
self.annotPos = undefined;
|
|
993
|
-
},
|
|
994
|
-
/**
|
|
995
|
-
* #action
|
|
996
|
-
*/
|
|
997
|
-
incrementRef() {
|
|
998
|
-
self.nref++;
|
|
999
|
-
},
|
|
1000
1040
|
}))
|
|
1001
1041
|
.views(self => ({
|
|
1002
1042
|
/**
|
|
1003
1043
|
* #getter
|
|
1044
|
+
* total height of track area (px)
|
|
1004
1045
|
*/
|
|
1005
1046
|
get totalTrackAreaHeight() {
|
|
1006
1047
|
return sum(self.turnedOnTracks.map(r => r.model.height));
|
|
1007
1048
|
},
|
|
1008
1049
|
}))
|
|
1009
1050
|
.actions(self => ({
|
|
1051
|
+
/**
|
|
1052
|
+
* #action
|
|
1053
|
+
* internal, used for drawing to canvas
|
|
1054
|
+
*/
|
|
1055
|
+
incrementRef() {
|
|
1056
|
+
self.nref++;
|
|
1057
|
+
},
|
|
1010
1058
|
afterCreate() {
|
|
1059
|
+
// autorun opens treeFilehandle
|
|
1011
1060
|
addDisposer(self, autorun(async () => {
|
|
1012
1061
|
const { treeFilehandle } = self;
|
|
1013
1062
|
if (treeFilehandle) {
|
|
@@ -1020,6 +1069,7 @@ const model = types
|
|
|
1020
1069
|
}
|
|
1021
1070
|
}
|
|
1022
1071
|
}));
|
|
1072
|
+
// autorun opens treeMetadataFilehandle
|
|
1023
1073
|
addDisposer(self, autorun(async () => {
|
|
1024
1074
|
const { treeMetadataFilehandle } = self;
|
|
1025
1075
|
if (treeMetadataFilehandle) {
|
|
@@ -1032,6 +1082,7 @@ const model = types
|
|
|
1032
1082
|
}
|
|
1033
1083
|
}
|
|
1034
1084
|
}));
|
|
1085
|
+
// autorun opens msaFilehandle
|
|
1035
1086
|
addDisposer(self, autorun(async () => {
|
|
1036
1087
|
const { msaFilehandle } = self;
|
|
1037
1088
|
if (msaFilehandle) {
|
|
@@ -1044,6 +1095,7 @@ const model = types
|
|
|
1044
1095
|
}
|
|
1045
1096
|
}
|
|
1046
1097
|
}));
|
|
1098
|
+
// autorun synchronizes treeWidth with treeAreaWidth
|
|
1047
1099
|
addDisposer(self, autorun(async () => {
|
|
1048
1100
|
if (self.treeWidthMatchesArea) {
|
|
1049
1101
|
self.setTreeWidth(Math.max(50, self.treeAreaWidth - self.labelsWidth - 20));
|