@jbrowse/plugin-linear-genome-view 3.6.4 → 3.7.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/BaseLinearDisplay.d.ts +1 -1
- package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +3 -18
- package/dist/BaseLinearDisplay/components/BlockMsg.js +2 -0
- package/dist/BaseLinearDisplay/components/LinearBlocks.d.ts +1 -5
- package/dist/BaseLinearDisplay/components/LinearBlocks.js +5 -38
- package/dist/BaseLinearDisplay/components/MaxHeightReachedIndicator.d.ts +3 -0
- package/dist/BaseLinearDisplay/components/MaxHeightReachedIndicator.js +27 -0
- package/dist/BaseLinearDisplay/components/MenuPage.d.ts +8 -0
- package/dist/BaseLinearDisplay/components/MenuPage.js +26 -0
- package/dist/BaseLinearDisplay/components/RenderedBlocks.d.ts +9 -0
- package/dist/BaseLinearDisplay/components/RenderedBlocks.js +27 -0
- package/dist/BaseLinearDisplay/components/Tooltip.d.ts +1 -0
- package/dist/BaseLinearDisplay/components/Tooltip.js +5 -2
- package/dist/BaseLinearDisplay/components/types.d.ts +1 -0
- package/dist/BaseLinearDisplay/components/types.js +2 -0
- package/dist/BaseLinearDisplay/index.d.ts +2 -2
- package/dist/BaseLinearDisplay/index.js +2 -2
- package/dist/BaseLinearDisplay/{models/BaseLinearDisplayModel.d.ts → model.d.ts} +17 -4
- package/dist/BaseLinearDisplay/{models/BaseLinearDisplayModel.js → model.js} +22 -7
- package/dist/BaseLinearDisplay/models/autorunFeatureDensityStats.d.ts +1 -1
- package/dist/BaseLinearDisplay/models/configSchema.js +2 -2
- package/dist/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
- package/dist/LinearBareDisplay/model.d.ts +17 -2
- package/dist/LinearBasicDisplay/model.d.ts +17 -2
- package/dist/LinearGenomeView/components/Cytobands.js +2 -0
- package/dist/LinearGenomeView/components/RegionWidthEditorDialog.js +1 -1
- package/dist/LinearGenomeView/components/SequenceSearchDialog.js +1 -1
- package/dist/LinearGenomeView/components/TrackContainer.js +7 -3
- package/dist/LinearGenomeView/components/TrackLabelMenu.js +1 -1
- package/dist/LinearGenomeView/components/useRangeSelect.js +10 -14
- package/dist/LinearGenomeView/model.d.ts +2 -2
- package/dist/LinearGenomeView/model.js +2 -2
- package/dist/LinearGenomeView/util.js +1 -1
- package/dist/index.d.ts +17 -2
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +1 -1
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +3 -18
- package/esm/BaseLinearDisplay/components/BlockMsg.js +2 -0
- package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +1 -5
- package/esm/BaseLinearDisplay/components/LinearBlocks.js +2 -37
- package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.d.ts +3 -0
- package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.js +24 -0
- package/esm/BaseLinearDisplay/components/MenuPage.d.ts +8 -0
- package/esm/BaseLinearDisplay/components/MenuPage.js +24 -0
- package/esm/BaseLinearDisplay/components/RenderedBlocks.d.ts +9 -0
- package/esm/BaseLinearDisplay/components/RenderedBlocks.js +22 -0
- package/esm/BaseLinearDisplay/components/Tooltip.d.ts +1 -0
- package/esm/BaseLinearDisplay/components/Tooltip.js +5 -2
- package/esm/BaseLinearDisplay/components/types.d.ts +1 -0
- package/esm/BaseLinearDisplay/components/types.js +1 -0
- package/esm/BaseLinearDisplay/index.d.ts +2 -2
- package/esm/BaseLinearDisplay/index.js +1 -1
- package/esm/BaseLinearDisplay/{models/BaseLinearDisplayModel.d.ts → model.d.ts} +17 -4
- package/esm/BaseLinearDisplay/{models/BaseLinearDisplayModel.js → model.js} +22 -7
- package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.d.ts +1 -1
- package/esm/BaseLinearDisplay/models/configSchema.js +2 -2
- package/esm/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
- package/esm/LinearBareDisplay/model.d.ts +17 -2
- package/esm/LinearBasicDisplay/model.d.ts +17 -2
- package/esm/LinearGenomeView/components/Cytobands.js +2 -0
- package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +1 -1
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js +1 -1
- package/esm/LinearGenomeView/components/TrackContainer.js +7 -3
- package/esm/LinearGenomeView/components/TrackLabelMenu.js +1 -1
- package/esm/LinearGenomeView/components/useRangeSelect.js +11 -15
- package/esm/LinearGenomeView/model.d.ts +2 -2
- package/esm/LinearGenomeView/model.js +2 -2
- package/esm/LinearGenomeView/util.js +1 -1
- package/esm/index.d.ts +17 -2
- package/package.json +3 -3
|
@@ -9,6 +9,11 @@ function useRangeSelect(ref, model, shiftOnly) {
|
|
|
9
9
|
const [anchorPosition, setAnchorPosition] = (0, react_1.useState)();
|
|
10
10
|
const [guideX, setGuideX] = (0, react_1.useState)();
|
|
11
11
|
const mouseDragging = startX !== undefined && anchorPosition === undefined;
|
|
12
|
+
const handleClose = (0, react_1.useCallback)(() => {
|
|
13
|
+
setAnchorPosition(undefined);
|
|
14
|
+
setStartX(undefined);
|
|
15
|
+
setCurrentX(undefined);
|
|
16
|
+
}, []);
|
|
12
17
|
(0, react_1.useEffect)(() => {
|
|
13
18
|
function computeOffsets(offsetX) {
|
|
14
19
|
if (startX === undefined) {
|
|
@@ -31,6 +36,10 @@ function useRangeSelect(ref, model, shiftOnly) {
|
|
|
31
36
|
if (startX !== undefined && ref.current) {
|
|
32
37
|
const { clientX, clientY } = event;
|
|
33
38
|
const offsetX = (0, util_1.getRelativeX)(event, ref.current);
|
|
39
|
+
if (Math.abs(offsetX - startX) <= 3) {
|
|
40
|
+
handleClose();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
34
43
|
setAnchorPosition({
|
|
35
44
|
offsetX,
|
|
36
45
|
clientX,
|
|
@@ -52,15 +61,7 @@ function useRangeSelect(ref, model, shiftOnly) {
|
|
|
52
61
|
};
|
|
53
62
|
}
|
|
54
63
|
return () => { };
|
|
55
|
-
}, [startX, mouseDragging, model, ref]);
|
|
56
|
-
(0, react_1.useEffect)(() => {
|
|
57
|
-
if (!mouseDragging &&
|
|
58
|
-
currentX !== undefined &&
|
|
59
|
-
startX !== undefined &&
|
|
60
|
-
Math.abs(currentX - startX) <= 3) {
|
|
61
|
-
handleClose();
|
|
62
|
-
}
|
|
63
|
-
}, [mouseDragging, currentX, startX]);
|
|
64
|
+
}, [startX, mouseDragging, model, ref, handleClose]);
|
|
64
65
|
function mouseDown(event) {
|
|
65
66
|
if (shiftOnly && !event.shiftKey) {
|
|
66
67
|
return;
|
|
@@ -87,11 +88,6 @@ function useRangeSelect(ref, model, shiftOnly) {
|
|
|
87
88
|
function mouseOut() {
|
|
88
89
|
setGuideX(undefined);
|
|
89
90
|
}
|
|
90
|
-
function handleClose() {
|
|
91
|
-
setAnchorPosition(undefined);
|
|
92
|
-
setStartX(undefined);
|
|
93
|
-
setCurrentX(undefined);
|
|
94
|
-
}
|
|
95
91
|
function handleMenuItemClick(_, callback) {
|
|
96
92
|
callback();
|
|
97
93
|
handleClose();
|
|
@@ -59,8 +59,8 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
59
59
|
readonly interRegionPaddingWidth: number;
|
|
60
60
|
readonly assemblyNames: string[];
|
|
61
61
|
readonly assemblyDisplayNames: string[];
|
|
62
|
-
readonly isTopLevelView:
|
|
63
|
-
readonly stickyViewHeaders: boolean
|
|
62
|
+
readonly isTopLevelView: boolean;
|
|
63
|
+
readonly stickyViewHeaders: boolean;
|
|
64
64
|
readonly rubberbandTop: number;
|
|
65
65
|
readonly pinnedTracksTop: number;
|
|
66
66
|
} & {
|
|
@@ -146,7 +146,7 @@ function stateModelFactory(pluginManager) {
|
|
|
146
146
|
},
|
|
147
147
|
get isTopLevelView() {
|
|
148
148
|
const session = (0, util_1.getSession)(self);
|
|
149
|
-
return session.views.
|
|
149
|
+
return session.views.some(r => r.id === self.id);
|
|
150
150
|
},
|
|
151
151
|
get stickyViewHeaders() {
|
|
152
152
|
const session = (0, util_1.getSession)(self);
|
|
@@ -687,7 +687,7 @@ function stateModelFactory(pluginManager) {
|
|
|
687
687
|
onClick: self.horizontallyFlip,
|
|
688
688
|
},
|
|
689
689
|
{
|
|
690
|
-
label: 'Color by CDS',
|
|
690
|
+
label: 'Color by CDS and draw amino acids',
|
|
691
691
|
type: 'checkbox',
|
|
692
692
|
checked: self.colorByCDS,
|
|
693
693
|
icon: Palette_1.default,
|
|
@@ -9,7 +9,7 @@ const util_1 = require("@jbrowse/core/util");
|
|
|
9
9
|
function chooseGridPitch(scale, minMajorPitchPx, minMinorPitchPx) {
|
|
10
10
|
scale = Math.abs(scale);
|
|
11
11
|
const minMajorPitchBp = minMajorPitchPx * scale;
|
|
12
|
-
const majorMagnitude =
|
|
12
|
+
const majorMagnitude = +minMajorPitchBp.toExponential().split(/e/i)[1];
|
|
13
13
|
let majorPitch = 10 ** majorMagnitude;
|
|
14
14
|
while (majorPitch < minMajorPitchBp) {
|
|
15
15
|
majorPitch *= 2;
|
package/dist/index.d.ts
CHANGED
|
@@ -176,6 +176,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
176
176
|
regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
|
|
177
177
|
regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): import("react/jsx-runtime").JSX.Element | null;
|
|
178
178
|
} & {
|
|
179
|
+
mouseoverExtraInformation: string | undefined;
|
|
179
180
|
featureIdUnderMouse: undefined | string;
|
|
180
181
|
contextMenuFeature: undefined | import("@jbrowse/core/util").Feature;
|
|
181
182
|
} & {
|
|
@@ -190,9 +191,22 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
190
191
|
} & {
|
|
191
192
|
readonly features: import("@jbrowse/core/util/compositeMap").default<string, import("@jbrowse/core/util").Feature>;
|
|
192
193
|
readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
|
|
194
|
+
readonly layoutFeatures: import("@jbrowse/core/util/compositeMap").default<string, [number, number, number, number] | [number, number, number, number, {
|
|
195
|
+
label?: string;
|
|
196
|
+
description?: string;
|
|
197
|
+
refName: string;
|
|
198
|
+
}]>;
|
|
193
199
|
getFeatureOverlapping(blockKey: string, x: number, y: number): string | undefined;
|
|
194
|
-
getFeatureByID(blockKey: string, id: string): [number, number, number, number] |
|
|
195
|
-
|
|
200
|
+
getFeatureByID(blockKey: string, id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
201
|
+
label?: string;
|
|
202
|
+
description?: string;
|
|
203
|
+
refName: string;
|
|
204
|
+
}]) | undefined;
|
|
205
|
+
searchFeatureByID(id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
206
|
+
label?: string;
|
|
207
|
+
description?: string;
|
|
208
|
+
refName: string;
|
|
209
|
+
}]) | undefined;
|
|
196
210
|
} & {
|
|
197
211
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
198
212
|
deleteBlock(key: string): void;
|
|
@@ -201,6 +215,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
201
215
|
clearFeatureSelection(): void;
|
|
202
216
|
setFeatureIdUnderMouse(feature?: string): void;
|
|
203
217
|
setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature): void;
|
|
218
|
+
setMouseoverExtraInformation(extra?: string): void;
|
|
204
219
|
} & {
|
|
205
220
|
reload(): Promise<void>;
|
|
206
221
|
} & {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense, useRef, useState } from 'react';
|
|
3
3
|
import { getConf } from '@jbrowse/core/configuration';
|
|
4
|
-
import { Menu } from '@jbrowse/core/ui';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
6
5
|
import { makeStyles } from 'tss-react/mui';
|
|
7
6
|
import LinearBlocks from './LinearBlocks';
|
|
7
|
+
import MenuPage from './MenuPage';
|
|
8
8
|
const useStyles = makeStyles()({
|
|
9
9
|
display: {
|
|
10
10
|
position: 'relative',
|
|
@@ -23,8 +23,6 @@ const BaseLinearDisplay = observer(function (props) {
|
|
|
23
23
|
const [contextCoord, setContextCoord] = useState();
|
|
24
24
|
const { model, children } = props;
|
|
25
25
|
const { TooltipComponent, DisplayMessageComponent, height } = model;
|
|
26
|
-
const items = model.contextMenuItems();
|
|
27
|
-
const open = Boolean(contextCoord) && items.length > 0;
|
|
28
26
|
return (_jsxs("div", { ref: ref, "data-testid": `display-${getConf(model, 'displayId')}`, className: classes.display, onContextMenu: event => {
|
|
29
27
|
event.preventDefault();
|
|
30
28
|
if (contextCoord) {
|
|
@@ -42,22 +40,9 @@ const BaseLinearDisplay = observer(function (props) {
|
|
|
42
40
|
setOffsetMouseCoord([event.clientX - left, event.clientY - top]);
|
|
43
41
|
setClientMouseCoord([event.clientX, event.clientY]);
|
|
44
42
|
setClientRect(rect);
|
|
45
|
-
}, children: [DisplayMessageComponent ? (_jsx(DisplayMessageComponent, { model: model })) : (_jsx(LinearBlocks, { ...props })), children, _jsx(Suspense, { fallback: null, children: _jsx(TooltipComponent, { model: model, height: height, offsetMouseCoord: offsetMouseCoord, clientMouseCoord: clientMouseCoord, clientRect: clientRect, mouseCoord: offsetMouseCoord }) }),
|
|
46
|
-
callback();
|
|
43
|
+
}, children: [DisplayMessageComponent ? (_jsx(DisplayMessageComponent, { model: model })) : (_jsx(LinearBlocks, { ...props })), children, _jsx(Suspense, { fallback: null, children: _jsx(TooltipComponent, { model: model, height: height, offsetMouseCoord: offsetMouseCoord, clientMouseCoord: clientMouseCoord, clientRect: clientRect, mouseCoord: offsetMouseCoord }) }), contextCoord ? (_jsx(MenuPage, { contextCoord: contextCoord, model: model, onClose: () => {
|
|
47
44
|
setContextCoord(undefined);
|
|
48
|
-
}
|
|
49
|
-
setContextCoord(undefined);
|
|
50
|
-
model.setContextMenuFeature(undefined);
|
|
51
|
-
}, slotProps: {
|
|
52
|
-
transition: {
|
|
53
|
-
onExit: () => {
|
|
54
|
-
setContextCoord(undefined);
|
|
55
|
-
model.setContextMenuFeature(undefined);
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
}, anchorReference: "anchorPosition", anchorPosition: contextCoord
|
|
59
|
-
? { top: contextCoord[1], left: contextCoord[0] }
|
|
60
|
-
: undefined, menuItems: items })) : null] }));
|
|
45
|
+
} })) : null] }));
|
|
61
46
|
});
|
|
62
47
|
export default BaseLinearDisplay;
|
|
63
48
|
export { default as Tooltip } from './Tooltip';
|
|
@@ -13,5 +13,7 @@ export default function BlockMsg({ message, severity, action, }) {
|
|
|
13
13
|
message: classes.ellipses,
|
|
14
14
|
}, onMouseDown: event => {
|
|
15
15
|
event.stopPropagation();
|
|
16
|
+
}, onClick: event => {
|
|
17
|
+
event.stopPropagation();
|
|
16
18
|
}, children: _jsx(Tooltip, { title: message, children: _jsx("div", { children: message }) }) }));
|
|
17
19
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type { BaseLinearDisplayModel } from '../
|
|
2
|
-
declare const RenderedBlocks: ({ model, }: {
|
|
3
|
-
model: BaseLinearDisplayModel;
|
|
4
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
export { RenderedBlocks };
|
|
1
|
+
import type { BaseLinearDisplayModel } from '../model';
|
|
6
2
|
declare const LinearBlocks: ({ model, }: {
|
|
7
3
|
model: BaseLinearDisplayModel;
|
|
8
4
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { getContainingView } from '@jbrowse/core/util';
|
|
3
3
|
import { observer } from 'mobx-react';
|
|
4
4
|
import { makeStyles } from 'tss-react/mui';
|
|
5
|
-
import
|
|
5
|
+
import RenderedBlocks from './RenderedBlocks';
|
|
6
6
|
const useStyles = makeStyles()({
|
|
7
7
|
linearBlocks: {
|
|
8
8
|
whiteSpace: 'nowrap',
|
|
@@ -11,42 +11,7 @@ const useStyles = makeStyles()({
|
|
|
11
11
|
minHeight: '100%',
|
|
12
12
|
display: 'flex',
|
|
13
13
|
},
|
|
14
|
-
heightOverflowed: {
|
|
15
|
-
position: 'absolute',
|
|
16
|
-
color: 'rgb(77,77,77)',
|
|
17
|
-
borderBottom: '2px solid rgb(77,77,77)',
|
|
18
|
-
textShadow: 'white 0px 0px 1px',
|
|
19
|
-
whiteSpace: 'nowrap',
|
|
20
|
-
width: '100%',
|
|
21
|
-
fontWeight: 'bold',
|
|
22
|
-
textAlign: 'center',
|
|
23
|
-
zIndex: 999,
|
|
24
|
-
boxSizing: 'border-box',
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
const RenderedBlocks = observer(function ({ model, }) {
|
|
28
|
-
const { classes } = useStyles();
|
|
29
|
-
const { blockDefinitions, blockState } = model;
|
|
30
|
-
return (_jsx(_Fragment, { children: blockDefinitions.map(block => {
|
|
31
|
-
const key = `${model.id}-${block.key}`;
|
|
32
|
-
if (block.type === 'ContentBlock') {
|
|
33
|
-
const state = blockState.get(block.key);
|
|
34
|
-
return (_jsxs(ContentBlockComponent, { block: block, children: [(state === null || state === void 0 ? void 0 : state.ReactComponent) ? (_jsx(state.ReactComponent, { model: state })) : null, (state === null || state === void 0 ? void 0 : state.maxHeightReached) ? (_jsx("div", { className: classes.heightOverflowed, style: {
|
|
35
|
-
top: state.layout.getTotalHeight() - 16,
|
|
36
|
-
pointerEvents: 'none',
|
|
37
|
-
height: 16,
|
|
38
|
-
}, children: "Max height reached" })) : null] }, key));
|
|
39
|
-
}
|
|
40
|
-
if (block.type === 'ElidedBlock') {
|
|
41
|
-
return _jsx(ElidedBlockComponent, { width: block.widthPx }, key);
|
|
42
|
-
}
|
|
43
|
-
if (block.type === 'InterRegionPaddingBlock') {
|
|
44
|
-
return (_jsx(InterRegionPaddingBlockComponent, { width: block.widthPx, style: { background: 'none' }, boundary: block.variant === 'boundary' }, key));
|
|
45
|
-
}
|
|
46
|
-
throw new Error(`invalid block type ${JSON.stringify(block)}`);
|
|
47
|
-
}) }));
|
|
48
14
|
});
|
|
49
|
-
export { RenderedBlocks };
|
|
50
15
|
const LinearBlocks = observer(function ({ model, }) {
|
|
51
16
|
const { classes } = useStyles();
|
|
52
17
|
const { blockDefinitions } = model;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { makeStyles } from 'tss-react/mui';
|
|
3
|
+
const useStyles = makeStyles()({
|
|
4
|
+
heightOverflowed: {
|
|
5
|
+
position: 'absolute',
|
|
6
|
+
color: 'rgb(77,77,77)',
|
|
7
|
+
borderBottom: '2px solid rgb(77,77,77)',
|
|
8
|
+
textShadow: 'white 0px 0px 1px',
|
|
9
|
+
whiteSpace: 'nowrap',
|
|
10
|
+
width: '100%',
|
|
11
|
+
fontWeight: 'bold',
|
|
12
|
+
textAlign: 'center',
|
|
13
|
+
zIndex: 999,
|
|
14
|
+
boxSizing: 'border-box',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
export default function MaxHeightReached({ top }) {
|
|
18
|
+
const { classes } = useStyles();
|
|
19
|
+
return (_jsx("div", { className: classes.heightOverflowed, style: {
|
|
20
|
+
top,
|
|
21
|
+
pointerEvents: 'none',
|
|
22
|
+
height: 16,
|
|
23
|
+
}, children: "Max height reached" }));
|
|
24
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Coord } from './types';
|
|
2
|
+
import type { BaseLinearDisplayModel } from '../model';
|
|
3
|
+
declare const MenuPage: ({ onClose, contextCoord, model, }: {
|
|
4
|
+
model: BaseLinearDisplayModel;
|
|
5
|
+
contextCoord: Coord;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default MenuPage;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Menu } from '@jbrowse/core/ui';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
4
|
+
const MenuPage = observer(function ({ onClose, contextCoord, model, }) {
|
|
5
|
+
const items = model.contextMenuItems();
|
|
6
|
+
return (_jsx(Menu, { open: items.length > 0, onMenuItemClick: (_, callback) => {
|
|
7
|
+
callback();
|
|
8
|
+
onClose();
|
|
9
|
+
}, onClose: () => {
|
|
10
|
+
onClose();
|
|
11
|
+
model.setContextMenuFeature(undefined);
|
|
12
|
+
}, slotProps: {
|
|
13
|
+
transition: {
|
|
14
|
+
onExit: () => {
|
|
15
|
+
onClose();
|
|
16
|
+
model.setContextMenuFeature(undefined);
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}, anchorReference: "anchorPosition", anchorPosition: {
|
|
20
|
+
top: contextCoord[1],
|
|
21
|
+
left: contextCoord[0],
|
|
22
|
+
}, menuItems: items }));
|
|
23
|
+
});
|
|
24
|
+
export default MenuPage;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BlockSet } from '@jbrowse/core/util/blockTypes';
|
|
2
|
+
declare const RenderedBlocks: ({ model, }: {
|
|
3
|
+
model: {
|
|
4
|
+
id: string;
|
|
5
|
+
blockDefinitions: BlockSet;
|
|
6
|
+
blockState: any;
|
|
7
|
+
};
|
|
8
|
+
}) => import("react/jsx-runtime").JSX.Element[];
|
|
9
|
+
export default RenderedBlocks;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
3
|
+
import { ContentBlock as ContentBlockComponent, ElidedBlock as ElidedBlockComponent, InterRegionPaddingBlock as InterRegionPaddingBlockComponent, } from './Block';
|
|
4
|
+
import MaxHeightReached from './MaxHeightReachedIndicator';
|
|
5
|
+
const RenderedBlocks = observer(function ({ model, }) {
|
|
6
|
+
const { blockDefinitions, blockState } = model;
|
|
7
|
+
return blockDefinitions.map(block => {
|
|
8
|
+
const key = `${model.id}-${block.key}`;
|
|
9
|
+
if (block.type === 'ContentBlock') {
|
|
10
|
+
const state = blockState.get(block.key);
|
|
11
|
+
return (_jsxs(ContentBlockComponent, { block: block, children: [(state === null || state === void 0 ? void 0 : state.ReactComponent) ? (_jsx(state.ReactComponent, { model: state })) : null, (state === null || state === void 0 ? void 0 : state.maxHeightReached) ? (_jsx(MaxHeightReached, { top: state.layout.getTotalHeight() - 16 })) : null] }, key));
|
|
12
|
+
}
|
|
13
|
+
else if (block.type === 'ElidedBlock') {
|
|
14
|
+
return _jsx(ElidedBlockComponent, { width: block.widthPx }, key);
|
|
15
|
+
}
|
|
16
|
+
else if (block.type === 'InterRegionPaddingBlock') {
|
|
17
|
+
return (_jsx(InterRegionPaddingBlockComponent, { width: block.widthPx, style: { background: 'none' }, boundary: block.variant === 'boundary' }, key));
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`invalid block type ${JSON.stringify(block)}`);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
export default RenderedBlocks;
|
|
@@ -8,11 +8,14 @@ const TooltipContents = forwardRef(function TooltipContents2({ message }, ref) {
|
|
|
8
8
|
return (_jsx("div", { ref: ref, children: isValidElement(message) ? (message) : message ? (_jsx(SanitizedHTML, { html: String(message) })) : null }));
|
|
9
9
|
});
|
|
10
10
|
const Tooltip = observer(function ({ model, clientMouseCoord, }) {
|
|
11
|
-
const { featureUnderMouse } = model;
|
|
11
|
+
const { featureUnderMouse, mouseoverExtraInformation } = model;
|
|
12
12
|
const x = clientMouseCoord[0] + 15;
|
|
13
13
|
const y = clientMouseCoord[1];
|
|
14
14
|
const contents = featureUnderMouse
|
|
15
|
-
? getConf(model, 'mouseover', {
|
|
15
|
+
? getConf(model, 'mouseover', {
|
|
16
|
+
feature: featureUnderMouse,
|
|
17
|
+
mouseoverExtraInformation,
|
|
18
|
+
})
|
|
16
19
|
: undefined;
|
|
17
20
|
return featureUnderMouse && contents ? (_jsx(BaseTooltip, { clientPoint: { x, y }, children: _jsx(TooltipContents, { message: contents }) })) : null;
|
|
18
21
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Coord = [number, number];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { default as baseLinearDisplayConfigSchema } from './models/configSchema';
|
|
2
2
|
export type { BlockModel } from './models/serverSideRenderedBlock';
|
|
3
|
-
export { BaseLinearDisplay } from './
|
|
4
|
-
export type { BaseLinearDisplayModel, BaseLinearDisplayStateModel, ExportSvgDisplayOptions, } from './
|
|
3
|
+
export { BaseLinearDisplay } from './model';
|
|
4
|
+
export type { BaseLinearDisplayModel, BaseLinearDisplayStateModel, ExportSvgDisplayOptions, } from './model';
|
|
5
5
|
export { BlockMsg, Tooltip, default as BaseLinearDisplayComponent, } from './components/BaseLinearDisplay';
|
|
6
6
|
export { default as TrackHeightMixin } from './models/TrackHeightMixin';
|
|
7
7
|
export { default as FeatureDensityMixin } from './models/FeatureDensityMixin';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as baseLinearDisplayConfigSchema } from './models/configSchema';
|
|
2
|
-
export { BaseLinearDisplay } from './
|
|
2
|
+
export { BaseLinearDisplay } from './model';
|
|
3
3
|
export { BlockMsg, Tooltip, default as BaseLinearDisplayComponent, } from './components/BaseLinearDisplay';
|
|
4
4
|
export { default as TrackHeightMixin } from './models/TrackHeightMixin';
|
|
5
5
|
export { default as FeatureDensityMixin } from './models/FeatureDensityMixin';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import CompositeMap from '@jbrowse/core/util/compositeMap';
|
|
3
|
-
import type { ExportSvgOptions } from '
|
|
3
|
+
import type { ExportSvgOptions } from '../LinearGenomeView/types';
|
|
4
4
|
import type { MenuItem } from '@jbrowse/core/ui';
|
|
5
5
|
import type { AnyReactComponentType, Feature } from '@jbrowse/core/util';
|
|
6
6
|
import type { BaseBlock } from '@jbrowse/core/util/blockTypes';
|
|
@@ -13,7 +13,17 @@ export interface Layout {
|
|
|
13
13
|
maxY: number;
|
|
14
14
|
name: string;
|
|
15
15
|
}
|
|
16
|
-
type LayoutRecord = [number, number, number, number]
|
|
16
|
+
type LayoutRecord = [number, number, number, number] | [
|
|
17
|
+
number,
|
|
18
|
+
number,
|
|
19
|
+
number,
|
|
20
|
+
number,
|
|
21
|
+
{
|
|
22
|
+
label?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
refName: string;
|
|
25
|
+
}
|
|
26
|
+
];
|
|
17
27
|
export interface ExportSvgDisplayOptions extends ExportSvgOptions {
|
|
18
28
|
overrideHeight: number;
|
|
19
29
|
theme: ThemeOptions;
|
|
@@ -61,7 +71,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
61
71
|
setStatus(message: string): void;
|
|
62
72
|
setLoading(newStopToken: string): void;
|
|
63
73
|
setMessage(messageText: string): void;
|
|
64
|
-
setRendered(props: import("./serverSideRenderedBlock").RenderedProps | undefined): void;
|
|
74
|
+
setRendered(props: import("./models/serverSideRenderedBlock").RenderedProps | undefined): void;
|
|
65
75
|
setError(error: unknown): void;
|
|
66
76
|
reload(): void;
|
|
67
77
|
beforeDestroy(): void;
|
|
@@ -187,6 +197,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
187
197
|
regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
|
|
188
198
|
regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): import("react/jsx-runtime").JSX.Element | null;
|
|
189
199
|
} & {
|
|
200
|
+
mouseoverExtraInformation: string | undefined;
|
|
190
201
|
featureIdUnderMouse: undefined | string;
|
|
191
202
|
contextMenuFeature: undefined | Feature;
|
|
192
203
|
} & {
|
|
@@ -201,6 +212,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
201
212
|
} & {
|
|
202
213
|
readonly features: CompositeMap<string, Feature>;
|
|
203
214
|
readonly featureUnderMouse: Feature | undefined;
|
|
215
|
+
readonly layoutFeatures: CompositeMap<string, LayoutRecord>;
|
|
204
216
|
getFeatureOverlapping(blockKey: string, x: number, y: number): string | undefined;
|
|
205
217
|
getFeatureByID(blockKey: string, id: string): LayoutRecord | undefined;
|
|
206
218
|
searchFeatureByID(id: string): LayoutRecord | undefined;
|
|
@@ -212,6 +224,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
212
224
|
clearFeatureSelection(): void;
|
|
213
225
|
setFeatureIdUnderMouse(feature?: string): void;
|
|
214
226
|
setContextMenuFeature(feature?: Feature): void;
|
|
227
|
+
setMouseoverExtraInformation(extra?: string): void;
|
|
215
228
|
} & {
|
|
216
229
|
reload(): Promise<void>;
|
|
217
230
|
} & {
|
|
@@ -264,7 +277,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
|
|
|
264
277
|
setStatus(message: string): void;
|
|
265
278
|
setLoading(newStopToken: string): void;
|
|
266
279
|
setMessage(messageText: string): void;
|
|
267
|
-
setRendered(props: import("./serverSideRenderedBlock").RenderedProps | undefined): void;
|
|
280
|
+
setRendered(props: import("./models/serverSideRenderedBlock").RenderedProps | undefined): void;
|
|
268
281
|
setError(error: unknown): void;
|
|
269
282
|
reload(): void;
|
|
270
283
|
beforeDestroy(): void;
|
|
@@ -10,11 +10,11 @@ import MenuOpenIcon from '@mui/icons-material/MenuOpen';
|
|
|
10
10
|
import copy from 'copy-to-clipboard';
|
|
11
11
|
import { autorun } from 'mobx';
|
|
12
12
|
import { addDisposer, isAlive, types } from 'mobx-state-tree';
|
|
13
|
-
import FeatureDensityMixin from './FeatureDensityMixin';
|
|
14
|
-
import TrackHeightMixin from './TrackHeightMixin';
|
|
15
|
-
import configSchema from './configSchema';
|
|
16
|
-
import BlockState from './serverSideRenderedBlock';
|
|
17
|
-
const Tooltip = lazy(() => import('
|
|
13
|
+
import FeatureDensityMixin from './models/FeatureDensityMixin';
|
|
14
|
+
import TrackHeightMixin from './models/TrackHeightMixin';
|
|
15
|
+
import configSchema from './models/configSchema';
|
|
16
|
+
import BlockState from './models/serverSideRenderedBlock';
|
|
17
|
+
const Tooltip = lazy(() => import('./components/Tooltip'));
|
|
18
18
|
function stateModelFactory() {
|
|
19
19
|
return types
|
|
20
20
|
.compose('BaseLinearDisplay', BaseDisplay, TrackHeightMixin(), FeatureDensityMixin(), types.model({
|
|
@@ -22,6 +22,7 @@ function stateModelFactory() {
|
|
|
22
22
|
configuration: ConfigurationReference(configSchema),
|
|
23
23
|
}))
|
|
24
24
|
.volatile(() => ({
|
|
25
|
+
mouseoverExtraInformation: undefined,
|
|
25
26
|
featureIdUnderMouse: undefined,
|
|
26
27
|
contextMenuFeature: undefined,
|
|
27
28
|
}))
|
|
@@ -77,6 +78,15 @@ function stateModelFactory() {
|
|
|
77
78
|
const feat = self.featureIdUnderMouse;
|
|
78
79
|
return feat ? this.features.get(feat) : undefined;
|
|
79
80
|
},
|
|
81
|
+
get layoutFeatures() {
|
|
82
|
+
const featureMaps = [];
|
|
83
|
+
for (const block of self.blockState.values()) {
|
|
84
|
+
if (block.layout) {
|
|
85
|
+
featureMaps.push(block.layout.rectangles);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return new CompositeMap(featureMaps);
|
|
89
|
+
},
|
|
80
90
|
getFeatureOverlapping(blockKey, x, y) {
|
|
81
91
|
var _a, _b;
|
|
82
92
|
return (_b = (_a = self.blockState.get(blockKey)) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.getByCoord(x, y);
|
|
@@ -154,6 +164,9 @@ function stateModelFactory() {
|
|
|
154
164
|
setContextMenuFeature(feature) {
|
|
155
165
|
self.contextMenuFeature = feature;
|
|
156
166
|
},
|
|
167
|
+
setMouseoverExtraInformation(extra) {
|
|
168
|
+
self.mouseoverExtraInformation = extra;
|
|
169
|
+
},
|
|
157
170
|
}))
|
|
158
171
|
.actions(self => {
|
|
159
172
|
const { reload: superReload } = self;
|
|
@@ -231,11 +244,13 @@ function stateModelFactory() {
|
|
|
231
244
|
self.setContextMenuFeature(self.features.get(f));
|
|
232
245
|
}
|
|
233
246
|
},
|
|
234
|
-
onMouseMove(_, featureId) {
|
|
247
|
+
onMouseMove(_, featureId, extra) {
|
|
235
248
|
self.setFeatureIdUnderMouse(featureId);
|
|
249
|
+
self.setMouseoverExtraInformation(extra);
|
|
236
250
|
},
|
|
237
251
|
onMouseLeave(_) {
|
|
238
252
|
self.setFeatureIdUnderMouse(undefined);
|
|
253
|
+
self.setMouseoverExtraInformation(undefined);
|
|
239
254
|
},
|
|
240
255
|
onContextMenu() {
|
|
241
256
|
self.setContextMenuFeature(undefined);
|
|
@@ -246,7 +261,7 @@ function stateModelFactory() {
|
|
|
246
261
|
}))
|
|
247
262
|
.actions(self => ({
|
|
248
263
|
async renderSvg(opts) {
|
|
249
|
-
const { renderBaseLinearDisplaySvg } = await import('./renderSvg');
|
|
264
|
+
const { renderBaseLinearDisplaySvg } = await import('./models/renderSvg');
|
|
250
265
|
return renderBaseLinearDisplaySvg(self, opts);
|
|
251
266
|
},
|
|
252
267
|
afterAttach() {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { BaseLinearDisplayModel } from '
|
|
1
|
+
import type { BaseLinearDisplayModel } from '../model';
|
|
2
2
|
export default function autorunFeatureDensityStats(self: BaseLinearDisplayModel): Promise<void>;
|
|
@@ -19,8 +19,8 @@ const baseLinearDisplayConfigSchema = ConfigurationSchema('BaseLinearDisplay', {
|
|
|
19
19
|
mouseover: {
|
|
20
20
|
type: 'string',
|
|
21
21
|
description: 'text to display when the cursor hovers over a feature',
|
|
22
|
-
defaultValue: `jexl:get(feature,'name')`,
|
|
23
|
-
contextVariable: ['feature'],
|
|
22
|
+
defaultValue: `jexl:join('<br/>',get(feature,'_mouseOver')||get(feature,'name')||get(feature,'id'),mouseoverExtraInformation||'')`,
|
|
23
|
+
contextVariable: ['feature', 'mouseoverExtraInformation'],
|
|
24
24
|
},
|
|
25
25
|
jexlFilters: {
|
|
26
26
|
type: 'stringArray',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { BaseLinearDisplayModel } from './BaseLinearDisplayModel';
|
|
2
1
|
import type { ExportSvgOptions } from '../../LinearGenomeView/types';
|
|
2
|
+
import type { BaseLinearDisplayModel } from '../model';
|
|
3
3
|
import type { ThemeOptions } from '@mui/material';
|
|
4
4
|
export declare function renderBaseLinearDisplaySvg(self: BaseLinearDisplayModel, opts: ExportSvgOptions & {
|
|
5
5
|
overrideHeight: number;
|
|
@@ -171,6 +171,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
171
171
|
regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
|
|
172
172
|
regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): import("react/jsx-runtime").JSX.Element | null;
|
|
173
173
|
} & {
|
|
174
|
+
mouseoverExtraInformation: string | undefined;
|
|
174
175
|
featureIdUnderMouse: undefined | string;
|
|
175
176
|
contextMenuFeature: undefined | import("@jbrowse/core/util").Feature;
|
|
176
177
|
} & {
|
|
@@ -185,9 +186,22 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
185
186
|
} & {
|
|
186
187
|
readonly features: import("@jbrowse/core/util/compositeMap").default<string, import("@jbrowse/core/util").Feature>;
|
|
187
188
|
readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
|
|
189
|
+
readonly layoutFeatures: import("@jbrowse/core/util/compositeMap").default<string, [number, number, number, number] | [number, number, number, number, {
|
|
190
|
+
label?: string;
|
|
191
|
+
description?: string;
|
|
192
|
+
refName: string;
|
|
193
|
+
}]>;
|
|
188
194
|
getFeatureOverlapping(blockKey: string, x: number, y: number): string | undefined;
|
|
189
|
-
getFeatureByID(blockKey: string, id: string): [number, number, number, number] |
|
|
190
|
-
|
|
195
|
+
getFeatureByID(blockKey: string, id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
196
|
+
label?: string;
|
|
197
|
+
description?: string;
|
|
198
|
+
refName: string;
|
|
199
|
+
}]) | undefined;
|
|
200
|
+
searchFeatureByID(id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
201
|
+
label?: string;
|
|
202
|
+
description?: string;
|
|
203
|
+
refName: string;
|
|
204
|
+
}]) | undefined;
|
|
191
205
|
} & {
|
|
192
206
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
193
207
|
deleteBlock(key: string): void;
|
|
@@ -196,6 +210,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
196
210
|
clearFeatureSelection(): void;
|
|
197
211
|
setFeatureIdUnderMouse(feature?: string): void;
|
|
198
212
|
setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature): void;
|
|
213
|
+
setMouseoverExtraInformation(extra?: string): void;
|
|
199
214
|
} & {
|
|
200
215
|
reload(): Promise<void>;
|
|
201
216
|
} & {
|