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.
Files changed (270) hide show
  1. package/bundle/index.js +32 -32
  2. package/dist/components/Checkbox2.d.ts +7 -0
  3. package/dist/components/Checkbox2.js +10 -0
  4. package/dist/components/Checkbox2.js.map +1 -0
  5. package/dist/components/Loading.js +12 -4
  6. package/dist/components/Loading.js.map +1 -1
  7. package/dist/components/MSAView.js +5 -8
  8. package/dist/components/MSAView.js.map +1 -1
  9. package/dist/components/SequenceTextArea.d.ts +4 -0
  10. package/dist/components/SequenceTextArea.js +38 -0
  11. package/dist/components/SequenceTextArea.js.map +1 -0
  12. package/dist/components/Track.js +9 -8
  13. package/dist/components/Track.js.map +1 -1
  14. package/dist/components/dialogs/AddTrackDialog.js +0 -1
  15. package/dist/components/dialogs/AddTrackDialog.js.map +1 -1
  16. package/dist/components/{ExportSVGDialog.d.ts → dialogs/ExportSVGDialog.d.ts} +1 -1
  17. package/dist/components/{ExportSVGDialog.js → dialogs/ExportSVGDialog.js} +3 -4
  18. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -0
  19. package/dist/components/dialogs/FeatureDialog.d.ts +7 -0
  20. package/dist/components/dialogs/FeatureDialog.js +52 -0
  21. package/dist/components/dialogs/FeatureDialog.js.map +1 -0
  22. package/dist/components/dialogs/InterProScanDialog.d.ts +7 -0
  23. package/dist/components/dialogs/InterProScanDialog.js +163 -0
  24. package/dist/components/dialogs/InterProScanDialog.js.map +1 -0
  25. package/dist/components/dialogs/MetadataDialog.js +6 -3
  26. package/dist/components/dialogs/MetadataDialog.js.map +1 -1
  27. package/dist/components/dialogs/SettingsDialog.js +6 -11
  28. package/dist/components/dialogs/SettingsDialog.js.map +1 -1
  29. package/dist/components/{Header.d.ts → header/Header.d.ts} +1 -1
  30. package/dist/components/header/Header.js +30 -0
  31. package/dist/components/header/Header.js.map +1 -0
  32. package/dist/components/{HeaderInfoArea.d.ts → header/HeaderInfoArea.d.ts} +2 -2
  33. package/dist/components/header/HeaderInfoArea.js +20 -0
  34. package/dist/components/header/HeaderInfoArea.js.map +1 -0
  35. package/dist/components/header/HeaderMenu.d.ts +6 -0
  36. package/dist/components/header/HeaderMenu.js +40 -0
  37. package/dist/components/header/HeaderMenu.js.map +1 -0
  38. package/dist/components/header/HeaderMenuExtra.d.ts +6 -0
  39. package/dist/components/header/HeaderMenuExtra.js +92 -0
  40. package/dist/components/header/HeaderMenuExtra.js.map +1 -0
  41. package/dist/components/header/HeaderStatusArea.d.ts +6 -0
  42. package/dist/components/header/HeaderStatusArea.js +20 -0
  43. package/dist/components/header/HeaderStatusArea.js.map +1 -0
  44. package/dist/components/{MultiAlignmentSelector.d.ts → header/MultiAlignmentSelector.d.ts} +1 -1
  45. package/dist/components/header/MultiAlignmentSelector.js.map +1 -0
  46. package/dist/components/{ZoomControls.d.ts → header/ZoomControls.d.ts} +1 -1
  47. package/dist/components/header/ZoomControls.js +15 -0
  48. package/dist/components/header/ZoomControls.js.map +1 -0
  49. package/dist/components/{ImportForm/index.js → import/ImportForm.js} +1 -1
  50. package/dist/components/import/ImportForm.js.map +1 -0
  51. package/dist/components/{ImportForm → import}/ImportFormExamples.js +6 -2
  52. package/dist/components/import/ImportFormExamples.js.map +1 -0
  53. package/dist/components/import/data/seq2.js.map +1 -0
  54. package/dist/components/import/util.js +10 -0
  55. package/dist/components/import/util.js.map +1 -0
  56. package/dist/components/{Minimap.d.ts → minimap/Minimap.d.ts} +1 -1
  57. package/dist/components/minimap/Minimap.js.map +1 -0
  58. package/dist/components/{MinimapSVG.d.ts → minimap/MinimapSVG.d.ts} +1 -1
  59. package/dist/components/minimap/MinimapSVG.js.map +1 -0
  60. package/dist/components/msa/Loading.js.map +1 -0
  61. package/dist/components/{MSAPanel → msa}/MSACanvas.js +3 -2
  62. package/dist/components/msa/MSACanvas.js.map +1 -0
  63. package/dist/components/{MSAPanel/MSABlock.js → msa/MSACanvasBlock.js} +21 -9
  64. package/dist/components/msa/MSACanvasBlock.js.map +1 -0
  65. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -0
  66. package/dist/components/msa/MSAPanel.d.ts +6 -0
  67. package/dist/components/{MSAPanel/index.js → msa/MSAPanel.js} +6 -3
  68. package/dist/components/msa/MSAPanel.js.map +1 -0
  69. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +9 -0
  70. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +44 -0
  71. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -0
  72. package/dist/components/{MSAPanel → msa}/renderMSABlock.js +24 -20
  73. package/dist/components/msa/renderMSABlock.js.map +1 -0
  74. package/dist/components/msa/renderMSAMouseover.js.map +1 -0
  75. package/dist/components/tree/TreeBranchMenu.js.map +1 -0
  76. package/dist/components/{TreePanel → tree}/TreeCanvas.js +1 -1
  77. package/dist/components/tree/TreeCanvas.js.map +1 -0
  78. package/dist/components/{TreePanel → tree}/TreeCanvasBlock.js +1 -1
  79. package/dist/components/tree/TreeCanvasBlock.js.map +1 -0
  80. package/dist/components/{TreePanel → tree}/TreeNodeMenu.js +2 -33
  81. package/dist/components/tree/TreeNodeMenu.js.map +1 -0
  82. package/dist/components/{TreePanel/index.js → tree/TreePanel.js} +2 -2
  83. package/dist/components/tree/TreePanel.js.map +1 -0
  84. package/dist/components/tree/TreeRuler.js.map +1 -0
  85. package/dist/components/{TreePanel → tree}/dialogs/TreeNodeInfoDialog.js +6 -2
  86. package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -0
  87. package/dist/components/{TreePanel → tree}/renderTreeCanvas.js +23 -37
  88. package/dist/components/tree/renderTreeCanvas.js.map +1 -0
  89. package/dist/fetchUtils.d.ts +5 -0
  90. package/dist/fetchUtils.js +23 -0
  91. package/dist/fetchUtils.js.map +1 -0
  92. package/dist/ggplotPalettes.d.ts +3 -0
  93. package/dist/ggplotPalettes.js +24 -0
  94. package/dist/ggplotPalettes.js.map +1 -0
  95. package/dist/index.d.ts +1 -1
  96. package/dist/index.js +1 -1
  97. package/dist/index.js.map +1 -1
  98. package/dist/launchInterProScan.d.ts +32 -0
  99. package/dist/launchInterProScan.js +47 -0
  100. package/dist/launchInterProScan.js.map +1 -0
  101. package/dist/model/DataModel.js.map +1 -0
  102. package/dist/model/DialogQueue.js.map +1 -0
  103. package/dist/model/msaModel.d.ts +14 -0
  104. package/dist/model/msaModel.js +36 -0
  105. package/dist/model/msaModel.js.map +1 -0
  106. package/dist/model/treeModel.d.ts +46 -0
  107. package/dist/model/treeModel.js +105 -0
  108. package/dist/model/treeModel.js.map +1 -0
  109. package/dist/model.d.ts +261 -273
  110. package/dist/model.js +1043 -1029
  111. package/dist/model.js.map +1 -1
  112. package/dist/parseGFF.d.ts +10 -0
  113. package/dist/parseGFF.js +29 -0
  114. package/dist/parseGFF.js.map +1 -0
  115. package/dist/renderToSvg.js +23 -9
  116. package/dist/renderToSvg.js.map +1 -1
  117. package/dist/reparseTree.d.ts +2 -0
  118. package/dist/reparseTree.js +13 -0
  119. package/dist/reparseTree.js.map +1 -0
  120. package/dist/util.d.ts +4 -10
  121. package/dist/util.js +3 -28
  122. package/dist/util.js.map +1 -1
  123. package/dist/version.d.ts +1 -1
  124. package/dist/version.js +1 -1
  125. package/package.json +12 -2
  126. package/src/components/Checkbox2.tsx +34 -0
  127. package/src/components/Loading.tsx +27 -11
  128. package/src/components/MSAView.tsx +6 -10
  129. package/src/components/SequenceTextArea.tsx +63 -0
  130. package/src/components/Track.tsx +8 -13
  131. package/src/components/dialogs/AddTrackDialog.tsx +0 -1
  132. package/src/components/{ExportSVGDialog.tsx → dialogs/ExportSVGDialog.tsx} +9 -16
  133. package/src/components/dialogs/FeatureDialog.tsx +109 -0
  134. package/src/components/dialogs/InterProScanDialog.tsx +230 -0
  135. package/src/components/dialogs/MetadataDialog.tsx +9 -2
  136. package/src/components/dialogs/SettingsDialog.tsx +10 -30
  137. package/src/components/header/Header.tsx +44 -0
  138. package/src/components/header/HeaderInfoArea.tsx +27 -0
  139. package/src/components/header/HeaderMenu.tsx +54 -0
  140. package/src/components/header/HeaderMenuExtra.tsx +108 -0
  141. package/src/components/header/HeaderStatusArea.tsx +31 -0
  142. package/src/components/{MultiAlignmentSelector.tsx → header/MultiAlignmentSelector.tsx} +1 -1
  143. package/src/components/header/ZoomControls.tsx +28 -0
  144. package/src/components/{ImportForm → import}/ImportFormExamples.tsx +12 -1
  145. package/src/components/{ImportForm → import}/util.ts +5 -10
  146. package/src/components/{Minimap.tsx → minimap/Minimap.tsx} +1 -1
  147. package/src/components/{MinimapSVG.tsx → minimap/MinimapSVG.tsx} +1 -1
  148. package/src/components/{MSAPanel → msa}/MSACanvas.tsx +3 -2
  149. package/src/components/{MSAPanel/MSABlock.tsx → msa/MSACanvasBlock.tsx} +25 -12
  150. package/src/components/{MSAPanel/index.tsx → msa/MSAPanel.tsx} +8 -2
  151. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +88 -0
  152. package/src/components/{MSAPanel → msa}/renderMSABlock.ts +26 -20
  153. package/src/components/{TreePanel → tree}/TreeCanvas.tsx +1 -1
  154. package/src/components/{TreePanel → tree}/TreeCanvasBlock.tsx +1 -1
  155. package/src/components/{TreePanel → tree}/TreeNodeMenu.tsx +1 -53
  156. package/src/components/{TreePanel/index.tsx → tree/TreePanel.tsx} +1 -1
  157. package/src/components/{TreePanel → tree}/dialogs/TreeNodeInfoDialog.tsx +9 -2
  158. package/src/components/{TreePanel → tree}/renderTreeCanvas.ts +25 -41
  159. package/src/fetchUtils.ts +30 -0
  160. package/src/ggplotPalettes.ts +25 -0
  161. package/src/index.ts +1 -1
  162. package/src/launchInterProScan.ts +98 -0
  163. package/src/model/msaModel.ts +39 -0
  164. package/src/model/treeModel.ts +116 -0
  165. package/src/model.ts +1124 -1126
  166. package/src/parseGFF.ts +32 -0
  167. package/src/renderToSvg.tsx +27 -8
  168. package/src/reparseTree.ts +16 -0
  169. package/src/util.ts +4 -33
  170. package/src/version.ts +1 -1
  171. package/dist/DataModel.js.map +0 -1
  172. package/dist/DialogQueue.js.map +0 -1
  173. package/dist/SelectedStructuresMixin.d.ts +0 -46
  174. package/dist/SelectedStructuresMixin.js +0 -52
  175. package/dist/SelectedStructuresMixin.js.map +0 -1
  176. package/dist/StructureModel.d.ts +0 -9
  177. package/dist/StructureModel.js +0 -11
  178. package/dist/StructureModel.js.map +0 -1
  179. package/dist/UniprotTrack.d.ts +0 -27
  180. package/dist/UniprotTrack.js +0 -53
  181. package/dist/UniprotTrack.js.map +0 -1
  182. package/dist/components/BoxTrack.d.ts +0 -7
  183. package/dist/components/BoxTrack.js +0 -15
  184. package/dist/components/BoxTrack.js.map +0 -1
  185. package/dist/components/BoxTrackBlock.d.ts +0 -8
  186. package/dist/components/BoxTrackBlock.js +0 -136
  187. package/dist/components/BoxTrackBlock.js.map +0 -1
  188. package/dist/components/ExportSVGDialog.js.map +0 -1
  189. package/dist/components/Header.js +0 -62
  190. package/dist/components/Header.js.map +0 -1
  191. package/dist/components/HeaderInfoArea.js +0 -12
  192. package/dist/components/HeaderInfoArea.js.map +0 -1
  193. package/dist/components/ImportForm/ImportFormExamples.js.map +0 -1
  194. package/dist/components/ImportForm/data/seq2.js.map +0 -1
  195. package/dist/components/ImportForm/index.js.map +0 -1
  196. package/dist/components/ImportForm/util.js +0 -16
  197. package/dist/components/ImportForm/util.js.map +0 -1
  198. package/dist/components/MSAPanel/Loading.js.map +0 -1
  199. package/dist/components/MSAPanel/MSABlock.js.map +0 -1
  200. package/dist/components/MSAPanel/MSACanvas.js.map +0 -1
  201. package/dist/components/MSAPanel/MSAMouseoverCanvas.js.map +0 -1
  202. package/dist/components/MSAPanel/index.d.ts +0 -5
  203. package/dist/components/MSAPanel/index.js.map +0 -1
  204. package/dist/components/MSAPanel/renderMSABlock.js.map +0 -1
  205. package/dist/components/MSAPanel/renderMSAMouseover.js.map +0 -1
  206. package/dist/components/Minimap.js.map +0 -1
  207. package/dist/components/MinimapSVG.js.map +0 -1
  208. package/dist/components/MultiAlignmentSelector.js.map +0 -1
  209. package/dist/components/TreePanel/TreeBranchMenu.js.map +0 -1
  210. package/dist/components/TreePanel/TreeCanvas.js.map +0 -1
  211. package/dist/components/TreePanel/TreeCanvasBlock.js.map +0 -1
  212. package/dist/components/TreePanel/TreeNodeMenu.js.map +0 -1
  213. package/dist/components/TreePanel/TreeRuler.js.map +0 -1
  214. package/dist/components/TreePanel/dialogs/TreeNodeInfoDialog.js.map +0 -1
  215. package/dist/components/TreePanel/index.js.map +0 -1
  216. package/dist/components/TreePanel/renderTreeCanvas.js.map +0 -1
  217. package/dist/components/VerticalGuide.d.ts +0 -7
  218. package/dist/components/VerticalGuide.js +0 -30
  219. package/dist/components/VerticalGuide.js.map +0 -1
  220. package/dist/components/ZoomControls.js +0 -59
  221. package/dist/components/ZoomControls.js.map +0 -1
  222. package/src/SelectedStructuresMixin.ts +0 -59
  223. package/src/StructureModel.ts +0 -11
  224. package/src/UniprotTrack.ts +0 -59
  225. package/src/components/BoxTrack.tsx +0 -33
  226. package/src/components/BoxTrackBlock.tsx +0 -200
  227. package/src/components/Header.tsx +0 -99
  228. package/src/components/HeaderInfoArea.tsx +0 -21
  229. package/src/components/VerticalGuide.tsx +0 -50
  230. package/src/components/ZoomControls.tsx +0 -86
  231. package/dist/components/{MultiAlignmentSelector.js → header/MultiAlignmentSelector.js} +0 -0
  232. package/dist/components/{ImportForm/index.d.ts → import/ImportForm.d.ts} +0 -0
  233. package/dist/components/{ImportForm → import}/ImportFormExamples.d.ts +0 -0
  234. package/dist/components/{ImportForm → import}/data/seq2.d.ts +0 -0
  235. package/dist/components/{ImportForm → import}/data/seq2.js +0 -0
  236. package/dist/components/{ImportForm → import}/util.d.ts +0 -0
  237. package/dist/components/{Minimap.js → minimap/Minimap.js} +0 -0
  238. package/dist/components/{MinimapSVG.js → minimap/MinimapSVG.js} +0 -0
  239. package/dist/components/{MSAPanel → msa}/Loading.d.ts +0 -0
  240. package/dist/components/{MSAPanel → msa}/Loading.js +0 -0
  241. package/dist/components/{MSAPanel → msa}/MSACanvas.d.ts +0 -0
  242. package/dist/components/{MSAPanel/MSABlock.d.ts → msa/MSACanvasBlock.d.ts} +0 -0
  243. package/dist/components/{MSAPanel → msa}/MSAMouseoverCanvas.d.ts +0 -0
  244. package/dist/components/{MSAPanel → msa}/MSAMouseoverCanvas.js +0 -0
  245. package/dist/components/{MSAPanel → msa}/renderMSABlock.d.ts +1 -1
  246. /package/dist/components/{MSAPanel → msa}/renderMSAMouseover.d.ts +0 -0
  247. /package/dist/components/{MSAPanel → msa}/renderMSAMouseover.js +0 -0
  248. /package/dist/components/{TreePanel → tree}/TreeBranchMenu.d.ts +0 -0
  249. /package/dist/components/{TreePanel → tree}/TreeBranchMenu.js +0 -0
  250. /package/dist/components/{TreePanel → tree}/TreeCanvas.d.ts +0 -0
  251. /package/dist/components/{TreePanel → tree}/TreeCanvasBlock.d.ts +0 -0
  252. /package/dist/components/{TreePanel → tree}/TreeNodeMenu.d.ts +0 -0
  253. /package/dist/components/{TreePanel/index.d.ts → tree/TreePanel.d.ts} +0 -0
  254. /package/dist/components/{TreePanel → tree}/TreeRuler.d.ts +0 -0
  255. /package/dist/components/{TreePanel → tree}/TreeRuler.js +0 -0
  256. /package/dist/components/{TreePanel → tree}/dialogs/TreeNodeInfoDialog.d.ts +0 -0
  257. /package/dist/components/{TreePanel → tree}/renderTreeCanvas.d.ts +0 -0
  258. /package/dist/{DataModel.d.ts → model/DataModel.d.ts} +0 -0
  259. /package/dist/{DataModel.js → model/DataModel.js} +0 -0
  260. /package/dist/{DialogQueue.d.ts → model/DialogQueue.d.ts} +0 -0
  261. /package/dist/{DialogQueue.js → model/DialogQueue.js} +0 -0
  262. /package/src/components/{ImportForm/index.tsx → import/ImportForm.tsx} +0 -0
  263. /package/src/components/{ImportForm → import}/data/seq2.ts +0 -0
  264. /package/src/components/{MSAPanel → msa}/Loading.tsx +0 -0
  265. /package/src/components/{MSAPanel → msa}/MSAMouseoverCanvas.tsx +0 -0
  266. /package/src/components/{MSAPanel → msa}/renderMSAMouseover.ts +0 -0
  267. /package/src/components/{TreePanel → tree}/TreeBranchMenu.tsx +0 -0
  268. /package/src/components/{TreePanel → tree}/TreeRuler.tsx +0 -0
  269. /package/src/{DataModel.ts → model/DataModel.ts} +0 -0
  270. /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
@@ -3,7 +3,7 @@ import { observer } from 'mobx-react'
3
3
  import { Select } from '@mui/material'
4
4
 
5
5
  // locals
6
- import { MsaViewModel } from '../model'
6
+ import { MsaViewModel } from '../../model'
7
7
 
8
8
  const MultiAlignmentSelector = observer(function ({
9
9
  model,
@@ -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
- try {
11
- if (msaFile) {
12
- await model.setMSAFilehandle(msaFile)
13
- }
14
- if (treeFile) {
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 '../model'
3
+ import { MsaViewModel } from '../../model'
4
4
 
5
5
  const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
6
6
  const [mouseDown, setMouseDown] = useState<{
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import { observer } from 'mobx-react'
3
- import { MsaViewModel } from '../model'
3
+ import { MsaViewModel } from '../../model'
4
4
 
5
5
  const MinimapSVG = observer(function ({ model }: { model: MsaViewModel }) {
6
6
  const {
@@ -4,7 +4,7 @@ import normalizeWheel from 'normalize-wheel'
4
4
 
5
5
  // locals
6
6
  import { MsaViewModel } from '../../model'
7
- import MSABlock from './MSABlock'
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
- <MSABlock
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
- return ctx
42
- ? autorun(() => {
43
- renderMSABlock({
44
- ctx,
45
- theme,
46
- offsetX,
47
- offsetY,
48
- contrastScheme,
49
- model,
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
- : undefined
53
- }, [model, offsetX, offsetY, theme, contrastScheme])
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
- export default function MSAPanel({ model }: { model: MsaViewModel }) {
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
- drawTiles({
56
- model,
57
- ctx,
58
- theme,
59
- offsetX,
60
- offsetY,
61
- xStart,
62
- xEnd,
63
- visibleLeaves,
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 } = model
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 = bgColor ? contrast : color || 'black'
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
  >
@@ -103,7 +103,7 @@ const TreeCanvasBlock = observer(function ({
103
103
  maxY: y + 1 + offsetY,
104
104
  })
105
105
 
106
- return entry && entry.branch
106
+ return entry?.branch
107
107
  ? { ...entry, x: event.clientX, y: event.clientY }
108
108
  : undefined
109
109
  }
@@ -17,9 +17,7 @@ const TreeMenu = observer(function ({
17
17
  model: MsaViewModel
18
18
  onClose: () => void
19
19
  }) {
20
- const { selectedStructures, collapsed, collapsed2, structures } = model
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} />