react-msaview 6.5.0 → 8.0.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 (414) hide show
  1. package/README.md +13 -11
  2. package/bundle/index.js +122 -112
  3. package/bundle/index.js.map +4 -4
  4. package/dist/colorSchemes.js +1 -2
  5. package/dist/colorSchemes.js.map +1 -1
  6. package/dist/columnStats.d.ts +28 -0
  7. package/dist/columnStats.js +34 -0
  8. package/dist/columnStats.js.map +1 -0
  9. package/dist/components/DragHandle.d.ts +3 -2
  10. package/dist/components/DragHandle.js +11 -5
  11. package/dist/components/DragHandle.js.map +1 -1
  12. package/dist/components/Loading.js +2 -2
  13. package/dist/components/Loading.js.map +1 -1
  14. package/dist/components/MSAView.js +17 -6
  15. package/dist/components/MSAView.js.map +1 -1
  16. package/dist/components/MSAViewer.d.ts +69 -4
  17. package/dist/components/MSAViewer.js +201 -8
  18. package/dist/components/MSAViewer.js.map +1 -1
  19. package/dist/components/PortalTooltip.d.ts +11 -0
  20. package/dist/components/PortalTooltip.js +29 -0
  21. package/dist/components/PortalTooltip.js.map +1 -0
  22. package/dist/components/ResizeHandles.d.ts +3 -3
  23. package/dist/components/ResizeHandles.js +13 -24
  24. package/dist/components/ResizeHandles.js.map +1 -1
  25. package/dist/components/SequenceTextArea.js +3 -3
  26. package/dist/components/SequenceTextArea.js.map +1 -1
  27. package/dist/components/Track.js +41 -22
  28. package/dist/components/Track.js.map +1 -1
  29. package/dist/components/dialogs/{InterProScanDialog.d.ts → AnnotationFileDialog.d.ts} +2 -2
  30. package/dist/components/dialogs/AnnotationFileDialog.js +92 -0
  31. package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -0
  32. package/dist/components/dialogs/ExportSVGDialog.js +5 -3
  33. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  34. package/dist/components/dialogs/FeatureDialog.js +13 -9
  35. package/dist/components/dialogs/FeatureDialog.js.map +1 -1
  36. package/dist/components/dialogs/TrackInfoDialog.js +1 -1
  37. package/dist/components/dialogs/TrackInfoDialog.js.map +1 -1
  38. package/dist/components/header/GappynessSlider.js +6 -11
  39. package/dist/components/header/GappynessSlider.js.map +1 -1
  40. package/dist/components/header/Header.js +7 -0
  41. package/dist/components/header/Header.js.map +1 -1
  42. package/dist/components/header/HeaderStatusArea.js +0 -2
  43. package/dist/components/header/HeaderStatusArea.js.map +1 -1
  44. package/dist/components/header/LoadWarnings.d.ts +6 -0
  45. package/dist/components/header/LoadWarnings.js +35 -0
  46. package/dist/components/header/LoadWarnings.js.map +1 -0
  47. package/dist/components/header/MultiAlignmentSelector.js +0 -0
  48. package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
  49. package/dist/components/header/ScrollZoomIcons.d.ts +6 -0
  50. package/dist/components/header/ScrollZoomIcons.js +35 -0
  51. package/dist/components/header/ScrollZoomIcons.js.map +1 -0
  52. package/dist/components/header/TreeSettingsMenu.js +7 -1
  53. package/dist/components/header/TreeSettingsMenu.js.map +1 -1
  54. package/dist/components/header/UnshareableDataWarning.d.ts +6 -0
  55. package/dist/components/header/UnshareableDataWarning.js +40 -0
  56. package/dist/components/header/UnshareableDataWarning.js.map +1 -0
  57. package/dist/components/header/ZoomControls.js +49 -6
  58. package/dist/components/header/ZoomControls.js.map +1 -1
  59. package/dist/components/header/getAnnotationsMenu.js +11 -14
  60. package/dist/components/header/getAnnotationsMenu.js.map +1 -1
  61. package/dist/components/header/settingsMenuItems.js +10 -7
  62. package/dist/components/header/settingsMenuItems.js.map +1 -1
  63. package/dist/components/import/ImportForm.js +1 -1
  64. package/dist/components/import/ImportForm.js.map +1 -1
  65. package/dist/components/import/ImportFormExamples.js +2 -6
  66. package/dist/components/import/ImportFormExamples.js.map +1 -1
  67. package/dist/components/import/util.js +2 -0
  68. package/dist/components/import/util.js.map +1 -1
  69. package/dist/components/minimap/Minimap.js +1 -2
  70. package/dist/components/minimap/Minimap.js.map +1 -1
  71. package/dist/components/msa/AnnotationLegend.js +27 -19
  72. package/dist/components/msa/AnnotationLegend.js.map +1 -1
  73. package/dist/components/msa/MSACanvas.js +1 -1
  74. package/dist/components/msa/MSACanvas.js.map +1 -1
  75. package/dist/components/msa/MSACanvasBlock.js +17 -20
  76. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  77. package/dist/components/msa/MSAMouseoverCanvas.js +2 -1
  78. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  79. package/dist/components/msa/domainBandCursor.d.ts +7 -11
  80. package/dist/components/msa/domainBandCursor.js +7 -11
  81. package/dist/components/msa/domainBandCursor.js.map +1 -1
  82. package/dist/components/msa/drawFeatureSpans.d.ts +53 -0
  83. package/dist/components/msa/drawFeatureSpans.js +78 -0
  84. package/dist/components/msa/drawFeatureSpans.js.map +1 -0
  85. package/dist/components/msa/legendRows.d.ts +8 -0
  86. package/dist/components/msa/legendRows.js +16 -0
  87. package/dist/components/msa/legendRows.js.map +1 -0
  88. package/dist/components/msa/msaRaster.d.ts +30 -27
  89. package/dist/components/msa/msaRaster.js +193 -90
  90. package/dist/components/msa/msaRaster.js.map +1 -1
  91. package/dist/components/msa/packDomainLanes.d.ts +20 -0
  92. package/dist/components/msa/packDomainLanes.js +33 -0
  93. package/dist/components/msa/packDomainLanes.js.map +1 -0
  94. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +3 -1
  95. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +51 -87
  96. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  97. package/dist/components/msa/renderHighlights.d.ts +44 -4
  98. package/dist/components/msa/renderHighlights.js +99 -11
  99. package/dist/components/msa/renderHighlights.js.map +1 -1
  100. package/dist/components/msa/renderMSABlock.d.ts +1 -2
  101. package/dist/components/msa/renderMSABlock.js +28 -31
  102. package/dist/components/msa/renderMSABlock.js.map +1 -1
  103. package/dist/components/msa/renderMSAMouseover.js +9 -30
  104. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  105. package/dist/components/msa/tileColor.js +4 -7
  106. package/dist/components/msa/tileColor.js.map +1 -1
  107. package/dist/components/msa/useMsaBlockMouse.d.ts +5 -3
  108. package/dist/components/msa/useMsaBlockMouse.js +6 -6
  109. package/dist/components/msa/useMsaBlockMouse.js.map +1 -1
  110. package/dist/components/renderCtx.d.ts +1 -1
  111. package/dist/components/rowpanels/RowPanelBlock.d.ts +9 -0
  112. package/dist/components/rowpanels/RowPanelBlock.js +86 -0
  113. package/dist/components/rowpanels/RowPanelBlock.js.map +1 -0
  114. package/dist/components/rowpanels/RowPanelHeaders.d.ts +12 -0
  115. package/dist/components/rowpanels/RowPanelHeaders.js +38 -0
  116. package/dist/components/rowpanels/RowPanelHeaders.js.map +1 -0
  117. package/dist/components/{msa/ColumnStats.d.ts → rowpanels/RowPanels.d.ts} +2 -2
  118. package/dist/components/rowpanels/RowPanels.js +32 -0
  119. package/dist/components/rowpanels/RowPanels.js.map +1 -0
  120. package/dist/components/rowpanels/headerLayout.d.ts +1 -0
  121. package/dist/components/rowpanels/headerLayout.js +5 -0
  122. package/dist/components/rowpanels/headerLayout.js.map +1 -0
  123. package/dist/components/rowpanels/renderFeaturePanel.d.ts +21 -0
  124. package/dist/components/rowpanels/renderFeaturePanel.js +37 -0
  125. package/dist/components/rowpanels/renderFeaturePanel.js.map +1 -0
  126. package/dist/components/rowpanels/renderRowPanel.d.ts +23 -0
  127. package/dist/components/rowpanels/renderRowPanel.js +22 -0
  128. package/dist/components/rowpanels/renderRowPanel.js.map +1 -0
  129. package/dist/components/rowpanels/renderStrip.d.ts +20 -0
  130. package/dist/components/rowpanels/renderStrip.js +26 -0
  131. package/dist/components/rowpanels/renderStrip.js.map +1 -0
  132. package/dist/components/tracks/TrackBlocks.js +13 -16
  133. package/dist/components/tracks/TrackBlocks.js.map +1 -1
  134. package/dist/components/tracks/TrackTooltipContent.d.ts +15 -0
  135. package/dist/components/tracks/TrackTooltipContent.js +109 -0
  136. package/dist/components/tracks/TrackTooltipContent.js.map +1 -0
  137. package/dist/components/tracks/drawTracks.d.ts +30 -12
  138. package/dist/components/tracks/drawTracks.js +127 -34
  139. package/dist/components/tracks/drawTracks.js.map +1 -1
  140. package/dist/components/tracks/useTrackHover.d.ts +22 -0
  141. package/dist/components/tracks/useTrackHover.js +30 -0
  142. package/dist/components/tracks/useTrackHover.js.map +1 -0
  143. package/dist/components/tree/CladeLabels.d.ts +12 -0
  144. package/dist/components/tree/CladeLabels.js +48 -0
  145. package/dist/components/tree/CladeLabels.js.map +1 -0
  146. package/dist/components/tree/TreeCanvas.js +6 -4
  147. package/dist/components/tree/TreeCanvas.js.map +1 -1
  148. package/dist/components/tree/TreeCanvasBlock.js +6 -21
  149. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  150. package/dist/components/tree/TreeOverview.d.ts +14 -0
  151. package/dist/components/tree/TreeOverview.js +75 -0
  152. package/dist/components/tree/TreeOverview.js.map +1 -0
  153. package/dist/components/tree/TreeRuler.js +11 -5
  154. package/dist/components/tree/TreeRuler.js.map +1 -1
  155. package/dist/components/tree/cladeBrackets.d.ts +25 -0
  156. package/dist/components/tree/cladeBrackets.js +51 -0
  157. package/dist/components/tree/cladeBrackets.js.map +1 -0
  158. package/dist/components/tree/dialogs/TreeNodeInfoDialog.js +2 -2
  159. package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -1
  160. package/dist/components/tree/renderTreeCanvas.d.ts +0 -1
  161. package/dist/components/tree/renderTreeCanvas.js +221 -47
  162. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  163. package/dist/components/tree/renderTreeOverview.d.ts +52 -0
  164. package/dist/components/tree/renderTreeOverview.js +138 -0
  165. package/dist/components/tree/renderTreeOverview.js.map +1 -0
  166. package/dist/components/tree/scaleBar.d.ts +10 -0
  167. package/dist/components/tree/scaleBar.js +24 -0
  168. package/dist/components/tree/scaleBar.js.map +1 -0
  169. package/dist/components/tree/useTreeHover.js +2 -4
  170. package/dist/components/tree/useTreeHover.js.map +1 -1
  171. package/dist/constants.d.ts +18 -1
  172. package/dist/constants.js +51 -8
  173. package/dist/constants.js.map +1 -1
  174. package/dist/createPaletteMap.d.ts +7 -6
  175. package/dist/createPaletteMap.js +10 -9
  176. package/dist/createPaletteMap.js.map +1 -1
  177. package/dist/element.d.ts +13 -0
  178. package/dist/element.js +269 -0
  179. package/dist/element.js.map +1 -0
  180. package/dist/featureFields.d.ts +11 -0
  181. package/dist/featureFields.js +17 -0
  182. package/dist/featureFields.js.map +1 -0
  183. package/dist/fetchUtils.d.ts +7 -7
  184. package/dist/fetchUtils.js +4 -32
  185. package/dist/fetchUtils.js.map +1 -1
  186. package/dist/flatToTree.js +1 -2
  187. package/dist/flatToTree.js.map +1 -1
  188. package/dist/ggplotPalettes.d.ts +10 -0
  189. package/dist/ggplotPalettes.js +58 -0
  190. package/dist/ggplotPalettes.js.map +1 -1
  191. package/dist/hierarchy.d.ts +29 -1
  192. package/dist/hierarchy.js +82 -19
  193. package/dist/hierarchy.js.map +1 -1
  194. package/dist/index.d.ts +10 -1
  195. package/dist/index.js +10 -2
  196. package/dist/index.js.map +1 -1
  197. package/dist/model/DataModel.js +4 -4
  198. package/dist/model/DataModel.js.map +1 -1
  199. package/dist/model/msaModel.d.ts +3 -2
  200. package/dist/model/msaModel.js +3 -2
  201. package/dist/model/msaModel.js.map +1 -1
  202. package/dist/model/treeModel.d.ts +30 -0
  203. package/dist/model/treeModel.js +37 -1
  204. package/dist/model/treeModel.js.map +1 -1
  205. package/dist/model.d.ts +792 -259
  206. package/dist/model.js +2092 -675
  207. package/dist/model.js.map +1 -1
  208. package/dist/mount.d.ts +11 -0
  209. package/dist/mount.js +22 -0
  210. package/dist/mount.js.map +1 -0
  211. package/dist/neighborJoining.js +8 -32
  212. package/dist/neighborJoining.js.map +1 -1
  213. package/dist/renderToStaticMarkup.d.ts +15 -13
  214. package/dist/renderToStaticMarkup.js +37 -25
  215. package/dist/renderToStaticMarkup.js.map +1 -1
  216. package/dist/renderToSvg.js +198 -68
  217. package/dist/renderToSvg.js.map +1 -1
  218. package/dist/rowCoordinateCalculations.d.ts +26 -28
  219. package/dist/rowCoordinateCalculations.js +13 -39
  220. package/dist/rowCoordinateCalculations.js.map +1 -1
  221. package/dist/scales.d.ts +22 -0
  222. package/dist/scales.js +30 -0
  223. package/dist/scales.js.map +1 -0
  224. package/dist/seqPosToGlobalCol.d.ts +2 -3
  225. package/dist/seqPosToGlobalCol.js +5 -4
  226. package/dist/seqPosToGlobalCol.js.map +1 -1
  227. package/dist/sequenceLogo.d.ts +6 -11
  228. package/dist/sequenceLogo.js +6 -11
  229. package/dist/sequenceLogo.js.map +1 -1
  230. package/dist/stripDefault.d.ts +7 -14
  231. package/dist/stripDefault.js +7 -14
  232. package/dist/stripDefault.js.map +1 -1
  233. package/dist/svgTestUtil.d.ts +306 -124
  234. package/dist/types.d.ts +295 -3
  235. package/dist/umd.d.ts +2 -0
  236. package/dist/umd.js +4 -2
  237. package/dist/umd.js.map +1 -1
  238. package/dist/useCanvasAutorun.d.ts +5 -10
  239. package/dist/useCanvasAutorun.js +5 -10
  240. package/dist/useCanvasAutorun.js.map +1 -1
  241. package/dist/useMsaSvgFigure.d.ts +20 -0
  242. package/dist/useMsaSvgFigure.js +46 -0
  243. package/dist/useMsaSvgFigure.js.map +1 -0
  244. package/dist/util.d.ts +10 -4
  245. package/dist/util.js +37 -10
  246. package/dist/util.js.map +1 -1
  247. package/dist/version.d.ts +1 -1
  248. package/dist/version.js +1 -1
  249. package/dist/wuss.d.ts +14 -0
  250. package/dist/wuss.js +55 -0
  251. package/dist/wuss.js.map +1 -0
  252. package/package.json +23 -14
  253. package/src/colorSchemes.ts +1 -2
  254. package/src/columnStats.ts +58 -0
  255. package/src/components/DragHandle.tsx +18 -7
  256. package/src/components/Loading.tsx +14 -8
  257. package/src/components/MSAView.tsx +19 -5
  258. package/src/components/MSAViewer.tsx +326 -10
  259. package/src/components/PortalTooltip.tsx +47 -0
  260. package/src/components/ResizeHandles.tsx +21 -36
  261. package/src/components/SequenceTextArea.tsx +3 -3
  262. package/src/components/Track.tsx +55 -18
  263. package/src/components/dialogs/AnnotationFileDialog.tsx +162 -0
  264. package/src/components/dialogs/ExportSVGDialog.tsx +7 -2
  265. package/src/components/dialogs/FeatureDialog.tsx +13 -9
  266. package/src/components/dialogs/TrackInfoDialog.tsx +1 -1
  267. package/src/components/header/GappynessSlider.tsx +6 -11
  268. package/src/components/header/Header.tsx +10 -0
  269. package/src/components/header/HeaderStatusArea.tsx +0 -5
  270. package/src/components/header/LoadWarnings.tsx +48 -0
  271. package/src/components/header/MultiAlignmentSelector.tsx +0 -0
  272. package/src/components/header/ScrollZoomIcons.tsx +52 -0
  273. package/src/components/header/TreeSettingsMenu.tsx +7 -1
  274. package/src/components/header/UnshareableDataWarning.tsx +56 -0
  275. package/src/components/header/ZoomControls.tsx +74 -14
  276. package/src/components/header/getAnnotationsMenu.ts +13 -17
  277. package/src/components/header/settingsMenuItems.ts +11 -6
  278. package/src/components/import/ImportForm.tsx +2 -2
  279. package/src/components/import/ImportFormExamples.tsx +4 -8
  280. package/src/components/import/util.ts +2 -0
  281. package/src/components/minimap/Minimap.tsx +1 -2
  282. package/src/components/msa/AnnotationLegend.tsx +48 -38
  283. package/src/components/msa/MSACanvas.tsx +3 -5
  284. package/src/components/msa/MSACanvasBlock.tsx +17 -21
  285. package/src/components/msa/MSAMouseoverCanvas.tsx +2 -1
  286. package/src/components/msa/domainBandCursor.ts +7 -11
  287. package/src/components/msa/drawFeatureSpans.ts +150 -0
  288. package/src/components/msa/legendRows.ts +24 -0
  289. package/src/components/msa/msaRaster.ts +236 -88
  290. package/src/components/msa/packDomainLanes.ts +36 -0
  291. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +69 -123
  292. package/src/components/msa/renderHighlights.ts +141 -10
  293. package/src/components/msa/renderMSABlock.ts +29 -38
  294. package/src/components/msa/renderMSAMouseover.ts +9 -39
  295. package/src/components/msa/tileColor.ts +4 -7
  296. package/src/components/msa/useMsaBlockMouse.ts +6 -6
  297. package/src/components/renderCtx.ts +1 -0
  298. package/src/components/rowpanels/RowPanelBlock.tsx +139 -0
  299. package/src/components/rowpanels/RowPanelHeaders.tsx +57 -0
  300. package/src/components/rowpanels/RowPanels.tsx +77 -0
  301. package/src/components/rowpanels/headerLayout.ts +5 -0
  302. package/src/components/rowpanels/renderFeaturePanel.ts +66 -0
  303. package/src/components/rowpanels/renderRowPanel.ts +41 -0
  304. package/src/components/rowpanels/renderStrip.ts +46 -0
  305. package/src/components/tracks/TrackBlocks.tsx +13 -18
  306. package/src/components/tracks/TrackTooltipContent.tsx +156 -0
  307. package/src/components/tracks/drawTracks.ts +169 -38
  308. package/src/components/tracks/useTrackHover.ts +42 -0
  309. package/src/components/tree/CladeLabels.tsx +77 -0
  310. package/src/components/tree/TreeCanvas.tsx +4 -3
  311. package/src/components/tree/TreeCanvasBlock.tsx +10 -32
  312. package/src/components/tree/TreeOverview.tsx +106 -0
  313. package/src/components/tree/TreeRuler.tsx +29 -5
  314. package/src/components/tree/cladeBrackets.ts +73 -0
  315. package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +2 -2
  316. package/src/components/tree/renderTreeCanvas.ts +312 -48
  317. package/src/components/tree/renderTreeOverview.ts +212 -0
  318. package/src/components/tree/scaleBar.ts +23 -0
  319. package/src/components/tree/useTreeHover.ts +2 -4
  320. package/src/constants.ts +61 -8
  321. package/src/createPaletteMap.ts +10 -9
  322. package/src/element.ts +321 -0
  323. package/src/featureFields.ts +19 -0
  324. package/src/fetchUtils.ts +7 -40
  325. package/src/flatToTree.ts +1 -2
  326. package/src/ggplotPalettes.ts +60 -0
  327. package/src/hierarchy.ts +97 -20
  328. package/src/index.ts +46 -6
  329. package/src/model/DataModel.ts +5 -4
  330. package/src/model/msaModel.ts +3 -2
  331. package/src/model/treeModel.ts +42 -0
  332. package/src/model.ts +2492 -793
  333. package/src/mount.tsx +32 -0
  334. package/src/neighborJoining.ts +8 -32
  335. package/src/rawImports.d.ts +9 -0
  336. package/src/renderToStaticMarkup.ts +41 -25
  337. package/src/renderToSvg.tsx +365 -92
  338. package/src/rowCoordinateCalculations.ts +16 -62
  339. package/src/scales.ts +47 -0
  340. package/src/seqPosToGlobalCol.ts +5 -4
  341. package/src/sequenceLogo.ts +6 -11
  342. package/src/stripDefault.ts +7 -14
  343. package/src/types.ts +352 -12
  344. package/src/umd.ts +4 -2
  345. package/src/useCanvasAutorun.ts +5 -10
  346. package/src/useMsaSvgFigure.ts +72 -0
  347. package/src/util.ts +40 -14
  348. package/src/version.ts +1 -1
  349. package/src/wuss.ts +62 -0
  350. package/dist/components/dialogs/InterProScanDialog.js +0 -137
  351. package/dist/components/dialogs/InterProScanDialog.js.map +0 -1
  352. package/dist/components/dialogs/InterProScanFileDialog.d.ts +0 -7
  353. package/dist/components/dialogs/InterProScanFileDialog.js +0 -64
  354. package/dist/components/dialogs/InterProScanFileDialog.js.map +0 -1
  355. package/dist/components/msa/ColumnStats.js +0 -42
  356. package/dist/components/msa/ColumnStats.js.map +0 -1
  357. package/dist/launchInterProScan.d.ts +0 -13
  358. package/dist/launchInterProScan.js +0 -110
  359. package/dist/launchInterProScan.js.map +0 -1
  360. package/dist/useColorContrast.d.ts +0 -10
  361. package/dist/useColorContrast.js +0 -13
  362. package/dist/useColorContrast.js.map +0 -1
  363. package/src/clustalX.test.ts +0 -74
  364. package/src/colSpace.test.ts +0 -67
  365. package/src/collapseLogic.test.ts +0 -115
  366. package/src/colorSchemes.docs.test.ts +0 -57
  367. package/src/columnCounts.test.ts +0 -73
  368. package/src/columnStats.test.ts +0 -94
  369. package/src/columnTracks.test.ts +0 -97
  370. package/src/components/dialogs/InterProScanDialog.tsx +0 -214
  371. package/src/components/dialogs/InterProScanFileDialog.tsx +0 -138
  372. package/src/components/minimap/minimapLayout.test.ts +0 -71
  373. package/src/components/msa/ColumnStats.tsx +0 -54
  374. package/src/components/msa/msaRaster.test.ts +0 -145
  375. package/src/components/msa/renderBoxFeatureCanvasBlock.test.ts +0 -51
  376. package/src/components/tree/renderTreeCanvas.test.ts +0 -296
  377. package/src/dataInitialized.test.ts +0 -42
  378. package/src/domainBands.test.ts +0 -122
  379. package/src/domainLetterColor.test.ts +0 -80
  380. package/src/exportFileName.test.ts +0 -40
  381. package/src/fetchUtils.test.ts +0 -83
  382. package/src/flatToTree.test.ts +0 -51
  383. package/src/hierarchy.test.ts +0 -228
  384. package/src/highlights.test.ts +0 -70
  385. package/src/impgRender.test.tsx +0 -68
  386. package/src/largeTree.test.ts +0 -67
  387. package/src/launchInterProScan.ts +0 -167
  388. package/src/loadErrorDisplay.test.tsx +0 -102
  389. package/src/modelFilehandleLoaders.test.ts +0 -137
  390. package/src/modelReset.test.ts +0 -120
  391. package/src/neighborJoining.test.ts +0 -164
  392. package/src/parseAsn1.test.ts +0 -36
  393. package/src/propertyConservation.test.ts +0 -36
  394. package/src/renderColumnTracksSvg.test.tsx +0 -108
  395. package/src/renderDomainsSvg.test.tsx +0 -118
  396. package/src/renderHighlightsSvg.test.tsx +0 -85
  397. package/src/renderMinimapSvg.test.tsx +0 -62
  398. package/src/renderRasterSvg.test.tsx +0 -144
  399. package/src/renderSequenceLogoSvg.test.tsx +0 -165
  400. package/src/renderToSvg.test.tsx +0 -65
  401. package/src/reset.test.ts +0 -61
  402. package/src/rowCoordinateCalculations.test.ts +0 -211
  403. package/src/rowSpace.test.ts +0 -46
  404. package/src/segmentOverlay.test.ts +0 -70
  405. package/src/seqPosToGlobalCol.test.ts +0 -59
  406. package/src/sequenceLogo.test.ts +0 -88
  407. package/src/setFontSize.test.ts +0 -33
  408. package/src/stripDefault.test.ts +0 -48
  409. package/src/stripDefaultSnapshot.test.ts +0 -87
  410. package/src/treeMetadata.test.ts +0 -39
  411. package/src/useCanvasAutorun.test.tsx +0 -98
  412. package/src/useColorContrast.ts +0 -18
  413. package/src/viewChrome.test.tsx +0 -134
  414. package/src/wheelZoom.test.ts +0 -46
@@ -1,31 +1,67 @@
1
- import {
2
- calcDepthToLeaf,
3
- forEachDescendant,
4
- forEachLink,
5
- } from '../../hierarchy.ts'
1
+ import { calcDepthToLeaf, nodeCoveringRows } from '../../hierarchy.ts'
6
2
  import { setFontSize } from '../../setFontSize.ts'
7
3
  import { getVisibleLeaves } from '../getVisibleLeaves.ts'
8
4
  import {
9
5
  drawHighlightLabel,
6
+ highlightLabelHeight,
10
7
  highlightRowFill,
11
8
  } from '../msa/renderHighlights.ts'
9
+ import { bracketBarWidth, bracketGap } from './cladeBrackets.ts'
12
10
 
13
11
  import type { HierarchyNode } from '../../hierarchy.ts'
14
12
  import type { MsaViewModel } from '../../model.ts'
13
+ import type { LabelBox } from '../msa/renderHighlights.ts'
15
14
  import type { RenderCtx } from '../renderCtx.ts'
16
15
  import type { ClickMapIndex } from './clickMap.ts'
17
16
  import type { Theme } from '@mui/material'
18
17
 
19
- export const padding = 600
20
-
21
- const extendBounds = 5
22
18
  const radius = 2.5
23
19
  const d = radius * 2
24
20
 
25
- // whether a node's row-center y falls within the block being drawn, padded by
26
- // extendBounds so bubbles/labels/triangles straddling the edge still render
27
- function inYBlock(y: number, offsetY: number, by: number) {
28
- return y > offsetY - extendBounds && y < offsetY + by + extendBounds
21
+ // How far outside a block a node's row-center can sit and still draw into it: a
22
+ // collapsed triangle reaches 0.42 rows each way, a tip label an em, and a
23
+ // highlight label its whole box. Five pixels clipped all three at block edges.
24
+ function blockPad(model: MsaViewModel) {
25
+ return Math.max(model.rowHeight, highlightLabelHeight)
26
+ }
27
+
28
+ // whether a node's row-center y falls within the block being drawn, padded so
29
+ // bubbles/labels/triangles straddling the edge still render
30
+ function inYBlock(y: number, offsetY: number, by: number, pad: number) {
31
+ return y > offsetY - pad && y < offsetY + by + pad
32
+ }
33
+
34
+ /**
35
+ * Every node whose subtree reaches into the block, skipping the subtrees that
36
+ * do not. A subtree's leaves are one contiguous run of rows, recorded by
37
+ * clusterLayout as xMin/xMax, so a block of a 200k-tip tree visits a few dozen
38
+ * nodes.
39
+ *
40
+ * A link out of a visited node is drawn even when its child is pruned, so a
41
+ * branch crossing the block stays visible.
42
+ */
43
+ function forEachNodeInBlock(
44
+ root: HierarchyNode,
45
+ offsetY: number,
46
+ by: number,
47
+ pad: number,
48
+ cb: (node: HierarchyNode) => void,
49
+ ) {
50
+ const top = offsetY - pad
51
+ const bottom = offsetY + by + pad
52
+ const stack = [root]
53
+ while (stack.length > 0) {
54
+ const node = stack.pop()!
55
+ if (node.xMax! < top || node.xMin! > bottom) {
56
+ continue
57
+ }
58
+ cb(node)
59
+ if (node.children) {
60
+ for (const child of node.children) {
61
+ stack.push(child)
62
+ }
63
+ }
64
+ }
29
65
  }
30
66
 
31
67
  // Calculate node x-coordinate for both phylogram (with branch lengths) and
@@ -66,31 +102,46 @@ function renderTree({
66
102
  maxDepthToLeaf: number
67
103
  blockSizeYOverride?: number
68
104
  }) {
69
- const { hierarchy, showBranchLenEffective: showBranchLen, blockSize } = model
105
+ const {
106
+ hierarchy,
107
+ showBranchLenEffective: showBranchLen,
108
+ blockSize,
109
+ branchColors,
110
+ } = model
70
111
  const by = blockSizeYOverride ?? blockSize
71
- ctx.strokeStyle = theme.palette.text.primary
72
- forEachLink(hierarchy, (source, target) => {
112
+ const defaultStroke = theme.palette.text.primary
113
+ ctx.strokeStyle = defaultStroke
114
+ forEachNodeInBlock(hierarchy, offsetY, by, blockPad(model), source => {
73
115
  const sy = source.x!
74
- const ty = target.x!
75
- const tx = getNodeX(target, showBranchLen, tipX, maxDepthToLeaf)
76
116
  const sx = getNodeX(source, showBranchLen, tipX, maxDepthToLeaf)
77
- if (tx === undefined || sx === undefined) {
117
+ if (sx === undefined || !source.children) {
78
118
  return
79
119
  }
80
-
81
- const y1 = Math.min(sy, ty)
82
- const y2 = Math.max(sy, ty)
83
- // 1d line intersection to check if line crosses block at all, this is an
84
- // optimization that allows us to skip drawing most tree links outside the
85
- // block
86
- if (offsetY + by >= y1 && y2 >= offsetY) {
87
- ctx.beginPath()
88
- ctx.moveTo(sx, sy)
89
- ctx.lineTo(sx, ty)
90
- ctx.lineTo(tx, ty)
91
- ctx.stroke()
120
+ for (const target of source.children) {
121
+ const ty = target.x!
122
+ const tx = getNodeX(target, showBranchLen, tipX, maxDepthToLeaf)
123
+ if (tx === undefined) {
124
+ continue
125
+ }
126
+ const y1 = Math.min(sy, ty)
127
+ const y2 = Math.max(sy, ty)
128
+ // 1d line intersection to check if line crosses block at all, this is an
129
+ // optimization that allows us to skip drawing most tree links outside the
130
+ // block
131
+ if (offsetY + by >= y1 && y2 >= offsetY) {
132
+ // the edge belongs to the child, whose id the branch channel colors
133
+ if (branchColors) {
134
+ ctx.strokeStyle = branchColors.get(target.data.id) ?? defaultStroke
135
+ }
136
+ ctx.beginPath()
137
+ ctx.moveTo(sx, sy)
138
+ ctx.lineTo(sx, ty)
139
+ ctx.lineTo(tx, ty)
140
+ ctx.stroke()
141
+ }
92
142
  }
93
143
  })
144
+ ctx.strokeStyle = defaultStroke
94
145
  }
95
146
 
96
147
  function renderCollapsedTriangles({
@@ -121,6 +172,7 @@ function renderCollapsedTriangles({
121
172
  rowHeight,
122
173
  fontSize,
123
174
  marginLeft: ml,
175
+ branchColors,
124
176
  } = model
125
177
  // nothing collapsed is the common case, and the traversal below visits every
126
178
  // node in the tree on every block of every redraw
@@ -129,12 +181,12 @@ function renderCollapsedTriangles({
129
181
  }
130
182
  const by = blockSizeYOverride ?? blockSize
131
183
  const halfHeight = Math.max(2, rowHeight * 0.42)
132
- forEachDescendant(hierarchy, node => {
184
+ forEachNodeInBlock(hierarchy, offsetY, by, blockPad(model), node => {
133
185
  const { id, name } = node.data
134
186
  if (collapsedSet.has(id)) {
135
187
  const apexX = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf)
136
188
  const y = node.x!
137
- const inBlock = inYBlock(y, offsetY, by)
189
+ const inBlock = inYBlock(y, offsetY, by, blockPad(model))
138
190
  // in cladogram mode the hidden tips align at the right edge, otherwise use
139
191
  // the branch-length extent recorded in the model's hierarchy getter
140
192
  const baseX = showBranchLen ? (node.collapsedTipXFar ?? tipX) : tipX
@@ -144,7 +196,7 @@ function renderCollapsedTriangles({
144
196
  ctx.lineTo(baseX, y - halfHeight)
145
197
  ctx.lineTo(baseX, y + halfHeight)
146
198
  ctx.closePath()
147
- ctx.fillStyle = theme.palette.action.disabled
199
+ ctx.fillStyle = branchColors?.get(id) ?? theme.palette.action.disabled
148
200
  ctx.fill()
149
201
  ctx.strokeStyle = theme.palette.text.primary
150
202
  ctx.stroke()
@@ -179,6 +231,7 @@ function renderCollapsedTriangles({
179
231
  // always runs and `draw` only decides whether it also strokes the circles
180
232
  function renderNodeBubbles({
181
233
  ctx,
234
+ theme,
182
235
  clickMap,
183
236
  offsetY,
184
237
  model,
@@ -197,6 +250,7 @@ function renderNodeBubbles({
197
250
  blockSizeYOverride?: number
198
251
  collapsedSet: Set<string>
199
252
  draw: boolean
253
+ theme: Theme
200
254
  }) {
201
255
  const {
202
256
  hierarchy,
@@ -205,7 +259,7 @@ function renderNodeBubbles({
205
259
  marginLeft: ml,
206
260
  } = model
207
261
  const by = blockSizeYOverride ?? blockSize
208
- forEachDescendant(hierarchy, node => {
262
+ forEachNodeInBlock(hierarchy, offsetY, by, blockPad(model), node => {
209
263
  const x = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf)
210
264
  if (x === undefined) {
211
265
  return
@@ -213,11 +267,13 @@ function renderNodeBubbles({
213
267
  const { data } = node
214
268
  const y = node.x!
215
269
  const { id, name } = data
216
- if (node.height >= 1 && inYBlock(y, offsetY, by)) {
270
+ if (node.height >= 1 && inYBlock(y, offsetY, by, blockPad(model))) {
217
271
  const isCollapsed = collapsedSet.has(id)
218
272
  if (draw) {
219
- ctx.strokeStyle = 'black'
220
- ctx.fillStyle = isCollapsed ? 'black' : 'white'
273
+ ctx.strokeStyle = theme.palette.text.primary
274
+ ctx.fillStyle = isCollapsed
275
+ ? theme.palette.text.primary
276
+ : theme.palette.background.default
221
277
  ctx.beginPath()
222
278
  ctx.arc(x, y, radius, 0, 2 * Math.PI)
223
279
  ctx.fill()
@@ -241,6 +297,53 @@ function renderNodeBubbles({
241
297
  })
242
298
  }
243
299
 
300
+ // The label a newick file puts on an internal node, which is where a bootstrap
301
+ // or posterior support value lands: ((A,B)95,(C,D)80);. withId falls back to the
302
+ // path-derived id for an unnamed node, so a node whose name is its id has no
303
+ // label of its own and an ungated pass prints node-0-1-1 across the tree.
304
+ function renderNodeLabels({
305
+ ctx,
306
+ theme,
307
+ offsetY,
308
+ model,
309
+ tipX,
310
+ maxDepthToLeaf,
311
+ blockSizeYOverride,
312
+ }: {
313
+ ctx: RenderCtx
314
+ theme: Theme
315
+ offsetY: number
316
+ model: MsaViewModel
317
+ tipX: number
318
+ maxDepthToLeaf: number
319
+ blockSizeYOverride?: number
320
+ }) {
321
+ const {
322
+ hierarchy,
323
+ showBranchLenEffective: showBranchLen,
324
+ blockSize,
325
+ fontSize,
326
+ } = model
327
+ const by = blockSizeYOverride ?? blockSize
328
+ const pad = blockPad(model)
329
+ setFontSize(ctx, Math.max(6, fontSize - 3))
330
+ ctx.fillStyle = theme.palette.text.primary
331
+ ctx.textAlign = 'right'
332
+ forEachNodeInBlock(hierarchy, offsetY, by, pad, node => {
333
+ const { id, name } = node.data
334
+ if (node.height < 1 || name === id) {
335
+ return
336
+ }
337
+ const x = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf)
338
+ const y = node.x!
339
+ if (x !== undefined && inYBlock(y, offsetY, by, pad)) {
340
+ ctx.fillText(name, x - radius - 1, y - radius - 1)
341
+ }
342
+ })
343
+ ctx.textAlign = 'start'
344
+ setFontSize(ctx, fontSize)
345
+ }
346
+
244
347
  function renderTreeLabels({
245
348
  theme,
246
349
  model,
@@ -265,7 +368,7 @@ function renderTreeLabels({
265
368
  const {
266
369
  fontSize,
267
370
  showBranchLenEffective: showBranchLen,
268
- treeMetadata,
371
+ tipLabelColors,
269
372
  blockSize,
270
373
  labelsAlignRight,
271
374
  drawTree,
@@ -279,6 +382,7 @@ function renderTreeLabels({
279
382
  // labels only exist for leaves, which are laid out top to bottom, so take the
280
383
  // same slice the MSA renderer uses instead of walking every tip per block
281
384
  const visibleLeaves = getVisibleLeaves({ model, offsetY, blockSizeY: by })
385
+ const pad = blockPad(model)
282
386
  const emHeight = ctx.measureText('M').width
283
387
  if (labelsAlignRight) {
284
388
  ctx.textAlign = 'right'
@@ -293,11 +397,11 @@ function renderTreeLabels({
293
397
  } = node
294
398
  const y = node.x!
295
399
 
296
- const displayName = treeMetadata[name]?.genome || name
400
+ const displayName = model.rowDataOf(name)?.genome || name
297
401
  // a collapsed clade is drawn as a triangle + tip count; suppress its leaf
298
402
  // label when the "name" is just the auto-generated internal-node id
299
403
  const isAnonymousCollapsed = collapsedSet.has(id) && name === id
300
- if (!isAnonymousCollapsed && inYBlock(y, offsetY, by)) {
404
+ if (!isAnonymousCollapsed && inYBlock(y, offsetY, by, pad)) {
301
405
  // note: +rowHeight/4 matches with -rowHeight/4 in msa
302
406
  const yp = y + fontSize / 4
303
407
  let xp = 0
@@ -311,7 +415,7 @@ function renderTreeLabels({
311
415
  ? ctx.measureText(displayName).width
312
416
  : measured * labelWidthScale
313
417
 
314
- ctx.fillStyle = theme.palette.text.primary
418
+ ctx.fillStyle = tipLabelColors?.get(name) ?? theme.palette.text.primary
315
419
  if (labelsAlignRight) {
316
420
  const smallPadding = 2
317
421
  const offset = treeAreaWidthMinusMargin - smallPadding
@@ -353,8 +457,123 @@ function renderTreeLabels({
353
457
  ctx.setLineDash([])
354
458
  }
355
459
 
356
- // the row sets of `highlights`, tinted across the tree area under the labels
357
- // with the label in the gutter at the first row of each set
460
+ // the first row of a set, as a loop: spreading into Math.min passes one
461
+ // argument per row, and the ~125k argument limit throws RangeError on a set
462
+ // covering the 230k-tip COVID tree
463
+ function firstRow(rowIndices: number[]) {
464
+ let min = Infinity
465
+ for (const index of rowIndices) {
466
+ if (index < min) {
467
+ min = index
468
+ }
469
+ }
470
+ return min
471
+ }
472
+
473
+ // the highlight mark of the `clades` layer: a translucent rectangle from the
474
+ // clade's common ancestor to the right edge of the tree area, under the
475
+ // branches. A clade spanning hundreds of rows crosses several blocks, so each
476
+ // block draws the whole rectangle and the canvas takes the part that is its.
477
+ function renderCladeHighlights({
478
+ ctx,
479
+ model,
480
+ offsetY,
481
+ tipX,
482
+ maxDepthToLeaf,
483
+ blockSizeYOverride,
484
+ }: {
485
+ ctx: RenderCtx
486
+ model: MsaViewModel
487
+ offsetY: number
488
+ tipX: number
489
+ maxDepthToLeaf: number
490
+ blockSizeYOverride?: number
491
+ }) {
492
+ const {
493
+ resolvedClades,
494
+ hierarchy,
495
+ showBranchLenEffective: showBranchLen,
496
+ rowHeight,
497
+ treeAreaWidth,
498
+ marginLeft,
499
+ blockSize,
500
+ } = model
501
+ const by = blockSizeYOverride ?? blockSize
502
+ const right = treeAreaWidth - marginLeft
503
+ for (const { rows, color, mark } of resolvedClades) {
504
+ if (mark !== 'highlight') {
505
+ continue
506
+ }
507
+ const top = rows[0] * rowHeight
508
+ const bottom = (rows[1] + 1) * rowHeight
509
+ if (bottom < offsetY || top > offsetY + by) {
510
+ continue
511
+ }
512
+ const node = nodeCoveringRows(
513
+ hierarchy,
514
+ top + rowHeight / 2,
515
+ bottom - rowHeight / 2,
516
+ )
517
+ const x = getNodeX(node, showBranchLen, tipX, maxDepthToLeaf) ?? 0
518
+ ctx.fillStyle = color
519
+ ctx.fillRect(x, top, right - x, bottom - top)
520
+ }
521
+ }
522
+
523
+ // the bar of the bracket mark, in the gutter `cladeGutterWidth` reserves at the
524
+ // right of the tree area. The label beside it is DOM text on screen and a
525
+ // <text> in the export, since the canvas layer has no rotation.
526
+ function renderCladeBrackets({
527
+ ctx,
528
+ model,
529
+ theme,
530
+ offsetY,
531
+ blockSizeYOverride,
532
+ }: {
533
+ ctx: RenderCtx
534
+ model: MsaViewModel
535
+ theme: Theme
536
+ offsetY: number
537
+ blockSizeYOverride?: number
538
+ }) {
539
+ const {
540
+ resolvedClades,
541
+ cladeGutterWidth,
542
+ rowHeight,
543
+ treeAreaWidth,
544
+ marginLeft,
545
+ blockSize,
546
+ } = model
547
+ if (cladeGutterWidth === 0) {
548
+ return
549
+ }
550
+ const by = blockSizeYOverride ?? blockSize
551
+ const x =
552
+ treeAreaWidth -
553
+ marginLeft -
554
+ cladeGutterWidth +
555
+ bracketGap +
556
+ bracketBarWidth / 2
557
+ ctx.lineWidth = bracketBarWidth
558
+ for (const { rows, mark, markColor } of resolvedClades) {
559
+ const top = rows[0] * rowHeight + 1
560
+ const bottom = (rows[1] + 1) * rowHeight - 1
561
+ if (mark !== 'bracket' || bottom < offsetY || top > offsetY + by) {
562
+ continue
563
+ }
564
+ ctx.strokeStyle = markColor ?? theme.palette.text.primary
565
+ ctx.beginPath()
566
+ ctx.moveTo(x, top)
567
+ ctx.lineTo(x, bottom)
568
+ ctx.stroke()
569
+ }
570
+ ctx.lineWidth = 1
571
+ ctx.strokeStyle = theme.palette.text.primary
572
+ }
573
+
574
+ // the `rowTint` encoding and the row sets of `highlights`, washed across the
575
+ // tree area under the labels, with each set's label in the gutter at its first
576
+ // row
358
577
  function renderRowHighlights({
359
578
  ctx,
360
579
  model,
@@ -370,25 +589,44 @@ function renderRowHighlights({
370
589
  }) {
371
590
  const {
372
591
  resolvedHighlights,
592
+ rowTints,
373
593
  rowHeight,
374
594
  treeAreaWidth,
375
595
  marginLeft,
376
596
  blockSize,
377
597
  } = model
378
598
  const by = blockSizeYOverride ?? blockSize
599
+ const pad = blockPad(model)
600
+ const placed: LabelBox[] = []
601
+ const fillRow = (index: number) => {
602
+ ctx.fillRect(-marginLeft, index * rowHeight, treeAreaWidth, rowHeight)
603
+ }
604
+ if (rowTints) {
605
+ const top = Math.max(0, Math.floor((offsetY - pad) / rowHeight))
606
+ const bottom = Math.min(
607
+ rowTints.length - 1,
608
+ Math.ceil((offsetY + by + pad) / rowHeight),
609
+ )
610
+ for (let index = top; index <= bottom; index++) {
611
+ const color = rowTints[index]
612
+ if (color) {
613
+ ctx.fillStyle = color
614
+ fillRow(index)
615
+ }
616
+ }
617
+ }
379
618
  for (const { rowIndices, label, color } of resolvedHighlights) {
380
619
  ctx.fillStyle = color ?? highlightRowFill
381
620
  for (const index of rowIndices) {
382
- const y = index * rowHeight
383
- if (inYBlock(y + rowHeight / 2, offsetY, by)) {
384
- ctx.fillRect(-marginLeft, y, treeAreaWidth, rowHeight)
621
+ if (inYBlock(index * rowHeight + rowHeight / 2, offsetY, by, pad)) {
622
+ fillRow(index)
385
623
  }
386
624
  }
387
- const first = Math.min(...rowIndices)
625
+ const first = firstRow(rowIndices)
388
626
  if (
389
627
  label &&
390
628
  rowIndices.length &&
391
- inYBlock(first * rowHeight, offsetY, by)
629
+ inYBlock(first * rowHeight, offsetY, by, pad)
392
630
  ) {
393
631
  drawHighlightLabel({
394
632
  ctx,
@@ -397,6 +635,8 @@ function renderRowHighlights({
397
635
  x: -marginLeft + 2,
398
636
  y: first * rowHeight,
399
637
  spanWidth: treeAreaWidth,
638
+ bounds: { min: -marginLeft, max: treeAreaWidth - marginLeft },
639
+ placed,
400
640
  })
401
641
  }
402
642
  }
@@ -426,6 +666,7 @@ export function renderTreeCanvas({
426
666
  noTree,
427
667
  drawTree,
428
668
  drawNodeBubbles,
669
+ drawNodeLabels,
429
670
  highResScaleFactor,
430
671
  fontSize,
431
672
  showTreeText,
@@ -456,6 +697,14 @@ export function renderTreeCanvas({
456
697
  // every block of every redraw, and `collapsed` is a list
457
698
  const collapsedSet = new Set(model.collapsed)
458
699
 
700
+ renderCladeHighlights({
701
+ ctx,
702
+ model,
703
+ offsetY,
704
+ tipX,
705
+ maxDepthToLeaf,
706
+ blockSizeYOverride,
707
+ })
459
708
  renderRowHighlights({ ctx, model, theme, offsetY, blockSizeYOverride })
460
709
  setFontSize(ctx, fontSize)
461
710
 
@@ -484,6 +733,7 @@ export function renderTreeCanvas({
484
733
 
485
734
  renderNodeBubbles({
486
735
  ctx,
736
+ theme,
487
737
  offsetY,
488
738
  clickMap,
489
739
  model,
@@ -493,6 +743,18 @@ export function renderTreeCanvas({
493
743
  collapsedSet,
494
744
  draw: drawNodeBubbles,
495
745
  })
746
+
747
+ if (drawNodeLabels) {
748
+ renderNodeLabels({
749
+ ctx,
750
+ theme,
751
+ offsetY,
752
+ model,
753
+ tipX,
754
+ maxDepthToLeaf,
755
+ blockSizeYOverride,
756
+ })
757
+ }
496
758
  }
497
759
 
498
760
  if (showTreeText) {
@@ -509,6 +771,8 @@ export function renderTreeCanvas({
509
771
  })
510
772
  }
511
773
 
774
+ renderCladeBrackets({ ctx, model, theme, offsetY, blockSizeYOverride })
775
+
512
776
  // Finish the index so it's ready for queries
513
777
  clickMap?.finish()
514
778
  }