react-msaview 3.2.1 → 4.0.0
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 +62 -76
- package/dist/components/msa/renderMSABlock.js +30 -26
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.js +4 -3
- package/dist/components/tree/TreeNodeMenu.js.map +1 -1
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js +2 -3
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.js +5 -5
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/model/DialogQueue.d.ts +1 -1
- package/dist/model.d.ts +23 -24
- package/dist/model.js +37 -13
- package/dist/model.js.map +1 -1
- package/dist/parseNewick.d.ts +4 -4
- package/dist/parseNewick.js +7 -7
- package/dist/parseNewick.js.map +1 -1
- package/dist/parsers/ClustalMSA.d.ts +4 -4
- package/dist/parsers/ClustalMSA.js +2 -2
- package/dist/parsers/ClustalMSA.js.map +1 -1
- package/dist/parsers/EmfMSA.d.ts +27 -0
- package/dist/parsers/EmfMSA.js +53 -0
- package/dist/parsers/EmfMSA.js.map +1 -0
- package/dist/parsers/EmfTree.d.ts +5 -0
- package/dist/parsers/EmfTree.js +8 -0
- package/dist/parsers/EmfTree.js.map +1 -0
- package/dist/parsers/FastaMSA.js +2 -2
- package/dist/parsers/FastaMSA.js.map +1 -1
- package/dist/parsers/StockholmMSA.js +2 -2
- package/dist/parsers/StockholmMSA.js.map +1 -1
- package/dist/reparseTree.js +2 -2
- package/dist/reparseTree.js.map +1 -1
- package/dist/util.d.ts +3 -3
- package/dist/util.js +1 -1
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -3
- package/src/components/msa/renderMSABlock.ts +42 -38
- package/src/components/tree/TreeNodeMenu.tsx +10 -4
- package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +6 -2
- package/src/components/tree/renderTreeCanvas.ts +2 -2
- package/src/index.ts +1 -0
- package/src/model.ts +38 -19
- package/src/parseNewick.ts +7 -7
- package/src/parsers/ClustalMSA.ts +2 -2
- package/src/parsers/EmfMSA.ts +66 -0
- package/src/parsers/EmfTree.ts +9 -0
- package/src/parsers/FastaMSA.ts +2 -2
- package/src/parsers/StockholmMSA.ts +2 -2
- package/src/reparseTree.ts +3 -3
- package/src/util.ts +5 -5
- package/src/version.ts +1 -1
package/src/model.ts
CHANGED
|
@@ -42,6 +42,7 @@ import TextTrack from './components/TextTrack'
|
|
|
42
42
|
|
|
43
43
|
// parsers
|
|
44
44
|
import ClustalMSA from './parsers/ClustalMSA'
|
|
45
|
+
import EmfMSA from './parsers/EmfMSA'
|
|
45
46
|
import StockholmMSA from './parsers/StockholmMSA'
|
|
46
47
|
import FastaMSA from './parsers/FastaMSA'
|
|
47
48
|
import parseNewick from './parseNewick'
|
|
@@ -57,6 +58,7 @@ import {
|
|
|
57
58
|
mouseOverCoordToGlobalCoord,
|
|
58
59
|
globalCoordToRowSpecificCoord,
|
|
59
60
|
} from './rowCoordinateCalculations'
|
|
61
|
+
import EmfTree from './parsers/EmfTree'
|
|
60
62
|
|
|
61
63
|
export interface Accession {
|
|
62
64
|
accession: string
|
|
@@ -150,7 +152,7 @@ function stateModelFactory() {
|
|
|
150
152
|
* #property
|
|
151
153
|
* height of each row, px
|
|
152
154
|
*/
|
|
153
|
-
rowHeight:
|
|
155
|
+
rowHeight: 18,
|
|
154
156
|
|
|
155
157
|
/**
|
|
156
158
|
* #property
|
|
@@ -168,7 +170,7 @@ function stateModelFactory() {
|
|
|
168
170
|
* #property
|
|
169
171
|
* width of columns, px
|
|
170
172
|
*/
|
|
171
|
-
colWidth:
|
|
173
|
+
colWidth: 14,
|
|
172
174
|
|
|
173
175
|
/**
|
|
174
176
|
* #property
|
|
@@ -224,7 +226,11 @@ function stateModelFactory() {
|
|
|
224
226
|
* data from the loaded tree/msa/treeMetadata, generally loaded by
|
|
225
227
|
* autorun
|
|
226
228
|
*/
|
|
227
|
-
data: types.optional(DataModelF(), {
|
|
229
|
+
data: types.optional(DataModelF(), {
|
|
230
|
+
tree: '',
|
|
231
|
+
msa: '',
|
|
232
|
+
treeMetadata: '',
|
|
233
|
+
}),
|
|
228
234
|
|
|
229
235
|
/**
|
|
230
236
|
* #property
|
|
@@ -476,7 +482,7 @@ function stateModelFactory() {
|
|
|
476
482
|
/**
|
|
477
483
|
* #action
|
|
478
484
|
*/
|
|
479
|
-
setData(data: { msa?: string; tree?: string }) {
|
|
485
|
+
setData(data: { msa?: string; tree?: string; treeMetadata?: string }) {
|
|
480
486
|
self.data = cast(data)
|
|
481
487
|
},
|
|
482
488
|
|
|
@@ -614,11 +620,13 @@ function stateModelFactory() {
|
|
|
614
620
|
if (text) {
|
|
615
621
|
if (Stockholm.sniff(text)) {
|
|
616
622
|
return new StockholmMSA(text, self.currentAlignment)
|
|
617
|
-
}
|
|
618
|
-
if (text.startsWith('>')) {
|
|
623
|
+
} else if (text.startsWith('>')) {
|
|
619
624
|
return new FastaMSA(text)
|
|
625
|
+
} else if (text.startsWith('SEQ')) {
|
|
626
|
+
return new EmfMSA(text)
|
|
627
|
+
} else {
|
|
628
|
+
return new ClustalMSA(text)
|
|
620
629
|
}
|
|
621
|
-
return new ClustalMSA(text)
|
|
622
630
|
}
|
|
623
631
|
return null
|
|
624
632
|
},
|
|
@@ -633,14 +641,25 @@ function stateModelFactory() {
|
|
|
633
641
|
* #getter
|
|
634
642
|
*/
|
|
635
643
|
get tree(): NodeWithIds {
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
+
const text = self.data.tree
|
|
645
|
+
let ret: NodeWithIds
|
|
646
|
+
if (text) {
|
|
647
|
+
let t: string
|
|
648
|
+
if (text.startsWith('SEQ')) {
|
|
649
|
+
const r = new EmfTree(text)
|
|
650
|
+
t = r.data.tree
|
|
651
|
+
} else {
|
|
652
|
+
t = text
|
|
653
|
+
}
|
|
654
|
+
ret = generateNodeIds(parseNewick(t))
|
|
655
|
+
} else {
|
|
656
|
+
ret = this.MSA?.getTree() || {
|
|
657
|
+
noTree: true,
|
|
658
|
+
children: [],
|
|
659
|
+
id: 'empty',
|
|
660
|
+
name: 'empty',
|
|
661
|
+
}
|
|
662
|
+
}
|
|
644
663
|
return reparseTree(ret)
|
|
645
664
|
},
|
|
646
665
|
/**
|
|
@@ -661,10 +680,10 @@ function stateModelFactory() {
|
|
|
661
680
|
* #getter
|
|
662
681
|
*/
|
|
663
682
|
get root() {
|
|
664
|
-
let hier = hierarchy(this.tree, d => d.
|
|
665
|
-
// todo: investigate whether needed, typescript says
|
|
683
|
+
let hier = hierarchy(this.tree, d => d.children)
|
|
684
|
+
// todo: investigate whether needed, typescript says children always true
|
|
666
685
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
667
|
-
.sum(d => (d.
|
|
686
|
+
.sum(d => (d.children ? 0 : 1))
|
|
668
687
|
.sort((a, b) => ascending(a.data.length || 1, b.data.length || 1))
|
|
669
688
|
|
|
670
689
|
if (self.showOnly) {
|
|
@@ -766,7 +785,7 @@ function stateModelFactory() {
|
|
|
766
785
|
* #getter
|
|
767
786
|
*/
|
|
768
787
|
get fontSize() {
|
|
769
|
-
return Math.min(Math.max(6, self.rowHeight -
|
|
788
|
+
return Math.min(Math.max(6, self.rowHeight - 3), 18)
|
|
770
789
|
},
|
|
771
790
|
/**
|
|
772
791
|
* #getter
|
package/src/parseNewick.ts
CHANGED
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
* Converted to JSON:
|
|
35
35
|
* {
|
|
36
36
|
* name: "F",
|
|
37
|
-
*
|
|
37
|
+
* children: [
|
|
38
38
|
* {name: "A", length: 0.1},
|
|
39
39
|
* {name: "B", length: 0.2},
|
|
40
40
|
* {
|
|
41
41
|
* name: "E",
|
|
42
42
|
* length: 0.5,
|
|
43
|
-
*
|
|
43
|
+
* children: [
|
|
44
44
|
* {name: "C", length: 0.3},
|
|
45
45
|
* {name: "D", length: 0.4}
|
|
46
46
|
* ]
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
*
|
|
51
51
|
* Converted to JSON, but with no names or lengths:
|
|
52
52
|
* {
|
|
53
|
-
*
|
|
53
|
+
* children: [
|
|
54
54
|
* {}, {}, {
|
|
55
|
-
*
|
|
55
|
+
* children: [{}, {}]
|
|
56
56
|
* }
|
|
57
57
|
* ]
|
|
58
58
|
* }
|
|
@@ -66,13 +66,13 @@ export default function parse(s: string) {
|
|
|
66
66
|
const token = tokens[i]!
|
|
67
67
|
const subtree = {}
|
|
68
68
|
switch (token) {
|
|
69
|
-
case '(': // new
|
|
70
|
-
tree.
|
|
69
|
+
case '(': // new children
|
|
70
|
+
tree.children = [subtree]
|
|
71
71
|
ancestors.push(tree)
|
|
72
72
|
tree = subtree
|
|
73
73
|
break
|
|
74
74
|
case ',': // another branch
|
|
75
|
-
ancestors.at(-1)?.
|
|
75
|
+
ancestors.at(-1)?.children.push(subtree)
|
|
76
76
|
tree = subtree
|
|
77
77
|
break
|
|
78
78
|
case ')': // optional name next
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { parseEmfAln } from 'emf-js'
|
|
2
|
+
import type { NodeWithIds } from '../util'
|
|
3
|
+
|
|
4
|
+
export default class EmfMSA {
|
|
5
|
+
private MSA: ReturnType<typeof parseEmfAln>
|
|
6
|
+
|
|
7
|
+
constructor(text: string) {
|
|
8
|
+
this.MSA = parseEmfAln(text)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
getMSA() {
|
|
12
|
+
return this.MSA
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getRow(name: string): string {
|
|
16
|
+
return this.MSA.find(aln => aln.protein === name)?.seq || ''
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getWidth() {
|
|
20
|
+
return this.MSA[0]!.seq.length
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getRowData() {
|
|
24
|
+
return undefined
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getHeader() {
|
|
28
|
+
return ''
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getNames() {
|
|
32
|
+
return this.MSA.map(aln => aln.protein)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getStructures() {
|
|
36
|
+
return {}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get alignmentNames() {
|
|
40
|
+
return []
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getTree(): NodeWithIds {
|
|
44
|
+
return {
|
|
45
|
+
id: 'root',
|
|
46
|
+
name: 'root',
|
|
47
|
+
noTree: true,
|
|
48
|
+
children: this.getNames().map(name => ({
|
|
49
|
+
id: name,
|
|
50
|
+
name,
|
|
51
|
+
children: [],
|
|
52
|
+
})),
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get seqConsensus() {
|
|
57
|
+
return undefined
|
|
58
|
+
}
|
|
59
|
+
get secondaryStructureConsensus() {
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get tracks() {
|
|
64
|
+
return []
|
|
65
|
+
}
|
|
66
|
+
}
|
package/src/parsers/FastaMSA.ts
CHANGED
|
@@ -100,9 +100,9 @@ export default class StockholmMSA {
|
|
|
100
100
|
id: 'root',
|
|
101
101
|
name: 'root',
|
|
102
102
|
noTree: true,
|
|
103
|
-
|
|
103
|
+
children: this.getNames().map(name => ({
|
|
104
104
|
id: name,
|
|
105
|
-
|
|
105
|
+
children: [],
|
|
106
106
|
name,
|
|
107
107
|
})),
|
|
108
108
|
}
|
package/src/reparseTree.ts
CHANGED
|
@@ -3,11 +3,11 @@ import type { NodeWithIds } from './util'
|
|
|
3
3
|
export function reparseTree(tree: NodeWithIds): NodeWithIds {
|
|
4
4
|
return {
|
|
5
5
|
...tree,
|
|
6
|
-
|
|
7
|
-
r.
|
|
6
|
+
children: tree.children.map(r =>
|
|
7
|
+
r.children.length
|
|
8
8
|
? reparseTree(r)
|
|
9
9
|
: {
|
|
10
|
-
|
|
10
|
+
children: [r],
|
|
11
11
|
id: `${r.id}-leafnode`,
|
|
12
12
|
name: `${r.name}-hidden`,
|
|
13
13
|
},
|
package/src/util.ts
CHANGED
|
@@ -14,7 +14,7 @@ export function transform<T>(
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
interface Node {
|
|
17
|
-
|
|
17
|
+
children?: Node[]
|
|
18
18
|
name?: string
|
|
19
19
|
[key: string]: unknown
|
|
20
20
|
}
|
|
@@ -22,7 +22,7 @@ interface Node {
|
|
|
22
22
|
export interface NodeWithIds {
|
|
23
23
|
id: string
|
|
24
24
|
name: string
|
|
25
|
-
|
|
25
|
+
children: NodeWithIds[]
|
|
26
26
|
length?: number
|
|
27
27
|
noTree?: boolean
|
|
28
28
|
}
|
|
@@ -30,7 +30,7 @@ export interface NodeWithIds {
|
|
|
30
30
|
export interface NodeWithIdsAndLength {
|
|
31
31
|
id: string
|
|
32
32
|
name: string
|
|
33
|
-
|
|
33
|
+
children: NodeWithIdsAndLength[]
|
|
34
34
|
noTree?: boolean
|
|
35
35
|
length: number
|
|
36
36
|
}
|
|
@@ -46,8 +46,8 @@ export function generateNodeIds(
|
|
|
46
46
|
...tree,
|
|
47
47
|
id,
|
|
48
48
|
name: tree.name || id,
|
|
49
|
-
|
|
50
|
-
tree.
|
|
49
|
+
children:
|
|
50
|
+
tree.children?.map((b, i) =>
|
|
51
51
|
generateNodeIds(b, `${id}-${i}`, depth + 1),
|
|
52
52
|
) || [],
|
|
53
53
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '
|
|
1
|
+
export const version = '4.0.0'
|