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.
- package/README.md +13 -11
- package/bundle/index.js +122 -112
- package/bundle/index.js.map +4 -4
- package/dist/colorSchemes.js +1 -2
- package/dist/colorSchemes.js.map +1 -1
- package/dist/columnStats.d.ts +28 -0
- package/dist/columnStats.js +34 -0
- package/dist/columnStats.js.map +1 -0
- package/dist/components/DragHandle.d.ts +3 -2
- package/dist/components/DragHandle.js +11 -5
- package/dist/components/DragHandle.js.map +1 -1
- package/dist/components/Loading.js +2 -2
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/MSAView.js +17 -6
- package/dist/components/MSAView.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +69 -4
- package/dist/components/MSAViewer.js +201 -8
- package/dist/components/MSAViewer.js.map +1 -1
- package/dist/components/PortalTooltip.d.ts +11 -0
- package/dist/components/PortalTooltip.js +29 -0
- package/dist/components/PortalTooltip.js.map +1 -0
- package/dist/components/ResizeHandles.d.ts +3 -3
- package/dist/components/ResizeHandles.js +13 -24
- package/dist/components/ResizeHandles.js.map +1 -1
- package/dist/components/SequenceTextArea.js +3 -3
- package/dist/components/SequenceTextArea.js.map +1 -1
- package/dist/components/Track.js +41 -22
- package/dist/components/Track.js.map +1 -1
- package/dist/components/dialogs/{InterProScanDialog.d.ts → AnnotationFileDialog.d.ts} +2 -2
- package/dist/components/dialogs/AnnotationFileDialog.js +92 -0
- package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -0
- package/dist/components/dialogs/ExportSVGDialog.js +5 -3
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/dialogs/FeatureDialog.js +13 -9
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/dialogs/TrackInfoDialog.js +1 -1
- package/dist/components/dialogs/TrackInfoDialog.js.map +1 -1
- package/dist/components/header/GappynessSlider.js +6 -11
- package/dist/components/header/GappynessSlider.js.map +1 -1
- package/dist/components/header/Header.js +7 -0
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderStatusArea.js +0 -2
- package/dist/components/header/HeaderStatusArea.js.map +1 -1
- package/dist/components/header/LoadWarnings.d.ts +6 -0
- package/dist/components/header/LoadWarnings.js +35 -0
- package/dist/components/header/LoadWarnings.js.map +1 -0
- package/dist/components/header/MultiAlignmentSelector.js +0 -0
- package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
- package/dist/components/header/ScrollZoomIcons.d.ts +6 -0
- package/dist/components/header/ScrollZoomIcons.js +35 -0
- package/dist/components/header/ScrollZoomIcons.js.map +1 -0
- package/dist/components/header/TreeSettingsMenu.js +7 -1
- package/dist/components/header/TreeSettingsMenu.js.map +1 -1
- package/dist/components/header/UnshareableDataWarning.d.ts +6 -0
- package/dist/components/header/UnshareableDataWarning.js +40 -0
- package/dist/components/header/UnshareableDataWarning.js.map +1 -0
- package/dist/components/header/ZoomControls.js +49 -6
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/header/getAnnotationsMenu.js +11 -14
- package/dist/components/header/getAnnotationsMenu.js.map +1 -1
- package/dist/components/header/settingsMenuItems.js +10 -7
- package/dist/components/header/settingsMenuItems.js.map +1 -1
- package/dist/components/import/ImportForm.js +1 -1
- package/dist/components/import/ImportForm.js.map +1 -1
- package/dist/components/import/ImportFormExamples.js +2 -6
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/import/util.js +2 -0
- package/dist/components/import/util.js.map +1 -1
- package/dist/components/minimap/Minimap.js +1 -2
- package/dist/components/minimap/Minimap.js.map +1 -1
- package/dist/components/msa/AnnotationLegend.js +27 -19
- package/dist/components/msa/AnnotationLegend.js.map +1 -1
- package/dist/components/msa/MSACanvas.js +1 -1
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +17 -20
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js +2 -1
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/msa/domainBandCursor.d.ts +7 -11
- package/dist/components/msa/domainBandCursor.js +7 -11
- package/dist/components/msa/domainBandCursor.js.map +1 -1
- package/dist/components/msa/drawFeatureSpans.d.ts +53 -0
- package/dist/components/msa/drawFeatureSpans.js +78 -0
- package/dist/components/msa/drawFeatureSpans.js.map +1 -0
- package/dist/components/msa/legendRows.d.ts +8 -0
- package/dist/components/msa/legendRows.js +16 -0
- package/dist/components/msa/legendRows.js.map +1 -0
- package/dist/components/msa/msaRaster.d.ts +30 -27
- package/dist/components/msa/msaRaster.js +193 -90
- package/dist/components/msa/msaRaster.js.map +1 -1
- package/dist/components/msa/packDomainLanes.d.ts +20 -0
- package/dist/components/msa/packDomainLanes.js +33 -0
- package/dist/components/msa/packDomainLanes.js.map +1 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +3 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +51 -87
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderHighlights.d.ts +44 -4
- package/dist/components/msa/renderHighlights.js +99 -11
- package/dist/components/msa/renderHighlights.js.map +1 -1
- package/dist/components/msa/renderMSABlock.d.ts +1 -2
- package/dist/components/msa/renderMSABlock.js +28 -31
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +9 -30
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/msa/tileColor.js +4 -7
- package/dist/components/msa/tileColor.js.map +1 -1
- package/dist/components/msa/useMsaBlockMouse.d.ts +5 -3
- package/dist/components/msa/useMsaBlockMouse.js +6 -6
- package/dist/components/msa/useMsaBlockMouse.js.map +1 -1
- package/dist/components/renderCtx.d.ts +1 -1
- package/dist/components/rowpanels/RowPanelBlock.d.ts +9 -0
- package/dist/components/rowpanels/RowPanelBlock.js +86 -0
- package/dist/components/rowpanels/RowPanelBlock.js.map +1 -0
- package/dist/components/rowpanels/RowPanelHeaders.d.ts +12 -0
- package/dist/components/rowpanels/RowPanelHeaders.js +38 -0
- package/dist/components/rowpanels/RowPanelHeaders.js.map +1 -0
- package/dist/components/{msa/ColumnStats.d.ts → rowpanels/RowPanels.d.ts} +2 -2
- package/dist/components/rowpanels/RowPanels.js +32 -0
- package/dist/components/rowpanels/RowPanels.js.map +1 -0
- package/dist/components/rowpanels/headerLayout.d.ts +1 -0
- package/dist/components/rowpanels/headerLayout.js +5 -0
- package/dist/components/rowpanels/headerLayout.js.map +1 -0
- package/dist/components/rowpanels/renderFeaturePanel.d.ts +21 -0
- package/dist/components/rowpanels/renderFeaturePanel.js +37 -0
- package/dist/components/rowpanels/renderFeaturePanel.js.map +1 -0
- package/dist/components/rowpanels/renderRowPanel.d.ts +23 -0
- package/dist/components/rowpanels/renderRowPanel.js +22 -0
- package/dist/components/rowpanels/renderRowPanel.js.map +1 -0
- package/dist/components/rowpanels/renderStrip.d.ts +20 -0
- package/dist/components/rowpanels/renderStrip.js +26 -0
- package/dist/components/rowpanels/renderStrip.js.map +1 -0
- package/dist/components/tracks/TrackBlocks.js +13 -16
- package/dist/components/tracks/TrackBlocks.js.map +1 -1
- package/dist/components/tracks/TrackTooltipContent.d.ts +15 -0
- package/dist/components/tracks/TrackTooltipContent.js +109 -0
- package/dist/components/tracks/TrackTooltipContent.js.map +1 -0
- package/dist/components/tracks/drawTracks.d.ts +30 -12
- package/dist/components/tracks/drawTracks.js +127 -34
- package/dist/components/tracks/drawTracks.js.map +1 -1
- package/dist/components/tracks/useTrackHover.d.ts +22 -0
- package/dist/components/tracks/useTrackHover.js +30 -0
- package/dist/components/tracks/useTrackHover.js.map +1 -0
- package/dist/components/tree/CladeLabels.d.ts +12 -0
- package/dist/components/tree/CladeLabels.js +48 -0
- package/dist/components/tree/CladeLabels.js.map +1 -0
- package/dist/components/tree/TreeCanvas.js +6 -4
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +6 -21
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeOverview.d.ts +14 -0
- package/dist/components/tree/TreeOverview.js +75 -0
- package/dist/components/tree/TreeOverview.js.map +1 -0
- package/dist/components/tree/TreeRuler.js +11 -5
- package/dist/components/tree/TreeRuler.js.map +1 -1
- package/dist/components/tree/cladeBrackets.d.ts +25 -0
- package/dist/components/tree/cladeBrackets.js +51 -0
- package/dist/components/tree/cladeBrackets.js.map +1 -0
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js +2 -2
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.d.ts +0 -1
- package/dist/components/tree/renderTreeCanvas.js +221 -47
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/components/tree/renderTreeOverview.d.ts +52 -0
- package/dist/components/tree/renderTreeOverview.js +138 -0
- package/dist/components/tree/renderTreeOverview.js.map +1 -0
- package/dist/components/tree/scaleBar.d.ts +10 -0
- package/dist/components/tree/scaleBar.js +24 -0
- package/dist/components/tree/scaleBar.js.map +1 -0
- package/dist/components/tree/useTreeHover.js +2 -4
- package/dist/components/tree/useTreeHover.js.map +1 -1
- package/dist/constants.d.ts +18 -1
- package/dist/constants.js +51 -8
- package/dist/constants.js.map +1 -1
- package/dist/createPaletteMap.d.ts +7 -6
- package/dist/createPaletteMap.js +10 -9
- package/dist/createPaletteMap.js.map +1 -1
- package/dist/element.d.ts +13 -0
- package/dist/element.js +269 -0
- package/dist/element.js.map +1 -0
- package/dist/featureFields.d.ts +11 -0
- package/dist/featureFields.js +17 -0
- package/dist/featureFields.js.map +1 -0
- package/dist/fetchUtils.d.ts +7 -7
- package/dist/fetchUtils.js +4 -32
- package/dist/fetchUtils.js.map +1 -1
- package/dist/flatToTree.js +1 -2
- package/dist/flatToTree.js.map +1 -1
- package/dist/ggplotPalettes.d.ts +10 -0
- package/dist/ggplotPalettes.js +58 -0
- package/dist/ggplotPalettes.js.map +1 -1
- package/dist/hierarchy.d.ts +29 -1
- package/dist/hierarchy.js +82 -19
- package/dist/hierarchy.js.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/model/DataModel.js +4 -4
- package/dist/model/DataModel.js.map +1 -1
- package/dist/model/msaModel.d.ts +3 -2
- package/dist/model/msaModel.js +3 -2
- package/dist/model/msaModel.js.map +1 -1
- package/dist/model/treeModel.d.ts +30 -0
- package/dist/model/treeModel.js +37 -1
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +792 -259
- package/dist/model.js +2092 -675
- package/dist/model.js.map +1 -1
- package/dist/mount.d.ts +11 -0
- package/dist/mount.js +22 -0
- package/dist/mount.js.map +1 -0
- package/dist/neighborJoining.js +8 -32
- package/dist/neighborJoining.js.map +1 -1
- package/dist/renderToStaticMarkup.d.ts +15 -13
- package/dist/renderToStaticMarkup.js +37 -25
- package/dist/renderToStaticMarkup.js.map +1 -1
- package/dist/renderToSvg.js +198 -68
- package/dist/renderToSvg.js.map +1 -1
- package/dist/rowCoordinateCalculations.d.ts +26 -28
- package/dist/rowCoordinateCalculations.js +13 -39
- package/dist/rowCoordinateCalculations.js.map +1 -1
- package/dist/scales.d.ts +22 -0
- package/dist/scales.js +30 -0
- package/dist/scales.js.map +1 -0
- package/dist/seqPosToGlobalCol.d.ts +2 -3
- package/dist/seqPosToGlobalCol.js +5 -4
- package/dist/seqPosToGlobalCol.js.map +1 -1
- package/dist/sequenceLogo.d.ts +6 -11
- package/dist/sequenceLogo.js +6 -11
- package/dist/sequenceLogo.js.map +1 -1
- package/dist/stripDefault.d.ts +7 -14
- package/dist/stripDefault.js +7 -14
- package/dist/stripDefault.js.map +1 -1
- package/dist/svgTestUtil.d.ts +306 -124
- package/dist/types.d.ts +295 -3
- package/dist/umd.d.ts +2 -0
- package/dist/umd.js +4 -2
- package/dist/umd.js.map +1 -1
- package/dist/useCanvasAutorun.d.ts +5 -10
- package/dist/useCanvasAutorun.js +5 -10
- package/dist/useCanvasAutorun.js.map +1 -1
- package/dist/useMsaSvgFigure.d.ts +20 -0
- package/dist/useMsaSvgFigure.js +46 -0
- package/dist/useMsaSvgFigure.js.map +1 -0
- package/dist/util.d.ts +10 -4
- package/dist/util.js +37 -10
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/wuss.d.ts +14 -0
- package/dist/wuss.js +55 -0
- package/dist/wuss.js.map +1 -0
- package/package.json +23 -14
- package/src/colorSchemes.ts +1 -2
- package/src/columnStats.ts +58 -0
- package/src/components/DragHandle.tsx +18 -7
- package/src/components/Loading.tsx +14 -8
- package/src/components/MSAView.tsx +19 -5
- package/src/components/MSAViewer.tsx +326 -10
- package/src/components/PortalTooltip.tsx +47 -0
- package/src/components/ResizeHandles.tsx +21 -36
- package/src/components/SequenceTextArea.tsx +3 -3
- package/src/components/Track.tsx +55 -18
- package/src/components/dialogs/AnnotationFileDialog.tsx +162 -0
- package/src/components/dialogs/ExportSVGDialog.tsx +7 -2
- package/src/components/dialogs/FeatureDialog.tsx +13 -9
- package/src/components/dialogs/TrackInfoDialog.tsx +1 -1
- package/src/components/header/GappynessSlider.tsx +6 -11
- package/src/components/header/Header.tsx +10 -0
- package/src/components/header/HeaderStatusArea.tsx +0 -5
- package/src/components/header/LoadWarnings.tsx +48 -0
- package/src/components/header/MultiAlignmentSelector.tsx +0 -0
- package/src/components/header/ScrollZoomIcons.tsx +52 -0
- package/src/components/header/TreeSettingsMenu.tsx +7 -1
- package/src/components/header/UnshareableDataWarning.tsx +56 -0
- package/src/components/header/ZoomControls.tsx +74 -14
- package/src/components/header/getAnnotationsMenu.ts +13 -17
- package/src/components/header/settingsMenuItems.ts +11 -6
- package/src/components/import/ImportForm.tsx +2 -2
- package/src/components/import/ImportFormExamples.tsx +4 -8
- package/src/components/import/util.ts +2 -0
- package/src/components/minimap/Minimap.tsx +1 -2
- package/src/components/msa/AnnotationLegend.tsx +48 -38
- package/src/components/msa/MSACanvas.tsx +3 -5
- package/src/components/msa/MSACanvasBlock.tsx +17 -21
- package/src/components/msa/MSAMouseoverCanvas.tsx +2 -1
- package/src/components/msa/domainBandCursor.ts +7 -11
- package/src/components/msa/drawFeatureSpans.ts +150 -0
- package/src/components/msa/legendRows.ts +24 -0
- package/src/components/msa/msaRaster.ts +236 -88
- package/src/components/msa/packDomainLanes.ts +36 -0
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +69 -123
- package/src/components/msa/renderHighlights.ts +141 -10
- package/src/components/msa/renderMSABlock.ts +29 -38
- package/src/components/msa/renderMSAMouseover.ts +9 -39
- package/src/components/msa/tileColor.ts +4 -7
- package/src/components/msa/useMsaBlockMouse.ts +6 -6
- package/src/components/renderCtx.ts +1 -0
- package/src/components/rowpanels/RowPanelBlock.tsx +139 -0
- package/src/components/rowpanels/RowPanelHeaders.tsx +57 -0
- package/src/components/rowpanels/RowPanels.tsx +77 -0
- package/src/components/rowpanels/headerLayout.ts +5 -0
- package/src/components/rowpanels/renderFeaturePanel.ts +66 -0
- package/src/components/rowpanels/renderRowPanel.ts +41 -0
- package/src/components/rowpanels/renderStrip.ts +46 -0
- package/src/components/tracks/TrackBlocks.tsx +13 -18
- package/src/components/tracks/TrackTooltipContent.tsx +156 -0
- package/src/components/tracks/drawTracks.ts +169 -38
- package/src/components/tracks/useTrackHover.ts +42 -0
- package/src/components/tree/CladeLabels.tsx +77 -0
- package/src/components/tree/TreeCanvas.tsx +4 -3
- package/src/components/tree/TreeCanvasBlock.tsx +10 -32
- package/src/components/tree/TreeOverview.tsx +106 -0
- package/src/components/tree/TreeRuler.tsx +29 -5
- package/src/components/tree/cladeBrackets.ts +73 -0
- package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +2 -2
- package/src/components/tree/renderTreeCanvas.ts +312 -48
- package/src/components/tree/renderTreeOverview.ts +212 -0
- package/src/components/tree/scaleBar.ts +23 -0
- package/src/components/tree/useTreeHover.ts +2 -4
- package/src/constants.ts +61 -8
- package/src/createPaletteMap.ts +10 -9
- package/src/element.ts +321 -0
- package/src/featureFields.ts +19 -0
- package/src/fetchUtils.ts +7 -40
- package/src/flatToTree.ts +1 -2
- package/src/ggplotPalettes.ts +60 -0
- package/src/hierarchy.ts +97 -20
- package/src/index.ts +46 -6
- package/src/model/DataModel.ts +5 -4
- package/src/model/msaModel.ts +3 -2
- package/src/model/treeModel.ts +42 -0
- package/src/model.ts +2492 -793
- package/src/mount.tsx +32 -0
- package/src/neighborJoining.ts +8 -32
- package/src/rawImports.d.ts +9 -0
- package/src/renderToStaticMarkup.ts +41 -25
- package/src/renderToSvg.tsx +365 -92
- package/src/rowCoordinateCalculations.ts +16 -62
- package/src/scales.ts +47 -0
- package/src/seqPosToGlobalCol.ts +5 -4
- package/src/sequenceLogo.ts +6 -11
- package/src/stripDefault.ts +7 -14
- package/src/types.ts +352 -12
- package/src/umd.ts +4 -2
- package/src/useCanvasAutorun.ts +5 -10
- package/src/useMsaSvgFigure.ts +72 -0
- package/src/util.ts +40 -14
- package/src/version.ts +1 -1
- package/src/wuss.ts +62 -0
- package/dist/components/dialogs/InterProScanDialog.js +0 -137
- package/dist/components/dialogs/InterProScanDialog.js.map +0 -1
- package/dist/components/dialogs/InterProScanFileDialog.d.ts +0 -7
- package/dist/components/dialogs/InterProScanFileDialog.js +0 -64
- package/dist/components/dialogs/InterProScanFileDialog.js.map +0 -1
- package/dist/components/msa/ColumnStats.js +0 -42
- package/dist/components/msa/ColumnStats.js.map +0 -1
- package/dist/launchInterProScan.d.ts +0 -13
- package/dist/launchInterProScan.js +0 -110
- package/dist/launchInterProScan.js.map +0 -1
- package/dist/useColorContrast.d.ts +0 -10
- package/dist/useColorContrast.js +0 -13
- package/dist/useColorContrast.js.map +0 -1
- package/src/clustalX.test.ts +0 -74
- package/src/colSpace.test.ts +0 -67
- package/src/collapseLogic.test.ts +0 -115
- package/src/colorSchemes.docs.test.ts +0 -57
- package/src/columnCounts.test.ts +0 -73
- package/src/columnStats.test.ts +0 -94
- package/src/columnTracks.test.ts +0 -97
- package/src/components/dialogs/InterProScanDialog.tsx +0 -214
- package/src/components/dialogs/InterProScanFileDialog.tsx +0 -138
- package/src/components/minimap/minimapLayout.test.ts +0 -71
- package/src/components/msa/ColumnStats.tsx +0 -54
- package/src/components/msa/msaRaster.test.ts +0 -145
- package/src/components/msa/renderBoxFeatureCanvasBlock.test.ts +0 -51
- package/src/components/tree/renderTreeCanvas.test.ts +0 -296
- package/src/dataInitialized.test.ts +0 -42
- package/src/domainBands.test.ts +0 -122
- package/src/domainLetterColor.test.ts +0 -80
- package/src/exportFileName.test.ts +0 -40
- package/src/fetchUtils.test.ts +0 -83
- package/src/flatToTree.test.ts +0 -51
- package/src/hierarchy.test.ts +0 -228
- package/src/highlights.test.ts +0 -70
- package/src/impgRender.test.tsx +0 -68
- package/src/largeTree.test.ts +0 -67
- package/src/launchInterProScan.ts +0 -167
- package/src/loadErrorDisplay.test.tsx +0 -102
- package/src/modelFilehandleLoaders.test.ts +0 -137
- package/src/modelReset.test.ts +0 -120
- package/src/neighborJoining.test.ts +0 -164
- package/src/parseAsn1.test.ts +0 -36
- package/src/propertyConservation.test.ts +0 -36
- package/src/renderColumnTracksSvg.test.tsx +0 -108
- package/src/renderDomainsSvg.test.tsx +0 -118
- package/src/renderHighlightsSvg.test.tsx +0 -85
- package/src/renderMinimapSvg.test.tsx +0 -62
- package/src/renderRasterSvg.test.tsx +0 -144
- package/src/renderSequenceLogoSvg.test.tsx +0 -165
- package/src/renderToSvg.test.tsx +0 -65
- package/src/reset.test.ts +0 -61
- package/src/rowCoordinateCalculations.test.ts +0 -211
- package/src/rowSpace.test.ts +0 -46
- package/src/segmentOverlay.test.ts +0 -70
- package/src/seqPosToGlobalCol.test.ts +0 -59
- package/src/sequenceLogo.test.ts +0 -88
- package/src/setFontSize.test.ts +0 -33
- package/src/stripDefault.test.ts +0 -48
- package/src/stripDefaultSnapshot.test.ts +0 -87
- package/src/treeMetadata.test.ts +0 -39
- package/src/useCanvasAutorun.test.tsx +0 -98
- package/src/useColorContrast.ts +0 -18
- package/src/viewChrome.test.tsx +0 -134
- 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
|
-
//
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
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 {
|
|
105
|
+
const {
|
|
106
|
+
hierarchy,
|
|
107
|
+
showBranchLenEffective: showBranchLen,
|
|
108
|
+
blockSize,
|
|
109
|
+
branchColors,
|
|
110
|
+
} = model
|
|
70
111
|
const by = blockSizeYOverride ?? blockSize
|
|
71
|
-
|
|
72
|
-
|
|
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 (
|
|
117
|
+
if (sx === undefined || !source.children) {
|
|
78
118
|
return
|
|
79
119
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
220
|
-
ctx.fillStyle = isCollapsed
|
|
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
|
-
|
|
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 =
|
|
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
|
|
357
|
-
//
|
|
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
|
-
|
|
383
|
-
|
|
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 =
|
|
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
|
}
|