react-msaview 2.1.1 → 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/dist/model.js CHANGED
@@ -17,41 +17,135 @@ import parseNewick from './parseNewick';
17
17
  import colorSchemes from './colorSchemes';
18
18
  import { UniprotTrack } from './UniprotTrack';
19
19
  import { StructureModel } from './StructureModel';
20
- const MSAModel = types
21
- .model('MsaView', {
20
+ /**
21
+ * #stateModel MsaView
22
+ */
23
+ function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
24
+ const model = types
25
+ .compose(BaseViewModel, types.model('MsaView', {
26
+ /**
27
+ * #property
28
+ */
22
29
  id: ElementId,
30
+ /**
31
+ * #property
32
+ */
23
33
  type: types.literal('MsaView'),
34
+ /**
35
+ * #property
36
+ */
24
37
  height: types.optional(types.number, 550),
38
+ /**
39
+ * #property
40
+ */
25
41
  treeAreaWidth: types.optional(types.number, 400),
42
+ /**
43
+ * #property
44
+ */
26
45
  treeWidth: types.optional(types.number, 300),
46
+ /**
47
+ * #property
48
+ */
27
49
  rowHeight: 20,
50
+ /**
51
+ * #property
52
+ */
28
53
  scrollY: 0,
54
+ /**
55
+ * #property
56
+ */
29
57
  scrollX: 0,
58
+ /**
59
+ * #property
60
+ */
30
61
  resizeHandleWidth: 5,
62
+ /**
63
+ * #property
64
+ */
31
65
  blockSize: 1000,
66
+ /**
67
+ * #property
68
+ */
32
69
  mouseRow: types.maybe(types.number),
70
+ /**
71
+ * #property
72
+ */
33
73
  mouseCol: types.maybe(types.number),
74
+ /**
75
+ * #property
76
+ */
34
77
  selectedStructures: types.array(StructureModel),
78
+ /**
79
+ * #property
80
+ */
35
81
  labelsAlignRight: false,
82
+ /**
83
+ * #property
84
+ */
36
85
  colWidth: 16,
86
+ /**
87
+ * #property
88
+ */
37
89
  showBranchLen: true,
90
+ /**
91
+ * #property
92
+ */
38
93
  bgColor: true,
94
+ /**
95
+ * #property
96
+ */
39
97
  drawTree: true,
98
+ /**
99
+ * #property
100
+ */
40
101
  drawNodeBubbles: true,
102
+ /**
103
+ * #property
104
+ */
41
105
  highResScaleFactor: 2,
106
+ /**
107
+ * #property
108
+ */
42
109
  colorSchemeName: 'maeditor',
110
+ /**
111
+ * #property
112
+ */
43
113
  treeFilehandle: types.maybe(FileLocation),
114
+ /**
115
+ * #property
116
+ */
44
117
  msaFilehandle: types.maybe(FileLocation),
118
+ /**
119
+ * #property
120
+ */
45
121
  currentAlignment: 0,
122
+ /**
123
+ * #property
124
+ */
46
125
  collapsed: types.array(types.string),
126
+ /**
127
+ * #property
128
+ */
47
129
  showOnly: types.maybe(types.string),
130
+ /**
131
+ * #property
132
+ */
48
133
  boxTracks: types.array(UniprotTrack),
134
+ /**
135
+ * #property
136
+ */
49
137
  turnedOffTracks: types.map(types.boolean),
138
+ /**
139
+ * #property
140
+ */
50
141
  annotatedRegions: types.array(types.model({
51
142
  start: types.number,
52
143
  end: types.number,
53
144
  attributes: types.frozen(),
54
145
  })),
146
+ /**
147
+ * #property
148
+ */
55
149
  data: types.optional(types
56
150
  .model({
57
151
  tree: types.maybe(types.string),
@@ -65,11 +159,14 @@ const MSAModel = types
65
159
  self.msa = msa;
66
160
  },
67
161
  })), { tree: '', msa: '' }),
68
- })
162
+ }))
69
163
  .volatile(() => ({
70
164
  rulerHeight: 20,
71
165
  error: undefined,
72
- margin: { left: 20, top: 20 },
166
+ margin: {
167
+ left: 20,
168
+ top: 20,
169
+ },
73
170
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
171
  DialogComponent: undefined,
75
172
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -78,23 +175,38 @@ const MSAModel = types
78
175
  annotPos: undefined,
79
176
  }))
80
177
  .actions(self => ({
178
+ /**
179
+ * #action
180
+ */
81
181
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
182
  setDialogComponent(dlg, props) {
83
183
  self.DialogComponent = dlg;
84
184
  self.DialogProps = props;
85
185
  },
186
+ /**
187
+ * #action
188
+ */
86
189
  setHeight(height) {
87
190
  self.height = height;
88
191
  },
192
+ /**
193
+ * #action
194
+ */
89
195
  addStructureToSelection(elt) {
90
196
  self.selectedStructures.push(elt);
91
197
  },
198
+ /**
199
+ * #action
200
+ */
92
201
  removeStructureFromSelection(elt) {
93
202
  const r = self.selectedStructures.find(node => node.id === elt.id);
94
203
  if (r) {
95
204
  self.selectedStructures.remove(r);
96
205
  }
97
206
  },
207
+ /**
208
+ * #action
209
+ */
98
210
  toggleStructureSelection(elt) {
99
211
  const r = self.selectedStructures.find(node => node.id === elt.id);
100
212
  if (r) {
@@ -104,47 +216,88 @@ const MSAModel = types
104
216
  self.selectedStructures.push(elt);
105
217
  }
106
218
  },
219
+ /**
220
+ * #action
221
+ */
107
222
  clearSelectedStructures() {
108
- // @ts-expect-error
109
- self.selectedStructures = [];
223
+ self.selectedStructures = cast([]);
110
224
  },
225
+ /**
226
+ * #action
227
+ */
111
228
  setError(error) {
112
229
  self.error = error;
113
230
  },
231
+ /**
232
+ * #action
233
+ */
114
234
  setMousePos(col, row) {
115
235
  self.mouseCol = col;
116
236
  self.mouseRow = row;
117
237
  },
238
+ /**
239
+ * #action
240
+ */
118
241
  setRowHeight(n) {
119
242
  self.rowHeight = n;
120
243
  },
244
+ /**
245
+ * #action
246
+ */
121
247
  setColWidth(n) {
122
248
  self.colWidth = n;
123
249
  },
250
+ /**
251
+ * #action
252
+ */
124
253
  setColorSchemeName(name) {
125
254
  self.colorSchemeName = name;
126
255
  },
256
+ /**
257
+ * #action
258
+ */
127
259
  setScrollY(n) {
128
260
  self.scrollY = n;
129
261
  },
262
+ /**
263
+ * #action
264
+ */
130
265
  setScrollX(n) {
131
266
  self.scrollX = n;
132
267
  },
268
+ /**
269
+ * #action
270
+ */
133
271
  setTreeAreaWidth(n) {
134
272
  self.treeAreaWidth = n;
135
273
  },
274
+ /**
275
+ * #action
276
+ */
136
277
  setTreeWidth(n) {
137
278
  self.treeWidth = n;
138
279
  },
280
+ /**
281
+ * #action
282
+ */
139
283
  setCurrentAlignment(n) {
140
284
  self.currentAlignment = n;
141
285
  },
286
+ /**
287
+ * #action
288
+ */
142
289
  toggleLabelsAlignRight() {
143
290
  self.labelsAlignRight = !self.labelsAlignRight;
144
291
  },
292
+ /**
293
+ * #action
294
+ */
145
295
  toggleDrawTree() {
146
296
  self.drawTree = !self.drawTree;
147
297
  },
298
+ /**
299
+ * #action
300
+ */
148
301
  toggleCollapsed(node) {
149
302
  if (self.collapsed.includes(node)) {
150
303
  self.collapsed.remove(node);
@@ -153,24 +306,45 @@ const MSAModel = types
153
306
  self.collapsed.push(node);
154
307
  }
155
308
  },
309
+ /**
310
+ * #action
311
+ */
156
312
  setShowOnly(node) {
157
313
  self.showOnly = node;
158
314
  },
315
+ /**
316
+ * #action
317
+ */
159
318
  toggleBranchLen() {
160
319
  self.showBranchLen = !self.showBranchLen;
161
320
  },
321
+ /**
322
+ * #action
323
+ */
162
324
  toggleBgColor() {
163
325
  self.bgColor = !self.bgColor;
164
326
  },
327
+ /**
328
+ * #action
329
+ */
165
330
  toggleNodeBubbles() {
166
331
  self.drawNodeBubbles = !self.drawNodeBubbles;
167
332
  },
333
+ /**
334
+ * #action
335
+ */
168
336
  setData(data) {
169
337
  self.data = cast(data);
170
338
  },
339
+ /**
340
+ * #action
341
+ */
171
342
  async setMSAFilehandle(msaFilehandle) {
172
343
  self.msaFilehandle = msaFilehandle;
173
344
  },
345
+ /**
346
+ * #action
347
+ */
174
348
  async setTreeFilehandle(treeFilehandle) {
175
349
  if (treeFilehandle && 'blobId' in treeFilehandle) {
176
350
  const r = await openLocation(treeFilehandle).readFile('utf8');
@@ -180,9 +354,15 @@ const MSAModel = types
180
354
  self.treeFilehandle = treeFilehandle;
181
355
  }
182
356
  },
357
+ /**
358
+ * #action
359
+ */
183
360
  setMSA(result) {
184
361
  self.data.setMSA(result);
185
362
  },
363
+ /**
364
+ * #action
365
+ */
186
366
  setTree(result) {
187
367
  self.data.setTree(result);
188
368
  },
@@ -219,6 +399,9 @@ const MSAModel = types
219
399
  let oldValX = 0;
220
400
  let oldValY = 0;
221
401
  return {
402
+ /**
403
+ * #getter
404
+ */
222
405
  get initialized() {
223
406
  return ((self.data.msa ||
224
407
  self.data.tree ||
@@ -226,6 +409,9 @@ const MSAModel = types
226
409
  self.treeFilehandle) &&
227
410
  !self.error);
228
411
  },
412
+ /**
413
+ * #getter
414
+ */
229
415
  get blocksX() {
230
416
  const { scrollX, blockSize: size, colWidth } = self;
231
417
  const ret = -(size * Math.floor(scrollX / size)) - size;
@@ -242,6 +428,9 @@ const MSAModel = types
242
428
  }
243
429
  return oldBlocksX;
244
430
  },
431
+ /**
432
+ * #getter
433
+ */
245
434
  get blocksY() {
246
435
  const { scrollY, blockSize: size, rowHeight } = self;
247
436
  const ret = -(size * Math.floor(scrollY / size)) - 2 * size;
@@ -261,19 +450,34 @@ const MSAModel = types
261
450
  };
262
451
  })
263
452
  .views(self => ({
453
+ /**
454
+ * #getter
455
+ */
264
456
  get blocks2d() {
265
457
  return self.blocksY.flatMap(by => self.blocksX.map(bx => [bx, by]));
266
458
  },
459
+ /**
460
+ * #getter
461
+ */
267
462
  get done() {
268
463
  return self.initialized && (self.data.msa || self.data.tree);
269
464
  },
465
+ /**
466
+ * #getter
467
+ */
270
468
  get colorScheme() {
271
469
  return colorSchemes[self.colorSchemeName];
272
470
  },
471
+ /**
472
+ * #getter
473
+ */
273
474
  get header() {
274
475
  var _a;
275
476
  return ((_a = this.MSA) === null || _a === void 0 ? void 0 : _a.getHeader()) || {};
276
477
  },
478
+ /**
479
+ * #method
480
+ */
277
481
  getRowData(name) {
278
482
  var _a;
279
483
  const matches = name.match(/\S+\/(\d+)-(\d+)/);
@@ -282,19 +486,34 @@ const MSAModel = types
282
486
  ...(matches && { range: { start: +matches[1], end: +matches[2] } }),
283
487
  };
284
488
  },
489
+ /**
490
+ * #getter
491
+ */
285
492
  get currentAlignmentName() {
286
493
  return this.alignmentNames[self.currentAlignment];
287
494
  },
495
+ /**
496
+ * #getter
497
+ */
288
498
  get alignmentNames() {
289
499
  var _a;
290
500
  return ((_a = this.MSA) === null || _a === void 0 ? void 0 : _a.alignmentNames) || [];
291
501
  },
502
+ /**
503
+ * #getter
504
+ */
292
505
  get noTree() {
293
506
  return !!this.tree.noTree;
294
507
  },
508
+ /**
509
+ * #getter
510
+ */
295
511
  get menuItems() {
296
512
  return [];
297
513
  },
514
+ /**
515
+ * #getter
516
+ */
298
517
  get MSA() {
299
518
  const text = self.data.msa;
300
519
  if (text) {
@@ -310,10 +529,16 @@ const MSAModel = types
310
529
  }
311
530
  return null;
312
531
  },
532
+ /**
533
+ * #getter
534
+ */
313
535
  get numColumns() {
314
536
  var _a;
315
537
  return ((((_a = this.MSA) === null || _a === void 0 ? void 0 : _a.getWidth()) || 0) - this.blanks.length) * self.colWidth;
316
538
  },
539
+ /**
540
+ * #getter
541
+ */
317
542
  get tree() {
318
543
  var _a;
319
544
  return self.data.tree
@@ -325,17 +550,28 @@ const MSAModel = types
325
550
  name: 'empty',
326
551
  };
327
552
  },
553
+ /**
554
+ * #getter
555
+ */
328
556
  get rowNames() {
329
557
  return this.hierarchy.leaves().map(node => node.data.name);
330
558
  },
331
- get mouseOverRowName() {
559
+ /**
560
+ * #getter
561
+ */ get mouseOverRowName() {
332
562
  return self.mouseRow !== undefined
333
563
  ? this.rowNames[self.mouseRow]
334
564
  : undefined;
335
565
  },
566
+ /**
567
+ * #method
568
+ */
336
569
  getMouseOverResidue(rowName) {
337
570
  return this.columns[rowName];
338
571
  },
572
+ /**
573
+ * #getter
574
+ */
339
575
  get root() {
340
576
  let hier = hierarchy(this.tree, d => d.branchset)
341
577
  .sum(d => (d.branchset ? 0 : 1))
@@ -354,17 +590,28 @@ const MSAModel = types
354
590
  }
355
591
  return hier;
356
592
  },
593
+ /**
594
+ * #getter
595
+ */
357
596
  get structures() {
358
597
  var _a;
359
598
  return ((_a = this.MSA) === null || _a === void 0 ? void 0 : _a.getStructures()) || {};
360
599
  },
600
+ /**
601
+ * #getter
602
+ */
361
603
  get inverseStructures() {
362
604
  return Object.fromEntries(Object.entries(this.structures).flatMap(([key, val]) => val.map(pdbEntry => [pdbEntry.pdb, { id: key }])));
363
605
  },
606
+ /**
607
+ * #getter
608
+ */
364
609
  get msaAreaWidth() {
365
- // @ts-expect-error
366
610
  return self.width - self.treeAreaWidth;
367
611
  },
612
+ /**
613
+ * #getter
614
+ */
368
615
  get blanks() {
369
616
  var _a;
370
617
  const blanks = [];
@@ -385,18 +632,30 @@ const MSAModel = types
385
632
  }
386
633
  return blanks;
387
634
  },
635
+ /**
636
+ * #getter
637
+ */
388
638
  get rows() {
389
639
  return this.hierarchy
390
640
  .leaves()
391
641
  .map(({ data }) => { var _a; return [data.name, (_a = this.MSA) === null || _a === void 0 ? void 0 : _a.getRow(data.name)]; })
392
642
  .filter((f) => !!f[1]);
393
643
  },
644
+ /**
645
+ * #getter
646
+ */
394
647
  get columns() {
395
648
  return Object.fromEntries(this.rows.map((row, index) => [row[0], this.columns2d[index]]));
396
649
  },
650
+ /**
651
+ * #getter
652
+ */
397
653
  get columns2d() {
398
654
  return this.rows.map(r => r[1]).map(str => skipBlanks(this.blanks, str));
399
655
  },
656
+ /**
657
+ * #getter
658
+ */
400
659
  get colStats() {
401
660
  const r = [];
402
661
  const columns = this.columns2d;
@@ -412,7 +671,10 @@ const MSAModel = types
412
671
  }
413
672
  return r;
414
673
  },
415
- // generates a new tree that is clustered with x,y positions
674
+ /**
675
+ * #getter
676
+ * generates a new tree that is clustered with x,y positions
677
+ */
416
678
  get hierarchy() {
417
679
  const root = this.root;
418
680
  const clust = cluster()
@@ -422,11 +684,17 @@ const MSAModel = types
422
684
  setBrLength(root, (root.data.length = 0), self.treeWidth / maxLength(root));
423
685
  return root;
424
686
  },
687
+ /**
688
+ * #getter
689
+ */
425
690
  get totalHeight() {
426
691
  return this.root.leaves().length * self.rowHeight;
427
692
  },
428
693
  }))
429
694
  .actions(self => ({
695
+ /**
696
+ * #action
697
+ */
430
698
  addUniprotTrack(node) {
431
699
  if (self.boxTracks.some(t => t.name === node.name)) {
432
700
  if (self.turnedOffTracks.has(node.name)) {
@@ -441,12 +709,21 @@ const MSAModel = types
441
709
  });
442
710
  }
443
711
  },
712
+ /**
713
+ * #action
714
+ */
444
715
  doScrollY(deltaY) {
445
716
  self.scrollY = clamp(-self.totalHeight + 10, self.scrollY + deltaY, 0);
446
717
  },
718
+ /**
719
+ * #action
720
+ */
447
721
  doScrollX(deltaX) {
448
722
  self.scrollX = clamp(-self.numColumns + (self.msaAreaWidth - 100), self.scrollX + deltaX, 0);
449
723
  },
724
+ /**
725
+ * #action
726
+ */
450
727
  setMouseoveredColumn(n, chain, file) {
451
728
  var _a;
452
729
  let j = 0;
@@ -465,6 +742,9 @@ const MSAModel = types
465
742
  self.mouseCol = undefined;
466
743
  }
467
744
  },
745
+ /**
746
+ * #action
747
+ */
468
748
  toggleTrack(id) {
469
749
  if (self.turnedOffTracks.has(id)) {
470
750
  self.turnedOffTracks.delete(id);
@@ -475,14 +755,23 @@ const MSAModel = types
475
755
  },
476
756
  }))
477
757
  .views(self => ({
758
+ /**
759
+ * #getter
760
+ */
478
761
  get secondaryStructureConsensus() {
479
762
  var _a;
480
763
  return (_a = self.MSA) === null || _a === void 0 ? void 0 : _a.secondaryStructureConsensus;
481
764
  },
765
+ /**
766
+ * #getter
767
+ */
482
768
  get seqConsensus() {
483
769
  var _a;
484
770
  return (_a = self.MSA) === null || _a === void 0 ? void 0 : _a.seqConsensus;
485
771
  },
772
+ /**
773
+ * #getter
774
+ */
486
775
  get conservation() {
487
776
  if (self.columns2d.length) {
488
777
  for (let i = 0; i < self.columns2d[0].length; i++) {
@@ -494,6 +783,9 @@ const MSAModel = types
494
783
  }
495
784
  return ['a'];
496
785
  },
786
+ /**
787
+ * #getter
788
+ */
497
789
  get tracks() {
498
790
  const blanks = self.blanks;
499
791
  const adapterTracks = self.MSA
@@ -551,13 +843,22 @@ const MSAModel = types
551
843
  : [];
552
844
  return [...adapterTracks, ...boxTracks, ...annotationTracks];
553
845
  },
846
+ /**
847
+ * #getter
848
+ */
554
849
  get turnedOnTracks() {
555
850
  return this.tracks.filter(f => !self.turnedOffTracks.has(f.model.id));
556
851
  },
557
- // returns coordinate in the current relative coordinate scheme
852
+ /**
853
+ * #method
854
+ * returns coordinate in the current relative coordinate scheme
855
+ */
558
856
  pxToBp(coord) {
559
857
  return Math.floor((coord - self.scrollX) / self.colWidth);
560
858
  },
859
+ /**
860
+ * #method
861
+ */
561
862
  rowSpecificBpToPx(rowName, position) {
562
863
  var _a;
563
864
  const { rowNames, rows, blanks } = self;
@@ -566,6 +867,7 @@ const MSAModel = types
566
867
  const details = self.getRowData(rowName);
567
868
  const offset = ((_a = details.range) === null || _a === void 0 ? void 0 : _a.start) || 0;
568
869
  const current = position - offset;
870
+ const s = new Set(self.blanks);
569
871
  if (current < 0) {
570
872
  return 0;
571
873
  }
@@ -578,22 +880,29 @@ const MSAModel = types
578
880
  }
579
881
  let count = 0;
580
882
  for (let k = 0; k < row.length; k++) {
581
- if (blanks.includes(k) && k < i + 1) {
883
+ if (s.has(k) && k < i + 1) {
582
884
  count++;
583
885
  }
584
886
  }
585
887
  return i - count;
586
888
  },
889
+ /**
890
+ * #method
891
+ */
587
892
  globalBpToPx(position) {
588
893
  var _a;
589
894
  let count = 0;
895
+ const s = new Set(self.blanks);
590
896
  for (let k = 0; k < ((_a = self.rows[0]) === null || _a === void 0 ? void 0 : _a[1].length); k++) {
591
- if (self.blanks.includes(k) && k < position + 1) {
897
+ if (s.has(k) && k < position + 1) {
592
898
  count++;
593
899
  }
594
900
  }
595
901
  return position - count;
596
902
  },
903
+ /**
904
+ * #method
905
+ */
597
906
  relativePxToBp(rowName, position) {
598
907
  const { rowNames, rows } = self;
599
908
  const index = rowNames.indexOf(rowName);
@@ -612,6 +921,9 @@ const MSAModel = types
612
921
  }
613
922
  return 0;
614
923
  },
924
+ /**
925
+ * #method
926
+ */
615
927
  getPos(pos) {
616
928
  let j = 0;
617
929
  for (let i = 0, k = 0; i < pos; i++, j++) {
@@ -624,6 +936,9 @@ const MSAModel = types
624
936
  },
625
937
  }))
626
938
  .actions(self => ({
939
+ /**
940
+ * #action
941
+ */
627
942
  addAnnotation(start, end, attributes) {
628
943
  self.annotatedRegions.push({
629
944
  start: self.getPos(start),
@@ -631,28 +946,32 @@ const MSAModel = types
631
946
  attributes,
632
947
  });
633
948
  },
634
- setOffsets(left, right) {
949
+ /**
950
+ * #action
951
+ */
952
+ setAnnotationClickBoundaries(left, right) {
635
953
  self.annotPos = { left, right };
636
954
  },
637
- clearAnnotPos() {
955
+ /**
956
+ * #action
957
+ */
958
+ clearAnnotationClickBoundaries() {
638
959
  self.annotPos = undefined;
639
960
  },
640
- }));
641
- const model = types.snapshotProcessor(types.compose(BaseViewModel, MSAModel), {
642
- postProcessor(result) {
643
- const snap = result;
644
- const { data: { tree, msa }, ...rest } = snap;
645
- // remove the MSA/tree data from the tree if the filehandle available in
646
- // which case it can be reloaded on refresh
647
- return {
648
- data: {
649
- // https://andreasimonecosta.dev/posts/the-shortest-way-to-conditionally-insert-properties-into-an-object-literal/
650
- ...(!result.treeFilehandle && { tree }),
651
- ...(!result.msaFilehandle && { msa }),
652
- },
653
- ...rest,
654
- };
655
- },
961
+ }))
962
+ .postProcessSnapshot(result => {
963
+ const snap = result;
964
+ const { data: { tree, msa }, ...rest } = snap;
965
+ // remove the MSA/tree data from the tree if the filehandle available in
966
+ // which case it can be reloaded on refresh
967
+ return {
968
+ data: {
969
+ // https://andreasimonecosta.dev/posts/the-shortest-way-to-conditionally-insert-properties-into-an-object-literal/
970
+ ...(!result.treeFilehandle && { tree }),
971
+ ...(!result.msaFilehandle && { msa }),
972
+ },
973
+ ...rest,
974
+ };
656
975
  });
657
976
  export default model;
658
977
  //# sourceMappingURL=model.js.map