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
package/src/components/Track.tsx
CHANGED
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
import React, { lazy, useCallback, useRef, useState } from 'react'
|
|
2
2
|
|
|
3
|
+
import BaseTooltip from '@jbrowse/core/ui/BaseTooltip'
|
|
3
4
|
import { makeStyles } from '@jbrowse/core/util/tss-react'
|
|
4
5
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'
|
|
5
6
|
import { IconButton, Menu, MenuItem } from '@mui/material'
|
|
6
7
|
import { observer } from 'mobx-react'
|
|
7
8
|
|
|
8
9
|
import { useWheelScroll } from '../useWheelScroll.ts'
|
|
10
|
+
import TrackTooltipContent from './tracks/TrackTooltipContent.tsx'
|
|
11
|
+
import { useTrackHover } from './tracks/useTrackHover.ts'
|
|
9
12
|
|
|
10
13
|
import type { MsaViewModel } from '../model.ts'
|
|
11
14
|
import type { BasicTrack } from '../types.ts'
|
|
12
15
|
|
|
13
16
|
const TrackInfoDialog = lazy(() => import('./dialogs/TrackInfoDialog.tsx'))
|
|
14
17
|
|
|
15
|
-
const useStyles = makeStyles()({
|
|
18
|
+
const useStyles = makeStyles()(theme => ({
|
|
16
19
|
button: {
|
|
17
20
|
padding: 0,
|
|
18
21
|
},
|
|
19
|
-
|
|
22
|
+
// a hairline under every track but the last, across the labels as well as
|
|
23
|
+
// the alignment. The divider a track's resize handle draws covers only the
|
|
24
|
+
// alignment, and tracks sharing a height have no handle between them. Inset,
|
|
25
|
+
// so the line costs no layout height: totalTrackAreaHeight sums the model's
|
|
26
|
+
// heights, and the column indicator is drawn against that sum
|
|
27
|
+
row: {
|
|
28
|
+
display: 'flex',
|
|
29
|
+
'&:not(:last-child)': {
|
|
30
|
+
boxShadow: `inset 0 -1px 0 ${theme.palette.divider}`,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
}))
|
|
20
34
|
|
|
21
35
|
const TrackLabel = observer(function TrackLabel({
|
|
22
36
|
model,
|
|
@@ -37,21 +51,37 @@ const TrackLabel = observer(function TrackLabel({
|
|
|
37
51
|
const trackLabelHeight = Math.min(height, fontSize)
|
|
38
52
|
|
|
39
53
|
return (
|
|
54
|
+
// a flex row, not inline text: zooming in grows fontSize against a tree
|
|
55
|
+
// area the leaf labels sized, and a name that wrapped took its menu button
|
|
56
|
+
// onto a second line, under the next track's button
|
|
40
57
|
<div
|
|
41
58
|
style={{
|
|
42
59
|
width,
|
|
43
60
|
height,
|
|
44
61
|
flexShrink: 0,
|
|
45
|
-
|
|
62
|
+
display: 'flex',
|
|
63
|
+
alignItems: 'flex-start',
|
|
64
|
+
justifyContent: 'flex-end',
|
|
65
|
+
gap: 2,
|
|
46
66
|
fontSize: trackLabelHeight,
|
|
47
67
|
}}
|
|
48
68
|
>
|
|
49
|
-
|
|
69
|
+
<span
|
|
70
|
+
title={name}
|
|
71
|
+
style={{
|
|
72
|
+
overflow: 'hidden',
|
|
73
|
+
textOverflow: 'ellipsis',
|
|
74
|
+
whiteSpace: 'nowrap',
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{drawLabels ? name : ''}
|
|
78
|
+
</span>
|
|
50
79
|
<IconButton
|
|
51
80
|
className={classes.button}
|
|
52
81
|
style={{
|
|
53
82
|
width: trackLabelHeight,
|
|
54
83
|
height: trackLabelHeight,
|
|
84
|
+
flexShrink: 0,
|
|
55
85
|
}}
|
|
56
86
|
onClick={event => {
|
|
57
87
|
setAnchorEl(event.currentTarget)
|
|
@@ -102,7 +132,7 @@ const Track = observer(function ({
|
|
|
102
132
|
model: MsaViewModel
|
|
103
133
|
track: BasicTrack
|
|
104
134
|
}) {
|
|
105
|
-
const { resizeHandleWidth,
|
|
135
|
+
const { resizeHandleWidth, rowPanelsWidth, showColumnStats } = model
|
|
106
136
|
const {
|
|
107
137
|
model: { height },
|
|
108
138
|
} = track
|
|
@@ -114,31 +144,38 @@ const Track = observer(function ({
|
|
|
114
144
|
[model],
|
|
115
145
|
)
|
|
116
146
|
useWheelScroll({ ref, onScrollX })
|
|
147
|
+
const { classes } = useStyles()
|
|
148
|
+
const { hover, onMouseMove, onMouseLeave } = useTrackHover({
|
|
149
|
+
model,
|
|
150
|
+
tooltip: showColumnStats,
|
|
151
|
+
})
|
|
117
152
|
|
|
118
153
|
return (
|
|
119
|
-
<div style={{
|
|
154
|
+
<div className={classes.row} style={{ height }}>
|
|
120
155
|
<TrackLabel model={model} track={track} />
|
|
121
|
-
|
|
156
|
+
{/* the row panels are row space, so a track leaves their column empty
|
|
157
|
+
and starts where the alignment canvas does */}
|
|
158
|
+
<div
|
|
159
|
+
style={{ width: rowPanelsWidth + resizeHandleWidth, flexShrink: 0 }}
|
|
160
|
+
/>
|
|
122
161
|
<div
|
|
123
162
|
ref={ref}
|
|
163
|
+
data-testid={`track_${track.model.id}`}
|
|
124
164
|
onMouseMove={event => {
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
const { left } = ref.current.getBoundingClientRect()
|
|
129
|
-
const mouseX = event.clientX - left - scrollX
|
|
130
|
-
const col = Math.floor(mouseX / colWidth)
|
|
131
|
-
if (col >= 0 && col < numColumns) {
|
|
132
|
-
model.setMousePos(col, undefined)
|
|
133
|
-
} else {
|
|
134
|
-
model.setMousePos(undefined, undefined)
|
|
165
|
+
if (ref.current) {
|
|
166
|
+
onMouseMove(event, ref.current)
|
|
135
167
|
}
|
|
136
168
|
}}
|
|
137
169
|
onMouseLeave={() => {
|
|
138
|
-
|
|
170
|
+
onMouseLeave()
|
|
139
171
|
}}
|
|
140
172
|
>
|
|
141
173
|
<track.ReactComponent model={model} track={track} />
|
|
174
|
+
{hover ? (
|
|
175
|
+
<BaseTooltip clientPoint={{ x: hover.x, y: hover.y + 15 }}>
|
|
176
|
+
<TrackTooltipContent model={model} track={track} col={hover.col} />
|
|
177
|
+
</BaseTooltip>
|
|
178
|
+
) : null}
|
|
142
179
|
</div>
|
|
143
180
|
</div>
|
|
144
181
|
)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import { Dialog, ErrorMessage } from '@jbrowse/core/ui'
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
DialogActions,
|
|
7
|
+
DialogContent,
|
|
8
|
+
FormControl,
|
|
9
|
+
FormControlLabel,
|
|
10
|
+
Radio,
|
|
11
|
+
RadioGroup,
|
|
12
|
+
TextField,
|
|
13
|
+
Typography,
|
|
14
|
+
} from '@mui/material'
|
|
15
|
+
import { observer } from 'mobx-react'
|
|
16
|
+
import {
|
|
17
|
+
annotationsToGFF,
|
|
18
|
+
interProScanResponseToAnnotations,
|
|
19
|
+
} from 'msa-parsers'
|
|
20
|
+
|
|
21
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
22
|
+
import type { InterProScanResponse } from 'msa-parsers'
|
|
23
|
+
|
|
24
|
+
// GFF3 as the CLI writes it, or the JSON an InterProScan run returns. Both
|
|
25
|
+
// arrive as text and the model keeps GFF, so the JSON is converted on the way
|
|
26
|
+
// in rather than given a second path through the model
|
|
27
|
+
function toGFF(text: string) {
|
|
28
|
+
const trimmed = text.trimStart()
|
|
29
|
+
if (!trimmed.startsWith('{')) {
|
|
30
|
+
return text
|
|
31
|
+
}
|
|
32
|
+
const response: InterProScanResponse = JSON.parse(trimmed)
|
|
33
|
+
return annotationsToGFF(interProScanResponseToAnnotations(response))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function fetchText(url: string) {
|
|
37
|
+
const response = await fetch(url)
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`HTTP ${response.status} fetching ${url} ${await response.text()}`,
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
return response.text()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const AnnotationFileDialog = observer(function ({
|
|
47
|
+
handleClose,
|
|
48
|
+
model,
|
|
49
|
+
}: {
|
|
50
|
+
handleClose: () => void
|
|
51
|
+
model: MsaViewModel
|
|
52
|
+
}) {
|
|
53
|
+
const [file, setFile] = useState<File>()
|
|
54
|
+
const [choice, setChoice] = useState('file')
|
|
55
|
+
const [url, setUrl] = useState('')
|
|
56
|
+
const [error, setError] = useState<unknown>()
|
|
57
|
+
const [loading, setLoading] = useState(false)
|
|
58
|
+
|
|
59
|
+
// the error is shown here rather than notified: the standalone app and the
|
|
60
|
+
// MSAViewer component have no jbrowse session to notify, and asking one for
|
|
61
|
+
// its notify() threw out of the success path into the catch, which threw
|
|
62
|
+
// again on the same missing session
|
|
63
|
+
return (
|
|
64
|
+
<Dialog
|
|
65
|
+
maxWidth="xl"
|
|
66
|
+
title="Open annotation file"
|
|
67
|
+
onClose={() => {
|
|
68
|
+
handleClose()
|
|
69
|
+
}}
|
|
70
|
+
open
|
|
71
|
+
>
|
|
72
|
+
<DialogContent>
|
|
73
|
+
{error ? <ErrorMessage error={error} /> : null}
|
|
74
|
+
<Typography>
|
|
75
|
+
Open a GFF3 file of annotations, such as the one `react-msaview-cli
|
|
76
|
+
interpro` writes, or the JSON an InterProScan run returns.
|
|
77
|
+
</Typography>
|
|
78
|
+
|
|
79
|
+
<div style={{ display: 'flex', margin: 30 }}>
|
|
80
|
+
<FormControl component="fieldset">
|
|
81
|
+
<RadioGroup
|
|
82
|
+
value={choice}
|
|
83
|
+
onChange={event => {
|
|
84
|
+
setChoice(event.target.value)
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
<FormControlLabel value="url" control={<Radio />} label="URL" />
|
|
88
|
+
<FormControlLabel value="file" control={<Radio />} label="File" />
|
|
89
|
+
</RadioGroup>
|
|
90
|
+
</FormControl>
|
|
91
|
+
{choice === 'url' ? (
|
|
92
|
+
<div>
|
|
93
|
+
<Typography>Open an annotation file from a URL</Typography>
|
|
94
|
+
<TextField
|
|
95
|
+
label="URL"
|
|
96
|
+
value={url}
|
|
97
|
+
onChange={event => {
|
|
98
|
+
setUrl(event.target.value)
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
) : (
|
|
103
|
+
<div style={{ paddingTop: 20 }}>
|
|
104
|
+
<Typography>
|
|
105
|
+
Open an annotation file from your local drive
|
|
106
|
+
</Typography>
|
|
107
|
+
<Button variant="outlined" component="label">
|
|
108
|
+
Choose File
|
|
109
|
+
<input
|
|
110
|
+
type="file"
|
|
111
|
+
hidden
|
|
112
|
+
onChange={({ target }) => {
|
|
113
|
+
const chosen = target.files?.[0]
|
|
114
|
+
if (chosen) {
|
|
115
|
+
setFile(chosen)
|
|
116
|
+
}
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
</Button>
|
|
120
|
+
{file ? <Typography>{file.name}</Typography> : null}
|
|
121
|
+
</div>
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
</DialogContent>
|
|
125
|
+
<DialogActions>
|
|
126
|
+
<Button
|
|
127
|
+
variant="contained"
|
|
128
|
+
color="primary"
|
|
129
|
+
disabled={loading}
|
|
130
|
+
onClick={() => {
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
132
|
+
;(async () => {
|
|
133
|
+
setLoading(true)
|
|
134
|
+
setError(undefined)
|
|
135
|
+
try {
|
|
136
|
+
const text = await (choice === 'file' && file
|
|
137
|
+
? file.text()
|
|
138
|
+
: fetchText(url))
|
|
139
|
+
// through the model's own GFF text, so the annotations travel
|
|
140
|
+
// in the snapshot and the shared URL like every other layer.
|
|
141
|
+
// Setting them straight onto the volatile left a view whose
|
|
142
|
+
// link opened without them
|
|
143
|
+
model.setGFF(toGFF(text))
|
|
144
|
+
model.setShowDomains(true)
|
|
145
|
+
handleClose()
|
|
146
|
+
} catch (e) {
|
|
147
|
+
console.error(e)
|
|
148
|
+
setError(e)
|
|
149
|
+
} finally {
|
|
150
|
+
setLoading(false)
|
|
151
|
+
}
|
|
152
|
+
})()
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
Open annotations
|
|
156
|
+
</Button>
|
|
157
|
+
</DialogActions>
|
|
158
|
+
</Dialog>
|
|
159
|
+
)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
export default AnnotationFileDialog
|
|
@@ -49,15 +49,20 @@ export default function ExportSVGDialog({
|
|
|
49
49
|
totalWidth,
|
|
50
50
|
totalHeight,
|
|
51
51
|
treeAreaWidth,
|
|
52
|
+
rowPanelsWidth,
|
|
52
53
|
turnedOnTracks,
|
|
53
54
|
totalTrackAreaHeight,
|
|
54
55
|
numColumns,
|
|
55
56
|
leaves,
|
|
56
57
|
showMsaLetters,
|
|
58
|
+
treeOverviewHeight,
|
|
57
59
|
} = model
|
|
58
60
|
const hasTracks = turnedOnTracks.length > 0
|
|
59
|
-
const entireWidth = totalWidth + treeAreaWidth
|
|
60
|
-
const entireHeight =
|
|
61
|
+
const entireWidth = totalWidth + treeAreaWidth + rowPanelsWidth
|
|
62
|
+
const entireHeight =
|
|
63
|
+
totalHeight +
|
|
64
|
+
(includeTracks ? totalTrackAreaHeight : 0) +
|
|
65
|
+
treeOverviewHeight
|
|
61
66
|
// the background is one raster image whatever its size, so what the figure
|
|
62
67
|
// actually costs is its residue letters: each is an svg element of its own.
|
|
63
68
|
// Past roughly this many the export runs to tens of seconds and can exhaust
|
|
@@ -16,14 +16,20 @@ import { observer } from 'mobx-react'
|
|
|
16
16
|
import type { MsaViewModel } from '../../model.ts'
|
|
17
17
|
|
|
18
18
|
const Toggles = observer(function ({ model }: { model: MsaViewModel }) {
|
|
19
|
-
|
|
19
|
+
// the accessions the file has, not the ones the filter map happens to hold:
|
|
20
|
+
// that map now carries only what the reader turned off, and before that it
|
|
21
|
+
// accumulated every accession of every file opened in this view
|
|
22
|
+
const { annotationTypes } = model
|
|
23
|
+
const setAll = (shown: boolean) => {
|
|
24
|
+
for (const accession of annotationTypes.keys()) {
|
|
25
|
+
model.setFilter(accession, shown)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
20
28
|
return (
|
|
21
29
|
<div>
|
|
22
30
|
<Button
|
|
23
31
|
onClick={() => {
|
|
24
|
-
|
|
25
|
-
model.setFilter(key, true)
|
|
26
|
-
}
|
|
32
|
+
setAll(true)
|
|
27
33
|
}}
|
|
28
34
|
>
|
|
29
35
|
Toggle all on
|
|
@@ -31,9 +37,7 @@ const Toggles = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
31
37
|
|
|
32
38
|
<Button
|
|
33
39
|
onClick={() => {
|
|
34
|
-
|
|
35
|
-
model.setFilter(key, false)
|
|
36
|
-
}
|
|
40
|
+
setAll(false)
|
|
37
41
|
}}
|
|
38
42
|
>
|
|
39
43
|
Toggle all off
|
|
@@ -68,11 +72,11 @@ const FeatureTable = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
68
72
|
<TableRow key={accession}>
|
|
69
73
|
<TableCell padding="checkbox">
|
|
70
74
|
<Checkbox
|
|
71
|
-
checked={model.
|
|
75
|
+
checked={!model.turnedOffFeatures.get(accession)}
|
|
72
76
|
onChange={() => {
|
|
73
77
|
model.setFilter(
|
|
74
78
|
accession,
|
|
75
|
-
|
|
79
|
+
!!model.turnedOffFeatures.get(accession),
|
|
76
80
|
)
|
|
77
81
|
}}
|
|
78
82
|
/>
|
|
@@ -23,18 +23,13 @@ const GappynessSlider = observer(function GappynessSlider({
|
|
|
23
23
|
Hide columns w/ ≥{allowedGappyness}% gaps
|
|
24
24
|
</Typography>
|
|
25
25
|
<Slider
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// and drives that instead — which reads as this slider ignoring its
|
|
31
|
-
// keyboard. Target `[data-testid="gappyness_slider"] input` to reach the
|
|
32
|
-
// hidden range input MUI renders in the thumb, which is the node that
|
|
33
|
-
// takes focus and receives arrow/PageUp/PageDown.
|
|
26
|
+
// In JBrowse other MUI Sliders share the page, so `.MuiSlider-thumb`
|
|
27
|
+
// can match the wrong one. Tests and screenshot specs target
|
|
28
|
+
// `[data-testid="gappyness_slider"] input`, the hidden range input that
|
|
29
|
+
// takes focus and arrow/PageUp/PageDown.
|
|
34
30
|
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
// `number | number[]` and no longer assigns to setAllowedGappyness.
|
|
31
|
+
// Not `slotProps={{ input: ... }}`: that widens `onChange`'s `val` to
|
|
32
|
+
// `number | number[]`, which setAllowedGappyness rejects.
|
|
38
33
|
data-testid="gappyness_slider"
|
|
39
34
|
style={{ width: 100 }}
|
|
40
35
|
min={1}
|
|
@@ -10,9 +10,11 @@ import FileMenu from './FileMenu.tsx'
|
|
|
10
10
|
import GappynessSlider from './GappynessSlider.tsx'
|
|
11
11
|
import HeaderInfoArea from './HeaderInfoArea.tsx'
|
|
12
12
|
import HeaderStatusArea from './HeaderStatusArea.tsx'
|
|
13
|
+
import LoadWarnings from './LoadWarnings.tsx'
|
|
13
14
|
import MSASettingsMenu from './MSASettingsMenu.tsx'
|
|
14
15
|
import MultiAlignmentSelector from './MultiAlignmentSelector.tsx'
|
|
15
16
|
import TreeSettingsMenu from './TreeSettingsMenu.tsx'
|
|
17
|
+
import UnshareableDataWarning from './UnshareableDataWarning.tsx'
|
|
16
18
|
import ZoomControls from './ZoomControls.tsx'
|
|
17
19
|
import ZoomMenu from './ZoomMenu.tsx'
|
|
18
20
|
|
|
@@ -25,6 +27,12 @@ const Header = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
25
27
|
useEffect(() => {
|
|
26
28
|
model.setHeaderHeight(height ?? 0)
|
|
27
29
|
}, [model, height])
|
|
30
|
+
useEffect(
|
|
31
|
+
() => () => {
|
|
32
|
+
model.setHeaderHeight(0)
|
|
33
|
+
},
|
|
34
|
+
[model],
|
|
35
|
+
)
|
|
28
36
|
return (
|
|
29
37
|
<div ref={ref} style={{ display: 'flex' }}>
|
|
30
38
|
<FileMenu model={model} />
|
|
@@ -39,6 +47,8 @@ const Header = observer(function ({ model }: { model: MsaViewModel }) {
|
|
|
39
47
|
</div>
|
|
40
48
|
<HeaderInfoArea model={model} />
|
|
41
49
|
<Spacer />
|
|
50
|
+
<LoadWarnings model={model} />
|
|
51
|
+
<UnshareableDataWarning model={model} />
|
|
42
52
|
<HeaderStatusArea model={model} />
|
|
43
53
|
<Tooltip title="About">
|
|
44
54
|
<IconButton
|
|
@@ -20,11 +20,6 @@ const HeaderStatusArea = observer(({ model }: { model: MsaViewModel }) => {
|
|
|
20
20
|
return status ? (
|
|
21
21
|
<Typography className={classes.margin}>
|
|
22
22
|
<LoadingEllipses message={status.msg} component="span" />{' '}
|
|
23
|
-
{status.url ? (
|
|
24
|
-
<a href={status.url} target="_blank" rel="noreferrer">
|
|
25
|
-
(status)
|
|
26
|
-
</a>
|
|
27
|
-
) : null}{' '}
|
|
28
23
|
{status.onCancel ? (
|
|
29
24
|
<Button size="small" onClick={() => status.onCancel?.()}>
|
|
30
25
|
Cancel
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react'
|
|
4
|
+
import Warning from '@mui/icons-material/Warning'
|
|
5
|
+
import { Tooltip, Typography } from '@mui/material'
|
|
6
|
+
import { observer } from 'mobx-react'
|
|
7
|
+
|
|
8
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
9
|
+
|
|
10
|
+
const useStyles = makeStyles()(theme => ({
|
|
11
|
+
warning: {
|
|
12
|
+
display: 'flex',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
gap: 4,
|
|
15
|
+
margin: 'auto',
|
|
16
|
+
marginLeft: 10,
|
|
17
|
+
whiteSpace: 'nowrap',
|
|
18
|
+
color: theme.palette.warning.main,
|
|
19
|
+
cursor: 'pointer',
|
|
20
|
+
},
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
// A failed optional layer, such as a 404 on the annotations or row metadata
|
|
24
|
+
// that is not JSON, shows here as a dismissible warning. Setting `error` would
|
|
25
|
+
// clear dataInitialized and hide the loaded alignment.
|
|
26
|
+
const LoadWarnings = observer(function ({ model }: { model: MsaViewModel }) {
|
|
27
|
+
const { warnings } = model
|
|
28
|
+
const { classes } = useStyles()
|
|
29
|
+
if (warnings.length === 0) {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
return (
|
|
33
|
+
<Tooltip title={`${warnings.join(' ')} (click to dismiss)`}>
|
|
34
|
+
<Typography
|
|
35
|
+
component="div"
|
|
36
|
+
className={classes.warning}
|
|
37
|
+
onClick={() => {
|
|
38
|
+
model.clearWarnings()
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<Warning fontSize="small" />
|
|
42
|
+
{warnings.length > 1 ? `${warnings.length} warnings` : 'Warning'}
|
|
43
|
+
</Typography>
|
|
44
|
+
</Tooltip>
|
|
45
|
+
)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
export default LoadWarnings
|
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import SvgIcon from '@mui/material/SvgIcon'
|
|
4
|
+
|
|
5
|
+
import type { SvgIconProps } from '@mui/material/SvgIcon'
|
|
6
|
+
|
|
7
|
+
// Mouse glyphs with outward arrows on the axes a wheel zoom scales.
|
|
8
|
+
// @mui/icons-material ships only the plain `Mouse`, and three variants that
|
|
9
|
+
// differ only in their arrows have to share one body to stay apart at 24px.
|
|
10
|
+
// The body's inner subpath runs the opposite sweep, which punches the hole the
|
|
11
|
+
// wheel bar sits in.
|
|
12
|
+
const BODY =
|
|
13
|
+
'M12 5a4 4 0 0 0-4 4v6a4 4 0 0 0 8 0V9a4 4 0 0 0-4-4zm0 2a2 2 0 0 1 2 2v6a2 2 0 0 1-4 0V9a2 2 0 0 1 2-2z'
|
|
14
|
+
const WHEEL = 'M11.2 8.6h1.6v3.2h-1.6z'
|
|
15
|
+
const LEFT = 'M.4 12 5 15V9z'
|
|
16
|
+
const RIGHT = 'M23.6 12 19 9v6z'
|
|
17
|
+
const UP = 'M12 .4 15 4H9z'
|
|
18
|
+
const DOWN = 'M12 23.6 9 20h6z'
|
|
19
|
+
|
|
20
|
+
function MouseZoom({
|
|
21
|
+
arrows,
|
|
22
|
+
...rest
|
|
23
|
+
}: SvgIconProps & { arrows: readonly string[] }) {
|
|
24
|
+
return (
|
|
25
|
+
<SvgIcon {...rest}>
|
|
26
|
+
<path d={BODY} />
|
|
27
|
+
<path d={WHEEL} />
|
|
28
|
+
{arrows.map(d => (
|
|
29
|
+
<path key={d} d={d} />
|
|
30
|
+
))}
|
|
31
|
+
</SvgIcon>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// the bare body, for a wheel that scrolls. @mui/icons-material's own `Mouse` is
|
|
36
|
+
// a solid silhouette, which would jump to a different drawing when the menu
|
|
37
|
+
// changes the mode.
|
|
38
|
+
export function MouseScroll(props: SvgIconProps) {
|
|
39
|
+
return <MouseZoom {...props} arrows={[]} />
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function MouseZoomBoth(props: SvgIconProps) {
|
|
43
|
+
return <MouseZoom {...props} arrows={[LEFT, RIGHT, UP, DOWN]} />
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function MouseZoomHorizontal(props: SvgIconProps) {
|
|
47
|
+
return <MouseZoom {...props} arrows={[LEFT, RIGHT]} />
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function MouseZoomVertical(props: SvgIconProps) {
|
|
51
|
+
return <MouseZoom {...props} arrows={[UP, DOWN]} />
|
|
52
|
+
}
|
|
@@ -4,6 +4,7 @@ import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
|
|
|
4
4
|
import AccountTree from '@mui/icons-material/AccountTree'
|
|
5
5
|
import { observer } from 'mobx-react'
|
|
6
6
|
|
|
7
|
+
import { maxNeighborJoiningRows } from '../../constants.ts'
|
|
7
8
|
import { treeSettingsMenuItems } from './settingsMenuItems.ts'
|
|
8
9
|
|
|
9
10
|
import type { MsaViewModel } from '../../model.ts'
|
|
@@ -14,6 +15,7 @@ const TreeSettingsMenu = observer(function ({
|
|
|
14
15
|
model: MsaViewModel
|
|
15
16
|
}) {
|
|
16
17
|
const { rows } = model
|
|
18
|
+
const tooManyRows = rows.length > maxNeighborJoiningRows
|
|
17
19
|
return (
|
|
18
20
|
<CascadingMenuButton
|
|
19
21
|
data-testid="tree_settings_menu"
|
|
@@ -30,7 +32,11 @@ const TreeSettingsMenu = observer(function ({
|
|
|
30
32
|
type: 'subMenu' as const,
|
|
31
33
|
subMenu: [
|
|
32
34
|
{
|
|
33
|
-
label
|
|
35
|
+
// the label shows the cap before a click would freeze the tab
|
|
36
|
+
label: tooManyRows
|
|
37
|
+
? `Calculate neighbor joining tree (over ${maxNeighborJoiningRows} rows, use FastTree)`
|
|
38
|
+
: 'Calculate neighbor joining tree (BLOSUM62)',
|
|
39
|
+
disabled: tooManyRows,
|
|
34
40
|
onClick: () => {
|
|
35
41
|
try {
|
|
36
42
|
model.calculateNeighborJoiningTreeFromMSA()
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react'
|
|
4
|
+
import LinkOff from '@mui/icons-material/LinkOff'
|
|
5
|
+
import { Tooltip, Typography } from '@mui/material'
|
|
6
|
+
import { observer } from 'mobx-react'
|
|
7
|
+
|
|
8
|
+
import type { MsaViewModel } from '../../model.ts'
|
|
9
|
+
|
|
10
|
+
const useStyles = makeStyles()(theme => ({
|
|
11
|
+
warning: {
|
|
12
|
+
display: 'flex',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
gap: 4,
|
|
15
|
+
margin: 'auto',
|
|
16
|
+
marginLeft: 10,
|
|
17
|
+
whiteSpace: 'nowrap',
|
|
18
|
+
color: theme.palette.warning.main,
|
|
19
|
+
cursor: 'help',
|
|
20
|
+
},
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
function size(bytes: number) {
|
|
24
|
+
return bytes < 1_000_000
|
|
25
|
+
? `${Math.round(bytes / 1000)} kB`
|
|
26
|
+
: `${(bytes / 1_000_000).toFixed(1)} MB`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Lists loaded documents the snapshot, and so a shared URL, omits. See
|
|
30
|
+
// `unshareableData` on the model.
|
|
31
|
+
const UnshareableDataWarning = observer(function ({
|
|
32
|
+
model,
|
|
33
|
+
}: {
|
|
34
|
+
model: MsaViewModel
|
|
35
|
+
}) {
|
|
36
|
+
const { unshareableData } = model
|
|
37
|
+
const { classes } = useStyles()
|
|
38
|
+
if (unshareableData.length === 0) {
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
const what = unshareableData
|
|
42
|
+
.map(({ what, bytes }) => `${what} (${size(bytes)})`)
|
|
43
|
+
.join(' and the ')
|
|
44
|
+
return (
|
|
45
|
+
<Tooltip
|
|
46
|
+
title={`The ${what} came from this computer and is too large to travel in a URL, so a link to this page opens without it. Serve the file over HTTP and open it by URL to share the view.`}
|
|
47
|
+
>
|
|
48
|
+
<Typography component="div" className={classes.warning}>
|
|
49
|
+
<LinkOff fontSize="small" />
|
|
50
|
+
Not in the link
|
|
51
|
+
</Typography>
|
|
52
|
+
</Tooltip>
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export default UnshareableDataWarning
|