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
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assigns each of one row's bands a lane: the first lane whose last band ends
|
|
3
|
+
* before this one starts, so only bands that actually overlap stack. A row of
|
|
4
|
+
* adjacent exons packs into a single lane; a family with a domain nested inside
|
|
5
|
+
* it takes two.
|
|
6
|
+
*
|
|
7
|
+
* Packing runs left to right, but the result keeps the input's largest-first
|
|
8
|
+
* paint order. `laneCount` is the row's depth, which the renderer divides the
|
|
9
|
+
* row height by so a deep stack stays inside its own row.
|
|
10
|
+
*
|
|
11
|
+
* The coordinates are whatever the caller packs in: alignment columns for the
|
|
12
|
+
* overlay, residue positions for a `features` row panel.
|
|
13
|
+
*/
|
|
14
|
+
export function packDomainLanes<T extends { startCol: number; endCol: number }>(
|
|
15
|
+
bands: T[],
|
|
16
|
+
): (T & { lane: number; laneCount: number })[] {
|
|
17
|
+
const laneEnds: number[] = []
|
|
18
|
+
const lanes = new Array<number>(bands.length)
|
|
19
|
+
const byStart = bands
|
|
20
|
+
.map((_, i) => i)
|
|
21
|
+
.sort((a, b) => bands[a]!.startCol - bands[b]!.startCol)
|
|
22
|
+
|
|
23
|
+
for (const i of byStart) {
|
|
24
|
+
const { startCol, endCol } = bands[i]!
|
|
25
|
+
const found = laneEnds.findIndex(end => end <= startCol)
|
|
26
|
+
const lane = found === -1 ? laneEnds.length : found
|
|
27
|
+
laneEnds[lane] = endCol
|
|
28
|
+
lanes[i] = lane
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return bands.map((band, i) => ({
|
|
32
|
+
...band,
|
|
33
|
+
lane: lanes[i]!,
|
|
34
|
+
laneCount: laneEnds.length,
|
|
35
|
+
}))
|
|
36
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { subFeatureRowHeight } from '../../constants.ts'
|
|
1
|
+
import { domainUnderlineHeight, subFeatureRowHeight } from '../../constants.ts'
|
|
2
|
+
import { contrastTextFn } from '../../util.ts'
|
|
2
3
|
import { getVisibleLeaves } from '../getVisibleLeaves.ts'
|
|
4
|
+
import { drawFeatureSpans, spanRows } from './drawFeatureSpans.ts'
|
|
3
5
|
|
|
4
|
-
import type { HierarchyNode } from '../../hierarchy.ts'
|
|
5
6
|
import type { MsaViewModel } from '../../model.ts'
|
|
6
|
-
import type {
|
|
7
|
+
import type { DomainBand } from '../../types.ts'
|
|
7
8
|
import type { RenderCtx } from '../renderCtx.ts'
|
|
9
|
+
import type { Theme } from '@mui/material'
|
|
8
10
|
|
|
9
11
|
export function renderBoxFeatureCanvasBlock({
|
|
10
12
|
model,
|
|
13
|
+
theme,
|
|
11
14
|
offsetX,
|
|
12
15
|
offsetY,
|
|
13
16
|
ctx,
|
|
@@ -18,144 +21,87 @@ export function renderBoxFeatureCanvasBlock({
|
|
|
18
21
|
offsetX: number
|
|
19
22
|
offsetY: number
|
|
20
23
|
model: MsaViewModel
|
|
24
|
+
theme: Theme
|
|
21
25
|
ctx: RenderCtx
|
|
22
26
|
highResScaleFactorOverride?: number
|
|
23
27
|
blockSizeXOverride?: number
|
|
24
28
|
blockSizeYOverride?: number
|
|
25
|
-
}) {
|
|
26
|
-
const { blockSize, rowHeight, highResScaleFactor, actuallyShowDomains } =
|
|
27
|
-
model
|
|
28
|
-
if (actuallyShowDomains) {
|
|
29
|
-
const k = highResScaleFactorOverride ?? highResScaleFactor
|
|
30
|
-
const bx = blockSizeXOverride ?? blockSize
|
|
31
|
-
const by = blockSizeYOverride ?? blockSize
|
|
32
|
-
ctx.resetTransform()
|
|
33
|
-
ctx.scale(k, k)
|
|
34
|
-
ctx.translate(-offsetX, rowHeight / 2 - offsetY)
|
|
35
|
-
|
|
36
|
-
drawTiles({
|
|
37
|
-
model,
|
|
38
|
-
ctx,
|
|
39
|
-
visibleLeaves: getVisibleLeaves({ model, offsetY, blockSizeY: by }),
|
|
40
|
-
offsetX,
|
|
41
|
-
blockWidth: bx,
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function drawTiles({
|
|
47
|
-
model,
|
|
48
|
-
ctx,
|
|
49
|
-
visibleLeaves,
|
|
50
|
-
offsetX,
|
|
51
|
-
blockWidth,
|
|
52
|
-
}: {
|
|
53
|
-
model: MsaViewModel
|
|
54
|
-
ctx: RenderCtx
|
|
55
|
-
visibleLeaves: HierarchyNode<NodeWithIdsAndLength>[]
|
|
56
|
-
offsetX: number
|
|
57
|
-
blockWidth: number
|
|
58
29
|
}) {
|
|
59
30
|
const {
|
|
31
|
+
blockSize,
|
|
32
|
+
rowHeight,
|
|
33
|
+
highResScaleFactor,
|
|
34
|
+
actuallyShowDomains,
|
|
60
35
|
subFeatureRows,
|
|
61
36
|
colWidth,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
strokePalette,
|
|
37
|
+
featureColors,
|
|
38
|
+
featureLabels,
|
|
65
39
|
segmentLabels,
|
|
66
40
|
showMsaLetters,
|
|
41
|
+
domainUnderline,
|
|
67
42
|
domainBands,
|
|
68
43
|
} = model
|
|
69
|
-
|
|
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
|
+
// the plain and underline modes give every band the same height; a sub-row
|
|
55
|
+
// band is thinner, and how thin depends on how many lanes its row needs
|
|
56
|
+
const barHeight = domainUnderline
|
|
57
|
+
? Math.min(domainUnderlineHeight, rowHeight)
|
|
58
|
+
: rowHeight
|
|
70
59
|
// exon numbers label the bands only when residue letters aren't drawn (zoomed
|
|
71
60
|
// out); when letters show, the alternating shades alone mark the boundaries
|
|
72
|
-
// and a number would collide with the sequence
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const cull = h + colWidth
|
|
77
|
-
const xMin = offsetX - cull
|
|
78
|
-
const xMax = offsetX + blockWidth + cull
|
|
79
|
-
|
|
61
|
+
// and a number would collide with the sequence. A featureLabel encoding names
|
|
62
|
+
// what every span carries instead
|
|
63
|
+
const drawSegmentLabels =
|
|
64
|
+
!featureLabels && !showMsaLetters && !subFeatureRows && barHeight >= 9
|
|
80
65
|
// a segment (exon) number labels its band once per block, on the topmost
|
|
81
66
|
// visible row carrying that segment, so it reads as a column header for the
|
|
82
67
|
// whole band. Keyed by accession rather than drawn on row 0, because the rows
|
|
83
68
|
// carrying the gene model are often not the first ones in the alignment
|
|
84
69
|
const labelled = drawSegmentLabels ? new Set<string>() : undefined
|
|
70
|
+
// gene arrow heads stick out up to a row height past the band, so pad the
|
|
71
|
+
// cull window enough that a band just outside the block still draws its head
|
|
72
|
+
const cull = rowHeight + colWidth
|
|
85
73
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// A gene arrow: a full-width rectangular body spanning the feature's
|
|
127
|
-
// start..end columns, plus a triangular head that points *beyond* that end in
|
|
128
|
-
// the strand direction (right for +, left for -). Keeping the body aligned to
|
|
129
|
-
// the exact start/end columns means + and - strand features read as having the
|
|
130
|
-
// same boundaries; the arrow lives outside them purely to show transcription
|
|
131
|
-
// direction, preserving the column-by-column homology down the rows.
|
|
132
|
-
function drawGeneArrow({
|
|
133
|
-
ctx,
|
|
134
|
-
x,
|
|
135
|
-
t,
|
|
136
|
-
w,
|
|
137
|
-
h,
|
|
138
|
-
strand,
|
|
139
|
-
}: {
|
|
140
|
-
ctx: RenderCtx
|
|
141
|
-
x: number
|
|
142
|
-
t: number
|
|
143
|
-
w: number
|
|
144
|
-
h: number
|
|
145
|
-
strand: number
|
|
146
|
-
}) {
|
|
147
|
-
// body spans bodyStart..bodyEnd (the exact columns); the head extends one
|
|
148
|
-
// row-height past bodyEnd in the strand direction
|
|
149
|
-
const dir = strand > 0 ? 1 : -1
|
|
150
|
-
const bodyStart = strand > 0 ? x : x + w
|
|
151
|
-
const bodyEnd = strand > 0 ? x + w : x
|
|
152
|
-
ctx.beginPath()
|
|
153
|
-
ctx.moveTo(bodyStart, t)
|
|
154
|
-
ctx.lineTo(bodyEnd, t)
|
|
155
|
-
ctx.lineTo(bodyEnd + dir * h, t + h / 2)
|
|
156
|
-
ctx.lineTo(bodyEnd, t + h)
|
|
157
|
-
ctx.lineTo(bodyStart, t + h)
|
|
158
|
-
ctx.closePath()
|
|
159
|
-
ctx.fill()
|
|
160
|
-
ctx.stroke()
|
|
74
|
+
drawFeatureSpans<DomainBand>({
|
|
75
|
+
ctx,
|
|
76
|
+
rows: spanRows(
|
|
77
|
+
getVisibleLeaves({ model, offsetY, blockSizeY: by }),
|
|
78
|
+
domainBands,
|
|
79
|
+
),
|
|
80
|
+
layout: {
|
|
81
|
+
// sub-rows are thin, but a row whose lanes would spill onto the row below
|
|
82
|
+
// shares out the row height between them instead
|
|
83
|
+
height: laneCount =>
|
|
84
|
+
subFeatureRows
|
|
85
|
+
? Math.min(subFeatureRowHeight, rowHeight / laneCount)
|
|
86
|
+
: barHeight,
|
|
87
|
+
top: (y, lane, h) =>
|
|
88
|
+
y -
|
|
89
|
+
rowHeight +
|
|
90
|
+
(subFeatureRows ? lane * h : domainUnderline ? rowHeight - h : 0),
|
|
91
|
+
// the head keeps its full size on an underline bar, since a head as short
|
|
92
|
+
// as the bar reads as a nub rather than as a direction
|
|
93
|
+
headLength: h => (domainUnderline ? rowHeight / 2 : h),
|
|
94
|
+
},
|
|
95
|
+
xOf: band => [band.startCol * colWidth, band.endCol * colWidth],
|
|
96
|
+
colors: featureColors,
|
|
97
|
+
labelOf: band =>
|
|
98
|
+
featureLabels?.get(band.annotation) ??
|
|
99
|
+
(labelled && !labelled.has(band.annotation.accession)
|
|
100
|
+
? segmentLabels.get(band.annotation.accession)
|
|
101
|
+
: undefined),
|
|
102
|
+
labelDrawn: band => labelled?.add(band.annotation.accession),
|
|
103
|
+
contrastText: contrastTextFn(theme),
|
|
104
|
+
xMin: offsetX - cull,
|
|
105
|
+
xMax: offsetX + bx + cull,
|
|
106
|
+
})
|
|
161
107
|
}
|
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
import { setFontSize } from '../../setFontSize.ts'
|
|
2
|
+
import { referenceColor } from '../overlayColors.ts'
|
|
2
3
|
|
|
3
4
|
import type { MsaViewModel } from '../../model.ts'
|
|
4
5
|
import type { RenderCtx } from '../renderCtx.ts'
|
|
5
6
|
import type { Theme } from '@mui/material'
|
|
6
7
|
|
|
8
|
+
// a fill plus a solid border; the hover wash alone is invisible over clustalx
|
|
9
|
+
// coloring
|
|
7
10
|
export const highlightFill = 'rgba(255,140,0,0.28)'
|
|
8
11
|
export const highlightBorder = 'rgba(210,90,0,0.95)'
|
|
9
12
|
export const highlightRowFill = 'rgba(255,140,0,0.18)'
|
|
10
13
|
|
|
11
14
|
export const labelFontSize = 11
|
|
12
15
|
const labelPad = 3
|
|
16
|
+
// the label box above a highlight band; tree blocks also check rows this far
|
|
17
|
+
// outside themselves
|
|
18
|
+
export const highlightLabelHeight = labelFontSize + labelPad * 2
|
|
13
19
|
|
|
20
|
+
export interface LabelBox {
|
|
21
|
+
left: number
|
|
22
|
+
right: number
|
|
23
|
+
top: number
|
|
24
|
+
bottom: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A highlight's label, over its band where it fits and beside it where it does
|
|
29
|
+
* not, kept inside `bounds` and out of the way of the labels already placed.
|
|
30
|
+
*
|
|
31
|
+
* `bounds` keeps the label of a band scrolled partly off the left edge visible.
|
|
32
|
+
* With `placed`, a label that would overlap an earlier one, as two
|
|
33
|
+
* single-residue highlights a column apart do, steps down a row.
|
|
34
|
+
*/
|
|
14
35
|
export function drawHighlightLabel({
|
|
15
36
|
ctx,
|
|
16
37
|
theme,
|
|
@@ -18,6 +39,8 @@ export function drawHighlightLabel({
|
|
|
18
39
|
x,
|
|
19
40
|
y,
|
|
20
41
|
spanWidth,
|
|
42
|
+
bounds,
|
|
43
|
+
placed,
|
|
21
44
|
}: {
|
|
22
45
|
ctx: RenderCtx
|
|
23
46
|
theme: Theme
|
|
@@ -25,24 +48,46 @@ export function drawHighlightLabel({
|
|
|
25
48
|
x: number
|
|
26
49
|
y: number
|
|
27
50
|
spanWidth: number
|
|
51
|
+
bounds?: { min: number; max: number }
|
|
52
|
+
placed?: LabelBox[]
|
|
28
53
|
}) {
|
|
29
54
|
setFontSize(ctx, labelFontSize)
|
|
30
55
|
ctx.textAlign = 'start'
|
|
31
56
|
const boxWidth = ctx.measureText(label).width + labelPad * 2
|
|
32
|
-
const boxHeight =
|
|
33
|
-
|
|
57
|
+
const boxHeight = highlightLabelHeight
|
|
58
|
+
let left = boxWidth <= spanWidth ? x : x + spanWidth + 2
|
|
59
|
+
if (bounds) {
|
|
60
|
+
left = Math.max(bounds.min, Math.min(left, bounds.max - boxWidth))
|
|
61
|
+
}
|
|
62
|
+
let top = y
|
|
63
|
+
if (placed) {
|
|
64
|
+
const overlaps = (box: LabelBox) =>
|
|
65
|
+
box.left < left + boxWidth &&
|
|
66
|
+
box.right > left &&
|
|
67
|
+
box.top < top + boxHeight &&
|
|
68
|
+
box.bottom > top
|
|
69
|
+
while (placed.some(overlaps)) {
|
|
70
|
+
top += boxHeight
|
|
71
|
+
}
|
|
72
|
+
placed.push({ left, right: left + boxWidth, top, bottom: top + boxHeight })
|
|
73
|
+
}
|
|
34
74
|
ctx.fillStyle = theme.palette.background.paper
|
|
35
|
-
ctx.fillRect(left,
|
|
75
|
+
ctx.fillRect(left, top, boxWidth, boxHeight)
|
|
36
76
|
ctx.fillStyle = theme.palette.text.primary
|
|
37
|
-
ctx.fillText(label, left + labelPad,
|
|
77
|
+
ctx.fillText(label, left + labelPad, top + labelPad + labelFontSize - 2)
|
|
38
78
|
}
|
|
39
79
|
|
|
40
80
|
/**
|
|
41
|
-
* The persistent
|
|
42
|
-
*
|
|
43
|
-
*
|
|
81
|
+
* The persistent overlay on the alignment: the band behind each clade of
|
|
82
|
+
* `clades`, the `rowTint` encoding's wash, the row tints and bordered column
|
|
83
|
+
* bands of `highlights`, and a label above each band. `offsetX`/`offsetY` are
|
|
84
|
+
* the content coordinates at the canvas origin, the convention renderMSABlock
|
|
44
85
|
* uses, so the live overlay passes -scrollX/-scrollY and the export passes its
|
|
45
86
|
* layout offsets.
|
|
87
|
+
*
|
|
88
|
+
* Rows are culled to the ones this block covers. A tint over every row of a
|
|
89
|
+
* large alignment would otherwise draw the whole column of rects in each block,
|
|
90
|
+
* and again on every pointer move through renderMouseover.
|
|
46
91
|
*/
|
|
47
92
|
export function renderHighlights({
|
|
48
93
|
ctx,
|
|
@@ -61,12 +106,45 @@ export function renderHighlights({
|
|
|
61
106
|
width: number
|
|
62
107
|
height: number
|
|
63
108
|
}) {
|
|
64
|
-
const { resolvedHighlights, colWidth, rowHeight } =
|
|
109
|
+
const { resolvedClades, resolvedHighlights, rowTints, colWidth, rowHeight } =
|
|
110
|
+
model
|
|
111
|
+
const placed: LabelBox[] = []
|
|
65
112
|
ctx.lineWidth = 2
|
|
113
|
+
const firstRow = Math.max(0, Math.floor(offsetY / rowHeight))
|
|
114
|
+
const lastRow = Math.ceil((offsetY + height) / rowHeight)
|
|
115
|
+
const fillRow = (index: number) => {
|
|
116
|
+
ctx.fillRect(0, index * rowHeight - offsetY, width, rowHeight)
|
|
117
|
+
}
|
|
118
|
+
for (const { rows, color, mark } of resolvedClades) {
|
|
119
|
+
if (mark === 'highlight' && rows[1] >= firstRow && rows[0] <= lastRow) {
|
|
120
|
+
ctx.fillStyle = color
|
|
121
|
+
ctx.fillRect(
|
|
122
|
+
0,
|
|
123
|
+
rows[0] * rowHeight - offsetY,
|
|
124
|
+
width,
|
|
125
|
+
(rows[1] - rows[0] + 1) * rowHeight,
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (rowTints) {
|
|
130
|
+
for (
|
|
131
|
+
let index = firstRow;
|
|
132
|
+
index <= Math.min(lastRow, rowTints.length - 1);
|
|
133
|
+
index++
|
|
134
|
+
) {
|
|
135
|
+
const color = rowTints[index]
|
|
136
|
+
if (color) {
|
|
137
|
+
ctx.fillStyle = color
|
|
138
|
+
fillRow(index)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
66
142
|
for (const { rowIndices, color } of resolvedHighlights) {
|
|
67
143
|
ctx.fillStyle = color ?? highlightRowFill
|
|
68
144
|
for (const index of rowIndices) {
|
|
69
|
-
|
|
145
|
+
if (index >= firstRow && index <= lastRow) {
|
|
146
|
+
fillRow(index)
|
|
147
|
+
}
|
|
70
148
|
}
|
|
71
149
|
}
|
|
72
150
|
for (const { startCol, endCol, label, color } of resolvedHighlights) {
|
|
@@ -80,7 +158,60 @@ export function renderHighlights({
|
|
|
80
158
|
ctx.strokeStyle = color ?? highlightBorder
|
|
81
159
|
ctx.strokeRect(x, 0, spanWidth, height)
|
|
82
160
|
if (label) {
|
|
83
|
-
drawHighlightLabel({
|
|
161
|
+
drawHighlightLabel({
|
|
162
|
+
ctx,
|
|
163
|
+
theme,
|
|
164
|
+
label,
|
|
165
|
+
x,
|
|
166
|
+
y: 0,
|
|
167
|
+
spanWidth,
|
|
168
|
+
bounds: { min: 0, max: width },
|
|
169
|
+
placed,
|
|
170
|
+
})
|
|
84
171
|
}
|
|
85
172
|
}
|
|
86
173
|
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* The overlay parts that come from the snapshot: the reference row's tint, a
|
|
177
|
+
* bordered band per run of highlighted columns, and the `highlights` layer. The
|
|
178
|
+
* live overlay draws these under its hover and click bands; the SVG export
|
|
179
|
+
* draws only these.
|
|
180
|
+
*/
|
|
181
|
+
export function renderPersistentHighlights({
|
|
182
|
+
ctx,
|
|
183
|
+
model,
|
|
184
|
+
theme,
|
|
185
|
+
offsetX,
|
|
186
|
+
offsetY,
|
|
187
|
+
width,
|
|
188
|
+
height,
|
|
189
|
+
}: {
|
|
190
|
+
ctx: RenderCtx
|
|
191
|
+
model: MsaViewModel
|
|
192
|
+
theme: Theme
|
|
193
|
+
offsetX: number
|
|
194
|
+
offsetY: number
|
|
195
|
+
width: number
|
|
196
|
+
height: number
|
|
197
|
+
}) {
|
|
198
|
+
const { colWidth, rowHeight, referenceRowIndex, highlightedColumnRuns } =
|
|
199
|
+
model
|
|
200
|
+
|
|
201
|
+
if (referenceRowIndex !== undefined) {
|
|
202
|
+
ctx.fillStyle = referenceColor
|
|
203
|
+
ctx.fillRect(0, referenceRowIndex * rowHeight - offsetY, width, rowHeight)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
ctx.lineWidth = 2
|
|
207
|
+
for (const { start, end } of highlightedColumnRuns) {
|
|
208
|
+
const x = start * colWidth - offsetX
|
|
209
|
+
const w = (end - start + 1) * colWidth
|
|
210
|
+
ctx.fillStyle = highlightFill
|
|
211
|
+
ctx.fillRect(x, 0, w, height)
|
|
212
|
+
ctx.strokeStyle = highlightBorder
|
|
213
|
+
ctx.strokeRect(x, 0, w, height)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
renderHighlights({ ctx, model, theme, offsetX, offsetY, width, height })
|
|
217
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { setFontSize } from '../../setFontSize.ts'
|
|
2
|
-
import { adjustColorForContrast } from '../../util.ts'
|
|
2
|
+
import { adjustColorForContrast, contrastTextFn } from '../../util.ts'
|
|
3
3
|
import { getVisibleLeaves } from '../getVisibleLeaves.ts'
|
|
4
4
|
import { domainBandCursor } from './domainBandCursor.ts'
|
|
5
5
|
import { tileColorFn } from './tileColor.ts'
|
|
@@ -15,7 +15,6 @@ export function renderMSABlock({
|
|
|
15
15
|
model,
|
|
16
16
|
offsetX,
|
|
17
17
|
offsetY,
|
|
18
|
-
contrastScheme,
|
|
19
18
|
ctx,
|
|
20
19
|
theme,
|
|
21
20
|
highResScaleFactorOverride,
|
|
@@ -27,7 +26,6 @@ export function renderMSABlock({
|
|
|
27
26
|
offsetY: number
|
|
28
27
|
theme: Theme
|
|
29
28
|
model: MsaViewModel
|
|
30
|
-
contrastScheme: Record<string, string>
|
|
31
29
|
ctx: RenderCtx
|
|
32
30
|
highResScaleFactorOverride?: number
|
|
33
31
|
blockSizeXOverride?: number
|
|
@@ -68,7 +66,6 @@ export function renderMSABlock({
|
|
|
68
66
|
model,
|
|
69
67
|
ctx,
|
|
70
68
|
theme,
|
|
71
|
-
contrastScheme,
|
|
72
69
|
xStart,
|
|
73
70
|
xEnd,
|
|
74
71
|
visibleLeaves,
|
|
@@ -90,23 +87,10 @@ export function renderMSABlock({
|
|
|
90
87
|
ctx.resetTransform()
|
|
91
88
|
}
|
|
92
89
|
|
|
93
|
-
// Letter color to use over a domain box, keyed by accession. Domain fills come
|
|
94
|
-
// from a categorical palette that has no fixed lightness, so ask the theme for a
|
|
95
|
-
// readable text color per fill instead of assuming dark-on-light.
|
|
96
|
-
function domainLetterColors(model: MsaViewModel, theme: Theme) {
|
|
97
|
-
return new Map(
|
|
98
|
-
Object.entries(model.fillPalette).map(([accession, fill]) => [
|
|
99
|
-
accession,
|
|
100
|
-
theme.palette.getContrastText(fill),
|
|
101
|
-
]),
|
|
102
|
-
)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
90
|
function drawTilesAndText({
|
|
106
91
|
model,
|
|
107
92
|
ctx,
|
|
108
93
|
theme,
|
|
109
|
-
contrastScheme,
|
|
110
94
|
visibleLeaves,
|
|
111
95
|
xStart,
|
|
112
96
|
xEnd,
|
|
@@ -117,7 +101,6 @@ function drawTilesAndText({
|
|
|
117
101
|
model: MsaViewModel
|
|
118
102
|
theme: Theme
|
|
119
103
|
ctx: RenderCtx
|
|
120
|
-
contrastScheme: Record<string, string>
|
|
121
104
|
visibleLeaves: HierarchyNode<NodeWithIdsAndLength>[]
|
|
122
105
|
xStart: number
|
|
123
106
|
xEnd: number
|
|
@@ -133,27 +116,30 @@ function drawTilesAndText({
|
|
|
133
116
|
relativeTo,
|
|
134
117
|
showMsaLetters,
|
|
135
118
|
subFeatureRows,
|
|
119
|
+
domainUnderline,
|
|
136
120
|
domainBandsByStart,
|
|
137
121
|
} = model
|
|
138
122
|
|
|
139
123
|
const tiles = drawTiles && bgColor
|
|
140
124
|
const paintTiles = tiles && !rasterTiles
|
|
141
125
|
if (paintTiles || showMsaLetters) {
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
const needsColor = paintTiles ||
|
|
126
|
+
// a letter takes its color from the cell it lands on, so the scheme lookup
|
|
127
|
+
// is only waste when nothing draws letters
|
|
128
|
+
const needsColor = paintTiles || showMsaLetters
|
|
145
129
|
const tileColor = tileColorFn(model)
|
|
130
|
+
// Domain fills come from a categorical palette with no fixed lightness, and
|
|
131
|
+
// a dynamic scheme colors a cell from its column, so a readable letter color
|
|
132
|
+
// is a question about the cell's own color rather than about its letter.
|
|
133
|
+
const contrastText = contrastTextFn(theme)
|
|
146
134
|
const offsetXAligned = xStart * colWidth
|
|
147
135
|
const halfColWidth = colWidth / 2
|
|
148
136
|
// note: -rowHeight/4 matches +rowHeight/4 in tree
|
|
149
137
|
const quarterRowHeight = rowHeight / 4
|
|
150
138
|
// with the tiles coming from the domain overlay instead, letters sit either
|
|
151
139
|
// on a domain box or on the plain background; sub-row layout stacks the boxes
|
|
152
|
-
// above the letters
|
|
153
|
-
|
|
154
|
-
const
|
|
155
|
-
? domainLetterColors(model, theme)
|
|
156
|
-
: undefined
|
|
140
|
+
// above the letters and letter-color mode shrinks them to a bar under the
|
|
141
|
+
// row, so neither leaves anything behind a letter
|
|
142
|
+
const overDomains = !drawTiles && !subFeatureRows && !domainUnderline
|
|
157
143
|
|
|
158
144
|
for (let i = 0, l1 = visibleLeaves.length; i < l1; i++) {
|
|
159
145
|
const node = visibleLeaves[i]!
|
|
@@ -186,18 +172,23 @@ function drawTilesAndText({
|
|
|
186
172
|
const covering = bandAt(col)
|
|
187
173
|
ctx.fillStyle = covering
|
|
188
174
|
? // on top of a domain box: contrast against the box fill
|
|
189
|
-
|
|
190
|
-
:
|
|
191
|
-
? // on
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
175
|
+
contrastText(model.fillPalette[covering.annotation.accession])
|
|
176
|
+
: isMatchingReference
|
|
177
|
+
? // the dot sits on the faint reference-match wash, which is
|
|
178
|
+
// the theme's background with a little of its text color in it
|
|
179
|
+
theme.palette.text.primary
|
|
180
|
+
: tiles
|
|
181
|
+
? // on top of a colored tile, or on the background where the
|
|
182
|
+
// scheme gives that cell no color
|
|
183
|
+
contrastText(color)
|
|
184
|
+
: bgColor || !color
|
|
185
|
+
? // plain background, uncolored letters
|
|
186
|
+
theme.palette.text.primary
|
|
187
|
+
: // letter-color mode: darken/lighten to stay readable
|
|
188
|
+
adjustColorForContrast(
|
|
189
|
+
color,
|
|
190
|
+
theme.palette.background.default,
|
|
191
|
+
)
|
|
201
192
|
ctx.fillText(
|
|
202
193
|
isMatchingReference ? '.' : letter,
|
|
203
194
|
x + halfColWidth,
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
hoverColor,
|
|
4
|
-
multiRowHoverColor,
|
|
5
|
-
referenceColor,
|
|
6
|
-
} from '../overlayColors.ts'
|
|
7
|
-
import { renderHighlights } from './renderHighlights.ts'
|
|
1
|
+
import { clickColor, hoverColor, multiRowHoverColor } from '../overlayColors.ts'
|
|
2
|
+
import { renderPersistentHighlights } from './renderHighlights.ts'
|
|
8
3
|
|
|
9
4
|
import type { MsaViewModel } from '../../model.ts'
|
|
10
5
|
import type { Theme } from '@mui/material'
|
|
11
6
|
|
|
12
|
-
// the persistent highlightColumns overlay: a stronger fill plus a solid border
|
|
13
|
-
// so a domain/motif band reads clearly over the colored alignment cells (the
|
|
14
|
-
// faint hover-style wash alone is invisible against clustalx coloring)
|
|
15
|
-
const highlightColumnsFill = 'rgba(255,140,0,0.28)'
|
|
16
|
-
const highlightColumnsBorder = 'rgba(210,90,0,0.95)'
|
|
17
|
-
|
|
18
7
|
export function renderMouseover({
|
|
19
8
|
ctx,
|
|
20
9
|
model,
|
|
@@ -36,9 +25,7 @@ export function renderMouseover({
|
|
|
36
25
|
mouseClickRow,
|
|
37
26
|
mouseClickCol,
|
|
38
27
|
highResScaleFactor,
|
|
39
|
-
referenceRowIndex,
|
|
40
28
|
hoveredRowIndices,
|
|
41
|
-
highlightedColumnRuns,
|
|
42
29
|
} = model
|
|
43
30
|
ctx.resetTransform()
|
|
44
31
|
ctx.clearRect(0, 0, width * highResScaleFactor, height * highResScaleFactor)
|
|
@@ -53,30 +40,7 @@ export function renderMouseover({
|
|
|
53
40
|
ctx.fillRect(index * colWidth + scrollX, 0, colWidth, height)
|
|
54
41
|
}
|
|
55
42
|
|
|
56
|
-
|
|
57
|
-
// tree node
|
|
58
|
-
if (referenceRowIndex !== undefined) {
|
|
59
|
-
ctx.fillStyle = referenceColor
|
|
60
|
-
rowBand(referenceRowIndex)
|
|
61
|
-
}
|
|
62
|
-
ctx.fillStyle = multiRowHoverColor
|
|
63
|
-
for (const rowIndex of hoveredRowIndices) {
|
|
64
|
-
rowBand(rowIndex)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// each contiguous run of highlighted columns draws as one filled, bordered
|
|
68
|
-
// band, so a domain/motif highlight stays visible over the alignment
|
|
69
|
-
ctx.lineWidth = 2
|
|
70
|
-
for (const { start, end } of highlightedColumnRuns) {
|
|
71
|
-
const x = start * colWidth + scrollX
|
|
72
|
-
const w = (end - start + 1) * colWidth
|
|
73
|
-
ctx.fillStyle = highlightColumnsFill
|
|
74
|
-
ctx.fillRect(x, 0, w, height)
|
|
75
|
-
ctx.strokeStyle = highlightColumnsBorder
|
|
76
|
-
ctx.strokeRect(x, 0, w, height)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
renderHighlights({
|
|
43
|
+
renderPersistentHighlights({
|
|
80
44
|
ctx,
|
|
81
45
|
model,
|
|
82
46
|
theme,
|
|
@@ -86,6 +50,12 @@ export function renderMouseover({
|
|
|
86
50
|
height,
|
|
87
51
|
})
|
|
88
52
|
|
|
53
|
+
// every tip under a hovered tree node stays lit
|
|
54
|
+
ctx.fillStyle = multiRowHoverColor
|
|
55
|
+
for (const rowIndex of hoveredRowIndices) {
|
|
56
|
+
rowBand(rowIndex)
|
|
57
|
+
}
|
|
58
|
+
|
|
89
59
|
ctx.fillStyle = hoverColor
|
|
90
60
|
if (mouseCol !== undefined) {
|
|
91
61
|
colBand(mouseCol)
|