@jbrowse/plugin-linear-genome-view 5.0.0-beta.2 → 5.0.0-beta.20
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/esm/LinearGenomeView/afterAttach.d.ts +22 -5
- package/esm/LinearGenomeView/afterAttach.js +129 -106
- package/esm/LinearGenomeView/axisConfigSchema.d.ts +18 -0
- package/esm/LinearGenomeView/axisConfigSchema.js +22 -0
- package/esm/LinearGenomeView/components/CenterLine.js +10 -5
- package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +2 -3
- package/esm/LinearGenomeView/components/CrisprGuidePanel.js +3 -5
- package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +9 -4
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +45 -8
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +2 -2
- package/esm/LinearGenomeView/components/Header.js +11 -1
- package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +2 -2
- package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -3
- package/esm/LinearGenomeView/components/HeaderPanControls.js +6 -3
- package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +4 -1
- package/esm/LinearGenomeView/components/HeaderZoomControls.js +6 -35
- package/esm/LinearGenomeView/components/Highlight.js +27 -11
- package/esm/LinearGenomeView/components/HighlightBand.d.ts +11 -2
- package/esm/LinearGenomeView/components/HighlightBand.js +32 -13
- package/esm/LinearGenomeView/components/HighlightChip.d.ts +3 -3
- package/esm/LinearGenomeView/components/HighlightChip.js +13 -8
- package/esm/LinearGenomeView/components/HighlightLabelDialog.d.ts +6 -0
- package/esm/LinearGenomeView/components/HighlightLabelDialog.js +18 -0
- package/esm/LinearGenomeView/components/HoverPositionHighlight.js +3 -3
- package/esm/LinearGenomeView/components/ImportForm.js +7 -9
- package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -12
- package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +13 -14
- package/esm/LinearGenomeView/components/MiniControls.js +11 -5
- package/esm/LinearGenomeView/components/OverviewHighlight.js +3 -3
- package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +3 -2
- package/esm/LinearGenomeView/components/OverviewHighlightBand.js +6 -5
- package/esm/LinearGenomeView/components/OverviewRubberband.js +25 -48
- package/esm/LinearGenomeView/components/OverviewScalebar.js +4 -5
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +5 -3
- package/esm/LinearGenomeView/components/PaddingBlocks.js +3 -8
- package/esm/LinearGenomeView/components/RangeSelectOverlay.js +5 -6
- package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +3 -2
- package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +4 -4
- package/esm/LinearGenomeView/components/ResizeAllTracksHandle.d.ts +5 -0
- package/esm/LinearGenomeView/components/ResizeAllTracksHandle.js +74 -0
- package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -2
- package/esm/LinearGenomeView/components/Rubberband.js +3 -2
- package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -1
- package/esm/LinearGenomeView/components/SVGHighlightBand.js +16 -5
- package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -6
- package/esm/LinearGenomeView/components/Scalebar.js +8 -5
- package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +51 -36
- package/esm/LinearGenomeView/components/SearchBox.js +10 -16
- package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +3 -2
- package/esm/LinearGenomeView/components/SearchPanelForm.js +4 -2
- package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +4 -8
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +7 -4
- package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -7
- package/esm/LinearGenomeView/components/SearchResultsTable.js +25 -53
- package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +2 -3
- package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -4
- package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +3 -2
- package/esm/LinearGenomeView/components/StrandCheckboxes.js +4 -2
- package/esm/LinearGenomeView/components/TrackContainer.d.ts +2 -3
- package/esm/LinearGenomeView/components/TrackContainer.js +63 -10
- package/esm/LinearGenomeView/components/TrackLabel.js +14 -4
- package/esm/LinearGenomeView/components/TrackLabelButtons.js +2 -2
- package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +4 -5
- package/esm/LinearGenomeView/components/TrackLabelMenu.js +11 -14
- package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +3 -4
- package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +23 -10
- package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +6 -4
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js +12 -24
- package/esm/LinearGenomeView/components/TracksContainer.js +11 -23
- package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -2
- package/esm/LinearGenomeView/components/VerticalGuide.js +3 -16
- package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
- package/esm/LinearGenomeView/components/fetchSequence.js +15 -7
- package/esm/LinearGenomeView/components/recentLocationsMenu.js +10 -0
- package/esm/LinearGenomeView/components/useRangeSelect.d.ts +0 -3
- package/esm/LinearGenomeView/components/useRangeSelect.js +26 -61
- package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +3 -1
- package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +4 -2
- package/esm/LinearGenomeView/components/useSideScroll.d.ts +17 -2
- package/esm/LinearGenomeView/components/useSideScroll.js +156 -102
- package/esm/LinearGenomeView/components/util.d.ts +4 -0
- package/esm/LinearGenomeView/components/util.js +4 -2
- package/esm/LinearGenomeView/consts.d.ts +2 -0
- package/esm/LinearGenomeView/consts.js +3 -1
- package/esm/LinearGenomeView/containingLgv.d.ts +21 -0
- package/esm/LinearGenomeView/containingLgv.js +23 -0
- package/esm/LinearGenomeView/headerFit.d.ts +4 -2
- package/esm/LinearGenomeView/headerFit.js +20 -7
- package/esm/LinearGenomeView/index.d.ts +2 -7
- package/esm/LinearGenomeView/index.js +5 -7
- package/esm/LinearGenomeView/keyboardHandler.d.ts +8 -7
- package/esm/LinearGenomeView/keyboardHandler.js +61 -23
- package/esm/LinearGenomeView/launchKeys.d.ts +1 -1
- package/esm/LinearGenomeView/launchKeys.js +11 -6
- package/esm/LinearGenomeView/lazyDialogs.d.ts +16 -3
- package/esm/LinearGenomeView/lazyDialogs.js +1 -0
- package/esm/LinearGenomeView/linkedViewSync.d.ts +3 -11
- package/esm/LinearGenomeView/linkedViewSync.js +27 -49
- package/esm/LinearGenomeView/menuItems.d.ts +16 -18
- package/esm/LinearGenomeView/menuItems.js +264 -164
- package/esm/LinearGenomeView/model.d.ts +1192 -560
- package/esm/LinearGenomeView/model.js +805 -590
- package/esm/LinearGenomeView/rExport/exportLinearView.d.ts +17 -0
- package/esm/LinearGenomeView/rExport/exportLinearView.js +117 -0
- package/esm/LinearGenomeView/rExport/rScript.d.ts +110 -0
- package/esm/LinearGenomeView/rExport/rScript.js +524 -0
- package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
- package/esm/LinearGenomeView/sharedScaleContainer.js +2 -12
- package/esm/LinearGenomeView/showFiles.d.ts +2 -0
- package/esm/LinearGenomeView/showFiles.js +19 -0
- package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +1 -1
- package/esm/LinearGenomeView/showRegionsWithUndo.js +13 -5
- package/esm/LinearGenomeView/stickyChrome.d.ts +5 -9
- package/esm/LinearGenomeView/stickyChrome.js +5 -9
- package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +4 -4
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +4 -1
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +8 -21
- package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +3 -1
- package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +9 -9
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +3 -1
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +5 -5
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +13 -18
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +2 -5
- package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +5 -6
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +9 -10
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +3 -3
- package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.d.ts +26 -0
- package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.js +12 -0
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +21 -13
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +4 -5
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +7 -6
- package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +2 -3
- package/esm/LinearGenomeView/svgcomponents/SVGView.js +17 -3
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +24 -20
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +42 -29
- package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +74 -77
- package/esm/LinearGenomeView/svgcomponents/util.d.ts +28 -12
- package/esm/LinearGenomeView/svgcomponents/util.js +41 -29
- package/esm/LinearGenomeView/types.d.ts +13 -10
- package/esm/LinearGenomeView/types.js +0 -1
- package/esm/LinearGenomeView/util.d.ts +103 -46
- package/esm/LinearGenomeView/util.js +222 -170
- package/esm/MultiLevelRubberband/MultiLevelRubberband.js +9 -6
- package/esm/MultiLevelRubberband/index.d.ts +2 -0
- package/esm/MultiLevelRubberband/index.js +2 -0
- package/esm/MultiLevelRubberband/menuItems.d.ts +34 -0
- package/esm/MultiLevelRubberband/menuItems.js +52 -0
- package/esm/MultiLevelRubberband/rowLabel.d.ts +22 -0
- package/esm/MultiLevelRubberband/rowLabel.js +27 -0
- package/esm/MultiLevelRubberband/types.d.ts +1 -0
- package/esm/MultiLevelRubberband/useRangeSelect.d.ts +2 -1
- package/esm/MultiLevelRubberband/useRangeSelect.js +45 -59
- package/esm/TrackModifiers/index.d.ts +83 -0
- package/esm/TrackModifiers/index.js +231 -0
- package/esm/displayKitTests/perRegionTestEnv.d.ts +244 -68
- package/esm/displayKitTests/perRegionTestEnv.js +30 -26
- package/esm/index.d.ts +21 -99
- package/esm/index.js +17 -38
- package/esm/searchUtils.d.ts +26 -10
- package/esm/searchUtils.js +137 -137
- package/esm/shared/RubberbandSpan.d.ts +3 -2
- package/esm/shared/RubberbandSpan.js +6 -3
- package/esm/shared/coordLabels.d.ts +11 -4
- package/esm/shared/coordLabels.js +20 -5
- package/esm/shared/useWindowDrag.d.ts +18 -0
- package/esm/shared/useWindowDrag.js +47 -0
- package/package.json +12 -11
- package/esm/FeatureTrack/configSchema.d.ts +0 -124
- package/esm/FeatureTrack/configSchema.js +0 -54
- package/esm/FeatureTrack/index.d.ts +0 -2
- package/esm/FeatureTrack/index.js +0 -13
- package/esm/LinearGenomeView/initKeys.d.ts +0 -12
- package/esm/LinearGenomeView/initKeys.js +0 -68
- package/esm/MultiLevelRubberband/VerticalGuide.d.ts +0 -6
- package/esm/MultiLevelRubberband/VerticalGuide.js +0 -21
- package/esm/lazyPluginExports.d.ts +0 -23
- package/esm/lazyPluginExports.js +0 -36
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
3
|
import { Tooltip } from '@mui/material';
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
import { observer } from 'mobx-react';
|
|
5
|
+
// A single absolute-positioned band over the overview scalebar. The 1px border
|
|
6
|
+
// keeps very narrow bands visible.
|
|
7
7
|
const useStyles = makeStyles()({
|
|
8
8
|
highlight: {
|
|
9
9
|
height: '100%',
|
|
@@ -11,7 +11,7 @@ const useStyles = makeStyles()({
|
|
|
11
11
|
left: 0,
|
|
12
12
|
},
|
|
13
13
|
});
|
|
14
|
-
|
|
14
|
+
const OverviewHighlightBand = observer(function OverviewHighlightBand({ coords, background, borderColor, tooltip, }) {
|
|
15
15
|
const { classes } = useStyles();
|
|
16
16
|
const band = (_jsx("div", { className: classes.highlight, style: {
|
|
17
17
|
transform: `translateX(${coords.left}px)`,
|
|
@@ -23,4 +23,5 @@ export default function OverviewHighlightBand({ coords, background, borderColor,
|
|
|
23
23
|
}),
|
|
24
24
|
} }));
|
|
25
25
|
return tooltip ? (_jsx(Tooltip, { title: tooltip, arrow: true, children: band })) : (band);
|
|
26
|
-
}
|
|
26
|
+
});
|
|
27
|
+
export default OverviewHighlightBand;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
3
|
import { getNotificationSink, stringify } from '@jbrowse/core/util';
|
|
4
4
|
import { getRelativeX } from '@jbrowse/core/util/getRelativeX';
|
|
5
5
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
6
6
|
import { observer } from 'mobx-react';
|
|
7
7
|
import RubberbandSpan from '../../shared/RubberbandSpan.js';
|
|
8
|
+
import { useWindowDrag } from '../../shared/useWindowDrag.js';
|
|
8
9
|
import OverviewRubberbandHoverTooltip from './OverviewRubberbandHoverTooltip.js';
|
|
9
10
|
import { overviewPxToBp } from './util.js';
|
|
10
11
|
const useStyles = makeStyles()({
|
|
@@ -25,61 +26,37 @@ const OverviewRubberband = observer(function OverviewRubberband({ model, overvie
|
|
|
25
26
|
const controlsRef = useRef(null);
|
|
26
27
|
const { classes } = useStyles();
|
|
27
28
|
const mouseDragging = startX !== undefined;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
function globalMouseUp(event) {
|
|
40
|
-
// read the up position from the event so currentX state doesn't need to
|
|
41
|
-
// be a dep (which would re-subscribe these listeners every mousemove)
|
|
42
|
-
if (startX !== undefined) {
|
|
43
|
-
const offsetX = event.clientX - left;
|
|
44
|
-
if (Math.abs(offsetX - startX) > 3) {
|
|
45
|
-
const leftPx = Math.min(startX, offsetX);
|
|
46
|
-
const rightPx = Math.max(startX, offsetX);
|
|
47
|
-
model.moveTo(overviewPxToBp(overview, leftPx, cytobandOffset), overviewPxToBp(overview, rightPx, cytobandOffset));
|
|
29
|
+
useWindowDrag(controlsRef, startX, {
|
|
30
|
+
onMove: setCurrentX,
|
|
31
|
+
onEnd: ({ startX, endX, isClick }) => {
|
|
32
|
+
if (!isClick) {
|
|
33
|
+
model.moveTo(overviewPxToBp(overview, Math.min(startX, endX), cytobandOffset), overviewPxToBp(overview, Math.max(startX, endX), cytobandOffset));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const click = overviewPxToBp(overview, startX, cytobandOffset);
|
|
37
|
+
if (click.refName) {
|
|
38
|
+
model.centerAt(click.coord0, click.refName, click.index);
|
|
48
39
|
}
|
|
49
40
|
else {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
model.centerAt(click.coord0, click.refName, click.index);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
getNotificationSink(model).notify('unknown position clicked');
|
|
56
|
-
console.error('unknown position clicked', click);
|
|
57
|
-
}
|
|
41
|
+
getNotificationSink(model).notify('unknown position clicked');
|
|
42
|
+
console.error('unknown position clicked', click);
|
|
58
43
|
}
|
|
59
44
|
}
|
|
60
45
|
setStartX(undefined);
|
|
61
46
|
setCurrentX(undefined);
|
|
62
47
|
setGuideX(undefined);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
window.addEventListener('mousemove', globalMouseMove);
|
|
71
|
-
window.addEventListener('mouseup', globalMouseUp);
|
|
72
|
-
window.addEventListener('keydown', globalKeyDown);
|
|
73
|
-
return () => {
|
|
74
|
-
window.removeEventListener('mousemove', globalMouseMove);
|
|
75
|
-
window.removeEventListener('mouseup', globalMouseUp);
|
|
76
|
-
window.removeEventListener('keydown', globalKeyDown);
|
|
77
|
-
};
|
|
78
|
-
}, [startX, mouseDragging, model, overview, cytobandOffset]);
|
|
48
|
+
},
|
|
49
|
+
onCancel: () => {
|
|
50
|
+
setStartX(undefined);
|
|
51
|
+
setCurrentX(undefined);
|
|
52
|
+
},
|
|
53
|
+
});
|
|
79
54
|
function mouseDown(event) {
|
|
80
|
-
event.
|
|
81
|
-
|
|
82
|
-
|
|
55
|
+
if (event.button === 0) {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
event.stopPropagation();
|
|
58
|
+
setStartX(getRelativeX(event, controlsRef.current));
|
|
59
|
+
}
|
|
83
60
|
}
|
|
84
61
|
function mouseMove(event) {
|
|
85
62
|
setGuideX(getRelativeX(event, controlsRef.current));
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PluggableElements } from '@jbrowse/core/ui';
|
|
3
|
+
import { alpha } from '@jbrowse/core/ui/palette';
|
|
3
4
|
import { getEnv, getSession } from '@jbrowse/core/util';
|
|
4
5
|
import { cx, makeStyles } from '@jbrowse/core/util/tss-react';
|
|
5
|
-
import { Typography
|
|
6
|
+
import { Typography } from '@mui/material';
|
|
6
7
|
import { observer } from 'mobx-react';
|
|
7
8
|
import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT } from '../consts.js';
|
|
8
9
|
import { REF_NAME_LABEL_FONT_SIZE, getBlockRefName, showRefNameLabels, } from '../util.js';
|
|
@@ -89,8 +90,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
89
90
|
},
|
|
90
91
|
}));
|
|
91
92
|
const OverviewBox = observer(function OverviewBox({ model, block, showRefName, }) {
|
|
92
|
-
const { classes } = useStyles();
|
|
93
|
-
const theme = useTheme();
|
|
93
|
+
const { classes, theme } = useStyles();
|
|
94
94
|
const { cytobandOffset, effectiveShowCytobands, overviewLayout: overview, } = model;
|
|
95
95
|
const { reversed, refName, assemblyName } = block;
|
|
96
96
|
const { assemblyManager } = getSession(model);
|
|
@@ -120,8 +120,7 @@ const OverviewBox = observer(function OverviewBox({ model, block, showRefName, }
|
|
|
120
120
|
}, children: [showRefName ? (_jsx(Typography, { style: { color: refNameColor, left: 3 }, className: classes.scalebarRefName, children: refName })) : null, _jsx(OverviewScalebarTickLabels, { model: model, block: block, refNameColor: refNameColor, showRefName: showRefName })] }));
|
|
121
121
|
});
|
|
122
122
|
const VisibleRegionBox = observer(function VisibleRegionBox({ model, }) {
|
|
123
|
-
const { classes } = useStyles();
|
|
124
|
-
const theme = useTheme();
|
|
123
|
+
const { classes, theme } = useStyles();
|
|
125
124
|
const { effectiveShowCytobands, cytobandOffset, overviewRegionPxSpan: span, } = model;
|
|
126
125
|
if (!span) {
|
|
127
126
|
return null;
|
|
@@ -24,10 +24,12 @@ function trapezoidPoints(top, bottom, height) {
|
|
|
24
24
|
// class computed once per theme (makeStyles memoizes) — an on-screen zoom frame
|
|
25
25
|
// then does zero color parsing. SVG export can't carry a CSS class, so that path
|
|
26
26
|
// serializes explicit fill/stroke attributes instead (see `exportSvg` below).
|
|
27
|
+
const FILL_OPACITY = 0.3;
|
|
28
|
+
const STROKE_OPACITY = 0.8;
|
|
27
29
|
const useStyles = makeStyles()(theme => ({
|
|
28
30
|
polygon: {
|
|
29
|
-
fill: alpha(theme.palette.tertiary.light,
|
|
30
|
-
stroke: alpha(theme.palette.tertiary.light,
|
|
31
|
+
fill: alpha(theme.palette.tertiary.light, FILL_OPACITY),
|
|
32
|
+
stroke: alpha(theme.palette.tertiary.light, STROKE_OPACITY),
|
|
31
33
|
},
|
|
32
34
|
}));
|
|
33
35
|
/**
|
|
@@ -57,6 +59,6 @@ const OverviewScalebarPolygon = observer(function OverviewScalebarPolygon({ mode
|
|
|
57
59
|
const top = transformPxSpan(extent, bpPerPx / overview.bpPerPx, overviewOffsetPx);
|
|
58
60
|
const bottom = transformPxSpan(extent, 1, -offsetPx);
|
|
59
61
|
const points = trapezoidPoints(top, bottom, HEADER_BAR_HEIGHT);
|
|
60
|
-
return exportSvg ? (_jsx("polygon", { points: points, ...getFillProps(alpha(theme.palette.tertiary.light,
|
|
62
|
+
return exportSvg ? (_jsx("polygon", { points: points, ...getFillProps(alpha(theme.palette.tertiary.light, FILL_OPACITY)), ...getStrokeProps(alpha(theme.palette.tertiary.light, STROKE_OPACITY)) })) : (_jsx("polygon", { points: points, className: classes.polygon }));
|
|
61
63
|
});
|
|
62
64
|
export default OverviewScalebarPolygon;
|
|
@@ -16,15 +16,10 @@ const useStyles = makeStyles()(theme => ({
|
|
|
16
16
|
boundaryBlock: {
|
|
17
17
|
background: theme.palette.action.disabledBackground,
|
|
18
18
|
},
|
|
19
|
+
// opaque, since a translucent fill would darken unevenly where the
|
|
20
|
+
// container-level and per-track PaddingBlocks overlap
|
|
19
21
|
regionSeparator: {
|
|
20
|
-
|
|
21
|
-
// out contiguously so the separator paints directly over track data on both
|
|
22
|
-
// sides. A translucent fill would tint the data instead of masking it, and
|
|
23
|
-
// would darken unevenly where the container-level and per-track
|
|
24
|
-
// PaddingBlocks overlap. An opaque grey masks cleanly and stays seamless.
|
|
25
|
-
background: theme.palette.mode === 'dark'
|
|
26
|
-
? theme.palette.grey[500]
|
|
27
|
-
: theme.palette.grey[600],
|
|
22
|
+
background: theme.palette.regionSeparator,
|
|
28
23
|
},
|
|
29
24
|
elided: {
|
|
30
25
|
...elidedBlockStyles,
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Suspense, lazy } from 'react';
|
|
3
2
|
import { Menu } from '@jbrowse/core/ui';
|
|
4
3
|
import { getBpDisplayStr, stringify } from '@jbrowse/core/util';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
5
|
+
import RubberbandSpan from '../../shared/RubberbandSpan.js';
|
|
6
6
|
import { stickyChromeTops } from '../stickyChrome.js';
|
|
7
7
|
import VerticalGuide from './VerticalGuide.js';
|
|
8
|
-
const RubberbandSpan = lazy(() => import('../../shared/RubberbandSpan.js'));
|
|
9
8
|
const RangeSelectOverlay = observer(function RangeSelectOverlay({ model, range, menuOffsetX = 0, }) {
|
|
10
9
|
const { stickyViewHeaders, headerHeight, isScalebarRefNameMenuOpen } = model;
|
|
11
10
|
const { scalebar } = stickyChromeTops({ stickyViewHeaders, headerHeight });
|
|
12
|
-
const { guideX,
|
|
13
|
-
return (_jsxs(_Fragment, { children: [guideX !== undefined && !isScalebarRefNameMenuOpen ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) :
|
|
11
|
+
const { guideX, rubberband, anchorPosition, isClick, handleMenuItemClick, handleClose, } = range;
|
|
12
|
+
return (_jsxs(_Fragment, { children: [guideX !== undefined && !isScalebarRefNameMenuOpen ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberband && !isClick ? (_jsx(RubberbandSpan, { left: rubberband.left, width: rubberband.width, viewWidth: model.width, stickyTop: scalebar, leftLabel: stringify(rubberband.leftBpOffset), rightLabel: stringify(rubberband.rightBpOffset), size: getBpDisplayStr(rubberband.numOfBpSelected) })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
|
|
14
13
|
left: anchorPosition.clientX + menuOffsetX,
|
|
15
14
|
top: anchorPosition.clientY,
|
|
16
|
-
}, onMenuItemClick: handleMenuItemClick, open:
|
|
17
|
-
? model.rubberbandClickMenuItems(
|
|
15
|
+
}, onMenuItemClick: handleMenuItemClick, open: true, onClose: handleClose, menuItems: isClick
|
|
16
|
+
? model.rubberbandClickMenuItems(model.pxToBp(anchorPosition.offsetX))
|
|
18
17
|
: model.rubberBandMenuItems() })) : null] }));
|
|
19
18
|
});
|
|
20
19
|
export default RangeSelectOverlay;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { LinearGenomeViewModel } from '../model.ts';
|
|
2
|
-
|
|
2
|
+
declare const RegionWidthEditorDialog: ({ model, handleClose, }: {
|
|
3
3
|
model: LinearGenomeViewModel;
|
|
4
4
|
handleClose: () => void;
|
|
5
|
-
})
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
6
|
+
export default RegionWidthEditorDialog;
|
|
@@ -3,12 +3,11 @@ import { useState } from 'react';
|
|
|
3
3
|
import { SubmitDialog } from '@jbrowse/core/ui';
|
|
4
4
|
import { parseBpString, toLocale } from '@jbrowse/core/util';
|
|
5
5
|
import { TextField, Typography } from '@mui/material';
|
|
6
|
+
import { observer } from 'mobx-react';
|
|
6
7
|
function format(n) {
|
|
7
8
|
return toLocale(Math.floor(n));
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
-
// user-edited thereafter, so it shouldn't reactively reset if bpPerPx changes
|
|
11
|
-
export default function RegionWidthEditorDialog({ model, handleClose, }) {
|
|
10
|
+
const RegionWidthEditorDialog = observer(function RegionWidthEditorDialog({ model, handleClose, }) {
|
|
12
11
|
const [val, setVal] = useState(() => format(model.bpPerPx * model.width));
|
|
13
12
|
const bp = parseBpString(val);
|
|
14
13
|
const valid = bp !== undefined && bp > 0;
|
|
@@ -20,4 +19,5 @@ export default function RegionWidthEditorDialog({ model, handleClose, }) {
|
|
|
20
19
|
}, children: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 30 }, children: [_jsx(Typography, { children: "Enter a specific number of base pairs to change the viewport to show, either in full or abbreviated as e.g. 500kb or 1.5Mbp. This is approximate and does not account for padding between regions or off-screen scrolling" }), _jsx(TextField, { label: "Zoom level (bp)", autoFocus: true, fullWidth: true, variant: "outlined", value: val, onChange: event => {
|
|
21
20
|
setVal(event.target.value);
|
|
22
21
|
} })] }) }));
|
|
23
|
-
}
|
|
22
|
+
});
|
|
23
|
+
export default RegionWidthEditorDialog;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef } from 'react';
|
|
3
|
+
import { ResizeHandle } from '@jbrowse/core/ui';
|
|
4
|
+
import { scrollPortOf } from '@jbrowse/core/util/hooks';
|
|
5
|
+
import { isAlive } from '@jbrowse/mobx-state-tree';
|
|
6
|
+
import { observer } from 'mobx-react';
|
|
7
|
+
import { RESIZE_ALL_HANDLE_HEIGHT } from '../consts.js';
|
|
8
|
+
function useScrollPortExcess(ref, model, enabled) {
|
|
9
|
+
useLayoutEffect(() => {
|
|
10
|
+
const box = ref.current?.closest('[data-testid^="view-container-"]') ??
|
|
11
|
+
ref.current?.closest('[data-testid^="linear-genome-view-"]');
|
|
12
|
+
if (!enabled || !box || !('ResizeObserver' in window)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const port = scrollPortOf(box);
|
|
16
|
+
const measure = () => {
|
|
17
|
+
const { marginTop, marginBottom } = getComputedStyle(box);
|
|
18
|
+
const outer = box.getBoundingClientRect().height +
|
|
19
|
+
Number.parseFloat(marginTop) +
|
|
20
|
+
Number.parseFloat(marginBottom);
|
|
21
|
+
model.setScrollPortExcess(Math.round(outer - (port?.clientHeight ?? window.innerHeight)));
|
|
22
|
+
};
|
|
23
|
+
measure();
|
|
24
|
+
const observer = new ResizeObserver(measure);
|
|
25
|
+
observer.observe(box);
|
|
26
|
+
if (port) {
|
|
27
|
+
observer.observe(port);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
window.addEventListener('resize', measure);
|
|
31
|
+
}
|
|
32
|
+
return () => {
|
|
33
|
+
observer.disconnect();
|
|
34
|
+
window.removeEventListener('resize', measure);
|
|
35
|
+
if (isAlive(model)) {
|
|
36
|
+
model.setScrollPortExcess(undefined);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}, [ref, model, enabled]);
|
|
40
|
+
}
|
|
41
|
+
const ResizeAllTracksHandle = observer(function ResizeAllTracksHandle({ model, }) {
|
|
42
|
+
const ref = useRef(null);
|
|
43
|
+
const drag = useRef({ from: new Map() });
|
|
44
|
+
const { isTopLevelView } = model;
|
|
45
|
+
useScrollPortExcess(ref, model, isTopLevelView);
|
|
46
|
+
return (_jsx("div", { ref: ref, style: isTopLevelView
|
|
47
|
+
? { position: 'sticky', bottom: 0, zIndex: 300 }
|
|
48
|
+
: { position: 'relative', height: 0, zIndex: 300 }, children: _jsx(ResizeHandle, { grip: isTopLevelView || 'hover', "data-testid": "resize-all-tracks", title: isTopLevelView
|
|
49
|
+
? 'Drag to resize all tracks, double-click to fit them to the window'
|
|
50
|
+
: 'Drag to resize all tracks', style: isTopLevelView
|
|
51
|
+
? { height: RESIZE_ALL_HANDLE_HEIGHT }
|
|
52
|
+
: {
|
|
53
|
+
height: RESIZE_ALL_HANDLE_HEIGHT,
|
|
54
|
+
position: 'absolute',
|
|
55
|
+
bottom: 0,
|
|
56
|
+
}, onDragStart: () => {
|
|
57
|
+
drag.current = { from: model.resizableTrackHeights };
|
|
58
|
+
for (const track of model.tracks) {
|
|
59
|
+
track.setResizing(true);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
// no value, so the distance from the press, every track scaled from
|
|
63
|
+
// where it was
|
|
64
|
+
onChange: distance => {
|
|
65
|
+
model.resizeTracks(distance, drag.current.from);
|
|
66
|
+
}, onDragEnd: () => {
|
|
67
|
+
for (const track of model.tracks) {
|
|
68
|
+
track.setResizing(false);
|
|
69
|
+
}
|
|
70
|
+
}, onDoubleClick: () => {
|
|
71
|
+
model.fitTracksToWindow();
|
|
72
|
+
} }) }));
|
|
73
|
+
});
|
|
74
|
+
export default ResizeAllTracksHandle;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { LinearGenomeViewModel } from '../index.ts';
|
|
2
2
|
type LGV = LinearGenomeViewModel;
|
|
3
|
-
declare const Rubberband: ({ model
|
|
3
|
+
declare const Rubberband: ({ model }: {
|
|
4
4
|
model: LGV;
|
|
5
|
-
ControlComponent?: React.ReactElement;
|
|
6
5
|
}) => import("react").JSX.Element;
|
|
7
6
|
export default Rubberband;
|
|
@@ -4,6 +4,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
|
4
4
|
import { observer } from 'mobx-react';
|
|
5
5
|
import { stickyChromeTops } from '../stickyChrome.js';
|
|
6
6
|
import RangeSelectOverlay from './RangeSelectOverlay.js';
|
|
7
|
+
import Scalebar from './Scalebar.js';
|
|
7
8
|
import { useRangeSelect } from './useRangeSelect.js';
|
|
8
9
|
const useStyles = makeStyles()({
|
|
9
10
|
rubberbandControl: {
|
|
@@ -13,7 +14,7 @@ const useStyles = makeStyles()({
|
|
|
13
14
|
zIndex: 825,
|
|
14
15
|
},
|
|
15
16
|
});
|
|
16
|
-
const Rubberband = observer(function Rubberband({ model
|
|
17
|
+
const Rubberband = observer(function Rubberband({ model }) {
|
|
17
18
|
const ref = useRef(null);
|
|
18
19
|
const { classes } = useStyles();
|
|
19
20
|
const { stickyViewHeaders, headerHeight } = model;
|
|
@@ -24,6 +25,6 @@ const Rubberband = observer(function Rubberband({ model, ControlComponent = _jsx
|
|
|
24
25
|
// (TracksContainer): mouseout bubbles from every child, so crossing a
|
|
25
26
|
// refName or coordinate label inside the scalebar cleared the guide and
|
|
26
27
|
// the next mousemove put it straight back
|
|
27
|
-
onMouseLeave: range.mouseOut, children:
|
|
28
|
+
onMouseLeave: range.mouseOut, children: _jsx(Scalebar, { model: model }) })] }));
|
|
28
29
|
});
|
|
29
30
|
export default Rubberband;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface BandGap {
|
|
2
|
+
top: number;
|
|
3
|
+
height: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function spansAround(gaps: BandGap[], height: number): {
|
|
6
|
+
top: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}[];
|
|
9
|
+
export default function SVGHighlightBand({ coords, height, gaps, color, label, labelColor, }: {
|
|
2
10
|
coords: {
|
|
3
11
|
left: number;
|
|
4
12
|
width: number;
|
|
5
13
|
};
|
|
6
14
|
height: number;
|
|
15
|
+
gaps: BandGap[];
|
|
7
16
|
color: string;
|
|
8
17
|
label?: string;
|
|
9
18
|
labelColor: string;
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { getFillProps } from '@jbrowse/core/util';
|
|
3
|
+
// The stretches of a band `height` tall left once the sorted, disjoint `gaps`
|
|
4
|
+
// are cut out of it.
|
|
5
|
+
export function spansAround(gaps, height) {
|
|
6
|
+
const edges = [0, ...gaps.flatMap(g => [g.top, g.top + g.height]), height];
|
|
7
|
+
return edges.flatMap((top, i) => {
|
|
8
|
+
const bottom = edges[i + 1];
|
|
9
|
+
return i % 2 === 0 && bottom !== undefined && bottom > top
|
|
10
|
+
? [{ top, height: bottom - top }]
|
|
11
|
+
: [];
|
|
12
|
+
});
|
|
13
|
+
}
|
|
3
14
|
// One full-height SVG highlight band with an optional label at the top,
|
|
4
|
-
// mirroring the on-screen HighlightBand div
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
export default function SVGHighlightBand({ coords, height, color, label, labelColor, }) {
|
|
8
|
-
return (_jsxs(_Fragment, { children: [_jsx("rect", { x: coords.left, y:
|
|
15
|
+
// mirroring the on-screen HighlightBand div: a label wider than its band runs
|
|
16
|
+
// past the band's right edge, and the band leaves out `gaps`, the tracks that
|
|
17
|
+
// do not draw in genomic coordinates.
|
|
18
|
+
export default function SVGHighlightBand({ coords, height, gaps, color, label, labelColor, }) {
|
|
19
|
+
return (_jsxs(_Fragment, { children: [spansAround(gaps, height).map(span => (_jsx("rect", { x: coords.left, y: span.top, width: coords.width, height: span.height, ...getFillProps(color) }, span.top))), label ? (_jsx("text", { x: coords.left + 3, y: 2, fontSize: 11, dominantBaseline: "hanging", ...getFillProps(labelColor), children: label })) : null] }));
|
|
9
20
|
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { LinearGenomeViewModel } from '../index.ts';
|
|
2
|
-
import type React from 'react';
|
|
3
2
|
type LGV = LinearGenomeViewModel;
|
|
4
|
-
|
|
3
|
+
declare const Scalebar: ({ model }: {
|
|
5
4
|
model: LGV;
|
|
6
|
-
|
|
7
|
-
className?: string;
|
|
8
|
-
}
|
|
9
|
-
declare const Scalebar: ({ model, style, className, }: ScalebarProps) => React.JSX.Element;
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
10
6
|
export default Scalebar;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
3
|
import { Paper } from '@mui/material';
|
|
4
4
|
import { observer } from 'mobx-react';
|
|
5
|
+
import { SCALE_BAR_HEIGHT } from '../consts.js';
|
|
5
6
|
import Gridlines from './Gridlines.js';
|
|
6
7
|
import PaddingBlocks from './PaddingBlocks.js';
|
|
7
8
|
import ScalebarCoordinateLabels from './ScalebarCoordinateLabels.js';
|
|
@@ -14,15 +15,17 @@ const useStyles = makeStyles()({
|
|
|
14
15
|
container: {
|
|
15
16
|
overflow: 'clip',
|
|
16
17
|
position: 'relative',
|
|
18
|
+
height: SCALE_BAR_HEIGHT,
|
|
19
|
+
boxSizing: 'border-box',
|
|
17
20
|
},
|
|
18
21
|
});
|
|
19
|
-
const Scalebar = observer(function Scalebar({ model
|
|
22
|
+
const Scalebar = observer(function Scalebar({ model }) {
|
|
20
23
|
const { classes } = useStyles();
|
|
21
24
|
return (_jsxs(Paper
|
|
22
|
-
// The rubberband owns presses on the scalebar (it wraps this
|
|
23
|
-
//
|
|
25
|
+
// The rubberband owns presses on the scalebar (it wraps this), so the
|
|
26
|
+
// view's click-drag pan must not also start one
|
|
24
27
|
// on the paths where the rubberband doesn't stopPropagation — a press with
|
|
25
28
|
// the refName menu already open. See ResizeHandle for the marker contract.
|
|
26
|
-
, { "data-gesture-owner": "true", className:
|
|
29
|
+
, { "data-gesture-owner": "true", className: classes.container, variant: "outlined", children: [_jsx(Gridlines, { model: model, offset: 1 }), _jsx(PaddingBlocks, { model: model, offset: 1 }), _jsx(ScalebarCoordinateLabels, { model: model }), _jsx(ScalebarRefNameLabels, { model: model })] }));
|
|
27
30
|
});
|
|
28
31
|
export default Scalebar;
|