react-msaview 9.0.0 → 9.1.1

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 (352) hide show
  1. package/README.md +19 -10
  2. package/bundle/index.js +111 -115
  3. package/bundle/index.js.map +4 -4
  4. package/dist/blosum62.d.ts +3 -0
  5. package/dist/blosum62.js +43 -0
  6. package/dist/blosum62.js.map +1 -0
  7. package/dist/colorSchemes.js +2 -3
  8. package/dist/colorSchemes.js.map +1 -1
  9. package/dist/columnCounts.d.ts +0 -1
  10. package/dist/columnCounts.js +1 -1
  11. package/dist/columnCounts.js.map +1 -1
  12. package/dist/components/Loading.d.ts +3 -2
  13. package/dist/components/Loading.js +7 -7
  14. package/dist/components/Loading.js.map +1 -1
  15. package/dist/components/MSAView.d.ts +3 -2
  16. package/dist/components/MSAView.js +7 -4
  17. package/dist/components/MSAView.js.map +1 -1
  18. package/dist/components/MSAViewer.d.ts +1941 -4
  19. package/dist/components/MSAViewer.js +144 -201
  20. package/dist/components/MSAViewer.js.map +1 -1
  21. package/dist/components/MetadataTable.d.ts +4 -1
  22. package/dist/components/MetadataTable.js +55 -16
  23. package/dist/components/MetadataTable.js.map +1 -1
  24. package/dist/components/ResizeHandles.js +3 -2
  25. package/dist/components/ResizeHandles.js.map +1 -1
  26. package/dist/components/Track.js +8 -1
  27. package/dist/components/Track.js.map +1 -1
  28. package/dist/components/controls.d.ts +11 -0
  29. package/dist/components/controls.js +49 -0
  30. package/dist/components/controls.js.map +1 -0
  31. package/dist/components/dialogs/AnnotationFileDialog.js +12 -18
  32. package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -1
  33. package/dist/components/dialogs/ExportSVGDialog.js +5 -7
  34. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  35. package/dist/components/dialogs/FeatureDialog.js +2 -2
  36. package/dist/components/dialogs/FeatureDialog.js.map +1 -1
  37. package/dist/components/{header/TreeSettingsMenu.d.ts → dialogs/GapThresholdDialog.d.ts} +3 -2
  38. package/dist/components/dialogs/GapThresholdDialog.js +15 -0
  39. package/dist/components/dialogs/GapThresholdDialog.js.map +1 -0
  40. package/dist/components/{header → dialogs}/GappynessSlider.d.ts +1 -1
  41. package/dist/components/{header → dialogs}/GappynessSlider.js +3 -10
  42. package/dist/components/dialogs/GappynessSlider.js.map +1 -0
  43. package/dist/components/{header → dialogs}/GoToBox.d.ts +4 -2
  44. package/dist/components/dialogs/GoToBox.js +48 -0
  45. package/dist/components/dialogs/GoToBox.js.map +1 -0
  46. package/dist/components/dialogs/GoToDialog.d.ts +6 -0
  47. package/dist/components/dialogs/GoToDialog.js +10 -0
  48. package/dist/components/dialogs/GoToDialog.js.map +1 -0
  49. package/dist/components/dialogs/HelpDialog.d.ts +6 -0
  50. package/dist/components/dialogs/HelpDialog.js +30 -0
  51. package/dist/components/dialogs/HelpDialog.js.map +1 -0
  52. package/dist/components/dialogs/MetadataDialog.js +11 -3
  53. package/dist/components/dialogs/MetadataDialog.js.map +1 -1
  54. package/dist/components/dialogs/goTo.d.ts +5 -0
  55. package/dist/components/{header → dialogs}/goTo.js +1 -1
  56. package/dist/components/dialogs/goTo.js.map +1 -0
  57. package/dist/components/dialogs/metadataLabels.d.ts +4 -0
  58. package/dist/components/dialogs/metadataLabels.js +52 -0
  59. package/dist/components/dialogs/metadataLabels.js.map +1 -0
  60. package/dist/components/dialogs/metadataRecord.d.ts +1 -0
  61. package/dist/components/dialogs/metadataRecord.js +38 -0
  62. package/dist/components/dialogs/metadataRecord.js.map +1 -0
  63. package/dist/components/header/Header.d.ts +6 -2
  64. package/dist/components/header/Header.js +30 -34
  65. package/dist/components/header/Header.js.map +1 -1
  66. package/dist/components/header/HiddenColumnsChip.d.ts +6 -0
  67. package/dist/components/header/HiddenColumnsChip.js +15 -0
  68. package/dist/components/header/HiddenColumnsChip.js.map +1 -0
  69. package/dist/components/header/{FileMenu.d.ts → MenuBar.d.ts} +3 -3
  70. package/dist/components/header/MenuBar.js +33 -0
  71. package/dist/components/header/MenuBar.js.map +1 -0
  72. package/dist/components/header/ScrollZoomCheckbox.d.ts +7 -0
  73. package/dist/components/header/ScrollZoomCheckbox.js +19 -0
  74. package/dist/components/header/ScrollZoomCheckbox.js.map +1 -0
  75. package/dist/components/header/ZoomControls.js +12 -48
  76. package/dist/components/header/ZoomControls.js.map +1 -1
  77. package/dist/components/header/colorSchemeMenuItems.d.ts +4 -0
  78. package/dist/components/header/colorSchemeMenuItems.js +106 -0
  79. package/dist/components/header/colorSchemeMenuItems.js.map +1 -0
  80. package/dist/components/header/getAnnotationsMenu.d.ts +3 -30
  81. package/dist/components/header/getAnnotationsMenu.js +48 -54
  82. package/dist/components/header/getAnnotationsMenu.js.map +1 -1
  83. package/dist/components/header/menuBarItems.d.ts +11 -0
  84. package/dist/components/header/menuBarItems.js +277 -0
  85. package/dist/components/header/menuBarItems.js.map +1 -0
  86. package/dist/components/import/ImportForm.js +12 -6
  87. package/dist/components/import/ImportForm.js.map +1 -1
  88. package/dist/components/import/data/seq2.d.ts +0 -1
  89. package/dist/components/import/data/seq2.js +0 -17
  90. package/dist/components/import/data/seq2.js.map +1 -1
  91. package/dist/components/minimap/Minimap.js +7 -3
  92. package/dist/components/minimap/Minimap.js.map +1 -1
  93. package/dist/components/minimap/MinimapSVG.js +2 -1
  94. package/dist/components/minimap/MinimapSVG.js.map +1 -1
  95. package/dist/components/minimap/minimapLayout.d.ts +12 -0
  96. package/dist/components/minimap/minimapLayout.js +20 -0
  97. package/dist/components/minimap/minimapLayout.js.map +1 -1
  98. package/dist/components/msa/MSACanvas.js +28 -10
  99. package/dist/components/msa/MSACanvas.js.map +1 -1
  100. package/dist/components/msa/MSACanvasBlock.js +17 -16
  101. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  102. package/dist/components/msa/MSAMouseoverCanvas.js +2 -2
  103. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  104. package/dist/components/msa/WheelZoomHint.d.ts +7 -0
  105. package/dist/components/msa/WheelZoomHint.js +38 -0
  106. package/dist/components/msa/WheelZoomHint.js.map +1 -0
  107. package/dist/components/msa/drawFeatureSpans.d.ts +50 -11
  108. package/dist/components/msa/drawFeatureSpans.js +99 -56
  109. package/dist/components/msa/drawFeatureSpans.js.map +1 -1
  110. package/dist/components/msa/msaKeys.js +3 -0
  111. package/dist/components/msa/msaKeys.js.map +1 -1
  112. package/dist/components/msa/msaRaster.d.ts +14 -2
  113. package/dist/components/msa/msaRaster.js +20 -10
  114. package/dist/components/msa/msaRaster.js.map +1 -1
  115. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +9 -0
  116. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +39 -8
  117. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  118. package/dist/components/msa/renderHighlights.d.ts +2 -5
  119. package/dist/components/msa/renderHighlights.js +5 -6
  120. package/dist/components/msa/renderHighlights.js.map +1 -1
  121. package/dist/components/msa/renderMSABlock.d.ts +6 -1
  122. package/dist/components/msa/renderMSABlock.js +44 -17
  123. package/dist/components/msa/renderMSABlock.js.map +1 -1
  124. package/dist/components/msa/renderMSAMouseover.js +2 -1
  125. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  126. package/dist/components/msa/tileColor.js +7 -0
  127. package/dist/components/msa/tileColor.js.map +1 -1
  128. package/dist/components/renderCtx.d.ts +1 -1
  129. package/dist/components/rowpanels/RowPanelBlock.js +2 -2
  130. package/dist/components/rowpanels/RowPanelBlock.js.map +1 -1
  131. package/dist/components/rowpanels/renderFeaturePanel.d.ts +5 -1
  132. package/dist/components/rowpanels/renderFeaturePanel.js +12 -5
  133. package/dist/components/rowpanels/renderFeaturePanel.js.map +1 -1
  134. package/dist/components/settings/MenuItemsForm.d.ts +10 -0
  135. package/dist/components/settings/MenuItemsForm.js +80 -0
  136. package/dist/components/settings/MenuItemsForm.js.map +1 -0
  137. package/dist/components/settings/SettingsPanel.d.ts +12 -0
  138. package/dist/components/settings/SettingsPanel.js +92 -0
  139. package/dist/components/settings/SettingsPanel.js.map +1 -0
  140. package/dist/components/{header/ZoomMenu.d.ts → settings/TrackList.d.ts} +2 -2
  141. package/dist/components/settings/TrackList.js +55 -0
  142. package/dist/components/settings/TrackList.js.map +1 -0
  143. package/dist/components/tracks/TrackBlocks.js +2 -2
  144. package/dist/components/tracks/TrackBlocks.js.map +1 -1
  145. package/dist/components/tracks/drawTracks.d.ts +1 -53
  146. package/dist/components/tracks/drawTracks.js +5 -5
  147. package/dist/components/tracks/drawTracks.js.map +1 -1
  148. package/dist/components/tree/CladeLabels.d.ts +1 -1
  149. package/dist/components/tree/CladeLabels.js +22 -34
  150. package/dist/components/tree/CladeLabels.js.map +1 -1
  151. package/dist/components/tree/TreeCanvasBlock.js +2 -2
  152. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  153. package/dist/components/tree/TreeMenu.js +4 -6
  154. package/dist/components/tree/TreeMenu.js.map +1 -1
  155. package/dist/components/tree/TreeOverview.js +2 -2
  156. package/dist/components/tree/TreeOverview.js.map +1 -1
  157. package/dist/components/tree/cladeBrackets.d.ts +17 -10
  158. package/dist/components/tree/cladeBrackets.js +33 -3
  159. package/dist/components/tree/cladeBrackets.js.map +1 -1
  160. package/dist/components/tree/renderTreeCanvas.js +2 -8
  161. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  162. package/dist/components/tree/renderTreeOverview.js +4 -11
  163. package/dist/components/tree/renderTreeOverview.js.map +1 -1
  164. package/dist/constants.d.ts +4 -1
  165. package/dist/constants.js +7 -1
  166. package/dist/constants.js.map +1 -1
  167. package/dist/darkReader.d.ts +7 -0
  168. package/dist/darkReader.js +42 -0
  169. package/dist/darkReader.js.map +1 -0
  170. package/dist/element.js +25 -53
  171. package/dist/element.js.map +1 -1
  172. package/dist/exportLayout.d.ts +39 -0
  173. package/dist/exportLayout.js +78 -0
  174. package/dist/exportLayout.js.map +1 -0
  175. package/dist/featurePanels.d.ts +37 -0
  176. package/dist/featurePanels.js +187 -0
  177. package/dist/featurePanels.js.map +1 -0
  178. package/dist/filehandleLoader.d.ts +41 -0
  179. package/dist/filehandleLoader.js +99 -0
  180. package/dist/filehandleLoader.js.map +1 -0
  181. package/dist/headlessRenderEnv.d.ts +12 -39
  182. package/dist/headlessRenderEnv.js +18 -12
  183. package/dist/headlessRenderEnv.js.map +1 -1
  184. package/dist/hierarchy.d.ts +5 -8
  185. package/dist/hierarchy.js +5 -79
  186. package/dist/hierarchy.js.map +1 -1
  187. package/dist/index.d.ts +6 -1
  188. package/dist/index.js +6 -1
  189. package/dist/index.js.map +1 -1
  190. package/dist/measureTextCanvas.d.ts +7 -0
  191. package/dist/measureTextCanvas.js +8 -6
  192. package/dist/measureTextCanvas.js.map +1 -1
  193. package/dist/model/treeModel.d.ts +6 -2
  194. package/dist/model/treeModel.js +8 -4
  195. package/dist/model/treeModel.js.map +1 -1
  196. package/dist/model.d.ts +180 -76
  197. package/dist/model.js +358 -618
  198. package/dist/model.js.map +1 -1
  199. package/dist/neighborJoining.js +1 -40
  200. package/dist/neighborJoining.js.map +1 -1
  201. package/dist/renderToSvg.d.ts +2 -7
  202. package/dist/renderToSvg.js +33 -133
  203. package/dist/renderToSvg.js.map +1 -1
  204. package/dist/rerootTree.d.ts +1 -0
  205. package/dist/rerootTree.js +7 -6
  206. package/dist/rerootTree.js.map +1 -1
  207. package/dist/schemeResidueColor.d.ts +12 -0
  208. package/dist/schemeResidueColor.js +33 -0
  209. package/dist/schemeResidueColor.js.map +1 -0
  210. package/dist/similarityColors.d.ts +11 -0
  211. package/dist/similarityColors.js +90 -0
  212. package/dist/similarityColors.js.map +1 -0
  213. package/dist/svgTestUtil.d.ts +74 -32
  214. package/dist/treeDisplay.d.ts +37 -0
  215. package/dist/treeDisplay.js +209 -0
  216. package/dist/treeDisplay.js.map +1 -0
  217. package/dist/types.d.ts +6 -3
  218. package/dist/useWheelScroll.d.ts +3 -1
  219. package/dist/useWheelScroll.js +36 -17
  220. package/dist/useWheelScroll.js.map +1 -1
  221. package/dist/util.d.ts +2 -0
  222. package/dist/util.js +2 -0
  223. package/dist/util.js.map +1 -1
  224. package/dist/version.d.ts +1 -1
  225. package/dist/version.js +1 -1
  226. package/dist/viewerSnapshot.d.ts +169 -0
  227. package/dist/viewerSnapshot.js +100 -0
  228. package/dist/viewerSnapshot.js.map +1 -0
  229. package/dist/wheelZoom.d.ts +8 -3
  230. package/dist/wheelZoom.js +44 -32
  231. package/dist/wheelZoom.js.map +1 -1
  232. package/dist/zoomSnapshot.d.ts +29 -0
  233. package/dist/zoomSnapshot.js +47 -0
  234. package/dist/zoomSnapshot.js.map +1 -0
  235. package/package.json +11 -11
  236. package/src/blosum62.ts +45 -0
  237. package/src/colorSchemes.ts +2 -4
  238. package/src/columnCounts.ts +1 -1
  239. package/src/components/Loading.tsx +25 -14
  240. package/src/components/MSAView.tsx +22 -5
  241. package/src/components/MSAViewer.tsx +275 -251
  242. package/src/components/MetadataTable.tsx +83 -26
  243. package/src/components/ResizeHandles.tsx +9 -2
  244. package/src/components/Track.tsx +15 -1
  245. package/src/components/controls.ts +62 -0
  246. package/src/components/dialogs/AnnotationFileDialog.tsx +16 -21
  247. package/src/components/dialogs/ExportSVGDialog.tsx +8 -19
  248. package/src/components/dialogs/FeatureDialog.tsx +2 -5
  249. package/src/components/dialogs/GapThresholdDialog.tsx +36 -0
  250. package/src/components/{header → dialogs}/GappynessSlider.tsx +3 -10
  251. package/src/components/{header → dialogs}/GoToBox.tsx +36 -10
  252. package/src/components/dialogs/GoToDialog.tsx +30 -0
  253. package/src/components/dialogs/HelpDialog.tsx +79 -0
  254. package/src/components/dialogs/MetadataDialog.tsx +32 -4
  255. package/src/components/{header → dialogs}/goTo.ts +1 -1
  256. package/src/components/dialogs/metadataLabels.ts +54 -0
  257. package/src/components/dialogs/metadataRecord.tsx +61 -0
  258. package/src/components/header/Header.tsx +75 -44
  259. package/src/components/header/HiddenColumnsChip.tsx +39 -0
  260. package/src/components/header/MenuBar.tsx +64 -0
  261. package/src/components/header/ScrollZoomCheckbox.tsx +46 -0
  262. package/src/components/header/ZoomControls.tsx +23 -74
  263. package/src/components/header/colorSchemeMenuItems.ts +121 -0
  264. package/src/components/header/getAnnotationsMenu.ts +52 -56
  265. package/src/components/header/menuBarItems.ts +357 -0
  266. package/src/components/import/ImportForm.tsx +19 -7
  267. package/src/components/import/data/seq2.ts +0 -18
  268. package/src/components/minimap/Minimap.tsx +11 -3
  269. package/src/components/minimap/MinimapSVG.tsx +17 -1
  270. package/src/components/minimap/minimapLayout.ts +27 -0
  271. package/src/components/msa/MSACanvas.tsx +24 -4
  272. package/src/components/msa/MSACanvasBlock.tsx +20 -17
  273. package/src/components/msa/MSAMouseoverCanvas.tsx +2 -2
  274. package/src/components/msa/WheelZoomHint.tsx +56 -0
  275. package/src/components/msa/drawFeatureSpans.ts +160 -79
  276. package/src/components/msa/msaKeys.ts +3 -0
  277. package/src/components/msa/msaRaster.ts +26 -10
  278. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +62 -24
  279. package/src/components/msa/renderHighlights.ts +5 -6
  280. package/src/components/msa/renderMSABlock.ts +51 -15
  281. package/src/components/msa/renderMSAMouseover.ts +5 -1
  282. package/src/components/msa/tileColor.ts +7 -0
  283. package/src/components/renderCtx.ts +0 -1
  284. package/src/components/rowpanels/RowPanelBlock.tsx +2 -2
  285. package/src/components/rowpanels/renderFeaturePanel.ts +26 -7
  286. package/src/components/settings/MenuItemsForm.tsx +225 -0
  287. package/src/components/settings/SettingsPanel.tsx +156 -0
  288. package/src/components/settings/TrackList.tsx +119 -0
  289. package/src/components/tracks/TrackBlocks.tsx +2 -2
  290. package/src/components/tracks/drawTracks.ts +5 -5
  291. package/src/components/tree/CladeLabels.tsx +30 -54
  292. package/src/components/tree/TreeCanvasBlock.tsx +2 -2
  293. package/src/components/tree/TreeMenu.tsx +4 -6
  294. package/src/components/tree/TreeOverview.tsx +2 -2
  295. package/src/components/tree/cladeBrackets.ts +50 -3
  296. package/src/components/tree/renderTreeCanvas.ts +2 -13
  297. package/src/components/tree/renderTreeOverview.ts +7 -14
  298. package/src/constants.ts +9 -1
  299. package/src/darkReader.ts +57 -0
  300. package/src/element.ts +37 -64
  301. package/src/exportLayout.ts +134 -0
  302. package/src/featurePanels.ts +269 -0
  303. package/src/filehandleLoader.ts +136 -0
  304. package/src/headlessRenderEnv.ts +24 -11
  305. package/src/hierarchy.ts +5 -88
  306. package/src/index.ts +9 -5
  307. package/src/measureTextCanvas.ts +8 -6
  308. package/src/model/treeModel.ts +9 -3
  309. package/src/model.ts +452 -807
  310. package/src/neighborJoining.ts +1 -42
  311. package/src/renderToSvg.tsx +56 -207
  312. package/src/rerootTree.ts +7 -6
  313. package/src/schemeResidueColor.ts +37 -0
  314. package/src/similarityColors.ts +112 -0
  315. package/src/treeDisplay.ts +278 -0
  316. package/src/types.ts +6 -4
  317. package/src/useWheelScroll.ts +43 -22
  318. package/src/util.ts +3 -0
  319. package/src/version.ts +1 -1
  320. package/src/viewerSnapshot.ts +147 -0
  321. package/src/wheelZoom.ts +55 -33
  322. package/src/zoomSnapshot.ts +80 -0
  323. package/dist/components/header/ColorSchemeMenu.d.ts +0 -12
  324. package/dist/components/header/ColorSchemeMenu.js +0 -37
  325. package/dist/components/header/ColorSchemeMenu.js.map +0 -1
  326. package/dist/components/header/FileMenu.js +0 -66
  327. package/dist/components/header/FileMenu.js.map +0 -1
  328. package/dist/components/header/GappynessSlider.js.map +0 -1
  329. package/dist/components/header/GoToBox.js +0 -31
  330. package/dist/components/header/GoToBox.js.map +0 -1
  331. package/dist/components/header/MSASettingsMenu.d.ts +0 -6
  332. package/dist/components/header/MSASettingsMenu.js +0 -11
  333. package/dist/components/header/MSASettingsMenu.js.map +0 -1
  334. package/dist/components/header/ScrollZoomIcons.d.ts +0 -6
  335. package/dist/components/header/ScrollZoomIcons.js +0 -35
  336. package/dist/components/header/ScrollZoomIcons.js.map +0 -1
  337. package/dist/components/header/TreeSettingsMenu.js +0 -42
  338. package/dist/components/header/TreeSettingsMenu.js.map +0 -1
  339. package/dist/components/header/ZoomMenu.js +0 -37
  340. package/dist/components/header/ZoomMenu.js.map +0 -1
  341. package/dist/components/header/goTo.d.ts +0 -20
  342. package/dist/components/header/goTo.js.map +0 -1
  343. package/dist/components/header/settingsMenuItems.d.ts +0 -4
  344. package/dist/components/header/settingsMenuItems.js +0 -127
  345. package/dist/components/header/settingsMenuItems.js.map +0 -1
  346. package/src/components/header/ColorSchemeMenu.tsx +0 -56
  347. package/src/components/header/FileMenu.tsx +0 -81
  348. package/src/components/header/MSASettingsMenu.tsx +0 -26
  349. package/src/components/header/ScrollZoomIcons.tsx +0 -52
  350. package/src/components/header/TreeSettingsMenu.tsx +0 -60
  351. package/src/components/header/ZoomMenu.tsx +0 -48
  352. package/src/components/header/settingsMenuItems.ts +0 -157
@@ -6,7 +6,7 @@ import type { Theme } from '@mui/material'
6
6
  // One raster tile holds this many cells on a side. A tile costs ~10ms to build
7
7
  // and ~1MB to hold, and is then drawn at any zoom for ~1ms, so the cache only
8
8
  // has to be large enough to cover a screen without thrashing.
9
- export const rasterTileSize = 512
9
+ const rasterTileSize = 512
10
10
  const maxCachedTiles = 64
11
11
  const maxThumbnailColumns = 2000
12
12
  const maxColorCacheEntries = 4096
@@ -242,17 +242,30 @@ function usableRasterCtx(ctx: unknown): ctx is RasterCtx {
242
242
  )
243
243
  }
244
244
 
245
- function makeRasterCanvas(width: number, height: number) {
245
+ /**
246
+ * A canvas off the page, an OffscreenCanvas where there is one, with its 2d
247
+ * context, or undefined where the context fails `usable` (jsdom has none).
248
+ */
249
+ export function makeOffscreenCanvas<Ctx>(
250
+ width: number,
251
+ height: number,
252
+ usable: (ctx: unknown) => ctx is Ctx,
253
+ settings?: CanvasRenderingContext2DSettings,
254
+ ) {
246
255
  const canvas =
247
256
  typeof OffscreenCanvas !== 'undefined'
248
257
  ? new OffscreenCanvas(width, height)
249
258
  : typeof document !== 'undefined'
250
259
  ? Object.assign(document.createElement('canvas'), { width, height })
251
260
  : undefined
252
- const ctx = canvas?.getContext('2d', { willReadFrequently: true })
253
- return usableRasterCtx(ctx)
254
- ? { canvas: canvas as RasterCanvas, ctx }
255
- : undefined
261
+ const ctx = canvas?.getContext('2d', settings)
262
+ return usable(ctx) ? { canvas: canvas as RasterCanvas, ctx } : undefined
263
+ }
264
+
265
+ function makeRasterCanvas(width: number, height: number) {
266
+ return makeOffscreenCanvas(width, height, usableRasterCtx, {
267
+ willReadFrequently: true,
268
+ })
256
269
  }
257
270
 
258
271
  function paint(
@@ -272,11 +285,14 @@ function paint(
272
285
 
273
286
  let supported: boolean | undefined
274
287
 
275
- // jsdom, and any browser without a 2d context, has no raster to draw; the
276
- // per-cell painter in renderMSABlock stays the fallback
277
- export function rasterSupported() {
288
+ /**
289
+ * Whether the alignment background comes from the raster: true while the
290
+ * residue scheme fills the cells, with a 2d context that reads back, which
291
+ * jsdom lacks. renderMSABlock paints each cell otherwise.
292
+ */
293
+ export function rasterApplies(model: Pick<MsaViewModel, 'cellFill'>) {
278
294
  supported ??= !!makeRasterCanvas(1, 1)
279
- return supported
295
+ return model.cellFill === 'residue' && supported
280
296
  }
281
297
 
282
298
  interface RasterCache {
@@ -3,9 +3,11 @@ import { contrastTextFn } from '../../util.ts'
3
3
  import { getVisibleLeaves } from '../getVisibleLeaves.ts'
4
4
  import { drawFeatureSpans, spanRows } from './drawFeatureSpans.ts'
5
5
 
6
+ import type { HierarchyNode } from '../../hierarchy.ts'
6
7
  import type { MsaViewModel } from '../../model.ts'
7
- import type { DomainBand } from '../../types.ts'
8
+ import type { DomainBand, NodeWithIdsAndLength } from '../../types.ts'
8
9
  import type { RenderCtx } from '../renderCtx.ts'
10
+ import type { SpanSource } from './drawFeatureSpans.ts'
9
11
  import type { Theme } from '@mui/material'
10
12
 
11
13
  export function renderBoxFeatureCanvasBlock({
@@ -27,11 +29,64 @@ export function renderBoxFeatureCanvasBlock({
27
29
  blockSizeXOverride?: number
28
30
  blockSizeYOverride?: number
29
31
  }) {
32
+ const { blockSize, rowHeight, highResScaleFactor, actuallyShowDomains } =
33
+ model
34
+ if (!actuallyShowDomains) {
35
+ return
36
+ }
37
+ const k = highResScaleFactorOverride ?? highResScaleFactor
38
+ const bx = blockSizeXOverride ?? blockSize
39
+ const by = blockSizeYOverride ?? blockSize
40
+ ctx.resetTransform()
41
+ ctx.scale(k, k)
42
+ ctx.translate(-offsetX, rowHeight / 2 - offsetY)
43
+
44
+ const source = domainOverlaySource(
45
+ model,
46
+ getVisibleLeaves({ model, offsetY, blockSizeY: by }),
47
+ )
48
+ const contrastText = contrastTextFn(theme)
49
+ if (model.cellFill === 'residue' && model.domainUnderline) {
50
+ // over residue colors a bar in a categorical color blends into the cells
51
+ // beside it, so a strip of the page background parts it from them
52
+ const { height } = source.layout
53
+ const halo = theme.palette.background.default
54
+ drawFeatureSpans<DomainBand>({
55
+ ctx,
56
+ ...source,
57
+ layout: { ...source.layout, height: n => height(n) + barHalo },
58
+ colors: new Map(
59
+ [...source.colors.keys()].map(a => [a, { fill: halo, stroke: halo }]),
60
+ ),
61
+ labelOf: undefined,
62
+ labelDrawn: undefined,
63
+ contrastText,
64
+ xMin: offsetX,
65
+ xMax: offsetX + bx,
66
+ })
67
+ }
68
+ drawFeatureSpans<DomainBand>({
69
+ ctx,
70
+ ...source,
71
+ contrastText,
72
+ xMin: offsetX,
73
+ xMax: offsetX + bx,
74
+ })
75
+ }
76
+
77
+ const barHalo = 1.5
78
+
79
+ /**
80
+ * The domain overlay's spans over `leaves`, in alignment pixels: filled rows,
81
+ * an underline bar, or thin sub-rows, as `domainUnderline` and
82
+ * `subFeatureRows` decide.
83
+ */
84
+ export function domainOverlaySource(
85
+ model: MsaViewModel,
86
+ leaves: HierarchyNode<NodeWithIdsAndLength>[],
87
+ ): SpanSource<DomainBand> {
30
88
  const {
31
- blockSize,
32
89
  rowHeight,
33
- highResScaleFactor,
34
- actuallyShowDomains,
35
90
  subFeatureRows,
36
91
  colWidth,
37
92
  featureColors,
@@ -41,16 +96,6 @@ export function renderBoxFeatureCanvasBlock({
41
96
  domainUnderline,
42
97
  domainBands,
43
98
  } = model
44
- if (!actuallyShowDomains) {
45
- return
46
- }
47
- const k = highResScaleFactorOverride ?? highResScaleFactor
48
- const bx = blockSizeXOverride ?? blockSize
49
- const by = blockSizeYOverride ?? blockSize
50
- ctx.resetTransform()
51
- ctx.scale(k, k)
52
- ctx.translate(-offsetX, rowHeight / 2 - offsetY)
53
-
54
99
  // the plain and underline modes give every band the same height; a sub-row
55
100
  // band is thinner, and how thin depends on how many lanes its row needs
56
101
  const barHeight = domainUnderline
@@ -67,12 +112,8 @@ export function renderBoxFeatureCanvasBlock({
67
112
  // carrying the gene model are often not the first ones in the alignment
68
113
  const labelled = drawSegmentLabels ? new Set<string>() : undefined
69
114
 
70
- drawFeatureSpans<DomainBand>({
71
- ctx,
72
- rows: spanRows(
73
- getVisibleLeaves({ model, offsetY, blockSizeY: by }),
74
- domainBands,
75
- ),
115
+ return {
116
+ rows: spanRows(leaves, domainBands),
76
117
  layout: {
77
118
  // sub-rows are thin, but a row whose lanes would spill onto the row below
78
119
  // shares out the row height between them instead
@@ -98,8 +139,5 @@ export function renderBoxFeatureCanvasBlock({
98
139
  ? segmentLabels.get(band.annotation.accession)
99
140
  : undefined),
100
141
  labelDrawn: band => labelled?.add(band.annotation.accession),
101
- contrastText: contrastTextFn(theme),
102
- xMin: offsetX,
103
- xMax: offsetX + bx,
104
- })
142
+ }
105
143
  }
@@ -11,11 +11,11 @@ import type { Theme } from '@mui/material'
11
11
 
12
12
  // a fill plus a solid border; the hover wash alone is invisible over clustalx
13
13
  // coloring
14
- export const highlightFill = 'rgba(255,140,0,0.28)'
15
- export const highlightBorder = 'rgba(210,90,0,0.95)'
14
+ const highlightFill = 'rgba(255,140,0,0.28)'
15
+ const highlightBorder = 'rgba(210,90,0,0.95)'
16
16
  export const highlightRowFill = 'rgba(255,140,0,0.18)'
17
17
 
18
- export const labelFontSize = 11
18
+ const labelFontSize = 11
19
19
  const labelPad = 3
20
20
  // the label box above a highlight band; tree blocks also check rows this far
21
21
  // outside themselves
@@ -215,8 +215,8 @@ export function renderSelection({
215
215
 
216
216
  /**
217
217
  * The overlay parts that come from the snapshot: the reference row's tint, a
218
- * bordered band per run of highlighted columns, the `highlights` layer and the
219
- * selected block. The live overlay draws these under its hover and click
218
+ * bordered band per run of highlighted columns and the `highlights` layer. The
219
+ * live overlay draws these under the selected block and its hover and click
220
220
  * bands; the SVG export draws only these.
221
221
  */
222
222
  export function renderPersistentHighlights({
@@ -255,5 +255,4 @@ export function renderPersistentHighlights({
255
255
  }
256
256
 
257
257
  renderHighlights({ ctx, model, theme, offsetX, offsetY, width, height })
258
- renderSelection({ ctx, model, offsetX, offsetY, height })
259
258
  }
@@ -1,7 +1,9 @@
1
+ import { zoomFrameMaxLetters } from '../../constants.ts'
1
2
  import { setFontSize } from '../../setFontSize.ts'
2
3
  import { adjustColorForContrast, contrastTextFn } from '../../util.ts'
3
4
  import { getVisibleLeaves } from '../getVisibleLeaves.ts'
4
5
  import { domainBandCursor } from './domainBandCursor.ts'
6
+ import { renderBoxFeatureCanvasBlock } from './renderBoxFeatureCanvasBlock.ts'
5
7
  import { tileColorFn } from './tileColor.ts'
6
8
  import { visibleColRange } from './visibleColRange.ts'
7
9
 
@@ -21,6 +23,7 @@ export function renderMSABlock({
21
23
  blockSizeXOverride,
22
24
  blockSizeYOverride,
23
25
  rasterTiles,
26
+ domains,
24
27
  }: {
25
28
  offsetX: number
26
29
  offsetY: number
@@ -31,6 +34,11 @@ export function renderMSABlock({
31
34
  blockSizeXOverride?: number
32
35
  blockSizeYOverride?: number
33
36
  rasterTiles?: boolean
37
+ /**
38
+ * draw the domain overlay too, over the cell colors and under the letters,
39
+ * which is the one order every cell fill reads right in
40
+ */
41
+ domains?: boolean
34
42
  }) {
35
43
  const {
36
44
  colWidth,
@@ -38,18 +46,21 @@ export function renderMSABlock({
38
46
  rowHeight,
39
47
  fontSize,
40
48
  highResScaleFactor,
41
- actuallyShowDomains,
49
+ cellFill,
42
50
  bgColor,
43
51
  } = model
44
52
  const k = highResScaleFactorOverride ?? highResScaleFactor
45
53
  const bx = blockSizeXOverride ?? blockSize
46
54
  const by = blockSizeYOverride ?? blockSize
47
- ctx.resetTransform()
48
- ctx.scale(k, k)
49
- ctx.translate(-offsetX, rowHeight / 2 - offsetY)
50
- ctx.textAlign = 'center'
51
- ctx.textBaseline = 'alphabetic'
52
- setFontSize(ctx, fontSize, !bgColor)
55
+ const setup = () => {
56
+ ctx.resetTransform()
57
+ ctx.scale(k, k)
58
+ ctx.translate(-offsetX, rowHeight / 2 - offsetY)
59
+ ctx.textAlign = 'center'
60
+ ctx.textBaseline = 'alphabetic'
61
+ setFontSize(ctx, fontSize, !bgColor)
62
+ }
63
+ setup()
53
64
 
54
65
  const { xStart, xEnd } = visibleColRange({
55
66
  offsetX,
@@ -62,7 +73,7 @@ export function renderMSABlock({
62
73
  ? columns.get(relativeTo)?.slice(xStart, xEnd)
63
74
  : null
64
75
 
65
- drawTilesAndText({
76
+ const cells = {
66
77
  model,
67
78
  ctx,
68
79
  theme,
@@ -70,13 +81,34 @@ export function renderMSABlock({
70
81
  xEnd,
71
82
  visibleLeaves,
72
83
  referenceSeq,
73
- // when domains are shown the background tiles come from
84
+ // when the domains fill the cells the background comes from
74
85
  // renderBoxFeatureCanvasBlock, so only the letters are drawn here
75
- drawTiles: !actuallyShowDomains,
86
+ drawTiles: cellFill !== 'domain',
76
87
  // ...and when the caller has already laid the raster down, the tiles are
77
88
  // there but nothing here has to paint them
78
89
  rasterTiles,
79
- })
90
+ letters:
91
+ model.showMsaLetters &&
92
+ (!model.wheelZooming ||
93
+ (bx * by) / (colWidth * rowHeight) <= zoomFrameMaxLetters),
94
+ }
95
+ if (domains) {
96
+ drawTilesAndText({ ...cells, pass: 'tiles' })
97
+ renderBoxFeatureCanvasBlock({
98
+ model,
99
+ theme,
100
+ ctx,
101
+ offsetX,
102
+ offsetY,
103
+ highResScaleFactorOverride,
104
+ blockSizeXOverride,
105
+ blockSizeYOverride,
106
+ })
107
+ setup()
108
+ drawTilesAndText({ ...cells, pass: 'letters' })
109
+ } else {
110
+ drawTilesAndText({ ...cells, pass: 'both' })
111
+ }
80
112
  drawInsertionIndicators({
81
113
  model,
82
114
  ctx,
@@ -97,6 +129,8 @@ function drawTilesAndText({
97
129
  referenceSeq,
98
130
  drawTiles,
99
131
  rasterTiles,
132
+ letters: lettersOn,
133
+ pass,
100
134
  }: {
101
135
  model: MsaViewModel
102
136
  theme: Theme
@@ -107,6 +141,8 @@ function drawTilesAndText({
107
141
  referenceSeq: string | null | undefined
108
142
  drawTiles: boolean
109
143
  rasterTiles?: boolean
144
+ letters: boolean
145
+ pass: 'tiles' | 'letters' | 'both'
110
146
  }) {
111
147
  const {
112
148
  bgColor,
@@ -115,7 +151,6 @@ function drawTilesAndText({
115
151
  rowHeight,
116
152
  fontSize,
117
153
  relativeTo,
118
- showMsaLetters,
119
154
  subFeatureRows,
120
155
  domainUnderline,
121
156
  domainBandsByStart,
@@ -123,8 +158,9 @@ function drawTilesAndText({
123
158
  } = model
124
159
 
125
160
  const tiles = drawTiles && bgColor
126
- const paintTiles = tiles && !rasterTiles
127
- if (paintTiles || showMsaLetters) {
161
+ const paintTiles = tiles && !rasterTiles && pass !== 'letters'
162
+ const letters = lettersOn && pass !== 'tiles'
163
+ if (paintTiles || letters) {
128
164
  const tileColor = tileColorFn(model)
129
165
  // Domain fills come from a categorical palette with no fixed lightness, and
130
166
  // a dynamic scheme colors a cell from its column, so a readable letter color
@@ -169,7 +205,7 @@ function drawTilesAndText({
169
205
  ctx.fillRect(x, tileY, colWidth, rowHeight)
170
206
  }
171
207
 
172
- if (showMsaLetters) {
208
+ if (letters) {
173
209
  const covering = bandAt(col)
174
210
  ctx.fillStyle = covering
175
211
  ? // on top of a domain box: contrast against the box fill
@@ -1,5 +1,8 @@
1
1
  import { clickColor, hoverColor, multiRowHoverColor } from '../overlayColors.ts'
2
- import { renderPersistentHighlights } from './renderHighlights.ts'
2
+ import {
3
+ renderPersistentHighlights,
4
+ renderSelection,
5
+ } from './renderHighlights.ts'
3
6
 
4
7
  import type { MsaViewModel } from '../../model.ts'
5
8
  import type { Theme } from '@mui/material'
@@ -49,6 +52,7 @@ export function renderMouseover({
49
52
  width,
50
53
  height,
51
54
  })
55
+ renderSelection({ ctx, model, offsetX: -scrollX, offsetY: -scrollY, height })
52
56
 
53
57
  // every tip under a hovered tree node stays lit
54
58
  ctx.fillStyle = multiRowHoverColor
@@ -9,6 +9,10 @@ export function tileColorFn(model: MsaViewModel) {
9
9
  const { colClustalX } = model
10
10
  return (col: number, letter: string) => colClustalX[col]![letter]
11
11
  }
12
+ if (dynamicColorSchemeName === 'blosum62_dynamic') {
13
+ const { colSimilarity } = model
14
+ return (col: number, letter: string) => colSimilarity[col]![letter]
15
+ }
12
16
  if (dynamicColorSchemeName === 'percent_identity_dynamic') {
13
17
  const { colConsensus } = model
14
18
  return (col: number, letter: string) => {
@@ -28,6 +32,9 @@ export function tileColorTable(model: MsaViewModel) {
28
32
  if (dynamicColorSchemeName === 'clustalx_protein_dynamic') {
29
33
  return model.colClustalX
30
34
  }
35
+ if (dynamicColorSchemeName === 'blosum62_dynamic') {
36
+ return model.colSimilarity
37
+ }
31
38
  if (dynamicColorSchemeName === 'percent_identity_dynamic') {
32
39
  return model.colConsensus
33
40
  }
@@ -8,7 +8,6 @@ export type RenderCtx = Pick<
8
8
  CanvasRenderingContext2D,
9
9
  | 'arc'
10
10
  | 'beginPath'
11
- | 'clearRect'
12
11
  | 'closePath'
13
12
  | 'fill'
14
13
  | 'fillRect'
@@ -1,9 +1,9 @@
1
1
  import React from 'react'
2
2
 
3
3
  import BaseTooltip from '@jbrowse/core/ui/BaseTooltip'
4
- import { useTheme } from '@mui/material'
5
4
  import { observer } from 'mobx-react'
6
5
 
6
+ import { useCanvasTheme } from '../../darkReader.ts'
7
7
  import { featureField, featureName } from '../../featureFields.ts'
8
8
  import { useCanvasAutorun } from '../../useCanvasAutorun.ts'
9
9
  import { useHoverAnchor } from '../useHoverAnchor.ts'
@@ -64,7 +64,7 @@ const RowPanelBlock = observer(function ({
64
64
  name: string
65
65
  lines: string[]
66
66
  }>()
67
- const theme = useTheme()
67
+ const theme = useCanvasTheme()
68
68
  const { blockSize, highResScaleFactor, rowHeight } = model
69
69
  const width = panel.width
70
70
  const height = blockSize
@@ -2,8 +2,14 @@ import { contrastTextFn } from '../../util.ts'
2
2
  import { getVisibleLeaves } from '../getVisibleLeaves.ts'
3
3
  import { drawFeatureSpans, spanRows } from '../msa/drawFeatureSpans.ts'
4
4
 
5
+ import type { HierarchyNode } from '../../hierarchy.ts'
5
6
  import type { MsaViewModel } from '../../model.ts'
6
- import type { ResolvedFeaturePanel, RowPanelSpan } from '../../types.ts'
7
+ import type {
8
+ NodeWithIdsAndLength,
9
+ ResolvedFeaturePanel,
10
+ RowPanelSpan,
11
+ } from '../../types.ts'
12
+ import type { SpanSource } from '../msa/drawFeatureSpans.ts'
7
13
  import type { RenderCtx } from '../renderCtx.ts'
8
14
  import type { Theme } from '@mui/material'
9
15
 
@@ -46,10 +52,26 @@ export function renderFeaturePanel({
46
52
 
47
53
  drawFeatureSpans<RowPanelSpan>({
48
54
  ctx,
49
- rows: spanRows(
55
+ ...featurePanelSource(
56
+ model,
57
+ panel,
50
58
  getVisibleLeaves({ model, offsetY, blockSizeY: by }),
51
- panel.spans,
52
59
  ),
60
+ contrastText: contrastTextFn(theme),
61
+ xMin: 0,
62
+ xMax: panel.width,
63
+ })
64
+ }
65
+
66
+ /** a features panel's spans over `leaves`, in panel pixels, a lane apiece */
67
+ export function featurePanelSource(
68
+ model: MsaViewModel,
69
+ panel: ResolvedFeaturePanel,
70
+ leaves: HierarchyNode<NodeWithIdsAndLength>[],
71
+ ): SpanSource<RowPanelSpan> {
72
+ const { rowHeight } = model
73
+ return {
74
+ rows: spanRows(leaves, panel.spans),
53
75
  layout: {
54
76
  height: laneCount => Math.max(1, rowHeight / laneCount - rowPadding),
55
77
  top: (y, lane, h) =>
@@ -59,8 +81,5 @@ export function renderFeaturePanel({
59
81
  xOf: span => [span.xStart, span.xEnd],
60
82
  colors: panel.colors,
61
83
  labelOf: span => panel.labels?.get(span.annotation),
62
- contrastText: contrastTextFn(theme),
63
- xMin: 0,
64
- xMax: panel.width,
65
- })
84
+ }
66
85
  }