@jbrowse/plugin-linear-genome-view 2.10.2 → 2.11.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/BlockMsg.d.ts +2 -4
- package/dist/BaseLinearDisplay/components/BlockMsg.js +2 -3
- package/dist/BaseLinearDisplay/components/LinearBlocks.js +2 -2
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.d.ts +10 -2
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +40 -4
- package/dist/BaseLinearDisplay/components/TooLargeMessage.js +5 -4
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +18 -4
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +9 -2
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -1
- package/dist/LaunchLinearGenomeView/index.js +24 -8
- package/dist/LinearBareDisplay/model.d.ts +18 -4
- package/dist/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -1
- package/dist/LinearBasicDisplay/model.d.ts +22 -4
- package/dist/LinearGenomeView/components/Cytobands.d.ts +1 -125
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +9 -5
- package/dist/LinearGenomeView/components/Highlight.d.ts +7 -0
- package/dist/LinearGenomeView/components/Highlight.js +126 -0
- package/dist/LinearGenomeView/components/MiniControls.js +13 -15
- package/dist/LinearGenomeView/components/OverviewHighlight.d.ts +9 -0
- package/dist/LinearGenomeView/components/OverviewHighlight.js +62 -0
- package/dist/LinearGenomeView/components/OverviewRubberband.d.ts +1 -1
- package/dist/LinearGenomeView/components/OverviewScalebar.js +6 -1
- package/dist/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +1 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +9 -9
- package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js +28 -35
- package/dist/LinearGenomeView/components/Rubberband.d.ts +1 -1
- package/dist/LinearGenomeView/components/SearchBox.d.ts +1 -1
- package/dist/LinearGenomeView/components/SearchResultsTable.js +1 -1
- package/dist/LinearGenomeView/components/TrackContainer.js +10 -23
- package/dist/LinearGenomeView/components/TrackLabel.js +33 -6
- package/dist/LinearGenomeView/components/TracksContainer.js +2 -0
- package/dist/LinearGenomeView/components/ZoomControls.js +4 -4
- package/dist/LinearGenomeView/model.d.ts +70 -5
- package/dist/LinearGenomeView/model.js +111 -14
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +1 -1
- package/dist/LinearGenomeView/util.d.ts +1 -1
- package/dist/index.d.ts +213 -21
- package/esm/BaseLinearDisplay/components/BlockMsg.d.ts +2 -4
- package/esm/BaseLinearDisplay/components/BlockMsg.js +3 -4
- package/esm/BaseLinearDisplay/components/LinearBlocks.js +2 -2
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.d.ts +10 -2
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +17 -4
- package/esm/BaseLinearDisplay/components/TooLargeMessage.js +5 -4
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +18 -4
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +9 -2
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -1
- package/esm/LaunchLinearGenomeView/index.js +25 -9
- package/esm/LinearBareDisplay/model.d.ts +18 -4
- package/esm/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -1
- package/esm/LinearBasicDisplay/model.d.ts +22 -4
- package/esm/LinearGenomeView/components/Cytobands.d.ts +1 -125
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +9 -5
- package/esm/LinearGenomeView/components/Highlight.d.ts +7 -0
- package/esm/LinearGenomeView/components/Highlight.js +98 -0
- package/esm/LinearGenomeView/components/MiniControls.js +14 -16
- package/esm/LinearGenomeView/components/OverviewHighlight.d.ts +9 -0
- package/esm/LinearGenomeView/components/OverviewHighlight.js +57 -0
- package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +1 -1
- package/esm/LinearGenomeView/components/OverviewScalebar.js +7 -2
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +1 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +9 -9
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +28 -35
- package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -1
- package/esm/LinearGenomeView/components/SearchBox.d.ts +1 -1
- package/esm/LinearGenomeView/components/SearchResultsTable.js +1 -1
- package/esm/LinearGenomeView/components/TrackContainer.js +10 -23
- package/esm/LinearGenomeView/components/TrackLabel.js +33 -6
- package/esm/LinearGenomeView/components/TracksContainer.js +2 -0
- package/esm/LinearGenomeView/components/ZoomControls.js +4 -4
- package/esm/LinearGenomeView/model.d.ts +70 -5
- package/esm/LinearGenomeView/model.js +112 -15
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +1 -1
- package/esm/LinearGenomeView/util.d.ts +1 -1
- package/esm/index.d.ts +213 -21
- package/package.json +2 -2
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const react_1 = __importStar(require("react"));
|
|
30
|
+
const mobx_react_1 = require("mobx-react");
|
|
31
|
+
const mui_1 = require("tss-react/mui");
|
|
32
|
+
const colord_1 = require("@jbrowse/core/util/colord");
|
|
33
|
+
const util_1 = require("@jbrowse/core/util");
|
|
34
|
+
const ui_1 = require("@jbrowse/core/ui");
|
|
35
|
+
const material_1 = require("@mui/material");
|
|
36
|
+
// icons
|
|
37
|
+
const Link_1 = __importDefault(require("@mui/icons-material/Link"));
|
|
38
|
+
const Close_1 = __importDefault(require("@mui/icons-material/Close"));
|
|
39
|
+
const Bookmark_1 = __importDefault(require("@mui/icons-material/Bookmark"));
|
|
40
|
+
const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
return ({
|
|
43
|
+
highlight: {
|
|
44
|
+
height: '100%',
|
|
45
|
+
position: 'absolute',
|
|
46
|
+
overflow: 'hidden',
|
|
47
|
+
background: `${(0, colord_1.colord)((_b = (_a = theme.palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
|
|
48
|
+
.alpha(0.35)
|
|
49
|
+
.toRgbString()}`,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
const Highlight = (0, mobx_react_1.observer)(function Highlight({ model, highlight, }) {
|
|
54
|
+
var _a, _b, _c;
|
|
55
|
+
const { classes } = useStyles();
|
|
56
|
+
const [open, setOpen] = (0, react_1.useState)(false);
|
|
57
|
+
const anchorEl = (0, react_1.useRef)(null);
|
|
58
|
+
const color = (_b = (_a = (0, material_1.useTheme)().palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod';
|
|
59
|
+
const session = (0, util_1.getSession)(model);
|
|
60
|
+
const { assemblyManager } = session;
|
|
61
|
+
const dismissHighlight = () => {
|
|
62
|
+
model.removeHighlight(highlight);
|
|
63
|
+
};
|
|
64
|
+
const menuItems = [
|
|
65
|
+
{
|
|
66
|
+
label: 'Dismiss highlight',
|
|
67
|
+
icon: Close_1.default,
|
|
68
|
+
onClick: () => dismissHighlight(),
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
label: 'Bookmark highlighted region',
|
|
72
|
+
icon: Bookmark_1.default,
|
|
73
|
+
onClick: () => {
|
|
74
|
+
let bookmarkWidget = session.widgets.get('GridBookmark');
|
|
75
|
+
if (!bookmarkWidget) {
|
|
76
|
+
bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
77
|
+
}
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
bookmarkWidget.addBookmark(highlight);
|
|
80
|
+
dismissHighlight();
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
function handleClose() {
|
|
85
|
+
setOpen(false);
|
|
86
|
+
}
|
|
87
|
+
// coords
|
|
88
|
+
const mapCoords = (r) => {
|
|
89
|
+
const s = model.bpToPx({
|
|
90
|
+
refName: r.refName,
|
|
91
|
+
coord: r.start,
|
|
92
|
+
});
|
|
93
|
+
const e = model.bpToPx({
|
|
94
|
+
refName: r.refName,
|
|
95
|
+
coord: r.end,
|
|
96
|
+
});
|
|
97
|
+
return s && e
|
|
98
|
+
? {
|
|
99
|
+
width: Math.max(Math.abs(e.offsetPx - s.offsetPx), 3),
|
|
100
|
+
left: Math.min(s.offsetPx, e.offsetPx) - model.offsetPx,
|
|
101
|
+
}
|
|
102
|
+
: undefined;
|
|
103
|
+
};
|
|
104
|
+
const asm = assemblyManager.get(highlight === null || highlight === void 0 ? void 0 : highlight.assemblyName);
|
|
105
|
+
const h = mapCoords({
|
|
106
|
+
...highlight,
|
|
107
|
+
refName: (_c = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(highlight.refName)) !== null && _c !== void 0 ? _c : highlight.refName,
|
|
108
|
+
});
|
|
109
|
+
return h ? (react_1.default.createElement("div", { className: classes.highlight, style: {
|
|
110
|
+
left: h.left,
|
|
111
|
+
width: h.width,
|
|
112
|
+
} },
|
|
113
|
+
react_1.default.createElement(material_1.Tooltip, { title: 'Highlighted from URL parameter', arrow: true },
|
|
114
|
+
react_1.default.createElement(material_1.IconButton, { ref: anchorEl, onClick: () => setOpen(true), style: { zIndex: 3 } },
|
|
115
|
+
react_1.default.createElement(Link_1.default, { fontSize: "small", sx: {
|
|
116
|
+
color: `${(0, colord_1.colord)(color).darken(0.2).toRgbString()}`,
|
|
117
|
+
} }))),
|
|
118
|
+
react_1.default.createElement(ui_1.Menu, { anchorEl: anchorEl.current, onMenuItemClick: (_event, callback) => {
|
|
119
|
+
callback(session);
|
|
120
|
+
handleClose();
|
|
121
|
+
}, open: open, onClose: handleClose, menuItems: menuItems }))) : null;
|
|
122
|
+
});
|
|
123
|
+
const HighlightGroup = (0, mobx_react_1.observer)(function HighlightGroup({ model, }) {
|
|
124
|
+
return model.highlight.map((highlight, idx) => (react_1.default.createElement(Highlight, { key: JSON.stringify(highlight) + '-' + idx, model: model, highlight: highlight })));
|
|
125
|
+
});
|
|
126
|
+
exports.default = HighlightGroup;
|
|
@@ -6,13 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
const mobx_react_1 = require("mobx-react");
|
|
8
8
|
const material_1 = require("@mui/material");
|
|
9
|
+
const CascadingMenuButton_1 = __importDefault(require("@jbrowse/core/ui/CascadingMenuButton"));
|
|
10
|
+
const mui_1 = require("tss-react/mui");
|
|
11
|
+
const util_1 = require("@jbrowse/core/util");
|
|
9
12
|
// icons
|
|
10
13
|
const ZoomIn_1 = __importDefault(require("@mui/icons-material/ZoomIn"));
|
|
11
14
|
const ZoomOut_1 = __importDefault(require("@mui/icons-material/ZoomOut"));
|
|
12
15
|
const KeyboardArrowDown_1 = __importDefault(require("@mui/icons-material/KeyboardArrowDown"));
|
|
13
|
-
const CascadingMenuButton_1 = __importDefault(require("@jbrowse/core/ui/CascadingMenuButton"));
|
|
14
|
-
const mui_1 = require("tss-react/mui");
|
|
15
|
-
const util_1 = require("@jbrowse/core/util");
|
|
16
16
|
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
17
17
|
background: {
|
|
18
18
|
position: 'absolute',
|
|
@@ -21,22 +21,20 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
21
21
|
background: theme.palette.background.paper,
|
|
22
22
|
},
|
|
23
23
|
focusedBackground: {
|
|
24
|
-
background: theme.palette.secondary.light,
|
|
25
|
-
svg: {
|
|
26
|
-
fill: theme.palette.secondary.contrastText,
|
|
27
|
-
},
|
|
24
|
+
background: (0, material_1.alpha)(theme.palette.secondary.light, 0.2),
|
|
28
25
|
},
|
|
29
26
|
}));
|
|
30
27
|
const MiniControls = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
31
|
-
const { classes
|
|
28
|
+
const { classes } = useStyles();
|
|
32
29
|
const { id, bpPerPx, maxBpPerPx, minBpPerPx, scaleFactor, hideHeader } = model;
|
|
33
30
|
const { focusedViewId } = (0, util_1.getSession)(model);
|
|
34
|
-
return hideHeader ? (react_1.default.createElement(material_1.Paper, { className:
|
|
35
|
-
react_1.default.createElement(
|
|
36
|
-
react_1.default.createElement(
|
|
37
|
-
|
|
38
|
-
react_1.default.createElement(
|
|
39
|
-
|
|
40
|
-
react_1.default.createElement(
|
|
31
|
+
return hideHeader ? (react_1.default.createElement(material_1.Paper, { className: classes.background },
|
|
32
|
+
react_1.default.createElement(material_1.Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined },
|
|
33
|
+
react_1.default.createElement(CascadingMenuButton_1.default, { menuItems: model.menuItems() },
|
|
34
|
+
react_1.default.createElement(KeyboardArrowDown_1.default, { fontSize: "small" })),
|
|
35
|
+
react_1.default.createElement(material_1.IconButton, { "data-testid": "zoom_out", onClick: () => model.zoom(bpPerPx * 2), disabled: bpPerPx >= maxBpPerPx - 0.0001 || scaleFactor !== 1 },
|
|
36
|
+
react_1.default.createElement(ZoomOut_1.default, { fontSize: "small" })),
|
|
37
|
+
react_1.default.createElement(material_1.IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1 },
|
|
38
|
+
react_1.default.createElement(ZoomIn_1.default, { fontSize: "small" }))))) : null;
|
|
41
39
|
});
|
|
42
40
|
exports.default = MiniControls;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel';
|
|
3
|
+
import { LinearGenomeViewModel } from '../model';
|
|
4
|
+
type LGV = LinearGenomeViewModel;
|
|
5
|
+
declare const OverviewHighlight: ({ model, overview, }: {
|
|
6
|
+
model: LGV;
|
|
7
|
+
overview: Base1DViewModel;
|
|
8
|
+
}) => React.JSX.Element[];
|
|
9
|
+
export default OverviewHighlight;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const mobx_react_1 = require("mobx-react");
|
|
8
|
+
const mui_1 = require("tss-react/mui");
|
|
9
|
+
const colord_1 = require("@jbrowse/core/util/colord");
|
|
10
|
+
const util_1 = require("@jbrowse/core/util");
|
|
11
|
+
const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
12
|
+
var _a, _b, _c, _d, _e, _f;
|
|
13
|
+
return ({
|
|
14
|
+
highlight: {
|
|
15
|
+
height: '100%',
|
|
16
|
+
position: 'absolute',
|
|
17
|
+
background: `${(0, colord_1.colord)((_b = (_a = theme.palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
|
|
18
|
+
.alpha(0.35)
|
|
19
|
+
.toRgbString()}`,
|
|
20
|
+
borderLeft: `1px solid ${(_d = (_c = theme.palette.highlight) === null || _c === void 0 ? void 0 : _c.main) !== null && _d !== void 0 ? _d : 'goldenrod'}`,
|
|
21
|
+
borderRight: `1px solid ${(_f = (_e = theme.palette.highlight) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : 'goldenrod'}`,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
const OverviewHighlight = (0, mobx_react_1.observer)(function OverviewHighlight({ model, overview, }) {
|
|
26
|
+
const { classes } = useStyles();
|
|
27
|
+
const { cytobandOffset } = model;
|
|
28
|
+
const session = (0, util_1.getSession)(model);
|
|
29
|
+
const { assemblyManager } = session;
|
|
30
|
+
// coords
|
|
31
|
+
const mapCoords = (r) => {
|
|
32
|
+
const s = overview.bpToPx({
|
|
33
|
+
...r,
|
|
34
|
+
coord: r.reversed ? r.end : r.start,
|
|
35
|
+
});
|
|
36
|
+
const e = overview.bpToPx({
|
|
37
|
+
...r,
|
|
38
|
+
coord: r.reversed ? r.start : r.end,
|
|
39
|
+
});
|
|
40
|
+
return s !== undefined && e != undefined
|
|
41
|
+
? {
|
|
42
|
+
width: Math.abs(e - s),
|
|
43
|
+
left: s + cytobandOffset,
|
|
44
|
+
}
|
|
45
|
+
: undefined;
|
|
46
|
+
};
|
|
47
|
+
return model.highlight
|
|
48
|
+
.map(h => {
|
|
49
|
+
var _a;
|
|
50
|
+
const asm = assemblyManager.get(h === null || h === void 0 ? void 0 : h.assemblyName);
|
|
51
|
+
return mapCoords({
|
|
52
|
+
...h,
|
|
53
|
+
refName: (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(h.refName)) !== null && _a !== void 0 ? _a : h.refName,
|
|
54
|
+
});
|
|
55
|
+
})
|
|
56
|
+
.filter(util_1.notEmpty)
|
|
57
|
+
.map(({ left, width }, idx) => (react_1.default.createElement("div", { key: `${left}_${width}_${idx}`, className: classes.highlight, style: {
|
|
58
|
+
width: width,
|
|
59
|
+
left: left,
|
|
60
|
+
} })));
|
|
61
|
+
});
|
|
62
|
+
exports.default = OverviewHighlight;
|
|
@@ -5,6 +5,6 @@ type LGV = LinearGenomeViewModel;
|
|
|
5
5
|
declare const OverviewRubberband: ({ model, overview, ControlComponent, }: {
|
|
6
6
|
model: LGV;
|
|
7
7
|
overview: Base1DViewModel;
|
|
8
|
-
ControlComponent?: React.ReactElement
|
|
8
|
+
ControlComponent?: React.ReactElement;
|
|
9
9
|
}) => React.JSX.Element;
|
|
10
10
|
export default OverviewRubberband;
|
|
@@ -41,6 +41,7 @@ const util_3 = require("./util");
|
|
|
41
41
|
const OverviewRubberband_1 = __importDefault(require("./OverviewRubberband"));
|
|
42
42
|
const Cytobands_1 = __importDefault(require("./Cytobands"));
|
|
43
43
|
const OverviewScalebarPolygon_1 = __importDefault(require("./OverviewScalebarPolygon"));
|
|
44
|
+
const OverviewHighlight_1 = __importDefault(require("./OverviewHighlight"));
|
|
44
45
|
const wholeSeqSpacer = 2;
|
|
45
46
|
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
46
47
|
scalebar: {
|
|
@@ -145,6 +146,7 @@ const Scalebar = (0, mobx_react_1.observer)(function ({ model, scale, overview,
|
|
|
145
146
|
const { classes } = useStyles();
|
|
146
147
|
const theme = (0, material_1.useTheme)();
|
|
147
148
|
const { dynamicBlocks, showCytobands, cytobandOffset } = model;
|
|
149
|
+
const { pluginManager } = (0, util_1.getEnv)(model);
|
|
148
150
|
const visibleRegions = dynamicBlocks.contentBlocks;
|
|
149
151
|
const overviewVisibleRegions = overview.dynamicBlocks;
|
|
150
152
|
const { tertiary, primary } = theme.palette;
|
|
@@ -165,6 +167,7 @@ const Scalebar = (0, mobx_react_1.observer)(function ({ model, scale, overview,
|
|
|
165
167
|
}) || 0;
|
|
166
168
|
const color = showCytobands ? '#f00' : scalebarColor;
|
|
167
169
|
const transparency = showCytobands ? 0.1 : 0.3;
|
|
170
|
+
const additional = pluginManager.evaluateExtensionPoint('LinearGenomeView-OverviewScalebarComponent', undefined, { model, overview });
|
|
168
171
|
return (react_1.default.createElement("div", { className: classes.scalebar },
|
|
169
172
|
react_1.default.createElement("div", { className: classes.scalebarVisibleRegion, style: {
|
|
170
173
|
width: lastOverviewPx - firstOverviewPx,
|
|
@@ -179,7 +182,9 @@ const Scalebar = (0, mobx_react_1.observer)(function ({ model, scale, overview,
|
|
|
179
182
|
backgroundColor: '#999',
|
|
180
183
|
backgroundImage: 'repeating-linear-gradient(90deg, transparent, transparent 1px, rgba(255,255,255,.5) 1px, rgba(255,255,255,.5) 3px)',
|
|
181
184
|
} })) : (react_1.default.createElement(OverviewBox, { scale: scale, block: block, model: model, overview: overview, key: `${JSON.stringify(block)}-${idx}` }));
|
|
182
|
-
})
|
|
185
|
+
}),
|
|
186
|
+
react_1.default.createElement(OverviewHighlight_1.default, { model: model, overview: overview }),
|
|
187
|
+
additional));
|
|
183
188
|
});
|
|
184
189
|
const OverviewScalebar = (0, mobx_react_1.observer)(function ({ model, children, }) {
|
|
185
190
|
const { classes } = useStyles();
|
|
@@ -4,6 +4,6 @@ import { LinearGenomeViewModel } from '..';
|
|
|
4
4
|
declare const OverviewScalebarPolygon: ({ model, overview, useOffset, }: {
|
|
5
5
|
model: LinearGenomeViewModel;
|
|
6
6
|
overview: Base1DViewModel;
|
|
7
|
-
useOffset?: boolean
|
|
7
|
+
useOffset?: boolean;
|
|
8
8
|
}) => React.JSX.Element | null;
|
|
9
9
|
export default OverviewScalebarPolygon;
|
|
@@ -4,15 +4,15 @@ import { TextFieldProps as TFP } from '@mui/material';
|
|
|
4
4
|
import { LinearGenomeViewModel } from '../../model';
|
|
5
5
|
declare const RefNameAutocomplete: ({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp, minWidth, maxWidth, TextFieldProps, }: {
|
|
6
6
|
model: LinearGenomeViewModel;
|
|
7
|
-
onSelect?: (
|
|
8
|
-
onChange?: (
|
|
9
|
-
assemblyName?: string
|
|
10
|
-
value?: string
|
|
7
|
+
onSelect?: (region: BaseResult) => void;
|
|
8
|
+
onChange?: (val: string) => void;
|
|
9
|
+
assemblyName?: string;
|
|
10
|
+
value?: string;
|
|
11
11
|
fetchResults: (query: string) => Promise<BaseResult[]>;
|
|
12
|
-
style?: React.CSSProperties
|
|
13
|
-
minWidth?: number
|
|
14
|
-
maxWidth?: number
|
|
15
|
-
showHelp?: boolean
|
|
16
|
-
TextFieldProps?: TFP
|
|
12
|
+
style?: React.CSSProperties;
|
|
13
|
+
minWidth?: number;
|
|
14
|
+
maxWidth?: number;
|
|
15
|
+
showHelp?: boolean;
|
|
16
|
+
TextFieldProps?: TFP;
|
|
17
17
|
}) => React.JSX.Element;
|
|
18
18
|
export default RefNameAutocomplete;
|
|
@@ -45,7 +45,8 @@ const RefNameAutocomplete = (0, mobx_react_1.observer)(function ({ model, onSele
|
|
|
45
45
|
const assembly = assemblyName ? assemblyManager.get(assemblyName) : undefined;
|
|
46
46
|
const { coarseVisibleLocStrings, hasDisplayedRegions } = model;
|
|
47
47
|
(0, react_1.useEffect)(() => {
|
|
48
|
-
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
49
|
+
;
|
|
49
50
|
(async () => {
|
|
50
51
|
try {
|
|
51
52
|
if (debouncedSearch === '' || !assemblyName) {
|
|
@@ -53,21 +54,14 @@ const RefNameAutocomplete = (0, mobx_react_1.observer)(function ({ model, onSele
|
|
|
53
54
|
}
|
|
54
55
|
setLoaded(false);
|
|
55
56
|
const results = await fetchResults(debouncedSearch);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
setSearchOptions((0, util_2.getDeduplicatedResult)(results));
|
|
59
|
-
}
|
|
57
|
+
setLoaded(true);
|
|
58
|
+
setSearchOptions((0, util_2.getDeduplicatedResult)(results));
|
|
60
59
|
}
|
|
61
60
|
catch (e) {
|
|
62
61
|
console.error(e);
|
|
63
|
-
|
|
64
|
-
session.notify(`${e}`, 'error');
|
|
65
|
-
}
|
|
62
|
+
session.notifyError(`${e}`, e);
|
|
66
63
|
}
|
|
67
64
|
})();
|
|
68
|
-
return () => {
|
|
69
|
-
active = false;
|
|
70
|
-
};
|
|
71
65
|
}, [assemblyName, fetchResults, debouncedSearch, session, model]);
|
|
72
66
|
const inputBoxVal = coarseVisibleLocStrings || value || '';
|
|
73
67
|
// heuristic, text width + 60 accommodates help icon and search icon
|
|
@@ -82,29 +76,28 @@ const RefNameAutocomplete = (0, mobx_react_1.observer)(function ({ model, onSele
|
|
|
82
76
|
}))) || [], [regions]);
|
|
83
77
|
// notes on implementation:
|
|
84
78
|
// The selectOnFocus setting helps highlight the field when clicked
|
|
85
|
-
return (react_1.default.createElement(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}, options: (searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.length) ? searchOptions : regionOptions, getOptionDisabled: option => option.group === 'limitOption', filterOptions: (opts, { inputValue }) => (0, util_2.getFiltered)(opts, inputValue), renderInput: params => (react_1.default.createElement(AutocompleteTextField_1.default, { showHelp: showHelp, params: params, inputBoxVal: inputBoxVal, TextFieldProps: TextFieldProps, setCurrentSearch: setCurrentSearch, setInputValue: setInputValue })), getOptionLabel: opt => typeof opt === 'string' ? opt : opt.result.getDisplayString() })));
|
|
79
|
+
return (react_1.default.createElement(material_1.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) => {
|
|
80
|
+
setInputValue(newInputValue);
|
|
81
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newInputValue);
|
|
82
|
+
}, loadingText: "loading results", open: open, onOpen: () => setOpen(true), onClose: () => {
|
|
83
|
+
setOpen(false);
|
|
84
|
+
setLoaded(true);
|
|
85
|
+
if (hasDisplayedRegions) {
|
|
86
|
+
setCurrentSearch('');
|
|
87
|
+
setSearchOptions(undefined);
|
|
88
|
+
}
|
|
89
|
+
}, onChange: (_event, selectedOption) => {
|
|
90
|
+
if (!selectedOption || !assemblyName) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (typeof selectedOption === 'string') {
|
|
94
|
+
// handles string inputs on keyPress enter
|
|
95
|
+
onSelect === null || onSelect === void 0 ? void 0 : onSelect(new BaseResults_1.default({ label: selectedOption }));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedOption.result);
|
|
99
|
+
}
|
|
100
|
+
setInputValue(inputBoxVal);
|
|
101
|
+
}, options: (searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.length) ? searchOptions : regionOptions, getOptionDisabled: option => option.group === 'limitOption', filterOptions: (opts, { inputValue }) => (0, util_2.getFiltered)(opts, inputValue), renderInput: params => (react_1.default.createElement(AutocompleteTextField_1.default, { showHelp: showHelp, params: params, inputBoxVal: inputBoxVal, TextFieldProps: TextFieldProps, setCurrentSearch: setCurrentSearch, setInputValue: setInputValue })), getOptionLabel: opt => typeof opt === 'string' ? opt : opt.result.getDisplayString() }));
|
|
109
102
|
});
|
|
110
103
|
exports.default = RefNameAutocomplete;
|
|
@@ -3,6 +3,6 @@ import { LinearGenomeViewModel } from '..';
|
|
|
3
3
|
type LGV = LinearGenomeViewModel;
|
|
4
4
|
declare const Rubberband: ({ model, ControlComponent, }: {
|
|
5
5
|
model: LGV;
|
|
6
|
-
ControlComponent?: React.ReactElement
|
|
6
|
+
ControlComponent?: React.ReactElement;
|
|
7
7
|
}) => React.JSX.Element;
|
|
8
8
|
export default Rubberband;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { LinearGenomeViewModel } from '..';
|
|
3
3
|
declare const SearchBox: ({ model, showHelp, }: {
|
|
4
|
-
showHelp?: boolean
|
|
4
|
+
showHelp?: boolean;
|
|
5
5
|
model: LinearGenomeViewModel;
|
|
6
6
|
}) => React.JSX.Element;
|
|
7
7
|
export default SearchBox;
|
|
@@ -74,7 +74,7 @@ function SearchResultsTable({ searchResults, assemblyName: optAssemblyName, mode
|
|
|
74
74
|
}
|
|
75
75
|
catch (e) {
|
|
76
76
|
console.error(e);
|
|
77
|
-
session.
|
|
77
|
+
session.notifyError(`${e}`, e);
|
|
78
78
|
}
|
|
79
79
|
handleClose();
|
|
80
80
|
}, color: "primary", variant: "contained" }, "Go")))))))));
|
|
@@ -33,7 +33,6 @@ const mobx_react_1 = require("mobx-react");
|
|
|
33
33
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
34
34
|
const react_error_boundary_1 = require("react-error-boundary");
|
|
35
35
|
const ui_1 = require("@jbrowse/core/ui");
|
|
36
|
-
const util_1 = require("@jbrowse/core/util");
|
|
37
36
|
const TrackLabelContainer_1 = __importDefault(require("./TrackLabelContainer"));
|
|
38
37
|
const TrackRenderingContainer_1 = __importDefault(require("./TrackRenderingContainer"));
|
|
39
38
|
const useStyles = (0, mui_1.makeStyles)()({
|
|
@@ -46,40 +45,28 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
46
45
|
position: 'relative',
|
|
47
46
|
zIndex: 2,
|
|
48
47
|
},
|
|
49
|
-
overlay: {
|
|
50
|
-
pointerEvents: 'none',
|
|
51
|
-
position: 'absolute',
|
|
52
|
-
top: 0,
|
|
53
|
-
left: 0,
|
|
54
|
-
width: '100%',
|
|
55
|
-
zIndex: 3,
|
|
56
|
-
},
|
|
57
48
|
});
|
|
58
49
|
const TrackContainer = (0, mobx_react_1.observer)(function ({ model, track, }) {
|
|
59
50
|
const { classes } = useStyles();
|
|
60
51
|
const display = track.displays[0];
|
|
61
52
|
const { draggingTrackId } = model;
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
const debouncedOnDragEnter = (0, util_1.useDebouncedCallback)(() => {
|
|
65
|
-
if ((0, mobx_state_tree_1.isAlive)(display) && dimmed) {
|
|
66
|
-
model.moveTrack(draggingTrackId, track.id);
|
|
67
|
-
}
|
|
68
|
-
}, 100);
|
|
69
|
-
return (react_1.default.createElement(material_1.Paper, { ref: ref2, className: classes.root, variant: "outlined", onClick: event => {
|
|
53
|
+
const ref = (0, react_1.useRef)(null);
|
|
54
|
+
return (react_1.default.createElement(material_1.Paper, { ref: ref, className: classes.root, variant: "outlined", onClick: event => {
|
|
70
55
|
var _a;
|
|
71
56
|
if (event.detail === 2 && !track.displays[0].featureIdUnderMouse) {
|
|
72
|
-
const left = ((_a =
|
|
57
|
+
const left = ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0;
|
|
73
58
|
model.zoomTo(model.bpPerPx / 2, event.clientX - left, true);
|
|
74
59
|
}
|
|
75
60
|
} },
|
|
76
61
|
react_1.default.createElement(TrackLabelContainer_1.default, { track: track, view: model }),
|
|
77
62
|
react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: e => react_1.default.createElement(ui_1.ErrorMessage, { error: e.error }) },
|
|
78
|
-
react_1.default.createElement(TrackRenderingContainer_1.default, { model: model, track: track, onDragEnter:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
63
|
+
react_1.default.createElement(TrackRenderingContainer_1.default, { model: model, track: track, onDragEnter: () => {
|
|
64
|
+
if ((0, mobx_state_tree_1.isAlive)(display) &&
|
|
65
|
+
draggingTrackId !== undefined &&
|
|
66
|
+
draggingTrackId !== display.id) {
|
|
67
|
+
model.moveTrack(draggingTrackId, track.id);
|
|
68
|
+
}
|
|
69
|
+
} })),
|
|
83
70
|
react_1.default.createElement(ui_1.ResizeHandle, { onDrag: display.resizeHeight, className: classes.resizeHandle })));
|
|
84
71
|
});
|
|
85
72
|
exports.default = TrackContainer;
|
|
@@ -17,6 +17,10 @@ const MoreVert_1 = __importDefault(require("@mui/icons-material/MoreVert"));
|
|
|
17
17
|
const Close_1 = __importDefault(require("@mui/icons-material/Close"));
|
|
18
18
|
const Minimize_1 = __importDefault(require("@mui/icons-material/Minimize"));
|
|
19
19
|
const Add_1 = __importDefault(require("@mui/icons-material/Add"));
|
|
20
|
+
const KeyboardDoubleArrowDown_1 = __importDefault(require("@mui/icons-material/KeyboardDoubleArrowDown"));
|
|
21
|
+
const KeyboardDoubleArrowUp_1 = __importDefault(require("@mui/icons-material/KeyboardDoubleArrowUp"));
|
|
22
|
+
const KeyboardArrowDown_1 = __importDefault(require("@mui/icons-material/KeyboardArrowDown"));
|
|
23
|
+
const KeyboardArrowUp_1 = __importDefault(require("@mui/icons-material/KeyboardArrowUp"));
|
|
20
24
|
const TrackLabelDragHandle_1 = __importDefault(require("./TrackLabelDragHandle"));
|
|
21
25
|
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
22
26
|
root: {
|
|
@@ -24,9 +28,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
24
28
|
'&:hover': {
|
|
25
29
|
background: theme.palette.background.paper,
|
|
26
30
|
},
|
|
27
|
-
transition: theme.transitions.create(['background'], {
|
|
28
|
-
duration: theme.transitions.duration.shortest,
|
|
29
|
-
}),
|
|
30
31
|
},
|
|
31
32
|
trackName: {
|
|
32
33
|
margin: '0 auto',
|
|
@@ -49,9 +50,35 @@ const TrackLabel = (0, mobx_react_1.observer)(react_1.default.forwardRef(functio
|
|
|
49
50
|
const trackName = (0, tracks_1.getTrackName)(trackConf, session);
|
|
50
51
|
const items = [
|
|
51
52
|
{
|
|
52
|
-
label:
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
label: 'Track order',
|
|
54
|
+
type: 'subMenu',
|
|
55
|
+
subMenu: [
|
|
56
|
+
{
|
|
57
|
+
label: minimized ? 'Restore track' : 'Minimize track',
|
|
58
|
+
icon: minimized ? Add_1.default : Minimize_1.default,
|
|
59
|
+
onClick: () => track.setMinimized(!minimized),
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: 'Move track to top',
|
|
63
|
+
icon: KeyboardDoubleArrowUp_1.default,
|
|
64
|
+
onClick: () => view.moveTrackToTop(track.id),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
label: 'Move track up',
|
|
68
|
+
icon: KeyboardArrowUp_1.default,
|
|
69
|
+
onClick: () => view.moveTrackUp(track.id),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
label: 'Move track down',
|
|
73
|
+
icon: KeyboardArrowDown_1.default,
|
|
74
|
+
onClick: () => view.moveTrackDown(track.id),
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
label: 'Move track to bottom',
|
|
78
|
+
icon: KeyboardDoubleArrowDown_1.default,
|
|
79
|
+
onClick: () => view.moveTrackToBottom(track.id),
|
|
80
|
+
},
|
|
81
|
+
],
|
|
55
82
|
},
|
|
56
83
|
...(((_a = session.getTrackActionMenuItems) === null || _a === void 0 ? void 0 : _a.call(session, trackConf)) || []),
|
|
57
84
|
...track.trackMenuItems(),
|
|
@@ -41,6 +41,7 @@ const Gridlines_1 = __importDefault(require("./Gridlines"));
|
|
|
41
41
|
const CenterLine_1 = __importDefault(require("./CenterLine"));
|
|
42
42
|
const VerticalGuide_1 = __importDefault(require("./VerticalGuide"));
|
|
43
43
|
const RubberbandSpan_1 = __importDefault(require("./RubberbandSpan"));
|
|
44
|
+
const Highlight_1 = __importDefault(require("./Highlight"));
|
|
44
45
|
const useStyles = (0, mui_1.makeStyles)()({
|
|
45
46
|
tracksContainer: {
|
|
46
47
|
position: 'relative',
|
|
@@ -67,6 +68,7 @@ const TracksContainer = (0, mobx_react_1.observer)(function TracksContainer({ ch
|
|
|
67
68
|
top: anchorPosition.clientY,
|
|
68
69
|
}, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null,
|
|
69
70
|
react_1.default.createElement(Rubberband_1.default, { model: model, ControlComponent: react_1.default.createElement(Scalebar_1.default, { model: model, style: { height: __1.SCALE_BAR_HEIGHT, boxSizing: 'border-box' } }) }),
|
|
71
|
+
react_1.default.createElement(Highlight_1.default, { model: model }),
|
|
70
72
|
additional,
|
|
71
73
|
children));
|
|
72
74
|
});
|
|
@@ -45,16 +45,16 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
45
45
|
}));
|
|
46
46
|
const ZoomControls = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
47
47
|
const { classes } = useStyles();
|
|
48
|
-
const { maxBpPerPx, minBpPerPx, bpPerPx
|
|
48
|
+
const { maxBpPerPx, minBpPerPx, bpPerPx } = model;
|
|
49
49
|
const [value, setValue] = (0, react_1.useState)(-Math.log2(bpPerPx) * 100);
|
|
50
50
|
(0, react_1.useEffect)(() => {
|
|
51
51
|
setValue(-Math.log2(bpPerPx) * 100);
|
|
52
52
|
}, [setValue, bpPerPx]);
|
|
53
53
|
return (react_1.default.createElement("div", { className: classes.container },
|
|
54
|
-
react_1.default.createElement(material_1.IconButton, { "data-testid": "zoom_out", onClick: () => model.zoom(bpPerPx * 2), disabled: bpPerPx >= maxBpPerPx - 0.0001
|
|
54
|
+
react_1.default.createElement(material_1.IconButton, { "data-testid": "zoom_out", onClick: () => model.zoom(bpPerPx * 2), disabled: bpPerPx >= maxBpPerPx - 0.0001, size: "large" },
|
|
55
55
|
react_1.default.createElement(ZoomOut_1.default, null)),
|
|
56
|
-
react_1.default.createElement(material_1.Slider, { size: "small", className: classes.slider, value: value, min: -Math.log2(maxBpPerPx) * 100, max: -Math.log2(minBpPerPx) * 100, onChange: (_, val) => setValue(val), onChangeCommitted: () => model.zoomTo(2 ** (-value / 100))
|
|
57
|
-
react_1.default.createElement(material_1.IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(model.bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001
|
|
56
|
+
react_1.default.createElement(material_1.Slider, { size: "small", className: classes.slider, value: value, min: -Math.log2(maxBpPerPx) * 100, max: -Math.log2(minBpPerPx) * 100, onChange: (_, val) => setValue(val), onChangeCommitted: () => model.zoomTo(2 ** (-value / 100)) }),
|
|
57
|
+
react_1.default.createElement(material_1.IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(model.bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001, size: "large" },
|
|
58
58
|
react_1.default.createElement(ZoomIn_1.default, null))));
|
|
59
59
|
});
|
|
60
60
|
exports.default = ZoomControls;
|