react-msaview 3.1.7 → 3.1.8
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 +32 -32
- package/dist/components/Checkbox2.d.ts +7 -0
- package/dist/components/Checkbox2.js +10 -0
- package/dist/components/Checkbox2.js.map +1 -0
- package/dist/components/Loading.js +12 -4
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/MSAView.js +5 -8
- package/dist/components/MSAView.js.map +1 -1
- package/dist/components/SequenceTextArea.d.ts +4 -0
- package/dist/components/SequenceTextArea.js +38 -0
- package/dist/components/SequenceTextArea.js.map +1 -0
- package/dist/components/Track.js +9 -8
- package/dist/components/Track.js.map +1 -1
- package/dist/components/dialogs/AddTrackDialog.js +0 -1
- package/dist/components/dialogs/AddTrackDialog.js.map +1 -1
- package/dist/components/{ExportSVGDialog.d.ts → dialogs/ExportSVGDialog.d.ts} +1 -1
- package/dist/components/{ExportSVGDialog.js → dialogs/ExportSVGDialog.js} +3 -4
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -0
- package/dist/components/dialogs/FeatureDialog.d.ts +7 -0
- package/dist/components/dialogs/FeatureDialog.js +52 -0
- package/dist/components/dialogs/FeatureDialog.js.map +1 -0
- package/dist/components/dialogs/InterProScanDialog.d.ts +7 -0
- package/dist/components/dialogs/InterProScanDialog.js +163 -0
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -0
- package/dist/components/dialogs/MetadataDialog.js +6 -3
- package/dist/components/dialogs/MetadataDialog.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.js +6 -11
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/{Header.d.ts → header/Header.d.ts} +1 -1
- package/dist/components/header/Header.js +30 -0
- package/dist/components/header/Header.js.map +1 -0
- package/dist/components/{HeaderInfoArea.d.ts → header/HeaderInfoArea.d.ts} +2 -2
- package/dist/components/header/HeaderInfoArea.js +20 -0
- package/dist/components/header/HeaderInfoArea.js.map +1 -0
- package/dist/components/header/HeaderMenu.d.ts +6 -0
- package/dist/components/header/HeaderMenu.js +40 -0
- package/dist/components/header/HeaderMenu.js.map +1 -0
- package/dist/components/header/HeaderMenuExtra.d.ts +6 -0
- package/dist/components/header/HeaderMenuExtra.js +92 -0
- package/dist/components/header/HeaderMenuExtra.js.map +1 -0
- package/dist/components/header/HeaderStatusArea.d.ts +6 -0
- package/dist/components/header/HeaderStatusArea.js +20 -0
- package/dist/components/header/HeaderStatusArea.js.map +1 -0
- package/dist/components/{MultiAlignmentSelector.d.ts → header/MultiAlignmentSelector.d.ts} +1 -1
- package/dist/components/header/MultiAlignmentSelector.js.map +1 -0
- package/dist/components/{ZoomControls.d.ts → header/ZoomControls.d.ts} +1 -1
- package/dist/components/header/ZoomControls.js +15 -0
- package/dist/components/header/ZoomControls.js.map +1 -0
- package/dist/components/{ImportForm/index.js → import/ImportForm.js} +1 -1
- package/dist/components/import/ImportForm.js.map +1 -0
- package/dist/components/{ImportForm → import}/ImportFormExamples.js +6 -2
- package/dist/components/import/ImportFormExamples.js.map +1 -0
- package/dist/components/import/data/seq2.js.map +1 -0
- package/dist/components/import/util.js +10 -0
- package/dist/components/import/util.js.map +1 -0
- package/dist/components/{Minimap.d.ts → minimap/Minimap.d.ts} +1 -1
- package/dist/components/minimap/Minimap.js.map +1 -0
- package/dist/components/{MinimapSVG.d.ts → minimap/MinimapSVG.d.ts} +1 -1
- package/dist/components/minimap/MinimapSVG.js.map +1 -0
- package/dist/components/msa/Loading.js.map +1 -0
- package/dist/components/{MSAPanel → msa}/MSACanvas.js +3 -2
- package/dist/components/msa/MSACanvas.js.map +1 -0
- package/dist/components/{MSAPanel/MSABlock.js → msa/MSACanvasBlock.js} +21 -9
- package/dist/components/msa/MSACanvasBlock.js.map +1 -0
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -0
- package/dist/components/msa/MSAPanel.d.ts +6 -0
- package/dist/components/{MSAPanel/index.js → msa/MSAPanel.js} +6 -3
- package/dist/components/msa/MSAPanel.js.map +1 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +9 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +44 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -0
- package/dist/components/{MSAPanel → msa}/renderMSABlock.js +24 -20
- package/dist/components/msa/renderMSABlock.js.map +1 -0
- package/dist/components/msa/renderMSAMouseover.js.map +1 -0
- package/dist/components/tree/TreeBranchMenu.js.map +1 -0
- package/dist/components/{TreePanel → tree}/TreeCanvas.js +1 -1
- package/dist/components/tree/TreeCanvas.js.map +1 -0
- package/dist/components/{TreePanel → tree}/TreeCanvasBlock.js +1 -1
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -0
- package/dist/components/{TreePanel → tree}/TreeNodeMenu.js +2 -33
- package/dist/components/tree/TreeNodeMenu.js.map +1 -0
- package/dist/components/{TreePanel/index.js → tree/TreePanel.js} +2 -2
- package/dist/components/tree/TreePanel.js.map +1 -0
- package/dist/components/tree/TreeRuler.js.map +1 -0
- package/dist/components/{TreePanel → tree}/dialogs/TreeNodeInfoDialog.js +6 -2
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -0
- package/dist/components/{TreePanel → tree}/renderTreeCanvas.js +23 -37
- package/dist/components/tree/renderTreeCanvas.js.map +1 -0
- package/dist/fetchUtils.d.ts +5 -0
- package/dist/fetchUtils.js +23 -0
- package/dist/fetchUtils.js.map +1 -0
- package/dist/ggplotPalettes.d.ts +3 -0
- package/dist/ggplotPalettes.js +24 -0
- package/dist/ggplotPalettes.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/launchInterProScan.d.ts +32 -0
- package/dist/launchInterProScan.js +47 -0
- package/dist/launchInterProScan.js.map +1 -0
- package/dist/model/DataModel.js.map +1 -0
- package/dist/model/DialogQueue.js.map +1 -0
- package/dist/model/msaModel.d.ts +14 -0
- package/dist/model/msaModel.js +36 -0
- package/dist/model/msaModel.js.map +1 -0
- package/dist/model/treeModel.d.ts +46 -0
- package/dist/model/treeModel.js +105 -0
- package/dist/model/treeModel.js.map +1 -0
- package/dist/model.d.ts +261 -273
- package/dist/model.js +1043 -1029
- package/dist/model.js.map +1 -1
- package/dist/parseGFF.d.ts +10 -0
- package/dist/parseGFF.js +29 -0
- package/dist/parseGFF.js.map +1 -0
- package/dist/renderToSvg.js +23 -9
- package/dist/renderToSvg.js.map +1 -1
- package/dist/reparseTree.d.ts +2 -0
- package/dist/reparseTree.js +13 -0
- package/dist/reparseTree.js.map +1 -0
- package/dist/util.d.ts +4 -10
- package/dist/util.js +3 -28
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +12 -2
- package/src/components/Checkbox2.tsx +34 -0
- package/src/components/Loading.tsx +27 -11
- package/src/components/MSAView.tsx +6 -10
- package/src/components/SequenceTextArea.tsx +63 -0
- package/src/components/Track.tsx +8 -13
- package/src/components/dialogs/AddTrackDialog.tsx +0 -1
- package/src/components/{ExportSVGDialog.tsx → dialogs/ExportSVGDialog.tsx} +9 -16
- package/src/components/dialogs/FeatureDialog.tsx +109 -0
- package/src/components/dialogs/InterProScanDialog.tsx +230 -0
- package/src/components/dialogs/MetadataDialog.tsx +9 -2
- package/src/components/dialogs/SettingsDialog.tsx +10 -30
- package/src/components/header/Header.tsx +44 -0
- package/src/components/header/HeaderInfoArea.tsx +27 -0
- package/src/components/header/HeaderMenu.tsx +54 -0
- package/src/components/header/HeaderMenuExtra.tsx +108 -0
- package/src/components/header/HeaderStatusArea.tsx +31 -0
- package/src/components/{MultiAlignmentSelector.tsx → header/MultiAlignmentSelector.tsx} +1 -1
- package/src/components/header/ZoomControls.tsx +28 -0
- package/src/components/{ImportForm → import}/ImportFormExamples.tsx +12 -1
- package/src/components/{ImportForm → import}/util.ts +5 -10
- package/src/components/{Minimap.tsx → minimap/Minimap.tsx} +1 -1
- package/src/components/{MinimapSVG.tsx → minimap/MinimapSVG.tsx} +1 -1
- package/src/components/{MSAPanel → msa}/MSACanvas.tsx +3 -2
- package/src/components/{MSAPanel/MSABlock.tsx → msa/MSACanvasBlock.tsx} +25 -12
- package/src/components/{MSAPanel/index.tsx → msa/MSAPanel.tsx} +8 -2
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +88 -0
- package/src/components/{MSAPanel → msa}/renderMSABlock.ts +26 -20
- package/src/components/{TreePanel → tree}/TreeCanvas.tsx +1 -1
- package/src/components/{TreePanel → tree}/TreeCanvasBlock.tsx +1 -1
- package/src/components/{TreePanel → tree}/TreeNodeMenu.tsx +1 -53
- package/src/components/{TreePanel/index.tsx → tree/TreePanel.tsx} +1 -1
- package/src/components/{TreePanel → tree}/dialogs/TreeNodeInfoDialog.tsx +9 -2
- package/src/components/{TreePanel → tree}/renderTreeCanvas.ts +25 -41
- package/src/fetchUtils.ts +30 -0
- package/src/ggplotPalettes.ts +25 -0
- package/src/index.ts +1 -1
- package/src/launchInterProScan.ts +98 -0
- package/src/model/msaModel.ts +39 -0
- package/src/model/treeModel.ts +116 -0
- package/src/model.ts +1124 -1126
- package/src/parseGFF.ts +32 -0
- package/src/renderToSvg.tsx +27 -8
- package/src/reparseTree.ts +16 -0
- package/src/util.ts +4 -33
- package/src/version.ts +1 -1
- package/dist/DataModel.js.map +0 -1
- package/dist/DialogQueue.js.map +0 -1
- package/dist/SelectedStructuresMixin.d.ts +0 -46
- package/dist/SelectedStructuresMixin.js +0 -52
- package/dist/SelectedStructuresMixin.js.map +0 -1
- package/dist/StructureModel.d.ts +0 -9
- package/dist/StructureModel.js +0 -11
- package/dist/StructureModel.js.map +0 -1
- package/dist/UniprotTrack.d.ts +0 -27
- package/dist/UniprotTrack.js +0 -53
- package/dist/UniprotTrack.js.map +0 -1
- package/dist/components/BoxTrack.d.ts +0 -7
- package/dist/components/BoxTrack.js +0 -15
- package/dist/components/BoxTrack.js.map +0 -1
- package/dist/components/BoxTrackBlock.d.ts +0 -8
- package/dist/components/BoxTrackBlock.js +0 -136
- package/dist/components/BoxTrackBlock.js.map +0 -1
- package/dist/components/ExportSVGDialog.js.map +0 -1
- package/dist/components/Header.js +0 -62
- package/dist/components/Header.js.map +0 -1
- package/dist/components/HeaderInfoArea.js +0 -12
- package/dist/components/HeaderInfoArea.js.map +0 -1
- package/dist/components/ImportForm/ImportFormExamples.js.map +0 -1
- package/dist/components/ImportForm/data/seq2.js.map +0 -1
- package/dist/components/ImportForm/index.js.map +0 -1
- package/dist/components/ImportForm/util.js +0 -16
- package/dist/components/ImportForm/util.js.map +0 -1
- package/dist/components/MSAPanel/Loading.js.map +0 -1
- package/dist/components/MSAPanel/MSABlock.js.map +0 -1
- package/dist/components/MSAPanel/MSACanvas.js.map +0 -1
- package/dist/components/MSAPanel/MSAMouseoverCanvas.js.map +0 -1
- package/dist/components/MSAPanel/index.d.ts +0 -5
- package/dist/components/MSAPanel/index.js.map +0 -1
- package/dist/components/MSAPanel/renderMSABlock.js.map +0 -1
- package/dist/components/MSAPanel/renderMSAMouseover.js.map +0 -1
- package/dist/components/Minimap.js.map +0 -1
- package/dist/components/MinimapSVG.js.map +0 -1
- package/dist/components/MultiAlignmentSelector.js.map +0 -1
- package/dist/components/TreePanel/TreeBranchMenu.js.map +0 -1
- package/dist/components/TreePanel/TreeCanvas.js.map +0 -1
- package/dist/components/TreePanel/TreeCanvasBlock.js.map +0 -1
- package/dist/components/TreePanel/TreeNodeMenu.js.map +0 -1
- package/dist/components/TreePanel/TreeRuler.js.map +0 -1
- package/dist/components/TreePanel/dialogs/TreeNodeInfoDialog.js.map +0 -1
- package/dist/components/TreePanel/index.js.map +0 -1
- package/dist/components/TreePanel/renderTreeCanvas.js.map +0 -1
- package/dist/components/VerticalGuide.d.ts +0 -7
- package/dist/components/VerticalGuide.js +0 -30
- package/dist/components/VerticalGuide.js.map +0 -1
- package/dist/components/ZoomControls.js +0 -59
- package/dist/components/ZoomControls.js.map +0 -1
- package/src/SelectedStructuresMixin.ts +0 -59
- package/src/StructureModel.ts +0 -11
- package/src/UniprotTrack.ts +0 -59
- package/src/components/BoxTrack.tsx +0 -33
- package/src/components/BoxTrackBlock.tsx +0 -200
- package/src/components/Header.tsx +0 -99
- package/src/components/HeaderInfoArea.tsx +0 -21
- package/src/components/VerticalGuide.tsx +0 -50
- package/src/components/ZoomControls.tsx +0 -86
- package/dist/components/{MultiAlignmentSelector.js → header/MultiAlignmentSelector.js} +0 -0
- package/dist/components/{ImportForm/index.d.ts → import/ImportForm.d.ts} +0 -0
- package/dist/components/{ImportForm → import}/ImportFormExamples.d.ts +0 -0
- package/dist/components/{ImportForm → import}/data/seq2.d.ts +0 -0
- package/dist/components/{ImportForm → import}/data/seq2.js +0 -0
- package/dist/components/{ImportForm → import}/util.d.ts +0 -0
- package/dist/components/{Minimap.js → minimap/Minimap.js} +0 -0
- package/dist/components/{MinimapSVG.js → minimap/MinimapSVG.js} +0 -0
- package/dist/components/{MSAPanel → msa}/Loading.d.ts +0 -0
- package/dist/components/{MSAPanel → msa}/Loading.js +0 -0
- package/dist/components/{MSAPanel → msa}/MSACanvas.d.ts +0 -0
- package/dist/components/{MSAPanel/MSABlock.d.ts → msa/MSACanvasBlock.d.ts} +0 -0
- package/dist/components/{MSAPanel → msa}/MSAMouseoverCanvas.d.ts +0 -0
- package/dist/components/{MSAPanel → msa}/MSAMouseoverCanvas.js +0 -0
- package/dist/components/{MSAPanel → msa}/renderMSABlock.d.ts +1 -1
- /package/dist/components/{MSAPanel → msa}/renderMSAMouseover.d.ts +0 -0
- /package/dist/components/{MSAPanel → msa}/renderMSAMouseover.js +0 -0
- /package/dist/components/{TreePanel → tree}/TreeBranchMenu.d.ts +0 -0
- /package/dist/components/{TreePanel → tree}/TreeBranchMenu.js +0 -0
- /package/dist/components/{TreePanel → tree}/TreeCanvas.d.ts +0 -0
- /package/dist/components/{TreePanel → tree}/TreeCanvasBlock.d.ts +0 -0
- /package/dist/components/{TreePanel → tree}/TreeNodeMenu.d.ts +0 -0
- /package/dist/components/{TreePanel/index.d.ts → tree/TreePanel.d.ts} +0 -0
- /package/dist/components/{TreePanel → tree}/TreeRuler.d.ts +0 -0
- /package/dist/components/{TreePanel → tree}/TreeRuler.js +0 -0
- /package/dist/components/{TreePanel → tree}/dialogs/TreeNodeInfoDialog.d.ts +0 -0
- /package/dist/components/{TreePanel → tree}/renderTreeCanvas.d.ts +0 -0
- /package/dist/{DataModel.d.ts → model/DataModel.d.ts} +0 -0
- /package/dist/{DataModel.js → model/DataModel.js} +0 -0
- /package/dist/{DialogQueue.d.ts → model/DialogQueue.d.ts} +0 -0
- /package/dist/{DialogQueue.js → model/DialogQueue.js} +0 -0
- /package/src/components/{ImportForm/index.tsx → import/ImportForm.tsx} +0 -0
- /package/src/components/{ImportForm → import}/data/seq2.ts +0 -0
- /package/src/components/{MSAPanel → msa}/Loading.tsx +0 -0
- /package/src/components/{MSAPanel → msa}/MSAMouseoverCanvas.tsx +0 -0
- /package/src/components/{MSAPanel → msa}/renderMSAMouseover.ts +0 -0
- /package/src/components/{TreePanel → tree}/TreeBranchMenu.tsx +0 -0
- /package/src/components/{TreePanel → tree}/TreeRuler.tsx +0 -0
- /package/src/{DataModel.ts → model/DataModel.ts} +0 -0
- /package/src/{DialogQueue.ts → model/DialogQueue.ts} +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import React, { lazy } from 'react'
|
|
2
|
+
import { observer } from 'mobx-react'
|
|
3
|
+
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
|
|
4
|
+
|
|
5
|
+
// locals
|
|
6
|
+
import { MsaViewModel } from '../../model'
|
|
7
|
+
|
|
8
|
+
// icons
|
|
9
|
+
import MoreVert from '@mui/icons-material/MoreVert'
|
|
10
|
+
import Sort from '@mui/icons-material/Sort'
|
|
11
|
+
import Visibility from '@mui/icons-material/Visibility'
|
|
12
|
+
import FilterAlt from '@mui/icons-material/FilterAlt'
|
|
13
|
+
import Search from '@mui/icons-material/Search'
|
|
14
|
+
import PhotoCamera from '@mui/icons-material/PhotoCamera'
|
|
15
|
+
import RestartAlt from '@mui/icons-material/RestartAlt'
|
|
16
|
+
|
|
17
|
+
// lazies
|
|
18
|
+
const ExportSVGDialog = lazy(() => import('../dialogs/ExportSVGDialog'))
|
|
19
|
+
const FeatureFilterDialog = lazy(() => import('../dialogs/FeatureDialog'))
|
|
20
|
+
const InterProScanDialog = lazy(() => import('../dialogs/InterProScanDialog'))
|
|
21
|
+
|
|
22
|
+
const HeaderMenuExtra = observer(function ({ model }: { model: MsaViewModel }) {
|
|
23
|
+
const { featureMode, subFeatureRows, noAnnotations, interProScanJobIds } =
|
|
24
|
+
model
|
|
25
|
+
return (
|
|
26
|
+
<CascadingMenuButton
|
|
27
|
+
menuItems={[
|
|
28
|
+
{
|
|
29
|
+
label: 'Reset zoom to default',
|
|
30
|
+
icon: RestartAlt,
|
|
31
|
+
onClick: () => {
|
|
32
|
+
model.setColWidth(16)
|
|
33
|
+
model.setRowHeight(20)
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
label: 'Export SVG',
|
|
38
|
+
icon: PhotoCamera,
|
|
39
|
+
onClick: () =>
|
|
40
|
+
model.queueDialog(onClose => [ExportSVGDialog, { onClose, model }]),
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
label: 'Features/protein domains',
|
|
44
|
+
type: 'subMenu',
|
|
45
|
+
subMenu: [
|
|
46
|
+
{
|
|
47
|
+
label:
|
|
48
|
+
'Show domains' + (noAnnotations ? ' (no domains loaded)' : ''),
|
|
49
|
+
icon: Visibility,
|
|
50
|
+
checked: featureMode,
|
|
51
|
+
type: 'checkbox',
|
|
52
|
+
onClick: () => model.setFeatureMode(!featureMode),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
label: 'Use sub-row layout',
|
|
56
|
+
checked: subFeatureRows,
|
|
57
|
+
icon: Sort,
|
|
58
|
+
type: 'checkbox',
|
|
59
|
+
onClick: () => model.setSubFeatureRows(!subFeatureRows),
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: 'Filter domains',
|
|
63
|
+
icon: FilterAlt,
|
|
64
|
+
onClick: () => {
|
|
65
|
+
model.queueDialog(onClose => [
|
|
66
|
+
FeatureFilterDialog,
|
|
67
|
+
{ onClose, model },
|
|
68
|
+
])
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
label: 'Query InterProScan for domains...',
|
|
73
|
+
icon: Search,
|
|
74
|
+
onClick: () =>
|
|
75
|
+
model.queueDialog(onClose => [
|
|
76
|
+
InterProScanDialog,
|
|
77
|
+
{ onClose, model },
|
|
78
|
+
]),
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
label: 'Load previous InterProScan results...',
|
|
82
|
+
icon: Search,
|
|
83
|
+
type: 'subMenu',
|
|
84
|
+
subMenu: interProScanJobIds.length
|
|
85
|
+
? interProScanJobIds.map(({ jobId, date }) => ({
|
|
86
|
+
label:
|
|
87
|
+
new Date(date).toLocaleString('en-US') + ' - ' + jobId,
|
|
88
|
+
onClick: () => model.loadInterProScanResults(jobId),
|
|
89
|
+
}))
|
|
90
|
+
: [
|
|
91
|
+
{
|
|
92
|
+
label: 'No previous searches',
|
|
93
|
+
disabled: true,
|
|
94
|
+
onClick: () => {},
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
...(model.extraViewMenuItems?.() || []),
|
|
101
|
+
]}
|
|
102
|
+
>
|
|
103
|
+
<MoreVert />
|
|
104
|
+
</CascadingMenuButton>
|
|
105
|
+
)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export default HeaderMenuExtra
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Typography } from '@mui/material'
|
|
3
|
+
import { observer } from 'mobx-react'
|
|
4
|
+
import { makeStyles } from 'tss-react/mui'
|
|
5
|
+
|
|
6
|
+
// locals
|
|
7
|
+
import { MsaViewModel } from '../../model'
|
|
8
|
+
|
|
9
|
+
const useStyles = makeStyles()({
|
|
10
|
+
margin: {
|
|
11
|
+
margin: 'auto',
|
|
12
|
+
marginLeft: 10,
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const HeaderStatusArea = observer(({ model }: { model: MsaViewModel }) => {
|
|
17
|
+
const { status } = model
|
|
18
|
+
const { classes } = useStyles()
|
|
19
|
+
return status ? (
|
|
20
|
+
<Typography className={classes.margin}>
|
|
21
|
+
{status.msg}{' '}
|
|
22
|
+
{status.url ? (
|
|
23
|
+
<a href={status.url} target="_blank" rel="noreferrer">
|
|
24
|
+
(status)
|
|
25
|
+
</a>
|
|
26
|
+
) : null}
|
|
27
|
+
</Typography>
|
|
28
|
+
) : null
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
export default HeaderStatusArea
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { IconButton } from '@mui/material'
|
|
3
|
+
import { observer } from 'mobx-react'
|
|
4
|
+
|
|
5
|
+
// locals
|
|
6
|
+
import { MsaViewModel } from '../../model'
|
|
7
|
+
|
|
8
|
+
// icons
|
|
9
|
+
import ZoomIn from '@mui/icons-material/ZoomIn'
|
|
10
|
+
import ZoomOut from '@mui/icons-material/ZoomOut'
|
|
11
|
+
|
|
12
|
+
const ZoomControls = observer(function ZoomControls({
|
|
13
|
+
model,
|
|
14
|
+
}: {
|
|
15
|
+
model: MsaViewModel
|
|
16
|
+
}) {
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<IconButton onClick={() => model.zoomIn()}>
|
|
20
|
+
<ZoomIn />
|
|
21
|
+
</IconButton>
|
|
22
|
+
<IconButton onClick={() => model.zoomOut()}>
|
|
23
|
+
<ZoomOut />
|
|
24
|
+
</IconButton>
|
|
25
|
+
</>
|
|
26
|
+
)
|
|
27
|
+
})
|
|
28
|
+
export default ZoomControls
|
|
@@ -114,7 +114,7 @@ const ImportFormExamples = observer(function ({
|
|
|
114
114
|
load(
|
|
115
115
|
model,
|
|
116
116
|
{
|
|
117
|
-
uri: '/rhv_test-only.aligned_with_mafft_auto.fa',
|
|
117
|
+
uri: 'https://jbrowse.org/genomes/multiple_sequence_alignments/rhv_test-only.aligned_with_mafft_auto.fa',
|
|
118
118
|
locationType: 'UriLocation',
|
|
119
119
|
},
|
|
120
120
|
{
|
|
@@ -126,6 +126,17 @@ const ImportFormExamples = observer(function ({
|
|
|
126
126
|
>
|
|
127
127
|
MAFFT+VeryFastTree(17.9k samples)
|
|
128
128
|
</ListItem>
|
|
129
|
+
<ListItem
|
|
130
|
+
model={model}
|
|
131
|
+
onClick={() =>
|
|
132
|
+
load(model, {
|
|
133
|
+
uri: 'https://jbrowse.org/demos/ttc39a.mfa',
|
|
134
|
+
locationType: 'UriLocation',
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
>
|
|
138
|
+
Human BLAST results mfa
|
|
139
|
+
</ListItem>
|
|
129
140
|
</ul>
|
|
130
141
|
)
|
|
131
142
|
})
|
|
@@ -7,15 +7,10 @@ export async function load(
|
|
|
7
7
|
treeFile?: FileLocation,
|
|
8
8
|
) {
|
|
9
9
|
model.setError(undefined)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
await model.setTreeFilehandle(treeFile)
|
|
16
|
-
}
|
|
17
|
-
} catch (e) {
|
|
18
|
-
console.error(e)
|
|
19
|
-
model.setError(e)
|
|
10
|
+
if (msaFile) {
|
|
11
|
+
model.setMSAFilehandle(msaFile)
|
|
12
|
+
}
|
|
13
|
+
if (treeFile) {
|
|
14
|
+
model.setTreeFilehandle(treeFile)
|
|
20
15
|
}
|
|
21
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react'
|
|
2
2
|
import { observer } from 'mobx-react'
|
|
3
|
-
import { MsaViewModel } from '
|
|
3
|
+
import { MsaViewModel } from '../../model'
|
|
4
4
|
|
|
5
5
|
const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
|
|
6
6
|
const [mouseDown, setMouseDown] = useState<{
|
|
@@ -4,7 +4,7 @@ import normalizeWheel from 'normalize-wheel'
|
|
|
4
4
|
|
|
5
5
|
// locals
|
|
6
6
|
import { MsaViewModel } from '../../model'
|
|
7
|
-
import
|
|
7
|
+
import MSACanvasBlock from './MSACanvasBlock'
|
|
8
8
|
import Loading from './Loading'
|
|
9
9
|
|
|
10
10
|
const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
|
|
@@ -39,6 +39,7 @@ const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
39
39
|
})
|
|
40
40
|
}
|
|
41
41
|
origEvent.preventDefault()
|
|
42
|
+
origEvent.stopPropagation()
|
|
42
43
|
}
|
|
43
44
|
curr.addEventListener('wheel', onWheel)
|
|
44
45
|
return () => {
|
|
@@ -124,7 +125,7 @@ const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
124
125
|
<Loading />
|
|
125
126
|
) : (
|
|
126
127
|
blocks2d.map(([bx, by]) => (
|
|
127
|
-
<
|
|
128
|
+
<MSACanvasBlock
|
|
128
129
|
key={`${bx}_${by}`}
|
|
129
130
|
model={model}
|
|
130
131
|
offsetX={bx}
|
|
@@ -7,6 +7,7 @@ import { observer } from 'mobx-react'
|
|
|
7
7
|
import { renderMSABlock } from './renderMSABlock'
|
|
8
8
|
import { MsaViewModel } from '../../model'
|
|
9
9
|
import { colorContrast } from '../../util'
|
|
10
|
+
import { renderBoxFeatureCanvasBlock } from './renderBoxFeatureCanvasBlock'
|
|
10
11
|
|
|
11
12
|
const MSABlock = observer(function ({
|
|
12
13
|
model,
|
|
@@ -38,19 +39,31 @@ const MSABlock = observer(function ({
|
|
|
38
39
|
const ref = useRef<HTMLCanvasElement>(null)
|
|
39
40
|
useEffect(() => {
|
|
40
41
|
const ctx = ref.current?.getContext('2d')
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
if (!ctx) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
return autorun(() => {
|
|
46
|
+
ctx.resetTransform()
|
|
47
|
+
ctx.clearRect(0, 0, blockSize, blockSize)
|
|
48
|
+
if (model.featureMode) {
|
|
49
|
+
renderBoxFeatureCanvasBlock({
|
|
50
|
+
ctx,
|
|
51
|
+
offsetX,
|
|
52
|
+
offsetY,
|
|
53
|
+
model,
|
|
51
54
|
})
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
}
|
|
56
|
+
renderMSABlock({
|
|
57
|
+
ctx,
|
|
58
|
+
theme,
|
|
59
|
+
offsetX,
|
|
60
|
+
offsetY,
|
|
61
|
+
contrastScheme,
|
|
62
|
+
model,
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
}, [model, offsetX, offsetY, theme, blockSize, contrastScheme])
|
|
66
|
+
|
|
54
67
|
return (
|
|
55
68
|
<canvas
|
|
56
69
|
ref={ref}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
+
import { observer } from 'mobx-react'
|
|
3
|
+
|
|
4
|
+
// locals
|
|
2
5
|
import MSACanvas from './MSACanvas'
|
|
3
6
|
import MSAMouseoverCanvas from './MSAMouseoverCanvas'
|
|
7
|
+
// types
|
|
4
8
|
import { MsaViewModel } from '../../model'
|
|
5
9
|
|
|
6
|
-
|
|
10
|
+
const MSAPanel = observer(function ({ model }: { model: MsaViewModel }) {
|
|
7
11
|
return (
|
|
8
12
|
<div style={{ position: 'relative' }}>
|
|
9
13
|
<MSACanvas model={model} />
|
|
10
14
|
<MSAMouseoverCanvas model={model} />
|
|
11
15
|
</div>
|
|
12
16
|
)
|
|
13
|
-
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export default MSAPanel
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { HierarchyNode } from 'd3-hierarchy'
|
|
2
|
+
|
|
3
|
+
// locals
|
|
4
|
+
import { MsaViewModel } from '../../model'
|
|
5
|
+
import { NodeWithIdsAndLength } from '../../util'
|
|
6
|
+
|
|
7
|
+
export function renderBoxFeatureCanvasBlock({
|
|
8
|
+
model,
|
|
9
|
+
offsetX,
|
|
10
|
+
offsetY,
|
|
11
|
+
ctx,
|
|
12
|
+
highResScaleFactorOverride,
|
|
13
|
+
blockSizeYOverride,
|
|
14
|
+
}: {
|
|
15
|
+
offsetX: number
|
|
16
|
+
offsetY: number
|
|
17
|
+
model: MsaViewModel
|
|
18
|
+
ctx: CanvasRenderingContext2D
|
|
19
|
+
highResScaleFactorOverride?: number
|
|
20
|
+
blockSizeYOverride?: number
|
|
21
|
+
}) {
|
|
22
|
+
const { hierarchy, blockSize, rowHeight, highResScaleFactor, featureMode } =
|
|
23
|
+
model
|
|
24
|
+
if (featureMode) {
|
|
25
|
+
const k = highResScaleFactorOverride || highResScaleFactor
|
|
26
|
+
const by = blockSizeYOverride || blockSize
|
|
27
|
+
ctx.resetTransform()
|
|
28
|
+
ctx.scale(k, k)
|
|
29
|
+
ctx.translate(-offsetX, rowHeight / 2 - offsetY)
|
|
30
|
+
|
|
31
|
+
const leaves = hierarchy.leaves()
|
|
32
|
+
const yStart = Math.max(0, Math.floor((offsetY - rowHeight) / rowHeight))
|
|
33
|
+
const yEnd = Math.max(0, Math.ceil((offsetY + by + rowHeight) / rowHeight))
|
|
34
|
+
const visibleLeaves = leaves.slice(yStart, yEnd)
|
|
35
|
+
|
|
36
|
+
drawTiles({
|
|
37
|
+
model,
|
|
38
|
+
ctx,
|
|
39
|
+
visibleLeaves,
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function drawTiles({
|
|
45
|
+
model,
|
|
46
|
+
ctx,
|
|
47
|
+
visibleLeaves,
|
|
48
|
+
}: {
|
|
49
|
+
model: MsaViewModel
|
|
50
|
+
ctx: CanvasRenderingContext2D
|
|
51
|
+
visibleLeaves: HierarchyNode<NodeWithIdsAndLength>[]
|
|
52
|
+
}) {
|
|
53
|
+
const {
|
|
54
|
+
subFeatureRows,
|
|
55
|
+
colWidth,
|
|
56
|
+
rowHeight,
|
|
57
|
+
fillPalette,
|
|
58
|
+
strokePalette,
|
|
59
|
+
tidyFilteredGatheredAnnotations,
|
|
60
|
+
} = model
|
|
61
|
+
|
|
62
|
+
for (const node of visibleLeaves) {
|
|
63
|
+
const {
|
|
64
|
+
x,
|
|
65
|
+
data: { name },
|
|
66
|
+
} = node
|
|
67
|
+
const y = x!
|
|
68
|
+
|
|
69
|
+
const entry = tidyFilteredGatheredAnnotations?.[name]
|
|
70
|
+
|
|
71
|
+
let j = 0
|
|
72
|
+
if (entry) {
|
|
73
|
+
for (const { start, end, accession } of entry) {
|
|
74
|
+
const m1 = model.seqCoordToRowSpecificGlobalCoord(name, start - 1)
|
|
75
|
+
const m2 = model.seqCoordToRowSpecificGlobalCoord(name, end)
|
|
76
|
+
const x = m1 * colWidth
|
|
77
|
+
ctx.fillStyle = fillPalette[accession]
|
|
78
|
+
ctx.strokeStyle = strokePalette[accession]
|
|
79
|
+
const h = subFeatureRows ? 4 : rowHeight
|
|
80
|
+
const t = y - rowHeight + (subFeatureRows ? j * h : 0)
|
|
81
|
+
const lw = colWidth * (m2 - m1)
|
|
82
|
+
ctx.fillRect(x, t, lw, h)
|
|
83
|
+
ctx.strokeRect(x, t, lw, h)
|
|
84
|
+
j++
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { HierarchyNode } from 'd3-hierarchy'
|
|
2
|
+
import { Theme } from '@mui/material'
|
|
3
|
+
|
|
1
4
|
// locals
|
|
2
5
|
import { MsaViewModel } from '../../model'
|
|
3
6
|
import { getClustalXColor, getPercentIdentityColor } from '../../colorSchemes'
|
|
4
7
|
import { NodeWithIdsAndLength } from '../../util'
|
|
5
|
-
import { HierarchyNode } from 'd3-hierarchy'
|
|
6
|
-
import { Theme } from '@mui/material'
|
|
7
8
|
|
|
8
9
|
export function renderMSABlock({
|
|
9
10
|
model,
|
|
@@ -33,13 +34,13 @@ export function renderMSABlock({
|
|
|
33
34
|
rowHeight,
|
|
34
35
|
fontSize,
|
|
35
36
|
highResScaleFactor,
|
|
37
|
+
featureMode,
|
|
36
38
|
} = model
|
|
37
39
|
const k = highResScaleFactorOverride || highResScaleFactor
|
|
38
40
|
const bx = blockSizeXOverride || blockSize
|
|
39
41
|
const by = blockSizeYOverride || blockSize
|
|
40
42
|
ctx.resetTransform()
|
|
41
43
|
ctx.scale(k, k)
|
|
42
|
-
ctx.clearRect(0, 0, bx, by)
|
|
43
44
|
ctx.translate(-offsetX, rowHeight / 2 - offsetY)
|
|
44
45
|
ctx.textAlign = 'center'
|
|
45
46
|
ctx.font = ctx.font.replace(/\d+px/, `${fontSize}px`)
|
|
@@ -52,16 +53,18 @@ export function renderMSABlock({
|
|
|
52
53
|
const xEnd = Math.max(0, Math.ceil((offsetX + bx) / colWidth))
|
|
53
54
|
const visibleLeaves = leaves.slice(yStart, yEnd)
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
if (!featureMode) {
|
|
57
|
+
drawTiles({
|
|
58
|
+
model,
|
|
59
|
+
ctx,
|
|
60
|
+
theme,
|
|
61
|
+
offsetX,
|
|
62
|
+
offsetY,
|
|
63
|
+
xStart,
|
|
64
|
+
xEnd,
|
|
65
|
+
visibleLeaves,
|
|
66
|
+
})
|
|
67
|
+
}
|
|
65
68
|
drawText({
|
|
66
69
|
model,
|
|
67
70
|
ctx,
|
|
@@ -72,6 +75,7 @@ export function renderMSABlock({
|
|
|
72
75
|
xEnd,
|
|
73
76
|
visibleLeaves,
|
|
74
77
|
})
|
|
78
|
+
ctx.resetTransform()
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
function drawTiles({
|
|
@@ -104,11 +108,9 @@ function drawTiles({
|
|
|
104
108
|
|
|
105
109
|
for (const node of visibleLeaves) {
|
|
106
110
|
const {
|
|
107
|
-
// @ts-expect-error
|
|
108
|
-
x: y,
|
|
109
111
|
data: { name },
|
|
110
112
|
} = node
|
|
111
|
-
|
|
113
|
+
const y = node.x!
|
|
112
114
|
const str = columns[name]?.slice(xStart, xEnd)
|
|
113
115
|
for (let i = 0; i < str?.length; i++) {
|
|
114
116
|
const letter = str[i]
|
|
@@ -150,14 +152,14 @@ function drawText({
|
|
|
150
152
|
xStart: number
|
|
151
153
|
xEnd: number
|
|
152
154
|
}) {
|
|
153
|
-
const { bgColor, colorScheme, columns, colWidth, rowHeight } =
|
|
155
|
+
const { bgColor, featureMode, colorScheme, columns, colWidth, rowHeight } =
|
|
156
|
+
model
|
|
154
157
|
if (rowHeight >= 5 && colWidth > rowHeight / 2) {
|
|
155
158
|
for (const node of visibleLeaves) {
|
|
156
159
|
const {
|
|
157
|
-
// @ts-expect-error
|
|
158
|
-
x: y,
|
|
159
160
|
data: { name },
|
|
160
161
|
} = node
|
|
162
|
+
const y = node.x!
|
|
161
163
|
const str = columns[name]?.slice(xStart, xEnd)
|
|
162
164
|
for (let i = 0; i < str?.length; i++) {
|
|
163
165
|
const letter = str[i]
|
|
@@ -166,7 +168,11 @@ function drawText({
|
|
|
166
168
|
const x = i * colWidth + offsetX - (offsetX % colWidth)
|
|
167
169
|
|
|
168
170
|
// note: -rowHeight/4 matches +rowHeight/4 in tree
|
|
169
|
-
ctx.fillStyle =
|
|
171
|
+
ctx.fillStyle = featureMode
|
|
172
|
+
? 'black'
|
|
173
|
+
: bgColor
|
|
174
|
+
? contrast
|
|
175
|
+
: color || 'black'
|
|
170
176
|
ctx.fillText(letter, x + colWidth / 2, y - rowHeight / 4)
|
|
171
177
|
}
|
|
172
178
|
}
|
|
@@ -33,6 +33,7 @@ const TreeCanvas = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
33
33
|
})
|
|
34
34
|
}
|
|
35
35
|
origEvent.preventDefault()
|
|
36
|
+
origEvent.stopPropagation()
|
|
36
37
|
}
|
|
37
38
|
curr.addEventListener('wheel', onWheel)
|
|
38
39
|
return () => {
|
|
@@ -113,7 +114,6 @@ const TreeCanvas = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
113
114
|
style={{
|
|
114
115
|
height,
|
|
115
116
|
position: 'relative',
|
|
116
|
-
overflow: 'hidden',
|
|
117
117
|
width: treeWidth + padding,
|
|
118
118
|
}}
|
|
119
119
|
>
|
|
@@ -17,9 +17,7 @@ const TreeMenu = observer(function ({
|
|
|
17
17
|
model: MsaViewModel
|
|
18
18
|
onClose: () => void
|
|
19
19
|
}) {
|
|
20
|
-
const {
|
|
21
|
-
const nodeDetails = node ? model.getRowData(node.name) : undefined
|
|
22
|
-
|
|
20
|
+
const { collapsed, collapsed2 } = model
|
|
23
21
|
return (
|
|
24
22
|
<Menu
|
|
25
23
|
anchorReference="anchorPosition"
|
|
@@ -72,56 +70,6 @@ const TreeMenu = observer(function ({
|
|
|
72
70
|
? 'Show node'
|
|
73
71
|
: 'Hide node'}
|
|
74
72
|
</MenuItem>
|
|
75
|
-
|
|
76
|
-
{structures[node.name]?.map(entry =>
|
|
77
|
-
!selectedStructures.some(n => n.id === node.name) ? (
|
|
78
|
-
<MenuItem
|
|
79
|
-
key={JSON.stringify(entry)}
|
|
80
|
-
dense
|
|
81
|
-
onClick={() => {
|
|
82
|
-
model.addStructureToSelection({
|
|
83
|
-
structure: entry,
|
|
84
|
-
id: node.name,
|
|
85
|
-
})
|
|
86
|
-
onClose()
|
|
87
|
-
}}
|
|
88
|
-
>
|
|
89
|
-
Add PDB to selection ({entry.pdb})
|
|
90
|
-
</MenuItem>
|
|
91
|
-
) : (
|
|
92
|
-
<MenuItem
|
|
93
|
-
key={JSON.stringify(entry)}
|
|
94
|
-
dense
|
|
95
|
-
onClick={() => {
|
|
96
|
-
model.removeStructureFromSelection({
|
|
97
|
-
structure: entry,
|
|
98
|
-
id: node.name,
|
|
99
|
-
})
|
|
100
|
-
onClose()
|
|
101
|
-
}}
|
|
102
|
-
>
|
|
103
|
-
Remove PDB from selection ({entry.pdb})
|
|
104
|
-
</MenuItem>
|
|
105
|
-
),
|
|
106
|
-
)}
|
|
107
|
-
|
|
108
|
-
{// @ts-expect-error
|
|
109
|
-
nodeDetails?.data.accession?.map(accession => (
|
|
110
|
-
<MenuItem
|
|
111
|
-
dense
|
|
112
|
-
key={accession}
|
|
113
|
-
onClick={() => {
|
|
114
|
-
model.addUniprotTrack({
|
|
115
|
-
// @ts-expect-error
|
|
116
|
-
name: nodeDetails?.data.name,
|
|
117
|
-
accession,
|
|
118
|
-
})
|
|
119
|
-
onClose()
|
|
120
|
-
}}
|
|
121
|
-
>
|
|
122
|
-
Open UniProt track ({accession})
|
|
123
|
-
</MenuItem>
|
|
124
|
-
))}
|
|
125
73
|
</Menu>
|
|
126
74
|
)
|
|
127
75
|
})
|
|
@@ -7,7 +7,7 @@ import TreeCanvas from './TreeCanvas'
|
|
|
7
7
|
const TreePanel = observer(function ({ model }: { model: MsaViewModel }) {
|
|
8
8
|
const { treeAreaWidth } = model
|
|
9
9
|
return (
|
|
10
|
-
<div style={{ flexShrink: 0, width: treeAreaWidth }}>
|
|
10
|
+
<div style={{ overflow: 'hidden', flexShrink: 0, width: treeAreaWidth }}>
|
|
11
11
|
<TreeCanvas model={model} />
|
|
12
12
|
</div>
|
|
13
13
|
)
|
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
Attributes,
|
|
7
7
|
BaseCard,
|
|
8
8
|
} from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
|
|
9
|
+
|
|
10
|
+
// locals
|
|
9
11
|
import { MsaViewModel } from '../../../model'
|
|
12
|
+
import SequenceTextArea from '../../SequenceTextArea'
|
|
10
13
|
|
|
11
14
|
export default observer(function ({
|
|
12
15
|
info,
|
|
@@ -19,14 +22,18 @@ export default observer(function ({
|
|
|
19
22
|
nodeName: string
|
|
20
23
|
onClose: () => void
|
|
21
24
|
}) {
|
|
22
|
-
const { treeMetadata } = model
|
|
25
|
+
const { treeMetadata, rows } = model
|
|
23
26
|
const metadata = treeMetadata[nodeName]
|
|
27
|
+
const [name, sequence] = rows.find(f => f[0] === nodeName)!
|
|
24
28
|
return (
|
|
25
|
-
<Dialog onClose={() => onClose()} open title="Tree node info">
|
|
29
|
+
<Dialog onClose={() => onClose()} open title="Tree node info" maxWidth="xl">
|
|
26
30
|
<DialogContent>
|
|
27
31
|
<BaseCard title="Attributes">
|
|
28
32
|
<Attributes attributes={{ nodeName, ...info }} />
|
|
29
33
|
</BaseCard>
|
|
34
|
+
<BaseCard title="Sequence">
|
|
35
|
+
<SequenceTextArea str={[[name, sequence]]} />
|
|
36
|
+
</BaseCard>
|
|
30
37
|
{metadata ? (
|
|
31
38
|
<BaseCard title="Extra metadata">
|
|
32
39
|
<Attributes attributes={metadata} />
|