react-msaview 2.1.0 → 2.1.2
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 +28 -28
- package/dist/colorSchemes.js +4 -2
- package/dist/colorSchemes.js.map +1 -1
- package/dist/components/MSAView.js +2 -4
- package/dist/components/MSAView.js.map +1 -1
- package/dist/components/Rubberband.js +2 -2
- package/dist/components/Rubberband.js.map +1 -1
- package/dist/model.d.ts +259 -12
- package/dist/model.js +349 -30
- package/dist/model.js.map +1 -1
- package/dist/util.js +4 -2
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -3
- package/src/colorSchemes.ts +5 -2
- package/src/components/MSAView.tsx +2 -4
- package/src/components/Rubberband.tsx +2 -2
- package/src/model.ts +402 -112
- package/src/util.ts +5 -2
- package/src/version.ts +1 -1
package/src/model.ts
CHANGED
|
@@ -49,7 +49,10 @@ export interface TextTrackModel extends BasicTrackModel {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export interface BoxTrackModel extends BasicTrackModel {
|
|
52
|
-
features: {
|
|
52
|
+
features: {
|
|
53
|
+
start: number
|
|
54
|
+
end: number
|
|
55
|
+
}[]
|
|
53
56
|
}
|
|
54
57
|
export interface ITextTrack {
|
|
55
58
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -64,65 +67,167 @@ export interface IBoxTrack {
|
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
type BasicTrack = IBoxTrack | ITextTrack
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
70
|
+
type StructureSnap = SnapshotIn<typeof StructureModel>
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* #stateModel MsaView
|
|
74
|
+
*/
|
|
75
|
+
function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
76
|
+
|
|
77
|
+
const model = types
|
|
78
|
+
.compose(
|
|
79
|
+
BaseViewModel,
|
|
80
|
+
types.model('MsaView', {
|
|
81
|
+
/**
|
|
82
|
+
* #property
|
|
83
|
+
*/
|
|
84
|
+
id: ElementId,
|
|
85
|
+
/**
|
|
86
|
+
* #property
|
|
87
|
+
*/
|
|
88
|
+
type: types.literal('MsaView'),
|
|
89
|
+
/**
|
|
90
|
+
* #property
|
|
91
|
+
*/
|
|
92
|
+
height: types.optional(types.number, 550),
|
|
93
|
+
/**
|
|
94
|
+
* #property
|
|
95
|
+
*/
|
|
96
|
+
treeAreaWidth: types.optional(types.number, 400),
|
|
97
|
+
/**
|
|
98
|
+
* #property
|
|
99
|
+
*/
|
|
100
|
+
treeWidth: types.optional(types.number, 300),
|
|
101
|
+
/**
|
|
102
|
+
* #property
|
|
103
|
+
*/
|
|
104
|
+
rowHeight: 20,
|
|
105
|
+
/**
|
|
106
|
+
* #property
|
|
107
|
+
*/
|
|
108
|
+
scrollY: 0,
|
|
109
|
+
/**
|
|
110
|
+
* #property
|
|
111
|
+
*/
|
|
112
|
+
scrollX: 0,
|
|
113
|
+
/**
|
|
114
|
+
* #property
|
|
115
|
+
*/
|
|
116
|
+
resizeHandleWidth: 5,
|
|
117
|
+
/**
|
|
118
|
+
* #property
|
|
119
|
+
*/
|
|
120
|
+
blockSize: 1000,
|
|
121
|
+
/**
|
|
122
|
+
* #property
|
|
123
|
+
*/
|
|
124
|
+
mouseRow: types.maybe(types.number),
|
|
125
|
+
/**
|
|
126
|
+
* #property
|
|
127
|
+
*/
|
|
128
|
+
mouseCol: types.maybe(types.number),
|
|
129
|
+
/**
|
|
130
|
+
* #property
|
|
131
|
+
*/
|
|
132
|
+
selectedStructures: types.array(StructureModel),
|
|
133
|
+
/**
|
|
134
|
+
* #property
|
|
135
|
+
*/
|
|
136
|
+
labelsAlignRight: false,
|
|
137
|
+
/**
|
|
138
|
+
* #property
|
|
139
|
+
*/
|
|
140
|
+
colWidth: 16,
|
|
141
|
+
/**
|
|
142
|
+
* #property
|
|
143
|
+
*/
|
|
144
|
+
showBranchLen: true,
|
|
145
|
+
/**
|
|
146
|
+
* #property
|
|
147
|
+
*/
|
|
148
|
+
bgColor: true,
|
|
149
|
+
/**
|
|
150
|
+
* #property
|
|
151
|
+
*/
|
|
152
|
+
drawTree: true,
|
|
153
|
+
/**
|
|
154
|
+
* #property
|
|
155
|
+
*/
|
|
156
|
+
drawNodeBubbles: true,
|
|
157
|
+
/**
|
|
158
|
+
* #property
|
|
159
|
+
*/
|
|
160
|
+
highResScaleFactor: 2,
|
|
161
|
+
/**
|
|
162
|
+
* #property
|
|
163
|
+
*/
|
|
164
|
+
colorSchemeName: 'maeditor',
|
|
165
|
+
/**
|
|
166
|
+
* #property
|
|
167
|
+
*/
|
|
168
|
+
treeFilehandle: types.maybe(FileLocation),
|
|
169
|
+
/**
|
|
170
|
+
* #property
|
|
171
|
+
*/
|
|
172
|
+
msaFilehandle: types.maybe(FileLocation),
|
|
173
|
+
/**
|
|
174
|
+
* #property
|
|
175
|
+
*/
|
|
176
|
+
currentAlignment: 0,
|
|
177
|
+
/**
|
|
178
|
+
* #property
|
|
179
|
+
*/
|
|
180
|
+
collapsed: types.array(types.string),
|
|
181
|
+
/**
|
|
182
|
+
* #property
|
|
183
|
+
*/
|
|
184
|
+
showOnly: types.maybe(types.string),
|
|
185
|
+
/**
|
|
186
|
+
* #property
|
|
187
|
+
*/
|
|
188
|
+
boxTracks: types.array(UniprotTrack),
|
|
189
|
+
/**
|
|
190
|
+
* #property
|
|
191
|
+
*/
|
|
192
|
+
turnedOffTracks: types.map(types.boolean),
|
|
193
|
+
/**
|
|
194
|
+
* #property
|
|
195
|
+
*/
|
|
196
|
+
annotatedRegions: types.array(
|
|
197
|
+
types.model({
|
|
198
|
+
start: types.number,
|
|
199
|
+
end: types.number,
|
|
200
|
+
attributes: types.frozen<Record<string, string[]>>(),
|
|
201
|
+
}),
|
|
202
|
+
),
|
|
203
|
+
/**
|
|
204
|
+
* #property
|
|
205
|
+
*/
|
|
206
|
+
data: types.optional(
|
|
207
|
+
types
|
|
208
|
+
.model({
|
|
209
|
+
tree: types.maybe(types.string),
|
|
210
|
+
msa: types.maybe(types.string),
|
|
211
|
+
})
|
|
212
|
+
.actions(self => ({
|
|
213
|
+
setTree(tree?: string) {
|
|
214
|
+
self.tree = tree
|
|
215
|
+
},
|
|
216
|
+
setMSA(msa?: string) {
|
|
217
|
+
self.msa = msa
|
|
218
|
+
},
|
|
219
|
+
})),
|
|
220
|
+
{ tree: '', msa: '' },
|
|
221
|
+
),
|
|
222
|
+
}),
|
|
223
|
+
)
|
|
122
224
|
.volatile(() => ({
|
|
123
225
|
rulerHeight: 20,
|
|
124
226
|
error: undefined as unknown,
|
|
125
|
-
margin: {
|
|
227
|
+
margin: {
|
|
228
|
+
left: 20,
|
|
229
|
+
top: 20,
|
|
230
|
+
},
|
|
126
231
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
232
|
DialogComponent: undefined as undefined | React.FC<any>,
|
|
128
233
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -132,23 +237,38 @@ const MSAModel = types
|
|
|
132
237
|
annotPos: undefined as { left: number; right: number } | undefined,
|
|
133
238
|
}))
|
|
134
239
|
.actions(self => ({
|
|
240
|
+
/**
|
|
241
|
+
* #action
|
|
242
|
+
*/
|
|
135
243
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
136
|
-
setDialogComponent(dlg
|
|
244
|
+
setDialogComponent(dlg?: React.FC<any>, props?: any) {
|
|
137
245
|
self.DialogComponent = dlg
|
|
138
246
|
self.DialogProps = props
|
|
139
247
|
},
|
|
248
|
+
/**
|
|
249
|
+
* #action
|
|
250
|
+
*/
|
|
140
251
|
setHeight(height: number) {
|
|
141
252
|
self.height = height
|
|
142
253
|
},
|
|
143
|
-
|
|
254
|
+
/**
|
|
255
|
+
* #action
|
|
256
|
+
*/
|
|
257
|
+
addStructureToSelection(elt: StructureSnap) {
|
|
144
258
|
self.selectedStructures.push(elt)
|
|
145
259
|
},
|
|
146
|
-
|
|
260
|
+
/**
|
|
261
|
+
* #action
|
|
262
|
+
*/
|
|
263
|
+
removeStructureFromSelection(elt: StructureSnap) {
|
|
147
264
|
const r = self.selectedStructures.find(node => node.id === elt.id)
|
|
148
265
|
if (r) {
|
|
149
266
|
self.selectedStructures.remove(r)
|
|
150
267
|
}
|
|
151
268
|
},
|
|
269
|
+
/**
|
|
270
|
+
* #action
|
|
271
|
+
*/
|
|
152
272
|
toggleStructureSelection(elt: {
|
|
153
273
|
id: string
|
|
154
274
|
structure: { startPos: number; endPos: number; pdb: string }
|
|
@@ -160,47 +280,88 @@ const MSAModel = types
|
|
|
160
280
|
self.selectedStructures.push(elt)
|
|
161
281
|
}
|
|
162
282
|
},
|
|
283
|
+
/**
|
|
284
|
+
* #action
|
|
285
|
+
*/
|
|
163
286
|
clearSelectedStructures() {
|
|
164
|
-
|
|
165
|
-
self.selectedStructures = []
|
|
287
|
+
self.selectedStructures = cast([])
|
|
166
288
|
},
|
|
289
|
+
/**
|
|
290
|
+
* #action
|
|
291
|
+
*/
|
|
167
292
|
setError(error?: unknown) {
|
|
168
293
|
self.error = error
|
|
169
294
|
},
|
|
295
|
+
/**
|
|
296
|
+
* #action
|
|
297
|
+
*/
|
|
170
298
|
setMousePos(col?: number, row?: number) {
|
|
171
299
|
self.mouseCol = col
|
|
172
300
|
self.mouseRow = row
|
|
173
301
|
},
|
|
302
|
+
/**
|
|
303
|
+
* #action
|
|
304
|
+
*/
|
|
174
305
|
setRowHeight(n: number) {
|
|
175
306
|
self.rowHeight = n
|
|
176
307
|
},
|
|
308
|
+
/**
|
|
309
|
+
* #action
|
|
310
|
+
*/
|
|
177
311
|
setColWidth(n: number) {
|
|
178
312
|
self.colWidth = n
|
|
179
313
|
},
|
|
314
|
+
/**
|
|
315
|
+
* #action
|
|
316
|
+
*/
|
|
180
317
|
setColorSchemeName(name: string) {
|
|
181
318
|
self.colorSchemeName = name
|
|
182
319
|
},
|
|
320
|
+
/**
|
|
321
|
+
* #action
|
|
322
|
+
*/
|
|
183
323
|
setScrollY(n: number) {
|
|
184
324
|
self.scrollY = n
|
|
185
325
|
},
|
|
326
|
+
/**
|
|
327
|
+
* #action
|
|
328
|
+
*/
|
|
186
329
|
setScrollX(n: number) {
|
|
187
330
|
self.scrollX = n
|
|
188
331
|
},
|
|
332
|
+
/**
|
|
333
|
+
* #action
|
|
334
|
+
*/
|
|
189
335
|
setTreeAreaWidth(n: number) {
|
|
190
336
|
self.treeAreaWidth = n
|
|
191
337
|
},
|
|
338
|
+
/**
|
|
339
|
+
* #action
|
|
340
|
+
*/
|
|
192
341
|
setTreeWidth(n: number) {
|
|
193
342
|
self.treeWidth = n
|
|
194
343
|
},
|
|
344
|
+
/**
|
|
345
|
+
* #action
|
|
346
|
+
*/
|
|
195
347
|
setCurrentAlignment(n: number) {
|
|
196
348
|
self.currentAlignment = n
|
|
197
349
|
},
|
|
350
|
+
/**
|
|
351
|
+
* #action
|
|
352
|
+
*/
|
|
198
353
|
toggleLabelsAlignRight() {
|
|
199
354
|
self.labelsAlignRight = !self.labelsAlignRight
|
|
200
355
|
},
|
|
356
|
+
/**
|
|
357
|
+
* #action
|
|
358
|
+
*/
|
|
201
359
|
toggleDrawTree() {
|
|
202
360
|
self.drawTree = !self.drawTree
|
|
203
361
|
},
|
|
362
|
+
/**
|
|
363
|
+
* #action
|
|
364
|
+
*/
|
|
204
365
|
toggleCollapsed(node: string) {
|
|
205
366
|
if (self.collapsed.includes(node)) {
|
|
206
367
|
self.collapsed.remove(node)
|
|
@@ -208,24 +369,45 @@ const MSAModel = types
|
|
|
208
369
|
self.collapsed.push(node)
|
|
209
370
|
}
|
|
210
371
|
},
|
|
372
|
+
/**
|
|
373
|
+
* #action
|
|
374
|
+
*/
|
|
211
375
|
setShowOnly(node?: string) {
|
|
212
376
|
self.showOnly = node
|
|
213
377
|
},
|
|
378
|
+
/**
|
|
379
|
+
* #action
|
|
380
|
+
*/
|
|
214
381
|
toggleBranchLen() {
|
|
215
382
|
self.showBranchLen = !self.showBranchLen
|
|
216
383
|
},
|
|
384
|
+
/**
|
|
385
|
+
* #action
|
|
386
|
+
*/
|
|
217
387
|
toggleBgColor() {
|
|
218
388
|
self.bgColor = !self.bgColor
|
|
219
389
|
},
|
|
390
|
+
/**
|
|
391
|
+
* #action
|
|
392
|
+
*/
|
|
220
393
|
toggleNodeBubbles() {
|
|
221
394
|
self.drawNodeBubbles = !self.drawNodeBubbles
|
|
222
395
|
},
|
|
396
|
+
/**
|
|
397
|
+
* #action
|
|
398
|
+
*/
|
|
223
399
|
setData(data: { msa?: string; tree?: string }) {
|
|
224
400
|
self.data = cast(data)
|
|
225
401
|
},
|
|
402
|
+
/**
|
|
403
|
+
* #action
|
|
404
|
+
*/
|
|
226
405
|
async setMSAFilehandle(msaFilehandle?: FileLocationType) {
|
|
227
406
|
self.msaFilehandle = msaFilehandle
|
|
228
407
|
},
|
|
408
|
+
/**
|
|
409
|
+
* #action
|
|
410
|
+
*/
|
|
229
411
|
async setTreeFilehandle(treeFilehandle?: FileLocationType) {
|
|
230
412
|
if (treeFilehandle && 'blobId' in treeFilehandle) {
|
|
231
413
|
const r = await openLocation(treeFilehandle).readFile('utf8')
|
|
@@ -234,9 +416,15 @@ const MSAModel = types
|
|
|
234
416
|
self.treeFilehandle = treeFilehandle
|
|
235
417
|
}
|
|
236
418
|
},
|
|
419
|
+
/**
|
|
420
|
+
* #action
|
|
421
|
+
*/
|
|
237
422
|
setMSA(result: string) {
|
|
238
423
|
self.data.setMSA(result)
|
|
239
424
|
},
|
|
425
|
+
/**
|
|
426
|
+
* #action
|
|
427
|
+
*/
|
|
240
428
|
setTree(result: string) {
|
|
241
429
|
self.data.setTree(result)
|
|
242
430
|
},
|
|
@@ -278,6 +466,9 @@ const MSAModel = types
|
|
|
278
466
|
let oldValX = 0
|
|
279
467
|
let oldValY = 0
|
|
280
468
|
return {
|
|
469
|
+
/**
|
|
470
|
+
* #getter
|
|
471
|
+
*/
|
|
281
472
|
get initialized() {
|
|
282
473
|
return (
|
|
283
474
|
(self.data.msa ||
|
|
@@ -287,7 +478,9 @@ const MSAModel = types
|
|
|
287
478
|
!self.error
|
|
288
479
|
)
|
|
289
480
|
},
|
|
290
|
-
|
|
481
|
+
/**
|
|
482
|
+
* #getter
|
|
483
|
+
*/
|
|
291
484
|
get blocksX() {
|
|
292
485
|
const { scrollX, blockSize: size, colWidth } = self
|
|
293
486
|
const ret = -(size * Math.floor(scrollX / size)) - size
|
|
@@ -307,7 +500,9 @@ const MSAModel = types
|
|
|
307
500
|
}
|
|
308
501
|
return oldBlocksX
|
|
309
502
|
},
|
|
310
|
-
|
|
503
|
+
/**
|
|
504
|
+
* #getter
|
|
505
|
+
*/
|
|
311
506
|
get blocksY() {
|
|
312
507
|
const { scrollY, blockSize: size, rowHeight } = self
|
|
313
508
|
const ret = -(size * Math.floor(scrollY / size)) - 2 * size
|
|
@@ -330,21 +525,33 @@ const MSAModel = types
|
|
|
330
525
|
}
|
|
331
526
|
})
|
|
332
527
|
.views(self => ({
|
|
528
|
+
/**
|
|
529
|
+
* #getter
|
|
530
|
+
*/
|
|
333
531
|
get blocks2d() {
|
|
334
532
|
return self.blocksY.flatMap(by => self.blocksX.map(bx => [bx, by]))
|
|
335
533
|
},
|
|
534
|
+
/**
|
|
535
|
+
* #getter
|
|
536
|
+
*/
|
|
336
537
|
get done() {
|
|
337
538
|
return self.initialized && (self.data.msa || self.data.tree)
|
|
338
539
|
},
|
|
339
|
-
|
|
540
|
+
/**
|
|
541
|
+
* #getter
|
|
542
|
+
*/
|
|
340
543
|
get colorScheme() {
|
|
341
544
|
return colorSchemes[self.colorSchemeName]
|
|
342
545
|
},
|
|
343
|
-
|
|
546
|
+
/**
|
|
547
|
+
* #getter
|
|
548
|
+
*/
|
|
344
549
|
get header() {
|
|
345
550
|
return this.MSA?.getHeader() || {}
|
|
346
551
|
},
|
|
347
|
-
|
|
552
|
+
/**
|
|
553
|
+
* #method
|
|
554
|
+
*/
|
|
348
555
|
getRowData(name: string) {
|
|
349
556
|
const matches = name.match(/\S+\/(\d+)-(\d+)/)
|
|
350
557
|
return {
|
|
@@ -352,23 +559,33 @@ const MSAModel = types
|
|
|
352
559
|
...(matches && { range: { start: +matches[1], end: +matches[2] } }),
|
|
353
560
|
}
|
|
354
561
|
},
|
|
355
|
-
|
|
562
|
+
/**
|
|
563
|
+
* #getter
|
|
564
|
+
*/
|
|
356
565
|
get currentAlignmentName() {
|
|
357
566
|
return this.alignmentNames[self.currentAlignment]
|
|
358
567
|
},
|
|
359
|
-
|
|
568
|
+
/**
|
|
569
|
+
* #getter
|
|
570
|
+
*/
|
|
360
571
|
get alignmentNames() {
|
|
361
572
|
return this.MSA?.alignmentNames || []
|
|
362
573
|
},
|
|
363
|
-
|
|
574
|
+
/**
|
|
575
|
+
* #getter
|
|
576
|
+
*/
|
|
364
577
|
get noTree() {
|
|
365
578
|
return !!this.tree.noTree
|
|
366
579
|
},
|
|
367
|
-
|
|
580
|
+
/**
|
|
581
|
+
* #getter
|
|
582
|
+
*/
|
|
368
583
|
get menuItems() {
|
|
369
584
|
return []
|
|
370
585
|
},
|
|
371
|
-
|
|
586
|
+
/**
|
|
587
|
+
* #getter
|
|
588
|
+
*/
|
|
372
589
|
get MSA() {
|
|
373
590
|
const text = self.data.msa
|
|
374
591
|
if (text) {
|
|
@@ -382,11 +599,15 @@ const MSAModel = types
|
|
|
382
599
|
}
|
|
383
600
|
return null
|
|
384
601
|
},
|
|
385
|
-
|
|
602
|
+
/**
|
|
603
|
+
* #getter
|
|
604
|
+
*/
|
|
386
605
|
get numColumns() {
|
|
387
606
|
return ((this.MSA?.getWidth() || 0) - this.blanks.length) * self.colWidth
|
|
388
607
|
},
|
|
389
|
-
|
|
608
|
+
/**
|
|
609
|
+
* #getter
|
|
610
|
+
*/
|
|
390
611
|
get tree(): NodeWithIds {
|
|
391
612
|
return self.data.tree
|
|
392
613
|
? generateNodeIds(parseNewick(self.data.tree))
|
|
@@ -397,21 +618,30 @@ const MSAModel = types
|
|
|
397
618
|
name: 'empty',
|
|
398
619
|
}
|
|
399
620
|
},
|
|
400
|
-
|
|
621
|
+
/**
|
|
622
|
+
* #getter
|
|
623
|
+
*/
|
|
401
624
|
get rowNames(): string[] {
|
|
402
625
|
return this.hierarchy.leaves().map(node => node.data.name)
|
|
403
626
|
},
|
|
404
|
-
|
|
405
|
-
|
|
627
|
+
/**
|
|
628
|
+
* #getter
|
|
629
|
+
*/ get mouseOverRowName() {
|
|
406
630
|
return self.mouseRow !== undefined
|
|
407
631
|
? this.rowNames[self.mouseRow]
|
|
408
632
|
: undefined
|
|
409
633
|
},
|
|
410
634
|
|
|
635
|
+
/**
|
|
636
|
+
* #method
|
|
637
|
+
*/
|
|
411
638
|
getMouseOverResidue(rowName: string) {
|
|
412
639
|
return this.columns[rowName]
|
|
413
640
|
},
|
|
414
641
|
|
|
642
|
+
/**
|
|
643
|
+
* #getter
|
|
644
|
+
*/
|
|
415
645
|
get root() {
|
|
416
646
|
let hier = hierarchy(this.tree, d => d.branchset)
|
|
417
647
|
.sum(d => (d.branchset ? 0 : 1))
|
|
@@ -431,7 +661,9 @@ const MSAModel = types
|
|
|
431
661
|
}
|
|
432
662
|
return hier
|
|
433
663
|
},
|
|
434
|
-
|
|
664
|
+
/**
|
|
665
|
+
* #getter
|
|
666
|
+
*/
|
|
435
667
|
get structures(): Record<
|
|
436
668
|
string,
|
|
437
669
|
{
|
|
@@ -442,7 +674,9 @@ const MSAModel = types
|
|
|
442
674
|
> {
|
|
443
675
|
return this.MSA?.getStructures() || {}
|
|
444
676
|
},
|
|
445
|
-
|
|
677
|
+
/**
|
|
678
|
+
* #getter
|
|
679
|
+
*/
|
|
446
680
|
get inverseStructures() {
|
|
447
681
|
return Object.fromEntries(
|
|
448
682
|
Object.entries(this.structures).flatMap(([key, val]) =>
|
|
@@ -450,12 +684,15 @@ const MSAModel = types
|
|
|
450
684
|
),
|
|
451
685
|
)
|
|
452
686
|
},
|
|
453
|
-
|
|
687
|
+
/**
|
|
688
|
+
* #getter
|
|
689
|
+
*/
|
|
454
690
|
get msaAreaWidth() {
|
|
455
|
-
// @ts-expect-error
|
|
456
691
|
return self.width - self.treeAreaWidth
|
|
457
692
|
},
|
|
458
|
-
|
|
693
|
+
/**
|
|
694
|
+
* #getter
|
|
695
|
+
*/
|
|
459
696
|
get blanks() {
|
|
460
697
|
const blanks = []
|
|
461
698
|
const strs = this.hierarchy
|
|
@@ -476,24 +713,32 @@ const MSAModel = types
|
|
|
476
713
|
}
|
|
477
714
|
return blanks
|
|
478
715
|
},
|
|
479
|
-
|
|
716
|
+
/**
|
|
717
|
+
* #getter
|
|
718
|
+
*/
|
|
480
719
|
get rows() {
|
|
481
720
|
return this.hierarchy
|
|
482
721
|
.leaves()
|
|
483
722
|
.map(({ data }) => [data.name, this.MSA?.getRow(data.name)] as const)
|
|
484
723
|
.filter((f): f is [string, string[]] => !!f[1])
|
|
485
724
|
},
|
|
486
|
-
|
|
725
|
+
/**
|
|
726
|
+
* #getter
|
|
727
|
+
*/
|
|
487
728
|
get columns() {
|
|
488
729
|
return Object.fromEntries(
|
|
489
730
|
this.rows.map((row, index) => [row[0], this.columns2d[index]] as const),
|
|
490
731
|
)
|
|
491
732
|
},
|
|
492
|
-
|
|
733
|
+
/**
|
|
734
|
+
* #getter
|
|
735
|
+
*/
|
|
493
736
|
get columns2d() {
|
|
494
737
|
return this.rows.map(r => r[1]).map(str => skipBlanks(this.blanks, str))
|
|
495
738
|
},
|
|
496
|
-
|
|
739
|
+
/**
|
|
740
|
+
* #getter
|
|
741
|
+
*/
|
|
497
742
|
get colStats() {
|
|
498
743
|
const r = [] as Record<string, number>[]
|
|
499
744
|
const columns = this.columns2d
|
|
@@ -509,8 +754,10 @@ const MSAModel = types
|
|
|
509
754
|
}
|
|
510
755
|
return r
|
|
511
756
|
},
|
|
512
|
-
|
|
513
|
-
|
|
757
|
+
/**
|
|
758
|
+
* #getter
|
|
759
|
+
* generates a new tree that is clustered with x,y positions
|
|
760
|
+
*/
|
|
514
761
|
get hierarchy(): HierarchyNode<NodeWithIdsAndLength> {
|
|
515
762
|
const root = this.root
|
|
516
763
|
const clust = cluster<NodeWithIds>()
|
|
@@ -524,12 +771,17 @@ const MSAModel = types
|
|
|
524
771
|
)
|
|
525
772
|
return root as HierarchyNode<NodeWithIdsAndLength>
|
|
526
773
|
},
|
|
527
|
-
|
|
774
|
+
/**
|
|
775
|
+
* #getter
|
|
776
|
+
*/
|
|
528
777
|
get totalHeight() {
|
|
529
778
|
return this.root.leaves().length * self.rowHeight
|
|
530
779
|
},
|
|
531
780
|
}))
|
|
532
781
|
.actions(self => ({
|
|
782
|
+
/**
|
|
783
|
+
* #action
|
|
784
|
+
*/
|
|
533
785
|
addUniprotTrack(node: { name: string; accession: string }) {
|
|
534
786
|
if (self.boxTracks.some(t => t.name === node.name)) {
|
|
535
787
|
if (self.turnedOffTracks.has(node.name)) {
|
|
@@ -543,11 +795,15 @@ const MSAModel = types
|
|
|
543
795
|
})
|
|
544
796
|
}
|
|
545
797
|
},
|
|
546
|
-
|
|
798
|
+
/**
|
|
799
|
+
* #action
|
|
800
|
+
*/
|
|
547
801
|
doScrollY(deltaY: number) {
|
|
548
802
|
self.scrollY = clamp(-self.totalHeight + 10, self.scrollY + deltaY, 0)
|
|
549
803
|
},
|
|
550
|
-
|
|
804
|
+
/**
|
|
805
|
+
* #action
|
|
806
|
+
*/
|
|
551
807
|
doScrollX(deltaX: number) {
|
|
552
808
|
self.scrollX = clamp(
|
|
553
809
|
-self.numColumns + (self.msaAreaWidth - 100),
|
|
@@ -555,6 +811,9 @@ const MSAModel = types
|
|
|
555
811
|
0,
|
|
556
812
|
)
|
|
557
813
|
},
|
|
814
|
+
/**
|
|
815
|
+
* #action
|
|
816
|
+
*/
|
|
558
817
|
setMouseoveredColumn(n: number, chain: string, file: string) {
|
|
559
818
|
let j = 0
|
|
560
819
|
let i = 0
|
|
@@ -572,7 +831,9 @@ const MSAModel = types
|
|
|
572
831
|
self.mouseCol = undefined
|
|
573
832
|
}
|
|
574
833
|
},
|
|
575
|
-
|
|
834
|
+
/**
|
|
835
|
+
* #action
|
|
836
|
+
*/
|
|
576
837
|
toggleTrack(id: string) {
|
|
577
838
|
if (self.turnedOffTracks.has(id)) {
|
|
578
839
|
self.turnedOffTracks.delete(id)
|
|
@@ -582,14 +843,21 @@ const MSAModel = types
|
|
|
582
843
|
},
|
|
583
844
|
}))
|
|
584
845
|
.views(self => ({
|
|
846
|
+
/**
|
|
847
|
+
* #getter
|
|
848
|
+
*/
|
|
585
849
|
get secondaryStructureConsensus() {
|
|
586
850
|
return self.MSA?.secondaryStructureConsensus
|
|
587
851
|
},
|
|
588
|
-
|
|
852
|
+
/**
|
|
853
|
+
* #getter
|
|
854
|
+
*/
|
|
589
855
|
get seqConsensus() {
|
|
590
856
|
return self.MSA?.seqConsensus
|
|
591
857
|
},
|
|
592
|
-
|
|
858
|
+
/**
|
|
859
|
+
* #getter
|
|
860
|
+
*/
|
|
593
861
|
get conservation() {
|
|
594
862
|
if (self.columns2d.length) {
|
|
595
863
|
for (let i = 0; i < self.columns2d[0].length; i++) {
|
|
@@ -601,7 +869,9 @@ const MSAModel = types
|
|
|
601
869
|
}
|
|
602
870
|
return ['a']
|
|
603
871
|
},
|
|
604
|
-
|
|
872
|
+
/**
|
|
873
|
+
* #getter
|
|
874
|
+
*/
|
|
605
875
|
get tracks(): BasicTrack[] {
|
|
606
876
|
const blanks = self.blanks
|
|
607
877
|
const adapterTracks = self.MSA
|
|
@@ -663,16 +933,22 @@ const MSAModel = types
|
|
|
663
933
|
|
|
664
934
|
return [...adapterTracks, ...boxTracks, ...annotationTracks]
|
|
665
935
|
},
|
|
666
|
-
|
|
936
|
+
/**
|
|
937
|
+
* #getter
|
|
938
|
+
*/
|
|
667
939
|
get turnedOnTracks() {
|
|
668
940
|
return this.tracks.filter(f => !self.turnedOffTracks.has(f.model.id))
|
|
669
941
|
},
|
|
670
|
-
|
|
671
|
-
|
|
942
|
+
/**
|
|
943
|
+
* #method
|
|
944
|
+
* returns coordinate in the current relative coordinate scheme
|
|
945
|
+
*/
|
|
672
946
|
pxToBp(coord: number) {
|
|
673
947
|
return Math.floor((coord - self.scrollX) / self.colWidth)
|
|
674
948
|
},
|
|
675
|
-
|
|
949
|
+
/**
|
|
950
|
+
* #method
|
|
951
|
+
*/
|
|
676
952
|
rowSpecificBpToPx(rowName: string, position: number) {
|
|
677
953
|
const { rowNames, rows, blanks } = self
|
|
678
954
|
const index = rowNames.indexOf(rowName)
|
|
@@ -680,6 +956,7 @@ const MSAModel = types
|
|
|
680
956
|
const details = self.getRowData(rowName)
|
|
681
957
|
const offset = details.range?.start || 0
|
|
682
958
|
const current = position - offset
|
|
959
|
+
const s = new Set(self.blanks)
|
|
683
960
|
|
|
684
961
|
if (current < 0) {
|
|
685
962
|
return 0
|
|
@@ -696,24 +973,31 @@ const MSAModel = types
|
|
|
696
973
|
|
|
697
974
|
let count = 0
|
|
698
975
|
for (let k = 0; k < row.length; k++) {
|
|
699
|
-
if (
|
|
976
|
+
if (s.has(k) && k < i + 1) {
|
|
700
977
|
count++
|
|
701
978
|
}
|
|
702
979
|
}
|
|
703
980
|
|
|
704
981
|
return i - count
|
|
705
982
|
},
|
|
983
|
+
/**
|
|
984
|
+
* #method
|
|
985
|
+
*/
|
|
706
986
|
globalBpToPx(position: number) {
|
|
707
987
|
let count = 0
|
|
988
|
+
const s = new Set(self.blanks)
|
|
989
|
+
|
|
708
990
|
for (let k = 0; k < self.rows[0]?.[1].length; k++) {
|
|
709
|
-
if (
|
|
991
|
+
if (s.has(k) && k < position + 1) {
|
|
710
992
|
count++
|
|
711
993
|
}
|
|
712
994
|
}
|
|
713
995
|
|
|
714
996
|
return position - count
|
|
715
997
|
},
|
|
716
|
-
|
|
998
|
+
/**
|
|
999
|
+
* #method
|
|
1000
|
+
*/
|
|
717
1001
|
relativePxToBp(rowName: string, position: number) {
|
|
718
1002
|
const { rowNames, rows } = self
|
|
719
1003
|
const index = rowNames.indexOf(rowName)
|
|
@@ -732,7 +1016,9 @@ const MSAModel = types
|
|
|
732
1016
|
}
|
|
733
1017
|
return 0
|
|
734
1018
|
},
|
|
735
|
-
|
|
1019
|
+
/**
|
|
1020
|
+
* #method
|
|
1021
|
+
*/
|
|
736
1022
|
getPos(pos: number) {
|
|
737
1023
|
let j = 0
|
|
738
1024
|
for (let i = 0, k = 0; i < pos; i++, j++) {
|
|
@@ -745,6 +1031,9 @@ const MSAModel = types
|
|
|
745
1031
|
},
|
|
746
1032
|
}))
|
|
747
1033
|
.actions(self => ({
|
|
1034
|
+
/**
|
|
1035
|
+
* #action
|
|
1036
|
+
*/
|
|
748
1037
|
addAnnotation(
|
|
749
1038
|
start: number,
|
|
750
1039
|
end: number,
|
|
@@ -756,18 +1045,20 @@ const MSAModel = types
|
|
|
756
1045
|
attributes,
|
|
757
1046
|
})
|
|
758
1047
|
},
|
|
759
|
-
|
|
760
|
-
|
|
1048
|
+
/**
|
|
1049
|
+
* #action
|
|
1050
|
+
*/
|
|
1051
|
+
setAnnotationClickBoundaries(left: number, right: number) {
|
|
761
1052
|
self.annotPos = { left, right }
|
|
762
1053
|
},
|
|
763
|
-
|
|
764
|
-
|
|
1054
|
+
/**
|
|
1055
|
+
* #action
|
|
1056
|
+
*/
|
|
1057
|
+
clearAnnotationClickBoundaries() {
|
|
765
1058
|
self.annotPos = undefined
|
|
766
1059
|
},
|
|
767
1060
|
}))
|
|
768
|
-
|
|
769
|
-
const model = types.snapshotProcessor(types.compose(BaseViewModel, MSAModel), {
|
|
770
|
-
postProcessor(result) {
|
|
1061
|
+
.postProcessSnapshot(result => {
|
|
771
1062
|
const snap = result as Omit<typeof result, symbol>
|
|
772
1063
|
const {
|
|
773
1064
|
data: { tree, msa },
|
|
@@ -784,8 +1075,7 @@ const model = types.snapshotProcessor(types.compose(BaseViewModel, MSAModel), {
|
|
|
784
1075
|
},
|
|
785
1076
|
...rest,
|
|
786
1077
|
}
|
|
787
|
-
}
|
|
788
|
-
})
|
|
1078
|
+
})
|
|
789
1079
|
|
|
790
1080
|
export default model
|
|
791
1081
|
|