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,18 +1,41 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react'
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
import { createJBrowseTheme } from '@jbrowse/core/ui/theme'
|
|
4
4
|
import useMeasure from '@jbrowse/core/util/useMeasure'
|
|
5
|
+
import { destroy, isAlive } from '@jbrowse/mobx-state-tree'
|
|
5
6
|
import { ThemeProvider } from '@mui/material/styles'
|
|
7
|
+
import { compareStructural, reaction, when } from 'mobx'
|
|
6
8
|
|
|
7
9
|
import MSAModelF from '../model.ts'
|
|
8
10
|
import Loading from './Loading.tsx'
|
|
9
11
|
|
|
10
|
-
import type {
|
|
12
|
+
import type { MsaViewModel } from '../model.ts'
|
|
13
|
+
import type {
|
|
14
|
+
Cell,
|
|
15
|
+
Clade,
|
|
16
|
+
ColumnTrackSpec,
|
|
17
|
+
Encoding,
|
|
18
|
+
Highlight,
|
|
19
|
+
Region,
|
|
20
|
+
ResidueEncoding,
|
|
21
|
+
ResidueMapping,
|
|
22
|
+
RowPanelSpec,
|
|
23
|
+
Viewport,
|
|
24
|
+
} from '../types.ts'
|
|
11
25
|
import type { FileLocation as FileLocationType } from '@jbrowse/core/util/types'
|
|
26
|
+
import type { ThemeOptions } from '@mui/material/styles'
|
|
12
27
|
|
|
13
|
-
|
|
28
|
+
function resolveTheme(theme: MSAViewerProps['theme']) {
|
|
29
|
+
return createJBrowseTheme(
|
|
30
|
+
theme === 'dark'
|
|
31
|
+
? { palette: { mode: 'dark' } }
|
|
32
|
+
: typeof theme === 'object'
|
|
33
|
+
? theme
|
|
34
|
+
: undefined,
|
|
35
|
+
)
|
|
36
|
+
}
|
|
14
37
|
|
|
15
|
-
interface MSAViewerProps {
|
|
38
|
+
export interface MSAViewerProps {
|
|
16
39
|
msa?: string
|
|
17
40
|
tree?: string
|
|
18
41
|
gff?: string
|
|
@@ -25,6 +48,10 @@ interface MSAViewerProps {
|
|
|
25
48
|
colWidth?: number
|
|
26
49
|
/** initial per-row pixel height */
|
|
27
50
|
rowHeight?: number
|
|
51
|
+
/**
|
|
52
|
+
* hide columns at least this percent gaps (default 100, i.e. hide nothing)
|
|
53
|
+
*/
|
|
54
|
+
allowedGappyness?: number
|
|
28
55
|
/** alignment columns (0-based) to highlight with a persistent overlay */
|
|
29
56
|
highlightColumns?: number[]
|
|
30
57
|
/**
|
|
@@ -33,19 +60,136 @@ interface MSAViewerProps {
|
|
|
33
60
|
* for whole rows, each with an optional `label` and `color`
|
|
34
61
|
*/
|
|
35
62
|
highlights?: Highlight[]
|
|
63
|
+
/**
|
|
64
|
+
* clades of the tree with a mark drawn over them: `{mrca, tips, mark}` or
|
|
65
|
+
* `{range, tips, mark}`, where `mark` is `highlight`, `bracket`, `collapse`
|
|
66
|
+
* or `focus` (see docs/layers.md)
|
|
67
|
+
*/
|
|
68
|
+
clades?: Clade[]
|
|
36
69
|
/** row name to diff every other row against (matches render as ".") */
|
|
37
70
|
relativeTo?: string
|
|
38
71
|
/** tracks supplied as data: per-column bar values or a text row (see docs/layers.md) */
|
|
39
72
|
columnTracks?: ColumnTrackSpec[]
|
|
73
|
+
/** which residue of which structure each row's residues are (see docs/layers.md) */
|
|
74
|
+
residueMappings?: ResidueMapping[]
|
|
75
|
+
/** extra fields per row name, such as a lineage or a host (see docs/layers.md) */
|
|
76
|
+
rowData?: Record<string, Record<string, string>>
|
|
77
|
+
/**
|
|
78
|
+
* what the viewer's marks read from a table: `{channel, field, scale?}`,
|
|
79
|
+
* where `channel` is `tipLabel`, `rowTint` or `branch` over `rowData`, or
|
|
80
|
+
* `featureFill` or `featureLabel` over the annotations (see docs/layers.md)
|
|
81
|
+
*/
|
|
82
|
+
encodings?: Encoding[]
|
|
83
|
+
/**
|
|
84
|
+
* panels between the tree and the alignment, one cell per row:
|
|
85
|
+
* `{kind: 'strip', field, scale?, width?, header?}` colors each row by a
|
|
86
|
+
* `rowData` field (see docs/layers.md)
|
|
87
|
+
*/
|
|
88
|
+
rowPanels?: RowPanelSpec[]
|
|
40
89
|
/** draw the phylogenetic tree (default true); false leaves a labels-only gutter */
|
|
41
90
|
drawTree?: boolean
|
|
42
91
|
/** fixed width (px) of the tree/label area */
|
|
43
92
|
treeAreaWidth?: number
|
|
44
93
|
/** auto-size the tree/label area to the labels (used when drawTree is false) */
|
|
45
94
|
autoTreeAreaWidth?: boolean
|
|
95
|
+
/** draw branch lengths (default true); false draws a cladogram */
|
|
96
|
+
showBranchLen?: boolean
|
|
97
|
+
/**
|
|
98
|
+
* which channel `colorScheme` paints: `fill` (default) colors the background
|
|
99
|
+
* of the cell a residue sits in, `color` colors the letter itself and leaves
|
|
100
|
+
* the background plain, which lets a domain overlay mark each span with a bar
|
|
101
|
+
* under the row and the residue colors show through
|
|
102
|
+
*/
|
|
103
|
+
residueEncoding?: ResidueEncoding
|
|
104
|
+
/**
|
|
105
|
+
* a span to zoom and scroll to once the alignment loads, and again whenever
|
|
106
|
+
* it changes: `{row, start, end}` in residues of that row, or `{start, end}`
|
|
107
|
+
* in columns, 1-based and inclusive
|
|
108
|
+
*/
|
|
109
|
+
region?: Region
|
|
110
|
+
/** leave out the toolbar, for a page drawing its own controls */
|
|
111
|
+
hideHeader?: boolean
|
|
112
|
+
/**
|
|
113
|
+
* 'light' (default), 'dark', or MUI theme options (palette, typography)
|
|
114
|
+
* merged over the JBrowse theme
|
|
115
|
+
*/
|
|
116
|
+
theme?: 'light' | 'dark' | ThemeOptions
|
|
117
|
+
/** the cell under the pointer, or undefined when it leaves the alignment */
|
|
118
|
+
onCellHover?: (cell: Cell | undefined) => void
|
|
119
|
+
/** the cell a click pinned, or undefined when a click clears it */
|
|
120
|
+
onCellClick?: (cell: Cell | undefined) => void
|
|
121
|
+
/** the alignment columns on screen, after every scroll, zoom and resize */
|
|
122
|
+
onViewportChange?: (viewport: Viewport | undefined) => void
|
|
123
|
+
/**
|
|
124
|
+
* the model the viewer built, for the model API; called again with the new
|
|
125
|
+
* model when msa, tree, gff or a filehandle changes
|
|
126
|
+
*/
|
|
127
|
+
onModel?: (model: MsaViewModel) => void
|
|
46
128
|
}
|
|
47
129
|
|
|
48
|
-
|
|
130
|
+
type DataSource = Pick<
|
|
131
|
+
MSAViewerProps,
|
|
132
|
+
'msa' | 'tree' | 'gff' | 'msaFilehandle' | 'treeFilehandle' | 'gffFilehandle'
|
|
133
|
+
>
|
|
134
|
+
|
|
135
|
+
function sameSource(a: DataSource, b: DataSource) {
|
|
136
|
+
return (
|
|
137
|
+
a.msa === b.msa &&
|
|
138
|
+
a.tree === b.tree &&
|
|
139
|
+
a.gff === b.gff &&
|
|
140
|
+
JSON.stringify([a.msaFilehandle, a.treeFilehandle, a.gffFilehandle]) ===
|
|
141
|
+
JSON.stringify([b.msaFilehandle, b.treeFilehandle, b.gffFilehandle])
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A new alignment, tree or annotation file needs a new model, so the viewer
|
|
147
|
+
* remounts when one of those props changes and keeps its model across every
|
|
148
|
+
* other change.
|
|
149
|
+
*/
|
|
150
|
+
export default function MSAViewer(props: MSAViewerProps) {
|
|
151
|
+
const { msa, tree, gff, msaFilehandle, treeFilehandle, gffFilehandle } = props
|
|
152
|
+
const source = {
|
|
153
|
+
msa,
|
|
154
|
+
tree,
|
|
155
|
+
gff,
|
|
156
|
+
msaFilehandle,
|
|
157
|
+
treeFilehandle,
|
|
158
|
+
gffFilehandle,
|
|
159
|
+
}
|
|
160
|
+
const [shown, setShown] = useState({ source, generation: 0 })
|
|
161
|
+
if (!sameSource(shown.source, source)) {
|
|
162
|
+
setShown({ source, generation: shown.generation + 1 })
|
|
163
|
+
}
|
|
164
|
+
return <Viewer key={shown.generation} {...props} />
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function useModelReaction<K extends 'hoveredCell' | 'clickedCell' | 'viewport'>(
|
|
168
|
+
model: MsaViewModel,
|
|
169
|
+
key: K,
|
|
170
|
+
handler: ((value: MsaViewModel[K]) => void) | undefined,
|
|
171
|
+
) {
|
|
172
|
+
const latest = useRef(handler)
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
latest.current = handler
|
|
175
|
+
})
|
|
176
|
+
const listening = !!handler
|
|
177
|
+
useEffect(
|
|
178
|
+
() =>
|
|
179
|
+
listening
|
|
180
|
+
? reaction(
|
|
181
|
+
() => model[key],
|
|
182
|
+
value => {
|
|
183
|
+
latest.current?.(value)
|
|
184
|
+
},
|
|
185
|
+
{ equals: compareStructural },
|
|
186
|
+
)
|
|
187
|
+
: undefined,
|
|
188
|
+
[model, key, listening],
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function Viewer({
|
|
49
193
|
msa,
|
|
50
194
|
tree,
|
|
51
195
|
gff,
|
|
@@ -56,21 +200,43 @@ export default function MSAViewer({
|
|
|
56
200
|
height,
|
|
57
201
|
colWidth,
|
|
58
202
|
rowHeight,
|
|
203
|
+
allowedGappyness,
|
|
59
204
|
highlightColumns,
|
|
60
205
|
highlights,
|
|
206
|
+
clades,
|
|
61
207
|
relativeTo,
|
|
62
208
|
columnTracks,
|
|
209
|
+
residueMappings,
|
|
210
|
+
rowData,
|
|
211
|
+
encodings,
|
|
212
|
+
rowPanels,
|
|
63
213
|
drawTree,
|
|
214
|
+
residueEncoding,
|
|
64
215
|
treeAreaWidth,
|
|
65
216
|
autoTreeAreaWidth,
|
|
217
|
+
showBranchLen,
|
|
218
|
+
region,
|
|
219
|
+
hideHeader,
|
|
220
|
+
theme,
|
|
221
|
+
onCellHover,
|
|
222
|
+
onCellClick,
|
|
223
|
+
onViewportChange,
|
|
224
|
+
onModel,
|
|
66
225
|
}: MSAViewerProps) {
|
|
67
|
-
// lazy initializer: the model is created exactly once from the initial props
|
|
68
|
-
// (a stable MST instance — not a value safe to recompute, so not useMemo)
|
|
69
226
|
const [model] = useState(() =>
|
|
70
227
|
MSAModelF().create({
|
|
71
228
|
type: 'MsaView',
|
|
72
|
-
...(msa || tree || gff
|
|
73
|
-
? {
|
|
229
|
+
...(msa || tree || gff || rowData
|
|
230
|
+
? {
|
|
231
|
+
data: {
|
|
232
|
+
msa: msa ?? '',
|
|
233
|
+
tree: tree ?? '',
|
|
234
|
+
gff,
|
|
235
|
+
// the row table is stored as this JSON string, which is what a
|
|
236
|
+
// shared URL and the size limit already cover
|
|
237
|
+
...(rowData ? { treeMetadata: JSON.stringify(rowData) } : {}),
|
|
238
|
+
},
|
|
239
|
+
}
|
|
74
240
|
: {}),
|
|
75
241
|
...(msaFilehandle ? { msaFilehandle } : {}),
|
|
76
242
|
...(treeFilehandle ? { treeFilehandle } : {}),
|
|
@@ -79,16 +245,29 @@ export default function MSAViewer({
|
|
|
79
245
|
...(height ? { height } : {}),
|
|
80
246
|
...(colWidth ? { colWidth } : {}),
|
|
81
247
|
...(rowHeight ? { rowHeight } : {}),
|
|
248
|
+
...(allowedGappyness !== undefined ? { allowedGappyness } : {}),
|
|
82
249
|
...(highlightColumns ? { highlightColumns } : {}),
|
|
83
250
|
...(highlights ? { highlights } : {}),
|
|
251
|
+
...(clades ? { clades } : {}),
|
|
84
252
|
...(relativeTo ? { relativeTo } : {}),
|
|
85
253
|
...(columnTracks ? { columnTracks } : {}),
|
|
254
|
+
...(residueMappings ? { residueMappings } : {}),
|
|
255
|
+
...(encodings ? { encodings } : {}),
|
|
256
|
+
...(rowPanels ? { rowPanels } : {}),
|
|
86
257
|
...(drawTree !== undefined ? { drawTree } : {}),
|
|
87
258
|
...(treeAreaWidth ? { treeAreaWidth } : {}),
|
|
88
259
|
...(autoTreeAreaWidth ? { autoTreeAreaWidth } : {}),
|
|
260
|
+
...(showBranchLen !== undefined ? { showBranchLen } : {}),
|
|
261
|
+
...(residueEncoding !== undefined
|
|
262
|
+
? { bgColor: residueEncoding === 'fill' }
|
|
263
|
+
: {}),
|
|
89
264
|
}),
|
|
90
265
|
)
|
|
91
266
|
|
|
267
|
+
const destroyTimer = useRef<ReturnType<typeof setTimeout> | undefined>(
|
|
268
|
+
undefined,
|
|
269
|
+
)
|
|
270
|
+
|
|
92
271
|
const [ref, { width }] = useMeasure()
|
|
93
272
|
useEffect(() => {
|
|
94
273
|
if (width) {
|
|
@@ -96,8 +275,145 @@ export default function MSAViewer({
|
|
|
96
275
|
}
|
|
97
276
|
}, [model, width])
|
|
98
277
|
|
|
278
|
+
// Each effect depends only on its own prop, so a change made inside the
|
|
279
|
+
// viewer survives the host's next render.
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
if (height !== undefined) {
|
|
282
|
+
model.setHeight(height)
|
|
283
|
+
}
|
|
284
|
+
}, [model, height])
|
|
285
|
+
useEffect(() => {
|
|
286
|
+
if (colorScheme !== undefined) {
|
|
287
|
+
model.setColorSchemeName(colorScheme)
|
|
288
|
+
}
|
|
289
|
+
}, [model, colorScheme])
|
|
290
|
+
useEffect(() => {
|
|
291
|
+
if (colWidth !== undefined) {
|
|
292
|
+
model.setColWidth(colWidth)
|
|
293
|
+
}
|
|
294
|
+
}, [model, colWidth])
|
|
295
|
+
useEffect(() => {
|
|
296
|
+
if (rowHeight !== undefined) {
|
|
297
|
+
model.setRowHeight(rowHeight)
|
|
298
|
+
}
|
|
299
|
+
}, [model, rowHeight])
|
|
300
|
+
useEffect(() => {
|
|
301
|
+
if (allowedGappyness !== undefined) {
|
|
302
|
+
model.setAllowedGappyness(allowedGappyness)
|
|
303
|
+
}
|
|
304
|
+
}, [model, allowedGappyness])
|
|
305
|
+
useEffect(() => {
|
|
306
|
+
if (drawTree !== undefined) {
|
|
307
|
+
model.setDrawTree(drawTree)
|
|
308
|
+
}
|
|
309
|
+
}, [model, drawTree])
|
|
310
|
+
useEffect(() => {
|
|
311
|
+
if (treeAreaWidth !== undefined) {
|
|
312
|
+
model.setTreeAreaWidth(treeAreaWidth)
|
|
313
|
+
}
|
|
314
|
+
}, [model, treeAreaWidth])
|
|
315
|
+
useEffect(() => {
|
|
316
|
+
if (showBranchLen !== undefined) {
|
|
317
|
+
model.setShowBranchLen(showBranchLen)
|
|
318
|
+
}
|
|
319
|
+
}, [model, showBranchLen])
|
|
320
|
+
useEffect(() => {
|
|
321
|
+
if (residueEncoding !== undefined) {
|
|
322
|
+
model.setBgColor(residueEncoding === 'fill')
|
|
323
|
+
}
|
|
324
|
+
}, [model, residueEncoding])
|
|
325
|
+
useEffect(() => {
|
|
326
|
+
model.setHideHeader(!!hideHeader)
|
|
327
|
+
}, [model, hideHeader])
|
|
328
|
+
// unguarded, so removing the prop turns the reference diff off
|
|
329
|
+
useEffect(() => {
|
|
330
|
+
model.drawRelativeTo(relativeTo)
|
|
331
|
+
}, [model, relativeTo])
|
|
332
|
+
|
|
333
|
+
// keyed by content, since a host computing a layer inline passes a new array
|
|
334
|
+
// on every render
|
|
335
|
+
const highlightsKey = JSON.stringify(highlights ?? [])
|
|
336
|
+
useEffect(() => {
|
|
337
|
+
model.setHighlights(JSON.parse(highlightsKey))
|
|
338
|
+
}, [model, highlightsKey])
|
|
339
|
+
const cladesKey = JSON.stringify(clades ?? [])
|
|
340
|
+
useEffect(() => {
|
|
341
|
+
model.setClades(JSON.parse(cladesKey))
|
|
342
|
+
}, [model, cladesKey])
|
|
343
|
+
const columnTracksKey = JSON.stringify(columnTracks ?? [])
|
|
344
|
+
useEffect(() => {
|
|
345
|
+
model.setColumnTracks(JSON.parse(columnTracksKey))
|
|
346
|
+
}, [model, columnTracksKey])
|
|
347
|
+
const residueMappingsKey = JSON.stringify(residueMappings ?? [])
|
|
348
|
+
useEffect(() => {
|
|
349
|
+
model.setResidueMappings(JSON.parse(residueMappingsKey))
|
|
350
|
+
}, [model, residueMappingsKey])
|
|
351
|
+
const rowDataKey = JSON.stringify(rowData ?? {})
|
|
352
|
+
useEffect(() => {
|
|
353
|
+
const table = JSON.parse(rowDataKey)
|
|
354
|
+
// an empty table leaves whatever the snapshot or a filehandle loaded
|
|
355
|
+
if (Object.keys(table).length) {
|
|
356
|
+
model.setRowData(table)
|
|
357
|
+
}
|
|
358
|
+
}, [model, rowDataKey])
|
|
359
|
+
const encodingsKey = JSON.stringify(encodings ?? [])
|
|
360
|
+
useEffect(() => {
|
|
361
|
+
model.setEncodings(JSON.parse(encodingsKey))
|
|
362
|
+
}, [model, encodingsKey])
|
|
363
|
+
const rowPanelsKey = JSON.stringify(rowPanels ?? [])
|
|
364
|
+
useEffect(() => {
|
|
365
|
+
model.setRowPanels(JSON.parse(rowPanelsKey))
|
|
366
|
+
}, [model, rowPanelsKey])
|
|
367
|
+
const highlightColumnsKey = JSON.stringify(highlightColumns ?? null)
|
|
368
|
+
useEffect(() => {
|
|
369
|
+
model.setHighlightedColumns(JSON.parse(highlightColumnsKey) ?? undefined)
|
|
370
|
+
}, [model, highlightColumnsKey])
|
|
371
|
+
|
|
372
|
+
const regionKey = JSON.stringify(region ?? null)
|
|
373
|
+
useEffect(() => {
|
|
374
|
+
const target = JSON.parse(regionKey) as Region | null
|
|
375
|
+
return target
|
|
376
|
+
? when(
|
|
377
|
+
() => model.viewInitialized && model.numColumns > 0,
|
|
378
|
+
() => {
|
|
379
|
+
model.zoomToRegion(target)
|
|
380
|
+
},
|
|
381
|
+
)
|
|
382
|
+
: undefined
|
|
383
|
+
}, [model, regionKey])
|
|
384
|
+
|
|
385
|
+
useModelReaction(model, 'hoveredCell', onCellHover)
|
|
386
|
+
useModelReaction(model, 'clickedCell', onCellClick)
|
|
387
|
+
useModelReaction(model, 'viewport', onViewportChange)
|
|
388
|
+
|
|
389
|
+
const latestOnModel = useRef(onModel)
|
|
390
|
+
useEffect(() => {
|
|
391
|
+
latestOnModel.current = onModel
|
|
392
|
+
})
|
|
393
|
+
useEffect(() => {
|
|
394
|
+
latestOnModel.current?.(model)
|
|
395
|
+
}, [model])
|
|
396
|
+
|
|
397
|
+
// destroy releases the model's matchMedia listener and fetches. It waits a
|
|
398
|
+
// tick because StrictMode remounts with the same state, and the remount's
|
|
399
|
+
// effect cancels it.
|
|
400
|
+
useEffect(() => {
|
|
401
|
+
if (destroyTimer.current !== undefined) {
|
|
402
|
+
clearTimeout(destroyTimer.current)
|
|
403
|
+
destroyTimer.current = undefined
|
|
404
|
+
}
|
|
405
|
+
return () => {
|
|
406
|
+
destroyTimer.current = setTimeout(() => {
|
|
407
|
+
destroyTimer.current = undefined
|
|
408
|
+
if (isAlive(model)) {
|
|
409
|
+
destroy(model)
|
|
410
|
+
}
|
|
411
|
+
})
|
|
412
|
+
}
|
|
413
|
+
}, [model])
|
|
414
|
+
|
|
99
415
|
return (
|
|
100
|
-
<ThemeProvider theme={theme}>
|
|
416
|
+
<ThemeProvider theme={resolveTheme(theme)}>
|
|
101
417
|
<div ref={ref}>
|
|
102
418
|
<Loading model={model} />
|
|
103
419
|
</div>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react'
|
|
4
|
+
import { createPortal } from 'react-dom'
|
|
5
|
+
|
|
6
|
+
const useStyles = makeStyles()(theme => ({
|
|
7
|
+
tooltip: {
|
|
8
|
+
position: 'fixed',
|
|
9
|
+
pointerEvents: 'none',
|
|
10
|
+
zIndex: 10000,
|
|
11
|
+
backgroundColor: theme.palette.grey[700],
|
|
12
|
+
color: theme.palette.common.white,
|
|
13
|
+
padding: '4px 8px',
|
|
14
|
+
borderRadius: 4,
|
|
15
|
+
fontSize: 12,
|
|
16
|
+
whiteSpace: 'nowrap',
|
|
17
|
+
maxWidth: 300,
|
|
18
|
+
overflow: 'hidden',
|
|
19
|
+
textOverflow: 'ellipsis',
|
|
20
|
+
},
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A tooltip beside the pointer, portaled to the body. A panel's scroll
|
|
25
|
+
* transform is a containing block, so a fixed tooltip left inside it would
|
|
26
|
+
* position against the scrolled content instead of the window.
|
|
27
|
+
*/
|
|
28
|
+
export default function PortalTooltip({
|
|
29
|
+
clientX,
|
|
30
|
+
clientY,
|
|
31
|
+
children,
|
|
32
|
+
}: {
|
|
33
|
+
clientX: number
|
|
34
|
+
clientY: number
|
|
35
|
+
children: React.ReactNode
|
|
36
|
+
}) {
|
|
37
|
+
const { classes } = useStyles()
|
|
38
|
+
return createPortal(
|
|
39
|
+
<div
|
|
40
|
+
className={classes.tooltip}
|
|
41
|
+
style={{ left: clientX + 12, top: clientY + 12 }}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
</div>,
|
|
45
|
+
document.body,
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react'
|
|
|
5
5
|
import DragHandle from './DragHandle.tsx'
|
|
6
6
|
|
|
7
7
|
import type { MsaViewModel } from '../model.ts'
|
|
8
|
-
import type {
|
|
8
|
+
import type { BasicTrack } from '../types.ts'
|
|
9
9
|
|
|
10
10
|
export const VerticalResizeHandle = observer(function ({
|
|
11
11
|
model,
|
|
@@ -51,53 +51,38 @@ export const HorizontalResizeHandle = observer(function ({
|
|
|
51
51
|
)
|
|
52
52
|
})
|
|
53
53
|
|
|
54
|
-
// The height behind each resizable track kind. Both bar tracks read one height
|
|
55
|
-
// so conservation and property conservation stay directly comparable; the logo
|
|
56
|
-
// keeps its own, being taller by default. Text tracks are absent: they are one
|
|
57
|
-
// alignment row tall and follow rowHeight, so the zoom controls already size
|
|
58
|
-
// them.
|
|
59
|
-
const trackHeights: Partial<
|
|
60
|
-
Record<
|
|
61
|
-
TrackKind,
|
|
62
|
-
{
|
|
63
|
-
get: (model: MsaViewModel) => number
|
|
64
|
-
set: (model: MsaViewModel, height: number) => void
|
|
65
|
-
}
|
|
66
|
-
>
|
|
67
|
-
> = {
|
|
68
|
-
bar: {
|
|
69
|
-
get: model => model.conservationTrackHeight,
|
|
70
|
-
set: (model, height) => {
|
|
71
|
-
model.setConservationTrackHeight(height)
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
logo: {
|
|
75
|
-
get: model => model.sequenceLogoTrackHeight,
|
|
76
|
-
set: (model, height) => {
|
|
77
|
-
model.setSequenceLogoTrackHeight(height)
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
}
|
|
81
|
-
|
|
82
54
|
export const TrackResizeHandle = observer(function ({
|
|
83
55
|
model,
|
|
84
|
-
|
|
56
|
+
track,
|
|
85
57
|
}: {
|
|
86
58
|
model: MsaViewModel
|
|
87
|
-
|
|
59
|
+
track: BasicTrack
|
|
88
60
|
}) {
|
|
89
|
-
const height =
|
|
61
|
+
const { id, heightKey, height } = track.model
|
|
62
|
+
// tracks sharing a key resize together, so only the last turned-on one of
|
|
63
|
+
// them carries the divider: a second between conservation and property
|
|
64
|
+
// conservation would move the pair this one already moves. The drag divides
|
|
65
|
+
// across the group, so its bottom edge follows the cursor rather than half
|
|
66
|
+
const siblings = model.turnedOnTracks.filter(
|
|
67
|
+
t => t.model.heightKey === heightKey,
|
|
68
|
+
)
|
|
69
|
+
const count = siblings.length
|
|
90
70
|
const onDrag = useCallback(
|
|
91
71
|
(delta: number, startHeight: number) => {
|
|
92
|
-
|
|
72
|
+
if (heightKey) {
|
|
73
|
+
model.setTrackHeight(
|
|
74
|
+
heightKey,
|
|
75
|
+
Math.max(10, startHeight + delta / count),
|
|
76
|
+
)
|
|
77
|
+
}
|
|
93
78
|
},
|
|
94
|
-
[model,
|
|
79
|
+
[model, heightKey, count],
|
|
95
80
|
)
|
|
96
|
-
return
|
|
81
|
+
return heightKey && siblings.at(-1)?.model.id === id ? (
|
|
97
82
|
<DragHandle
|
|
98
83
|
axis="y"
|
|
99
84
|
variant="resizer"
|
|
100
|
-
getStart={() => height
|
|
85
|
+
getStart={() => height}
|
|
101
86
|
onDrag={onDrag}
|
|
102
87
|
style={{
|
|
103
88
|
position: 'absolute',
|
|
@@ -7,17 +7,17 @@ import { getUngappedSequence } from 'msa-parsers'
|
|
|
7
7
|
import Checkbox2 from './Checkbox2.tsx'
|
|
8
8
|
import CopyButton from './CopyButton.tsx'
|
|
9
9
|
|
|
10
|
-
const useStyles = makeStyles()({
|
|
10
|
+
const useStyles = makeStyles()(theme => ({
|
|
11
11
|
textAreaFont: {
|
|
12
12
|
fontFamily: 'Courier New',
|
|
13
13
|
wordWrap: 'break-word',
|
|
14
14
|
},
|
|
15
15
|
dialogContent: {
|
|
16
|
-
background:
|
|
16
|
+
background: theme.palette.action.selected,
|
|
17
17
|
margin: 4,
|
|
18
18
|
minWidth: '80em',
|
|
19
19
|
},
|
|
20
|
-
})
|
|
20
|
+
}))
|
|
21
21
|
|
|
22
22
|
export default function SequenceTextArea({ str }: { str: [string, string][] }) {
|
|
23
23
|
const { classes } = useStyles()
|