react-msaview 9.0.0 → 9.1.1
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 +19 -10
- package/bundle/index.js +111 -115
- package/bundle/index.js.map +4 -4
- package/dist/blosum62.d.ts +3 -0
- package/dist/blosum62.js +43 -0
- package/dist/blosum62.js.map +1 -0
- package/dist/colorSchemes.js +2 -3
- package/dist/colorSchemes.js.map +1 -1
- package/dist/columnCounts.d.ts +0 -1
- package/dist/columnCounts.js +1 -1
- package/dist/columnCounts.js.map +1 -1
- package/dist/components/Loading.d.ts +3 -2
- package/dist/components/Loading.js +7 -7
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/MSAView.d.ts +3 -2
- package/dist/components/MSAView.js +7 -4
- package/dist/components/MSAView.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +1941 -4
- package/dist/components/MSAViewer.js +144 -201
- package/dist/components/MSAViewer.js.map +1 -1
- package/dist/components/MetadataTable.d.ts +4 -1
- package/dist/components/MetadataTable.js +55 -16
- package/dist/components/MetadataTable.js.map +1 -1
- package/dist/components/ResizeHandles.js +3 -2
- package/dist/components/ResizeHandles.js.map +1 -1
- package/dist/components/Track.js +8 -1
- package/dist/components/Track.js.map +1 -1
- package/dist/components/controls.d.ts +11 -0
- package/dist/components/controls.js +49 -0
- package/dist/components/controls.js.map +1 -0
- package/dist/components/dialogs/AnnotationFileDialog.js +12 -18
- package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -1
- package/dist/components/dialogs/ExportSVGDialog.js +5 -7
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/dialogs/FeatureDialog.js +2 -2
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/{header/TreeSettingsMenu.d.ts → dialogs/GapThresholdDialog.d.ts} +3 -2
- package/dist/components/dialogs/GapThresholdDialog.js +15 -0
- package/dist/components/dialogs/GapThresholdDialog.js.map +1 -0
- package/dist/components/{header → dialogs}/GappynessSlider.d.ts +1 -1
- package/dist/components/{header → dialogs}/GappynessSlider.js +3 -10
- package/dist/components/dialogs/GappynessSlider.js.map +1 -0
- package/dist/components/{header → dialogs}/GoToBox.d.ts +4 -2
- package/dist/components/dialogs/GoToBox.js +48 -0
- package/dist/components/dialogs/GoToBox.js.map +1 -0
- package/dist/components/dialogs/GoToDialog.d.ts +6 -0
- package/dist/components/dialogs/GoToDialog.js +10 -0
- package/dist/components/dialogs/GoToDialog.js.map +1 -0
- package/dist/components/dialogs/HelpDialog.d.ts +6 -0
- package/dist/components/dialogs/HelpDialog.js +30 -0
- package/dist/components/dialogs/HelpDialog.js.map +1 -0
- package/dist/components/dialogs/MetadataDialog.js +11 -3
- package/dist/components/dialogs/MetadataDialog.js.map +1 -1
- package/dist/components/dialogs/goTo.d.ts +5 -0
- package/dist/components/{header → dialogs}/goTo.js +1 -1
- package/dist/components/dialogs/goTo.js.map +1 -0
- package/dist/components/dialogs/metadataLabels.d.ts +4 -0
- package/dist/components/dialogs/metadataLabels.js +52 -0
- package/dist/components/dialogs/metadataLabels.js.map +1 -0
- package/dist/components/dialogs/metadataRecord.d.ts +1 -0
- package/dist/components/dialogs/metadataRecord.js +38 -0
- package/dist/components/dialogs/metadataRecord.js.map +1 -0
- package/dist/components/header/Header.d.ts +6 -2
- package/dist/components/header/Header.js +30 -34
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HiddenColumnsChip.d.ts +6 -0
- package/dist/components/header/HiddenColumnsChip.js +15 -0
- package/dist/components/header/HiddenColumnsChip.js.map +1 -0
- package/dist/components/header/{FileMenu.d.ts → MenuBar.d.ts} +3 -3
- package/dist/components/header/MenuBar.js +33 -0
- package/dist/components/header/MenuBar.js.map +1 -0
- package/dist/components/header/ScrollZoomCheckbox.d.ts +7 -0
- package/dist/components/header/ScrollZoomCheckbox.js +19 -0
- package/dist/components/header/ScrollZoomCheckbox.js.map +1 -0
- package/dist/components/header/ZoomControls.js +12 -48
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/header/colorSchemeMenuItems.d.ts +4 -0
- package/dist/components/header/colorSchemeMenuItems.js +106 -0
- package/dist/components/header/colorSchemeMenuItems.js.map +1 -0
- package/dist/components/header/getAnnotationsMenu.d.ts +3 -30
- package/dist/components/header/getAnnotationsMenu.js +48 -54
- package/dist/components/header/getAnnotationsMenu.js.map +1 -1
- package/dist/components/header/menuBarItems.d.ts +11 -0
- package/dist/components/header/menuBarItems.js +277 -0
- package/dist/components/header/menuBarItems.js.map +1 -0
- package/dist/components/import/ImportForm.js +12 -6
- package/dist/components/import/ImportForm.js.map +1 -1
- package/dist/components/import/data/seq2.d.ts +0 -1
- package/dist/components/import/data/seq2.js +0 -17
- package/dist/components/import/data/seq2.js.map +1 -1
- package/dist/components/minimap/Minimap.js +7 -3
- package/dist/components/minimap/Minimap.js.map +1 -1
- package/dist/components/minimap/MinimapSVG.js +2 -1
- package/dist/components/minimap/MinimapSVG.js.map +1 -1
- package/dist/components/minimap/minimapLayout.d.ts +12 -0
- package/dist/components/minimap/minimapLayout.js +20 -0
- package/dist/components/minimap/minimapLayout.js.map +1 -1
- package/dist/components/msa/MSACanvas.js +28 -10
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +17 -16
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js +2 -2
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/msa/WheelZoomHint.d.ts +7 -0
- package/dist/components/msa/WheelZoomHint.js +38 -0
- package/dist/components/msa/WheelZoomHint.js.map +1 -0
- package/dist/components/msa/drawFeatureSpans.d.ts +50 -11
- package/dist/components/msa/drawFeatureSpans.js +99 -56
- package/dist/components/msa/drawFeatureSpans.js.map +1 -1
- package/dist/components/msa/msaKeys.js +3 -0
- package/dist/components/msa/msaKeys.js.map +1 -1
- package/dist/components/msa/msaRaster.d.ts +14 -2
- package/dist/components/msa/msaRaster.js +20 -10
- package/dist/components/msa/msaRaster.js.map +1 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +9 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +39 -8
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderHighlights.d.ts +2 -5
- package/dist/components/msa/renderHighlights.js +5 -6
- package/dist/components/msa/renderHighlights.js.map +1 -1
- package/dist/components/msa/renderMSABlock.d.ts +6 -1
- package/dist/components/msa/renderMSABlock.js +44 -17
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +2 -1
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/msa/tileColor.js +7 -0
- package/dist/components/msa/tileColor.js.map +1 -1
- package/dist/components/renderCtx.d.ts +1 -1
- package/dist/components/rowpanels/RowPanelBlock.js +2 -2
- package/dist/components/rowpanels/RowPanelBlock.js.map +1 -1
- package/dist/components/rowpanels/renderFeaturePanel.d.ts +5 -1
- package/dist/components/rowpanels/renderFeaturePanel.js +12 -5
- package/dist/components/rowpanels/renderFeaturePanel.js.map +1 -1
- package/dist/components/settings/MenuItemsForm.d.ts +10 -0
- package/dist/components/settings/MenuItemsForm.js +80 -0
- package/dist/components/settings/MenuItemsForm.js.map +1 -0
- package/dist/components/settings/SettingsPanel.d.ts +12 -0
- package/dist/components/settings/SettingsPanel.js +92 -0
- package/dist/components/settings/SettingsPanel.js.map +1 -0
- package/dist/components/{header/ZoomMenu.d.ts → settings/TrackList.d.ts} +2 -2
- package/dist/components/settings/TrackList.js +55 -0
- package/dist/components/settings/TrackList.js.map +1 -0
- package/dist/components/tracks/TrackBlocks.js +2 -2
- package/dist/components/tracks/TrackBlocks.js.map +1 -1
- package/dist/components/tracks/drawTracks.d.ts +1 -53
- package/dist/components/tracks/drawTracks.js +5 -5
- package/dist/components/tracks/drawTracks.js.map +1 -1
- package/dist/components/tree/CladeLabels.d.ts +1 -1
- package/dist/components/tree/CladeLabels.js +22 -34
- package/dist/components/tree/CladeLabels.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +2 -2
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeMenu.js +4 -6
- package/dist/components/tree/TreeMenu.js.map +1 -1
- package/dist/components/tree/TreeOverview.js +2 -2
- package/dist/components/tree/TreeOverview.js.map +1 -1
- package/dist/components/tree/cladeBrackets.d.ts +17 -10
- package/dist/components/tree/cladeBrackets.js +33 -3
- package/dist/components/tree/cladeBrackets.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.js +2 -8
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/components/tree/renderTreeOverview.js +4 -11
- package/dist/components/tree/renderTreeOverview.js.map +1 -1
- package/dist/constants.d.ts +4 -1
- package/dist/constants.js +7 -1
- package/dist/constants.js.map +1 -1
- package/dist/darkReader.d.ts +7 -0
- package/dist/darkReader.js +42 -0
- package/dist/darkReader.js.map +1 -0
- package/dist/element.js +25 -53
- package/dist/element.js.map +1 -1
- package/dist/exportLayout.d.ts +39 -0
- package/dist/exportLayout.js +78 -0
- package/dist/exportLayout.js.map +1 -0
- package/dist/featurePanels.d.ts +37 -0
- package/dist/featurePanels.js +187 -0
- package/dist/featurePanels.js.map +1 -0
- package/dist/filehandleLoader.d.ts +41 -0
- package/dist/filehandleLoader.js +99 -0
- package/dist/filehandleLoader.js.map +1 -0
- package/dist/headlessRenderEnv.d.ts +12 -39
- package/dist/headlessRenderEnv.js +18 -12
- package/dist/headlessRenderEnv.js.map +1 -1
- package/dist/hierarchy.d.ts +5 -8
- package/dist/hierarchy.js +5 -79
- package/dist/hierarchy.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/measureTextCanvas.d.ts +7 -0
- package/dist/measureTextCanvas.js +8 -6
- package/dist/measureTextCanvas.js.map +1 -1
- package/dist/model/treeModel.d.ts +6 -2
- package/dist/model/treeModel.js +8 -4
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +180 -76
- package/dist/model.js +358 -618
- package/dist/model.js.map +1 -1
- package/dist/neighborJoining.js +1 -40
- package/dist/neighborJoining.js.map +1 -1
- package/dist/renderToSvg.d.ts +2 -7
- package/dist/renderToSvg.js +33 -133
- package/dist/renderToSvg.js.map +1 -1
- package/dist/rerootTree.d.ts +1 -0
- package/dist/rerootTree.js +7 -6
- package/dist/rerootTree.js.map +1 -1
- package/dist/schemeResidueColor.d.ts +12 -0
- package/dist/schemeResidueColor.js +33 -0
- package/dist/schemeResidueColor.js.map +1 -0
- package/dist/similarityColors.d.ts +11 -0
- package/dist/similarityColors.js +90 -0
- package/dist/similarityColors.js.map +1 -0
- package/dist/svgTestUtil.d.ts +74 -32
- package/dist/treeDisplay.d.ts +37 -0
- package/dist/treeDisplay.js +209 -0
- package/dist/treeDisplay.js.map +1 -0
- package/dist/types.d.ts +6 -3
- package/dist/useWheelScroll.d.ts +3 -1
- package/dist/useWheelScroll.js +36 -17
- package/dist/useWheelScroll.js.map +1 -1
- package/dist/util.d.ts +2 -0
- package/dist/util.js +2 -0
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/viewerSnapshot.d.ts +169 -0
- package/dist/viewerSnapshot.js +100 -0
- package/dist/viewerSnapshot.js.map +1 -0
- package/dist/wheelZoom.d.ts +8 -3
- package/dist/wheelZoom.js +44 -32
- package/dist/wheelZoom.js.map +1 -1
- package/dist/zoomSnapshot.d.ts +29 -0
- package/dist/zoomSnapshot.js +47 -0
- package/dist/zoomSnapshot.js.map +1 -0
- package/package.json +11 -11
- package/src/blosum62.ts +45 -0
- package/src/colorSchemes.ts +2 -4
- package/src/columnCounts.ts +1 -1
- package/src/components/Loading.tsx +25 -14
- package/src/components/MSAView.tsx +22 -5
- package/src/components/MSAViewer.tsx +275 -251
- package/src/components/MetadataTable.tsx +83 -26
- package/src/components/ResizeHandles.tsx +9 -2
- package/src/components/Track.tsx +15 -1
- package/src/components/controls.ts +62 -0
- package/src/components/dialogs/AnnotationFileDialog.tsx +16 -21
- package/src/components/dialogs/ExportSVGDialog.tsx +8 -19
- package/src/components/dialogs/FeatureDialog.tsx +2 -5
- package/src/components/dialogs/GapThresholdDialog.tsx +36 -0
- package/src/components/{header → dialogs}/GappynessSlider.tsx +3 -10
- package/src/components/{header → dialogs}/GoToBox.tsx +36 -10
- package/src/components/dialogs/GoToDialog.tsx +30 -0
- package/src/components/dialogs/HelpDialog.tsx +79 -0
- package/src/components/dialogs/MetadataDialog.tsx +32 -4
- package/src/components/{header → dialogs}/goTo.ts +1 -1
- package/src/components/dialogs/metadataLabels.ts +54 -0
- package/src/components/dialogs/metadataRecord.tsx +61 -0
- package/src/components/header/Header.tsx +75 -44
- package/src/components/header/HiddenColumnsChip.tsx +39 -0
- package/src/components/header/MenuBar.tsx +64 -0
- package/src/components/header/ScrollZoomCheckbox.tsx +46 -0
- package/src/components/header/ZoomControls.tsx +23 -74
- package/src/components/header/colorSchemeMenuItems.ts +121 -0
- package/src/components/header/getAnnotationsMenu.ts +52 -56
- package/src/components/header/menuBarItems.ts +357 -0
- package/src/components/import/ImportForm.tsx +19 -7
- package/src/components/import/data/seq2.ts +0 -18
- package/src/components/minimap/Minimap.tsx +11 -3
- package/src/components/minimap/MinimapSVG.tsx +17 -1
- package/src/components/minimap/minimapLayout.ts +27 -0
- package/src/components/msa/MSACanvas.tsx +24 -4
- package/src/components/msa/MSACanvasBlock.tsx +20 -17
- package/src/components/msa/MSAMouseoverCanvas.tsx +2 -2
- package/src/components/msa/WheelZoomHint.tsx +56 -0
- package/src/components/msa/drawFeatureSpans.ts +160 -79
- package/src/components/msa/msaKeys.ts +3 -0
- package/src/components/msa/msaRaster.ts +26 -10
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +62 -24
- package/src/components/msa/renderHighlights.ts +5 -6
- package/src/components/msa/renderMSABlock.ts +51 -15
- package/src/components/msa/renderMSAMouseover.ts +5 -1
- package/src/components/msa/tileColor.ts +7 -0
- package/src/components/renderCtx.ts +0 -1
- package/src/components/rowpanels/RowPanelBlock.tsx +2 -2
- package/src/components/rowpanels/renderFeaturePanel.ts +26 -7
- package/src/components/settings/MenuItemsForm.tsx +225 -0
- package/src/components/settings/SettingsPanel.tsx +156 -0
- package/src/components/settings/TrackList.tsx +119 -0
- package/src/components/tracks/TrackBlocks.tsx +2 -2
- package/src/components/tracks/drawTracks.ts +5 -5
- package/src/components/tree/CladeLabels.tsx +30 -54
- package/src/components/tree/TreeCanvasBlock.tsx +2 -2
- package/src/components/tree/TreeMenu.tsx +4 -6
- package/src/components/tree/TreeOverview.tsx +2 -2
- package/src/components/tree/cladeBrackets.ts +50 -3
- package/src/components/tree/renderTreeCanvas.ts +2 -13
- package/src/components/tree/renderTreeOverview.ts +7 -14
- package/src/constants.ts +9 -1
- package/src/darkReader.ts +57 -0
- package/src/element.ts +37 -64
- package/src/exportLayout.ts +134 -0
- package/src/featurePanels.ts +269 -0
- package/src/filehandleLoader.ts +136 -0
- package/src/headlessRenderEnv.ts +24 -11
- package/src/hierarchy.ts +5 -88
- package/src/index.ts +9 -5
- package/src/measureTextCanvas.ts +8 -6
- package/src/model/treeModel.ts +9 -3
- package/src/model.ts +452 -807
- package/src/neighborJoining.ts +1 -42
- package/src/renderToSvg.tsx +56 -207
- package/src/rerootTree.ts +7 -6
- package/src/schemeResidueColor.ts +37 -0
- package/src/similarityColors.ts +112 -0
- package/src/treeDisplay.ts +278 -0
- package/src/types.ts +6 -4
- package/src/useWheelScroll.ts +43 -22
- package/src/util.ts +3 -0
- package/src/version.ts +1 -1
- package/src/viewerSnapshot.ts +147 -0
- package/src/wheelZoom.ts +55 -33
- package/src/zoomSnapshot.ts +80 -0
- package/dist/components/header/ColorSchemeMenu.d.ts +0 -12
- package/dist/components/header/ColorSchemeMenu.js +0 -37
- package/dist/components/header/ColorSchemeMenu.js.map +0 -1
- package/dist/components/header/FileMenu.js +0 -66
- package/dist/components/header/FileMenu.js.map +0 -1
- package/dist/components/header/GappynessSlider.js.map +0 -1
- package/dist/components/header/GoToBox.js +0 -31
- package/dist/components/header/GoToBox.js.map +0 -1
- package/dist/components/header/MSASettingsMenu.d.ts +0 -6
- package/dist/components/header/MSASettingsMenu.js +0 -11
- package/dist/components/header/MSASettingsMenu.js.map +0 -1
- package/dist/components/header/ScrollZoomIcons.d.ts +0 -6
- package/dist/components/header/ScrollZoomIcons.js +0 -35
- package/dist/components/header/ScrollZoomIcons.js.map +0 -1
- package/dist/components/header/TreeSettingsMenu.js +0 -42
- package/dist/components/header/TreeSettingsMenu.js.map +0 -1
- package/dist/components/header/ZoomMenu.js +0 -37
- package/dist/components/header/ZoomMenu.js.map +0 -1
- package/dist/components/header/goTo.d.ts +0 -20
- package/dist/components/header/goTo.js.map +0 -1
- package/dist/components/header/settingsMenuItems.d.ts +0 -4
- package/dist/components/header/settingsMenuItems.js +0 -127
- package/dist/components/header/settingsMenuItems.js.map +0 -1
- package/src/components/header/ColorSchemeMenu.tsx +0 -56
- package/src/components/header/FileMenu.tsx +0 -81
- package/src/components/header/MSASettingsMenu.tsx +0 -26
- package/src/components/header/ScrollZoomIcons.tsx +0 -52
- package/src/components/header/TreeSettingsMenu.tsx +0 -60
- package/src/components/header/ZoomMenu.tsx +0 -48
- package/src/components/header/settingsMenuItems.ts +0 -157
|
@@ -16,4 +16,24 @@ export function getMinimapLayout(model) {
|
|
|
16
16
|
const polygonPoints = `${s + w},0 ${s},0 0,${polygonHeight} ${msaCanvasWidth},${polygonHeight}`;
|
|
17
17
|
return { unit, s, w, polygonHeight, polygonPoints };
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* The domain overlay's boxes scaled onto the minimap bar, one per row's band,
|
|
21
|
+
* in the colors the alignment draws them, so the overview shows the domains
|
|
22
|
+
* the alignment does. Empty unless the domains fill the cells.
|
|
23
|
+
*/
|
|
24
|
+
export function minimapDomainRects(model, width, height) {
|
|
25
|
+
const { cellFill, domainBands, featureColors, leaves, numColumns } = model;
|
|
26
|
+
if (cellFill !== 'domain' || numColumns <= 0 || leaves.length === 0) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const colUnit = width / numColumns;
|
|
30
|
+
const rowUnit = height / leaves.length;
|
|
31
|
+
return leaves.flatMap((leaf, row) => (domainBands.get(leaf.data.name) ?? []).map(band => ({
|
|
32
|
+
x: band.startCol * colUnit,
|
|
33
|
+
y: row * rowUnit,
|
|
34
|
+
w: Math.max(1, (band.endCol - band.startCol) * colUnit),
|
|
35
|
+
h: Math.max(1, rowUnit),
|
|
36
|
+
fill: featureColors.get(band.annotation)?.fill ?? 'grey',
|
|
37
|
+
})));
|
|
38
|
+
}
|
|
19
39
|
//# sourceMappingURL=minimapLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minimapLayout.js","sourceRoot":"","sources":["../../../src/components/minimap/minimapLayout.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,KAAK,CAAA;IACpE,MAAM,IAAI,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7D,MAAM,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;IACzB,6EAA6E;IAC7E,4BAA4B;IAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;IACvE,MAAM,aAAa,GAAG,aAAa,GAAG,kBAAkB,CAAA;IACxD,MAAM,aAAa,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,aAAa,IAAI,cAAc,IAAI,aAAa,EAAE,CAAA;IAC/F,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE,CAAA;AACrD,CAAC"}
|
|
1
|
+
{"version":3,"file":"minimapLayout.js","sourceRoot":"","sources":["../../../src/components/minimap/minimapLayout.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,KAAK,CAAA;IACpE,MAAM,IAAI,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7D,MAAM,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;IACzB,6EAA6E;IAC7E,4BAA4B;IAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;IACvE,MAAM,aAAa,GAAG,aAAa,GAAG,kBAAkB,CAAA;IACxD,MAAM,aAAa,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,aAAa,IAAI,cAAc,IAAI,aAAa,EAAE,CAAA;IAC/F,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE,CAAA;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAmB,EACnB,KAAa,EACb,MAAc;IAEd,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAC1E,IAAI,QAAQ,KAAK,QAAQ,IAAI,UAAU,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpE,OAAO,EAAE,CAAA;IACX,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,GAAG,UAAU,CAAA;IAClC,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IACtC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAClC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,OAAO;QAC1B,CAAC,EAAE,GAAG,GAAG,OAAO;QAChB,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;QACvD,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;QACvB,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,IAAI,MAAM;KACzD,CAAC,CAAC,CACJ,CAAA;AACH,CAAC"}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import React, { useCallback, useRef } from 'react';
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
3
|
import { useWheelScroll } from '../../useWheelScroll.js';
|
|
4
|
+
import { zoomSnapshotScale } from '../../zoomSnapshot.js';
|
|
5
|
+
import { alignmentAriaLabel } from '../controls.js';
|
|
4
6
|
import Loading from './Loading.js';
|
|
5
7
|
import MSACanvasBlock from './MSACanvasBlock.js';
|
|
8
|
+
import { WheelZoomHint, useWheelZoomHint } from './WheelZoomHint.js';
|
|
6
9
|
import { onMsaKey } from './msaKeys.js';
|
|
7
10
|
const MSACanvas = observer(function ({ model }) {
|
|
8
|
-
const { MSA, msaFilehandle, height, msaCanvasWidth, blocks2d, scrollZoom, scrollX, scrollY, } = model;
|
|
11
|
+
const { MSA, msaFilehandle, height, msaCanvasWidth, blocks2d, scrollZoom, scrollX, scrollY, zoomSnapshot, } = model;
|
|
12
|
+
const blocks = zoomSnapshot
|
|
13
|
+
? zoomSnapshot.blocksY.flatMap(by => zoomSnapshot.blocksX.map(bx => [bx, by]))
|
|
14
|
+
: blocks2d;
|
|
15
|
+
const scale = zoomSnapshot
|
|
16
|
+
? zoomSnapshotScale(model, zoomSnapshot)
|
|
17
|
+
: undefined;
|
|
9
18
|
const ref = useRef(null);
|
|
10
19
|
const onScrollX = useCallback((d) => {
|
|
11
20
|
model.doScrollX(d);
|
|
@@ -14,16 +23,22 @@ const MSACanvas = observer(function ({ model }) {
|
|
|
14
23
|
model.doScrollY(d);
|
|
15
24
|
}, [model]);
|
|
16
25
|
const onZoom = useCallback((scaleFactor, offsetX, offsetY) => {
|
|
17
|
-
model.
|
|
26
|
+
model.wheelZoomToPos(scaleFactor, offsetX, offsetY);
|
|
18
27
|
}, [model]);
|
|
28
|
+
const onZoomSettle = useCallback(() => {
|
|
29
|
+
model.endWheelZoom();
|
|
30
|
+
}, [model]);
|
|
31
|
+
const hint = useWheelZoomHint(model);
|
|
19
32
|
const { onMouseDown, onMouseUp } = useWheelScroll({
|
|
20
33
|
ref,
|
|
21
34
|
onScrollX,
|
|
22
35
|
onScrollY,
|
|
23
36
|
onZoom,
|
|
37
|
+
onZoomSettle,
|
|
38
|
+
onWheelScroll: hint.onWheelScroll,
|
|
24
39
|
scrollZoom,
|
|
25
40
|
});
|
|
26
|
-
return (React.createElement("div", { ref: ref, "data-testid": "msa_canvas", tabIndex: 0, "aria-label":
|
|
41
|
+
return (React.createElement("div", { ref: ref, "data-testid": "msa_canvas", tabIndex: 0, "aria-label": alignmentAriaLabel, onKeyDown: event => {
|
|
27
42
|
if (onMsaKey(model, event)) {
|
|
28
43
|
event.preventDefault();
|
|
29
44
|
}
|
|
@@ -43,13 +58,16 @@ const MSACanvas = observer(function ({ model }) {
|
|
|
43
58
|
height,
|
|
44
59
|
width: msaCanvasWidth,
|
|
45
60
|
overflow: 'hidden',
|
|
46
|
-
} },
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
} },
|
|
62
|
+
!MSA && !msaFilehandle ? null : MSA ? (React.createElement("div", { style: {
|
|
63
|
+
position: 'absolute',
|
|
64
|
+
top: 0,
|
|
65
|
+
left: 0,
|
|
66
|
+
transform: `translate(${scrollX}px, ${scrollY}px)${scale ? ` scale(${scale.sx}, ${scale.sy})` : ''}`,
|
|
67
|
+
transformOrigin: '0 0',
|
|
68
|
+
willChange: 'transform',
|
|
69
|
+
} }, blocks.map(([bx, by]) => (React.createElement(MSACanvasBlock, { key: `${bx}_${by}`, model: model, offsetX: bx, offsetY: by }))))) : (React.createElement(Loading, null)),
|
|
70
|
+
hint.visible ? React.createElement(WheelZoomHint, null) : null));
|
|
53
71
|
});
|
|
54
72
|
export default MSACanvas;
|
|
55
73
|
//# sourceMappingURL=MSACanvas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MSACanvas.js","sourceRoot":"","sources":["../../../src/components/msa/MSACanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,OAAO,MAAM,cAAe,CAAA;AACnC,OAAO,cAAc,MAAM,qBAAsB,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAIvC,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,EAAE,KAAK,EAA2B;IACrE,MAAM,EACJ,GAAG,EACH,aAAa,EACb,MAAM,EACN,cAAc,EACd,QAAQ,EACR,UAAU,EACV,OAAO,EACP,OAAO,
|
|
1
|
+
{"version":3,"file":"MSACanvas.js","sourceRoot":"","sources":["../../../src/components/msa/MSACanvas.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
2
|
import BaseTooltip from '@jbrowse/core/ui/BaseTooltip';
|
|
3
|
-
import { useTheme } from '@mui/material';
|
|
4
3
|
import { observer } from 'mobx-react';
|
|
4
|
+
import { useCanvasTheme } from '../../darkReader.js';
|
|
5
5
|
import { useCanvasAutorun } from '../../useCanvasAutorun.js';
|
|
6
|
-
import { drawMsaRaster,
|
|
7
|
-
import { renderBoxFeatureCanvasBlock } from './renderBoxFeatureCanvasBlock.js';
|
|
6
|
+
import { drawMsaRaster, rasterApplies } from './msaRaster.js';
|
|
8
7
|
import { renderMSABlock } from './renderMSABlock.js';
|
|
9
8
|
import { useMsaBlockMouse } from './useMsaBlockMouse.js';
|
|
10
9
|
const MSACanvasBlock = observer(function ({ model, offsetX, offsetY, }) {
|
|
11
10
|
const { blockSize, highResScaleFactor } = model;
|
|
12
|
-
const theme =
|
|
11
|
+
const theme = useCanvasTheme();
|
|
13
12
|
const { anchor, onMouseMove, onMouseDown, onClick, onMouseLeave } = useMsaBlockMouse({ model, offsetX, offsetY });
|
|
14
13
|
const canvasSize = blockSize * highResScaleFactor;
|
|
14
|
+
const drawnAt = useRef(undefined);
|
|
15
15
|
const ref = useCanvasAutorun({
|
|
16
16
|
draw: ctx => {
|
|
17
|
+
// during a wheel zoom MSACanvas scales what this block drew at the
|
|
18
|
+
// snapshot, so the block redraws only when a new snapshot is taken
|
|
19
|
+
const snap = model.zoomSnapshot;
|
|
20
|
+
if (snap &&
|
|
21
|
+
(snap === drawnAt.current ||
|
|
22
|
+
snap.colWidth !== model.colWidth ||
|
|
23
|
+
snap.rowHeight !== model.rowHeight)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
drawnAt.current = snap;
|
|
17
27
|
ctx.resetTransform();
|
|
18
28
|
ctx.clearRect(0, 0, canvasSize, canvasSize);
|
|
19
|
-
|
|
20
|
-
ctx,
|
|
21
|
-
theme,
|
|
22
|
-
offsetX,
|
|
23
|
-
offsetY,
|
|
24
|
-
model,
|
|
25
|
-
});
|
|
26
|
-
// the alignment background comes from zoom-independent raster tiles; the
|
|
27
|
-
// domain overlay paints its own boxes instead, and letter-color mode has
|
|
28
|
-
// no background to paint
|
|
29
|
-
const rasterTiles = !model.actuallyShowDomains && model.bgColor && rasterSupported();
|
|
29
|
+
const rasterTiles = rasterApplies(model);
|
|
30
30
|
if (rasterTiles) {
|
|
31
31
|
drawMsaRaster({ ctx, model, theme, offsetX, offsetY });
|
|
32
32
|
}
|
|
@@ -37,6 +37,7 @@ const MSACanvasBlock = observer(function ({ model, offsetX, offsetY, }) {
|
|
|
37
37
|
offsetY,
|
|
38
38
|
model,
|
|
39
39
|
rasterTiles,
|
|
40
|
+
domains: true,
|
|
40
41
|
});
|
|
41
42
|
},
|
|
42
43
|
width: canvasSize,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MSACanvasBlock.js","sourceRoot":"","sources":["../../../src/components/msa/MSACanvasBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"MSACanvasBlock.js","sourceRoot":"","sources":["../../../src/components/msa/MSACanvasBlock.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { isAlive } from '@jbrowse/mobx-state-tree';
|
|
3
|
-
import { useTheme } from '@mui/material';
|
|
4
3
|
import { observer } from 'mobx-react';
|
|
5
4
|
import { msaOverlayZIndex } from '../../constants.js';
|
|
5
|
+
import { useCanvasTheme } from '../../darkReader.js';
|
|
6
6
|
import { useCanvasAutorun } from '../../useCanvasAutorun.js';
|
|
7
7
|
import { renderMouseover } from './renderMSAMouseover.js';
|
|
8
8
|
const MSAMouseoverCanvas = observer(function ({ model, }) {
|
|
9
9
|
const { height, msaCanvasWidth: width, highResScaleFactor } = model;
|
|
10
|
-
const theme =
|
|
10
|
+
const theme = useCanvasTheme();
|
|
11
11
|
const canvasWidth = width * highResScaleFactor;
|
|
12
12
|
const canvasHeight = height * highResScaleFactor;
|
|
13
13
|
const ref = useCanvasAutorun({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MSAMouseoverCanvas.js","sourceRoot":"","sources":["../../../src/components/msa/MSAMouseoverCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"MSAMouseoverCanvas.js","sourceRoot":"","sources":["../../../src/components/msa/MSAMouseoverCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAIzD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,UAAU,EAC5C,KAAK,GAGN;IACC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAA;IACnE,MAAM,KAAK,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,WAAW,GAAG,KAAK,GAAG,kBAAkB,CAAA;IAC9C,MAAM,YAAY,GAAG,MAAM,GAAG,kBAAkB,CAAA;IAChD,MAAM,GAAG,GAAG,gBAAgB,CAAC;QAC3B,IAAI,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnB,eAAe,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;YACxC,CAAC;QACH,CAAC;QACD,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,YAAY;QACpB,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;KACrB,CAAC,CAAA;IAEF,OAAO,CACL,gCACE,GAAG,EAAE,GAAG,EACR,EAAE,EAAC,WAAW,EACd,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,CAAC;YACN,IAAI,EAAE,CAAC;YACP,KAAK;YACL,MAAM;YACN,MAAM,EAAE,gBAAgB;YACxB,aAAa,EAAE,MAAM;SACtB,GACD,CACH,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { MsaViewModel } from '../../model.ts';
|
|
3
|
+
export declare function useWheelZoomHint(model: MsaViewModel): {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
onWheelScroll: (event: WheelEvent) => void;
|
|
6
|
+
};
|
|
7
|
+
export declare function WheelZoomHint(): React.JSX.Element;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, { useCallback, useRef, useState } from 'react';
|
|
2
|
+
import { Paper, Typography } from '@mui/material';
|
|
3
|
+
const hinted = new WeakSet();
|
|
4
|
+
const zoomKey = typeof navigator !== 'undefined' && navigator.platform.startsWith('Mac')
|
|
5
|
+
? '⌘'
|
|
6
|
+
: 'Ctrl';
|
|
7
|
+
export function useWheelZoomHint(model) {
|
|
8
|
+
const [visible, setVisible] = useState(false);
|
|
9
|
+
const timer = useRef(undefined);
|
|
10
|
+
const onWheelScroll = useCallback((event) => {
|
|
11
|
+
if (!model.scrollZoom &&
|
|
12
|
+
Math.abs(event.deltaY) > Math.abs(event.deltaX) &&
|
|
13
|
+
!hinted.has(model)) {
|
|
14
|
+
hinted.add(model);
|
|
15
|
+
setVisible(true);
|
|
16
|
+
clearTimeout(timer.current);
|
|
17
|
+
timer.current = setTimeout(() => {
|
|
18
|
+
setVisible(false);
|
|
19
|
+
}, 2500);
|
|
20
|
+
}
|
|
21
|
+
}, [model]);
|
|
22
|
+
return { visible, onWheelScroll };
|
|
23
|
+
}
|
|
24
|
+
export function WheelZoomHint() {
|
|
25
|
+
return (React.createElement(Paper, { elevation: 3, style: {
|
|
26
|
+
position: 'absolute',
|
|
27
|
+
top: 12,
|
|
28
|
+
left: '50%',
|
|
29
|
+
transform: 'translateX(-50%)',
|
|
30
|
+
padding: '4px 12px',
|
|
31
|
+
pointerEvents: 'none',
|
|
32
|
+
zIndex: 2,
|
|
33
|
+
} },
|
|
34
|
+
React.createElement(Typography, { variant: "body2" },
|
|
35
|
+
zoomKey,
|
|
36
|
+
" + scroll to zoom, or check Zoom on scroll")));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=WheelZoomHint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WheelZoomHint.js","sourceRoot":"","sources":["../../../src/components/msa/WheelZoomHint.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE5D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAIjD,MAAM,MAAM,GAAG,IAAI,OAAO,EAAgB,CAAA;AAE1C,MAAM,OAAO,GACX,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC;IACtE,CAAC,CAAC,GAAG;IACL,CAAC,CAAC,MAAM,CAAA;AAEZ,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAgC,SAAS,CAAC,CAAA;IAC9D,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,KAAiB,EAAE,EAAE;QACpB,IACE,CAAC,KAAK,CAAC,UAAU;YACjB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;YAC/C,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAClB,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACjB,UAAU,CAAC,IAAI,CAAC,CAAA;YAChB,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC3B,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,UAAU,CAAC,KAAK,CAAC,CAAA;YACnB,CAAC,EAAE,IAAI,CAAC,CAAA;QACV,CAAC;IACH,CAAC,EACD,CAAC,KAAK,CAAC,CACR,CAAA;IACD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAA;AACnC,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,oBAAC,KAAK,IACJ,SAAS,EAAE,CAAC,EACZ,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,EAAE;YACP,IAAI,EAAE,KAAK;YACX,SAAS,EAAE,kBAAkB;YAC7B,OAAO,EAAE,UAAU;YACnB,aAAa,EAAE,MAAM;YACrB,MAAM,EAAE,CAAC;SACV;QAED,oBAAC,UAAU,IAAC,OAAO,EAAC,OAAO;YACxB,OAAO;yDACG,CACP,CACT,CAAA;AACH,CAAC"}
|
|
@@ -31,19 +31,11 @@ export interface SpanLayout {
|
|
|
31
31
|
*/
|
|
32
32
|
headRise?: (height: number) => number;
|
|
33
33
|
}
|
|
34
|
-
/** the rows of `bandsByRow` that `leaves` covers, in display order */
|
|
35
|
-
export declare function spanRows<T extends SpanBand>(leaves: HierarchyNode<NodeWithIdsAndLength>[], bandsByRow: Map<string, T[]>): SpanRow<T>[];
|
|
36
34
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* feature with a strand draws as an arrow, one without as a box, and a label
|
|
40
|
-
* draws inside the span wherever the text fits.
|
|
41
|
-
*
|
|
42
|
-
* `xOf` returns the span's `[xStart, xEnd]` in the context's coordinates, and
|
|
43
|
-
* the context is translated so that `y - rowHeight` is the row's top edge.
|
|
35
|
+
* What a renderer hands the span mark: its rows, where a band lands in them,
|
|
36
|
+
* its x mapping, the colors and the label each feature takes.
|
|
44
37
|
*/
|
|
45
|
-
export
|
|
46
|
-
ctx: RenderCtx;
|
|
38
|
+
export interface SpanSource<T extends SpanBand> {
|
|
47
39
|
rows: SpanRow<T>[];
|
|
48
40
|
layout: SpanLayout;
|
|
49
41
|
xOf: (band: T) => [number, number];
|
|
@@ -53,6 +45,53 @@ export declare function drawFeatureSpans<T extends SpanBand>({ ctx, rows, layout
|
|
|
53
45
|
}>;
|
|
54
46
|
labelOf?: (band: T) => string | undefined;
|
|
55
47
|
labelDrawn?: (band: T) => void;
|
|
48
|
+
}
|
|
49
|
+
/** a span as drawn: a box, or an arrow's outline where it carries a strand */
|
|
50
|
+
export interface SpanShape<T extends SpanBand> {
|
|
51
|
+
band: T;
|
|
52
|
+
fill: string;
|
|
53
|
+
stroke: string;
|
|
54
|
+
box?: {
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
w: number;
|
|
58
|
+
h: number;
|
|
59
|
+
};
|
|
60
|
+
outline?: [number, number][];
|
|
61
|
+
}
|
|
62
|
+
export interface SpanLabel {
|
|
63
|
+
text: string;
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
fill: string;
|
|
67
|
+
}
|
|
68
|
+
/** one row's shapes, then the labels drawn over them at `fontSize` */
|
|
69
|
+
export interface SpanMarkRow<T extends SpanBand> {
|
|
70
|
+
shapes: SpanShape<T>[];
|
|
71
|
+
labels: SpanLabel[];
|
|
72
|
+
fontSize: number;
|
|
73
|
+
}
|
|
74
|
+
/** the rows of `bandsByRow` that `leaves` covers, in display order */
|
|
75
|
+
export declare function spanRows<T extends SpanBand>(leaves: HierarchyNode<NodeWithIdsAndLength>[], bandsByRow: Map<string, T[]>): SpanRow<T>[];
|
|
76
|
+
/**
|
|
77
|
+
* The span mark as geometry, in whatever x space `xOf` maps its bands into:
|
|
78
|
+
* alignment columns for the domain overlay, panel pixels for a `features` row
|
|
79
|
+
* panel. A feature with a strand is an arrow, one without a box, and a label
|
|
80
|
+
* lands inside the span wherever `measureText` says the text fits.
|
|
81
|
+
*
|
|
82
|
+
* `y - rowHeight` is the row's top edge in the coordinates `rows` gives.
|
|
83
|
+
*/
|
|
84
|
+
export declare function featureSpanMarks<T extends SpanBand>({ rows, layout, xOf, colors, labelOf, labelDrawn, measureText, xMin, xMax, }: SpanSource<T> & {
|
|
85
|
+
measureText: (text: string, fontSize: number) => number;
|
|
86
|
+
xMin: number;
|
|
87
|
+
xMax: number;
|
|
88
|
+
}): SpanMarkRow<T>[];
|
|
89
|
+
/**
|
|
90
|
+
* The span mark, drawn into `ctx` from `featureSpanMarks`, with the context
|
|
91
|
+
* translated so that `y - rowHeight` is the row's top edge.
|
|
92
|
+
*/
|
|
93
|
+
export declare function drawFeatureSpans<T extends SpanBand>({ ctx, contrastText, ...source }: SpanSource<T> & {
|
|
94
|
+
ctx: RenderCtx;
|
|
56
95
|
contrastText: (color: string) => string;
|
|
57
96
|
xMin: number;
|
|
58
97
|
xMax: number;
|
|
@@ -11,26 +11,28 @@ export function spanRows(leaves, bandsByRow) {
|
|
|
11
11
|
return rows;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* The span mark, in whatever x space
|
|
15
|
-
* columns for the domain overlay, panel pixels for a `features` row
|
|
16
|
-
* feature with a strand
|
|
17
|
-
*
|
|
14
|
+
* The span mark as geometry, in whatever x space `xOf` maps its bands into:
|
|
15
|
+
* alignment columns for the domain overlay, panel pixels for a `features` row
|
|
16
|
+
* panel. A feature with a strand is an arrow, one without a box, and a label
|
|
17
|
+
* lands inside the span wherever `measureText` says the text fits.
|
|
18
18
|
*
|
|
19
|
-
* `
|
|
20
|
-
* the context is translated so that `y - rowHeight` is the row's top edge.
|
|
19
|
+
* `y - rowHeight` is the row's top edge in the coordinates `rows` gives.
|
|
21
20
|
*/
|
|
22
|
-
export function
|
|
23
|
-
|
|
24
|
-
// longest-first so a nested one lands on top, and drawing each label with its
|
|
25
|
-
// own span put the child's box over the parent's text: `S` covered `RBD`, and
|
|
26
|
-
// `RBD` read as `RB`. Reused across rows rather than allocated per row.
|
|
27
|
-
const placed = [];
|
|
21
|
+
export function featureSpanMarks({ rows, layout, xOf, colors, labelOf, labelDrawn, measureText, xMin, xMax, }) {
|
|
22
|
+
const out = [];
|
|
28
23
|
for (const { y, bands } of rows) {
|
|
29
24
|
const h = layout.height(bands[0].laneCount);
|
|
30
25
|
const headLen = layout.headLength(h);
|
|
31
26
|
const rise = layout.headRise?.(h) ?? 0;
|
|
32
27
|
const labelled = labelOf !== undefined && h >= minFeatureLabelHeight;
|
|
33
|
-
|
|
28
|
+
const fontSize = Math.min(h - 2, 11);
|
|
29
|
+
const shapes = [];
|
|
30
|
+
const labels = [];
|
|
31
|
+
// one row's spans are drawn before any of its labels. Bands are ordered
|
|
32
|
+
// longest-first so a nested one lands on top, and drawing each label with
|
|
33
|
+
// its own span put the child's box over the parent's text: `S` covered
|
|
34
|
+
// `RBD`, and `RBD` read as `RB`.
|
|
35
|
+
const placed = [];
|
|
34
36
|
for (const band of bands) {
|
|
35
37
|
const [xStart, xEnd] = xOf(band);
|
|
36
38
|
const w = xEnd - xStart;
|
|
@@ -39,75 +41,116 @@ export function drawFeatureSpans({ ctx, rows, layout, xOf, colors, labelOf, labe
|
|
|
39
41
|
}
|
|
40
42
|
const t = layout.top(y, band.lane, h);
|
|
41
43
|
const { fill, stroke } = colors.get(band.annotation);
|
|
42
|
-
ctx.fillStyle = fill;
|
|
43
|
-
ctx.strokeStyle = stroke;
|
|
44
44
|
const { strand } = band.annotation;
|
|
45
45
|
const head = strand === undefined ? 0 : Math.min(headLen, w);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
shapes.push(strand === undefined
|
|
47
|
+
? { band, fill, stroke, box: { x: xStart, y: t, w, h } }
|
|
48
|
+
: {
|
|
49
|
+
band,
|
|
50
|
+
fill,
|
|
51
|
+
stroke,
|
|
52
|
+
outline: geneArrow({ x: xStart, t, w, h, head, rise, strand }),
|
|
53
|
+
});
|
|
53
54
|
if (labelled) {
|
|
54
55
|
placed.push({ band, xStart, w, t, head, fill });
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
for (const { band, xStart, w, t, head, fill } of placed) {
|
|
59
|
+
// asking for the label here rather than in the pass above keeps the
|
|
60
|
+
// once-per-block segment numbering in drawing order
|
|
61
|
+
const text = labelOf(band);
|
|
62
|
+
// the head narrows to a point, so only about half of it holds text
|
|
63
|
+
if (text !== undefined &&
|
|
64
|
+
measureText(text, fontSize) + 2 <= w - head / 2) {
|
|
65
|
+
labelDrawn?.(band);
|
|
66
|
+
labels.push({ text, x: xStart + w / 2, y: t + h / 2, fill });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
out.push({ shapes, labels, fontSize });
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The span mark, drawn into `ctx` from `featureSpanMarks`, with the context
|
|
75
|
+
* translated so that `y - rowHeight` is the row's top edge.
|
|
76
|
+
*/
|
|
77
|
+
export function drawFeatureSpans({ ctx, contrastText, ...source }) {
|
|
78
|
+
let font = '';
|
|
79
|
+
const setFont = (fontSize) => {
|
|
80
|
+
const next = `${fontSize}px sans-serif`;
|
|
81
|
+
if (next !== font) {
|
|
82
|
+
ctx.font = next;
|
|
83
|
+
font = next;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const rows = featureSpanMarks({
|
|
87
|
+
...source,
|
|
88
|
+
measureText: (text, fontSize) => {
|
|
89
|
+
setFont(fontSize);
|
|
90
|
+
return ctx.measureText(text).width;
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
for (const { shapes, labels, fontSize } of rows) {
|
|
94
|
+
for (const { fill, stroke, box, outline } of shapes) {
|
|
95
|
+
ctx.fillStyle = fill;
|
|
96
|
+
ctx.strokeStyle = stroke;
|
|
97
|
+
if (box) {
|
|
98
|
+
ctx.fillRect(box.x, box.y, box.w, box.h);
|
|
99
|
+
ctx.strokeRect(box.x, box.y, box.w, box.h);
|
|
100
|
+
}
|
|
101
|
+
else if (outline) {
|
|
102
|
+
ctx.beginPath();
|
|
103
|
+
ctx.moveTo(...outline[0]);
|
|
104
|
+
for (let i = 1; i < outline.length; i++) {
|
|
105
|
+
ctx.lineTo(...outline[i]);
|
|
106
|
+
}
|
|
107
|
+
ctx.closePath();
|
|
108
|
+
ctx.fill();
|
|
109
|
+
ctx.stroke();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (labels.length > 0) {
|
|
113
|
+
setFont(fontSize);
|
|
59
114
|
ctx.textAlign = 'center';
|
|
60
115
|
ctx.textBaseline = 'middle';
|
|
61
|
-
for (const {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const label = labelOf(band);
|
|
65
|
-
// the head narrows to a point, so only about half of it holds text
|
|
66
|
-
if (label !== undefined &&
|
|
67
|
-
ctx.measureText(label).width + 2 <= w - head / 2) {
|
|
68
|
-
labelDrawn?.(band);
|
|
69
|
-
ctx.fillStyle = contrastText(fill);
|
|
70
|
-
ctx.fillText(label, xStart + w / 2, t + h / 2);
|
|
71
|
-
}
|
|
116
|
+
for (const { text, x, y, fill } of labels) {
|
|
117
|
+
ctx.fillStyle = contrastText(fill);
|
|
118
|
+
ctx.fillText(text, x, y);
|
|
72
119
|
}
|
|
73
120
|
}
|
|
74
121
|
}
|
|
75
122
|
}
|
|
76
123
|
/**
|
|
77
|
-
* A gene arrow,
|
|
78
|
-
* last `head` pixels *of* the feature, tapering to a point at its end, and
|
|
79
|
-
* feature shorter than the head is all head. The glyph therefore covers its
|
|
124
|
+
* A gene arrow's outline, the way gggenes and gggenomes draw one: the head is
|
|
125
|
+
* the last `head` pixels *of* the feature, tapering to a point at its end, and
|
|
126
|
+
* a feature shorter than the head is all head. The glyph therefore covers its
|
|
80
127
|
* start..end span and nothing else, so adjacent genes butt together instead of
|
|
81
128
|
* biting triangles out of each other, a neighbour never draws over a label, and
|
|
82
129
|
* a gene 20 columns wide reads as 20 columns wide.
|
|
83
130
|
*
|
|
84
131
|
* `rise` lifts the head above the band, for a bar too thin to taper.
|
|
85
132
|
*/
|
|
86
|
-
function
|
|
133
|
+
function geneArrow({ x, t, w, h, head, rise, strand, }) {
|
|
87
134
|
const tip = strand > 0 ? x + w : x;
|
|
88
135
|
const tail = strand > 0 ? x : x + w;
|
|
89
136
|
const flange = strand > 0 ? tip - head : tip + head;
|
|
90
137
|
const bottom = t + h;
|
|
91
138
|
const crown = t - rise;
|
|
92
139
|
const point = (crown + bottom) / 2;
|
|
93
|
-
ctx.beginPath();
|
|
94
140
|
if (head >= w) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
ctx.moveTo(tail, t);
|
|
101
|
-
ctx.lineTo(flange, t);
|
|
102
|
-
if (rise > 0) {
|
|
103
|
-
ctx.lineTo(flange, crown);
|
|
104
|
-
}
|
|
105
|
-
ctx.lineTo(tip, point);
|
|
106
|
-
ctx.lineTo(flange, bottom);
|
|
107
|
-
ctx.lineTo(tail, bottom);
|
|
141
|
+
return [
|
|
142
|
+
[tail, crown],
|
|
143
|
+
[tip, point],
|
|
144
|
+
[tail, bottom],
|
|
145
|
+
];
|
|
108
146
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
147
|
+
return [
|
|
148
|
+
[tail, t],
|
|
149
|
+
[flange, t],
|
|
150
|
+
...(rise > 0 ? [[flange, crown]] : []),
|
|
151
|
+
[tip, point],
|
|
152
|
+
[flange, bottom],
|
|
153
|
+
[tail, bottom],
|
|
154
|
+
];
|
|
112
155
|
}
|
|
113
156
|
//# sourceMappingURL=drawFeatureSpans.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawFeatureSpans.js","sourceRoot":"","sources":["../../../src/components/msa/drawFeatureSpans.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"drawFeatureSpans.js","sourceRoot":"","sources":["../../../src/components/msa/drawFeatureSpans.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"msaKeys.js","sourceRoot":"","sources":["../../../src/components/msa/msaKeys.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,QAAQ,CACtB,KAAmB,EACnB,EAAE,GAAG,EAAE,QAAQ,EAAsC;IAErD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,KAAK,CAAA;IACpE,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAA;IAC/C,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,WAAW;YACd,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YACnB,OAAO,IAAI,CAAA;QACb,KAAK,YAAY;YACf,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAA;YACpB,OAAO,IAAI,CAAA;QACb,KAAK,SAAS;YACZ,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YACnB,OAAO,IAAI,CAAA;QACb,KAAK,WAAW;YACd,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAA;YACpB,OAAO,IAAI,CAAA;QACb,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,KAAK,CAAC,MAAM,EAAE,CAAA;YACd,OAAO,IAAI,CAAA;QACb,KAAK,GAAG;YACN,KAAK,CAAC,OAAO,EAAE,CAAA;YACf,OAAO,IAAI,CAAA;QACb,KAAK,MAAM;YACT,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;YACnB,OAAO,IAAI,CAAA;QACb,KAAK,KAAK;YACR,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;QACb,KAAK,QAAQ;YACX,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpB,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,KAAK,CAAA;QACd;YACE,OAAO,KAAK,CAAA;IAChB,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"msaKeys.js","sourceRoot":"","sources":["../../../src/components/msa/msaKeys.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,QAAQ,CACtB,KAAmB,EACnB,EAAE,GAAG,EAAE,QAAQ,EAAsC;IAErD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,KAAK,CAAA;IACpE,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAA;IAC/C,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,WAAW;YACd,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YACnB,OAAO,IAAI,CAAA;QACb,KAAK,YAAY;YACf,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAA;YACpB,OAAO,IAAI,CAAA;QACb,KAAK,SAAS;YACZ,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YACnB,OAAO,IAAI,CAAA;QACb,KAAK,WAAW;YACd,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAA;YACpB,OAAO,IAAI,CAAA;QACb,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,KAAK,CAAC,MAAM,EAAE,CAAA;YACd,OAAO,IAAI,CAAA;QACb,KAAK,GAAG;YACN,KAAK,CAAC,OAAO,EAAE,CAAA;YACf,OAAO,IAAI,CAAA;QACb,KAAK,GAAG;YACN,KAAK,CAAC,SAAS,EAAE,CAAA;YACjB,OAAO,IAAI,CAAA;QACb,KAAK,MAAM;YACT,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;YACnB,OAAO,IAAI,CAAA;QACb,KAAK,KAAK;YACR,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;QACb,KAAK,QAAQ;YACX,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpB,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,KAAK,CAAA;QACd;YACE,OAAO,KAAK,CAAA;IAChB,CAAC;AACH,CAAC"}
|