@jbrowse/plugin-linear-genome-view 3.0.5 → 3.2.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.
Files changed (77) hide show
  1. package/dist/BaseLinearDisplay/components/BlockErrorMessage.d.ts +7 -0
  2. package/dist/BaseLinearDisplay/components/{BlockError.js → BlockErrorMessage.js} +6 -3
  3. package/dist/BaseLinearDisplay/components/BlockLoadingMessage.d.ts +6 -0
  4. package/dist/BaseLinearDisplay/components/BlockLoadingMessage.js +26 -0
  5. package/dist/BaseLinearDisplay/components/BlockMsg.js +4 -2
  6. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +4 -24
  7. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +9 -9
  8. package/dist/LaunchLinearGenomeView/index.js +9 -5
  9. package/dist/LinearGenomeView/components/CenterLine.js +1 -1
  10. package/dist/LinearGenomeView/components/Gridlines.d.ts +2 -1
  11. package/dist/LinearGenomeView/components/Gridlines.js +3 -4
  12. package/dist/LinearGenomeView/components/Header.js +2 -0
  13. package/dist/LinearGenomeView/components/LinearGenomeView.js +2 -49
  14. package/dist/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +5 -0
  15. package/dist/LinearGenomeView/components/LinearGenomeViewContainer.js +98 -0
  16. package/dist/LinearGenomeView/components/MiniControls.js +0 -1
  17. package/dist/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  18. package/dist/LinearGenomeView/components/OverviewRubberband.js +2 -15
  19. package/dist/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +10 -0
  20. package/dist/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +36 -0
  21. package/dist/LinearGenomeView/components/Rubberband.js +7 -2
  22. package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +3 -1
  23. package/dist/LinearGenomeView/components/RubberbandSpan.js +13 -25
  24. package/dist/LinearGenomeView/components/RubberbandTooltip.d.ts +5 -0
  25. package/dist/LinearGenomeView/components/RubberbandTooltip.js +28 -0
  26. package/dist/LinearGenomeView/components/Scalebar.js +2 -2
  27. package/dist/LinearGenomeView/components/TrackContainer.js +9 -4
  28. package/dist/LinearGenomeView/components/TrackLabel.js +1 -1
  29. package/dist/LinearGenomeView/components/TrackLabelContainer.js +1 -1
  30. package/dist/LinearGenomeView/components/TrackLabelMenu.js +21 -0
  31. package/dist/LinearGenomeView/components/TrackRenderingContainer.js +0 -1
  32. package/dist/LinearGenomeView/components/TracksContainer.js +3 -4
  33. package/dist/LinearGenomeView/components/VerticalGuide.js +12 -5
  34. package/dist/LinearGenomeView/model.d.ts +31 -3
  35. package/dist/LinearGenomeView/model.js +84 -24
  36. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +2 -2
  37. package/dist/LinearGenomeView/types.d.ts +5 -0
  38. package/esm/BaseLinearDisplay/components/BlockErrorMessage.d.ts +7 -0
  39. package/esm/BaseLinearDisplay/components/{BlockError.js → BlockErrorMessage.js} +6 -3
  40. package/esm/BaseLinearDisplay/components/BlockLoadingMessage.d.ts +6 -0
  41. package/esm/BaseLinearDisplay/components/BlockLoadingMessage.js +24 -0
  42. package/esm/BaseLinearDisplay/components/BlockMsg.js +4 -2
  43. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +4 -24
  44. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +9 -9
  45. package/esm/LaunchLinearGenomeView/index.js +9 -5
  46. package/esm/LinearGenomeView/components/CenterLine.js +1 -1
  47. package/esm/LinearGenomeView/components/Gridlines.d.ts +2 -1
  48. package/esm/LinearGenomeView/components/Gridlines.js +3 -4
  49. package/esm/LinearGenomeView/components/Header.js +2 -0
  50. package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -50
  51. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +5 -0
  52. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +60 -0
  53. package/esm/LinearGenomeView/components/MiniControls.js +0 -1
  54. package/esm/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  55. package/esm/LinearGenomeView/components/OverviewRubberband.js +3 -16
  56. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +10 -0
  57. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +34 -0
  58. package/esm/LinearGenomeView/components/Rubberband.js +7 -2
  59. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +3 -1
  60. package/esm/LinearGenomeView/components/RubberbandSpan.js +11 -26
  61. package/esm/LinearGenomeView/components/RubberbandTooltip.d.ts +5 -0
  62. package/esm/LinearGenomeView/components/RubberbandTooltip.js +25 -0
  63. package/esm/LinearGenomeView/components/Scalebar.js +2 -2
  64. package/esm/LinearGenomeView/components/TrackContainer.js +9 -4
  65. package/esm/LinearGenomeView/components/TrackLabel.js +1 -1
  66. package/esm/LinearGenomeView/components/TrackLabelContainer.js +1 -1
  67. package/esm/LinearGenomeView/components/TrackLabelMenu.js +21 -0
  68. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +0 -1
  69. package/esm/LinearGenomeView/components/TracksContainer.js +3 -4
  70. package/esm/LinearGenomeView/components/VerticalGuide.js +13 -6
  71. package/esm/LinearGenomeView/model.d.ts +31 -3
  72. package/esm/LinearGenomeView/model.js +84 -24
  73. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +2 -2
  74. package/esm/LinearGenomeView/types.d.ts +5 -0
  75. package/package.json +3 -3
  76. package/dist/BaseLinearDisplay/components/BlockError.d.ts +0 -4
  77. package/esm/BaseLinearDisplay/components/BlockError.d.ts +0 -4
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.default = RubberbandSpan;
4
7
  const jsx_runtime_1 = require("react/jsx-runtime");
@@ -6,6 +9,7 @@ const react_1 = require("react");
6
9
  const util_1 = require("@jbrowse/core/util");
7
10
  const material_1 = require("@mui/material");
8
11
  const mui_1 = require("tss-react/mui");
12
+ const RubberbandTooltip_1 = __importDefault(require("./RubberbandTooltip"));
9
13
  const useStyles = (0, mui_1.makeStyles)()(theme => {
10
14
  const { tertiary } = theme.palette;
11
15
  const background = (0, material_1.alpha)(tertiary.light, 0.7);
@@ -14,9 +18,8 @@ const useStyles = (0, mui_1.makeStyles)()(theme => {
14
18
  height: '100%',
15
19
  background,
16
20
  position: 'absolute',
17
- zIndex: 10,
21
+ zIndex: 830,
18
22
  textAlign: 'center',
19
- overflow: 'hidden',
20
23
  },
21
24
  rubberbandControl: {
22
25
  cursor: 'crosshair',
@@ -24,32 +27,17 @@ const useStyles = (0, mui_1.makeStyles)()(theme => {
24
27
  minHeight: 8,
25
28
  },
26
29
  rubberbandText: {
27
- color: tertiary.contrastText,
28
- },
29
- popover: {
30
- mouseEvents: 'none',
31
- cursor: 'crosshair',
32
- },
33
- paper: {
34
- paddingLeft: theme.spacing(1),
35
- paddingRight: theme.spacing(1),
30
+ color: theme.palette.tertiary.contrastText,
36
31
  },
37
32
  };
38
33
  });
39
- function Tooltip({ anchorEl, side, text, }) {
40
- const { classes } = useStyles();
41
- return ((0, jsx_runtime_1.jsx)(material_1.Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: anchorEl, anchorOrigin: {
42
- vertical: 'top',
43
- horizontal: side === 'left' ? 'right' : 'left',
44
- }, transformOrigin: {
45
- vertical: 'bottom',
46
- horizontal: side === 'left' ? 'left' : 'right',
47
- }, keepMounted: true, disableRestoreFocus: true, children: (0, jsx_runtime_1.jsx)(material_1.Typography, { children: text }) }));
48
- }
49
- function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, }) {
34
+ function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top = 0, sticky = false, }) {
50
35
  const { classes } = useStyles();
51
36
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
52
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [anchorEl ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Tooltip, { side: "left", anchorEl: anchorEl, text: (0, util_1.stringify)(leftBpOffset) }), (0, jsx_runtime_1.jsx)(Tooltip, { side: "right", anchorEl: anchorEl, text: (0, util_1.stringify)(rightBpOffset) })] })) : null, (0, jsx_runtime_1.jsx)("div", { ref: el => {
53
- setAnchorEl(el);
54
- }, className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? ((0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "h6", className: classes.rubberbandText, children: [(0, util_1.toLocale)(numOfBpSelected), " bp"] })) : null })] }));
37
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [anchorEl ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(RubberbandTooltip_1.default, { side: "left", anchorEl: anchorEl, text: (0, util_1.stringify)(leftBpOffset) }), (0, jsx_runtime_1.jsx)(RubberbandTooltip_1.default, { side: "right", anchorEl: anchorEl, text: (0, util_1.stringify)(rightBpOffset) })] })) : null, (0, jsx_runtime_1.jsx)("div", { className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? ((0, jsx_runtime_1.jsxs)(material_1.Typography, { ref: el => {
38
+ setAnchorEl(el);
39
+ }, variant: "h6", className: classes.rubberbandText, style: {
40
+ top,
41
+ position: sticky ? 'sticky' : undefined,
42
+ }, children: [(0, util_1.toLocale)(numOfBpSelected), " bp"] })) : null })] }));
55
43
  }
@@ -0,0 +1,5 @@
1
+ export default function RubberbandTooltip({ anchorEl, side, text, }: {
2
+ anchorEl: HTMLSpanElement;
3
+ side: string;
4
+ text: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = RubberbandTooltip;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const material_1 = require("@mui/material");
6
+ const mui_1 = require("tss-react/mui");
7
+ const useStyles = (0, mui_1.makeStyles)()(theme => {
8
+ return {
9
+ popover: {
10
+ mouseEvents: 'none',
11
+ cursor: 'crosshair',
12
+ },
13
+ paper: {
14
+ paddingLeft: theme.spacing(1),
15
+ paddingRight: theme.spacing(1),
16
+ },
17
+ };
18
+ });
19
+ function RubberbandTooltip({ anchorEl, side, text, }) {
20
+ const { classes } = useStyles();
21
+ return ((0, jsx_runtime_1.jsx)(material_1.Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: anchorEl, anchorOrigin: {
22
+ vertical: 'top',
23
+ horizontal: side === 'left' ? 'left' : 'right',
24
+ }, transformOrigin: {
25
+ vertical: 'bottom',
26
+ horizontal: side === 'left' ? 'right' : 'left',
27
+ }, keepMounted: true, disableRestoreFocus: true, children: (0, jsx_runtime_1.jsx)(material_1.Typography, { children: text }) }));
28
+ }
@@ -8,6 +8,7 @@ const react_1 = require("react");
8
8
  const material_1 = require("@mui/material");
9
9
  const mobx_react_1 = require("mobx-react");
10
10
  const mui_1 = require("tss-react/mui");
11
+ const Gridlines_1 = __importDefault(require("./Gridlines"));
11
12
  const ScalebarCoordinateLabels_1 = __importDefault(require("./ScalebarCoordinateLabels"));
12
13
  const ScalebarRefNameLabels_1 = __importDefault(require("./ScalebarRefNameLabels"));
13
14
  const useStyles = (0, mui_1.makeStyles)()({
@@ -17,7 +18,6 @@ const useStyles = (0, mui_1.makeStyles)()({
17
18
  },
18
19
  zoomContainer: {
19
20
  position: 'relative',
20
- zIndex: 1,
21
21
  },
22
22
  scalebar: {
23
23
  position: 'absolute',
@@ -29,7 +29,7 @@ const Scalebar = (0, mobx_react_1.observer)((0, react_1.forwardRef)(function Sca
29
29
  const { classes, cx } = useStyles();
30
30
  const { staticBlocks, offsetPx, scaleFactor } = model;
31
31
  const offsetLeft = staticBlocks.offsetPx - offsetPx;
32
- return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined", ref: ref, style: style, ...other, children: [(0, jsx_runtime_1.jsx)("div", { className: classes.zoomContainer, style: {
32
+ return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined", ref: ref, style: style, ...other, children: [(0, jsx_runtime_1.jsx)(Gridlines_1.default, { model: model, offset: 1 }), (0, jsx_runtime_1.jsx)("div", { className: classes.zoomContainer, style: {
33
33
  transform: scaleFactor !== 1 ? `scaleX(${scaleFactor})` : undefined,
34
34
  }, children: (0, jsx_runtime_1.jsx)("div", { className: classes.scalebar, style: {
35
35
  left: offsetLeft - 1,
@@ -11,31 +11,36 @@ const material_1 = require("@mui/material");
11
11
  const mobx_react_1 = require("mobx-react");
12
12
  const mobx_state_tree_1 = require("mobx-state-tree");
13
13
  const mui_1 = require("tss-react/mui");
14
+ const Gridlines_1 = __importDefault(require("./Gridlines"));
14
15
  const TrackLabelContainer_1 = __importDefault(require("./TrackLabelContainer"));
15
16
  const TrackRenderingContainer_1 = __importDefault(require("./TrackRenderingContainer"));
16
17
  const useStyles = (0, mui_1.makeStyles)()({
17
18
  root: {
18
19
  marginTop: 2,
20
+ overflow: 'hidden',
21
+ position: 'relative',
22
+ },
23
+ unpinnedTrack: {
24
+ background: 'none',
19
25
  },
20
26
  resizeHandle: {
21
27
  height: 3,
22
28
  boxSizing: 'border-box',
23
29
  position: 'relative',
24
- zIndex: 2,
25
30
  },
26
31
  });
27
32
  const TrackContainer = (0, mobx_react_1.observer)(function ({ model, track, }) {
28
- const { classes } = useStyles();
33
+ const { classes, cx } = useStyles();
29
34
  const display = track.displays[0];
30
35
  const { draggingTrackId, showTrackOutlines } = model;
31
36
  const ref = (0, react_1.useRef)(null);
32
- return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { ref: ref, className: classes.root, variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
37
+ return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { ref: ref, className: cx(classes.root, track.pinned ? null : classes.unpinnedTrack), variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
33
38
  var _a;
34
39
  if (event.detail === 2 && !track.displays[0].featureIdUnderMouse) {
35
40
  const left = ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0;
36
41
  model.zoomTo(model.bpPerPx / 2, event.clientX - left, true);
37
42
  }
38
- }, children: [(0, jsx_runtime_1.jsx)(TrackLabelContainer_1.default, { track: track, view: model }), (0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorBoundary, { FallbackComponent: e => (0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: e.error }), children: (0, jsx_runtime_1.jsx)(TrackRenderingContainer_1.default, { model: model, track: track, onDragEnter: () => {
43
+ }, children: [track.pinned ? (0, jsx_runtime_1.jsx)(Gridlines_1.default, { model: model, offset: 1 }) : null, (0, jsx_runtime_1.jsx)(TrackLabelContainer_1.default, { track: track, view: model }), (0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorBoundary, { FallbackComponent: e => (0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: e.error }), children: (0, jsx_runtime_1.jsx)(TrackRenderingContainer_1.default, { model: model, track: track, onDragEnter: () => {
39
44
  if ((0, mobx_state_tree_1.isAlive)(display) &&
40
45
  draggingTrackId !== undefined &&
41
46
  draggingTrackId !== display.id) {
@@ -34,7 +34,7 @@ const TrackLabel = (0, mobx_react_1.observer)((0, react_1.forwardRef)(function T
34
34
  const view = (0, util_1.getContainingView)(track);
35
35
  const session = (0, util_1.getSession)(track);
36
36
  const trackConf = track.configuration;
37
- const minimized = track.minimized;
37
+ const { minimized } = track;
38
38
  const trackId = (0, configuration_1.getConf)(track, 'trackId');
39
39
  const trackName = (0, tracks_1.getTrackName)(trackConf, session);
40
40
  return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { ref: ref, className: cx(className, classes.root), onClick: event => {
@@ -9,7 +9,7 @@ const mui_1 = require("tss-react/mui");
9
9
  const TrackLabel_1 = __importDefault(require("./TrackLabel"));
10
10
  const useStyles = (0, mui_1.makeStyles)()({
11
11
  trackLabel: {
12
- zIndex: 3,
12
+ zIndex: 2,
13
13
  },
14
14
  trackLabelOffset: {
15
15
  position: 'relative',
@@ -13,6 +13,7 @@ const KeyboardDoubleArrowDown_1 = __importDefault(require("@mui/icons-material/K
13
13
  const KeyboardDoubleArrowUp_1 = __importDefault(require("@mui/icons-material/KeyboardDoubleArrowUp"));
14
14
  const Minimize_1 = __importDefault(require("@mui/icons-material/Minimize"));
15
15
  const MoreVert_1 = __importDefault(require("@mui/icons-material/MoreVert"));
16
+ const PushPin_1 = __importDefault(require("@mui/icons-material/PushPin"));
16
17
  const mobx_react_1 = require("mobx-react");
17
18
  const TrackLabelMenu = (0, mobx_react_1.observer)(function ({ track, }) {
18
19
  var _a;
@@ -20,7 +21,27 @@ const TrackLabelMenu = (0, mobx_react_1.observer)(function ({ track, }) {
20
21
  const session = (0, util_1.getSession)(track);
21
22
  const trackConf = track.configuration;
22
23
  const minimized = track.minimized;
24
+ const pinned = track.pinned;
25
+ let lgvHasParentView;
26
+ try {
27
+ (0, util_1.getContainingView)(view);
28
+ lgvHasParentView = true;
29
+ }
30
+ catch (error) {
31
+ lgvHasParentView = false;
32
+ }
23
33
  const items = [
34
+ ...(lgvHasParentView
35
+ ? []
36
+ : [
37
+ {
38
+ label: pinned ? 'Unpin track' : 'Pin track',
39
+ icon: PushPin_1.default,
40
+ onClick: () => {
41
+ track.setPinned(!pinned);
42
+ },
43
+ },
44
+ ]),
24
45
  {
25
46
  label: 'Track order',
26
47
  type: 'subMenu',
@@ -19,7 +19,6 @@ const useStyles = (0, mui_1.makeStyles)()({
19
19
  whiteSpace: 'nowrap',
20
20
  position: 'relative',
21
21
  background: 'none',
22
- zIndex: 2,
23
22
  },
24
23
  });
25
24
  const TrackRenderingContainer = (0, mobx_react_1.observer)(function ({ model, track, onDragEnter, }) {
@@ -56,22 +56,21 @@ const RubberbandSpan = (0, react_1.lazy)(() => Promise.resolve().then(() => __im
56
56
  const useStyles = (0, mui_1.makeStyles)()({
57
57
  tracksContainer: {
58
58
  position: 'relative',
59
- overflow: 'hidden',
60
59
  },
61
60
  });
62
61
  const TracksContainer = (0, mobx_react_1.observer)(function TracksContainer({ children, model, }) {
63
62
  const { classes } = useStyles();
64
63
  const { pluginManager } = (0, util_1.getEnv)(model);
65
64
  const { mouseDown: mouseDown1, mouseUp } = (0, useSideScroll_1.useSideScroll)(model);
66
- const { showGridlines, showCenterLine } = model;
65
+ const { stickyViewHeaders, rubberbandTop, showGridlines, showCenterLine } = model;
67
66
  const ref = (0, react_1.useRef)(null);
68
67
  const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown: mouseDown2, } = (0, useRangeSelect_1.useRangeSelect)(ref, model, true);
69
68
  (0, useWheelScroll_1.useWheelScroll)(ref, model);
70
69
  const additional = pluginManager.evaluateExtensionPoint('LinearGenomeView-TracksContainerComponent', undefined, { model });
71
- return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, "data-testid": "trackContainer", className: classes.tracksContainer, onMouseDown: event => {
70
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, "data-testid": "tracksContainer", className: classes.tracksContainer, onMouseDown: event => {
72
71
  mouseDown1(event);
73
72
  mouseDown2(event);
74
- }, onMouseMove: mouseMove, onMouseUp: mouseUp, children: [showGridlines ? (0, jsx_runtime_1.jsx)(Gridlines_1.default, { model: model }) : null, (0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: showCenterLine ? (0, jsx_runtime_1.jsx)(CenterLine, { model: model }) : null }), guideX !== undefined ? ((0, jsx_runtime_1.jsx)(VerticalGuide_1.default, { model: model, coordX: guideX })) : rubberbandOn ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left }) })) : null, anchorPosition ? ((0, jsx_runtime_1.jsx)(ui_1.Menu, { anchorReference: "anchorPosition", anchorPosition: {
73
+ }, onMouseMove: mouseMove, onMouseUp: mouseUp, children: [showGridlines ? (0, jsx_runtime_1.jsx)(Gridlines_1.default, { model: model }) : null, (0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: showCenterLine ? (0, jsx_runtime_1.jsx)(CenterLine, { model: model }) : null }), guideX !== undefined ? ((0, jsx_runtime_1.jsx)(VerticalGuide_1.default, { model: model, coordX: guideX })) : rubberbandOn ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders }) })) : null, anchorPosition ? ((0, jsx_runtime_1.jsx)(ui_1.Menu, { anchorReference: "anchorPosition", anchorPosition: {
75
74
  left: anchorPosition.clientX,
76
75
  top: anchorPosition.clientY,
77
76
  }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, (0, jsx_runtime_1.jsx)(Rubberband_1.default, { model: model, ControlComponent: (0, jsx_runtime_1.jsx)(Scalebar_1.default, { model: model, style: {
@@ -11,14 +11,21 @@ const useStyles = (0, mui_1.makeStyles)()({
11
11
  height: '100%',
12
12
  width: 1,
13
13
  position: 'absolute',
14
- zIndex: 10,
14
+ background: 'red',
15
+ zIndex: 1001,
16
+ },
17
+ tooltipTarget: {
18
+ position: 'sticky',
19
+ width: 1,
15
20
  },
16
21
  });
17
22
  const VerticalGuide = (0, mobx_react_1.observer)(function VerticalGuide({ model, coordX, }) {
18
23
  const { classes } = useStyles();
19
- return ((0, jsx_runtime_1.jsx)(material_1.Tooltip, { open: true, placement: "top", title: (0, util_1.stringify)(model.pxToBp(coordX)), arrow: true, children: (0, jsx_runtime_1.jsx)("div", { className: classes.guide, style: {
20
- left: coordX,
21
- background: 'red',
22
- } }) }));
24
+ const { stickyViewHeaders, rubberbandTop } = model;
25
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Tooltip, { open: true, placement: "top", title: (0, util_1.stringify)(model.pxToBp(coordX)), arrow: true, children: (0, jsx_runtime_1.jsx)("div", { className: classes.tooltipTarget, style: {
26
+ left: coordX + 6,
27
+ top: rubberbandTop,
28
+ position: stickyViewHeaders ? 'sticky' : undefined,
29
+ } }) }), (0, jsx_runtime_1.jsx)("div", { className: classes.guide, style: { left: coordX } })] }));
23
30
  });
24
31
  exports.default = VerticalGuide;
@@ -1,5 +1,5 @@
1
1
  import type React from 'react';
2
- import type { BpOffset, ExportSvgOptions, HighlightType, NavLocation } from './types';
2
+ import type { BpOffset, ExportSvgOptions, HighlightType, InitState, NavLocation } from './types';
3
3
  import type PluginManager from '@jbrowse/core/PluginManager';
4
4
  import type BaseResult from '@jbrowse/core/TextSearch/BaseResults';
5
5
  import type { Assembly } from '@jbrowse/core/assemblyManager/assembly';
@@ -30,6 +30,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
30
30
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<HighlightType, HighlightType, HighlightType>>, [undefined]>;
31
31
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
32
32
  showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
33
+ init: import("mobx-state-tree").IType<InitState | undefined, InitState | undefined, InitState | undefined>;
33
34
  }, {
34
35
  width: number;
35
36
  } & {
@@ -51,10 +52,15 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
51
52
  leftOffset: undefined | BpOffset;
52
53
  rightOffset: undefined | BpOffset;
53
54
  } & {
55
+ readonly pinnedTracks: any[];
56
+ readonly unpinnedTracks: any[];
54
57
  readonly trackLabelsSetting: any;
55
58
  readonly width: number;
56
59
  readonly interRegionPaddingWidth: number;
57
60
  readonly assemblyNames: string[];
61
+ readonly stickyViewHeaders: boolean;
62
+ readonly rubberbandTop: number;
63
+ readonly pinnedTracksTop: number;
58
64
  } & {
59
65
  scaleBarDisplayPrefix(): string | undefined;
60
66
  MiniControlsComponent(): React.FC<any>;
@@ -140,6 +146,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
140
146
  setDraggingTrackId(idx?: string): void;
141
147
  setScaleFactor(factor: number): void;
142
148
  clearView(): void;
149
+ setInit(arg?: InitState): void;
143
150
  exportSvg(opts?: ExportSvgOptions): Promise<void>;
144
151
  } & {
145
152
  slide: (viewWidths: number) => void;
@@ -160,7 +167,6 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
160
167
  readonly coarseVisibleLocStrings: string;
161
168
  } & {
162
169
  setCoarseDynamicBlocks(blocks: BlockSet): void;
163
- afterAttach(): void;
164
170
  } & {
165
171
  moveTo(start?: BpOffset, end?: BpOffset): void;
166
172
  navToLocString(input: string, optAssemblyName?: string): Promise<void>;
@@ -206,6 +212,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
206
212
  } | undefined;
207
213
  } & {
208
214
  afterCreate(): void;
215
+ afterAttach(): void;
209
216
  }, import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
210
217
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
211
218
  displayName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -228,7 +235,28 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
228
235
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<HighlightType, HighlightType, HighlightType>>, [undefined]>;
229
236
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
230
237
  showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
231
- }>>, import("mobx-state-tree")._NotCustomized>;
238
+ init: import("mobx-state-tree").IType<InitState | undefined, InitState | undefined, InitState | undefined>;
239
+ }>>, {
240
+ type: string;
241
+ id: string;
242
+ displayName: string | undefined;
243
+ tracks: any[];
244
+ minimized: boolean;
245
+ displayedRegions: Region[];
246
+ offsetPx: number;
247
+ bpPerPx: number;
248
+ hideHeader: boolean;
249
+ hideHeaderOverview: boolean;
250
+ hideNoTracksActive: boolean;
251
+ trackSelectorType: string;
252
+ showCenterLine: boolean;
253
+ showCytobandsSetting: boolean;
254
+ trackLabels: string;
255
+ showGridlines: boolean;
256
+ highlight: HighlightType[];
257
+ colorByCDS: boolean;
258
+ showTrackOutlines: boolean;
259
+ }>;
232
260
  export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>;
233
261
  export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>;
234
262
  export { default as LinearGenomeView, default as ReactComponent, } from './components/LinearGenomeView';
@@ -41,6 +41,7 @@ exports.stateModelFactory = stateModelFactory;
41
41
  const react_1 = require("react");
42
42
  const configuration_1 = require("@jbrowse/core/configuration");
43
43
  const models_1 = require("@jbrowse/core/pluggableElementTypes/models");
44
+ const ui_1 = require("@jbrowse/core/ui");
44
45
  const Icons_1 = require("@jbrowse/core/ui/Icons");
45
46
  const util_1 = require("@jbrowse/core/util");
46
47
  const Base1DUtils_1 = require("@jbrowse/core/util/Base1DUtils");
@@ -49,6 +50,7 @@ const calculateDynamicBlocks_1 = __importDefault(require("@jbrowse/core/util/cal
49
50
  const calculateStaticBlocks_1 = __importDefault(require("@jbrowse/core/util/calculateStaticBlocks"));
50
51
  const tracks_1 = require("@jbrowse/core/util/tracks");
51
52
  const mst_1 = require("@jbrowse/core/util/types/mst");
53
+ const product_core_1 = require("@jbrowse/product-core");
52
54
  const FolderOpen_1 = __importDefault(require("@mui/icons-material/FolderOpen"));
53
55
  const Label_1 = __importDefault(require("@mui/icons-material/Label"));
54
56
  const MenuOpen_1 = __importDefault(require("@mui/icons-material/MenuOpen"));
@@ -91,6 +93,7 @@ function stateModelFactory(pluginManager) {
91
93
  highlight: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.array(mobx_state_tree_1.types.frozen()), []),
92
94
  colorByCDS: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => (0, util_1.localStorageGetBoolean)('lgv-colorByCDS', false)),
93
95
  showTrackOutlines: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => (0, util_1.localStorageGetBoolean)('lgv-showTrackOutlines', true)),
96
+ init: mobx_state_tree_1.types.frozen(),
94
97
  }))
95
98
  .volatile(() => ({
96
99
  volatileWidth: undefined,
@@ -106,6 +109,12 @@ function stateModelFactory(pluginManager) {
106
109
  rightOffset: undefined,
107
110
  }))
108
111
  .views(self => ({
112
+ get pinnedTracks() {
113
+ return self.tracks.filter(t => t.pinned);
114
+ },
115
+ get unpinnedTracks() {
116
+ return self.tracks.filter(t => !t.pinned);
117
+ },
109
118
  get trackLabelsSetting() {
110
119
  const sessionSetting = (0, configuration_1.getConf)((0, util_1.getSession)(self), [
111
120
  'LinearGenomeViewPlugin',
@@ -127,6 +136,28 @@ function stateModelFactory(pluginManager) {
127
136
  ...new Set(self.displayedRegions.map(region => region.assemblyName)),
128
137
  ];
129
138
  },
139
+ get stickyViewHeaders() {
140
+ const session = (0, util_1.getSession)(self);
141
+ return (0, product_core_1.isSessionWithMultipleViews)(session)
142
+ ? session.stickyViewHeaders
143
+ : false;
144
+ },
145
+ get rubberbandTop() {
146
+ let pinnedTracksTop = 0;
147
+ if (this.stickyViewHeaders) {
148
+ pinnedTracksTop = ui_1.VIEW_HEADER_HEIGHT;
149
+ if (!self.hideHeader) {
150
+ pinnedTracksTop += consts_1.HEADER_BAR_HEIGHT;
151
+ if (!self.hideHeaderOverview) {
152
+ pinnedTracksTop += consts_1.HEADER_OVERVIEW_HEIGHT;
153
+ }
154
+ }
155
+ }
156
+ return pinnedTracksTop;
157
+ },
158
+ get pinnedTracksTop() {
159
+ return this.rubberbandTop + consts_1.SCALE_BAR_HEIGHT;
160
+ },
130
161
  }))
131
162
  .views(self => ({
132
163
  scaleBarDisplayPrefix() {
@@ -240,32 +271,32 @@ function stateModelFactory(pluginManager) {
240
271
  return results;
241
272
  },
242
273
  rewriteOnClicks(trackType, viewMenuActions) {
243
- viewMenuActions.forEach(action => {
274
+ for (const action of viewMenuActions) {
244
275
  if ('subMenu' in action) {
245
276
  this.rewriteOnClicks(trackType, action.subMenu);
246
277
  }
247
278
  if ('onClick' in action) {
248
279
  const holdOnClick = action.onClick;
249
280
  action.onClick = (...args) => {
250
- self.tracks.forEach(track => {
281
+ for (const track of self.tracks) {
251
282
  if (track.type === trackType) {
252
283
  holdOnClick.apply(track, [track, ...args]);
253
284
  }
254
- });
285
+ }
255
286
  };
256
287
  }
257
- });
288
+ }
258
289
  },
259
290
  get trackTypeActions() {
260
291
  const allActions = new Map();
261
- self.tracks.forEach(track => {
292
+ for (const track of self.tracks) {
262
293
  const trackInMap = allActions.get(track.type);
263
294
  if (!trackInMap) {
264
295
  const viewMenuActions = structuredClone(track.viewMenuActions);
265
296
  this.rewriteOnClicks(track.type, viewMenuActions);
266
297
  allActions.set(track.type, viewMenuActions);
267
298
  }
268
- });
299
+ }
269
300
  return allActions;
270
301
  },
271
302
  }))
@@ -390,11 +421,13 @@ function stateModelFactory(pluginManager) {
390
421
  hideTrack(trackId) {
391
422
  const schema = pluginManager.pluggableConfigSchemaType('track');
392
423
  const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
393
- const t = self.tracks.filter(t => t.configuration === conf);
424
+ const tracks = self.tracks.filter(t => t.configuration === conf);
394
425
  (0, mobx_1.transaction)(() => {
395
- t.forEach(t => self.tracks.remove(t));
426
+ for (const track of tracks) {
427
+ self.tracks.remove(track);
428
+ }
396
429
  });
397
- return t.length;
430
+ return tracks.length;
398
431
  },
399
432
  }))
400
433
  .actions(self => ({
@@ -535,6 +568,9 @@ function stateModelFactory(pluginManager) {
535
568
  self.scrollTo(0);
536
569
  self.zoomTo(10);
537
570
  },
571
+ setInit(arg) {
572
+ self.init = arg;
573
+ },
538
574
  async exportSvg(opts = {}) {
539
575
  const { renderToSvg } = await Promise.resolve().then(() => __importStar(require('./svgcomponents/SVGLinearGenomeView')));
540
576
  const html = await renderToSvg(self, opts);
@@ -755,7 +791,9 @@ function stateModelFactory(pluginManager) {
755
791
  for (const [key, value] of self.trackTypeActions.entries()) {
756
792
  if (value.length) {
757
793
  menuItems.push({ type: 'divider' }, { type: 'subHeader', label: key });
758
- value.forEach(action => menuItems.push(action));
794
+ for (const action of value) {
795
+ menuItems.push(action);
796
+ }
759
797
  }
760
798
  }
761
799
  return menuItems;
@@ -797,20 +835,6 @@ function stateModelFactory(pluginManager) {
797
835
  self.coarseDynamicBlocks = blocks.contentBlocks;
798
836
  self.coarseTotalBp = blocks.totalBp;
799
837
  },
800
- afterAttach() {
801
- (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
802
- if (self.initialized) {
803
- this.setCoarseDynamicBlocks(self.dynamicBlocks);
804
- }
805
- }, { delay: 150 }));
806
- (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
807
- const s = (s) => JSON.stringify(s);
808
- const { showCytobandsSetting, showCenterLine, colorByCDS } = self;
809
- (0, util_1.localStorageSetItem)('lgv-showCytobands', s(showCytobandsSetting));
810
- (0, util_1.localStorageSetItem)('lgv-showCenterLine', s(showCenterLine));
811
- (0, util_1.localStorageSetItem)('lgv-colorByCDS', s(colorByCDS));
812
- }));
813
- },
814
838
  }))
815
839
  .actions(self => ({
816
840
  moveTo(start, end) {
@@ -977,6 +1001,33 @@ function stateModelFactory(pluginManager) {
977
1001
  document.removeEventListener('keydown', handler);
978
1002
  });
979
1003
  },
1004
+ afterAttach() {
1005
+ (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
1006
+ var _a;
1007
+ const { init } = self;
1008
+ if (init) {
1009
+ self
1010
+ .navToLocString(init.loc, init.assembly)
1011
+ .catch((e) => {
1012
+ (0, util_1.getSession)(self).notifyError(`${e}`, e);
1013
+ });
1014
+ (_a = init.tracks) === null || _a === void 0 ? void 0 : _a.map(t => self.showTrack(t));
1015
+ self.setInit(undefined);
1016
+ }
1017
+ }));
1018
+ (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
1019
+ if (self.initialized) {
1020
+ self.setCoarseDynamicBlocks(self.dynamicBlocks);
1021
+ }
1022
+ }, { delay: 150 }));
1023
+ (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
1024
+ const s = (s) => JSON.stringify(s);
1025
+ const { showCytobandsSetting, showCenterLine, colorByCDS } = self;
1026
+ (0, util_1.localStorageSetItem)('lgv-showCytobands', s(showCytobandsSetting));
1027
+ (0, util_1.localStorageSetItem)('lgv-showCenterLine', s(showCenterLine));
1028
+ (0, util_1.localStorageSetItem)('lgv-colorByCDS', s(colorByCDS));
1029
+ }));
1030
+ },
980
1031
  }))
981
1032
  .preProcessSnapshot(snap => {
982
1033
  if (!snap) {
@@ -989,6 +1040,15 @@ function stateModelFactory(pluginManager) {
989
1040
  : [highlight],
990
1041
  ...rest,
991
1042
  };
1043
+ })
1044
+ .postProcessSnapshot(snap => {
1045
+ if (!snap) {
1046
+ return snap;
1047
+ }
1048
+ else {
1049
+ const { init, ...rest } = snap;
1050
+ return rest;
1051
+ }
992
1052
  });
993
1053
  }
994
1054
  var LinearGenomeView_1 = require("./components/LinearGenomeView");
@@ -21,12 +21,12 @@ async function renderToSvg(model, opts) {
21
21
  const session = (0, util_1.getSession)(model);
22
22
  const { allThemes } = session;
23
23
  const theme = allThemes === null || allThemes === void 0 ? void 0 : allThemes()[themeName];
24
- const { width, tracks, showCytobands } = model;
24
+ const { width, pinnedTracks, unpinnedTracks, tracks, showCytobands } = model;
25
25
  const shift = 50;
26
26
  const c = +showCytobands * cytobandHeight;
27
27
  const offset = headerHeight + rulerHeight + c + 10;
28
28
  const height = (0, util_2.totalHeight)(tracks, textHeight, trackLabels) + offset + 100;
29
- const displayResults = await Promise.all(tracks.map(async (track) => {
29
+ const displayResults = await Promise.all([...pinnedTracks, ...unpinnedTracks].map(async (track) => {
30
30
  const display = track.displays[0];
31
31
  await (0, mobx_1.when)(() => !display.renderProps().notReady);
32
32
  return { track, result: await display.renderSvg({ ...opts, theme }) };
@@ -36,3 +36,8 @@ export interface NavLocation {
36
36
  end?: number;
37
37
  assemblyName?: string;
38
38
  }
39
+ export interface InitState {
40
+ loc: string;
41
+ assembly: string;
42
+ tracks?: string[];
43
+ }
@@ -0,0 +1,7 @@
1
+ declare const BlockErrorMessage: ({ model, }: {
2
+ model: {
3
+ error?: unknown;
4
+ reload: () => void;
5
+ };
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ export default BlockErrorMessage;
@@ -6,14 +6,17 @@ import ReportIcon from '@mui/icons-material/Report';
6
6
  import { IconButton, Tooltip } from '@mui/material';
7
7
  import { observer } from 'mobx-react';
8
8
  import BlockMsg from './BlockMsg';
9
- const BlockError = observer(function ({ model }) {
9
+ const BlockErrorMessage = observer(function ({ model, }) {
10
10
  return (_jsx(BlockMsg, { message: `${model.error}`, severity: "error", action: _jsxs(_Fragment, { children: [_jsx(Tooltip, { title: "Reload track", children: _jsx(IconButton, { "data-testid": "reload_button", onClick: () => {
11
11
  model.reload();
12
12
  }, children: _jsx(RefreshIcon, {}) }) }), _jsx(Tooltip, { title: "Show stack trace", children: _jsx(IconButton, { onClick: () => {
13
13
  getSession(model).queueDialog(onClose => [
14
14
  ErrorMessageStackTraceDialog,
15
- { onClose, error: model.error },
15
+ {
16
+ onClose,
17
+ error: model.error,
18
+ },
16
19
  ]);
17
20
  }, children: _jsx(ReportIcon, {}) }) })] }) }));
18
21
  });
19
- export default BlockError;
22
+ export default BlockErrorMessage;