@jbrowse/plugin-linear-genome-view 2.13.0 → 2.14.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/dist/BaseLinearDisplay/components/LinearBlocks.js +2 -2
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +3 -1
- package/dist/BaseLinearDisplay/components/Tooltip.js +1 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -5
- package/dist/BaseLinearDisplay/models/FeatureDensityMixin.js +2 -3
- package/dist/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/renderSvg.js +3 -1
- package/dist/BaseLinearDisplay/models/util.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/util.js +3 -5
- package/dist/LaunchLinearGenomeView/index.js +12 -11
- package/dist/LinearBareDisplay/model.d.ts +1 -1
- package/dist/LinearBasicDisplay/components/AddFiltersDialog.js +9 -3
- package/dist/LinearBasicDisplay/components/SetMaxHeightDialog.js +6 -2
- package/dist/LinearBasicDisplay/model.d.ts +2 -4
- package/dist/LinearBasicDisplay/model.js +9 -3
- package/dist/LinearGenomeView/components/Cytobands.js +6 -23
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +16 -6
- package/dist/LinearGenomeView/components/GetSequenceDialog.js +13 -16
- package/dist/LinearGenomeView/components/Header.js +6 -2
- package/dist/LinearGenomeView/components/Highlight.js +24 -25
- package/dist/LinearGenomeView/components/ImportForm.js +5 -2
- package/dist/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +5 -1
- package/dist/LinearGenomeView/components/LinearGenomeView.d.ts +2 -3
- package/dist/LinearGenomeView/components/LinearGenomeView.js +5 -3
- package/dist/LinearGenomeView/components/MiniControls.js +6 -2
- package/dist/LinearGenomeView/components/OverviewHighlight.js +23 -30
- package/dist/LinearGenomeView/components/OverviewRubberband.js +1 -1
- package/dist/LinearGenomeView/components/OverviewScalebar.js +6 -11
- package/dist/LinearGenomeView/components/OverviewScalebarPolygon.js +1 -2
- package/dist/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +6 -5
- package/dist/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +6 -2
- package/dist/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +3 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js +9 -7
- package/dist/LinearGenomeView/components/RubberbandSpan.js +3 -5
- package/dist/LinearGenomeView/components/Scalebar.js +2 -1
- package/dist/LinearGenomeView/components/SearchResultsDialog.js +3 -1
- package/dist/LinearGenomeView/components/SearchResultsTable.js +2 -3
- package/dist/LinearGenomeView/components/SequenceSearchDialog.js +15 -5
- package/dist/LinearGenomeView/components/TrackContainer.js +2 -2
- package/dist/LinearGenomeView/components/TrackLabel.js +15 -5
- package/dist/LinearGenomeView/components/TrackLabelDragHandle.js +3 -1
- package/dist/LinearGenomeView/components/TracksContainer.js +1 -1
- package/dist/LinearGenomeView/components/ZoomControls.js +10 -4
- package/dist/LinearGenomeView/components/hooks.d.ts +2 -2
- package/dist/LinearGenomeView/components/hooks.js +24 -26
- package/dist/LinearGenomeView/components/util.d.ts +2 -2
- package/dist/LinearGenomeView/model.d.ts +24 -13
- package/dist/LinearGenomeView/model.js +75 -46
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGRuler.js +1 -1
- package/dist/LinearGenomeView/util.d.ts +1 -1
- package/dist/LinearGenomeView/util.js +4 -9
- package/dist/index.d.ts +3 -414
- package/dist/searchUtils.js +4 -6
- package/esm/BaseLinearDisplay/components/LinearBlocks.js +2 -2
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +3 -1
- package/esm/BaseLinearDisplay/components/Tooltip.js +1 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +8 -5
- package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +2 -3
- package/esm/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/renderSvg.js +3 -1
- package/esm/BaseLinearDisplay/models/util.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/util.js +3 -5
- package/esm/LaunchLinearGenomeView/index.js +13 -12
- package/esm/LinearBareDisplay/model.d.ts +1 -1
- package/esm/LinearBasicDisplay/components/AddFiltersDialog.js +9 -3
- package/esm/LinearBasicDisplay/components/SetMaxHeightDialog.js +6 -2
- package/esm/LinearBasicDisplay/model.d.ts +2 -4
- package/esm/LinearBasicDisplay/model.js +9 -3
- package/esm/LinearGenomeView/components/Cytobands.js +6 -23
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +16 -6
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +13 -16
- package/esm/LinearGenomeView/components/Header.js +6 -2
- package/esm/LinearGenomeView/components/Highlight.js +26 -27
- package/esm/LinearGenomeView/components/ImportForm.js +5 -2
- package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +5 -1
- package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +2 -3
- package/esm/LinearGenomeView/components/LinearGenomeView.js +5 -3
- package/esm/LinearGenomeView/components/MiniControls.js +6 -2
- package/esm/LinearGenomeView/components/OverviewHighlight.js +24 -31
- package/esm/LinearGenomeView/components/OverviewRubberband.js +1 -1
- package/esm/LinearGenomeView/components/OverviewScalebar.js +6 -11
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +1 -2
- package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +6 -5
- package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +6 -2
- package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +3 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +10 -8
- package/esm/LinearGenomeView/components/RubberbandSpan.js +3 -5
- package/esm/LinearGenomeView/components/Scalebar.js +2 -1
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +3 -1
- package/esm/LinearGenomeView/components/SearchResultsTable.js +2 -3
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js +15 -5
- package/esm/LinearGenomeView/components/TrackContainer.js +2 -2
- package/esm/LinearGenomeView/components/TrackLabel.js +15 -5
- package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +3 -1
- package/esm/LinearGenomeView/components/TracksContainer.js +1 -1
- package/esm/LinearGenomeView/components/ZoomControls.js +10 -4
- package/esm/LinearGenomeView/components/hooks.d.ts +2 -2
- package/esm/LinearGenomeView/components/hooks.js +24 -26
- package/esm/LinearGenomeView/components/util.d.ts +2 -2
- package/esm/LinearGenomeView/model.d.ts +24 -13
- package/esm/LinearGenomeView/model.js +77 -48
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +1 -1
- package/esm/LinearGenomeView/util.d.ts +1 -1
- package/esm/LinearGenomeView/util.js +4 -9
- package/esm/index.d.ts +3 -414
- package/esm/searchUtils.js +4 -6
- package/package.json +3 -3
|
@@ -112,7 +112,7 @@ const OverviewRubberband = observer(function OverviewRubberband({ model, overvie
|
|
|
112
112
|
}
|
|
113
113
|
let left = startX || 0;
|
|
114
114
|
let width = 0;
|
|
115
|
-
if (
|
|
115
|
+
if (currentX !== undefined) {
|
|
116
116
|
left = currentX < startX ? currentX : startX;
|
|
117
117
|
width = currentX - startX;
|
|
118
118
|
}
|
|
@@ -120,8 +120,7 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
|
|
|
120
120
|
const { pluginManager } = getEnv(model);
|
|
121
121
|
const visibleRegions = dynamicBlocks.contentBlocks;
|
|
122
122
|
const overviewVisibleRegions = overview.dynamicBlocks;
|
|
123
|
-
const
|
|
124
|
-
const scalebarColor = tertiary ? tertiary.light : primary.light;
|
|
123
|
+
const scalebarColor = theme.palette.tertiary.light;
|
|
125
124
|
// catches possible null from at's below
|
|
126
125
|
if (!visibleRegions.length) {
|
|
127
126
|
return null;
|
|
@@ -159,23 +158,19 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
|
|
|
159
158
|
});
|
|
160
159
|
const OverviewScalebar = observer(function ({ model, children, }) {
|
|
161
160
|
const { classes } = useStyles();
|
|
162
|
-
const { totalBp, width, cytobandOffset, displayedRegions } = model;
|
|
161
|
+
const { minimumBlockWidth, totalBp, width, cytobandOffset, displayedRegions, } = model;
|
|
163
162
|
const modWidth = width - cytobandOffset;
|
|
163
|
+
const str = JSON.stringify(displayedRegions);
|
|
164
164
|
const overview = useMemo(() => {
|
|
165
165
|
const overview = Base1DView.create({
|
|
166
|
-
displayedRegions: JSON.parse(
|
|
166
|
+
displayedRegions: JSON.parse(str),
|
|
167
167
|
interRegionPaddingWidth: 0,
|
|
168
|
-
minimumBlockWidth
|
|
168
|
+
minimumBlockWidth,
|
|
169
169
|
});
|
|
170
170
|
overview.setVolatileWidth(modWidth);
|
|
171
171
|
overview.showAllRegions();
|
|
172
172
|
return overview;
|
|
173
|
-
}, [
|
|
174
|
-
JSON.stringify(displayedRegions), // eslint-disable-line react-hooks/exhaustive-deps
|
|
175
|
-
model.minimumBlockWidth,
|
|
176
|
-
modWidth,
|
|
177
|
-
displayedRegions,
|
|
178
|
-
]);
|
|
173
|
+
}, [str, minimumBlockWidth, modWidth]);
|
|
179
174
|
const scale = totalBp / (modWidth - (displayedRegions.length - 1) * wholeSeqSpacer);
|
|
180
175
|
return (React.createElement("div", null,
|
|
181
176
|
React.createElement(OverviewRubberband, { model: model, overview: overview, ControlComponent: React.createElement(Scalebar, { model: model, overview: overview, scale: scale }) }),
|
|
@@ -9,8 +9,7 @@ const OverviewScalebarPolygon = observer(function ({ model, overview, useOffset
|
|
|
9
9
|
const multiplier = Number(useOffset);
|
|
10
10
|
const { interRegionPaddingWidth, offsetPx, dynamicBlocks, cytobandOffset } = model;
|
|
11
11
|
const { contentBlocks, totalWidthPxWithoutBorders } = dynamicBlocks;
|
|
12
|
-
const
|
|
13
|
-
const polygonColor = tertiary ? tertiary.light : primary.light;
|
|
12
|
+
const polygonColor = theme.palette.tertiary.light;
|
|
14
13
|
// catches possible null from at's below
|
|
15
14
|
if (!contentBlocks.length) {
|
|
16
15
|
return null;
|
|
@@ -4,12 +4,13 @@ import { TextField, } from '@mui/material';
|
|
|
4
4
|
import EndAdornment from './EndAdornment';
|
|
5
5
|
export default function AutocompleteTextField({ TextFieldProps, inputBoxVal, params, showHelp, setInputValue, setCurrentSearch, }) {
|
|
6
6
|
const { helperText, InputProps = {} } = TextFieldProps;
|
|
7
|
-
return (React.createElement(TextField, { onBlur: () =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
setInputValue(inputBoxVal), ...params, ...TextFieldProps, size: "small", helperText: helperText, InputProps: {
|
|
7
|
+
return (React.createElement(TextField, { onBlur: () => {
|
|
8
|
+
setInputValue(inputBoxVal);
|
|
9
|
+
}, ...params, ...TextFieldProps, size: "small", helperText: helperText, InputProps: {
|
|
11
10
|
...params.InputProps,
|
|
12
11
|
...InputProps,
|
|
13
12
|
endAdornment: (React.createElement(EndAdornment, { showHelp: showHelp, endAdornment: params.InputProps.endAdornment })),
|
|
14
|
-
}, placeholder: "Search for location", onChange: e =>
|
|
13
|
+
}, placeholder: "Search for location", onChange: e => {
|
|
14
|
+
setCurrentSearch(e.target.value);
|
|
15
|
+
} }));
|
|
15
16
|
}
|
|
@@ -8,10 +8,14 @@ const HelpDialog = lazy(() => import('./HelpDialog'));
|
|
|
8
8
|
function HelpAdornment() {
|
|
9
9
|
const [isHelpDialogDisplayed, setHelpDialogDisplayed] = useState(false);
|
|
10
10
|
return (React.createElement(React.Fragment, null,
|
|
11
|
-
React.createElement(IconButton, { onClick: () =>
|
|
11
|
+
React.createElement(IconButton, { onClick: () => {
|
|
12
|
+
setHelpDialogDisplayed(true);
|
|
13
|
+
}, size: "small" },
|
|
12
14
|
React.createElement(HelpIcon, { fontSize: "small" })),
|
|
13
15
|
isHelpDialogDisplayed ? (React.createElement(Suspense, { fallback: null },
|
|
14
|
-
React.createElement(HelpDialog, { handleClose: () =>
|
|
16
|
+
React.createElement(HelpDialog, { handleClose: () => {
|
|
17
|
+
setHelpDialogDisplayed(false);
|
|
18
|
+
} }))) : null));
|
|
15
19
|
}
|
|
16
20
|
export default function EndAdornment({ showHelp, endAdornment, }) {
|
|
17
21
|
return (React.createElement(React.Fragment, null,
|
|
@@ -38,5 +38,7 @@ export default function HelpDialog({ handleClose, }) {
|
|
|
38
38
|
" - use whitespace separated refname, start, end"))),
|
|
39
39
|
React.createElement(Divider, null),
|
|
40
40
|
React.createElement(DialogActions, null,
|
|
41
|
-
React.createElement(Button, { onClick: () =>
|
|
41
|
+
React.createElement(Button, { onClick: () => {
|
|
42
|
+
handleClose();
|
|
43
|
+
}, color: "primary" }, "Close"))));
|
|
42
44
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect,
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
3
|
import { getSession, useDebounce, measureText } from '@jbrowse/core/util';
|
|
4
4
|
import BaseResult, { RefSequenceResult, } from '@jbrowse/core/TextSearch/BaseResults';
|
|
@@ -34,24 +34,26 @@ const RefNameAutocomplete = observer(function ({ model, onSelect, assemblyName,
|
|
|
34
34
|
session.notifyError(`${e}`, e);
|
|
35
35
|
}
|
|
36
36
|
})();
|
|
37
|
-
}, [assemblyName, fetchResults, debouncedSearch, session
|
|
37
|
+
}, [assemblyName, fetchResults, debouncedSearch, session]);
|
|
38
38
|
const inputBoxVal = coarseVisibleLocStrings || value || '';
|
|
39
39
|
// heuristic, text width + 60 accommodates help icon and search icon
|
|
40
40
|
const width = Math.min(Math.max(measureText(inputBoxVal, 14) + 100, minWidth), maxWidth);
|
|
41
|
-
const
|
|
42
|
-
const regionOptions =
|
|
41
|
+
const refNames = assembly === null || assembly === void 0 ? void 0 : assembly.refNames;
|
|
42
|
+
const regionOptions = (refNames === null || refNames === void 0 ? void 0 : refNames.map(refName => ({
|
|
43
43
|
result: new RefSequenceResult({
|
|
44
|
-
refName
|
|
45
|
-
label:
|
|
44
|
+
refName,
|
|
45
|
+
label: refName,
|
|
46
46
|
matchedAttribute: 'refName',
|
|
47
47
|
}),
|
|
48
|
-
}))) || []
|
|
48
|
+
}))) || [];
|
|
49
49
|
// notes on implementation:
|
|
50
50
|
// The selectOnFocus setting helps highlight the field when clicked
|
|
51
51
|
return (React.createElement(Autocomplete, { "data-testid": "autocomplete", disableListWrap: true, disableClearable: true, disabled: !assemblyName, freeSolo: true, includeInputInList: true, selectOnFocus: true, style: { ...style, width }, value: inputBoxVal, loading: !loaded, inputValue: inputValue, onInputChange: (_event, newInputValue) => {
|
|
52
52
|
setInputValue(newInputValue);
|
|
53
53
|
onChange === null || onChange === void 0 ? void 0 : onChange(newInputValue);
|
|
54
|
-
}, loadingText: "loading results", open: open, onOpen: () =>
|
|
54
|
+
}, loadingText: "loading results", open: open, onOpen: () => {
|
|
55
|
+
setOpen(true);
|
|
56
|
+
}, onClose: () => {
|
|
55
57
|
setOpen(false);
|
|
56
58
|
setLoaded(true);
|
|
57
59
|
if (hasDisplayedRegions) {
|
|
@@ -3,10 +3,8 @@ import { makeStyles } from 'tss-react/mui';
|
|
|
3
3
|
import { Popover, Typography, alpha } from '@mui/material';
|
|
4
4
|
import { stringify, toLocale } from '@jbrowse/core/util';
|
|
5
5
|
const useStyles = makeStyles()(theme => {
|
|
6
|
-
const {
|
|
7
|
-
const background = tertiary
|
|
8
|
-
? alpha(tertiary.light, 0.7)
|
|
9
|
-
: alpha(primary.light, 0.7);
|
|
6
|
+
const { tertiary } = theme.palette;
|
|
7
|
+
const background = alpha(tertiary.light, 0.7);
|
|
10
8
|
return {
|
|
11
9
|
rubberband: {
|
|
12
10
|
height: '100%',
|
|
@@ -22,7 +20,7 @@ const useStyles = makeStyles()(theme => {
|
|
|
22
20
|
minHeight: 8,
|
|
23
21
|
},
|
|
24
22
|
rubberbandText: {
|
|
25
|
-
color: tertiary
|
|
23
|
+
color: tertiary.contrastText,
|
|
26
24
|
},
|
|
27
25
|
popover: {
|
|
28
26
|
mouseEvents: 'none',
|
|
@@ -46,6 +46,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
46
46
|
},
|
|
47
47
|
}));
|
|
48
48
|
const RenderedRefNameLabels = observer(function ({ model }) {
|
|
49
|
+
var _a;
|
|
49
50
|
const { classes } = useStyles();
|
|
50
51
|
const { staticBlocks, offsetPx, scaleBarDisplayPrefix } = model;
|
|
51
52
|
// find the block that needs pinning to the left side for context
|
|
@@ -57,7 +58,7 @@ const RenderedRefNameLabels = observer(function ({ model }) {
|
|
|
57
58
|
});
|
|
58
59
|
const val = scaleBarDisplayPrefix();
|
|
59
60
|
return (React.createElement(React.Fragment, null,
|
|
60
|
-
staticBlocks.blocks[0].type !== 'ContentBlock' && val ? (React.createElement(Typography, { style: { left: 0, zIndex: 100 }, className: classes.refLabel }, val)) : null,
|
|
61
|
+
((_a = staticBlocks.blocks[0]) === null || _a === void 0 ? void 0 : _a.type) !== 'ContentBlock' && val ? (React.createElement(Typography, { style: { left: 0, zIndex: 100 }, className: classes.refLabel }, val)) : null,
|
|
61
62
|
staticBlocks.map((block, index) => {
|
|
62
63
|
return block.type === 'ContentBlock' &&
|
|
63
64
|
(block.isLeftEndOfDisplayedRegion || index === lastLeftBlock) ? (React.createElement(Typography, { key: `refLabel-${block.key}-${index}`, style: {
|
|
@@ -13,5 +13,7 @@ export default function SearchResultsDialog({ model, assemblyName, searchQuery,
|
|
|
13
13
|
React.createElement(SearchResultsTable, { model: model, handleClose: handleClose, assemblyName: assemblyName, searchResults: searchResults })))),
|
|
14
14
|
React.createElement(Divider, null),
|
|
15
15
|
React.createElement(DialogActions, null,
|
|
16
|
-
React.createElement(Button, { onClick: () =>
|
|
16
|
+
React.createElement(Button, { onClick: () => {
|
|
17
|
+
handleClose();
|
|
18
|
+
}, color: "primary" }, "Cancel"))));
|
|
17
19
|
}
|
|
@@ -3,11 +3,10 @@ import { Button, Paper, Table, TableBody, TableCell, TableContainer, TableHead,
|
|
|
3
3
|
import { getRoot, resolveIdentifier } from 'mobx-state-tree';
|
|
4
4
|
import { getEnv, getSession } from '@jbrowse/core/util';
|
|
5
5
|
export default function SearchResultsTable({ searchResults, assemblyName: optAssemblyName, model, handleClose, }) {
|
|
6
|
-
var _a;
|
|
7
6
|
const session = getSession(model);
|
|
8
7
|
const { pluginManager } = getEnv(session);
|
|
9
8
|
const { assemblyManager } = session;
|
|
10
|
-
const assemblyName = optAssemblyName ||
|
|
9
|
+
const assemblyName = optAssemblyName || model.displayedRegions[0].assemblyName;
|
|
11
10
|
const assembly = assemblyManager.get(assemblyName);
|
|
12
11
|
if (!assembly) {
|
|
13
12
|
throw new Error(`assembly ${assemblyName} not found`);
|
|
@@ -51,7 +50,7 @@ export default function SearchResultsTable({ searchResults, assemblyName: optAss
|
|
|
51
50
|
React.createElement(TableCell, { align: "right" }, "Location"),
|
|
52
51
|
React.createElement(TableCell, { align: "right" }, "Track"),
|
|
53
52
|
React.createElement(TableCell, { align: "right" }))),
|
|
54
|
-
React.createElement(TableBody, null, searchResults.map(result => (React.createElement(TableRow, { key:
|
|
53
|
+
React.createElement(TableBody, null, searchResults.map(result => (React.createElement(TableRow, { key: result.getId() },
|
|
55
54
|
React.createElement(TableCell, { component: "th", scope: "row" }, result.getLabel()),
|
|
56
55
|
React.createElement(TableCell, { align: "right" }, result.getLocation()),
|
|
57
56
|
React.createElement(TableCell, { align: "right" }, getTrackName(result.getTrackId()) || 'N/A'),
|
|
@@ -26,11 +26,19 @@ const SequenceSearchDialog = observer(function ({ model, handleClose, }) {
|
|
|
26
26
|
return (React.createElement(Dialog, { maxWidth: "xl", open: true, onClose: handleClose, title: "Sequence search" },
|
|
27
27
|
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
28
28
|
React.createElement(Typography, null, "Supply a sequence to search for. A track will be created with the resulting matches once submitted. You can also supply regex style expressions e.g. AACT(C|T)."),
|
|
29
|
-
React.createElement(TextField, { value: value, onChange: e =>
|
|
29
|
+
React.createElement(TextField, { value: value, onChange: e => {
|
|
30
|
+
setValue(e.target.value);
|
|
31
|
+
}, helperText: "Sequence search pattern" }),
|
|
30
32
|
React.createElement(FormGroup, null,
|
|
31
|
-
React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: searchForward, onChange: event =>
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: searchForward, onChange: event => {
|
|
34
|
+
setSearchForward(event.target.checked);
|
|
35
|
+
} }), label: "Search forward strand" }),
|
|
36
|
+
React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: searchReverse, onChange: event => {
|
|
37
|
+
setSearchReverse(event.target.checked);
|
|
38
|
+
} }), label: "Search reverse strand" }),
|
|
39
|
+
React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: caseInsensitive, onChange: event => {
|
|
40
|
+
setCaseInsensitive(event.target.checked);
|
|
41
|
+
} }), label: "Case insensitive" })),
|
|
34
42
|
error ? React.createElement(Typography, { color: "error" }, `${error}`) : null),
|
|
35
43
|
React.createElement(DialogActions, null,
|
|
36
44
|
React.createElement(Button, { onClick: () => {
|
|
@@ -60,6 +68,8 @@ const SequenceSearchDialog = observer(function ({ model, handleClose, }) {
|
|
|
60
68
|
}
|
|
61
69
|
handleClose();
|
|
62
70
|
}, variant: "contained", color: "primary" }, "Submit"),
|
|
63
|
-
React.createElement(Button, { onClick: () =>
|
|
71
|
+
React.createElement(Button, { onClick: () => {
|
|
72
|
+
handleClose();
|
|
73
|
+
}, variant: "contained", color: "secondary" }, "Close"))));
|
|
64
74
|
});
|
|
65
75
|
export default SequenceSearchDialog;
|
|
@@ -21,9 +21,9 @@ const useStyles = makeStyles()({
|
|
|
21
21
|
const TrackContainer = observer(function ({ model, track, }) {
|
|
22
22
|
const { classes } = useStyles();
|
|
23
23
|
const display = track.displays[0];
|
|
24
|
-
const { draggingTrackId } = model;
|
|
24
|
+
const { draggingTrackId, showTrackOutlines } = model;
|
|
25
25
|
const ref = useRef(null);
|
|
26
|
-
return (React.createElement(Paper, { ref: ref, className: classes.root, variant:
|
|
26
|
+
return (React.createElement(Paper, { ref: ref, className: classes.root, variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
|
|
27
27
|
var _a;
|
|
28
28
|
if (event.detail === 2 && !track.displays[0].featureIdUnderMouse) {
|
|
29
29
|
const left = ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0;
|
|
@@ -48,27 +48,37 @@ const TrackLabel = observer(React.forwardRef(function TrackLabel2({ track, class
|
|
|
48
48
|
{
|
|
49
49
|
label: minimized ? 'Restore track' : 'Minimize track',
|
|
50
50
|
icon: minimized ? AddIcon : MinimizeIcon,
|
|
51
|
-
onClick: () =>
|
|
51
|
+
onClick: () => {
|
|
52
|
+
track.setMinimized(!minimized);
|
|
53
|
+
},
|
|
52
54
|
},
|
|
53
55
|
{
|
|
54
56
|
label: 'Move track to top',
|
|
55
57
|
icon: KeyboardDoubleArrowUpIcon,
|
|
56
|
-
onClick: () =>
|
|
58
|
+
onClick: () => {
|
|
59
|
+
view.moveTrackToTop(track.id);
|
|
60
|
+
},
|
|
57
61
|
},
|
|
58
62
|
{
|
|
59
63
|
label: 'Move track up',
|
|
60
64
|
icon: KeyboardArrowUpIcon,
|
|
61
|
-
onClick: () =>
|
|
65
|
+
onClick: () => {
|
|
66
|
+
view.moveTrackUp(track.id);
|
|
67
|
+
},
|
|
62
68
|
},
|
|
63
69
|
{
|
|
64
70
|
label: 'Move track down',
|
|
65
71
|
icon: KeyboardArrowDownIcon,
|
|
66
|
-
onClick: () =>
|
|
72
|
+
onClick: () => {
|
|
73
|
+
view.moveTrackDown(track.id);
|
|
74
|
+
},
|
|
67
75
|
},
|
|
68
76
|
{
|
|
69
77
|
label: 'Move track to bottom',
|
|
70
78
|
icon: KeyboardDoubleArrowDownIcon,
|
|
71
|
-
onClick: () =>
|
|
79
|
+
onClick: () => {
|
|
80
|
+
view.moveTrackToBottom(track.id);
|
|
81
|
+
},
|
|
72
82
|
},
|
|
73
83
|
],
|
|
74
84
|
},
|
|
@@ -21,7 +21,9 @@ function TrackLabelDragHandle({ trackId, view, track, }) {
|
|
|
21
21
|
event.dataTransfer.setDragImage(parent, 20, 20);
|
|
22
22
|
view.setDraggingTrackId(track.id);
|
|
23
23
|
}
|
|
24
|
-
}, onDragEnd: () =>
|
|
24
|
+
}, onDragEnd: () => {
|
|
25
|
+
view.setDraggingTrackId(undefined);
|
|
26
|
+
}, "data-testid": `dragHandle-${view.id}-${trackId}` },
|
|
25
27
|
React.createElement(DragIcon, { className: classes.dragHandleIcon, fontSize: "small" })));
|
|
26
28
|
}
|
|
27
29
|
export default TrackLabelDragHandle;
|
|
@@ -25,7 +25,7 @@ const TracksContainer = observer(function TracksContainer({ children, model, })
|
|
|
25
25
|
const { pluginManager } = getEnv(model);
|
|
26
26
|
const { mouseDown: mouseDown1, mouseUp } = useSideScroll(model);
|
|
27
27
|
const ref = useRef(null);
|
|
28
|
-
const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition,
|
|
28
|
+
const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown: mouseDown2, } = useRangeSelect(ref, model, true);
|
|
29
29
|
useWheelScroll(ref, model);
|
|
30
30
|
const additional = pluginManager.evaluateExtensionPoint('LinearGenomeView-TracksContainerComponent', undefined, { model });
|
|
31
31
|
return (React.createElement("div", { ref: ref, "data-testid": "trackContainer", className: classes.tracksContainer, onMouseDown: event => {
|
|
@@ -21,12 +21,18 @@ const ZoomControls = observer(function ({ model, }) {
|
|
|
21
21
|
const [value, setValue] = useState(-Math.log2(bpPerPx) * 100);
|
|
22
22
|
useEffect(() => {
|
|
23
23
|
setValue(-Math.log2(bpPerPx) * 100);
|
|
24
|
-
}, [
|
|
24
|
+
}, [bpPerPx]);
|
|
25
25
|
return (React.createElement("div", { className: classes.container },
|
|
26
|
-
React.createElement(IconButton, { "data-testid": "zoom_out", onClick: () =>
|
|
26
|
+
React.createElement(IconButton, { "data-testid": "zoom_out", onClick: () => {
|
|
27
|
+
model.zoom(bpPerPx * 2);
|
|
28
|
+
}, disabled: bpPerPx >= maxBpPerPx - 0.0001, size: "large" },
|
|
27
29
|
React.createElement(ZoomOut, null)),
|
|
28
|
-
React.createElement(Slider, { size: "small", className: classes.slider, value: value, min: -Math.log2(maxBpPerPx) * 100, max: -Math.log2(minBpPerPx) * 100, onChange: (_, val) =>
|
|
29
|
-
|
|
30
|
+
React.createElement(Slider, { size: "small", className: classes.slider, value: value, min: -Math.log2(maxBpPerPx) * 100, max: -Math.log2(minBpPerPx) * 100, onChange: (_, val) => {
|
|
31
|
+
setValue(val);
|
|
32
|
+
}, onChangeCommitted: () => model.zoomTo(2 ** (-value / 100)) }),
|
|
33
|
+
React.createElement(IconButton, { "data-testid": "zoom_in", onClick: () => {
|
|
34
|
+
model.zoom(model.bpPerPx / 2);
|
|
35
|
+
}, disabled: bpPerPx <= minBpPerPx + 0.0001, size: "large" },
|
|
30
36
|
React.createElement(ZoomIn, null))));
|
|
31
37
|
});
|
|
32
38
|
export default ZoomControls;
|
|
@@ -16,7 +16,7 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement>, mod
|
|
|
16
16
|
mouseDown: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
17
17
|
mouseMove: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
18
18
|
mouseOut: () => void;
|
|
19
|
-
handleMenuItemClick: (_: unknown, callback:
|
|
19
|
+
handleMenuItemClick: (_: unknown, callback: () => void) => void;
|
|
20
20
|
rubberbandOn?: undefined;
|
|
21
21
|
handleClose?: undefined;
|
|
22
22
|
leftBpOffset?: undefined;
|
|
@@ -32,7 +32,7 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement>, mod
|
|
|
32
32
|
mouseMove: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
33
33
|
mouseOut: () => void;
|
|
34
34
|
handleClose: () => void;
|
|
35
|
-
handleMenuItemClick: (_: unknown, callback:
|
|
35
|
+
handleMenuItemClick: (_: unknown, callback: () => void) => void;
|
|
36
36
|
leftBpOffset: {
|
|
37
37
|
coord: number;
|
|
38
38
|
index: number;
|
|
@@ -40,7 +40,7 @@ export function useSideScroll(model) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
return cleanup;
|
|
43
|
-
}, [model, mouseDragging
|
|
43
|
+
}, [model, mouseDragging]);
|
|
44
44
|
function mouseDown(event) {
|
|
45
45
|
if (event.shiftKey) {
|
|
46
46
|
return;
|
|
@@ -117,7 +117,7 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
119
|
return () => { };
|
|
120
|
-
}, [startX, mouseDragging,
|
|
120
|
+
}, [startX, mouseDragging, model, ref]);
|
|
121
121
|
useEffect(() => {
|
|
122
122
|
if (!mouseDragging &&
|
|
123
123
|
currentX !== undefined &&
|
|
@@ -173,29 +173,27 @@ export function useRangeSelect(ref, model, shiftOnly) {
|
|
|
173
173
|
handleMenuItemClick,
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
};
|
|
198
|
-
}
|
|
176
|
+
const right = anchorPosition ? anchorPosition.offsetX : currentX || 0;
|
|
177
|
+
const left = right < startX ? right : startX;
|
|
178
|
+
const width = Math.abs(right - startX);
|
|
179
|
+
const leftBpOffset = model.pxToBp(left);
|
|
180
|
+
const rightBpOffset = model.pxToBp(left + width);
|
|
181
|
+
const numOfBpSelected = Math.ceil(width * model.bpPerPx);
|
|
182
|
+
return {
|
|
183
|
+
open,
|
|
184
|
+
rubberbandOn: true,
|
|
185
|
+
mouseDown,
|
|
186
|
+
mouseMove,
|
|
187
|
+
mouseOut,
|
|
188
|
+
handleClose,
|
|
189
|
+
handleMenuItemClick,
|
|
190
|
+
leftBpOffset,
|
|
191
|
+
rightBpOffset,
|
|
192
|
+
anchorPosition,
|
|
193
|
+
numOfBpSelected,
|
|
194
|
+
width,
|
|
195
|
+
left,
|
|
196
|
+
};
|
|
199
197
|
}
|
|
200
198
|
export function useWheelScroll(ref, model) {
|
|
201
199
|
const delta = useRef(0);
|
|
@@ -206,7 +204,7 @@ export function useWheelScroll(ref, model) {
|
|
|
206
204
|
// if ctrl is held down, zoom in with y-scroll
|
|
207
205
|
// else scroll horizontally with x-scroll
|
|
208
206
|
function onWheel(event) {
|
|
209
|
-
if (event.ctrlKey
|
|
207
|
+
if (event.ctrlKey) {
|
|
210
208
|
event.preventDefault();
|
|
211
209
|
delta.current += event.deltaY / 500;
|
|
212
210
|
model.setScaleFactor(delta.current < 0 ? 1 - delta.current : 1 / (1 + delta.current));
|
|
@@ -12,10 +12,10 @@ export declare function fetchResults({ queryString, searchType, searchScope, ran
|
|
|
12
12
|
assembly?: Assembly;
|
|
13
13
|
}): Promise<BaseResult[]>;
|
|
14
14
|
export declare function splitLast(str: string, split: string): [string, string];
|
|
15
|
-
export declare function getRelativeX
|
|
15
|
+
export declare function getRelativeX(event: {
|
|
16
16
|
clientX: number;
|
|
17
17
|
target: EventTarget | null;
|
|
18
|
-
}
|
|
18
|
+
}, element: HTMLElement | null): number;
|
|
19
19
|
export declare function getCytobands(assembly: Assembly | undefined, refName: string): {
|
|
20
20
|
refName: string;
|
|
21
21
|
start: number;
|
|
@@ -33,6 +33,12 @@ export interface ExportSvgOptions {
|
|
|
33
33
|
trackLabels?: string;
|
|
34
34
|
themeName?: string;
|
|
35
35
|
}
|
|
36
|
+
export interface HighlightType {
|
|
37
|
+
start: number;
|
|
38
|
+
end: number;
|
|
39
|
+
assemblyName: string;
|
|
40
|
+
refName: string;
|
|
41
|
+
}
|
|
36
42
|
export interface NavLocation {
|
|
37
43
|
refName: string;
|
|
38
44
|
start?: number;
|
|
@@ -72,8 +78,9 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
72
78
|
showCytobandsSetting: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
73
79
|
trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
74
80
|
showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
75
|
-
highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<
|
|
81
|
+
highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<HighlightType, HighlightType, HighlightType>>, [undefined]>;
|
|
76
82
|
colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
83
|
+
showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
77
84
|
}, {
|
|
78
85
|
width: number;
|
|
79
86
|
} & {
|
|
@@ -87,7 +94,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
87
94
|
minimumBlockWidth: number;
|
|
88
95
|
draggingTrackId: undefined | string;
|
|
89
96
|
volatileError: unknown;
|
|
90
|
-
afterDisplayedRegionsSetCallbacks:
|
|
97
|
+
afterDisplayedRegionsSetCallbacks: (() => void)[];
|
|
91
98
|
scaleFactor: number;
|
|
92
99
|
trackRefs: Record<string, HTMLDivElement>;
|
|
93
100
|
coarseDynamicBlocks: BaseBlock[];
|
|
@@ -95,7 +102,6 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
95
102
|
leftOffset: undefined | BpOffset;
|
|
96
103
|
rightOffset: undefined | BpOffset;
|
|
97
104
|
} & {
|
|
98
|
-
scaleBarDisplayPrefix(): "";
|
|
99
105
|
/**
|
|
100
106
|
* #getter
|
|
101
107
|
* this is the effective value of the track labels setting, incorporating
|
|
@@ -115,6 +121,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
115
121
|
*/
|
|
116
122
|
readonly assemblyNames: string[];
|
|
117
123
|
} & {
|
|
124
|
+
/**
|
|
125
|
+
* #method
|
|
126
|
+
*/
|
|
127
|
+
scaleBarDisplayPrefix(): string | undefined;
|
|
118
128
|
/**
|
|
119
129
|
* #method
|
|
120
130
|
*/
|
|
@@ -174,7 +184,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
174
184
|
/**
|
|
175
185
|
* #getter
|
|
176
186
|
*/
|
|
177
|
-
readonly error:
|
|
187
|
+
readonly error: unknown;
|
|
178
188
|
/**
|
|
179
189
|
* #getter
|
|
180
190
|
*/
|
|
@@ -217,6 +227,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
217
227
|
*/
|
|
218
228
|
readonly trackTypeActions: Map<string, MenuItem[]>;
|
|
219
229
|
} & {
|
|
230
|
+
/**
|
|
231
|
+
* #action
|
|
232
|
+
*/
|
|
233
|
+
setShowTrackOutlines(arg: boolean): void;
|
|
220
234
|
/**
|
|
221
235
|
* #action
|
|
222
236
|
*/
|
|
@@ -252,15 +266,15 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
252
266
|
/**
|
|
253
267
|
* #action
|
|
254
268
|
*/
|
|
255
|
-
addToHighlights(highlight:
|
|
269
|
+
addToHighlights(highlight: HighlightType): void;
|
|
256
270
|
/**
|
|
257
271
|
* #action
|
|
258
272
|
*/
|
|
259
|
-
setHighlight(highlight
|
|
273
|
+
setHighlight(highlight?: HighlightType[]): void;
|
|
260
274
|
/**
|
|
261
275
|
* #action
|
|
262
276
|
*/
|
|
263
|
-
removeHighlight(highlight:
|
|
277
|
+
removeHighlight(highlight: HighlightType): void;
|
|
264
278
|
/**
|
|
265
279
|
* #action
|
|
266
280
|
*/
|
|
@@ -317,10 +331,6 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
317
331
|
* #action
|
|
318
332
|
*/
|
|
319
333
|
moveTrack(movingId: string, targetId: string): void;
|
|
320
|
-
/**
|
|
321
|
-
* #action
|
|
322
|
-
*/
|
|
323
|
-
closeView(): void;
|
|
324
334
|
/**
|
|
325
335
|
* #action
|
|
326
336
|
*/
|
|
@@ -372,7 +382,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
372
382
|
* schedule something to be run after the next time displayedRegions is
|
|
373
383
|
* set
|
|
374
384
|
*/
|
|
375
|
-
afterDisplayedRegionsSet(cb:
|
|
385
|
+
afterDisplayedRegionsSet(cb: () => void): void;
|
|
376
386
|
/**
|
|
377
387
|
* #action
|
|
378
388
|
*/
|
|
@@ -614,8 +624,9 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
614
624
|
showCytobandsSetting: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
615
625
|
trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
616
626
|
showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
617
|
-
highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<
|
|
627
|
+
highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<HighlightType, HighlightType, HighlightType>>, [undefined]>;
|
|
618
628
|
colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
629
|
+
showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
619
630
|
}>>, import("mobx-state-tree")._NotCustomized>;
|
|
620
631
|
export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>;
|
|
621
632
|
export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>;
|