react-msaview 7.0.0 → 8.1.0

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 (335) hide show
  1. package/README.md +11 -10
  2. package/bundle/index.js +122 -111
  3. package/bundle/index.js.map +4 -4
  4. package/dist/calculateBlocks.js +5 -3
  5. package/dist/calculateBlocks.js.map +1 -1
  6. package/dist/colorSchemes.js +1 -2
  7. package/dist/colorSchemes.js.map +1 -1
  8. package/dist/columnStats.d.ts +28 -0
  9. package/dist/columnStats.js +34 -0
  10. package/dist/columnStats.js.map +1 -0
  11. package/dist/components/DragHandle.d.ts +3 -2
  12. package/dist/components/DragHandle.js +11 -5
  13. package/dist/components/DragHandle.js.map +1 -1
  14. package/dist/components/Loading.js +2 -8
  15. package/dist/components/Loading.js.map +1 -1
  16. package/dist/components/MSAView.js +17 -6
  17. package/dist/components/MSAView.js.map +1 -1
  18. package/dist/components/MSAViewer.d.ts +64 -7
  19. package/dist/components/MSAViewer.js +128 -23
  20. package/dist/components/MSAViewer.js.map +1 -1
  21. package/dist/components/PortalTooltip.d.ts +11 -0
  22. package/dist/components/PortalTooltip.js +29 -0
  23. package/dist/components/PortalTooltip.js.map +1 -0
  24. package/dist/components/ResizeHandles.js +11 -29
  25. package/dist/components/ResizeHandles.js.map +1 -1
  26. package/dist/components/SequenceTextArea.js +3 -4
  27. package/dist/components/SequenceTextArea.js.map +1 -1
  28. package/dist/components/Track.js +43 -24
  29. package/dist/components/Track.js.map +1 -1
  30. package/dist/components/dialogs/AboutDialog.js +6 -6
  31. package/dist/components/dialogs/AboutDialog.js.map +1 -1
  32. package/dist/components/dialogs/AnnotationFileDialog.js +5 -2
  33. package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -1
  34. package/dist/components/dialogs/ExportSVGDialog.js +6 -4
  35. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  36. package/dist/components/dialogs/FeatureDialog.js +8 -3
  37. package/dist/components/dialogs/FeatureDialog.js.map +1 -1
  38. package/dist/components/dialogs/TrackInfoDialog.js +1 -1
  39. package/dist/components/dialogs/TrackInfoDialog.js.map +1 -1
  40. package/dist/components/header/GappynessSlider.js +6 -11
  41. package/dist/components/header/GappynessSlider.js.map +1 -1
  42. package/dist/components/header/Header.js +4 -1
  43. package/dist/components/header/Header.js.map +1 -1
  44. package/dist/components/header/LoadWarnings.js +6 -23
  45. package/dist/components/header/LoadWarnings.js.map +1 -1
  46. package/dist/components/header/ScrollZoomIcons.d.ts +6 -0
  47. package/dist/components/header/ScrollZoomIcons.js +35 -0
  48. package/dist/components/header/ScrollZoomIcons.js.map +1 -0
  49. package/dist/components/header/TreeSettingsMenu.js +1 -3
  50. package/dist/components/header/TreeSettingsMenu.js.map +1 -1
  51. package/dist/components/header/UnshareableDataWarning.js +2 -4
  52. package/dist/components/header/UnshareableDataWarning.js.map +1 -1
  53. package/dist/components/header/ZoomControls.js +49 -6
  54. package/dist/components/header/ZoomControls.js.map +1 -1
  55. package/dist/components/header/getAnnotationsMenu.js +3 -6
  56. package/dist/components/header/getAnnotationsMenu.js.map +1 -1
  57. package/dist/components/header/settingsMenuItems.js +12 -9
  58. package/dist/components/header/settingsMenuItems.js.map +1 -1
  59. package/dist/components/import/ImportForm.js +1 -1
  60. package/dist/components/import/ImportForm.js.map +1 -1
  61. package/dist/components/import/util.js +1 -2
  62. package/dist/components/import/util.js.map +1 -1
  63. package/dist/components/minimap/Minimap.js +1 -2
  64. package/dist/components/minimap/Minimap.js.map +1 -1
  65. package/dist/components/msa/AnnotationLegend.js +27 -19
  66. package/dist/components/msa/AnnotationLegend.js.map +1 -1
  67. package/dist/components/msa/MSACanvas.js +2 -4
  68. package/dist/components/msa/MSACanvas.js.map +1 -1
  69. package/dist/components/msa/MSACanvasBlock.js +13 -15
  70. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  71. package/dist/components/msa/MSAMouseoverCanvas.js +2 -1
  72. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  73. package/dist/components/msa/domainBandCursor.d.ts +7 -11
  74. package/dist/components/msa/domainBandCursor.js +7 -11
  75. package/dist/components/msa/domainBandCursor.js.map +1 -1
  76. package/dist/components/msa/drawFeatureSpans.d.ts +59 -0
  77. package/dist/components/msa/drawFeatureSpans.js +113 -0
  78. package/dist/components/msa/drawFeatureSpans.js.map +1 -0
  79. package/dist/components/msa/legendRows.d.ts +8 -0
  80. package/dist/components/msa/legendRows.js +16 -0
  81. package/dist/components/msa/legendRows.js.map +1 -0
  82. package/dist/components/msa/msaRaster.d.ts +24 -31
  83. package/dist/components/msa/msaRaster.js +30 -39
  84. package/dist/components/msa/msaRaster.js.map +1 -1
  85. package/dist/components/msa/packDomainLanes.d.ts +20 -0
  86. package/dist/components/msa/packDomainLanes.js +33 -0
  87. package/dist/components/msa/packDomainLanes.js.map +1 -0
  88. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +3 -1
  89. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +50 -87
  90. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  91. package/dist/components/msa/renderHighlights.d.ts +15 -13
  92. package/dist/components/msa/renderHighlights.js +43 -20
  93. package/dist/components/msa/renderHighlights.js.map +1 -1
  94. package/dist/components/msa/renderMSABlock.js +12 -12
  95. package/dist/components/msa/renderMSABlock.js.map +1 -1
  96. package/dist/components/msa/tileColor.js +4 -7
  97. package/dist/components/msa/tileColor.js.map +1 -1
  98. package/dist/components/msa/useMsaBlockMouse.d.ts +5 -3
  99. package/dist/components/msa/useMsaBlockMouse.js +6 -6
  100. package/dist/components/msa/useMsaBlockMouse.js.map +1 -1
  101. package/dist/components/rowpanels/RowPanelBlock.d.ts +9 -0
  102. package/dist/components/rowpanels/RowPanelBlock.js +86 -0
  103. package/dist/components/rowpanels/RowPanelBlock.js.map +1 -0
  104. package/dist/components/rowpanels/RowPanelHeaders.d.ts +12 -0
  105. package/dist/components/rowpanels/RowPanelHeaders.js +38 -0
  106. package/dist/components/rowpanels/RowPanelHeaders.js.map +1 -0
  107. package/dist/components/{msa/ColumnStats.d.ts → rowpanels/RowPanels.d.ts} +2 -2
  108. package/dist/components/rowpanels/RowPanels.js +32 -0
  109. package/dist/components/rowpanels/RowPanels.js.map +1 -0
  110. package/dist/components/rowpanels/headerLayout.d.ts +1 -0
  111. package/dist/components/rowpanels/headerLayout.js +5 -0
  112. package/dist/components/rowpanels/headerLayout.js.map +1 -0
  113. package/dist/components/rowpanels/renderFeaturePanel.d.ts +21 -0
  114. package/dist/components/rowpanels/renderFeaturePanel.js +37 -0
  115. package/dist/components/rowpanels/renderFeaturePanel.js.map +1 -0
  116. package/dist/components/rowpanels/renderRowPanel.d.ts +23 -0
  117. package/dist/components/rowpanels/renderRowPanel.js +22 -0
  118. package/dist/components/rowpanels/renderRowPanel.js.map +1 -0
  119. package/dist/components/rowpanels/renderStrip.d.ts +20 -0
  120. package/dist/components/rowpanels/renderStrip.js +26 -0
  121. package/dist/components/rowpanels/renderStrip.js.map +1 -0
  122. package/dist/components/tracks/TrackBlocks.js +3 -5
  123. package/dist/components/tracks/TrackBlocks.js.map +1 -1
  124. package/dist/components/tracks/TrackTooltipContent.d.ts +15 -0
  125. package/dist/components/tracks/TrackTooltipContent.js +109 -0
  126. package/dist/components/tracks/TrackTooltipContent.js.map +1 -0
  127. package/dist/components/tracks/drawTracks.d.ts +4 -4
  128. package/dist/components/tracks/drawTracks.js +25 -39
  129. package/dist/components/tracks/drawTracks.js.map +1 -1
  130. package/dist/components/tracks/useTrackHover.d.ts +22 -0
  131. package/dist/components/tracks/useTrackHover.js +30 -0
  132. package/dist/components/tracks/useTrackHover.js.map +1 -0
  133. package/dist/components/tree/CladeLabels.d.ts +12 -0
  134. package/dist/components/tree/CladeLabels.js +48 -0
  135. package/dist/components/tree/CladeLabels.js.map +1 -0
  136. package/dist/components/tree/TreeBranchMenu.js +1 -1
  137. package/dist/components/tree/TreeBranchMenu.js.map +1 -1
  138. package/dist/components/tree/TreeCanvas.js +5 -4
  139. package/dist/components/tree/TreeCanvas.js.map +1 -1
  140. package/dist/components/tree/TreeCanvasBlock.js +4 -21
  141. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  142. package/dist/components/tree/TreeNodeMenu.js +1 -1
  143. package/dist/components/tree/TreeNodeMenu.js.map +1 -1
  144. package/dist/components/tree/TreeOverview.d.ts +14 -0
  145. package/dist/components/tree/TreeOverview.js +75 -0
  146. package/dist/components/tree/TreeOverview.js.map +1 -0
  147. package/dist/components/tree/TreeRuler.js +9 -13
  148. package/dist/components/tree/TreeRuler.js.map +1 -1
  149. package/dist/components/tree/cladeBrackets.d.ts +25 -0
  150. package/dist/components/tree/cladeBrackets.js +51 -0
  151. package/dist/components/tree/cladeBrackets.js.map +1 -0
  152. package/dist/components/tree/dialogs/TreeNodeInfoDialog.js +2 -2
  153. package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -1
  154. package/dist/components/tree/renderTreeCanvas.js +160 -25
  155. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  156. package/dist/components/tree/renderTreeOverview.d.ts +52 -0
  157. package/dist/components/tree/renderTreeOverview.js +138 -0
  158. package/dist/components/tree/renderTreeOverview.js.map +1 -0
  159. package/dist/components/tree/useTreeHover.js +2 -4
  160. package/dist/components/tree/useTreeHover.js.map +1 -1
  161. package/dist/constants.d.ts +16 -0
  162. package/dist/constants.js +52 -22
  163. package/dist/constants.js.map +1 -1
  164. package/dist/createPaletteMap.d.ts +7 -6
  165. package/dist/createPaletteMap.js +10 -9
  166. package/dist/createPaletteMap.js.map +1 -1
  167. package/dist/element.d.ts +13 -0
  168. package/dist/element.js +269 -0
  169. package/dist/element.js.map +1 -0
  170. package/dist/featureFields.d.ts +11 -0
  171. package/dist/featureFields.js +17 -0
  172. package/dist/featureFields.js.map +1 -0
  173. package/dist/flatToTree.js +1 -2
  174. package/dist/flatToTree.js.map +1 -1
  175. package/dist/ggplotPalettes.d.ts +10 -0
  176. package/dist/ggplotPalettes.js +58 -0
  177. package/dist/ggplotPalettes.js.map +1 -1
  178. package/dist/hierarchy.d.ts +27 -0
  179. package/dist/hierarchy.js +66 -9
  180. package/dist/hierarchy.js.map +1 -1
  181. package/dist/index.d.ts +9 -1
  182. package/dist/index.js +5 -3
  183. package/dist/index.js.map +1 -1
  184. package/dist/model/DataModel.js +2 -5
  185. package/dist/model/DataModel.js.map +1 -1
  186. package/dist/model/msaModel.d.ts +3 -2
  187. package/dist/model/msaModel.js +3 -2
  188. package/dist/model/msaModel.js.map +1 -1
  189. package/dist/model/treeModel.d.ts +30 -0
  190. package/dist/model/treeModel.js +37 -1
  191. package/dist/model/treeModel.js.map +1 -1
  192. package/dist/model.d.ts +549 -294
  193. package/dist/model.js +1412 -621
  194. package/dist/model.js.map +1 -1
  195. package/dist/mount.d.ts +11 -0
  196. package/dist/mount.js +22 -0
  197. package/dist/mount.js.map +1 -0
  198. package/dist/neighborJoining.js +8 -32
  199. package/dist/neighborJoining.js.map +1 -1
  200. package/dist/renderToStaticMarkup.d.ts +10 -19
  201. package/dist/renderToStaticMarkup.js +13 -24
  202. package/dist/renderToStaticMarkup.js.map +1 -1
  203. package/dist/renderToSvg.js +180 -56
  204. package/dist/renderToSvg.js.map +1 -1
  205. package/dist/rowCoordinateCalculations.d.ts +4 -6
  206. package/dist/rowCoordinateCalculations.js +4 -6
  207. package/dist/rowCoordinateCalculations.js.map +1 -1
  208. package/dist/scales.d.ts +22 -0
  209. package/dist/scales.js +30 -0
  210. package/dist/scales.js.map +1 -0
  211. package/dist/seqPosToGlobalCol.d.ts +2 -3
  212. package/dist/seqPosToGlobalCol.js +2 -3
  213. package/dist/seqPosToGlobalCol.js.map +1 -1
  214. package/dist/sequenceLogo.d.ts +6 -11
  215. package/dist/sequenceLogo.js +6 -11
  216. package/dist/sequenceLogo.js.map +1 -1
  217. package/dist/stripDefault.d.ts +7 -14
  218. package/dist/stripDefault.js +7 -14
  219. package/dist/stripDefault.js.map +1 -1
  220. package/dist/svgTestUtil.d.ts +186 -70
  221. package/dist/types.d.ts +221 -21
  222. package/dist/umd.d.ts +2 -0
  223. package/dist/umd.js +4 -2
  224. package/dist/umd.js.map +1 -1
  225. package/dist/useCanvasAutorun.d.ts +5 -10
  226. package/dist/useCanvasAutorun.js +5 -10
  227. package/dist/useCanvasAutorun.js.map +1 -1
  228. package/dist/useMsaSvgFigure.d.ts +20 -0
  229. package/dist/useMsaSvgFigure.js +46 -0
  230. package/dist/useMsaSvgFigure.js.map +1 -0
  231. package/dist/useWheelScroll.js +0 -4
  232. package/dist/useWheelScroll.js.map +1 -1
  233. package/dist/util.d.ts +5 -6
  234. package/dist/util.js +13 -6
  235. package/dist/util.js.map +1 -1
  236. package/dist/version.d.ts +1 -1
  237. package/dist/version.js +1 -1
  238. package/package.json +19 -12
  239. package/src/calculateBlocks.ts +5 -3
  240. package/src/colorSchemes.ts +1 -2
  241. package/src/columnStats.ts +58 -0
  242. package/src/components/DragHandle.tsx +18 -7
  243. package/src/components/Loading.tsx +4 -36
  244. package/src/components/MSAView.tsx +19 -5
  245. package/src/components/MSAViewer.tsx +240 -28
  246. package/src/components/PortalTooltip.tsx +47 -0
  247. package/src/components/ResizeHandles.tsx +17 -32
  248. package/src/components/SequenceTextArea.tsx +3 -4
  249. package/src/components/Track.tsx +57 -19
  250. package/src/components/dialogs/AboutDialog.tsx +35 -6
  251. package/src/components/dialogs/AnnotationFileDialog.tsx +10 -1
  252. package/src/components/dialogs/ExportSVGDialog.tsx +8 -3
  253. package/src/components/dialogs/FeatureDialog.tsx +11 -3
  254. package/src/components/dialogs/TrackInfoDialog.tsx +1 -1
  255. package/src/components/header/GappynessSlider.tsx +6 -11
  256. package/src/components/header/Header.tsx +7 -1
  257. package/src/components/header/LoadWarnings.tsx +11 -25
  258. package/src/components/header/ScrollZoomIcons.tsx +52 -0
  259. package/src/components/header/TreeSettingsMenu.tsx +1 -3
  260. package/src/components/header/UnshareableDataWarning.tsx +2 -4
  261. package/src/components/header/ZoomControls.tsx +74 -14
  262. package/src/components/header/getAnnotationsMenu.ts +3 -6
  263. package/src/components/header/settingsMenuItems.ts +13 -8
  264. package/src/components/import/ImportForm.tsx +3 -5
  265. package/src/components/import/ImportFormExamples.tsx +2 -2
  266. package/src/components/import/util.ts +1 -2
  267. package/src/components/minimap/Minimap.tsx +1 -2
  268. package/src/components/msa/AnnotationLegend.tsx +48 -38
  269. package/src/components/msa/MSACanvas.tsx +3 -8
  270. package/src/components/msa/MSACanvasBlock.tsx +13 -16
  271. package/src/components/msa/MSAMouseoverCanvas.tsx +2 -1
  272. package/src/components/msa/domainBandCursor.ts +7 -11
  273. package/src/components/msa/drawFeatureSpans.ts +205 -0
  274. package/src/components/msa/legendRows.ts +24 -0
  275. package/src/components/msa/msaRaster.ts +30 -39
  276. package/src/components/msa/packDomainLanes.ts +36 -0
  277. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +67 -123
  278. package/src/components/msa/renderHighlights.ts +53 -20
  279. package/src/components/msa/renderMSABlock.ts +14 -11
  280. package/src/components/msa/tileColor.ts +4 -7
  281. package/src/components/msa/useMsaBlockMouse.ts +6 -6
  282. package/src/components/rowpanels/RowPanelBlock.tsx +139 -0
  283. package/src/components/rowpanels/RowPanelHeaders.tsx +57 -0
  284. package/src/components/rowpanels/RowPanels.tsx +77 -0
  285. package/src/components/rowpanels/headerLayout.ts +5 -0
  286. package/src/components/rowpanels/renderFeaturePanel.ts +66 -0
  287. package/src/components/rowpanels/renderRowPanel.ts +41 -0
  288. package/src/components/rowpanels/renderStrip.ts +46 -0
  289. package/src/components/tracks/TrackBlocks.tsx +3 -5
  290. package/src/components/tracks/TrackTooltipContent.tsx +156 -0
  291. package/src/components/tracks/drawTracks.ts +25 -50
  292. package/src/components/tracks/useTrackHover.ts +42 -0
  293. package/src/components/tree/CladeLabels.tsx +77 -0
  294. package/src/components/tree/TreeBranchMenu.tsx +1 -2
  295. package/src/components/tree/TreeCanvas.tsx +2 -3
  296. package/src/components/tree/TreeCanvasBlock.tsx +8 -32
  297. package/src/components/tree/TreeNodeMenu.tsx +1 -2
  298. package/src/components/tree/TreeOverview.tsx +106 -0
  299. package/src/components/tree/TreeRuler.tsx +11 -22
  300. package/src/components/tree/cladeBrackets.ts +73 -0
  301. package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +2 -2
  302. package/src/components/tree/renderTreeCanvas.ts +242 -21
  303. package/src/components/tree/renderTreeOverview.ts +212 -0
  304. package/src/components/tree/useTreeHover.ts +2 -4
  305. package/src/constants.ts +61 -22
  306. package/src/createPaletteMap.ts +10 -9
  307. package/src/element.ts +321 -0
  308. package/src/featureFields.ts +19 -0
  309. package/src/flatToTree.ts +1 -2
  310. package/src/ggplotPalettes.ts +60 -0
  311. package/src/hierarchy.ts +77 -9
  312. package/src/index.ts +31 -7
  313. package/src/model/DataModel.ts +2 -5
  314. package/src/model/msaModel.ts +3 -2
  315. package/src/model/treeModel.ts +42 -0
  316. package/src/model.ts +1677 -643
  317. package/src/mount.tsx +32 -0
  318. package/src/neighborJoining.ts +8 -32
  319. package/src/renderToStaticMarkup.ts +13 -24
  320. package/src/renderToSvg.tsx +335 -68
  321. package/src/rowCoordinateCalculations.ts +4 -6
  322. package/src/scales.ts +47 -0
  323. package/src/seqPosToGlobalCol.ts +2 -3
  324. package/src/sequenceLogo.ts +6 -11
  325. package/src/stripDefault.ts +7 -14
  326. package/src/types.ts +260 -45
  327. package/src/umd.ts +4 -2
  328. package/src/useCanvasAutorun.ts +5 -10
  329. package/src/useMsaSvgFigure.ts +72 -0
  330. package/src/useWheelScroll.ts +0 -4
  331. package/src/util.ts +15 -6
  332. package/src/version.ts +1 -1
  333. package/dist/components/msa/ColumnStats.js +0 -42
  334. package/dist/components/msa/ColumnStats.js.map +0 -1
  335. package/src/components/msa/ColumnStats.tsx +0 -54
@@ -17,16 +17,33 @@ export default function AboutDialog({ onClose }: { onClose: () => void }) {
17
17
  <DialogContent>
18
18
  <Typography>
19
19
  MSAView {version} (
20
- <Link href="https://github.com/gmod/react-msaview">Github</Link>)
20
+ <Link
21
+ target="_blank"
22
+ rel="noopener"
23
+ href="https://github.com/gmod/react-msaview"
24
+ >
25
+ Github
26
+ </Link>
27
+ )
21
28
  </Typography>
22
29
 
23
30
  <ul>
24
31
  <li>
25
32
  <Typography>
26
33
  We use some color schemes from the{' '}
27
- <Link href="https://github.com/biotite-dev/biotite">biotite</Link>{' '}
34
+ <Link
35
+ target="_blank"
36
+ rel="noopener"
37
+ href="https://github.com/biotite-dev/biotite"
38
+ >
39
+ biotite
40
+ </Link>{' '}
28
41
  project, and their license is reproduced{' '}
29
- <Link href="https://github.com/biotite-dev/biotite/blob/master/LICENSE.rst">
42
+ <Link
43
+ target="_blank"
44
+ rel="noopener"
45
+ href="https://github.com/biotite-dev/biotite/blob/master/LICENSE.rst"
46
+ >
30
47
  here
31
48
  </Link>
32
49
  </Typography>
@@ -34,7 +51,11 @@ export default function AboutDialog({ onClose }: { onClose: () => void }) {
34
51
  <li>
35
52
  <Typography>
36
53
  See this page for some information on jalview colorings{' '}
37
- <Link href="https://www.jalview.org/help/html/colourSchemes/">
54
+ <Link
55
+ target="_blank"
56
+ rel="noopener"
57
+ href="https://www.jalview.org/help/html/colourSchemes/"
58
+ >
38
59
  here
39
60
  </Link>
40
61
  </Typography>
@@ -43,7 +64,11 @@ export default function AboutDialog({ onClose }: { onClose: () => void }) {
43
64
  <Typography>
44
65
  See this page for some info on the clustal, cinema, maeditor, and
45
66
  lesk color schemes{' '}
46
- <Link href="http://www.bioinformatics.nl/~berndb/aacolour.html">
67
+ <Link
68
+ target="_blank"
69
+ rel="noopener"
70
+ href="http://www.bioinformatics.nl/~berndb/aacolour.html"
71
+ >
47
72
  here
48
73
  </Link>
49
74
  </Typography>
@@ -51,7 +76,11 @@ export default function AboutDialog({ onClose }: { onClose: () => void }) {
51
76
  <li>
52
77
  <Typography>
53
78
  See this paper about the flower color scheme{' '}
54
- <Link href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7245768/">
79
+ <Link
80
+ target="_blank"
81
+ rel="noopener"
82
+ href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7245768/"
83
+ >
55
84
  here
56
85
  </Link>
57
86
  </Typography>
@@ -126,7 +126,7 @@ const AnnotationFileDialog = observer(function ({
126
126
  <Button
127
127
  variant="contained"
128
128
  color="primary"
129
- disabled={loading}
129
+ disabled={loading || (choice === 'file' ? !file : !url.trim())}
130
130
  onClick={() => {
131
131
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
132
132
  ;(async () => {
@@ -154,6 +154,15 @@ const AnnotationFileDialog = observer(function ({
154
154
  >
155
155
  Open annotations
156
156
  </Button>
157
+ <Button
158
+ variant="contained"
159
+ color="secondary"
160
+ onClick={() => {
161
+ handleClose()
162
+ }}
163
+ >
164
+ Cancel
165
+ </Button>
157
166
  </DialogActions>
158
167
  </Dialog>
159
168
  )
@@ -49,15 +49,20 @@ export default function ExportSVGDialog({
49
49
  totalWidth,
50
50
  totalHeight,
51
51
  treeAreaWidth,
52
+ rowPanelsWidth,
52
53
  turnedOnTracks,
53
54
  totalTrackAreaHeight,
54
55
  numColumns,
55
56
  leaves,
56
57
  showMsaLetters,
58
+ treeOverviewHeight,
57
59
  } = model
58
60
  const hasTracks = turnedOnTracks.length > 0
59
- const entireWidth = totalWidth + treeAreaWidth
60
- const entireHeight = totalHeight + (includeTracks ? totalTrackAreaHeight : 0)
61
+ const entireWidth = totalWidth + treeAreaWidth + rowPanelsWidth
62
+ const entireHeight =
63
+ totalHeight +
64
+ (includeTracks ? totalTrackAreaHeight : 0) +
65
+ treeOverviewHeight
61
66
  // the background is one raster image whatever its size, so what the figure
62
67
  // actually costs is its residue letters: each is an svg element of its own.
63
68
  // Past roughly this many the export runs to tens of seconds and can exhaust
@@ -162,7 +167,7 @@ export default function ExportSVGDialog({
162
167
  })
163
168
  }}
164
169
  >
165
- {exporting ? 'Exporting…' : 'Submit'}
170
+ {exporting ? 'Exporting…' : 'Export'}
166
171
  </Button>
167
172
  <Button
168
173
  variant="contained"
@@ -47,10 +47,18 @@ const Toggles = observer(function ({ model }: { model: MsaViewModel }) {
47
47
  })
48
48
 
49
49
  const FeatureTable = observer(function ({ model }: { model: MsaViewModel }) {
50
- const { annotationTypes, annotations, fillPalette } = model
50
+ const { annotationTypes, annotations, featureColors, fillPalette } = model
51
51
  const counts = new Map<string, number>()
52
+ const swatches = new Map<string, string>()
52
53
  for (const annot of annotations) {
53
- counts.set(annot.accession, (counts.get(annot.accession) ?? 0) + 1)
54
+ const { accession } = annot
55
+ counts.set(accession, (counts.get(accession) ?? 0) + 1)
56
+ if (!swatches.has(accession)) {
57
+ swatches.set(
58
+ accession,
59
+ featureColors.get(annot)?.fill ?? fillPalette[accession]!,
60
+ )
61
+ }
54
62
  }
55
63
  return (
56
64
  <>
@@ -86,7 +94,7 @@ const FeatureTable = observer(function ({ model }: { model: MsaViewModel }) {
86
94
  style={{
87
95
  width: 20,
88
96
  height: 20,
89
- background: fillPalette[accession],
97
+ background: swatches.get(accession),
90
98
  }}
91
99
  />
92
100
  </TableCell>
@@ -13,7 +13,7 @@ const useStyles = makeStyles()(theme => ({
13
13
  textArea: {
14
14
  padding: theme.spacing(2),
15
15
  overflow: 'auto',
16
- background: '#ddd',
16
+ background: theme.palette.action.selected,
17
17
  wordBreak: 'break-word',
18
18
  },
19
19
  }))
@@ -23,18 +23,13 @@ const GappynessSlider = observer(function GappynessSlider({
23
23
  Hide columns w/ &ge;{allowedGappyness}% gaps
24
24
  </Typography>
25
25
  <Slider
26
- // Named, because the class alone is not enough to find it from outside.
27
- // An MSA is normally embedded beside other MUI Sliders (in JBrowse, the
28
- // linear view's own zoom control), so a `.MuiSlider-thumb` selector in a
29
- // test or a screenshot spec picks whichever comes first in the document
30
- // and drives that instead — which reads as this slider ignoring its
31
- // keyboard. Target `[data-testid="gappyness_slider"] input` to reach the
32
- // hidden range input MUI renders in the thumb, which is the node that
33
- // takes focus and receives arrow/PageUp/PageDown.
26
+ // In JBrowse other MUI Sliders share the page, so `.MuiSlider-thumb`
27
+ // can match the wrong one. Tests and screenshot specs target
28
+ // `[data-testid="gappyness_slider"] input`, the hidden range input that
29
+ // takes focus and arrow/PageUp/PageDown.
34
30
  //
35
- // Deliberately NOT `slotProps={{ input: ... }}`: passing slotProps here
36
- // widens the Slider's generic so `onChange`'s `val` infers as
37
- // `number | number[]` and no longer assigns to setAllowedGappyness.
31
+ // Not `slotProps={{ input: ... }}`: that widens `onChange`'s `val` to
32
+ // `number | number[]`, which setAllowedGappyness rejects.
38
33
  data-testid="gappyness_slider"
39
34
  style={{ width: 100 }}
40
35
  min={1}
@@ -27,8 +27,14 @@ const Header = observer(function ({ model }: { model: MsaViewModel }) {
27
27
  useEffect(() => {
28
28
  model.setHeaderHeight(height ?? 0)
29
29
  }, [model, height])
30
+ useEffect(
31
+ () => () => {
32
+ model.setHeaderHeight(0)
33
+ },
34
+ [model],
35
+ )
30
36
  return (
31
- <div ref={ref} style={{ display: 'flex' }}>
37
+ <div ref={ref} style={{ display: 'flex', flexWrap: 'wrap' }}>
32
38
  <FileMenu model={model} />
33
39
  <ColorSchemeMenu model={model} />
34
40
  <TreeSettingsMenu model={model} />
@@ -1,47 +1,33 @@
1
1
  import React from 'react'
2
2
 
3
- import { makeStyles } from '@jbrowse/core/util/tss-react'
4
3
  import Warning from '@mui/icons-material/Warning'
5
- import { Tooltip, Typography } from '@mui/material'
4
+ import { Button, Tooltip } from '@mui/material'
6
5
  import { observer } from 'mobx-react'
7
6
 
8
7
  import type { MsaViewModel } from '../../model.ts'
9
8
 
10
- const useStyles = makeStyles()(theme => ({
11
- warning: {
12
- display: 'flex',
13
- alignItems: 'center',
14
- gap: 4,
15
- margin: 'auto',
16
- marginLeft: 10,
17
- whiteSpace: 'nowrap',
18
- color: theme.palette.warning.main,
19
- cursor: 'pointer',
20
- },
21
- }))
22
-
23
- // An optional layer that failed -- a 404 on the annotations, a row-metadata
24
- // file that is not JSON -- used to go to `error`, which takes dataInitialized
25
- // down with it and replaces a perfectly good alignment with an error screen.
26
- // It says so here instead, and the reader dismisses it.
9
+ // A failed optional layer, such as a 404 on the annotations or row metadata
10
+ // that is not JSON, shows here as a dismissible warning. Setting `error` would
11
+ // clear dataInitialized and hide the loaded alignment.
27
12
  const LoadWarnings = observer(function ({ model }: { model: MsaViewModel }) {
28
13
  const { warnings } = model
29
- const { classes } = useStyles()
30
14
  if (warnings.length === 0) {
31
15
  return null
32
16
  }
33
17
  return (
34
18
  <Tooltip title={`${warnings.join(' ')} (click to dismiss)`}>
35
- <Typography
36
- component="div"
37
- className={classes.warning}
19
+ <Button
20
+ aria-label="Dismiss warnings"
21
+ color="warning"
22
+ size="small"
23
+ startIcon={<Warning fontSize="small" />}
24
+ style={{ margin: 'auto', marginLeft: 10, whiteSpace: 'nowrap' }}
38
25
  onClick={() => {
39
26
  model.clearWarnings()
40
27
  }}
41
28
  >
42
- <Warning fontSize="small" />
43
29
  {warnings.length > 1 ? `${warnings.length} warnings` : 'Warning'}
44
- </Typography>
30
+ </Button>
45
31
  </Tooltip>
46
32
  )
47
33
  })
@@ -0,0 +1,52 @@
1
+ import React from 'react'
2
+
3
+ import SvgIcon from '@mui/material/SvgIcon'
4
+
5
+ import type { SvgIconProps } from '@mui/material/SvgIcon'
6
+
7
+ // Mouse glyphs with outward arrows on the axes a wheel zoom scales.
8
+ // @mui/icons-material ships only the plain `Mouse`, and three variants that
9
+ // differ only in their arrows have to share one body to stay apart at 24px.
10
+ // The body's inner subpath runs the opposite sweep, which punches the hole the
11
+ // wheel bar sits in.
12
+ const BODY =
13
+ 'M12 5a4 4 0 0 0-4 4v6a4 4 0 0 0 8 0V9a4 4 0 0 0-4-4zm0 2a2 2 0 0 1 2 2v6a2 2 0 0 1-4 0V9a2 2 0 0 1 2-2z'
14
+ const WHEEL = 'M11.2 8.6h1.6v3.2h-1.6z'
15
+ const LEFT = 'M.4 12 5 15V9z'
16
+ const RIGHT = 'M23.6 12 19 9v6z'
17
+ const UP = 'M12 .4 15 4H9z'
18
+ const DOWN = 'M12 23.6 9 20h6z'
19
+
20
+ function MouseZoom({
21
+ arrows,
22
+ ...rest
23
+ }: SvgIconProps & { arrows: readonly string[] }) {
24
+ return (
25
+ <SvgIcon {...rest}>
26
+ <path d={BODY} />
27
+ <path d={WHEEL} />
28
+ {arrows.map(d => (
29
+ <path key={d} d={d} />
30
+ ))}
31
+ </SvgIcon>
32
+ )
33
+ }
34
+
35
+ // the bare body, for a wheel that scrolls. @mui/icons-material's own `Mouse` is
36
+ // a solid silhouette, which would jump to a different drawing when the menu
37
+ // changes the mode.
38
+ export function MouseScroll(props: SvgIconProps) {
39
+ return <MouseZoom {...props} arrows={[]} />
40
+ }
41
+
42
+ export function MouseZoomBoth(props: SvgIconProps) {
43
+ return <MouseZoom {...props} arrows={[LEFT, RIGHT, UP, DOWN]} />
44
+ }
45
+
46
+ export function MouseZoomHorizontal(props: SvgIconProps) {
47
+ return <MouseZoom {...props} arrows={[LEFT, RIGHT]} />
48
+ }
49
+
50
+ export function MouseZoomVertical(props: SvgIconProps) {
51
+ return <MouseZoom {...props} arrows={[UP, DOWN]} />
52
+ }
@@ -32,9 +32,7 @@ const TreeSettingsMenu = observer(function ({
32
32
  type: 'subMenu' as const,
33
33
  subMenu: [
34
34
  {
35
- // the cap shows in the label rather than arriving as an
36
- // error after the click, since the click is what would
37
- // freeze the tab
35
+ // the label shows the cap before a click would freeze the tab
38
36
  label: tooManyRows
39
37
  ? `Calculate neighbor joining tree (over ${maxNeighborJoiningRows} rows, use FastTree)`
40
38
  : 'Calculate neighbor joining tree (BLOSUM62)',
@@ -26,10 +26,8 @@ function size(bytes: number) {
26
26
  : `${(bytes / 1_000_000).toFixed(1)} MB`
27
27
  }
28
28
 
29
- // The viewer holds documents its own snapshot does not carry, and until this
30
- // existed it said nothing about it: the view worked, the URL quietly lost the
31
- // data, and whoever copied the link found out from the person who opened it.
32
- // See `unshareableData` on the model.
29
+ // Lists loaded documents the snapshot, and so a shared URL, omits. See
30
+ // `unshareableData` on the model.
33
31
  const UnshareableDataWarning = observer(function ({
34
32
  model,
35
33
  }: {
@@ -1,18 +1,67 @@
1
1
  import React from 'react'
2
2
 
3
- import Mouse from '@mui/icons-material/Mouse'
3
+ import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
4
4
  import ZoomIn from '@mui/icons-material/ZoomIn'
5
5
  import ZoomOut from '@mui/icons-material/ZoomOut'
6
- import { IconButton, ToggleButton, Tooltip } from '@mui/material'
6
+ import { IconButton, Tooltip } from '@mui/material'
7
7
  import { observer } from 'mobx-react'
8
8
 
9
+ import {
10
+ MouseScroll,
11
+ MouseZoomBoth,
12
+ MouseZoomHorizontal,
13
+ MouseZoomVertical,
14
+ } from './ScrollZoomIcons.tsx'
15
+
16
+ import type { ScrollZoomAxis } from '../../constants.ts'
9
17
  import type { MsaViewModel } from '../../model.ts'
10
18
 
19
+ interface WheelMode {
20
+ label: string
21
+ // undefined is the wheel scrolling the alignment, which is the default
22
+ axis?: ScrollZoomAxis
23
+ Icon: typeof MouseScroll
24
+ helpText?: string
25
+ }
26
+
27
+ const scrollMode: WheelMode = {
28
+ label: 'Scrolls the alignment',
29
+ Icon: MouseScroll,
30
+ helpText: 'Ctrl+wheel zooms both axes at the cursor.',
31
+ }
32
+
33
+ const wheelModes: WheelMode[] = [
34
+ scrollMode,
35
+ {
36
+ label: 'Zooms both axes',
37
+ axis: 'both',
38
+ Icon: MouseZoomBoth,
39
+ helpText: 'Hold shift to pan while the wheel zooms.',
40
+ },
41
+ {
42
+ label: 'Zooms columns only',
43
+ axis: 'horizontal',
44
+ Icon: MouseZoomHorizontal,
45
+ helpText:
46
+ 'Holds the row height, so the labels and letters stay at their size while the alignment compresses.',
47
+ },
48
+ {
49
+ label: 'Zooms rows only',
50
+ axis: 'vertical',
51
+ Icon: MouseZoomVertical,
52
+ helpText:
53
+ 'Holds the column width, so the alignment stays as wide while the rows grow or shrink.',
54
+ },
55
+ ]
56
+
11
57
  const ZoomControls = observer(function ZoomControls({
12
58
  model,
13
59
  }: {
14
60
  model: MsaViewModel
15
61
  }) {
62
+ const { scrollZoom, scrollZoomAxis } = model
63
+ const activeAxis = scrollZoom ? scrollZoomAxis : undefined
64
+ const current = wheelModes.find(m => m.axis === activeAxis) ?? scrollMode
16
65
  return (
17
66
  <>
18
67
  <Tooltip title="Zoom in">
@@ -35,19 +84,30 @@ const ZoomControls = observer(function ZoomControls({
35
84
  <ZoomOut />
36
85
  </IconButton>
37
86
  </Tooltip>
38
- <ToggleButton
39
- value="scrollZoom"
40
- selected={model.scrollZoom}
41
- aria-label="Toggle scroll-to-zoom"
42
- title="Toggle scroll-to-zoom (zoom on plain mouse wheel; ctrl+wheel always zooms)"
43
- size="small"
44
- sx={{ border: 'none' }}
45
- onChange={() => {
46
- model.setScrollZoom(!model.scrollZoom)
47
- }}
87
+ <CascadingMenuButton
88
+ data-testid="scroll_zoom_menu"
89
+ tooltip={`Mouse wheel: ${current.label.toLowerCase()} (ctrl+wheel always zooms)`}
90
+ anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
91
+ transformOrigin={{ vertical: 'top', horizontal: 'left' }}
92
+ menuItems={[
93
+ { type: 'subHeader', label: 'Mouse wheel' },
94
+ ...wheelModes.map(({ label, axis, Icon, helpText }) => ({
95
+ label,
96
+ icon: Icon,
97
+ helpText,
98
+ type: 'radio' as const,
99
+ checked: current.label === label,
100
+ onClick: () => {
101
+ model.setScrollZoom(axis !== undefined)
102
+ if (axis !== undefined) {
103
+ model.setScrollZoomAxis(axis)
104
+ }
105
+ },
106
+ })),
107
+ ]}
48
108
  >
49
- <Mouse />
50
- </ToggleButton>
109
+ <current.Icon />
110
+ </CascadingMenuButton>
51
111
  </>
52
112
  )
53
113
  })
@@ -32,12 +32,9 @@ export function getAnnotationsMenu({ model }: { model: MsaViewModel }) {
32
32
  ])
33
33
  },
34
34
  },
35
- // The viewer used to submit the whole alignment to the EBI iprscan5 queue
36
- // and poll it for about fifteen minutes, capped at 140 rows and under a
37
- // hardcoded email address. `react-msaview-cli interpro` answers the same
38
- // question from InterPro's precomputed matches in seconds, and
39
- // `interproscan` covers rows InterPro has not seen. Neither belongs in a
40
- // browser tab, so this points at the page that walks through them.
35
+ // `react-msaview-cli interpro` reads InterPro's precomputed matches in
36
+ // seconds, and `interproscan` covers rows InterPro has not seen; this links
37
+ // the tutorial for both
41
38
  {
42
39
  label: 'How to get a domain file...',
43
40
  icon: MenuBook,
@@ -12,9 +12,7 @@ function toggle(label: string, checked: boolean, set: (arg: boolean) => void) {
12
12
  }
13
13
  }
14
14
 
15
- // Every track the alignment can show, with its current state. Without this the
16
- // "Close" item on a track's own dropdown is a one-way door -- there is nowhere
17
- // else in the UI to turn a track back on.
15
+ // the only place in the UI to turn a hidden track back on
18
16
  function tracksSubMenu(model: MsaViewModel): MenuItem[] {
19
17
  const shown = new Set(model.turnedOnTracks.map(t => t.model.id))
20
18
  return model.tracks.map(({ model: { id, name } }) =>
@@ -33,18 +31,17 @@ export function msaSettingsMenuItems(model: MsaViewModel): MenuItem[] {
33
31
  subMenu: tracksSubMenu(model),
34
32
  },
35
33
  { type: 'divider' as const },
36
- toggle('Show column statistics on hover', showColumnStats, arg => {
34
+ toggle('Show track values on hover', showColumnStats, arg => {
37
35
  model.setShowColumnStats(arg)
38
36
  }),
39
37
  toggle('Draw letters', drawMsaLetters, arg => {
40
38
  model.setDrawMsaLetters(arg)
41
39
  }),
42
- // the checkbox reads as the inverse of the property it sets: bgColor draws
43
- // the tile, and turning it off is what leaves the letter itself colored
44
- toggle('Color letters instead of background of tiles', !bgColor, arg => {
40
+ // inverted: bgColor colors the tile, and off colors the letter
41
+ toggle('Color letters, not cells', !bgColor, arg => {
45
42
  model.setBgColor(!arg)
46
43
  }),
47
- toggle('Enable hiding gappy columns?', hideGaps, arg => {
44
+ toggle('Hide gappy columns', hideGaps, arg => {
48
45
  model.setHideGaps(arg)
49
46
  }),
50
47
  ]
@@ -56,7 +53,9 @@ export function treeSettingsMenuItems(model: MsaViewModel): MenuItem[] {
56
53
  showBranchLen,
57
54
  labelsAlignRight,
58
55
  drawNodeBubbles,
56
+ drawNodeLabels,
59
57
  drawLabels,
58
+ showTreeOverview,
60
59
  } = model
61
60
  return [
62
61
  toggle('Show branch length', showBranchLen, arg => {
@@ -68,6 +67,12 @@ export function treeSettingsMenuItems(model: MsaViewModel): MenuItem[] {
68
67
  toggle('Draw bubbles on tree branches', drawNodeBubbles, arg => {
69
68
  model.setDrawNodeBubbles(arg)
70
69
  }),
70
+ toggle('Draw internal node labels', drawNodeLabels, arg => {
71
+ model.setDrawNodeLabels(arg)
72
+ }),
73
+ toggle('Show tree overview', showTreeOverview, arg => {
74
+ model.setShowTreeOverview(arg)
75
+ }),
71
76
  toggle('Tree labels align right', labelsAlignRight, arg => {
72
77
  model.setLabelsAlignRight(arg)
73
78
  }),
@@ -24,11 +24,9 @@ const ImportForm = observer(function ({ model }: { model: MsaViewModel }) {
24
24
  Open an MSA file (FASTA, Stockholm, Clustal, A3M or EMF format) and/or
25
25
  a tree file (Newick format).
26
26
  </Typography>
27
- <Typography color="error">
28
- Note: you can open up just an MSA or just a tree, both are not
29
- required. Some MSA files e.g. stockholm format have an embedded tree
30
- also and this is fine, and opening a separate tree file is not
31
- required.
27
+ <Typography color="text.secondary">
28
+ An MSA alone or a tree alone is enough, and a Stockholm file with an
29
+ embedded tree needs no separate tree file.
32
30
  </Typography>
33
31
  </div>
34
32
 
@@ -11,8 +11,8 @@ import type { MsaViewModel } from '../../model.ts'
11
11
  const BASE = 'https://jbrowse.org/genomes/multiple_sequence_alignments'
12
12
  const TREES = 'https://jbrowse.org/genomes/newick_trees'
13
13
 
14
- // each example either points at remote files (msa/tree/gff urls) or carries its
15
- // data inline, which is what the two bundled small ones do
14
+ // each example points at remote files (msa/tree/gff urls) or carries its data
15
+ // inline, as the two small bundled ones do
16
16
  interface Example {
17
17
  label: string
18
18
  msa?: string
@@ -16,8 +16,7 @@ export function load(
16
16
  }
17
17
  if (gffFile) {
18
18
  model.setGFFFilehandle(gffFile)
19
- // asked for by hand, so drawn -- even if the reader hid the overlay
20
- // earlier in this view
19
+ // a file opened by hand shows even if the overlay was hidden earlier
21
20
  model.setShowDomains(true)
22
21
  }
23
22
  }
@@ -15,8 +15,7 @@ const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
15
15
  const theme = useTheme()
16
16
  const { unit, s, w, polygonHeight, polygonPoints } = getMinimapLayout(model)
17
17
 
18
- // the whole alignment, sampled down to the bar: it says where the conserved
19
- // blocks and the gappy stretches are, which is what a scroll aims at
18
+ // the whole alignment, sampled down to the bar
20
19
  const barWidth = Math.round(msaCanvasWidth * highResScaleFactor)
21
20
  const barHeight = Math.round(MINIMAP_BAR_HEIGHT * highResScaleFactor)
22
21
  const ref = useCanvasAutorun({