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/renderToSvg.test.tsx
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
//
|
|
3
|
-
// Layout and palette of the exported figure itself, as opposed to what any one
|
|
4
|
-
// layer draws inside it.
|
|
5
|
-
import { createJBrowseTheme } from '@jbrowse/core/ui/theme'
|
|
6
|
-
import { beforeAll, expect, test } from 'vitest'
|
|
7
|
-
|
|
8
|
-
import { renderToSvg } from './renderToSvg.tsx'
|
|
9
|
-
import {
|
|
10
|
-
createTestModel,
|
|
11
|
-
installSvgTestEnv,
|
|
12
|
-
syntheticProteinMsa,
|
|
13
|
-
} from './svgTestUtil.ts'
|
|
14
|
-
|
|
15
|
-
beforeAll(() => {
|
|
16
|
-
installSvgTestEnv()
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
function makeModel({ rows = 60, cols = 400 } = {}) {
|
|
20
|
-
return createTestModel({ data: { msa: syntheticProteinMsa(rows, cols) } })
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const rootRect = (svg: string) => /<rect[^>]*height="100%"[^>]*>/.exec(svg)?.[0]
|
|
24
|
-
|
|
25
|
-
test('the page takes the theme background, not a hardcoded white', async () => {
|
|
26
|
-
const model = makeModel()
|
|
27
|
-
const dark = createJBrowseTheme({ palette: { mode: 'dark' } })
|
|
28
|
-
expect(dark.palette.background.default).not.toBe('white')
|
|
29
|
-
|
|
30
|
-
const svg = await renderToSvg(model, { theme: dark, exportType: 'entire' })
|
|
31
|
-
|
|
32
|
-
// the layers below draw in theme colors: text.primary is near-white in a dark
|
|
33
|
-
// theme, so a white page would export white on white
|
|
34
|
-
expect(rootRect(svg)).toContain(`fill="${dark.palette.background.default}"`)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
test('a viewport export is the alignment canvas, not the whole widget', async () => {
|
|
38
|
-
const model = makeModel()
|
|
39
|
-
expect(model.showHorizontalScrollbar).toBe(true)
|
|
40
|
-
expect(model.showVerticalScrollbar).toBe(true)
|
|
41
|
-
|
|
42
|
-
const svg = await renderToSvg(model, {
|
|
43
|
-
theme: createJBrowseTheme(),
|
|
44
|
-
exportType: 'viewport',
|
|
45
|
-
includeMinimap: true,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
// the widget box also covers the resize handle and the scrollbars; exporting
|
|
49
|
-
// it drew the rows and columns those hide
|
|
50
|
-
const { treeAreaWidth, msaCanvasWidth, msaAreaHeight, minimapHeight } = model
|
|
51
|
-
expect(svg).toContain(`width="${treeAreaWidth + msaCanvasWidth}"`)
|
|
52
|
-
expect(svg).toContain(`height="${msaAreaHeight + minimapHeight}"`)
|
|
53
|
-
expect(msaAreaHeight + minimapHeight).toBe(model.height)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('no attribute is serialized as the string "undefined"', async () => {
|
|
57
|
-
const model = makeModel({ rows: 4, cols: 20 })
|
|
58
|
-
const svg = await renderToSvg(model, {
|
|
59
|
-
theme: createJBrowseTheme(),
|
|
60
|
-
exportType: 'entire',
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
expect(svg).toContain('<text')
|
|
64
|
-
expect(svg).not.toContain('="undefined"')
|
|
65
|
-
})
|
package/src/reset.test.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import stateModelFactory from './model.ts'
|
|
4
|
-
|
|
5
|
-
const MsaView = stateModelFactory()
|
|
6
|
-
|
|
7
|
-
function loaded() {
|
|
8
|
-
const model = MsaView.create({
|
|
9
|
-
type: 'MsaView',
|
|
10
|
-
data: { msa: '>a\nAC\n>b\nAC\n>c\nAC\n>d\nAC', tree: '((a,b),(c,d));' },
|
|
11
|
-
})
|
|
12
|
-
model.setWidth(1000)
|
|
13
|
-
return model
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
test('reset returns to the import form', () => {
|
|
17
|
-
const model = loaded()
|
|
18
|
-
expect(model.dataInitialized).toBe(true)
|
|
19
|
-
model.reset()
|
|
20
|
-
expect(model.dataInitialized).toBe(false)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
// generateNodeIds derives ids from the path, so 'node-0-0-1' is the root's
|
|
24
|
-
// first child in EVERY tree. Carrying collapsed/showOnly across a reset opens
|
|
25
|
-
// the next file collapsed, or focused on a subtree, with nothing on screen
|
|
26
|
-
// saying why
|
|
27
|
-
test('reset drops view state that names the old data', () => {
|
|
28
|
-
const model = loaded()
|
|
29
|
-
const innerNode = model.hierarchy.children![0]!.data.id
|
|
30
|
-
model.toggleCollapsed(innerNode)
|
|
31
|
-
model.setShowOnly(innerNode)
|
|
32
|
-
model.drawRelativeTo('a')
|
|
33
|
-
model.setHighlightedColumns([0, 1])
|
|
34
|
-
model.setMousePos(1, 1)
|
|
35
|
-
model.setMouseClickPos(1, 1)
|
|
36
|
-
model.setHoveredTreeNode(innerNode)
|
|
37
|
-
|
|
38
|
-
model.reset()
|
|
39
|
-
|
|
40
|
-
expect([...model.collapsed]).toEqual([])
|
|
41
|
-
expect(model.showOnly).toBeUndefined()
|
|
42
|
-
expect(model.relativeTo).toBeUndefined()
|
|
43
|
-
expect(model.highlightedColumns).toBeUndefined()
|
|
44
|
-
expect(model.mouseCol).toBeUndefined()
|
|
45
|
-
expect(model.mouseClickCol).toBeUndefined()
|
|
46
|
-
expect(model.hoveredTreeNode).toBeUndefined()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('a file opened after a reset is not collapsed by the previous one', () => {
|
|
50
|
-
const model = loaded()
|
|
51
|
-
model.toggleCollapsed(model.hierarchy.children![0]!.data.id)
|
|
52
|
-
expect(model.numRows).toBeLessThan(4)
|
|
53
|
-
|
|
54
|
-
model.reset()
|
|
55
|
-
model.setData({
|
|
56
|
-
msa: '>x\nGT\n>y\nGT\n>z\nGT\n>w\nGT',
|
|
57
|
-
tree: '((x,y),(z,w));',
|
|
58
|
-
})
|
|
59
|
-
expect(model.numRows).toBe(4)
|
|
60
|
-
expect(model.rowNames).toEqual(['x', 'y', 'z', 'w'])
|
|
61
|
-
})
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
globalColToVisibleCol,
|
|
5
|
-
visibleColToGlobalCol,
|
|
6
|
-
visibleColToSeqPos,
|
|
7
|
-
} from './rowCoordinateCalculations.ts'
|
|
8
|
-
|
|
9
|
-
// Tests for visibleColToGlobalCol (visible → global)
|
|
10
|
-
test('visibleColToGlobalCol with blanks at positions [2, 5, 8]', () => {
|
|
11
|
-
const blanks = [2, 5, 8]
|
|
12
|
-
;(
|
|
13
|
-
[
|
|
14
|
-
[0, 0],
|
|
15
|
-
[1, 1],
|
|
16
|
-
[2, 3],
|
|
17
|
-
[3, 4],
|
|
18
|
-
[4, 6],
|
|
19
|
-
[5, 7],
|
|
20
|
-
[6, 9],
|
|
21
|
-
[7, 10],
|
|
22
|
-
] as const
|
|
23
|
-
).forEach(r => {
|
|
24
|
-
expect(visibleColToGlobalCol(blanks, r[0])).toBe(r[1])
|
|
25
|
-
})
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('visibleColToGlobalCol with no blanks', () => {
|
|
29
|
-
const blanks: number[] = []
|
|
30
|
-
;(
|
|
31
|
-
[
|
|
32
|
-
[0, 0],
|
|
33
|
-
[1, 1],
|
|
34
|
-
[5, 5],
|
|
35
|
-
[10, 10],
|
|
36
|
-
] as const
|
|
37
|
-
).forEach(r => {
|
|
38
|
-
expect(visibleColToGlobalCol(blanks, r[0])).toBe(r[1])
|
|
39
|
-
})
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test('visibleColToGlobalCol with consecutive blanks', () => {
|
|
43
|
-
const blanks = [2, 3, 4, 7, 8]
|
|
44
|
-
;(
|
|
45
|
-
[
|
|
46
|
-
[0, 0],
|
|
47
|
-
[1, 1],
|
|
48
|
-
[2, 5], // After position 1, skip 3 blanks (2,3,4)
|
|
49
|
-
[3, 6], // Next position
|
|
50
|
-
[4, 9], // After position 3, skip 2 blanks (7,8)
|
|
51
|
-
[5, 10],
|
|
52
|
-
] as const
|
|
53
|
-
).forEach(r => {
|
|
54
|
-
expect(visibleColToGlobalCol(blanks, r[0])).toBe(r[1])
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
test('visibleColToGlobalCol with blanks at the beginning', () => {
|
|
59
|
-
const blanks = [1, 2, 5]
|
|
60
|
-
;(
|
|
61
|
-
[
|
|
62
|
-
[0, 0],
|
|
63
|
-
[1, 3], // After position 0, skip 2 blanks (1,2)
|
|
64
|
-
[2, 4],
|
|
65
|
-
[3, 6], // After position 2, skip 1 blank (5)
|
|
66
|
-
[4, 7],
|
|
67
|
-
] as const
|
|
68
|
-
).forEach(r => {
|
|
69
|
-
expect(visibleColToGlobalCol(blanks, r[0])).toBe(r[1])
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
test('visibleColToGlobalCol with position exceeding blanks array', () => {
|
|
74
|
-
const blanks = [2, 5]
|
|
75
|
-
;(
|
|
76
|
-
[
|
|
77
|
-
[0, 0],
|
|
78
|
-
[1, 1],
|
|
79
|
-
[2, 3], // After position 1, skip 1 blank (2)
|
|
80
|
-
[3, 4],
|
|
81
|
-
[4, 6], // After position 3, skip 1 blank (5)
|
|
82
|
-
[10, 12], // Far beyond blanks array
|
|
83
|
-
] as const
|
|
84
|
-
).forEach(r => {
|
|
85
|
-
expect(visibleColToGlobalCol(blanks, r[0])).toBe(r[1])
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
// Tests for globalColToVisibleCol (global → visible)
|
|
90
|
-
test('globalColToVisibleCol with blanks at positions [2, 5, 8]', () => {
|
|
91
|
-
const blanks = [2, 5, 8]
|
|
92
|
-
// Inverse of visibleColToGlobalCol
|
|
93
|
-
expect(globalColToVisibleCol(blanks, 0)).toBe(0)
|
|
94
|
-
expect(globalColToVisibleCol(blanks, 1)).toBe(1)
|
|
95
|
-
expect(globalColToVisibleCol(blanks, 2)).toBe(undefined) // Hidden
|
|
96
|
-
expect(globalColToVisibleCol(blanks, 3)).toBe(2)
|
|
97
|
-
expect(globalColToVisibleCol(blanks, 4)).toBe(3)
|
|
98
|
-
expect(globalColToVisibleCol(blanks, 5)).toBe(undefined) // Hidden
|
|
99
|
-
expect(globalColToVisibleCol(blanks, 6)).toBe(4)
|
|
100
|
-
expect(globalColToVisibleCol(blanks, 7)).toBe(5)
|
|
101
|
-
expect(globalColToVisibleCol(blanks, 8)).toBe(undefined) // Hidden
|
|
102
|
-
expect(globalColToVisibleCol(blanks, 9)).toBe(6)
|
|
103
|
-
expect(globalColToVisibleCol(blanks, 10)).toBe(7)
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
test('globalColToVisibleCol with no blanks', () => {
|
|
107
|
-
const blanks: number[] = []
|
|
108
|
-
expect(globalColToVisibleCol(blanks, 0)).toBe(0)
|
|
109
|
-
expect(globalColToVisibleCol(blanks, 5)).toBe(5)
|
|
110
|
-
expect(globalColToVisibleCol(blanks, 10)).toBe(10)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
test('globalColToVisibleCol with consecutive blanks', () => {
|
|
114
|
-
const blanks = [2, 3, 4, 7, 8]
|
|
115
|
-
expect(globalColToVisibleCol(blanks, 0)).toBe(0)
|
|
116
|
-
expect(globalColToVisibleCol(blanks, 1)).toBe(1)
|
|
117
|
-
expect(globalColToVisibleCol(blanks, 2)).toBe(undefined) // Hidden
|
|
118
|
-
expect(globalColToVisibleCol(blanks, 3)).toBe(undefined) // Hidden
|
|
119
|
-
expect(globalColToVisibleCol(blanks, 4)).toBe(undefined) // Hidden
|
|
120
|
-
expect(globalColToVisibleCol(blanks, 5)).toBe(2)
|
|
121
|
-
expect(globalColToVisibleCol(blanks, 6)).toBe(3)
|
|
122
|
-
expect(globalColToVisibleCol(blanks, 7)).toBe(undefined) // Hidden
|
|
123
|
-
expect(globalColToVisibleCol(blanks, 8)).toBe(undefined) // Hidden
|
|
124
|
-
expect(globalColToVisibleCol(blanks, 9)).toBe(4)
|
|
125
|
-
expect(globalColToVisibleCol(blanks, 10)).toBe(5)
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
// Tests for visibleColToSeqPos (visible column → sequence position)
|
|
129
|
-
test('visibleColToSeqPos returns sequence position or undefined for gaps', () => {
|
|
130
|
-
const seq = 'AC--GT--CT'
|
|
131
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 0, blanks: [] })).toBe(0)
|
|
132
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 1, blanks: [] })).toBe(1)
|
|
133
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 2, blanks: [] })).toBe(undefined)
|
|
134
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 3, blanks: [] })).toBe(undefined)
|
|
135
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 4, blanks: [] })).toBe(2)
|
|
136
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 5, blanks: [] })).toBe(3)
|
|
137
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 6, blanks: [] })).toBe(undefined)
|
|
138
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 7, blanks: [] })).toBe(undefined)
|
|
139
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 8, blanks: [] })).toBe(4)
|
|
140
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 9, blanks: [] })).toBe(5)
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
// Round-trip tests: visible → global → visible should be identity for valid columns
|
|
144
|
-
test('round-trip: visibleColToGlobalCol and globalColToVisibleCol are inverses', () => {
|
|
145
|
-
const blanks = [2, 5, 8]
|
|
146
|
-
// For each visible column, going to global and back should return the same value
|
|
147
|
-
for (let visibleCol = 0; visibleCol < 10; visibleCol++) {
|
|
148
|
-
const globalCol = visibleColToGlobalCol(blanks, visibleCol)
|
|
149
|
-
const backToVisible = globalColToVisibleCol(blanks, globalCol)
|
|
150
|
-
expect(backToVisible).toBe(visibleCol)
|
|
151
|
-
}
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
test('round-trip: globalColToVisibleCol and visibleColToGlobalCol for non-hidden columns', () => {
|
|
155
|
-
const blanks = [2, 5, 8]
|
|
156
|
-
// For each global column that is NOT hidden, going to visible and back should return the same value
|
|
157
|
-
for (let globalCol = 0; globalCol < 15; globalCol++) {
|
|
158
|
-
const visibleCol = globalColToVisibleCol(blanks, globalCol)
|
|
159
|
-
if (visibleCol !== undefined) {
|
|
160
|
-
const backToGlobal = visibleColToGlobalCol(blanks, visibleCol)
|
|
161
|
-
expect(backToGlobal).toBe(globalCol)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
// Edge case: blanks at position 0
|
|
167
|
-
test('globalColToVisibleCol with blank at position 0', () => {
|
|
168
|
-
const blanks = [0, 1, 5]
|
|
169
|
-
expect(globalColToVisibleCol(blanks, 0)).toBe(undefined) // Hidden
|
|
170
|
-
expect(globalColToVisibleCol(blanks, 1)).toBe(undefined) // Hidden
|
|
171
|
-
expect(globalColToVisibleCol(blanks, 2)).toBe(0) // First visible column
|
|
172
|
-
expect(globalColToVisibleCol(blanks, 3)).toBe(1)
|
|
173
|
-
expect(globalColToVisibleCol(blanks, 4)).toBe(2)
|
|
174
|
-
expect(globalColToVisibleCol(blanks, 5)).toBe(undefined) // Hidden
|
|
175
|
-
expect(globalColToVisibleCol(blanks, 6)).toBe(3)
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
test('visibleColToGlobalCol with blank at position 0', () => {
|
|
179
|
-
const blanks = [0, 1, 5]
|
|
180
|
-
expect(visibleColToGlobalCol(blanks, 0)).toBe(2) // Skips 0, 1
|
|
181
|
-
expect(visibleColToGlobalCol(blanks, 1)).toBe(3)
|
|
182
|
-
expect(visibleColToGlobalCol(blanks, 2)).toBe(4)
|
|
183
|
-
expect(visibleColToGlobalCol(blanks, 3)).toBe(6) // Skips 5
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
// Edge case: all columns before a position are blanks
|
|
187
|
-
test('globalColToVisibleCol with many leading blanks', () => {
|
|
188
|
-
const blanks = [0, 1, 2, 3, 4]
|
|
189
|
-
expect(globalColToVisibleCol(blanks, 0)).toBe(undefined)
|
|
190
|
-
expect(globalColToVisibleCol(blanks, 4)).toBe(undefined)
|
|
191
|
-
expect(globalColToVisibleCol(blanks, 5)).toBe(0) // First visible
|
|
192
|
-
expect(globalColToVisibleCol(blanks, 6)).toBe(1)
|
|
193
|
-
expect(globalColToVisibleCol(blanks, 10)).toBe(5)
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
// Test visibleColToSeqPos with blanks (combined gap hiding and row gaps)
|
|
197
|
-
test('visibleColToSeqPos with both blanks and row gaps', () => {
|
|
198
|
-
// Sequence: A-C-G (global cols 0,1,2,3,4)
|
|
199
|
-
// If blanks = [1, 3], visible sequence becomes: A C G (visible cols 0,1,2)
|
|
200
|
-
const seq = 'A-C-G'
|
|
201
|
-
const blanks = [1, 3]
|
|
202
|
-
|
|
203
|
-
// Visible col 0 → global col 0 → 'A' → seqPos 0
|
|
204
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 0, blanks })).toBe(0)
|
|
205
|
-
|
|
206
|
-
// Visible col 1 → global col 2 → 'C' → seqPos 1
|
|
207
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 1, blanks })).toBe(1)
|
|
208
|
-
|
|
209
|
-
// Visible col 2 → global col 4 → 'G' → seqPos 2
|
|
210
|
-
expect(visibleColToSeqPos({ seq, visibleCol: 2, blanks })).toBe(2)
|
|
211
|
-
})
|
package/src/rowSpace.test.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { expect, test } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import MSAModelF from './model.ts'
|
|
5
|
-
|
|
6
|
-
// the tree names a tip the alignment has no sequence for. It still occupies a
|
|
7
|
-
// row of vertical space (drawn blank), so anything that maps y-pixels to rows has
|
|
8
|
-
// to count it, or the last row becomes unhoverable and fit-to-height overshoots.
|
|
9
|
-
const msa = `>a
|
|
10
|
-
ACGT
|
|
11
|
-
>b
|
|
12
|
-
ACGT`
|
|
13
|
-
const tree = '((a:1,b:1):1,ghost:1);'
|
|
14
|
-
|
|
15
|
-
function makeModel() {
|
|
16
|
-
const model = MSAModelF().create({
|
|
17
|
-
id: 'row-space-test',
|
|
18
|
-
type: 'MsaView',
|
|
19
|
-
msaFormat: 'fasta',
|
|
20
|
-
height: 400,
|
|
21
|
-
data: { msa, tree },
|
|
22
|
-
})
|
|
23
|
-
model.setWidth(800)
|
|
24
|
-
return model
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
test('row space counts tree leaves, not just rows with sequence', () => {
|
|
28
|
-
const model = makeModel()
|
|
29
|
-
expect(model.rowNames).toEqual(['a', 'b', 'ghost'])
|
|
30
|
-
expect(model.rows.map(r => r[0])).toEqual(['a', 'b'])
|
|
31
|
-
expect(model.numRows).toBe(3)
|
|
32
|
-
expect(model.totalHeight).toBe(3 * model.rowHeight)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('the last row is addressable', () => {
|
|
36
|
-
const model = makeModel()
|
|
37
|
-
const lastRow = model.numRows - 1
|
|
38
|
-
model.setMousePos(0, lastRow)
|
|
39
|
-
expect(model.mouseOverRowName).toBe('ghost')
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test('fit vertically leaves every row on screen', () => {
|
|
43
|
-
const model = makeModel()
|
|
44
|
-
model.fitVertically()
|
|
45
|
-
expect(model.totalHeight).toBeLessThanOrEqual(model.msaAreaHeight)
|
|
46
|
-
})
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
// Verifies that ordinal segment features (exons) from a GFF overlay are treated
|
|
2
|
-
// as a numbered gene model — alternating two shades, labeled by number, and
|
|
3
|
-
// kept out of the categorical color-key legend — while real domains keep a
|
|
4
|
-
// distinct color + legend entry.
|
|
5
|
-
import { expect, test } from 'vitest'
|
|
6
|
-
|
|
7
|
-
import { segmentShades } from './constants.ts'
|
|
8
|
-
import MSAModelF from './model.ts'
|
|
9
|
-
|
|
10
|
-
const msa = `>human
|
|
11
|
-
ACDEFGHIKLMNPQRSTVWYACDEFGHIKLMNPQRSTVWYACDEFGHIKLMNPQRSTVWY
|
|
12
|
-
>mouse
|
|
13
|
-
ACDEFGHIKLMNPQRSTVWYACDEFGHIKLMNPQRSTVWYACDEFGHIKLMNPQRSTVWY`
|
|
14
|
-
|
|
15
|
-
// three exons in CDS coordinates plus one real domain, deliberately out of
|
|
16
|
-
// start order in the file to prove ordering is by position not file/length
|
|
17
|
-
const gff = `##gff-version 3
|
|
18
|
-
human src exon 41 60 . . . ID=human.exon3;Name=exon-3
|
|
19
|
-
human src exon 1 20 . . . ID=human.exon1;Name=exon-1
|
|
20
|
-
human src exon 21 40 . . . ID=human.exon2;Name=exon-2
|
|
21
|
-
human Pfam protein_match 5 35 . . . Name=PF00069;signature_desc=Kinase`
|
|
22
|
-
|
|
23
|
-
function makeModel() {
|
|
24
|
-
const model = MSAModelF().create({
|
|
25
|
-
id: 'segment-overlay-test',
|
|
26
|
-
type: 'MsaView',
|
|
27
|
-
height: 400,
|
|
28
|
-
msaFormat: 'fasta',
|
|
29
|
-
data: { msa },
|
|
30
|
-
})
|
|
31
|
-
model.setWidth(800)
|
|
32
|
-
model.applyGFFText(gff)
|
|
33
|
-
return model
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
test('exons are ordered by sequence position, domains kept separate', () => {
|
|
37
|
-
const model = makeModel()
|
|
38
|
-
expect(model.segmentDomainTypes.map(d => d.accession)).toEqual([
|
|
39
|
-
'exon-1',
|
|
40
|
-
'exon-2',
|
|
41
|
-
'exon-3',
|
|
42
|
-
])
|
|
43
|
-
expect(model.categoricalDomainTypes.map(d => d.accession)).toEqual([
|
|
44
|
-
'PF00069',
|
|
45
|
-
])
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
test('exons alternate two shades; domain gets its own color', () => {
|
|
49
|
-
const { fillPalette } = makeModel()
|
|
50
|
-
expect(fillPalette['exon-1']).toBe(segmentShades[0])
|
|
51
|
-
expect(fillPalette['exon-2']).toBe(segmentShades[1])
|
|
52
|
-
expect(fillPalette['exon-3']).toBe(segmentShades[0])
|
|
53
|
-
expect(fillPalette.PF00069).not.toBe(segmentShades[0])
|
|
54
|
-
expect(fillPalette.PF00069).not.toBe(segmentShades[1])
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test('exons are labeled by their number', () => {
|
|
58
|
-
const { segmentLabels } = makeModel()
|
|
59
|
-
expect(segmentLabels.get('exon-1')).toBe('1')
|
|
60
|
-
expect(segmentLabels.get('exon-2')).toBe('2')
|
|
61
|
-
expect(segmentLabels.get('exon-3')).toBe('3')
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
test('legend lists only categorical domains, not exons', () => {
|
|
65
|
-
const model = makeModel()
|
|
66
|
-
for (const acc of ['exon-1', 'exon-2', 'exon-3', 'PF00069']) {
|
|
67
|
-
model.setFilter(acc, true)
|
|
68
|
-
}
|
|
69
|
-
expect(model.visibleDomainTypes.map(d => d.accession)).toEqual(['PF00069'])
|
|
70
|
-
})
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// seqPos -> global column, exercised through the model method rather than the
|
|
2
|
-
// buildSeqPosIndex primitive behind it: the method is what
|
|
3
|
-
// jbrowse-plugin-protein3d calls (see the cross-repo note in model.ts), and it
|
|
4
|
-
// owns the past-the-end answers the index alone cannot give.
|
|
5
|
-
import { describe, expect, test } from 'vitest'
|
|
6
|
-
|
|
7
|
-
import MSAModelF from './model.ts'
|
|
8
|
-
|
|
9
|
-
function colsOf(row: string, positions: number[]) {
|
|
10
|
-
const model = MSAModelF().create({
|
|
11
|
-
type: 'MsaView',
|
|
12
|
-
data: { msa: `>r\n${row}` },
|
|
13
|
-
})
|
|
14
|
-
model.setWidth(800)
|
|
15
|
-
return positions.map(pos => model.seqPosToGlobalCol('r', pos))
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
describe('seqPosToGlobalCol', () => {
|
|
19
|
-
test('is the identity when the row has no gaps', () => {
|
|
20
|
-
// 8 residues, so seqPos 8 is one past the end
|
|
21
|
-
expect(colsOf('ATGCATGC', [0, 3, 7, 8])).toEqual([0, 3, 7, 8])
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
test('skips gap columns', () => {
|
|
25
|
-
// Global: A(0) -(1) T(2) G(3) -(4) C(5) A(6) -(7) T(8) G(9) C(10)
|
|
26
|
-
// SeqPos: A(0) T(1) G(2) C(3) A(4) T(5) G(6) C(7)
|
|
27
|
-
expect(colsOf('A-TG-CA-TGC', [0, 1, 2, 3, 4, 5, 6, 7, 8])).toEqual([
|
|
28
|
-
0, 2, 3, 5, 6, 8, 9, 10, 11,
|
|
29
|
-
])
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('counts both gap characters, - and .', () => {
|
|
33
|
-
// Global: A(0) -(1) .(2) G(3) -(4) C(5) .(6)
|
|
34
|
-
// SeqPos: A(0) G(1) C(2)
|
|
35
|
-
expect(colsOf('A-.G-C.', [0, 1, 2, 3])).toEqual([0, 3, 5, 7])
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('handles leading and trailing gaps', () => {
|
|
39
|
-
expect(colsOf('--ACG', [0, 1, 2])).toEqual([2, 3, 4])
|
|
40
|
-
expect(colsOf('ACG--', [0, 1, 2, 3])).toEqual([0, 1, 2, 5])
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
test('an all-gap row reports position 0 at column 0', () => {
|
|
44
|
-
expect(colsOf('---..--', [0, 1])).toEqual([0, 7])
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
test('an empty row reports column 0', () => {
|
|
48
|
-
expect(colsOf('', [0])).toEqual([0])
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
test('an unknown row reports column 0', () => {
|
|
52
|
-
const model = MSAModelF().create({
|
|
53
|
-
type: 'MsaView',
|
|
54
|
-
data: { msa: '>r\nACGT' },
|
|
55
|
-
})
|
|
56
|
-
model.setWidth(800)
|
|
57
|
-
expect(model.seqPosToGlobalCol('nope', 2)).toBe(0)
|
|
58
|
-
})
|
|
59
|
-
})
|
package/src/sequenceLogo.test.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { columnCountsFromColumns } from './columnCounts.ts'
|
|
4
|
-
import { columnLogoStack, maxBitsFor } from './sequenceLogo.ts'
|
|
5
|
-
|
|
6
|
-
const dnaBits = maxBitsFor('dna')
|
|
7
|
-
const aminoBits = maxBitsFor('amino')
|
|
8
|
-
|
|
9
|
-
function stackOf(column: string, maxBits = dnaBits) {
|
|
10
|
-
return columnLogoStack(columnCountsFromColumns([column]), 0, maxBits)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
test('maxBits is log2 of the alphabet', () => {
|
|
14
|
-
expect(maxBitsFor('dna')).toBe(2)
|
|
15
|
-
expect(maxBitsFor('rna')).toBe(2)
|
|
16
|
-
expect(maxBitsFor('amino')).toBeCloseTo(4.3219, 4)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
test('a fully conserved column is one letter at the full height', () => {
|
|
20
|
-
const stack = stackOf('AAAA')
|
|
21
|
-
expect(stack).toHaveLength(1)
|
|
22
|
-
expect(stack[0]!.letter).toBe('A')
|
|
23
|
-
expect(stack[0]!.bits).toBeCloseTo(2, 10)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
test('an even four-way column carries no information', () => {
|
|
27
|
-
expect(stackOf('ACGT')).toEqual([])
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
test('a two-way split is half the height, shared evenly', () => {
|
|
31
|
-
const stack = stackOf('AACC')
|
|
32
|
-
expect(stack.map(s => s.letter)).toEqual(['A', 'C'])
|
|
33
|
-
// entropy 1 bit, so information content is 2 - 1 = 1, split evenly
|
|
34
|
-
expect(stack[0]!.bits).toBeCloseTo(0.5, 10)
|
|
35
|
-
expect(stack[1]!.bits).toBeCloseTo(0.5, 10)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('letters are ordered ascending so the tallest draws last, on top', () => {
|
|
39
|
-
const stack = stackOf('AAAC')
|
|
40
|
-
expect(stack.map(s => s.letter)).toEqual(['C', 'A'])
|
|
41
|
-
expect(stack[0]!.bits).toBeLessThan(stack[1]!.bits)
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
test('ties break on letter so redraws are stable', () => {
|
|
45
|
-
expect(stackOf('GGCC').map(s => s.letter)).toEqual(['C', 'G'])
|
|
46
|
-
expect(stackOf('CCGG').map(s => s.letter)).toEqual(['C', 'G'])
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('gaps scale the stack down without skewing the frequencies', () => {
|
|
50
|
-
// 'A' is the only residue, so it takes the whole stack either way; the height
|
|
51
|
-
// is what the gaps change
|
|
52
|
-
const clean = stackOf('AAAA')
|
|
53
|
-
const gappy = stackOf('AA--')
|
|
54
|
-
expect(gappy[0]!.letter).toBe('A')
|
|
55
|
-
expect(gappy[0]!.bits).toBeCloseTo(clean[0]!.bits / 2, 10)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
test('gaps do not make a two-residue column look like a four-way one', () => {
|
|
59
|
-
// frequencies come from the two real residues, so this is a 1-bit choice
|
|
60
|
-
// scaled by the half-gap occupancy, not a 4-way split
|
|
61
|
-
const stack = stackOf('AC--')
|
|
62
|
-
expect(stack.map(s => s.letter)).toEqual(['A', 'C'])
|
|
63
|
-
expect(stack[0]!.bits + stack[1]!.bits).toBeCloseTo(0.5, 10)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test('an all-gap column has no stack', () => {
|
|
67
|
-
expect(stackOf('----')).toEqual([])
|
|
68
|
-
expect(stackOf('....')).toEqual([])
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
test('the protein ceiling is higher than the nucleotide one', () => {
|
|
72
|
-
const protein = stackOf('WWWW', aminoBits)
|
|
73
|
-
expect(protein[0]!.bits).toBeCloseTo(aminoBits, 10)
|
|
74
|
-
expect(protein[0]!.bits).toBeGreaterThan(stackOf('AAAA')[0]!.bits)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('stack height never exceeds the ceiling', () => {
|
|
78
|
-
const columns = ['AAAA', 'AACG', 'A-C-', 'ACGT', 'AAAT']
|
|
79
|
-
for (const column of columns) {
|
|
80
|
-
const total = stackOf(column).reduce((a, b) => a + b.bits, 0)
|
|
81
|
-
expect(total).toBeLessThanOrEqual(dnaBits + 1e-9)
|
|
82
|
-
}
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
test('a column past the end of a ragged alignment is empty, not a crash', () => {
|
|
86
|
-
const counts = columnCountsFromColumns(['AC'])
|
|
87
|
-
expect(columnLogoStack(counts, 5, dnaBits)).toEqual([])
|
|
88
|
-
})
|
package/src/setFontSize.test.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { setFontSize } from './setFontSize.ts'
|
|
4
|
-
|
|
5
|
-
describe('setFontSize', () => {
|
|
6
|
-
test('replaces integer size, preserving family', () => {
|
|
7
|
-
const ctx = { font: '10px sans-serif' }
|
|
8
|
-
setFontSize(ctx, 16)
|
|
9
|
-
expect(ctx.font).toBe('16px sans-serif')
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
test('handles fractional sizes from smooth zoom', () => {
|
|
13
|
-
// regression: \d+ alone matched "8604" inside "14.8604px" and produced an
|
|
14
|
-
// invalid string like "14 0.18px sans-serif", silently breaking fillText
|
|
15
|
-
const ctx = { font: '14.8604px sans-serif' }
|
|
16
|
-
setFontSize(ctx, 16.9372)
|
|
17
|
-
expect(ctx.font).toBe('16.9372px sans-serif')
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
test('does not accumulate "bold " across re-renders', () => {
|
|
21
|
-
const ctx = { font: '10px sans-serif' }
|
|
22
|
-
setFontSize(ctx, 12, true)
|
|
23
|
-
expect(ctx.font).toBe('bold 12px sans-serif')
|
|
24
|
-
setFontSize(ctx, 14, true)
|
|
25
|
-
expect(ctx.font).toBe('bold 14px sans-serif')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('drops "bold " when bold goes false', () => {
|
|
29
|
-
const ctx = { font: 'bold 12px sans-serif' }
|
|
30
|
-
setFontSize(ctx, 14)
|
|
31
|
-
expect(ctx.font).toBe('14px sans-serif')
|
|
32
|
-
})
|
|
33
|
-
})
|
package/src/stripDefault.test.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { getSnapshot, types } from '@jbrowse/mobx-state-tree'
|
|
2
|
-
import { afterEach, expect, test } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import { stripDefault } from './stripDefault.ts'
|
|
5
|
-
|
|
6
|
-
const real = types.stripDefault
|
|
7
|
-
|
|
8
|
-
afterEach(() => {
|
|
9
|
-
types.stripDefault = real
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
test('strips defaults from the snapshot when the host mst supports it', () => {
|
|
13
|
-
const model = types
|
|
14
|
-
.model({ a: stripDefault(types.boolean, false) })
|
|
15
|
-
.create({})
|
|
16
|
-
expect(model.a).toBe(false)
|
|
17
|
-
expect(getSnapshot(model).a).toBeUndefined()
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
// The path that actually runs inside every RELEASED jbrowse-web: the host
|
|
21
|
-
// supplies its own mobx-state-tree, and stripDefault only exists in the copy
|
|
22
|
-
// that ships with unreleased @jbrowse/core. Calling it there used to throw while
|
|
23
|
-
// the model was built, which error-paged the whole app. dev has the API, so
|
|
24
|
-
// without stubbing it away this path is never exercised.
|
|
25
|
-
test('falls back to types.optional when the host mst lacks stripDefault', () => {
|
|
26
|
-
// @ts-expect-error deleting it is the point: simulate an older host
|
|
27
|
-
delete types.stripDefault
|
|
28
|
-
const model = types
|
|
29
|
-
.model({ a: stripDefault(types.boolean, false) })
|
|
30
|
-
.create({})
|
|
31
|
-
expect(model.a).toBe(false)
|
|
32
|
-
// the only difference: the default is serialized rather than omitted
|
|
33
|
-
expect(getSnapshot(model).a).toBe(false)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
test('non-default values survive both paths', () => {
|
|
37
|
-
const withApi = types
|
|
38
|
-
.model({ a: stripDefault(types.number, 1) })
|
|
39
|
-
.create({ a: 5 })
|
|
40
|
-
expect(getSnapshot(withApi).a).toBe(5)
|
|
41
|
-
|
|
42
|
-
// @ts-expect-error see above
|
|
43
|
-
delete types.stripDefault
|
|
44
|
-
const without = types
|
|
45
|
-
.model({ a: stripDefault(types.number, 1) })
|
|
46
|
-
.create({ a: 5 })
|
|
47
|
-
expect(getSnapshot(without).a).toBe(5)
|
|
48
|
-
})
|