@jbrowse/plugin-linear-genome-view 2.10.2 → 2.10.3
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/LaunchLinearGenomeView/index.js +15 -7
- package/dist/LinearBareDisplay/model.d.ts +18 -4
- package/dist/LinearBasicDisplay/model.d.ts +22 -4
- package/dist/LinearGenomeView/components/Highlight.d.ts +7 -0
- package/dist/LinearGenomeView/components/Highlight.js +122 -0
- package/dist/LinearGenomeView/components/OverviewHighlight.d.ts +9 -0
- package/dist/LinearGenomeView/components/OverviewHighlight.js +53 -0
- package/dist/LinearGenomeView/components/OverviewScalebar.js +3 -1
- package/dist/LinearGenomeView/components/TracksContainer.js +2 -0
- package/dist/LinearGenomeView/model.d.ts +5 -0
- package/dist/LinearGenomeView/model.js +11 -0
- package/dist/LinearGenomeView/util.d.ts +1 -1
- package/dist/index.d.ts +66 -12
- 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/LaunchLinearGenomeView/index.js +16 -8
- package/esm/LinearBareDisplay/model.d.ts +18 -4
- package/esm/LinearBasicDisplay/model.d.ts +22 -4
- package/esm/LinearGenomeView/components/Highlight.d.ts +7 -0
- package/esm/LinearGenomeView/components/Highlight.js +94 -0
- package/esm/LinearGenomeView/components/OverviewHighlight.d.ts +9 -0
- package/esm/LinearGenomeView/components/OverviewHighlight.js +48 -0
- package/esm/LinearGenomeView/components/OverviewScalebar.js +3 -1
- package/esm/LinearGenomeView/components/TracksContainer.js +2 -0
- package/esm/LinearGenomeView/model.d.ts +5 -0
- package/esm/LinearGenomeView/model.js +11 -0
- package/esm/LinearGenomeView/util.d.ts +1 -1
- package/esm/index.d.ts +66 -12
- package/package.json +2 -2
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { AlertColor } from '@mui/material';
|
|
3
|
-
export default function BlockMsg({ message, severity,
|
|
3
|
+
export default function BlockMsg({ message, severity, action, }: {
|
|
4
4
|
message: string;
|
|
5
5
|
severity?: AlertColor;
|
|
6
|
-
|
|
7
|
-
icon?: React.ReactNode;
|
|
8
|
-
action?: () => void;
|
|
6
|
+
action?: React.ReactNode;
|
|
9
7
|
}): React.JSX.Element;
|
|
@@ -12,10 +12,9 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
12
12
|
overflow: 'hidden',
|
|
13
13
|
},
|
|
14
14
|
});
|
|
15
|
-
function BlockMsg({ message, severity,
|
|
15
|
+
function BlockMsg({ message, severity, action, }) {
|
|
16
16
|
const { classes } = useStyles();
|
|
17
|
-
|
|
18
|
-
return (react_1.default.createElement(material_1.Alert, { severity: severity, action: button, classes: { message: classes.ellipses } },
|
|
17
|
+
return (react_1.default.createElement(material_1.Alert, { severity: severity, action: action, classes: { message: classes.ellipses } },
|
|
19
18
|
react_1.default.createElement(material_1.Tooltip, { title: message },
|
|
20
19
|
react_1.default.createElement("div", null, message))));
|
|
21
20
|
}
|
|
@@ -38,8 +38,8 @@ const RenderedBlocks = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
|
38
38
|
if (block instanceof blockTypes_1.ContentBlock) {
|
|
39
39
|
const state = blockState.get(block.key);
|
|
40
40
|
return (react_1.default.createElement(Block_1.ContentBlock, { block: block, key: `${model.id}-${block.key}` },
|
|
41
|
-
state
|
|
42
|
-
state
|
|
41
|
+
(state === null || state === void 0 ? void 0 : state.ReactComponent) ? (react_1.default.createElement(state.ReactComponent, { model: state })) : null,
|
|
42
|
+
(state === null || state === void 0 ? void 0 : state.maxHeightReached) ? (react_1.default.createElement("div", { className: classes.heightOverflowed, style: {
|
|
43
43
|
top: state.layout.getTotalHeight() - 16,
|
|
44
44
|
pointerEvents: 'none',
|
|
45
45
|
height: 16,
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
declare const ServerSideRenderedBlockContent: ({ model, }: {
|
|
2
|
-
model:
|
|
3
|
-
|
|
3
|
+
model: {
|
|
4
|
+
error?: unknown;
|
|
5
|
+
reload: () => void;
|
|
6
|
+
message: React.ReactNode;
|
|
7
|
+
filled?: boolean;
|
|
8
|
+
status?: string;
|
|
9
|
+
reactElement?: React.ReactElement;
|
|
10
|
+
};
|
|
11
|
+
}) => React.JSX.Element | undefined;
|
|
4
12
|
export default ServerSideRenderedBlockContent;
|
|
@@ -1,17 +1,44 @@
|
|
|
1
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
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const react_1 =
|
|
29
|
+
const react_1 = __importStar(require("react"));
|
|
30
|
+
const material_1 = require("@mui/material");
|
|
7
31
|
const mui_1 = require("tss-react/mui");
|
|
8
32
|
const mobx_react_1 = require("mobx-react");
|
|
9
33
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
10
34
|
const ui_1 = require("@jbrowse/core/ui");
|
|
35
|
+
const util_1 = require("@jbrowse/core/util");
|
|
11
36
|
// icons
|
|
12
37
|
const Refresh_1 = __importDefault(require("@mui/icons-material/Refresh"));
|
|
38
|
+
const Report_1 = __importDefault(require("@mui/icons-material/Report"));
|
|
13
39
|
// locals
|
|
14
40
|
const BlockMsg_1 = __importDefault(require("./BlockMsg"));
|
|
41
|
+
const ErrorMessageStackTraceDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('@jbrowse/core/ui/ErrorMessageStackTraceDialog'))));
|
|
15
42
|
const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
16
43
|
const bg = theme.palette.action.disabledBackground;
|
|
17
44
|
return {
|
|
@@ -23,11 +50,9 @@ const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
|
23
50
|
},
|
|
24
51
|
};
|
|
25
52
|
});
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
53
|
const LoadingMessage = (0, mobx_react_1.observer)(({ model }) => {
|
|
28
54
|
const { classes } = useStyles();
|
|
29
55
|
const { status: blockStatus } = model;
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
56
|
const { message: displayStatus } = (0, mobx_state_tree_1.getParent)(model, 2);
|
|
32
57
|
const status = displayStatus || blockStatus;
|
|
33
58
|
return (react_1.default.createElement("div", { className: classes.loading },
|
|
@@ -35,7 +60,18 @@ const LoadingMessage = (0, mobx_react_1.observer)(({ model }) => {
|
|
|
35
60
|
});
|
|
36
61
|
const ServerSideRenderedBlockContent = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
37
62
|
if (model.error) {
|
|
38
|
-
return (react_1.default.createElement(BlockMsg_1.default, { message: `${model.error}`, severity: "error",
|
|
63
|
+
return (react_1.default.createElement(BlockMsg_1.default, { message: `${model.error}`, severity: "error", action: react_1.default.createElement(react_1.default.Fragment, null,
|
|
64
|
+
react_1.default.createElement(material_1.Tooltip, { title: "Reload track" },
|
|
65
|
+
react_1.default.createElement(material_1.IconButton, { "data-testid": "reload_button", onClick: () => model.reload() },
|
|
66
|
+
react_1.default.createElement(Refresh_1.default, null))),
|
|
67
|
+
react_1.default.createElement(material_1.Tooltip, { title: "Show stack trace" },
|
|
68
|
+
react_1.default.createElement(material_1.IconButton, { onClick: () => {
|
|
69
|
+
(0, util_1.getSession)(model).queueDialog(onClose => [
|
|
70
|
+
ErrorMessageStackTraceDialog,
|
|
71
|
+
{ onClose, error: model.error },
|
|
72
|
+
]);
|
|
73
|
+
} },
|
|
74
|
+
react_1.default.createElement(Report_1.default, null)))) }));
|
|
39
75
|
}
|
|
40
76
|
else if (model.message) {
|
|
41
77
|
// the message can be a fully rendered react component, e.g. the region too large message
|
|
@@ -6,12 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
// locals
|
|
8
8
|
const BlockMsg_1 = __importDefault(require("../components/BlockMsg"));
|
|
9
|
+
const material_1 = require("@mui/material");
|
|
9
10
|
function TooLargeMessage({ model, }) {
|
|
10
11
|
const { regionTooLargeReason } = model;
|
|
11
|
-
return (react_1.default.createElement(BlockMsg_1.default, { severity: "warning", action: () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
return (react_1.default.createElement(BlockMsg_1.default, { severity: "warning", action: react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
13
|
+
model.setFeatureDensityStatsLimit(model.featureDensityStats);
|
|
14
|
+
model.reload();
|
|
15
|
+
} }, "Force load"), message: [
|
|
15
16
|
regionTooLargeReason,
|
|
16
17
|
'Zoom in to see features or force load (may be slow)',
|
|
17
18
|
]
|
|
@@ -58,8 +58,15 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
58
58
|
message: string | undefined;
|
|
59
59
|
maxHeightReached: boolean;
|
|
60
60
|
ReactComponent: ({ model, }: {
|
|
61
|
-
model:
|
|
62
|
-
|
|
61
|
+
model: {
|
|
62
|
+
error?: unknown;
|
|
63
|
+
reload: () => void;
|
|
64
|
+
message: React.ReactNode;
|
|
65
|
+
filled?: boolean | undefined;
|
|
66
|
+
status?: string | undefined;
|
|
67
|
+
reactElement?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
|
|
68
|
+
};
|
|
69
|
+
}) => React.JSX.Element | undefined;
|
|
63
70
|
renderProps: any;
|
|
64
71
|
} & {
|
|
65
72
|
doReload(): void;
|
|
@@ -342,8 +349,15 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
342
349
|
message: string | undefined;
|
|
343
350
|
maxHeightReached: boolean;
|
|
344
351
|
ReactComponent: ({ model, }: {
|
|
345
|
-
model:
|
|
346
|
-
|
|
352
|
+
model: {
|
|
353
|
+
error?: unknown;
|
|
354
|
+
reload: () => void;
|
|
355
|
+
message: React.ReactNode;
|
|
356
|
+
filled?: boolean | undefined;
|
|
357
|
+
status?: string | undefined;
|
|
358
|
+
reactElement?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
|
|
359
|
+
};
|
|
360
|
+
}) => React.JSX.Element | undefined;
|
|
347
361
|
renderProps: any;
|
|
348
362
|
} & {
|
|
349
363
|
doReload(): void;
|
|
@@ -28,8 +28,15 @@ declare const blockState: import("mobx-state-tree").IModelType<{
|
|
|
28
28
|
message: string | undefined;
|
|
29
29
|
maxHeightReached: boolean;
|
|
30
30
|
ReactComponent: ({ model, }: {
|
|
31
|
-
model:
|
|
32
|
-
|
|
31
|
+
model: {
|
|
32
|
+
error?: unknown;
|
|
33
|
+
reload: () => void;
|
|
34
|
+
message: React.ReactNode;
|
|
35
|
+
filled?: boolean | undefined;
|
|
36
|
+
status?: string | undefined;
|
|
37
|
+
reactElement?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
|
|
38
|
+
};
|
|
39
|
+
}) => React.JSX.Element | undefined;
|
|
33
40
|
renderProps: any;
|
|
34
41
|
} & {
|
|
35
42
|
doReload(): void;
|
|
@@ -5,9 +5,10 @@ const searchUtils_1 = require("../searchUtils");
|
|
|
5
5
|
exports.default = (pluginManager) => {
|
|
6
6
|
pluginManager.addToExtensionPoint('LaunchView-LinearGenomeView',
|
|
7
7
|
// @ts-expect-error
|
|
8
|
-
async ({ session, assembly, loc, tracks = [], tracklist, nav, }) => {
|
|
8
|
+
async ({ session, assembly, loc, tracks = [], tracklist, nav, highlight, }) => {
|
|
9
9
|
try {
|
|
10
10
|
const { assemblyManager } = session;
|
|
11
|
+
const { isValidRefName } = assemblyManager;
|
|
11
12
|
const view = session.addView('LinearGenomeView', {});
|
|
12
13
|
await (0, util_1.when)(() => !!view.volatileWidth);
|
|
13
14
|
if (!assembly) {
|
|
@@ -17,18 +18,25 @@ exports.default = (pluginManager) => {
|
|
|
17
18
|
if (!asm) {
|
|
18
19
|
throw new Error(`Assembly "${assembly}" not found when launching linear genome view`);
|
|
19
20
|
}
|
|
20
|
-
await (0, searchUtils_1.handleSelectedRegion)({ input: loc, model: view, assembly: asm });
|
|
21
|
-
const idsNotFound = [];
|
|
22
|
-
tracks.forEach(track => tryTrack(view, track, idsNotFound));
|
|
23
|
-
if (idsNotFound.length) {
|
|
24
|
-
throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
|
|
25
|
-
}
|
|
26
21
|
if (tracklist) {
|
|
27
22
|
view.activateTrackSelector();
|
|
28
23
|
}
|
|
29
24
|
if (nav !== undefined) {
|
|
30
25
|
view.setHideHeader(!nav);
|
|
31
26
|
}
|
|
27
|
+
if (highlight !== undefined) {
|
|
28
|
+
const location = (0, util_1.parseLocString)(highlight, refName => isValidRefName(refName, assembly));
|
|
29
|
+
if ((location === null || location === void 0 ? void 0 : location.start) !== undefined && (location === null || location === void 0 ? void 0 : location.end) !== undefined) {
|
|
30
|
+
location.assemblyName = assembly;
|
|
31
|
+
view.setHighlight(location);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
await (0, searchUtils_1.handleSelectedRegion)({ input: loc, model: view, assembly: asm });
|
|
35
|
+
const idsNotFound = [];
|
|
36
|
+
tracks.forEach(track => tryTrack(view, track, idsNotFound));
|
|
37
|
+
if (idsNotFound.length) {
|
|
38
|
+
throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
|
|
39
|
+
}
|
|
32
40
|
}
|
|
33
41
|
catch (e) {
|
|
34
42
|
session.notify(`${e}`, 'error');
|
|
@@ -42,8 +42,15 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
42
42
|
message: string | undefined;
|
|
43
43
|
maxHeightReached: boolean;
|
|
44
44
|
ReactComponent: ({ model, }: {
|
|
45
|
-
model:
|
|
46
|
-
|
|
45
|
+
model: {
|
|
46
|
+
error?: unknown;
|
|
47
|
+
reload: () => void;
|
|
48
|
+
message: import("react").ReactNode;
|
|
49
|
+
filled?: boolean | undefined;
|
|
50
|
+
status?: string | undefined;
|
|
51
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
52
|
+
};
|
|
53
|
+
}) => import("react").JSX.Element | undefined;
|
|
47
54
|
renderProps: any;
|
|
48
55
|
} & {
|
|
49
56
|
doReload(): void;
|
|
@@ -267,8 +274,15 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
267
274
|
message: string | undefined;
|
|
268
275
|
maxHeightReached: boolean;
|
|
269
276
|
ReactComponent: ({ model, }: {
|
|
270
|
-
model:
|
|
271
|
-
|
|
277
|
+
model: {
|
|
278
|
+
error?: unknown;
|
|
279
|
+
reload: () => void;
|
|
280
|
+
message: import("react").ReactNode;
|
|
281
|
+
filled?: boolean | undefined;
|
|
282
|
+
status?: string | undefined;
|
|
283
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
284
|
+
};
|
|
285
|
+
}) => import("react").JSX.Element | undefined;
|
|
272
286
|
renderProps: any;
|
|
273
287
|
} & {
|
|
274
288
|
doReload(): void;
|
|
@@ -47,8 +47,17 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
47
47
|
message: string | undefined;
|
|
48
48
|
maxHeightReached: boolean;
|
|
49
49
|
ReactComponent: ({ model, }: {
|
|
50
|
-
model:
|
|
51
|
-
|
|
50
|
+
model: {
|
|
51
|
+
error?: unknown;
|
|
52
|
+
reload: () => void;
|
|
53
|
+
message: import("react").ReactNode;
|
|
54
|
+
filled?: boolean | undefined;
|
|
55
|
+
status?: string | undefined; /**
|
|
56
|
+
* #getter
|
|
57
|
+
*/
|
|
58
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
59
|
+
};
|
|
60
|
+
}) => import("react").JSX.Element | undefined;
|
|
52
61
|
renderProps: any;
|
|
53
62
|
} & {
|
|
54
63
|
doReload(): void;
|
|
@@ -343,8 +352,17 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
343
352
|
message: string | undefined;
|
|
344
353
|
maxHeightReached: boolean;
|
|
345
354
|
ReactComponent: ({ model, }: {
|
|
346
|
-
model:
|
|
347
|
-
|
|
355
|
+
model: {
|
|
356
|
+
error?: unknown;
|
|
357
|
+
reload: () => void;
|
|
358
|
+
message: import("react").ReactNode;
|
|
359
|
+
filled?: boolean | undefined;
|
|
360
|
+
status?: string | undefined; /**
|
|
361
|
+
* #getter
|
|
362
|
+
*/
|
|
363
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
364
|
+
};
|
|
365
|
+
}) => import("react").JSX.Element | undefined;
|
|
348
366
|
renderProps: any;
|
|
349
367
|
} & {
|
|
350
368
|
doReload(): void;
|
|
@@ -0,0 +1,122 @@
|
|
|
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, _c, _d, _e, _f;
|
|
42
|
+
return ({
|
|
43
|
+
highlight: {
|
|
44
|
+
height: '100%',
|
|
45
|
+
position: 'absolute',
|
|
46
|
+
background: `${(0, colord_1.colord)((_b = (_a = theme.palette.quaternary) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
|
|
47
|
+
.alpha(0.35)
|
|
48
|
+
.toRgbString()}`,
|
|
49
|
+
borderLeft: `1px solid ${(_d = (_c = theme.palette.quaternary) === null || _c === void 0 ? void 0 : _c.main) !== null && _d !== void 0 ? _d : 'goldenrod'}`,
|
|
50
|
+
borderRight: `1px solid ${(_f = (_e = theme.palette.quaternary) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : 'goldenrod'}`,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
const Highlight = (0, mobx_react_1.observer)(function Highlight({ model }) {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
const { classes } = useStyles();
|
|
57
|
+
const [open, setOpen] = (0, react_1.useState)(false);
|
|
58
|
+
const anchorEl = (0, react_1.useRef)(null);
|
|
59
|
+
const color = (_b = (_a = (0, material_1.useTheme)().palette.quaternary) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod';
|
|
60
|
+
const session = (0, util_1.getSession)(model);
|
|
61
|
+
const dismissHighlight = () => {
|
|
62
|
+
model.setHighlight(undefined);
|
|
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(model.highlight);
|
|
80
|
+
dismissHighlight();
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
function handleClose() {
|
|
85
|
+
setOpen(false);
|
|
86
|
+
}
|
|
87
|
+
if (!model.highlight) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
// coords
|
|
91
|
+
const mapCoords = (r) => {
|
|
92
|
+
const s = model.bpToPx({
|
|
93
|
+
refName: r.refName,
|
|
94
|
+
coord: r.start,
|
|
95
|
+
});
|
|
96
|
+
const e = model.bpToPx({
|
|
97
|
+
refName: r.refName,
|
|
98
|
+
coord: r.end,
|
|
99
|
+
});
|
|
100
|
+
return s && e
|
|
101
|
+
? {
|
|
102
|
+
width: Math.max(Math.abs(e.offsetPx - s.offsetPx), 3),
|
|
103
|
+
left: Math.min(s.offsetPx, e.offsetPx) - model.offsetPx,
|
|
104
|
+
}
|
|
105
|
+
: undefined;
|
|
106
|
+
};
|
|
107
|
+
const h = mapCoords(model.highlight);
|
|
108
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, h ? (react_1.default.createElement("div", { className: classes.highlight, style: {
|
|
109
|
+
left: h.left,
|
|
110
|
+
width: h.width,
|
|
111
|
+
} },
|
|
112
|
+
react_1.default.createElement(material_1.Tooltip, { title: 'Highlighted from URL parameter', arrow: true },
|
|
113
|
+
react_1.default.createElement(material_1.IconButton, { ref: anchorEl, onClick: () => setOpen(true) },
|
|
114
|
+
react_1.default.createElement(Link_1.default, { fontSize: "small", sx: {
|
|
115
|
+
color: `${(0, colord_1.colord)(color).darken(0.2).toRgbString()}`,
|
|
116
|
+
} }))),
|
|
117
|
+
react_1.default.createElement(ui_1.Menu, { anchorEl: anchorEl.current, onMenuItemClick: (_event, callback) => {
|
|
118
|
+
callback(session);
|
|
119
|
+
handleClose();
|
|
120
|
+
}, open: open, onClose: handleClose, menuItems: menuItems }))) : null));
|
|
121
|
+
});
|
|
122
|
+
exports.default = Highlight;
|
|
@@ -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 | null;
|
|
9
|
+
export default OverviewHighlight;
|
|
@@ -0,0 +1,53 @@
|
|
|
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 useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
11
|
+
var _a, _b, _c, _d, _e, _f;
|
|
12
|
+
return ({
|
|
13
|
+
highlight: {
|
|
14
|
+
height: '100%',
|
|
15
|
+
position: 'absolute',
|
|
16
|
+
background: `${(0, colord_1.colord)((_b = (_a = theme.palette.quaternary) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
|
|
17
|
+
.alpha(0.35)
|
|
18
|
+
.toRgbString()}`,
|
|
19
|
+
borderLeft: `1px solid ${(_d = (_c = theme.palette.quaternary) === null || _c === void 0 ? void 0 : _c.main) !== null && _d !== void 0 ? _d : 'goldenrod'}`,
|
|
20
|
+
borderRight: `1px solid ${(_f = (_e = theme.palette.quaternary) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : 'goldenrod'}`,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
const OverviewHighlight = (0, mobx_react_1.observer)(function OverviewHighlight({ model, overview, }) {
|
|
25
|
+
const { classes } = useStyles();
|
|
26
|
+
const { cytobandOffset } = model;
|
|
27
|
+
// coords
|
|
28
|
+
const mapCoords = (r) => {
|
|
29
|
+
const s = overview.bpToPx({
|
|
30
|
+
...r,
|
|
31
|
+
coord: r.reversed ? r.end : r.start,
|
|
32
|
+
});
|
|
33
|
+
const e = overview.bpToPx({
|
|
34
|
+
...r,
|
|
35
|
+
coord: r.reversed ? r.start : r.end,
|
|
36
|
+
});
|
|
37
|
+
return s !== undefined && e != undefined
|
|
38
|
+
? {
|
|
39
|
+
width: Math.abs(e - s),
|
|
40
|
+
left: s + cytobandOffset,
|
|
41
|
+
}
|
|
42
|
+
: undefined;
|
|
43
|
+
};
|
|
44
|
+
if (!model.highlight) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const h = mapCoords(model.highlight);
|
|
48
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, h ? (react_1.default.createElement("div", { className: classes.highlight, style: {
|
|
49
|
+
width: h.width,
|
|
50
|
+
left: h.left,
|
|
51
|
+
} })) : null));
|
|
52
|
+
});
|
|
53
|
+
exports.default = OverviewHighlight;
|
|
@@ -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: {
|
|
@@ -179,7 +180,8 @@ const Scalebar = (0, mobx_react_1.observer)(function ({ model, scale, overview,
|
|
|
179
180
|
backgroundColor: '#999',
|
|
180
181
|
backgroundImage: 'repeating-linear-gradient(90deg, transparent, transparent 1px, rgba(255,255,255,.5) 1px, rgba(255,255,255,.5) 3px)',
|
|
181
182
|
} })) : (react_1.default.createElement(OverviewBox, { scale: scale, block: block, model: model, overview: overview, key: `${JSON.stringify(block)}-${idx}` }));
|
|
182
|
-
})
|
|
183
|
+
}),
|
|
184
|
+
react_1.default.createElement(OverviewHighlight_1.default, { model: model, overview: overview })));
|
|
183
185
|
});
|
|
184
186
|
const OverviewScalebar = (0, mobx_react_1.observer)(function ({ model, children, }) {
|
|
185
187
|
const { classes } = useStyles();
|
|
@@ -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
|
});
|
|
@@ -81,6 +81,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
81
81
|
showCytobandsSetting: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
82
82
|
trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
83
83
|
showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
84
|
+
highlight: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IType<Required<ParsedLocString>, Required<ParsedLocString>, Required<ParsedLocString>>>;
|
|
84
85
|
}, {
|
|
85
86
|
width: number;
|
|
86
87
|
} & {
|
|
@@ -251,6 +252,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
251
252
|
* #action
|
|
252
253
|
*/
|
|
253
254
|
setShowGridlines(b: boolean): void;
|
|
255
|
+
/**
|
|
256
|
+
* #action
|
|
257
|
+
*/
|
|
258
|
+
setHighlight(highlight: Required<ParsedLocString> | undefined): void;
|
|
254
259
|
/**
|
|
255
260
|
* #action
|
|
256
261
|
*/
|
|
@@ -165,6 +165,11 @@ function stateModelFactory(pluginManager) {
|
|
|
165
165
|
* show the "gridlines" in the track area
|
|
166
166
|
*/
|
|
167
167
|
showGridlines: true,
|
|
168
|
+
/**
|
|
169
|
+
* #property
|
|
170
|
+
* highlights on the LGV from the URL parameters
|
|
171
|
+
*/
|
|
172
|
+
highlight: mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.frozen()),
|
|
168
173
|
}))
|
|
169
174
|
.volatile(() => ({
|
|
170
175
|
volatileWidth: undefined,
|
|
@@ -468,6 +473,12 @@ function stateModelFactory(pluginManager) {
|
|
|
468
473
|
setShowGridlines(b) {
|
|
469
474
|
self.showGridlines = b;
|
|
470
475
|
},
|
|
476
|
+
/**
|
|
477
|
+
* #action
|
|
478
|
+
*/
|
|
479
|
+
setHighlight(highlight) {
|
|
480
|
+
self.highlight = highlight;
|
|
481
|
+
},
|
|
471
482
|
/**
|
|
472
483
|
* #action
|
|
473
484
|
*/
|
|
@@ -24,8 +24,8 @@ export declare function generateLocations(regions: ParsedLocString[] | undefined
|
|
|
24
24
|
assemblyName: string;
|
|
25
25
|
parentRegion: import("@jbrowse/core/assemblyManager/assembly").BasicRegion;
|
|
26
26
|
end?: number | undefined;
|
|
27
|
-
reversed?: boolean | undefined;
|
|
28
27
|
start?: number | undefined;
|
|
28
|
+
reversed?: boolean | undefined;
|
|
29
29
|
refName: string;
|
|
30
30
|
}[]>;
|
|
31
31
|
/**
|