react-msaview 5.0.6 → 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.
Files changed (190) hide show
  1. package/bundle/index.js +106 -106
  2. package/bundle/index.js.LICENSE.txt +1 -1
  3. package/bundle/index.js.map +1 -1
  4. package/dist/components/Checkbox2.js +3 -6
  5. package/dist/components/Checkbox2.js.map +1 -1
  6. package/dist/components/MSAViewer.d.ts +14 -0
  7. package/dist/components/MSAViewer.js +34 -0
  8. package/dist/components/MSAViewer.js.map +1 -0
  9. package/dist/components/Track.d.ts +0 -4
  10. package/dist/components/Track.js +6 -26
  11. package/dist/components/Track.js.map +1 -1
  12. package/dist/components/dialogs/DomainDialog.js +2 -5
  13. package/dist/components/dialogs/DomainDialog.js.map +1 -1
  14. package/dist/components/dialogs/InterProScanDialog.js +7 -7
  15. package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
  16. package/dist/components/dialogs/SettingsDialog.js +3 -19
  17. package/dist/components/dialogs/SettingsDialog.js.map +1 -1
  18. package/dist/components/header/ColorSchemeMenu.d.ts +6 -0
  19. package/dist/components/header/ColorSchemeMenu.js +19 -0
  20. package/dist/components/header/ColorSchemeMenu.js.map +1 -0
  21. package/dist/components/header/{ZoomStar.d.ts → FileMenu.d.ts} +2 -2
  22. package/dist/components/header/FileMenu.js +71 -0
  23. package/dist/components/header/FileMenu.js.map +1 -0
  24. package/dist/components/header/Header.js +8 -6
  25. package/dist/components/header/Header.js.map +1 -1
  26. package/dist/components/header/HeaderMenu.js +3 -145
  27. package/dist/components/header/HeaderMenu.js.map +1 -1
  28. package/dist/components/header/MSASettingsMenu.d.ts +6 -0
  29. package/dist/components/header/MSASettingsMenu.js +36 -0
  30. package/dist/components/header/MSASettingsMenu.js.map +1 -0
  31. package/dist/components/header/SettingsMenu.js +1 -21
  32. package/dist/components/header/SettingsMenu.js.map +1 -1
  33. package/dist/components/header/TreeSettingsMenu.d.ts +6 -0
  34. package/dist/components/header/TreeSettingsMenu.js +74 -0
  35. package/dist/components/header/TreeSettingsMenu.js.map +1 -0
  36. package/dist/components/header/ZoomMenu.js +0 -8
  37. package/dist/components/header/ZoomMenu.js.map +1 -1
  38. package/dist/components/header/getDomainsMenu.d.ts +31 -0
  39. package/dist/components/header/getDomainsMenu.js +75 -0
  40. package/dist/components/header/getDomainsMenu.js.map +1 -0
  41. package/dist/components/import/ImportFormExamples.js +21 -19
  42. package/dist/components/import/ImportFormExamples.js.map +1 -1
  43. package/dist/components/msa/MSACanvas.js +13 -89
  44. package/dist/components/msa/MSACanvas.js.map +1 -1
  45. package/dist/components/msa/MSACanvasBlock.js +1 -3
  46. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  47. package/dist/components/msa/renderMSABlock.js +2 -4
  48. package/dist/components/msa/renderMSABlock.js.map +1 -1
  49. package/dist/components/msa/renderMSAMouseover.js +1 -7
  50. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  51. package/dist/components/tree/TreeCanvas.js +18 -101
  52. package/dist/components/tree/TreeCanvas.js.map +1 -1
  53. package/dist/components/tree/TreeCanvasBlock.js +33 -1
  54. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  55. package/dist/components/tree/TreeNodeMenu.js +5 -16
  56. package/dist/components/tree/TreeNodeMenu.js.map +1 -1
  57. package/dist/components/tree/renderTreeCanvas.js +4 -12
  58. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  59. package/dist/constants.d.ts +0 -2
  60. package/dist/constants.js +0 -2
  61. package/dist/constants.js.map +1 -1
  62. package/dist/fetchUtils.d.ts +0 -1
  63. package/dist/fetchUtils.js +0 -4
  64. package/dist/fetchUtils.js.map +1 -1
  65. package/dist/flatToTree.d.ts +0 -5
  66. package/dist/flatToTree.js +13 -30
  67. package/dist/flatToTree.js.map +1 -1
  68. package/dist/hierarchy.d.ts +28 -0
  69. package/dist/hierarchy.js +164 -0
  70. package/dist/hierarchy.js.map +1 -0
  71. package/dist/index.d.ts +2 -0
  72. package/dist/index.js +1 -0
  73. package/dist/index.js.map +1 -1
  74. package/dist/launchInterProScan.d.ts +0 -5
  75. package/dist/launchInterProScan.js +5 -3
  76. package/dist/launchInterProScan.js.map +1 -1
  77. package/dist/model/DataModel.d.ts +9 -0
  78. package/dist/model/DataModel.js +12 -1
  79. package/dist/model/DataModel.js.map +1 -1
  80. package/dist/model/msaModel.d.ts +3 -0
  81. package/dist/model/msaModel.js +0 -1
  82. package/dist/model/msaModel.js.map +1 -1
  83. package/dist/model/treeModel.d.ts +3 -6
  84. package/dist/model/treeModel.js +3 -15
  85. package/dist/model/treeModel.js.map +1 -1
  86. package/dist/model.d.ts +34 -77
  87. package/dist/model.js +140 -239
  88. package/dist/model.js.map +1 -1
  89. package/dist/neighborJoining.js +40 -633
  90. package/dist/neighborJoining.js.map +1 -1
  91. package/dist/parseAsn1.d.ts +0 -12
  92. package/dist/parseAsn1.js +125 -332
  93. package/dist/parseAsn1.js.map +1 -1
  94. package/dist/useWheelScroll.d.ts +8 -0
  95. package/dist/useWheelScroll.js +93 -0
  96. package/dist/useWheelScroll.js.map +1 -0
  97. package/dist/util.d.ts +1 -6
  98. package/dist/util.js +5 -34
  99. package/dist/util.js.map +1 -1
  100. package/dist/vendor/copyToClipboard.d.ts +1 -10
  101. package/dist/vendor/copyToClipboard.js +14 -109
  102. package/dist/vendor/copyToClipboard.js.map +1 -1
  103. package/dist/vendor/fileSaver.d.ts +1 -11
  104. package/dist/vendor/fileSaver.js +7 -76
  105. package/dist/vendor/fileSaver.js.map +1 -1
  106. package/dist/version.d.ts +1 -1
  107. package/dist/version.js +1 -1
  108. package/dist/version.js.map +1 -1
  109. package/package.json +14 -14
  110. package/src/collapseLogic.test.ts +115 -0
  111. package/src/components/Checkbox2.tsx +9 -18
  112. package/src/components/MSAViewer.tsx +67 -0
  113. package/src/components/Track.tsx +11 -30
  114. package/src/components/dialogs/DomainDialog.tsx +4 -5
  115. package/src/components/dialogs/InterProScanDialog.tsx +7 -7
  116. package/src/components/dialogs/SettingsDialog.tsx +0 -37
  117. package/src/components/header/ColorSchemeMenu.tsx +35 -0
  118. package/src/components/header/FileMenu.tsx +84 -0
  119. package/src/components/header/Header.tsx +8 -6
  120. package/src/components/header/HeaderMenu.tsx +4 -155
  121. package/src/components/header/MSASettingsMenu.tsx +48 -0
  122. package/src/components/header/SettingsMenu.tsx +0 -23
  123. package/src/components/header/TreeSettingsMenu.tsx +96 -0
  124. package/src/components/header/ZoomMenu.tsx +0 -8
  125. package/src/components/header/getDomainsMenu.ts +83 -0
  126. package/src/components/import/ImportFormExamples.tsx +37 -34
  127. package/src/components/msa/MSACanvas.tsx +21 -97
  128. package/src/components/msa/MSACanvasBlock.tsx +1 -3
  129. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +1 -1
  130. package/src/components/msa/renderMSABlock.ts +2 -5
  131. package/src/components/msa/renderMSAMouseover.ts +0 -6
  132. package/src/components/tree/TreeCanvas.tsx +48 -111
  133. package/src/components/tree/TreeCanvasBlock.tsx +44 -0
  134. package/src/components/tree/TreeNodeMenu.tsx +5 -14
  135. package/src/components/tree/renderTreeCanvas.ts +8 -21
  136. package/src/constants.ts +0 -2
  137. package/src/fetchUtils.ts +0 -5
  138. package/src/flatToTree.ts +20 -38
  139. package/src/hierarchy.test.ts +120 -0
  140. package/src/hierarchy.ts +220 -0
  141. package/src/index.ts +2 -0
  142. package/src/launchInterProScan.ts +4 -3
  143. package/src/model/DataModel.ts +12 -1
  144. package/src/model/msaModel.ts +0 -2
  145. package/src/model/treeModel.ts +2 -18
  146. package/src/model.ts +203 -278
  147. package/src/neighborJoining.test.ts +15 -7
  148. package/src/neighborJoining.ts +40 -632
  149. package/src/parseAsn1.test.ts +5 -2
  150. package/src/parseAsn1.ts +135 -405
  151. package/src/useWheelScroll.ts +109 -0
  152. package/src/util.ts +5 -50
  153. package/src/vendor/copyToClipboard.ts +14 -122
  154. package/src/vendor/fileSaver.ts +8 -105
  155. package/src/version.ts +1 -1
  156. package/dist/components/dialogs/AddTrackDialog.d.ts +0 -8
  157. package/dist/components/dialogs/AddTrackDialog.js +0 -30
  158. package/dist/components/dialogs/AddTrackDialog.js.map +0 -1
  159. package/dist/components/dialogs/TabPanel.d.ts +0 -6
  160. package/dist/components/dialogs/TabPanel.js +0 -6
  161. package/dist/components/dialogs/TabPanel.js.map +0 -1
  162. package/dist/components/header/ZoomStar.js +0 -40
  163. package/dist/components/header/ZoomStar.js.map +0 -1
  164. package/dist/createPaletteMap.test.d.ts +0 -1
  165. package/dist/createPaletteMap.test.js +0 -49
  166. package/dist/createPaletteMap.test.js.map +0 -1
  167. package/dist/layout.d.ts +0 -26
  168. package/dist/layout.js +0 -74
  169. package/dist/layout.js.map +0 -1
  170. package/dist/neighborJoining.test.d.ts +0 -1
  171. package/dist/neighborJoining.test.js +0 -110
  172. package/dist/neighborJoining.test.js.map +0 -1
  173. package/dist/parseAsn1.test.d.ts +0 -1
  174. package/dist/parseAsn1.test.js +0 -8
  175. package/dist/parseAsn1.test.js.map +0 -1
  176. package/dist/reparseTree.d.ts +0 -2
  177. package/dist/reparseTree.js +0 -15
  178. package/dist/reparseTree.js.map +0 -1
  179. package/dist/rowCoordinateCalculations.test.d.ts +0 -1
  180. package/dist/rowCoordinateCalculations.test.js +0 -224
  181. package/dist/rowCoordinateCalculations.test.js.map +0 -1
  182. package/dist/seqPosToGlobalCol.test.d.ts +0 -1
  183. package/dist/seqPosToGlobalCol.test.js +0 -60
  184. package/dist/seqPosToGlobalCol.test.js.map +0 -1
  185. package/src/components/dialogs/AddTrackDialog.tsx +0 -85
  186. package/src/components/dialogs/TabPanel.tsx +0 -19
  187. package/src/components/header/ZoomStar.tsx +0 -74
  188. package/src/createPaletteMap.test.ts +0 -57
  189. package/src/layout.ts +0 -118
  190. 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
- <FormControlLabel2
29
- control={
30
- <Checkbox disabled={disabled} checked={checked} onChange={onChange} />
31
- }
32
- label={label}
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
+ }
@@ -1,13 +1,14 @@
1
- import React, { lazy, useEffect, useRef, useState } from 'react'
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
- // lazies
11
12
  const TrackInfoDialog = lazy(() => import('./dialogs/TrackInfoDialog.tsx'))
12
13
 
13
14
  const useStyles = makeStyles()({
@@ -16,12 +17,11 @@ const useStyles = makeStyles()({
16
17
  },
17
18
  })
18
19
 
19
- export const TrackLabel = observer(function ({
20
+ const TrackLabel = observer(function TrackLabel({
20
21
  model,
21
22
  track,
22
23
  }: {
23
24
  model: MsaViewModel
24
-
25
25
  track: any
26
26
  }) {
27
27
  const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>()
@@ -96,7 +96,6 @@ const Track = observer(function ({
96
96
  track,
97
97
  }: {
98
98
  model: MsaViewModel
99
-
100
99
  track: any
101
100
  }) {
102
101
  const { resizeHandleWidth, colWidth, scrollX, numColumns } = model
@@ -104,31 +103,13 @@ const Track = observer(function ({
104
103
  model: { height, error },
105
104
  } = track
106
105
  const ref = useRef<HTMLDivElement>(null)
107
- const scheduled = useRef(false)
108
- const deltaX = useRef(0)
109
- useEffect(() => {
110
- const curr = ref.current
111
- if (!curr) {
112
- return
113
- }
114
- function onWheel(event: WheelEvent) {
115
- deltaX.current += event.deltaX
116
-
117
- if (!scheduled.current) {
118
- scheduled.current = true
119
- requestAnimationFrame(() => {
120
- model.doScrollX(-deltaX.current)
121
- deltaX.current = 0
122
- scheduled.current = false
123
- })
124
- }
125
- event.preventDefault()
126
- }
127
- curr.addEventListener('wheel', onWheel)
128
- return () => {
129
- curr.removeEventListener('wheel', onWheel)
130
- }
131
- }, [model])
106
+ const onScrollX = useCallback(
107
+ (d: number) => {
108
+ model.doScrollX(d)
109
+ },
110
+ [model],
111
+ )
112
+ useWheelScroll({ ref, onScrollX })
132
113
 
133
114
  return (
134
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
- <TabPanel value={choice} index={0}>
37
+ {choice === 0 ? (
39
38
  <InterProScanPanel model={model} handleClose={handleClose} />
40
- </TabPanel>
41
- <TabPanel value={choice} index={1}>
39
+ ) : null}
40
+ {choice === 1 ? (
42
41
  <UserProvidedResultPanel model={model} handleClose={handleClose} />
43
- </TabPanel>
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: 'SUPERFAMILY',
60
+ name: 'SuperFamily',
61
61
  category: 'Structural domains',
62
62
  checked: true,
63
63
  },
64
64
  {
65
- name: 'PANTHER',
65
+ name: 'Panther',
66
66
  category: 'Families, domains, sites & repeats',
67
67
  checked: true,
68
68
  },
69
69
  {
70
- name: 'Gene3D',
70
+ name: 'Gene3d',
71
71
  category: 'Structural domains',
72
72
  checked: true,
73
73
  },
74
74
  {
75
- name: 'Hamap',
75
+ name: 'HAMAP',
76
76
  category: 'Families, domains, sites & repeats',
77
77
  checked: true,
78
78
  },
79
79
  {
80
- name: 'ProSiteProfiles',
80
+ name: 'PrositeProfiles',
81
81
  category: 'Families, domains, sites & repeats',
82
82
  checked: true,
83
83
  },
84
84
  {
85
- name: 'ProSitePatterns',
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: 'Pfam',
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 SettingsMenu from './SettingsMenu.tsx'
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
- <HeaderMenu model={model} />
30
- <SettingsMenu model={model} />
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' }}>