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/dist/useColorContrast.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { useTheme } from '@mui/material';
|
|
3
|
-
import { colorContrast } from './util.js';
|
|
4
|
-
/**
|
|
5
|
-
* Resolves the current theme and a memoized contrast-color scheme for a given
|
|
6
|
-
* color scheme. Shared by the MSA and text-track canvas blocks.
|
|
7
|
-
*/
|
|
8
|
-
export function useColorContrast(colorScheme) {
|
|
9
|
-
const theme = useTheme();
|
|
10
|
-
const contrastScheme = useMemo(() => colorContrast(colorScheme, theme), [colorScheme, theme]);
|
|
11
|
-
return { theme, contrastScheme };
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=useColorContrast.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useColorContrast.js","sourceRoot":"","sources":["../src/useColorContrast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmC;IAClE,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,MAAM,cAAc,GAAG,OAAO,CAC5B,GAAG,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,EACvC,CAAC,WAAW,EAAE,KAAK,CAAC,CACrB,CAAA;IACD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;AAClC,CAAC"}
|
package/src/clustalX.test.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { clustalXColumnColors } from './clustalX.ts'
|
|
4
|
-
import { columnCountsFromColumns } from './columnCounts.ts'
|
|
5
|
-
|
|
6
|
-
// one alignment column, given top-to-bottom
|
|
7
|
-
function column(letters: string) {
|
|
8
|
-
return clustalXColumnColors(columnCountsFromColumns([letters]), 0)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const BLUE = 'rgb(128,179,230)'
|
|
12
|
-
const RED = '#d88'
|
|
13
|
-
const GREEN = '#8f8'
|
|
14
|
-
const GREEN_ST = 'rgb(26,204,26)'
|
|
15
|
-
const ORANGE = 'rgb(240, 144, 72)'
|
|
16
|
-
const YELLOW = 'rgb(204, 204, 0)'
|
|
17
|
-
const CYAN = 'rgb(26, 179, 179)'
|
|
18
|
-
|
|
19
|
-
describe('clustalXColumnColors', () => {
|
|
20
|
-
test('hydrophobic column (all L) colors the hydrophobic group', () => {
|
|
21
|
-
expect(column('LLLLLLLLLL')).toEqual({
|
|
22
|
-
W: BLUE,
|
|
23
|
-
L: BLUE,
|
|
24
|
-
V: BLUE,
|
|
25
|
-
A: BLUE,
|
|
26
|
-
I: BLUE,
|
|
27
|
-
M: BLUE,
|
|
28
|
-
F: BLUE,
|
|
29
|
-
C: BLUE,
|
|
30
|
-
S: GREEN_ST,
|
|
31
|
-
T: GREEN_ST,
|
|
32
|
-
H: CYAN,
|
|
33
|
-
Y: CYAN,
|
|
34
|
-
})
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
test('glycine is always colored when present', () => {
|
|
38
|
-
expect(column('GGGGGGGGGG')).toEqual({
|
|
39
|
-
G: ORANGE,
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
test('proline is always colored, and counts as hydrophobic', () => {
|
|
44
|
-
expect(column('PPPPPPPPPP')).toEqual({
|
|
45
|
-
W: BLUE,
|
|
46
|
-
L: BLUE,
|
|
47
|
-
V: BLUE,
|
|
48
|
-
A: BLUE,
|
|
49
|
-
I: BLUE,
|
|
50
|
-
M: BLUE,
|
|
51
|
-
F: BLUE,
|
|
52
|
-
C: BLUE,
|
|
53
|
-
S: GREEN_ST,
|
|
54
|
-
T: GREEN_ST,
|
|
55
|
-
P: YELLOW,
|
|
56
|
-
H: CYAN,
|
|
57
|
-
Y: CYAN,
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test('positively charged column (all K)', () => {
|
|
62
|
-
expect(column('KKKKKKKKKK')).toEqual({
|
|
63
|
-
K: RED,
|
|
64
|
-
R: RED,
|
|
65
|
-
E: 'rgb(192, 72, 192)',
|
|
66
|
-
D: 'rgb(204, 77, 204)',
|
|
67
|
-
Q: GREEN,
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
test('unconserved column produces no colors', () => {
|
|
72
|
-
expect(column('XXXXXXXXXX')).toEqual({})
|
|
73
|
-
})
|
|
74
|
-
})
|
package/src/colSpace.test.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { expect, test } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import MSAModelF from './model.ts'
|
|
5
|
-
|
|
6
|
-
// a ragged alignment: row `a` stops early, so the alignment is as wide as `b`.
|
|
7
|
-
// Column space has to follow the widest row -- the gap analysis already does --
|
|
8
|
-
// or every column past the first row's end becomes unreachable: unscrollable,
|
|
9
|
-
// unhoverable, and missing from the minimap.
|
|
10
|
-
const msa = `>a
|
|
11
|
-
ACGT
|
|
12
|
-
>b
|
|
13
|
-
ACGTACGTAC`
|
|
14
|
-
|
|
15
|
-
function makeModel() {
|
|
16
|
-
const model = MSAModelF().create({
|
|
17
|
-
id: 'col-space-test',
|
|
18
|
-
type: 'MsaView',
|
|
19
|
-
msaFormat: 'fasta',
|
|
20
|
-
data: { msa },
|
|
21
|
-
})
|
|
22
|
-
model.setWidth(800)
|
|
23
|
-
return model
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
test('column space spans the widest row', () => {
|
|
27
|
-
const model = makeModel()
|
|
28
|
-
expect(model.numColumns).toBe(10)
|
|
29
|
-
expect(model.totalWidth).toBe(10 * model.colWidth)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('the last column agrees with the column statistics', () => {
|
|
33
|
-
const model = makeModel()
|
|
34
|
-
expect(model.colStats.numColumns).toBe(model.numColumns)
|
|
35
|
-
expect(model.conservation).toHaveLength(model.numColumns)
|
|
36
|
-
|
|
37
|
-
model.setMousePos(model.numColumns - 1, 1)
|
|
38
|
-
expect(model.mouseOverColumnStats?.col).toBe(9)
|
|
39
|
-
expect(model.visibleColToRowLetter('b', 9)).toBe('C')
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// enough rows to force the vertical scrollbar, which eats into the width the
|
|
43
|
-
// alignment canvas actually gets
|
|
44
|
-
function makeTallModel() {
|
|
45
|
-
const names = Array.from({ length: 60 }, (_, i) => `seq${i}`)
|
|
46
|
-
const model = MSAModelF().create({
|
|
47
|
-
id: 'col-fit-test',
|
|
48
|
-
type: 'MsaView',
|
|
49
|
-
msaFormat: 'fasta',
|
|
50
|
-
height: 300,
|
|
51
|
-
data: { msa: names.map(n => `>${n}\n${'ACGT'.repeat(50)}`).join('\n') },
|
|
52
|
-
})
|
|
53
|
-
model.setWidth(800)
|
|
54
|
-
return model
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
test('fit horizontally leaves every column on screen', () => {
|
|
58
|
-
const model = makeTallModel()
|
|
59
|
-
expect(model.showVerticalScrollbar).toBe(true)
|
|
60
|
-
|
|
61
|
-
model.fitHorizontally()
|
|
62
|
-
// the canvas is the msa area minus the scrollbar; fitting to the msa area
|
|
63
|
-
// alone pushed the last columns past the right edge, with no minimap to
|
|
64
|
-
// show that anything was cut off
|
|
65
|
-
expect(model.totalWidth).toBeLessThanOrEqual(model.msaCanvasWidth)
|
|
66
|
-
expect(model.showHorizontalScrollbar).toBe(false)
|
|
67
|
-
})
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { collapse, find, hierarchy, leaves, sort, sum } from './hierarchy.ts'
|
|
4
|
-
|
|
5
|
-
import type { NodeWithIds } from './types.ts'
|
|
6
|
-
|
|
7
|
-
function buildRoot(tree: NodeWithIds, collapsed: string[], showOnly?: string) {
|
|
8
|
-
let hier = hierarchy(tree, d => d.children)
|
|
9
|
-
sum(hier, d => (d.children.length > 0 ? 0 : 1))
|
|
10
|
-
sort(hier, (a, b) => (a.data.length ?? 1) - (b.data.length ?? 1))
|
|
11
|
-
|
|
12
|
-
if (showOnly) {
|
|
13
|
-
const res = find(hier, n => n.data.id === showOnly)
|
|
14
|
-
if (res) {
|
|
15
|
-
hier = res
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
for (const collapsedId of collapsed) {
|
|
20
|
-
const node = find(hier, n => n.data.id === collapsedId)
|
|
21
|
-
if (!node) {
|
|
22
|
-
continue
|
|
23
|
-
}
|
|
24
|
-
if (node.children) {
|
|
25
|
-
collapse(node)
|
|
26
|
-
} else if (node.parent?.children) {
|
|
27
|
-
node.parent.children = node.parent.children.filter(
|
|
28
|
-
c => c.data.id !== collapsedId,
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return hier
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function simpleTree(): NodeWithIds {
|
|
37
|
-
return {
|
|
38
|
-
id: 'root',
|
|
39
|
-
name: 'root',
|
|
40
|
-
children: [
|
|
41
|
-
{
|
|
42
|
-
id: 'clade1',
|
|
43
|
-
name: 'clade1',
|
|
44
|
-
children: [
|
|
45
|
-
{ id: 'seq1', name: 'seq1', children: [] },
|
|
46
|
-
{ id: 'seq2', name: 'seq2', children: [] },
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: 'clade2',
|
|
51
|
-
name: 'clade2',
|
|
52
|
-
children: [
|
|
53
|
-
{ id: 'seq3', name: 'seq3', children: [] },
|
|
54
|
-
{ id: 'seq4', name: 'seq4', children: [] },
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
describe('collapse logic (mirrors model.root getter)', () => {
|
|
62
|
-
test('no collapsed nodes returns all leaves', () => {
|
|
63
|
-
const root = buildRoot(simpleTree(), [])
|
|
64
|
-
expect(leaves(root).map(n => n.data.name)).toEqual([
|
|
65
|
-
'seq1',
|
|
66
|
-
'seq2',
|
|
67
|
-
'seq3',
|
|
68
|
-
'seq4',
|
|
69
|
-
])
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
test('collapsing a branch hides its children', () => {
|
|
73
|
-
const root = buildRoot(simpleTree(), ['clade1'])
|
|
74
|
-
const l = leaves(root).map(n => n.data.name)
|
|
75
|
-
expect(l).toEqual(['clade1', 'seq3', 'seq4'])
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
test('collapsing a leaf node removes it', () => {
|
|
79
|
-
const root = buildRoot(simpleTree(), ['seq2'])
|
|
80
|
-
const l = leaves(root).map(n => n.data.name)
|
|
81
|
-
expect(l).toEqual(['seq1', 'seq3', 'seq4'])
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
test('collapsing multiple leaves', () => {
|
|
85
|
-
const root = buildRoot(simpleTree(), ['seq1', 'seq4'])
|
|
86
|
-
const l = leaves(root).map(n => n.data.name)
|
|
87
|
-
expect(l).toEqual(['seq2', 'seq3'])
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test('collapsing a branch and a leaf in another branch', () => {
|
|
91
|
-
const root = buildRoot(simpleTree(), ['clade1', 'seq3'])
|
|
92
|
-
const l = leaves(root).map(n => n.data.name)
|
|
93
|
-
expect(l).toEqual(['clade1', 'seq4'])
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
test('collapsing nonexistent id is a no-op', () => {
|
|
97
|
-
const root = buildRoot(simpleTree(), ['doesnotexist'])
|
|
98
|
-
expect(leaves(root).map(n => n.data.name)).toEqual([
|
|
99
|
-
'seq1',
|
|
100
|
-
'seq2',
|
|
101
|
-
'seq3',
|
|
102
|
-
'seq4',
|
|
103
|
-
])
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
test('showOnly focuses on a subtree', () => {
|
|
107
|
-
const root = buildRoot(simpleTree(), [], 'clade2')
|
|
108
|
-
expect(leaves(root).map(n => n.data.name)).toEqual(['seq3', 'seq4'])
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
test('showOnly + collapse within subtree', () => {
|
|
112
|
-
const root = buildRoot(simpleTree(), ['seq3'], 'clade2')
|
|
113
|
-
expect(leaves(root).map(n => n.data.name)).toEqual(['seq4'])
|
|
114
|
-
})
|
|
115
|
-
})
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs'
|
|
2
|
-
|
|
3
|
-
import { expect, test } from 'vitest'
|
|
4
|
-
|
|
5
|
-
import colorSchemes from './colorSchemes.ts'
|
|
6
|
-
|
|
7
|
-
// Guard against doc drift: every color-scheme name listed in the JS embedding
|
|
8
|
-
// docs (USAGE.md) must be a real registered scheme, so a rename or removal in
|
|
9
|
-
// colorSchemes.ts can't silently leave a dead name in the docs that users copy.
|
|
10
|
-
// (Subset check only — a registered scheme may intentionally go undocumented.)
|
|
11
|
-
test('color schemes listed in USAGE.md all exist', () => {
|
|
12
|
-
const registered = new Set(Object.keys(colorSchemes))
|
|
13
|
-
const usage = readFileSync(
|
|
14
|
-
new URL('../../../USAGE.md', import.meta.url),
|
|
15
|
-
'utf8',
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
const section = /## Color schemes\n([\s\S]*?)\n## /.exec(usage)?.[1]
|
|
19
|
-
expect(section, 'could not find the "## Color schemes" section').toBeTruthy()
|
|
20
|
-
|
|
21
|
-
// drop the bold labels (**Protein:**, **Dynamic (per-column):**, …), leaving
|
|
22
|
-
// just the comma-separated scheme names
|
|
23
|
-
const names = section!.replace(/\*\*[^*]+\*\*/g, '').match(/[a-z][a-z0-9_]+/g)
|
|
24
|
-
expect(names?.length).toBeGreaterThan(0)
|
|
25
|
-
|
|
26
|
-
const unknown = names!.filter(name => !registered.has(name))
|
|
27
|
-
expect(
|
|
28
|
-
unknown,
|
|
29
|
-
`documented but not registered: ${unknown.join(', ')}`,
|
|
30
|
-
).toEqual([])
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
// Same guard for the R package docs, whose color_scheme names pass straight
|
|
34
|
-
// through as colorSchemeName with no remapping — a name that isn't registered
|
|
35
|
-
// silently renders with no coloring.
|
|
36
|
-
test('color schemes listed in the R README all exist', () => {
|
|
37
|
-
const registered = new Set(Object.keys(colorSchemes))
|
|
38
|
-
const readme = readFileSync(
|
|
39
|
-
new URL('../../r-msaview/README.md', import.meta.url),
|
|
40
|
-
'utf8',
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
const section = /## Color schemes\n([\s\S]*?)\n## /.exec(readme)?.[1]
|
|
44
|
-
expect(section, 'could not find the "## Color schemes" section').toBeTruthy()
|
|
45
|
-
|
|
46
|
-
// names are backtick-quoted, e.g. `jalview_taylor`
|
|
47
|
-
const names = [...section!.matchAll(/`([a-z][a-z0-9_]+)`/g)].flatMap(m =>
|
|
48
|
-
m[1] ? [m[1]] : [],
|
|
49
|
-
)
|
|
50
|
-
expect(names.length).toBeGreaterThan(0)
|
|
51
|
-
|
|
52
|
-
const unknown = names.filter(name => !registered.has(name))
|
|
53
|
-
expect(
|
|
54
|
-
unknown,
|
|
55
|
-
`documented but not registered: ${unknown.join(', ')}`,
|
|
56
|
-
).toEqual([])
|
|
57
|
-
})
|
package/src/columnCounts.test.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
columnCountsFromColumns,
|
|
5
|
-
columnCountsFromRows,
|
|
6
|
-
letterOfResidueSlot,
|
|
7
|
-
} from './columnCounts.ts'
|
|
8
|
-
|
|
9
|
-
describe('columnCounts', () => {
|
|
10
|
-
test('tallies residues and gaps per column', () => {
|
|
11
|
-
const counts = columnCountsFromRows(['AC-', 'AG.', 'AC-'])
|
|
12
|
-
expect(counts.numColumns).toBe(3)
|
|
13
|
-
expect(counts.count(0, 'A')).toBe(3)
|
|
14
|
-
expect(counts.count(1, 'C')).toBe(2)
|
|
15
|
-
expect(counts.count(1, 'G')).toBe(1)
|
|
16
|
-
expect(counts.total(2)).toBe(3)
|
|
17
|
-
expect(counts.gapCount(2)).toBe(3)
|
|
18
|
-
expect(counts.gapCount(0)).toBe(0)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
test('counts both gap characters, and neither as a residue', () => {
|
|
22
|
-
const counts = columnCountsFromColumns(['-.A'])
|
|
23
|
-
expect(counts.count(0, '-')).toBe(1)
|
|
24
|
-
expect(counts.count(0, '.')).toBe(1)
|
|
25
|
-
expect(counts.gapCount(0)).toBe(2)
|
|
26
|
-
expect(counts.residueEntries(0)).toEqual([['A', 1]])
|
|
27
|
-
expect(counts.lettersPresent).toEqual(new Set(['A']))
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
test('folds case, so lowercase (a3m insertions) counts as its residue', () => {
|
|
31
|
-
const counts = columnCountsFromColumns(['aA'])
|
|
32
|
-
expect(counts.count(0, 'A')).toBe(2)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('digits and punctuation do not land on letter slots', () => {
|
|
36
|
-
// a plain `code & 31` would fold '0' onto 'P' and '!' onto 'A'
|
|
37
|
-
const counts = columnCountsFromColumns(['0!'])
|
|
38
|
-
expect(counts.count(0, 'P')).toBe(0)
|
|
39
|
-
expect(counts.count(0, 'A')).toBe(0)
|
|
40
|
-
expect(counts.residueEntries(0)).toEqual([['?', 2]])
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
test('ragged rows: the widest row sets the column count', () => {
|
|
44
|
-
const counts = columnCountsFromRows(['AAAA', 'AA'])
|
|
45
|
-
expect(counts.numColumns).toBe(4)
|
|
46
|
-
expect(counts.total(0)).toBe(2)
|
|
47
|
-
expect(counts.total(3)).toBe(1)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test('entropy is taken over the non-gap residues only', () => {
|
|
51
|
-
const counts = columnCountsFromColumns(['AAAA', 'AACC', 'ACGT', 'AC--'])
|
|
52
|
-
// fully conserved: no choice left to make
|
|
53
|
-
expect(counts.entropy(0)).toBeCloseTo(0, 10)
|
|
54
|
-
// even two-way and four-way splits
|
|
55
|
-
expect(counts.entropy(1)).toBeCloseTo(1, 10)
|
|
56
|
-
expect(counts.entropy(2)).toBeCloseTo(2, 10)
|
|
57
|
-
// the two gaps do not turn a 1-bit choice into a 2-bit one
|
|
58
|
-
expect(counts.entropy(3)).toBeCloseTo(1, 10)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test('an all-gap column has no entropy rather than NaN', () => {
|
|
62
|
-
expect(columnCountsFromColumns(['----']).entropy(0)).toBe(0)
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
test('residue slots round-trip to their letters', () => {
|
|
66
|
-
const counts = columnCountsFromColumns(['WY'])
|
|
67
|
-
const slots: number[] = []
|
|
68
|
-
counts.forEachResidue(0, slot => {
|
|
69
|
-
slots.push(slot)
|
|
70
|
-
})
|
|
71
|
-
expect(slots.map(letterOfResidueSlot)).toEqual(['W', 'Y'])
|
|
72
|
-
})
|
|
73
|
-
})
|
package/src/columnStats.test.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { beforeAll, describe, expect, test } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import MSAModelF from './model.ts'
|
|
5
|
-
|
|
6
|
-
beforeAll(() => {
|
|
7
|
-
HTMLCanvasElement.prototype.getContext = function () {
|
|
8
|
-
let font = '10px sans-serif'
|
|
9
|
-
return {
|
|
10
|
-
get font() {
|
|
11
|
-
return font
|
|
12
|
-
},
|
|
13
|
-
set font(v: string) {
|
|
14
|
-
font = v
|
|
15
|
-
},
|
|
16
|
-
measureText(t: string) {
|
|
17
|
-
const size = Number.parseFloat(font) || 10
|
|
18
|
-
return { width: t.length * size * 0.6 } as TextMetrics
|
|
19
|
-
},
|
|
20
|
-
} as unknown as CanvasRenderingContext2D
|
|
21
|
-
} as unknown as typeof HTMLCanvasElement.prototype.getContext
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// col0 is invariant M; col3 varies V/V/A (all hydrophobic) so property
|
|
25
|
-
// conservation stays high while identity conservation drops
|
|
26
|
-
const protein = `>a
|
|
27
|
-
MKLVIL
|
|
28
|
-
>b
|
|
29
|
-
MRLVIL
|
|
30
|
-
>c
|
|
31
|
-
MKLAIL`
|
|
32
|
-
|
|
33
|
-
const dna = `>a
|
|
34
|
-
ACGTAC
|
|
35
|
-
>b
|
|
36
|
-
ACGTAG
|
|
37
|
-
>c
|
|
38
|
-
ACGAAC`
|
|
39
|
-
|
|
40
|
-
function make(msa: string, id: string) {
|
|
41
|
-
return MSAModelF().create({
|
|
42
|
-
id,
|
|
43
|
-
type: 'MsaView',
|
|
44
|
-
msaFormat: 'fasta',
|
|
45
|
-
data: { msa },
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
describe('property conservation track', () => {
|
|
50
|
-
test('present for protein alignments', () => {
|
|
51
|
-
const ids = make(protein, 'p').tracks.map(t => t.model.id)
|
|
52
|
-
expect(ids).toContain('conservation')
|
|
53
|
-
expect(ids).toContain('property-conservation')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('omitted for nucleotide alignments', () => {
|
|
57
|
-
const ids = make(dna, 'd').tracks.map(t => t.model.id)
|
|
58
|
-
expect(ids).toContain('conservation')
|
|
59
|
-
expect(ids).not.toContain('property-conservation')
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
test('conservative-substitution column: property beats identity', () => {
|
|
63
|
-
const model = make(protein, 'pc')
|
|
64
|
-
// col3 = V/V/A: same property class, different identity
|
|
65
|
-
expect(model.propertyConservation[3]!).toBeGreaterThan(
|
|
66
|
-
model.conservation[3]!,
|
|
67
|
-
)
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
describe('mouseOverColumnStats', () => {
|
|
72
|
-
test('undefined when nothing hovered', () => {
|
|
73
|
-
expect(make(protein, 'm0').mouseOverColumnStats).toBeUndefined()
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
test('reports consensus, gaps and distribution for hovered column', () => {
|
|
77
|
-
const model = make(protein, 'm1')
|
|
78
|
-
model.setMousePos(0, 0)
|
|
79
|
-
const s = model.mouseOverColumnStats
|
|
80
|
-
expect(s?.consensusLetter).toBe('M')
|
|
81
|
-
expect(s?.consensusFraction).toBe(1)
|
|
82
|
-
expect(s?.gapFraction).toBe(0)
|
|
83
|
-
expect(s?.total).toBe(3)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
test('mixed column reports the majority residue as consensus', () => {
|
|
87
|
-
const model = make(protein, 'm2')
|
|
88
|
-
// col1 = K/R/K -> consensus K at 2/3
|
|
89
|
-
model.setMousePos(1, 0)
|
|
90
|
-
const s = model.mouseOverColumnStats
|
|
91
|
-
expect(s?.consensusLetter).toBe('K')
|
|
92
|
-
expect(s?.consensusCount).toBe(2)
|
|
93
|
-
})
|
|
94
|
-
})
|
package/src/columnTracks.test.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { getSnapshot } from '@jbrowse/mobx-state-tree'
|
|
2
|
-
import { expect, test } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import stateModelFactory from './model.ts'
|
|
5
|
-
|
|
6
|
-
import type { ColumnTrackSpec } from './types.ts'
|
|
7
|
-
|
|
8
|
-
const MsaView = stateModelFactory()
|
|
9
|
-
|
|
10
|
-
// s1 has a gap at column 1 and s2 a gap at column 3, and every row is gapped at
|
|
11
|
-
// column 5, so hiding gappy columns drops that one
|
|
12
|
-
const msa = '>s1\nA-CDE-F\n>s2\nAB-DE-F\n>s3\nABCDE-F\n'
|
|
13
|
-
|
|
14
|
-
function makeModel(columnTracks: ColumnTrackSpec[]) {
|
|
15
|
-
return MsaView.create({
|
|
16
|
-
type: 'MsaView',
|
|
17
|
-
msaFormat: 'fasta',
|
|
18
|
-
data: { msa },
|
|
19
|
-
columnTracks,
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
test('column-indexed values normalize by max and clamp to 0..1', () => {
|
|
24
|
-
const model = makeModel([
|
|
25
|
-
{ id: 't', name: 'T', kind: 'bar', values: [1, 2, 4, -1], max: 2 },
|
|
26
|
-
])
|
|
27
|
-
expect(model.columnTrackContent.get('t')?.values).toEqual([0.5, 1, 1, 0])
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
test('row-indexed values land on the residues of that row', () => {
|
|
31
|
-
const model = makeModel([
|
|
32
|
-
{ id: 't', name: 'T', kind: 'bar', values: [0.1, 0.2, 0.3], row: 's1' },
|
|
33
|
-
])
|
|
34
|
-
// residues 1..3 of s1 are A, C, D at global columns 0, 2, 3
|
|
35
|
-
expect(model.columnTrackContent.get('t')?.values).toEqual([
|
|
36
|
-
0.1, 0, 0.2, 0.3, 0, 0, 0,
|
|
37
|
-
])
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
test('a row-indexed text track spreads its letters the same way', () => {
|
|
41
|
-
const model = makeModel([
|
|
42
|
-
{ id: 'f', name: 'Frame', kind: 'text', data: '123', row: 's2' },
|
|
43
|
-
])
|
|
44
|
-
// residues of s2 sit at columns 0, 1, 3
|
|
45
|
-
expect(model.columnTrackContent.get('f')?.data).toBe('12 3 ')
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
test('hiding gappy columns drops them from the values and the text', () => {
|
|
49
|
-
const model = makeModel([
|
|
50
|
-
{ id: 't', name: 'T', kind: 'bar', values: [1, 2, 3, 4, 5, 6, 7], max: 7 },
|
|
51
|
-
{ id: 'f', name: 'F', kind: 'text', data: 'abcdefg' },
|
|
52
|
-
])
|
|
53
|
-
model.setHideGaps(true)
|
|
54
|
-
model.setAllowedGappyness(99)
|
|
55
|
-
expect(model.blanks).toEqual([5])
|
|
56
|
-
expect(model.columnTrackContent.get('t')?.values).toHaveLength(6)
|
|
57
|
-
expect(model.columnTrackContent.get('f')?.data).toBe('abcdeg')
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
test('data tracks join the track list with their own color and height', () => {
|
|
61
|
-
const model = makeModel([
|
|
62
|
-
{ id: 't', name: 'dN/dS', kind: 'bar', values: [1], color: 'red' },
|
|
63
|
-
{ id: 'f', name: 'Frame', kind: 'text', data: '1', colors: { 1: 'blue' } },
|
|
64
|
-
])
|
|
65
|
-
const ids = model.tracks.map(t => t.model.id)
|
|
66
|
-
expect(ids).toContain('t')
|
|
67
|
-
expect(ids).toContain('f')
|
|
68
|
-
const bar = model.tracks.find(t => t.model.id === 't')!.model
|
|
69
|
-
expect(bar.barColor).toBe('red')
|
|
70
|
-
expect(bar.height).toBe(model.conservationTrackHeight)
|
|
71
|
-
const text = model.tracks.find(t => t.model.id === 'f')!.model
|
|
72
|
-
expect(text.customColorScheme).toEqual({ 1: 'blue' })
|
|
73
|
-
expect(text.height).toBe(model.rowHeight)
|
|
74
|
-
expect(text.data).toBe('1')
|
|
75
|
-
|
|
76
|
-
expect(model.turnedOnTracks.map(t => t.model.id)).toContain('t')
|
|
77
|
-
model.toggleTrack('t')
|
|
78
|
-
expect(model.turnedOnTracks.map(t => t.model.id)).not.toContain('t')
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
test('setColumnTracks replaces the set and the snapshot carries it', () => {
|
|
82
|
-
const model = makeModel([])
|
|
83
|
-
expect(getSnapshot(model)).not.toHaveProperty('columnTracks')
|
|
84
|
-
model.setColumnTracks([{ id: 't', name: 'T', kind: 'bar', values: [0.5] }])
|
|
85
|
-
expect(getSnapshot(model).columnTracks).toEqual([
|
|
86
|
-
{ id: 't', name: 'T', kind: 'bar', values: [0.5] },
|
|
87
|
-
])
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test('a track too large to share leaves the snapshot but keeps drawing', () => {
|
|
91
|
-
const model = makeModel([
|
|
92
|
-
{ id: 'big', name: 'Big', kind: 'bar', values: Array(20_000).fill(0.5) },
|
|
93
|
-
{ id: 'small', name: 'Small', kind: 'bar', values: [0.5] },
|
|
94
|
-
])
|
|
95
|
-
expect(model.columnTrackContent.get('big')?.values).toHaveLength(20_000)
|
|
96
|
-
expect(getSnapshot(model).columnTracks?.map(t => t.id)).toEqual(['small'])
|
|
97
|
-
})
|