react-msaview 7.0.0 → 8.1.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 +11 -10
- package/bundle/index.js +122 -111
- package/bundle/index.js.map +4 -4
- package/dist/calculateBlocks.js +5 -3
- package/dist/calculateBlocks.js.map +1 -1
- 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 -8
- 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 +64 -7
- package/dist/components/MSAViewer.js +128 -23
- 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.js +11 -29
- package/dist/components/ResizeHandles.js.map +1 -1
- package/dist/components/SequenceTextArea.js +3 -4
- package/dist/components/SequenceTextArea.js.map +1 -1
- package/dist/components/Track.js +43 -24
- package/dist/components/Track.js.map +1 -1
- package/dist/components/dialogs/AboutDialog.js +6 -6
- package/dist/components/dialogs/AboutDialog.js.map +1 -1
- package/dist/components/dialogs/AnnotationFileDialog.js +5 -2
- package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -1
- package/dist/components/dialogs/ExportSVGDialog.js +6 -4
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/dialogs/FeatureDialog.js +8 -3
- 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 +4 -1
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/LoadWarnings.js +6 -23
- package/dist/components/header/LoadWarnings.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 +1 -3
- package/dist/components/header/TreeSettingsMenu.js.map +1 -1
- package/dist/components/header/UnshareableDataWarning.js +2 -4
- package/dist/components/header/UnshareableDataWarning.js.map +1 -1
- package/dist/components/header/ZoomControls.js +49 -6
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/header/getAnnotationsMenu.js +3 -6
- package/dist/components/header/getAnnotationsMenu.js.map +1 -1
- package/dist/components/header/settingsMenuItems.js +12 -9
- 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/util.js +1 -2
- 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 +2 -4
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +13 -15
- 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 +59 -0
- package/dist/components/msa/drawFeatureSpans.js +113 -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 +24 -31
- package/dist/components/msa/msaRaster.js +30 -39
- 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 +50 -87
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderHighlights.d.ts +15 -13
- package/dist/components/msa/renderHighlights.js +43 -20
- package/dist/components/msa/renderHighlights.js.map +1 -1
- package/dist/components/msa/renderMSABlock.js +12 -12
- package/dist/components/msa/renderMSABlock.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/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 +3 -5
- 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 +4 -4
- package/dist/components/tracks/drawTracks.js +25 -39
- 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/TreeBranchMenu.js +1 -1
- package/dist/components/tree/TreeBranchMenu.js.map +1 -1
- package/dist/components/tree/TreeCanvas.js +5 -4
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +4 -21
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.js +1 -1
- package/dist/components/tree/TreeNodeMenu.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 +9 -13
- 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.js +160 -25
- 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/useTreeHover.js +2 -4
- package/dist/components/tree/useTreeHover.js.map +1 -1
- package/dist/constants.d.ts +16 -0
- package/dist/constants.js +52 -22
- 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/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 +27 -0
- package/dist/hierarchy.js +66 -9
- package/dist/hierarchy.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/model/DataModel.js +2 -5
- 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 +549 -294
- package/dist/model.js +1412 -621
- 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 +10 -19
- package/dist/renderToStaticMarkup.js +13 -24
- package/dist/renderToStaticMarkup.js.map +1 -1
- package/dist/renderToSvg.js +180 -56
- package/dist/renderToSvg.js.map +1 -1
- package/dist/rowCoordinateCalculations.d.ts +4 -6
- package/dist/rowCoordinateCalculations.js +4 -6
- 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 +2 -3
- 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 +186 -70
- package/dist/types.d.ts +221 -21
- 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/useWheelScroll.js +0 -4
- package/dist/useWheelScroll.js.map +1 -1
- package/dist/util.d.ts +5 -6
- package/dist/util.js +13 -6
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +19 -12
- package/src/calculateBlocks.ts +5 -3
- package/src/colorSchemes.ts +1 -2
- package/src/columnStats.ts +58 -0
- package/src/components/DragHandle.tsx +18 -7
- package/src/components/Loading.tsx +4 -36
- package/src/components/MSAView.tsx +19 -5
- package/src/components/MSAViewer.tsx +240 -28
- package/src/components/PortalTooltip.tsx +47 -0
- package/src/components/ResizeHandles.tsx +17 -32
- package/src/components/SequenceTextArea.tsx +3 -4
- package/src/components/Track.tsx +57 -19
- package/src/components/dialogs/AboutDialog.tsx +35 -6
- package/src/components/dialogs/AnnotationFileDialog.tsx +10 -1
- package/src/components/dialogs/ExportSVGDialog.tsx +8 -3
- package/src/components/dialogs/FeatureDialog.tsx +11 -3
- package/src/components/dialogs/TrackInfoDialog.tsx +1 -1
- package/src/components/header/GappynessSlider.tsx +6 -11
- package/src/components/header/Header.tsx +7 -1
- package/src/components/header/LoadWarnings.tsx +11 -25
- package/src/components/header/ScrollZoomIcons.tsx +52 -0
- package/src/components/header/TreeSettingsMenu.tsx +1 -3
- package/src/components/header/UnshareableDataWarning.tsx +2 -4
- package/src/components/header/ZoomControls.tsx +74 -14
- package/src/components/header/getAnnotationsMenu.ts +3 -6
- package/src/components/header/settingsMenuItems.ts +13 -8
- package/src/components/import/ImportForm.tsx +3 -5
- package/src/components/import/ImportFormExamples.tsx +2 -2
- package/src/components/import/util.ts +1 -2
- package/src/components/minimap/Minimap.tsx +1 -2
- package/src/components/msa/AnnotationLegend.tsx +48 -38
- package/src/components/msa/MSACanvas.tsx +3 -8
- package/src/components/msa/MSACanvasBlock.tsx +13 -16
- package/src/components/msa/MSAMouseoverCanvas.tsx +2 -1
- package/src/components/msa/domainBandCursor.ts +7 -11
- package/src/components/msa/drawFeatureSpans.ts +205 -0
- package/src/components/msa/legendRows.ts +24 -0
- package/src/components/msa/msaRaster.ts +30 -39
- package/src/components/msa/packDomainLanes.ts +36 -0
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +67 -123
- package/src/components/msa/renderHighlights.ts +53 -20
- package/src/components/msa/renderMSABlock.ts +14 -11
- package/src/components/msa/tileColor.ts +4 -7
- package/src/components/msa/useMsaBlockMouse.ts +6 -6
- 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 +3 -5
- package/src/components/tracks/TrackTooltipContent.tsx +156 -0
- package/src/components/tracks/drawTracks.ts +25 -50
- package/src/components/tracks/useTrackHover.ts +42 -0
- package/src/components/tree/CladeLabels.tsx +77 -0
- package/src/components/tree/TreeBranchMenu.tsx +1 -2
- package/src/components/tree/TreeCanvas.tsx +2 -3
- package/src/components/tree/TreeCanvasBlock.tsx +8 -32
- package/src/components/tree/TreeNodeMenu.tsx +1 -2
- package/src/components/tree/TreeOverview.tsx +106 -0
- package/src/components/tree/TreeRuler.tsx +11 -22
- package/src/components/tree/cladeBrackets.ts +73 -0
- package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +2 -2
- package/src/components/tree/renderTreeCanvas.ts +242 -21
- package/src/components/tree/renderTreeOverview.ts +212 -0
- package/src/components/tree/useTreeHover.ts +2 -4
- package/src/constants.ts +61 -22
- package/src/createPaletteMap.ts +10 -9
- package/src/element.ts +321 -0
- package/src/featureFields.ts +19 -0
- package/src/flatToTree.ts +1 -2
- package/src/ggplotPalettes.ts +60 -0
- package/src/hierarchy.ts +77 -9
- package/src/index.ts +31 -7
- package/src/model/DataModel.ts +2 -5
- package/src/model/msaModel.ts +3 -2
- package/src/model/treeModel.ts +42 -0
- package/src/model.ts +1677 -643
- package/src/mount.tsx +32 -0
- package/src/neighborJoining.ts +8 -32
- package/src/renderToStaticMarkup.ts +13 -24
- package/src/renderToSvg.tsx +335 -68
- package/src/rowCoordinateCalculations.ts +4 -6
- package/src/scales.ts +47 -0
- package/src/seqPosToGlobalCol.ts +2 -3
- package/src/sequenceLogo.ts +6 -11
- package/src/stripDefault.ts +7 -14
- package/src/types.ts +260 -45
- package/src/umd.ts +4 -2
- package/src/useCanvasAutorun.ts +5 -10
- package/src/useMsaSvgFigure.ts +72 -0
- package/src/useWheelScroll.ts +0 -4
- package/src/util.ts +15 -6
- package/src/version.ts +1 -1
- package/dist/components/msa/ColumnStats.js +0 -42
- package/dist/components/msa/ColumnStats.js.map +0 -1
- package/src/components/msa/ColumnStats.tsx +0 -54
package/src/scales.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createPaletteMap } from './createPaletteMap.ts'
|
|
2
|
+
import { paletteNamed } from './ggplotPalettes.ts'
|
|
3
|
+
|
|
4
|
+
import type { LegendEntry } from './types.ts'
|
|
5
|
+
|
|
6
|
+
/** how a channel reads a field: a palette by name, or a color per value */
|
|
7
|
+
export interface ScaleSpec {
|
|
8
|
+
palette?: string
|
|
9
|
+
map?: Record<string, string>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ResolvedScale {
|
|
13
|
+
kind: 'categorical'
|
|
14
|
+
colorOf: (value: string) => string | undefined
|
|
15
|
+
legend: LegendEntry[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The scale a channel reads its field through. `values` are the field's values,
|
|
20
|
+
* in any order and with repeats; the domain is their distinct values sorted, so
|
|
21
|
+
* a value keeps its color when rows are re-ordered, collapsed or filtered.
|
|
22
|
+
*
|
|
23
|
+
* `{map}` colors the values the producer named and leaves the rest uncolored.
|
|
24
|
+
* `{palette}` takes the colors of a named palette, and a spec with neither
|
|
25
|
+
* takes the ggplot palette of the domain's size. Every scale is categorical
|
|
26
|
+
* today; a continuous one waits for a caller.
|
|
27
|
+
*/
|
|
28
|
+
export function resolveScale(
|
|
29
|
+
spec: ScaleSpec | undefined,
|
|
30
|
+
values: Iterable<string>,
|
|
31
|
+
): ResolvedScale {
|
|
32
|
+
const domain = [...new Set(values)].sort((a, b) => a.localeCompare(b))
|
|
33
|
+
const { map, palette } = spec ?? {}
|
|
34
|
+
const colors = map ?? createPaletteMap(domain, paletteNamed(palette))
|
|
35
|
+
const present = new Set(domain)
|
|
36
|
+
const labels = map ? Object.keys(map).filter(v => present.has(v)) : domain
|
|
37
|
+
return {
|
|
38
|
+
kind: 'categorical',
|
|
39
|
+
colorOf: (value: string) => colors[value],
|
|
40
|
+
// a categorical value is its own label, and the id a legend keys on
|
|
41
|
+
legend: labels.map(value => ({
|
|
42
|
+
id: value,
|
|
43
|
+
label: value,
|
|
44
|
+
color: colors[value]!,
|
|
45
|
+
})),
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/seqPosToGlobalCol.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* The global column of every ungapped sequence position in a row, i.e.
|
|
3
3
|
* index[seqPos] is the column holding the seqPos-th non-gap character.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* per row on every redraw, and scanning the row for each would be quadratic.
|
|
5
|
+
* The domain overlay resolves one position per feature per row on every redraw,
|
|
6
|
+
* and scanning the row for each would be quadratic.
|
|
8
7
|
*
|
|
9
8
|
* @example
|
|
10
9
|
* // Row: "A-TG-C" (A at 0, T at 2, G at 3, C at 5)
|
package/src/sequenceLogo.ts
CHANGED
|
@@ -19,18 +19,13 @@ export function maxBitsFor(sequenceType: 'dna' | 'rna' | 'amino') {
|
|
|
19
19
|
* stack bottom-up in array order.
|
|
20
20
|
*
|
|
21
21
|
* Heights follow Schneider & Stephens: the column's information content is
|
|
22
|
-
* `log2(alphabet) - H` bits,
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* ten-way one -- otherwise every gappy column would look uninformative for the
|
|
26
|
-
* wrong reason.
|
|
22
|
+
* `log2(alphabet) - H` bits, split among residues by frequency. Frequencies
|
|
23
|
+
* count non-gap residues only, so two residues and eight gaps form a two-way
|
|
24
|
+
* choice.
|
|
27
25
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* full-height stack off its one remaining pair of residues reads as a conserved
|
|
32
|
-
* site. Scaling makes stack height mean "how much this column tells you about
|
|
33
|
-
* the family", matching what the conservation track above it already plots.
|
|
26
|
+
* Unlike plain WebLogo, the stack is then scaled by the non-gap fraction, so a
|
|
27
|
+
* 90%-gap column with one conserved pair does not draw a full-height stack, and
|
|
28
|
+
* stack height matches the conservation track.
|
|
34
29
|
*/
|
|
35
30
|
export function columnLogoStack(
|
|
36
31
|
colStats: ColumnCounts,
|
package/src/stripDefault.ts
CHANGED
|
@@ -9,21 +9,14 @@ import type {
|
|
|
9
9
|
/**
|
|
10
10
|
* `types.stripDefault`, degrading to `types.optional` on hosts that lack it.
|
|
11
11
|
*
|
|
12
|
-
* stripDefault keeps defaulted properties out of snapshots,
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* stripDefault keeps defaulted properties out of snapshots, and only the
|
|
13
|
+
* mobx-state-tree in unreleased @jbrowse/core has it. The plugin bundle
|
|
14
|
+
* externalizes mobx-state-tree, so the host's copy is known only at runtime, and
|
|
15
|
+
* calling a missing stripDefault during model construction makes PluginLoader
|
|
16
|
+
* reject and the whole app show its error page.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* its error page. Losing minimal snapshots is a far better failure than losing
|
|
21
|
-
* the session, so this degrades instead.
|
|
22
|
-
*
|
|
23
|
-
* The two signatures are identical, so behaviour differs only in that defaults
|
|
24
|
-
* reappear in snapshots on older hosts (bigger session snapshots and shared
|
|
25
|
-
* URLs, nothing incorrect). stripDefaultSnapshot.test.ts still pins the stripped
|
|
26
|
-
* behaviour, since dev runs against a version that has it.
|
|
18
|
+
* The signatures are identical; on older hosts, defaults reappear in snapshots
|
|
19
|
+
* and shared URLs. stripDefaultSnapshot.test.ts pins the stripped behaviour.
|
|
27
20
|
*/
|
|
28
21
|
export function stripDefault<IT extends IAnyType>(
|
|
29
22
|
type: IT,
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ResolvedScale, ScaleSpec } from './scales.ts'
|
|
1
2
|
import type { Annotation } from 'msa-parsers'
|
|
2
3
|
|
|
3
4
|
export interface Accession {
|
|
@@ -5,17 +6,26 @@ export interface Accession {
|
|
|
5
6
|
name: string
|
|
6
7
|
description: string
|
|
7
8
|
}
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// the geometry -- see drawTracks.ts, which dispatches on it.
|
|
9
|
+
// every kind draws into the same per-column space; drawTracks.ts dispatches on
|
|
10
|
+
// it to pick the draw function
|
|
11
11
|
export type TrackKind = 'text' | 'bar' | 'logo' | 'arc' | 'ruler'
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Which channel the color scheme paints. `fill` colors the cell a residue sits
|
|
15
|
+
* in, `color` colors the letter itself, the same distinction a grammar of
|
|
16
|
+
* graphics draws between a shape's interior and its own ink.
|
|
17
|
+
*/
|
|
18
|
+
export type ResidueEncoding = 'fill' | 'color'
|
|
19
|
+
|
|
13
20
|
export interface BasicTrackModel {
|
|
14
21
|
id: string
|
|
15
22
|
name: string
|
|
16
23
|
associatedRowName?: string
|
|
17
24
|
height: number
|
|
18
25
|
kind: TrackKind
|
|
26
|
+
// the model height this track's divider writes, shared with every track
|
|
27
|
+
// carrying the same key. Absent on a track no divider resizes.
|
|
28
|
+
heightKey?: string
|
|
19
29
|
// hidden until the user asks for it, unless they have already chosen
|
|
20
30
|
defaultOff?: boolean
|
|
21
31
|
}
|
|
@@ -31,8 +41,8 @@ export interface BarTrackModel extends BasicTrackModel {
|
|
|
31
41
|
barColor?: string
|
|
32
42
|
}
|
|
33
43
|
|
|
34
|
-
// a pair of columns joined by an arc,
|
|
35
|
-
//
|
|
44
|
+
// a pair of columns joined by an arc, resolved to 0-based visible columns for
|
|
45
|
+
// the renderer
|
|
36
46
|
export interface Arc {
|
|
37
47
|
start: number
|
|
38
48
|
end: number
|
|
@@ -77,11 +87,108 @@ export interface ColumnTrackSpec {
|
|
|
77
87
|
height?: number
|
|
78
88
|
}
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
/**
|
|
91
|
+
* A strip panel: one cell per row, colored from a `rowData` field through
|
|
92
|
+
* `scale`, which is ggtree's `gheatmap`. `width` is in pixels and defaults to
|
|
93
|
+
* the row height, and `header` labels the column and defaults to the field.
|
|
94
|
+
* `legend` titles the strip's legend and defaults to the field, and strips
|
|
95
|
+
* naming one title share one legend.
|
|
96
|
+
*/
|
|
97
|
+
export interface RowStripSpec {
|
|
98
|
+
kind: 'strip'
|
|
99
|
+
field: string
|
|
100
|
+
scale?: ScaleSpec
|
|
101
|
+
width?: number
|
|
102
|
+
header?: string
|
|
103
|
+
legend?: string
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** the channels a `features` panel reads off the feature table */
|
|
107
|
+
export interface FeatureEncodingSpec {
|
|
108
|
+
color?: { field: string; scale?: ScaleSpec }
|
|
109
|
+
label?: string
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Shifts each row so that the first feature named `on` starts at zero, which
|
|
114
|
+
* is gggenes' `make_alignment_dummies`. Only `x: "position"` reads it.
|
|
115
|
+
*/
|
|
116
|
+
export interface AlignTransform {
|
|
117
|
+
type: 'align'
|
|
118
|
+
on: string
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* A features panel: the GFF's spans per row, as arrows where they carry a
|
|
123
|
+
* strand. `x: "column"` draws them in the alignment's columns, and
|
|
124
|
+
* `x: "position"` in each row's own residue positions on one linear scale, so
|
|
125
|
+
* a genome with no alignment has an x.
|
|
126
|
+
*/
|
|
127
|
+
export interface RowFeaturesSpec {
|
|
128
|
+
kind: 'features'
|
|
129
|
+
x: 'column' | 'position'
|
|
130
|
+
width?: number
|
|
131
|
+
header?: string
|
|
132
|
+
encoding?: FeatureEncodingSpec
|
|
133
|
+
transform?: AlignTransform[]
|
|
134
|
+
/** how overlapping features share the row's height; see docs/layers.md */
|
|
135
|
+
position?: 'identity' | 'strandpile'
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* A panel left of the alignment on the row scale, the counterpart of
|
|
140
|
+
* ColumnTrackSpec on the column scale. See docs/layers.md
|
|
141
|
+
*/
|
|
142
|
+
export type RowPanelSpec = RowStripSpec | RowFeaturesSpec
|
|
143
|
+
|
|
144
|
+
interface ResolvedPanelBase {
|
|
145
|
+
id: string
|
|
146
|
+
header: string
|
|
147
|
+
width: number
|
|
148
|
+
offsetX: number
|
|
149
|
+
legend: LegendEntry[]
|
|
150
|
+
/** the legend this panel's entries go under; absent means the domain key */
|
|
151
|
+
legendTitle?: string
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* A strip with its scale resolved: the color each row takes, keyed by row
|
|
156
|
+
* name, and the pixel column the panel draws in.
|
|
157
|
+
*/
|
|
158
|
+
export interface ResolvedStripPanel extends ResolvedPanelBase {
|
|
159
|
+
kind: 'strip'
|
|
160
|
+
field: string
|
|
161
|
+
colors: Map<string, string>
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** one feature of a features panel, at its pixel span inside the panel */
|
|
165
|
+
export interface RowPanelSpan {
|
|
166
|
+
annotation: Annotation
|
|
167
|
+
xStart: number
|
|
168
|
+
xEnd: number
|
|
169
|
+
lane: number
|
|
170
|
+
laneCount: number
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* A features panel with its x mapping and its scale resolved: the spans per
|
|
175
|
+
* row name in panel pixels, the fill and outline of each feature, and the
|
|
176
|
+
* label its `label` channel draws. `field` is the field its color scale reads,
|
|
177
|
+
* which its legend is titled by.
|
|
178
|
+
*/
|
|
179
|
+
export interface ResolvedFeaturePanel extends ResolvedPanelBase {
|
|
180
|
+
kind: 'features'
|
|
181
|
+
x: 'column' | 'position'
|
|
182
|
+
field?: string
|
|
183
|
+
spans: Map<string, RowPanelSpan[]>
|
|
184
|
+
colors: Map<Annotation, { fill: string; stroke: string }>
|
|
185
|
+
labels?: Map<Annotation, string>
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export type ResolvedRowPanel = ResolvedStripPanel | ResolvedFeaturePanel
|
|
189
|
+
|
|
190
|
+
// One contiguous run where a row's residues and a structure's line up 1:1, as
|
|
191
|
+
// SIFTS reports them. A position no segment covers is unmapped.
|
|
85
192
|
export interface ResidueSegment {
|
|
86
193
|
rowStart: number
|
|
87
194
|
rowEnd: number
|
|
@@ -90,8 +197,8 @@ export interface ResidueSegment {
|
|
|
90
197
|
}
|
|
91
198
|
|
|
92
199
|
// the structure half of a mapping. `id` is whatever the producer calls the
|
|
93
|
-
// entry (a PDB id, an AlphaFold accession); `asymId` names the chain
|
|
94
|
-
//
|
|
200
|
+
// entry (a PDB id, an AlphaFold accession); `asymId` names the chain and
|
|
201
|
+
// distinguishes two mappings onto the same entry
|
|
95
202
|
export interface MappedStructure {
|
|
96
203
|
id: string
|
|
97
204
|
kind?: 'experimental' | 'predicted'
|
|
@@ -100,21 +207,16 @@ export interface MappedStructure {
|
|
|
100
207
|
}
|
|
101
208
|
|
|
102
209
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* structure by sequence equality fails for a construct with an expression tag,
|
|
107
|
-
* a truncation, an engineered residue, or a row that is a subsequence of the
|
|
108
|
-
* entry, and it fails in the direction that looks like it worked.
|
|
210
|
+
* The structure residue for each residue of a row, computed outside the viewer
|
|
211
|
+
* (SIFTS, an AlphaFold model, a curator). Sequence equality misplaces tagged
|
|
212
|
+
* constructs, truncations and subsequence rows; see docs/layers.md.
|
|
109
213
|
*
|
|
110
214
|
* Positions are 1-based and inclusive on both sides, as GFF and `highlights`
|
|
111
215
|
* are. Structure positions are `label_seq_id`, the index into the entity's
|
|
112
|
-
* SEQRES; author numbering carries insertion codes and
|
|
216
|
+
* SEQRES; author numbering carries insertion codes and is not used.
|
|
113
217
|
*
|
|
114
218
|
* `unobserved` is in structure positions: present in SEQRES with no
|
|
115
|
-
* coordinates
|
|
116
|
-
* crystallographer could not see it" and "this protein does not have that
|
|
117
|
-
* residue" mean different things to a reader.
|
|
219
|
+
* coordinates, as distinct from a residue the structure lacks.
|
|
118
220
|
*/
|
|
119
221
|
export interface ResidueMapping {
|
|
120
222
|
row: string
|
|
@@ -123,11 +225,9 @@ export interface ResidueMapping {
|
|
|
123
225
|
segments: ResidueSegment[]
|
|
124
226
|
unobserved?: [number, number][]
|
|
125
227
|
/**
|
|
126
|
-
* ungapped length of the row this was computed against.
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* is the failure this whole layer exists to avoid. Declared here, the viewer
|
|
130
|
-
* can notice and refuse instead of answering from stale arithmetic.
|
|
228
|
+
* ungapped length of the row this was computed against. When set, the viewer
|
|
229
|
+
* ignores the mapping if the loaded row's length differs, as it does after a
|
|
230
|
+
* re-alignment, revision or swapped sequence.
|
|
131
231
|
*/
|
|
132
232
|
rowLength?: number
|
|
133
233
|
generated?: {
|
|
@@ -137,25 +237,21 @@ export interface ResidueMapping {
|
|
|
137
237
|
}
|
|
138
238
|
}
|
|
139
239
|
|
|
140
|
-
// why a mapping, or one segment of it, is
|
|
141
|
-
//
|
|
142
|
-
// no longer matches what is loaded", which are different problems with
|
|
143
|
-
// different fixes.
|
|
240
|
+
// why a mapping, or one segment of it, is ignored, so a host can tell "no
|
|
241
|
+
// structure for this row" from "the mapping no longer matches what is loaded"
|
|
144
242
|
export interface ResidueMappingProblem {
|
|
145
243
|
row: string
|
|
146
244
|
structureId: string
|
|
147
245
|
/**
|
|
148
|
-
* `mapping`
|
|
149
|
-
*
|
|
150
|
-
* segment, since the rest of the mapping still describes residues that exist.
|
|
246
|
+
* `mapping` ignores the whole mapping, because the problem concerns its row.
|
|
247
|
+
* `segment` ignores only that segment and keeps the rest.
|
|
151
248
|
*/
|
|
152
249
|
scope: 'mapping' | 'segment'
|
|
153
250
|
reason: string
|
|
154
251
|
}
|
|
155
252
|
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
// structure declares but did not resolve.
|
|
253
|
+
// a lookup result in either direction. `observed` is false for a residue in
|
|
254
|
+
// SEQRES with no coordinates.
|
|
159
255
|
export interface StructureResidue {
|
|
160
256
|
structure: MappedStructure
|
|
161
257
|
position: number
|
|
@@ -168,29 +264,50 @@ export interface RowResidue {
|
|
|
168
264
|
}
|
|
169
265
|
|
|
170
266
|
/**
|
|
171
|
-
* One loaded document that the snapshot
|
|
172
|
-
*
|
|
173
|
-
* would go to load it differently.
|
|
267
|
+
* One loaded document that the snapshot omits, and its size. `what` uses the
|
|
268
|
+
* import form's names for the documents.
|
|
174
269
|
*/
|
|
175
270
|
export interface UnshareableData {
|
|
176
271
|
what: 'alignment' | 'tree' | 'annotations' | 'row metadata' | 'data tracks'
|
|
177
272
|
bytes: number
|
|
178
273
|
}
|
|
179
274
|
|
|
180
|
-
//
|
|
181
|
-
//
|
|
182
|
-
// downstream plugins name it in their emitted declarations.
|
|
275
|
+
// Annotation is defined in msa-parsers. Downstream plugins' emitted
|
|
276
|
+
// declarations still name TidyDomainAnnotation.
|
|
183
277
|
export type { Annotation }
|
|
184
278
|
export type TidyDomainAnnotation = Annotation
|
|
185
279
|
|
|
186
280
|
// an annotation resolved to the visible column span it is drawn across.
|
|
187
|
-
// stackIndex is its position
|
|
188
|
-
//
|
|
281
|
+
// stackIndex is its position in its row's paint order; lane is the sub-row it
|
|
282
|
+
// occupies, out of the laneCount the row's overlaps need.
|
|
189
283
|
export interface DomainBand {
|
|
190
284
|
annotation: Annotation
|
|
191
285
|
startCol: number
|
|
192
286
|
endCol: number
|
|
193
287
|
stackIndex: number
|
|
288
|
+
lane: number
|
|
289
|
+
laneCount: number
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* One swatch of a categorical color key. `id` is the value the scale read, and
|
|
294
|
+
* `label` is the text drawn beside the swatch.
|
|
295
|
+
*/
|
|
296
|
+
export interface LegendEntry {
|
|
297
|
+
id: string
|
|
298
|
+
label: string
|
|
299
|
+
color: string
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* A categorical color key, drawn by the on-screen overlay and reserved as a
|
|
304
|
+
* column in the SVG export. `title` names the legend where the viewer draws
|
|
305
|
+
* more than one.
|
|
306
|
+
*/
|
|
307
|
+
export interface Legend {
|
|
308
|
+
id: string
|
|
309
|
+
title: string
|
|
310
|
+
entries: LegendEntry[]
|
|
194
311
|
}
|
|
195
312
|
|
|
196
313
|
/**
|
|
@@ -207,6 +324,104 @@ export interface Highlight {
|
|
|
207
324
|
color?: string
|
|
208
325
|
}
|
|
209
326
|
|
|
327
|
+
/**
|
|
328
|
+
* What the viewer draws over a clade. `highlight` fills the rows behind it,
|
|
329
|
+
* across the tree and the alignment. `bracket` draws a bar and the clade's
|
|
330
|
+
* `label` in the gutter right of the tip labels. `collapse` and `focus` seed
|
|
331
|
+
* the collapsed list and the subtree in focus at load.
|
|
332
|
+
*/
|
|
333
|
+
export type CladeMark = 'highlight' | 'bracket' | 'collapse' | 'focus'
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* A clade of the tree and the mark drawn over it. `mrca` names tips whose most
|
|
337
|
+
* recent common ancestor is the clade; `range` names the first and last tip of
|
|
338
|
+
* a run in display order, in either order. `tips` is the leaf count the
|
|
339
|
+
* producer measured, and a clade that resolves to a different count is dropped.
|
|
340
|
+
* `label` names the clade beside a bracket, and a highlight carrying one draws
|
|
341
|
+
* the label without the bar. See docs/layers.md
|
|
342
|
+
*/
|
|
343
|
+
export interface Clade {
|
|
344
|
+
mrca?: string[]
|
|
345
|
+
range?: [string, string]
|
|
346
|
+
tips: number
|
|
347
|
+
mark: CladeMark
|
|
348
|
+
color?: string
|
|
349
|
+
label?: string
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* A Clade resolved to the rows it covers, with its fill color settled. `color`
|
|
354
|
+
* is the highlight fill; `markColor` is the producer's own color for a bracket
|
|
355
|
+
* bar and its label, unset where the theme's text color stands. `nodeId` is the
|
|
356
|
+
* node an `mrca` resolved to, which `collapse` and `focus` seed themselves
|
|
357
|
+
* with, and a `range` record has none.
|
|
358
|
+
*/
|
|
359
|
+
export interface ResolvedClade {
|
|
360
|
+
rows: [number, number]
|
|
361
|
+
mark: CladeMark
|
|
362
|
+
color: string
|
|
363
|
+
markColor?: string
|
|
364
|
+
label?: string
|
|
365
|
+
nodeId?: string
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* A span in Highlight coordinates: 1-based inclusive residues of `row`, or
|
|
370
|
+
* columns of the file without it
|
|
371
|
+
*/
|
|
372
|
+
export interface Region {
|
|
373
|
+
row?: string
|
|
374
|
+
start: number
|
|
375
|
+
end: number
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* A cell of the alignment in the host's coordinates, 1-based like Highlight:
|
|
380
|
+
* `column` counts every column of the file, hidden gappy ones included, and
|
|
381
|
+
* `residue` counts the row's own letters, absent on a gap. A pointer over a
|
|
382
|
+
* track has a column and no row.
|
|
383
|
+
*/
|
|
384
|
+
export interface Cell {
|
|
385
|
+
column: number
|
|
386
|
+
row?: string
|
|
387
|
+
residue?: number
|
|
388
|
+
letter?: string
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/** the alignment columns on screen, 1-based and inclusive */
|
|
392
|
+
export interface Viewport {
|
|
393
|
+
startColumn: number
|
|
394
|
+
endColumn: number
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* A channel of a mark the viewer always draws. `tipLabel` colors each tip label
|
|
399
|
+
* in the tree, `rowTint` washes the row across the tree gutter and the
|
|
400
|
+
* alignment, and `branch` colors a tree edge whose tips all share one value;
|
|
401
|
+
* all three read a field of `rowData`. `featureFill` colors each span of the
|
|
402
|
+
* annotation overlay and `featureLabel` names the field drawn inside a span,
|
|
403
|
+
* both from a field of the feature table.
|
|
404
|
+
*/
|
|
405
|
+
export type EncodingChannel =
|
|
406
|
+
| 'tipLabel'
|
|
407
|
+
| 'rowTint'
|
|
408
|
+
| 'branch'
|
|
409
|
+
| 'featureFill'
|
|
410
|
+
| 'featureLabel'
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* A channel, the field feeding it, and the scale it reads that field through.
|
|
414
|
+
* See docs/layers.md
|
|
415
|
+
*/
|
|
416
|
+
export interface Encoding {
|
|
417
|
+
channel: EncodingChannel
|
|
418
|
+
field: string
|
|
419
|
+
scale?: ScaleSpec
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/** an Encoding with its scale resolved against the values in the table */
|
|
423
|
+
export type ResolvedEncoding = Encoding & ResolvedScale
|
|
424
|
+
|
|
210
425
|
/** a Highlight resolved to visible column indices and row indices */
|
|
211
426
|
export interface ResolvedHighlight {
|
|
212
427
|
startCol?: number
|
package/src/umd.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
|
|
3
|
-
// a
|
|
4
|
-
//
|
|
3
|
+
// a page that builds models with MSAModelF destroys each one it replaces, so
|
|
4
|
+
// the disposers its autoruns registered run
|
|
5
5
|
export { destroy } from '@jbrowse/mobx-state-tree'
|
|
6
6
|
export { default as MSAView } from './components/Loading.tsx'
|
|
7
|
+
export { mount } from './mount.tsx'
|
|
8
|
+
export { defineMsaElement } from './element.ts'
|
|
7
9
|
export { type MsaViewModel, default as MSAModelF } from './model.ts'
|
|
8
10
|
|
|
9
11
|
export * from 'react-dom/client'
|
package/src/useCanvasAutorun.ts
CHANGED
|
@@ -6,17 +6,12 @@ import type React from 'react'
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Wires a canvas ref to a mobx autorun: grabs the 2d context once the canvas
|
|
9
|
-
* mounts and re-runs `draw` whenever any observable it reads changes.
|
|
10
|
-
* the getContext/null-guard/autorun-dispose boilerplate repeated by every canvas
|
|
11
|
-
* block host.
|
|
9
|
+
* mounts and re-runs `draw` whenever any observable it reads changes.
|
|
12
10
|
*
|
|
13
|
-
* `width`/`height` are the canvas
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* *after* the mobx reaction that already redrew at the old size. Without a redraw
|
|
18
|
-
* on the far side of that commit the canvas is left blank: it is what blanked the
|
|
19
|
-
* tree on a tree-area resize and the consensus tracks on a vertical zoom.
|
|
11
|
+
* `width`/`height` are the canvas backing store size (logical size times the
|
|
12
|
+
* high-res scale factor). Assigning either clears the bitmap, and React assigns
|
|
13
|
+
* them after the mobx reaction has drawn at the old size, so the effect redraws
|
|
14
|
+
* when they change.
|
|
20
15
|
*
|
|
21
16
|
* `deps` covers everything else the effect should re-subscribe on, matching a
|
|
22
17
|
* normal useEffect dep array.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import { createJBrowseTheme } from '@jbrowse/core/ui/theme'
|
|
4
|
+
import { getSnapshot } from '@jbrowse/mobx-state-tree'
|
|
5
|
+
import { compareStructural, reaction } from 'mobx'
|
|
6
|
+
|
|
7
|
+
import { renderToSvg } from './renderToSvg.tsx'
|
|
8
|
+
|
|
9
|
+
import type { MsaViewModel } from './model.ts'
|
|
10
|
+
import type { Theme } from '@mui/material'
|
|
11
|
+
|
|
12
|
+
export interface MsaSvgFigure {
|
|
13
|
+
/** the SVG document for what is on screen, once the first draw finishes */
|
|
14
|
+
svg?: string
|
|
15
|
+
error?: unknown
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The viewer's SVG export of its viewport, as markup for the page to insert.
|
|
20
|
+
* It redraws after the view settles: `delay` ms after the last scroll, zoom,
|
|
21
|
+
* resize or change to the snapshot. A draw a later one overtakes is dropped.
|
|
22
|
+
*
|
|
23
|
+
* The figure's row names and letters are SVG text, so the browser's find
|
|
24
|
+
* locates them, a reader can select them, and print stylesheets apply.
|
|
25
|
+
*/
|
|
26
|
+
export function useMsaSvgFigure(
|
|
27
|
+
model: MsaViewModel,
|
|
28
|
+
{
|
|
29
|
+
theme,
|
|
30
|
+
includeTracks = false,
|
|
31
|
+
delay = 300,
|
|
32
|
+
}: { theme?: Theme; includeTracks?: boolean; delay?: number } = {},
|
|
33
|
+
) {
|
|
34
|
+
const [figure, setFigure] = useState<MsaSvgFigure>({})
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
let latest = 0
|
|
37
|
+
const dispose = reaction(
|
|
38
|
+
() =>
|
|
39
|
+
model.viewInitialized && model.dataInitialized
|
|
40
|
+
? [getSnapshot(model), model.width, model.height]
|
|
41
|
+
: undefined,
|
|
42
|
+
key => {
|
|
43
|
+
if (!key) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
const draw = ++latest
|
|
47
|
+
renderToSvg(model, {
|
|
48
|
+
theme: theme ?? createJBrowseTheme(),
|
|
49
|
+
exportType: 'viewport',
|
|
50
|
+
includeTracks,
|
|
51
|
+
}).then(
|
|
52
|
+
svg => {
|
|
53
|
+
if (draw === latest) {
|
|
54
|
+
setFigure({ svg })
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
(error: unknown) => {
|
|
58
|
+
if (draw === latest) {
|
|
59
|
+
setFigure({ error })
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
},
|
|
64
|
+
{ delay, fireImmediately: true, equals: compareStructural },
|
|
65
|
+
)
|
|
66
|
+
return () => {
|
|
67
|
+
latest = -1
|
|
68
|
+
dispose()
|
|
69
|
+
}
|
|
70
|
+
}, [model, theme, includeTracks, delay])
|
|
71
|
+
return figure
|
|
72
|
+
}
|
package/src/useWheelScroll.ts
CHANGED
|
@@ -147,10 +147,6 @@ export function useWheelScroll({
|
|
|
147
147
|
}, [mouseDragging, onScrollX, onScrollY])
|
|
148
148
|
|
|
149
149
|
function onMouseDown(event: React.MouseEvent) {
|
|
150
|
-
const target = event.target as HTMLElement
|
|
151
|
-
if (target.draggable || target.dataset.resizer) {
|
|
152
|
-
return
|
|
153
|
-
}
|
|
154
150
|
if (event.button === 0) {
|
|
155
151
|
prevX.current = event.clientX
|
|
156
152
|
prevY.current = event.clientY
|