react-msaview 5.0.7 → 5.0.13
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 +25 -25
- package/bundle/index.js.map +1 -1
- package/dist/components/Checkbox2.js +3 -6
- package/dist/components/Checkbox2.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +14 -0
- package/dist/components/MSAViewer.js +34 -0
- package/dist/components/MSAViewer.js.map +1 -0
- package/dist/components/Track.js +5 -24
- package/dist/components/Track.js.map +1 -1
- package/dist/components/dialogs/DomainDialog.js +2 -5
- package/dist/components/dialogs/DomainDialog.js.map +1 -1
- package/dist/components/dialogs/InterProScanDialog.js +7 -7
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.js +3 -19
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/header/ColorSchemeMenu.d.ts +6 -0
- package/dist/components/header/ColorSchemeMenu.js +19 -0
- package/dist/components/header/ColorSchemeMenu.js.map +1 -0
- package/dist/components/header/{ZoomStar.d.ts → FileMenu.d.ts} +2 -2
- package/dist/components/header/FileMenu.js +71 -0
- package/dist/components/header/FileMenu.js.map +1 -0
- package/dist/components/header/Header.js +8 -6
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderMenu.js +3 -145
- package/dist/components/header/HeaderMenu.js.map +1 -1
- package/dist/components/header/MSASettingsMenu.d.ts +6 -0
- package/dist/components/header/MSASettingsMenu.js +36 -0
- package/dist/components/header/MSASettingsMenu.js.map +1 -0
- package/dist/components/header/SettingsMenu.js +1 -21
- package/dist/components/header/SettingsMenu.js.map +1 -1
- package/dist/components/header/TreeSettingsMenu.d.ts +6 -0
- package/dist/components/header/TreeSettingsMenu.js +74 -0
- package/dist/components/header/TreeSettingsMenu.js.map +1 -0
- package/dist/components/header/ZoomMenu.js +0 -8
- package/dist/components/header/ZoomMenu.js.map +1 -1
- package/dist/components/header/getDomainsMenu.d.ts +31 -0
- package/dist/components/header/getDomainsMenu.js +75 -0
- package/dist/components/header/getDomainsMenu.js.map +1 -0
- package/dist/components/import/ImportFormExamples.js +21 -19
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/msa/MSACanvas.js +13 -84
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +1 -3
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.js +2 -4
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +1 -7
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/tree/TreeCanvas.js +14 -91
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.js +5 -16
- package/dist/components/tree/TreeNodeMenu.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.js +4 -12
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/constants.js.map +1 -1
- package/dist/fetchUtils.d.ts +0 -1
- package/dist/fetchUtils.js +0 -4
- package/dist/fetchUtils.js.map +1 -1
- package/dist/flatToTree.d.ts +0 -5
- package/dist/flatToTree.js +13 -30
- package/dist/flatToTree.js.map +1 -1
- package/dist/hierarchy.d.ts +28 -0
- package/dist/hierarchy.js +164 -0
- package/dist/hierarchy.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/launchInterProScan.d.ts +0 -5
- package/dist/launchInterProScan.js +5 -3
- package/dist/launchInterProScan.js.map +1 -1
- package/dist/model/DataModel.d.ts +9 -0
- package/dist/model/DataModel.js +12 -1
- package/dist/model/DataModel.js.map +1 -1
- package/dist/model/msaModel.d.ts +3 -0
- package/dist/model/msaModel.js +0 -1
- package/dist/model/msaModel.js.map +1 -1
- package/dist/model/treeModel.d.ts +3 -6
- package/dist/model/treeModel.js +3 -15
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +24 -77
- package/dist/model.js +117 -239
- package/dist/model.js.map +1 -1
- package/dist/neighborJoining.js +38 -629
- package/dist/neighborJoining.js.map +1 -1
- package/dist/parseAsn1.d.ts +0 -12
- package/dist/parseAsn1.js +125 -332
- package/dist/parseAsn1.js.map +1 -1
- package/dist/useWheelScroll.d.ts +8 -0
- package/dist/useWheelScroll.js +93 -0
- package/dist/useWheelScroll.js.map +1 -0
- package/dist/util.d.ts +1 -6
- package/dist/util.js +5 -34
- package/dist/util.js.map +1 -1
- package/dist/vendor/copyToClipboard.d.ts +1 -10
- package/dist/vendor/copyToClipboard.js +14 -109
- package/dist/vendor/copyToClipboard.js.map +1 -1
- package/dist/vendor/fileSaver.d.ts +1 -11
- package/dist/vendor/fileSaver.js +7 -76
- package/dist/vendor/fileSaver.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +10 -13
- package/src/collapseLogic.test.ts +115 -0
- package/src/components/Checkbox2.tsx +9 -18
- package/src/components/MSAViewer.tsx +67 -0
- package/src/components/Track.tsx +10 -26
- package/src/components/dialogs/DomainDialog.tsx +4 -5
- package/src/components/dialogs/InterProScanDialog.tsx +7 -7
- package/src/components/dialogs/SettingsDialog.tsx +0 -37
- package/src/components/header/ColorSchemeMenu.tsx +35 -0
- package/src/components/header/FileMenu.tsx +84 -0
- package/src/components/header/Header.tsx +8 -6
- package/src/components/header/HeaderMenu.tsx +4 -155
- package/src/components/header/MSASettingsMenu.tsx +48 -0
- package/src/components/header/SettingsMenu.tsx +0 -23
- package/src/components/header/TreeSettingsMenu.tsx +96 -0
- package/src/components/header/ZoomMenu.tsx +0 -8
- package/src/components/header/getDomainsMenu.ts +83 -0
- package/src/components/import/ImportFormExamples.tsx +37 -34
- package/src/components/msa/MSACanvas.tsx +21 -91
- package/src/components/msa/MSACanvasBlock.tsx +1 -3
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +1 -1
- package/src/components/msa/renderMSABlock.ts +2 -5
- package/src/components/msa/renderMSAMouseover.ts +0 -6
- package/src/components/tree/TreeCanvas.tsx +35 -100
- package/src/components/tree/TreeNodeMenu.tsx +5 -14
- package/src/components/tree/renderTreeCanvas.ts +8 -21
- package/src/constants.ts +0 -2
- package/src/fetchUtils.ts +0 -5
- package/src/flatToTree.ts +20 -38
- package/src/hierarchy.test.ts +120 -0
- package/src/hierarchy.ts +220 -0
- package/src/index.ts +2 -0
- package/src/launchInterProScan.ts +4 -3
- package/src/model/DataModel.ts +12 -1
- package/src/model/msaModel.ts +0 -2
- package/src/model/treeModel.ts +2 -18
- package/src/model.ts +179 -278
- package/src/neighborJoining.ts +38 -628
- package/src/parseAsn1.test.ts +4 -1
- package/src/parseAsn1.ts +135 -405
- package/src/useWheelScroll.ts +109 -0
- package/src/util.ts +5 -50
- package/src/vendor/copyToClipboard.ts +14 -122
- package/src/vendor/fileSaver.ts +8 -105
- package/src/version.ts +1 -1
- package/dist/components/dialogs/AddTrackDialog.d.ts +0 -8
- package/dist/components/dialogs/AddTrackDialog.js +0 -30
- package/dist/components/dialogs/AddTrackDialog.js.map +0 -1
- package/dist/components/dialogs/TabPanel.d.ts +0 -6
- package/dist/components/dialogs/TabPanel.js +0 -6
- package/dist/components/dialogs/TabPanel.js.map +0 -1
- package/dist/components/header/ZoomStar.js +0 -40
- package/dist/components/header/ZoomStar.js.map +0 -1
- package/dist/layout.d.ts +0 -26
- package/dist/layout.js +0 -74
- package/dist/layout.js.map +0 -1
- package/dist/reparseTree.d.ts +0 -2
- package/dist/reparseTree.js +0 -15
- package/dist/reparseTree.js.map +0 -1
- package/src/components/dialogs/AddTrackDialog.tsx +0 -85
- package/src/components/dialogs/TabPanel.tsx +0 -19
- package/src/components/header/ZoomStar.tsx +0 -74
- package/src/createPaletteMap.test.ts +0 -57
- package/src/layout.ts +0 -118
- package/src/reparseTree.ts +0 -18
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { collapse, find, hierarchy, leaves, sort, sum } from './hierarchy.ts'
|
|
4
|
+
|
|
5
|
+
import type { NodeWithIds } from './types.ts'
|
|
6
|
+
|
|
7
|
+
function buildRoot(tree: NodeWithIds, collapsed: string[], showOnly?: string) {
|
|
8
|
+
let hier = hierarchy(tree, d => d.children)
|
|
9
|
+
sum(hier, d => (d.children.length > 0 ? 0 : 1))
|
|
10
|
+
sort(hier, (a, b) => (a.data.length ?? 1) - (b.data.length ?? 1))
|
|
11
|
+
|
|
12
|
+
if (showOnly) {
|
|
13
|
+
const res = find(hier, n => n.data.id === showOnly)
|
|
14
|
+
if (res) {
|
|
15
|
+
hier = res
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
for (const collapsedId of collapsed) {
|
|
20
|
+
const node = find(hier, n => n.data.id === collapsedId)
|
|
21
|
+
if (!node) {
|
|
22
|
+
continue
|
|
23
|
+
}
|
|
24
|
+
if (node.children) {
|
|
25
|
+
collapse(node)
|
|
26
|
+
} else if (node.parent?.children) {
|
|
27
|
+
node.parent.children = node.parent.children.filter(
|
|
28
|
+
c => c.data.id !== collapsedId,
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return hier
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function simpleTree(): NodeWithIds {
|
|
37
|
+
return {
|
|
38
|
+
id: 'root',
|
|
39
|
+
name: 'root',
|
|
40
|
+
children: [
|
|
41
|
+
{
|
|
42
|
+
id: 'clade1',
|
|
43
|
+
name: 'clade1',
|
|
44
|
+
children: [
|
|
45
|
+
{ id: 'seq1', name: 'seq1', children: [] },
|
|
46
|
+
{ id: 'seq2', name: 'seq2', children: [] },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'clade2',
|
|
51
|
+
name: 'clade2',
|
|
52
|
+
children: [
|
|
53
|
+
{ id: 'seq3', name: 'seq3', children: [] },
|
|
54
|
+
{ id: 'seq4', name: 'seq4', children: [] },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
describe('collapse logic (mirrors model.root getter)', () => {
|
|
62
|
+
test('no collapsed nodes returns all leaves', () => {
|
|
63
|
+
const root = buildRoot(simpleTree(), [])
|
|
64
|
+
expect(leaves(root).map(n => n.data.name)).toEqual([
|
|
65
|
+
'seq1',
|
|
66
|
+
'seq2',
|
|
67
|
+
'seq3',
|
|
68
|
+
'seq4',
|
|
69
|
+
])
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('collapsing a branch hides its children', () => {
|
|
73
|
+
const root = buildRoot(simpleTree(), ['clade1'])
|
|
74
|
+
const l = leaves(root).map(n => n.data.name)
|
|
75
|
+
expect(l).toEqual(['clade1', 'seq3', 'seq4'])
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('collapsing a leaf node removes it', () => {
|
|
79
|
+
const root = buildRoot(simpleTree(), ['seq2'])
|
|
80
|
+
const l = leaves(root).map(n => n.data.name)
|
|
81
|
+
expect(l).toEqual(['seq1', 'seq3', 'seq4'])
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('collapsing multiple leaves', () => {
|
|
85
|
+
const root = buildRoot(simpleTree(), ['seq1', 'seq4'])
|
|
86
|
+
const l = leaves(root).map(n => n.data.name)
|
|
87
|
+
expect(l).toEqual(['seq2', 'seq3'])
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test('collapsing a branch and a leaf in another branch', () => {
|
|
91
|
+
const root = buildRoot(simpleTree(), ['clade1', 'seq3'])
|
|
92
|
+
const l = leaves(root).map(n => n.data.name)
|
|
93
|
+
expect(l).toEqual(['clade1', 'seq4'])
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('collapsing nonexistent id is a no-op', () => {
|
|
97
|
+
const root = buildRoot(simpleTree(), ['doesnotexist'])
|
|
98
|
+
expect(leaves(root).map(n => n.data.name)).toEqual([
|
|
99
|
+
'seq1',
|
|
100
|
+
'seq2',
|
|
101
|
+
'seq3',
|
|
102
|
+
'seq4',
|
|
103
|
+
])
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('showOnly focuses on a subtree', () => {
|
|
107
|
+
const root = buildRoot(simpleTree(), [], 'clade2')
|
|
108
|
+
expect(leaves(root).map(n => n.data.name)).toEqual(['seq3', 'seq4'])
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test('showOnly + collapse within subtree', () => {
|
|
112
|
+
const root = buildRoot(simpleTree(), ['seq3'], 'clade2')
|
|
113
|
+
expect(leaves(root).map(n => n.data.name)).toEqual(['seq4'])
|
|
114
|
+
})
|
|
115
|
+
})
|
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
Checkbox,
|
|
5
|
-
FormControlLabel,
|
|
6
|
-
type FormControlLabelProps,
|
|
7
|
-
} from '@mui/material'
|
|
3
|
+
import { Checkbox, FormControlLabel } from '@mui/material'
|
|
8
4
|
|
|
9
|
-
function FormControlLabel2(rest: FormControlLabelProps) {
|
|
10
|
-
return (
|
|
11
|
-
<div>
|
|
12
|
-
<FormControlLabel {...rest} />
|
|
13
|
-
</div>
|
|
14
|
-
)
|
|
15
|
-
}
|
|
16
5
|
export default function Checkbox2({
|
|
17
6
|
checked,
|
|
18
7
|
label,
|
|
@@ -25,11 +14,13 @@ export default function Checkbox2({
|
|
|
25
14
|
onChange: () => void
|
|
26
15
|
}) {
|
|
27
16
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
17
|
+
<div>
|
|
18
|
+
<FormControlLabel
|
|
19
|
+
control={
|
|
20
|
+
<Checkbox disabled={disabled} checked={checked} onChange={onChange} />
|
|
21
|
+
}
|
|
22
|
+
label={label}
|
|
23
|
+
/>
|
|
24
|
+
</div>
|
|
34
25
|
)
|
|
35
26
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { useEffect, useMemo } from 'react'
|
|
2
|
+
|
|
3
|
+
import { createJBrowseTheme } from '@jbrowse/core/ui/theme'
|
|
4
|
+
import useMeasure from '@jbrowse/core/util/useMeasure'
|
|
5
|
+
import { ThemeProvider } from '@mui/material/styles'
|
|
6
|
+
|
|
7
|
+
import MSAModelF from '../model.ts'
|
|
8
|
+
import Loading from './Loading.tsx'
|
|
9
|
+
|
|
10
|
+
import type { FileLocation as FileLocationType } from '@jbrowse/core/util/types'
|
|
11
|
+
|
|
12
|
+
interface MSAViewerProps {
|
|
13
|
+
msa?: string
|
|
14
|
+
tree?: string
|
|
15
|
+
gff?: string
|
|
16
|
+
msaFilehandle?: FileLocationType
|
|
17
|
+
treeFilehandle?: FileLocationType
|
|
18
|
+
gffFilehandle?: FileLocationType
|
|
19
|
+
colorScheme?: string
|
|
20
|
+
height?: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default function MSAViewer({
|
|
24
|
+
msa,
|
|
25
|
+
tree,
|
|
26
|
+
gff,
|
|
27
|
+
msaFilehandle,
|
|
28
|
+
treeFilehandle,
|
|
29
|
+
gffFilehandle,
|
|
30
|
+
colorScheme,
|
|
31
|
+
height,
|
|
32
|
+
}: MSAViewerProps) {
|
|
33
|
+
const theme = useMemo(() => createJBrowseTheme(), [])
|
|
34
|
+
const model = useMemo(
|
|
35
|
+
() =>
|
|
36
|
+
MSAModelF().create({
|
|
37
|
+
type: 'MsaView',
|
|
38
|
+
...(msa || tree || gff
|
|
39
|
+
? { data: { msa: msa ?? '', tree: tree ?? '', gff } }
|
|
40
|
+
: {}),
|
|
41
|
+
...(msaFilehandle ? { msaFilehandle } : {}),
|
|
42
|
+
...(treeFilehandle ? { treeFilehandle } : {}),
|
|
43
|
+
...(gffFilehandle ? { gffFilehandle } : {}),
|
|
44
|
+
...(colorScheme ? { colorSchemeName: colorScheme } : {}),
|
|
45
|
+
...(height ? { height } : {}),
|
|
46
|
+
}),
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
[],
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const [ref, { width }] = useMeasure()
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (width) {
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
model.setWidth(width)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}, [model, width])
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<ThemeProvider theme={theme}>
|
|
62
|
+
<div ref={ref}>
|
|
63
|
+
<Loading model={model} />
|
|
64
|
+
</div>
|
|
65
|
+
</ThemeProvider>
|
|
66
|
+
)
|
|
67
|
+
}
|
package/src/components/Track.tsx
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import React, { lazy,
|
|
1
|
+
import React, { lazy, useCallback, useRef, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'
|
|
4
4
|
import { IconButton, Menu, MenuItem } from '@mui/material'
|
|
5
5
|
import { observer } from 'mobx-react'
|
|
6
6
|
import { makeStyles } from 'tss-react/mui'
|
|
7
7
|
|
|
8
|
+
import { useWheelScroll } from '../useWheelScroll.ts'
|
|
9
|
+
|
|
8
10
|
import type { MsaViewModel } from '../model.ts'
|
|
9
11
|
|
|
10
12
|
const TrackInfoDialog = lazy(() => import('./dialogs/TrackInfoDialog.tsx'))
|
|
@@ -101,31 +103,13 @@ const Track = observer(function ({
|
|
|
101
103
|
model: { height, error },
|
|
102
104
|
} = track
|
|
103
105
|
const ref = useRef<HTMLDivElement>(null)
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function onWheel(event: WheelEvent) {
|
|
112
|
-
deltaX.current += event.deltaX
|
|
113
|
-
|
|
114
|
-
if (!scheduled.current) {
|
|
115
|
-
scheduled.current = true
|
|
116
|
-
requestAnimationFrame(() => {
|
|
117
|
-
model.doScrollX(-deltaX.current)
|
|
118
|
-
deltaX.current = 0
|
|
119
|
-
scheduled.current = false
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
event.preventDefault()
|
|
123
|
-
}
|
|
124
|
-
curr.addEventListener('wheel', onWheel, { passive: false })
|
|
125
|
-
return () => {
|
|
126
|
-
curr.removeEventListener('wheel', onWheel)
|
|
127
|
-
}
|
|
128
|
-
}, [model])
|
|
106
|
+
const onScrollX = useCallback(
|
|
107
|
+
(d: number) => {
|
|
108
|
+
model.doScrollX(d)
|
|
109
|
+
},
|
|
110
|
+
[model],
|
|
111
|
+
)
|
|
112
|
+
useWheelScroll({ ref, onScrollX })
|
|
129
113
|
|
|
130
114
|
return (
|
|
131
115
|
<div key={track.id} style={{ display: 'flex', height }}>
|
|
@@ -4,7 +4,6 @@ import { Dialog } from '@jbrowse/core/ui'
|
|
|
4
4
|
import { Tab, Tabs } from '@mui/material'
|
|
5
5
|
|
|
6
6
|
import InterProScanPanel from './InterProScanDialog.tsx'
|
|
7
|
-
import TabPanel from './TabPanel.tsx'
|
|
8
7
|
import UserProvidedResultPanel from './UserProvidedDomainsDialog.tsx'
|
|
9
8
|
|
|
10
9
|
import type { MsaViewModel } from '../../model.ts'
|
|
@@ -35,12 +34,12 @@ export default function LaunchDomainViewDialog({
|
|
|
35
34
|
<Tab value={0} label="Automatic lookup" />
|
|
36
35
|
<Tab value={1} label="Manual" />
|
|
37
36
|
</Tabs>
|
|
38
|
-
|
|
37
|
+
{choice === 0 ? (
|
|
39
38
|
<InterProScanPanel model={model} handleClose={handleClose} />
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
) : null}
|
|
40
|
+
{choice === 1 ? (
|
|
42
41
|
<UserProvidedResultPanel model={model} handleClose={handleClose} />
|
|
43
|
-
|
|
42
|
+
) : null}
|
|
44
43
|
</Dialog>
|
|
45
44
|
)
|
|
46
45
|
}
|
|
@@ -57,32 +57,32 @@ const InterProScanDialog = observer(function ({
|
|
|
57
57
|
category: 'Other category',
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
|
-
name: '
|
|
60
|
+
name: 'SuperFamily',
|
|
61
61
|
category: 'Structural domains',
|
|
62
62
|
checked: true,
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
|
-
name: '
|
|
65
|
+
name: 'Panther',
|
|
66
66
|
category: 'Families, domains, sites & repeats',
|
|
67
67
|
checked: true,
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
|
-
name: '
|
|
70
|
+
name: 'Gene3d',
|
|
71
71
|
category: 'Structural domains',
|
|
72
72
|
checked: true,
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
|
-
name: '
|
|
75
|
+
name: 'HAMAP',
|
|
76
76
|
category: 'Families, domains, sites & repeats',
|
|
77
77
|
checked: true,
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
|
-
name: '
|
|
80
|
+
name: 'PrositeProfiles',
|
|
81
81
|
category: 'Families, domains, sites & repeats',
|
|
82
82
|
checked: true,
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
|
-
name: '
|
|
85
|
+
name: 'PrositePatterns',
|
|
86
86
|
category: 'Families, domains, sites & repeats',
|
|
87
87
|
checked: true,
|
|
88
88
|
},
|
|
@@ -108,7 +108,7 @@ const InterProScanDialog = observer(function ({
|
|
|
108
108
|
checked: true,
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
|
-
name: '
|
|
111
|
+
name: 'PfamA',
|
|
112
112
|
category: 'Families, domains, sites & repeats',
|
|
113
113
|
checked: true,
|
|
114
114
|
},
|
|
@@ -46,16 +46,12 @@ const TreeSettings = observer(function TreeSettings({
|
|
|
46
46
|
}: {
|
|
47
47
|
model: MsaViewModel
|
|
48
48
|
}) {
|
|
49
|
-
const { classes } = useStyles()
|
|
50
49
|
const {
|
|
51
50
|
drawTree,
|
|
52
51
|
drawLabels,
|
|
53
52
|
drawNodeBubbles,
|
|
54
53
|
labelsAlignRight,
|
|
55
|
-
noTree,
|
|
56
54
|
showBranchLen,
|
|
57
|
-
treeWidthMatchesArea,
|
|
58
|
-
treeWidth,
|
|
59
55
|
} = model
|
|
60
56
|
|
|
61
57
|
return (
|
|
@@ -99,31 +95,6 @@ const TreeSettings = observer(function TreeSettings({
|
|
|
99
95
|
model.setDrawLabels(!drawLabels)
|
|
100
96
|
}}
|
|
101
97
|
/>
|
|
102
|
-
{noTree ? null : (
|
|
103
|
-
<div>
|
|
104
|
-
<Checkbox2
|
|
105
|
-
checked={treeWidthMatchesArea}
|
|
106
|
-
label="Make tree width fit to tree area?"
|
|
107
|
-
onChange={() => {
|
|
108
|
-
model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
|
|
109
|
-
}}
|
|
110
|
-
/>
|
|
111
|
-
{treeWidthMatchesArea ? null : (
|
|
112
|
-
<div className={classes.flex}>
|
|
113
|
-
<Typography>Tree width ({treeWidth}px)</Typography>
|
|
114
|
-
<Slider
|
|
115
|
-
className={classes.field}
|
|
116
|
-
min={50}
|
|
117
|
-
max={600}
|
|
118
|
-
value={treeWidth}
|
|
119
|
-
onChange={(_, val) => {
|
|
120
|
-
model.setTreeWidth(val)
|
|
121
|
-
}}
|
|
122
|
-
/>
|
|
123
|
-
</div>
|
|
124
|
-
)}
|
|
125
|
-
</div>
|
|
126
|
-
)}
|
|
127
98
|
</div>
|
|
128
99
|
)
|
|
129
100
|
})
|
|
@@ -136,7 +107,6 @@ const MSASettings = observer(function MSASettings({
|
|
|
136
107
|
const { classes } = useStyles()
|
|
137
108
|
const {
|
|
138
109
|
bgColor,
|
|
139
|
-
contrastLettering,
|
|
140
110
|
colWidth,
|
|
141
111
|
allowedGappyness,
|
|
142
112
|
drawMsaLetters,
|
|
@@ -162,13 +132,6 @@ const MSASettings = observer(function MSASettings({
|
|
|
162
132
|
model.setBgColor(!bgColor)
|
|
163
133
|
}}
|
|
164
134
|
/>
|
|
165
|
-
<Checkbox2
|
|
166
|
-
checked={contrastLettering}
|
|
167
|
-
label="Use contrast lettering"
|
|
168
|
-
onChange={() => {
|
|
169
|
-
model.setContrastLettering(!contrastLettering)
|
|
170
|
-
}}
|
|
171
|
-
/>
|
|
172
135
|
<Checkbox2
|
|
173
136
|
checked={hideGaps}
|
|
174
137
|
label="Enable hiding gappy columns?"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
|
|
4
|
+
import Palette from '@mui/icons-material/Palette'
|
|
5
|
+
import { observer } from 'mobx-react'
|
|
6
|
+
|
|
7
|
+
import colorSchemes from '../../colorSchemes.ts'
|
|
8
|
+
|
|
9
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
10
|
+
|
|
11
|
+
const ColorSchemeMenu = observer(function ({ model }: { model: MsaViewModel }) {
|
|
12
|
+
const { colorSchemeName } = model
|
|
13
|
+
return (
|
|
14
|
+
<CascadingMenuButton
|
|
15
|
+
closeAfterItemClick
|
|
16
|
+
anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
|
|
17
|
+
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
|
|
18
|
+
menuItems={Object.keys(colorSchemes).map(
|
|
19
|
+
option =>
|
|
20
|
+
({
|
|
21
|
+
label: option,
|
|
22
|
+
type: 'radio',
|
|
23
|
+
checked: colorSchemeName === option,
|
|
24
|
+
onClick: () => {
|
|
25
|
+
model.setColorSchemeName(option)
|
|
26
|
+
},
|
|
27
|
+
}) as const,
|
|
28
|
+
)}
|
|
29
|
+
>
|
|
30
|
+
<Palette />
|
|
31
|
+
</CascadingMenuButton>
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
export default ColorSchemeMenu
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { lazy } from 'react'
|
|
2
|
+
|
|
3
|
+
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
|
|
4
|
+
import Assignment from '@mui/icons-material/Assignment'
|
|
5
|
+
import FolderOpen from '@mui/icons-material/FolderOpen'
|
|
6
|
+
import PhotoCamera from '@mui/icons-material/PhotoCamera'
|
|
7
|
+
import Settings from '@mui/icons-material/Settings'
|
|
8
|
+
import { observer } from 'mobx-react'
|
|
9
|
+
|
|
10
|
+
import { getDomainMenu } from './getDomainsMenu.ts'
|
|
11
|
+
|
|
12
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
13
|
+
|
|
14
|
+
const MetadataDialog = lazy(() => import('../dialogs/MetadataDialog.tsx'))
|
|
15
|
+
const ExportSVGDialog = lazy(() => import('../dialogs/ExportSVGDialog.tsx'))
|
|
16
|
+
const SettingsDialog = lazy(() => import('../dialogs/SettingsDialog.tsx'))
|
|
17
|
+
|
|
18
|
+
const FileMenu = observer(({ model }: { model: MsaViewModel }) => {
|
|
19
|
+
return (
|
|
20
|
+
<CascadingMenuButton
|
|
21
|
+
menuItems={[
|
|
22
|
+
{
|
|
23
|
+
label: 'Return to import form',
|
|
24
|
+
icon: FolderOpen,
|
|
25
|
+
onClick: () => {
|
|
26
|
+
model.reset()
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: 'Metadata',
|
|
31
|
+
icon: Assignment,
|
|
32
|
+
onClick: () => {
|
|
33
|
+
model.queueDialog(onClose => [
|
|
34
|
+
MetadataDialog,
|
|
35
|
+
{
|
|
36
|
+
model,
|
|
37
|
+
onClose,
|
|
38
|
+
},
|
|
39
|
+
])
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
label: 'More settings',
|
|
44
|
+
icon: Settings,
|
|
45
|
+
onClick: () => {
|
|
46
|
+
model.queueDialog(onClose => [
|
|
47
|
+
SettingsDialog,
|
|
48
|
+
{
|
|
49
|
+
model,
|
|
50
|
+
onClose,
|
|
51
|
+
},
|
|
52
|
+
])
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
label: 'Domain settings',
|
|
57
|
+
type: 'subMenu',
|
|
58
|
+
subMenu: getDomainMenu({
|
|
59
|
+
model,
|
|
60
|
+
}),
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
label: 'Export SVG',
|
|
64
|
+
icon: PhotoCamera,
|
|
65
|
+
onClick: () => {
|
|
66
|
+
model.queueDialog(onClose => [
|
|
67
|
+
ExportSVGDialog,
|
|
68
|
+
{
|
|
69
|
+
onClose,
|
|
70
|
+
model,
|
|
71
|
+
},
|
|
72
|
+
])
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
]}
|
|
76
|
+
anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
|
|
77
|
+
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
|
|
78
|
+
>
|
|
79
|
+
<FolderOpen />
|
|
80
|
+
</CascadingMenuButton>
|
|
81
|
+
)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
export default FileMenu
|
|
@@ -5,15 +5,16 @@ import Help from '@mui/icons-material/Help'
|
|
|
5
5
|
import { IconButton } from '@mui/material'
|
|
6
6
|
import { observer } from 'mobx-react'
|
|
7
7
|
|
|
8
|
+
import ColorSchemeMenu from './ColorSchemeMenu.tsx'
|
|
9
|
+
import FileMenu from './FileMenu.tsx'
|
|
8
10
|
import GappynessSlider from './GappynessSlider.tsx'
|
|
9
11
|
import HeaderInfoArea from './HeaderInfoArea.tsx'
|
|
10
|
-
import HeaderMenu from './HeaderMenu.tsx'
|
|
11
12
|
import HeaderStatusArea from './HeaderStatusArea.tsx'
|
|
13
|
+
import MSASettingsMenu from './MSASettingsMenu.tsx'
|
|
12
14
|
import MultiAlignmentSelector from './MultiAlignmentSelector.tsx'
|
|
13
|
-
import
|
|
15
|
+
import TreeSettingsMenu from './TreeSettingsMenu.tsx'
|
|
14
16
|
import ZoomControls from './ZoomControls.tsx'
|
|
15
17
|
import ZoomMenu from './ZoomMenu.tsx'
|
|
16
|
-
import ZoomStar from './ZoomStar.tsx'
|
|
17
18
|
|
|
18
19
|
import type { MsaViewModel } from '../../model.ts'
|
|
19
20
|
|
|
@@ -26,10 +27,11 @@ const Header = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
26
27
|
}, [model, height])
|
|
27
28
|
return (
|
|
28
29
|
<div ref={ref} style={{ display: 'flex' }}>
|
|
29
|
-
<
|
|
30
|
-
<
|
|
30
|
+
<FileMenu model={model} />
|
|
31
|
+
<ColorSchemeMenu model={model} />
|
|
32
|
+
<TreeSettingsMenu model={model} />
|
|
33
|
+
<MSASettingsMenu model={model} />
|
|
31
34
|
<ZoomControls model={model} />
|
|
32
|
-
{model.showZoomStar ? <ZoomStar model={model} /> : null}
|
|
33
35
|
<ZoomMenu model={model} />
|
|
34
36
|
<GappynessSlider model={model} />
|
|
35
37
|
<div style={{ paddingLeft: 20, margin: 'auto' }}>
|