react-msaview 3.2.0 → 3.2.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 +12 -12
- package/dist/colorSchemes.js +2 -2
- package/dist/colorSchemes.js.map +1 -1
- package/dist/components/Loading.js +3 -1
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/ResizeHandles.js +6 -2
- package/dist/components/ResizeHandles.js.map +1 -1
- package/dist/components/SequenceTextArea.js +9 -3
- package/dist/components/SequenceTextArea.js.map +1 -1
- package/dist/components/TextTrack.js +1 -1
- package/dist/components/TextTrack.js.map +1 -1
- package/dist/components/Track.js +6 -2
- package/dist/components/Track.js.map +1 -1
- package/dist/components/VerticalScrollbar.js +5 -1
- package/dist/components/VerticalScrollbar.js.map +1 -1
- package/dist/components/dialogs/AboutDialog.js +3 -1
- package/dist/components/dialogs/AboutDialog.js.map +1 -1
- package/dist/components/dialogs/AddTrackDialog.d.ts +2 -2
- package/dist/components/dialogs/AddTrackDialog.js +8 -3
- package/dist/components/dialogs/AddTrackDialog.js.map +1 -1
- package/dist/components/dialogs/DomainDialog.js +6 -2
- package/dist/components/dialogs/DomainDialog.js.map +1 -1
- package/dist/components/dialogs/ExportSVGDialog.js +29 -17
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/dialogs/FeatureDialog.js +8 -4
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/dialogs/InterProScanDialog.js +23 -9
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
- package/dist/components/dialogs/MetadataDialog.js +3 -1
- package/dist/components/dialogs/MetadataDialog.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.js +61 -23
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/dialogs/TracklistDialog.d.ts +2 -2
- package/dist/components/dialogs/TracklistDialog.js +8 -3
- package/dist/components/dialogs/TracklistDialog.js.map +1 -1
- package/dist/components/dialogs/UserProvidedDomainsDialog.js +10 -4
- package/dist/components/dialogs/UserProvidedDomainsDialog.js.map +1 -1
- package/dist/components/header/Header.js +3 -1
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderInfoArea.js +5 -2
- package/dist/components/header/HeaderInfoArea.js.map +1 -1
- package/dist/components/header/HeaderMenu.js +12 -4
- package/dist/components/header/HeaderMenu.js.map +1 -1
- package/dist/components/header/HeaderMenuExtra.js +34 -16
- package/dist/components/header/HeaderMenuExtra.js.map +1 -1
- package/dist/components/header/ZoomControls.js +18 -6
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/import/ImportForm.d.ts +2 -2
- package/dist/components/import/ImportForm.js +15 -2
- package/dist/components/import/ImportForm.js.map +1 -1
- package/dist/components/import/ImportFormExamples.js +44 -31
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/minimap/Minimap.js +12 -4
- package/dist/components/minimap/Minimap.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +5 -3
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.d.ts +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +2 -2
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.js +4 -4
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +3 -3
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/tree/TreeBranchMenu.js +6 -3
- package/dist/components/tree/TreeBranchMenu.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +11 -4
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.js +1 -1
- package/dist/components/tree/TreeNodeMenu.js.map +1 -1
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.d.ts +2 -2
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js +5 -2
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -1
- package/dist/components/util.js +0 -3
- package/dist/components/util.js.map +1 -1
- package/dist/ggplotPalettes.js.map +1 -1
- package/dist/launchInterProScan.js +4 -4
- package/dist/launchInterProScan.js.map +1 -1
- package/dist/model/DialogQueue.js +0 -1
- package/dist/model/DialogQueue.js.map +1 -1
- package/dist/model.d.ts +57 -22
- package/dist/model.js +87 -50
- package/dist/model.js.map +1 -1
- package/dist/parseGFF.js +8 -6
- package/dist/parseGFF.js.map +1 -1
- package/dist/parseNewick.js +0 -1
- package/dist/parseNewick.js.map +1 -1
- package/dist/parsers/ClustalMSA.d.ts +1 -1
- package/dist/parsers/ClustalMSA.js.map +1 -1
- package/dist/parsers/FastaMSA.js +3 -3
- package/dist/parsers/FastaMSA.js.map +1 -1
- package/dist/parsers/StockholmMSA.d.ts +6 -6
- package/dist/parsers/StockholmMSA.js +4 -4
- package/dist/parsers/StockholmMSA.js.map +1 -1
- package/dist/renderToSvg.js +3 -6
- package/dist/renderToSvg.js.map +1 -1
- package/dist/rowCoordinateCalculations.d.ts +2 -0
- package/dist/rowCoordinateCalculations.js +26 -0
- package/dist/rowCoordinateCalculations.js.map +1 -0
- package/dist/rowCoordinateCalculations.test.d.ts +1 -0
- package/dist/rowCoordinateCalculations.test.js +18 -0
- package/dist/rowCoordinateCalculations.test.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -3
- package/src/colorSchemes.ts +4 -4
- package/src/components/Loading.tsx +7 -1
- package/src/components/ResizeHandles.tsx +6 -2
- package/src/components/SequenceTextArea.tsx +10 -4
- package/src/components/TextTrack.tsx +2 -2
- package/src/components/Track.tsx +8 -4
- package/src/components/VerticalScrollbar.tsx +6 -2
- package/src/components/dialogs/AboutDialog.tsx +7 -1
- package/src/components/dialogs/AddTrackDialog.tsx +13 -3
- package/src/components/dialogs/DomainDialog.tsx +9 -2
- package/src/components/dialogs/ExportSVGDialog.tsx +36 -17
- package/src/components/dialogs/FeatureDialog.tsx +7 -5
- package/src/components/dialogs/InterProScanDialog.tsx +20 -10
- package/src/components/dialogs/MetadataDialog.tsx +8 -1
- package/src/components/dialogs/SettingsDialog.tsx +76 -32
- package/src/components/dialogs/TracklistDialog.tsx +17 -3
- package/src/components/dialogs/UserProvidedDomainsDialog.tsx +11 -5
- package/src/components/header/Header.tsx +3 -1
- package/src/components/header/HeaderInfoArea.tsx +3 -2
- package/src/components/header/HeaderMenu.tsx +12 -7
- package/src/components/header/HeaderMenuExtra.tsx +28 -16
- package/src/components/header/ZoomControls.tsx +22 -6
- package/src/components/import/ImportForm.tsx +14 -2
- package/src/components/import/ImportFormExamples.tsx +59 -48
- package/src/components/minimap/Minimap.tsx +21 -9
- package/src/components/msa/MSACanvasBlock.tsx +5 -3
- package/src/components/msa/MSAMouseoverCanvas.tsx +5 -1
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +4 -4
- package/src/components/msa/renderMSABlock.ts +10 -10
- package/src/components/msa/renderMSAMouseover.ts +3 -3
- package/src/components/tree/TreeBranchMenu.tsx +5 -3
- package/src/components/tree/TreeCanvasBlock.tsx +11 -4
- package/src/components/tree/TreeNodeMenu.tsx +1 -1
- package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +11 -2
- package/src/components/util.ts +1 -4
- package/src/ggplotPalettes.ts +1 -1
- package/src/launchInterProScan.ts +5 -5
- package/src/model/DialogQueue.ts +0 -1
- package/src/model.ts +99 -56
- package/src/parseGFF.ts +13 -11
- package/src/parseNewick.ts +3 -3
- package/src/parsers/ClustalMSA.ts +2 -2
- package/src/parsers/FastaMSA.ts +4 -4
- package/src/parsers/StockholmMSA.ts +10 -10
- package/src/renderToSvg.tsx +1 -2
- package/src/rowCoordinateCalculations.test.ts +19 -0
- package/src/rowCoordinateCalculations.ts +26 -0
- package/src/version.ts +1 -1
|
@@ -35,8 +35,8 @@ const Toggles = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
35
35
|
})
|
|
36
36
|
|
|
37
37
|
const Table = observer(function ({ model }: { model: MsaViewModel }) {
|
|
38
|
-
const {
|
|
39
|
-
const values = [...
|
|
38
|
+
const { tidyInterProAnnotationTypes, featureFilters } = model
|
|
39
|
+
const values = [...tidyInterProAnnotationTypes.values()]
|
|
40
40
|
const palette = getPalette(values.length - 1)
|
|
41
41
|
return (
|
|
42
42
|
<>
|
|
@@ -57,12 +57,12 @@ const Table = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
57
57
|
<input
|
|
58
58
|
type="checkbox"
|
|
59
59
|
checked={featureFilters.get(accession) ?? false}
|
|
60
|
-
onChange={() =>
|
|
60
|
+
onChange={() => {
|
|
61
61
|
model.setFilter(
|
|
62
62
|
accession,
|
|
63
63
|
!model.featureFilters.get(accession),
|
|
64
64
|
)
|
|
65
|
-
}
|
|
65
|
+
}}
|
|
66
66
|
/>
|
|
67
67
|
</td>
|
|
68
68
|
<td>{accession}</td>
|
|
@@ -94,7 +94,9 @@ const FeatureTypeDialog = observer(function ({
|
|
|
94
94
|
}) {
|
|
95
95
|
return (
|
|
96
96
|
<Dialog
|
|
97
|
-
onClose={() =>
|
|
97
|
+
onClose={() => {
|
|
98
|
+
onClose()
|
|
99
|
+
}}
|
|
98
100
|
open
|
|
99
101
|
title="Feature filters"
|
|
100
102
|
maxWidth="xl"
|
|
@@ -151,7 +151,9 @@ const InterProScanDialog = observer(function ({
|
|
|
151
151
|
<Dialog
|
|
152
152
|
maxWidth="xl"
|
|
153
153
|
title="Query InterProScan API for domains"
|
|
154
|
-
onClose={() =>
|
|
154
|
+
onClose={() => {
|
|
155
|
+
handleClose()
|
|
156
|
+
}}
|
|
155
157
|
open
|
|
156
158
|
>
|
|
157
159
|
<DialogContent>
|
|
@@ -159,7 +161,11 @@ const InterProScanDialog = observer(function ({
|
|
|
159
161
|
This will run InterProScan via the InterProScan API on all rows of the
|
|
160
162
|
current MSA
|
|
161
163
|
</Typography>
|
|
162
|
-
<Button
|
|
164
|
+
<Button
|
|
165
|
+
onClick={() => {
|
|
166
|
+
setShow(!show)
|
|
167
|
+
}}
|
|
168
|
+
>
|
|
163
169
|
{show ? 'Hide' : 'Show'} advanced options
|
|
164
170
|
</Button>
|
|
165
171
|
{show ? (
|
|
@@ -169,18 +175,18 @@ const InterProScanDialog = observer(function ({
|
|
|
169
175
|
<Button
|
|
170
176
|
variant="contained"
|
|
171
177
|
color="secondary"
|
|
172
|
-
onClick={() =>
|
|
178
|
+
onClick={() => {
|
|
173
179
|
setVals(vals.map(v => ({ ...v, checked: false })))
|
|
174
|
-
}
|
|
180
|
+
}}
|
|
175
181
|
>
|
|
176
182
|
Select none
|
|
177
183
|
</Button>
|
|
178
184
|
<Button
|
|
179
185
|
variant="contained"
|
|
180
186
|
color="primary"
|
|
181
|
-
onClick={() =>
|
|
187
|
+
onClick={() => {
|
|
182
188
|
setVals(vals.map(v => ({ ...v, checked: true })))
|
|
183
|
-
}
|
|
189
|
+
}}
|
|
184
190
|
>
|
|
185
191
|
Select all
|
|
186
192
|
</Button>
|
|
@@ -196,7 +202,7 @@ const InterProScanDialog = observer(function ({
|
|
|
196
202
|
type="checkbox"
|
|
197
203
|
key={name}
|
|
198
204
|
checked={checked}
|
|
199
|
-
onChange={() =>
|
|
205
|
+
onChange={() => {
|
|
200
206
|
setVals(
|
|
201
207
|
vals.map(e =>
|
|
202
208
|
e.name === name
|
|
@@ -204,7 +210,7 @@ const InterProScanDialog = observer(function ({
|
|
|
204
210
|
: e,
|
|
205
211
|
),
|
|
206
212
|
)
|
|
207
|
-
}
|
|
213
|
+
}}
|
|
208
214
|
/>
|
|
209
215
|
</td>
|
|
210
216
|
<td>{name}</td>
|
|
@@ -220,7 +226,9 @@ const InterProScanDialog = observer(function ({
|
|
|
220
226
|
<Button
|
|
221
227
|
variant="contained"
|
|
222
228
|
color="secondary"
|
|
223
|
-
onClick={() =>
|
|
229
|
+
onClick={() => {
|
|
230
|
+
handleClose()
|
|
231
|
+
}}
|
|
224
232
|
>
|
|
225
233
|
Cancel
|
|
226
234
|
</Button>
|
|
@@ -245,7 +253,9 @@ const InterProScanDialog = observer(function ({
|
|
|
245
253
|
.filter(f => !!f[1])
|
|
246
254
|
.map(row => `>${row[0]}\n${row[1]}`)
|
|
247
255
|
.join('\n'),
|
|
248
|
-
onProgress: arg =>
|
|
256
|
+
onProgress: arg => {
|
|
257
|
+
model.setStatus(arg)
|
|
258
|
+
},
|
|
249
259
|
model,
|
|
250
260
|
})
|
|
251
261
|
} catch (e) {
|
|
@@ -21,7 +21,14 @@ const MetadataDialog = observer(function ({
|
|
|
21
21
|
const { header } = model
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
<Dialog
|
|
24
|
+
<Dialog
|
|
25
|
+
onClose={() => {
|
|
26
|
+
onClose()
|
|
27
|
+
}}
|
|
28
|
+
open
|
|
29
|
+
title="Metadata"
|
|
30
|
+
maxWidth="xl"
|
|
31
|
+
>
|
|
25
32
|
<DialogContent>
|
|
26
33
|
<Attributes attributes={header} />
|
|
27
34
|
<BaseCard title="sequence">
|
|
@@ -23,6 +23,9 @@ const useStyles = makeStyles()(theme => ({
|
|
|
23
23
|
flex: {
|
|
24
24
|
display: 'flex',
|
|
25
25
|
},
|
|
26
|
+
minw: {
|
|
27
|
+
width: '80em',
|
|
28
|
+
},
|
|
26
29
|
}))
|
|
27
30
|
|
|
28
31
|
const SettingsContent = observer(function ({ model }: { model: MsaViewModel }) {
|
|
@@ -56,39 +59,49 @@ const TreeSettings = observer(function TreeSettings({
|
|
|
56
59
|
<h1>Tree options</h1>
|
|
57
60
|
<Checkbox2
|
|
58
61
|
checked={showBranchLen}
|
|
59
|
-
onChange={() =>
|
|
62
|
+
onChange={() => {
|
|
63
|
+
model.setShowBranchLen(!showBranchLen)
|
|
64
|
+
}}
|
|
60
65
|
label="Show branch length?"
|
|
61
66
|
/>
|
|
62
67
|
|
|
63
68
|
<Checkbox2
|
|
64
69
|
checked={drawNodeBubbles}
|
|
65
|
-
onChange={() =>
|
|
70
|
+
onChange={() => {
|
|
71
|
+
model.setDrawNodeBubbles(!drawNodeBubbles)
|
|
72
|
+
}}
|
|
66
73
|
label="Draw clickable bubbles on tree branches?"
|
|
67
74
|
/>
|
|
68
75
|
<Checkbox2
|
|
69
76
|
checked={drawTree}
|
|
70
|
-
onChange={() =>
|
|
77
|
+
onChange={() => {
|
|
78
|
+
model.setDrawTree(!drawTree)
|
|
79
|
+
}}
|
|
71
80
|
label="Show tree?"
|
|
72
81
|
/>
|
|
73
82
|
|
|
74
83
|
<Checkbox2
|
|
75
84
|
checked={labelsAlignRight}
|
|
76
|
-
onChange={() =>
|
|
85
|
+
onChange={() => {
|
|
86
|
+
model.setLabelsAlignRight(!labelsAlignRight)
|
|
87
|
+
}}
|
|
77
88
|
label="Tree labels align right?"
|
|
78
89
|
/>
|
|
79
90
|
|
|
80
91
|
<Checkbox2
|
|
81
92
|
checked={drawLabels}
|
|
82
|
-
onChange={() =>
|
|
93
|
+
onChange={() => {
|
|
94
|
+
model.setDrawLabels(!drawLabels)
|
|
95
|
+
}}
|
|
83
96
|
label="Draw labels"
|
|
84
97
|
/>
|
|
85
98
|
{noTree ? null : (
|
|
86
99
|
<div>
|
|
87
100
|
<Checkbox2
|
|
88
101
|
checked={treeWidthMatchesArea}
|
|
89
|
-
onChange={() =>
|
|
102
|
+
onChange={() => {
|
|
90
103
|
model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
|
|
91
|
-
}
|
|
104
|
+
}}
|
|
92
105
|
label="Make tree width fit to tree area?"
|
|
93
106
|
/>
|
|
94
107
|
{treeWidthMatchesArea ? null : (
|
|
@@ -99,7 +112,9 @@ const TreeSettings = observer(function TreeSettings({
|
|
|
99
112
|
min={50}
|
|
100
113
|
max={600}
|
|
101
114
|
value={treeWidth}
|
|
102
|
-
onChange={(_, val) =>
|
|
115
|
+
onChange={(_, val) => {
|
|
116
|
+
model.setTreeWidth(val as number)
|
|
117
|
+
}}
|
|
103
118
|
/>
|
|
104
119
|
</div>
|
|
105
120
|
)}
|
|
@@ -131,25 +146,46 @@ const MSASettings = observer(function MSASettings({
|
|
|
131
146
|
<h1>MSA options</h1>
|
|
132
147
|
<Checkbox2
|
|
133
148
|
checked={drawMsaLetters}
|
|
134
|
-
onChange={() =>
|
|
149
|
+
onChange={() => {
|
|
150
|
+
model.setDrawMsaLetters(!drawMsaLetters)
|
|
151
|
+
}}
|
|
135
152
|
label="Draw letters"
|
|
136
153
|
/>
|
|
137
154
|
<Checkbox2
|
|
138
155
|
checked={bgColor}
|
|
139
|
-
onChange={() =>
|
|
156
|
+
onChange={() => {
|
|
157
|
+
model.setBgColor(!bgColor)
|
|
158
|
+
}}
|
|
140
159
|
label="Color background tiles of MSA?"
|
|
141
160
|
/>
|
|
142
161
|
<Checkbox2
|
|
143
162
|
checked={contrastLettering}
|
|
144
|
-
onChange={() =>
|
|
163
|
+
onChange={() => {
|
|
164
|
+
model.setContrastLettering(!contrastLettering)
|
|
165
|
+
}}
|
|
145
166
|
label="Use contrast lettering"
|
|
146
167
|
/>
|
|
147
168
|
<Checkbox2
|
|
148
169
|
checked={hideGaps}
|
|
149
|
-
onChange={() =>
|
|
150
|
-
|
|
170
|
+
onChange={() => {
|
|
171
|
+
model.setHideGaps(!hideGaps)
|
|
172
|
+
}}
|
|
173
|
+
label={`Hide columns that are ${allowedGappyness}% gaps`}
|
|
151
174
|
/>
|
|
152
|
-
|
|
175
|
+
{hideGaps ? (
|
|
176
|
+
<div className={classes.flex}>
|
|
177
|
+
<Typography>Allowed gappyness ({100 - allowedGappyness}%)</Typography>
|
|
178
|
+
<Slider
|
|
179
|
+
className={classes.field}
|
|
180
|
+
min={1}
|
|
181
|
+
max={100}
|
|
182
|
+
value={allowedGappyness}
|
|
183
|
+
onChange={(_, val) => {
|
|
184
|
+
model.setAllowedGappyness(val as number)
|
|
185
|
+
}}
|
|
186
|
+
/>
|
|
187
|
+
</div>
|
|
188
|
+
) : null}
|
|
153
189
|
<div className={classes.flex}>
|
|
154
190
|
<Typography>Column width ({colWidth}px)</Typography>
|
|
155
191
|
<Slider
|
|
@@ -157,7 +193,9 @@ const MSASettings = observer(function MSASettings({
|
|
|
157
193
|
min={1}
|
|
158
194
|
max={50}
|
|
159
195
|
value={colWidth}
|
|
160
|
-
onChange={(_, val) =>
|
|
196
|
+
onChange={(_, val) => {
|
|
197
|
+
model.setColWidth(val as number)
|
|
198
|
+
}}
|
|
161
199
|
/>
|
|
162
200
|
</div>
|
|
163
201
|
<div className={classes.flex}>
|
|
@@ -167,27 +205,19 @@ const MSASettings = observer(function MSASettings({
|
|
|
167
205
|
min={1}
|
|
168
206
|
max={50}
|
|
169
207
|
value={rowHeight}
|
|
170
|
-
onChange={(_, val) =>
|
|
208
|
+
onChange={(_, val) => {
|
|
209
|
+
model.setRowHeight(val as number)
|
|
210
|
+
}}
|
|
171
211
|
/>
|
|
172
212
|
</div>
|
|
173
|
-
{hideGaps ? (
|
|
174
|
-
<div className={classes.flex}>
|
|
175
|
-
<Typography>Allowed gappyness ({100 - allowedGappyness}%)</Typography>
|
|
176
|
-
<Slider
|
|
177
|
-
className={classes.field}
|
|
178
|
-
min={1}
|
|
179
|
-
max={100}
|
|
180
|
-
value={allowedGappyness}
|
|
181
|
-
onChange={(_, val) => model.setAllowedGappyness(val as number)}
|
|
182
|
-
/>
|
|
183
|
-
</div>
|
|
184
|
-
) : null}
|
|
185
213
|
|
|
186
214
|
<TextField
|
|
187
215
|
select
|
|
188
216
|
label="Color scheme"
|
|
189
217
|
value={colorSchemeName}
|
|
190
|
-
onChange={event =>
|
|
218
|
+
onChange={event => {
|
|
219
|
+
model.setColorSchemeName(event.target.value)
|
|
220
|
+
}}
|
|
191
221
|
>
|
|
192
222
|
{Object.keys(colorSchemes).map(option => (
|
|
193
223
|
<MenuItem key={option} value={option}>
|
|
@@ -206,12 +236,26 @@ const SettingsDialog = observer(function ({
|
|
|
206
236
|
model: MsaViewModel
|
|
207
237
|
onClose: () => void
|
|
208
238
|
}) {
|
|
239
|
+
const { classes } = useStyles()
|
|
209
240
|
return (
|
|
210
|
-
<Dialog
|
|
211
|
-
|
|
241
|
+
<Dialog
|
|
242
|
+
open
|
|
243
|
+
onClose={() => {
|
|
244
|
+
onClose()
|
|
245
|
+
}}
|
|
246
|
+
title="Settings"
|
|
247
|
+
maxWidth="xl"
|
|
248
|
+
>
|
|
249
|
+
<DialogContent className={classes.minw}>
|
|
212
250
|
<SettingsContent model={model} />
|
|
213
251
|
<DialogActions>
|
|
214
|
-
<Button
|
|
252
|
+
<Button
|
|
253
|
+
onClick={() => {
|
|
254
|
+
onClose()
|
|
255
|
+
}}
|
|
256
|
+
variant="contained"
|
|
257
|
+
color="primary"
|
|
258
|
+
>
|
|
215
259
|
Submit
|
|
216
260
|
</Button>
|
|
217
261
|
</DialogActions>
|
|
@@ -14,7 +14,7 @@ import { observer } from 'mobx-react'
|
|
|
14
14
|
// locals
|
|
15
15
|
import type { MsaViewModel } from '../../model'
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const TracklistDialog = observer(function ({
|
|
18
18
|
model,
|
|
19
19
|
onClose,
|
|
20
20
|
}: {
|
|
@@ -24,7 +24,13 @@ export default observer(function ({
|
|
|
24
24
|
const { tracks } = model
|
|
25
25
|
|
|
26
26
|
return (
|
|
27
|
-
<Dialog
|
|
27
|
+
<Dialog
|
|
28
|
+
onClose={() => {
|
|
29
|
+
onClose()
|
|
30
|
+
}}
|
|
31
|
+
open
|
|
32
|
+
title="Add track"
|
|
33
|
+
>
|
|
28
34
|
<DialogContent>
|
|
29
35
|
<Typography>
|
|
30
36
|
Open relevant per-alignment tracks e.g. protein domains
|
|
@@ -49,7 +55,13 @@ export default observer(function ({
|
|
|
49
55
|
})}
|
|
50
56
|
</FormGroup>
|
|
51
57
|
<DialogActions>
|
|
52
|
-
<Button
|
|
58
|
+
<Button
|
|
59
|
+
onClick={() => {
|
|
60
|
+
onClose()
|
|
61
|
+
}}
|
|
62
|
+
variant="contained"
|
|
63
|
+
color="primary"
|
|
64
|
+
>
|
|
53
65
|
Close
|
|
54
66
|
</Button>
|
|
55
67
|
</DialogActions>
|
|
@@ -57,3 +69,5 @@ export default observer(function ({
|
|
|
57
69
|
</Dialog>
|
|
58
70
|
)
|
|
59
71
|
})
|
|
72
|
+
|
|
73
|
+
export default TracklistDialog
|
|
@@ -34,7 +34,9 @@ const UserProvidedDomainsDialog = observer(function ({
|
|
|
34
34
|
<Dialog
|
|
35
35
|
maxWidth="xl"
|
|
36
36
|
title="Open protein domains from file"
|
|
37
|
-
onClose={() =>
|
|
37
|
+
onClose={() => {
|
|
38
|
+
handleClose()
|
|
39
|
+
}}
|
|
38
40
|
open
|
|
39
41
|
>
|
|
40
42
|
<DialogContent>
|
|
@@ -48,7 +50,9 @@ const UserProvidedDomainsDialog = observer(function ({
|
|
|
48
50
|
<FormControl component="fieldset">
|
|
49
51
|
<RadioGroup
|
|
50
52
|
value={choice}
|
|
51
|
-
onChange={event =>
|
|
53
|
+
onChange={event => {
|
|
54
|
+
setChoice(event.target.value)
|
|
55
|
+
}}
|
|
52
56
|
>
|
|
53
57
|
<FormControlLabel value="url" control={<Radio />} label="URL" />
|
|
54
58
|
<FormControlLabel
|
|
@@ -66,7 +70,9 @@ const UserProvidedDomainsDialog = observer(function ({
|
|
|
66
70
|
<TextField
|
|
67
71
|
label="URL"
|
|
68
72
|
value={interProURL}
|
|
69
|
-
onChange={event =>
|
|
73
|
+
onChange={event => {
|
|
74
|
+
setInterProURL(event.target.value)
|
|
75
|
+
}}
|
|
70
76
|
/>
|
|
71
77
|
</div>
|
|
72
78
|
) : null}
|
|
@@ -81,7 +87,7 @@ const UserProvidedDomainsDialog = observer(function ({
|
|
|
81
87
|
type="file"
|
|
82
88
|
hidden
|
|
83
89
|
onChange={({ target }) => {
|
|
84
|
-
const file = target
|
|
90
|
+
const file = target.files?.[0]
|
|
85
91
|
if (file) {
|
|
86
92
|
setFile(file)
|
|
87
93
|
}
|
|
@@ -106,7 +112,7 @@ const UserProvidedDomainsDialog = observer(function ({
|
|
|
106
112
|
: await jsonfetch(interProURL)
|
|
107
113
|
|
|
108
114
|
model.setInterProAnnotations(
|
|
109
|
-
Object.fromEntries(ret.results.map(r => [r.xref[0]
|
|
115
|
+
Object.fromEntries(ret.results.map(r => [r.xref[0]!.id, r])),
|
|
110
116
|
)
|
|
111
117
|
model.setShowDomains(true)
|
|
112
118
|
getSession(model).notify(
|
|
@@ -32,7 +32,9 @@ const Header = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
32
32
|
<Spacer />
|
|
33
33
|
<HeaderStatusArea model={model} />
|
|
34
34
|
<IconButton
|
|
35
|
-
onClick={() =>
|
|
35
|
+
onClick={() => {
|
|
36
|
+
model.queueDialog(onClose => [AboutDialog, { onClose }])
|
|
37
|
+
}}
|
|
36
38
|
>
|
|
37
39
|
<Help />
|
|
38
40
|
</IconButton>
|
|
@@ -13,13 +13,14 @@ const useStyles = makeStyles()({
|
|
|
13
13
|
},
|
|
14
14
|
})
|
|
15
15
|
|
|
16
|
-
const HeaderInfoArea = observer(({ model }: { model: MsaViewModel })
|
|
16
|
+
const HeaderInfoArea = observer(function ({ model }: { model: MsaViewModel }) {
|
|
17
17
|
const { mouseOverRowName, mouseCol } = model
|
|
18
18
|
const { classes } = useStyles()
|
|
19
19
|
return mouseOverRowName && mouseCol !== undefined ? (
|
|
20
20
|
<Typography className={classes.margin}>
|
|
21
21
|
{mouseOverRowName}:
|
|
22
|
-
{model.
|
|
22
|
+
{model.mouseOverCoordToGapRemovedRowCoord(mouseOverRowName, mouseCol)} (
|
|
23
|
+
{model.mouseOverCoordToRowLetter(mouseOverRowName, mouseCol)})
|
|
23
24
|
</Typography>
|
|
24
25
|
) : null
|
|
25
26
|
})
|
|
@@ -24,24 +24,29 @@ const HeaderMenu = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
24
24
|
{
|
|
25
25
|
label: 'Return to import form',
|
|
26
26
|
icon: FolderOpen,
|
|
27
|
-
onClick: () =>
|
|
27
|
+
onClick: () => {
|
|
28
|
+
model.reset()
|
|
29
|
+
},
|
|
28
30
|
},
|
|
29
31
|
{
|
|
30
32
|
label: 'Settings',
|
|
31
|
-
onClick: () =>
|
|
32
|
-
model.queueDialog(onClose => [SettingsDialog, { model, onClose }])
|
|
33
|
+
onClick: () => {
|
|
34
|
+
model.queueDialog(onClose => [SettingsDialog, { model, onClose }])
|
|
35
|
+
},
|
|
33
36
|
icon: Settings,
|
|
34
37
|
},
|
|
35
38
|
{
|
|
36
39
|
label: 'Metadata',
|
|
37
|
-
onClick: () =>
|
|
38
|
-
model.queueDialog(onClose => [MetadataDialog, { model, onClose }])
|
|
40
|
+
onClick: () => {
|
|
41
|
+
model.queueDialog(onClose => [MetadataDialog, { model, onClose }])
|
|
42
|
+
},
|
|
39
43
|
icon: Assignment,
|
|
40
44
|
},
|
|
41
45
|
{
|
|
42
46
|
label: 'Extra tracks',
|
|
43
|
-
onClick: () =>
|
|
44
|
-
model.queueDialog(onClose => [TracklistDialog, { model, onClose }])
|
|
47
|
+
onClick: () => {
|
|
48
|
+
model.queueDialog(onClose => [TracklistDialog, { model, onClose }])
|
|
49
|
+
},
|
|
45
50
|
icon: List,
|
|
46
51
|
},
|
|
47
52
|
]}
|
|
@@ -36,32 +36,38 @@ const HeaderMenuExtra = observer(({ model }: { model: MsaViewModel }) => {
|
|
|
36
36
|
{
|
|
37
37
|
label: 'Return to import form',
|
|
38
38
|
icon: FolderOpen,
|
|
39
|
-
onClick: () =>
|
|
39
|
+
onClick: () => {
|
|
40
|
+
model.reset()
|
|
41
|
+
},
|
|
40
42
|
},
|
|
41
43
|
{
|
|
42
44
|
label: 'Settings',
|
|
43
|
-
onClick: () =>
|
|
44
|
-
model.queueDialog(onClose => [SettingsDialog, { model, onClose }])
|
|
45
|
+
onClick: () => {
|
|
46
|
+
model.queueDialog(onClose => [SettingsDialog, { model, onClose }])
|
|
47
|
+
},
|
|
45
48
|
icon: Settings,
|
|
46
49
|
},
|
|
47
50
|
{
|
|
48
51
|
label: 'Metadata',
|
|
49
|
-
onClick: () =>
|
|
50
|
-
model.queueDialog(onClose => [MetadataDialog, { model, onClose }])
|
|
52
|
+
onClick: () => {
|
|
53
|
+
model.queueDialog(onClose => [MetadataDialog, { model, onClose }])
|
|
54
|
+
},
|
|
51
55
|
icon: Assignment,
|
|
52
56
|
},
|
|
53
57
|
{
|
|
54
58
|
label: 'Extra tracks',
|
|
55
|
-
onClick: () =>
|
|
56
|
-
model.queueDialog(onClose => [TracklistDialog, { model, onClose }])
|
|
59
|
+
onClick: () => {
|
|
60
|
+
model.queueDialog(onClose => [TracklistDialog, { model, onClose }])
|
|
61
|
+
},
|
|
57
62
|
icon: List,
|
|
58
63
|
},
|
|
59
64
|
|
|
60
65
|
{
|
|
61
66
|
label: 'Export SVG',
|
|
62
67
|
icon: PhotoCamera,
|
|
63
|
-
onClick: () =>
|
|
64
|
-
model.queueDialog(onClose => [ExportSVGDialog, { onClose, model }])
|
|
68
|
+
onClick: () => {
|
|
69
|
+
model.queueDialog(onClose => [ExportSVGDialog, { onClose, model }])
|
|
70
|
+
},
|
|
65
71
|
},
|
|
66
72
|
{
|
|
67
73
|
label: 'Features/protein domains',
|
|
@@ -70,20 +76,22 @@ const HeaderMenuExtra = observer(({ model }: { model: MsaViewModel }) => {
|
|
|
70
76
|
{
|
|
71
77
|
label: 'Open domains...',
|
|
72
78
|
icon: FolderOpen,
|
|
73
|
-
onClick: () =>
|
|
79
|
+
onClick: () => {
|
|
74
80
|
model.queueDialog(handleClose => [
|
|
75
81
|
UserProvidedDomainsDialog,
|
|
76
82
|
{ handleClose, model },
|
|
77
|
-
])
|
|
83
|
+
])
|
|
84
|
+
},
|
|
78
85
|
},
|
|
79
86
|
{
|
|
80
87
|
label: 'Query InterProScan for domains...',
|
|
81
88
|
icon: Search,
|
|
82
|
-
onClick: () =>
|
|
89
|
+
onClick: () => {
|
|
83
90
|
model.queueDialog(handleClose => [
|
|
84
91
|
InterProScanDialog,
|
|
85
92
|
{ handleClose, model },
|
|
86
|
-
])
|
|
93
|
+
])
|
|
94
|
+
},
|
|
87
95
|
},
|
|
88
96
|
{
|
|
89
97
|
label: `Show domains${noDomains ? ' (no domains loaded)' : ''}`,
|
|
@@ -91,7 +99,9 @@ const HeaderMenuExtra = observer(({ model }: { model: MsaViewModel }) => {
|
|
|
91
99
|
icon: Visibility,
|
|
92
100
|
checked: actuallyShowDomains ? showDomains : false,
|
|
93
101
|
type: 'checkbox',
|
|
94
|
-
onClick: () =>
|
|
102
|
+
onClick: () => {
|
|
103
|
+
model.setShowDomains(!showDomains)
|
|
104
|
+
},
|
|
95
105
|
},
|
|
96
106
|
{
|
|
97
107
|
label: `Use sub-row layout${noDomains ? ' (no domains loaded)' : ''}`,
|
|
@@ -99,7 +109,9 @@ const HeaderMenuExtra = observer(({ model }: { model: MsaViewModel }) => {
|
|
|
99
109
|
checked: actuallyShowDomains ? subFeatureRows : false,
|
|
100
110
|
icon: Sort,
|
|
101
111
|
type: 'checkbox',
|
|
102
|
-
onClick: () =>
|
|
112
|
+
onClick: () => {
|
|
113
|
+
model.setSubFeatureRows(!subFeatureRows)
|
|
114
|
+
},
|
|
103
115
|
},
|
|
104
116
|
{
|
|
105
117
|
label: `Filter domains${noDomains ? ' (no domains loaded)' : ''}`,
|
|
@@ -114,7 +126,7 @@ const HeaderMenuExtra = observer(({ model }: { model: MsaViewModel }) => {
|
|
|
114
126
|
},
|
|
115
127
|
],
|
|
116
128
|
},
|
|
117
|
-
...
|
|
129
|
+
...model.extraViewMenuItems(),
|
|
118
130
|
]}
|
|
119
131
|
>
|
|
120
132
|
<MoreVert />
|
|
@@ -19,30 +19,46 @@ const ZoomControls = observer(function ZoomControls({
|
|
|
19
19
|
}) {
|
|
20
20
|
return (
|
|
21
21
|
<>
|
|
22
|
-
<IconButton
|
|
22
|
+
<IconButton
|
|
23
|
+
onClick={() => {
|
|
24
|
+
model.zoomIn()
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
23
27
|
<ZoomIn />
|
|
24
28
|
</IconButton>
|
|
25
|
-
<IconButton
|
|
29
|
+
<IconButton
|
|
30
|
+
onClick={() => {
|
|
31
|
+
model.zoomOut()
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
26
34
|
<ZoomOut />
|
|
27
35
|
</IconButton>
|
|
28
36
|
<CascadingMenuButton
|
|
29
37
|
menuItems={[
|
|
30
38
|
{
|
|
31
39
|
label: 'Zoom in horizontal',
|
|
32
|
-
onClick: () =>
|
|
40
|
+
onClick: () => {
|
|
41
|
+
model.zoomInHorizontal()
|
|
42
|
+
},
|
|
33
43
|
},
|
|
34
44
|
{
|
|
35
45
|
label: 'Zoom in vertical',
|
|
36
|
-
onClick: () =>
|
|
46
|
+
onClick: () => {
|
|
47
|
+
model.zoomInVertical()
|
|
48
|
+
},
|
|
37
49
|
},
|
|
38
50
|
{
|
|
39
51
|
label: 'Zoom out horizontal',
|
|
40
|
-
onClick: () =>
|
|
52
|
+
onClick: () => {
|
|
53
|
+
model.zoomOutHorizontal()
|
|
54
|
+
},
|
|
41
55
|
},
|
|
42
56
|
|
|
43
57
|
{
|
|
44
58
|
label: 'Zoom out vertical',
|
|
45
|
-
onClick: () =>
|
|
59
|
+
onClick: () => {
|
|
60
|
+
model.zoomOutVertical()
|
|
61
|
+
},
|
|
46
62
|
},
|
|
47
63
|
{
|
|
48
64
|
label: 'Reset zoom to default',
|