@jbrowse/plugin-linear-genome-view 3.1.0 → 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 (29) hide show
  1. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +9 -9
  2. package/dist/LaunchLinearGenomeView/index.js +9 -5
  3. package/dist/LinearGenomeView/components/OverviewRubberband.js +2 -14
  4. package/dist/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +10 -0
  5. package/dist/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +36 -0
  6. package/dist/LinearGenomeView/components/Rubberband.js +3 -21
  7. package/dist/LinearGenomeView/components/RubberbandSpan.js +6 -20
  8. package/dist/LinearGenomeView/components/RubberbandTooltip.d.ts +5 -0
  9. package/dist/LinearGenomeView/components/RubberbandTooltip.js +28 -0
  10. package/dist/LinearGenomeView/components/TracksContainer.js +2 -2
  11. package/dist/LinearGenomeView/components/VerticalGuide.js +3 -21
  12. package/dist/LinearGenomeView/model.d.ts +27 -3
  13. package/dist/LinearGenomeView/model.js +59 -26
  14. package/dist/LinearGenomeView/types.d.ts +5 -0
  15. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +9 -9
  16. package/esm/LaunchLinearGenomeView/index.js +9 -5
  17. package/esm/LinearGenomeView/components/OverviewRubberband.js +3 -15
  18. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +10 -0
  19. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +34 -0
  20. package/esm/LinearGenomeView/components/Rubberband.js +4 -22
  21. package/esm/LinearGenomeView/components/RubberbandSpan.js +4 -21
  22. package/esm/LinearGenomeView/components/RubberbandTooltip.d.ts +5 -0
  23. package/esm/LinearGenomeView/components/RubberbandTooltip.js +25 -0
  24. package/esm/LinearGenomeView/components/TracksContainer.js +2 -2
  25. package/esm/LinearGenomeView/components/VerticalGuide.js +4 -22
  26. package/esm/LinearGenomeView/model.d.ts +27 -3
  27. package/esm/LinearGenomeView/model.js +59 -26
  28. package/esm/LinearGenomeView/types.d.ts +5 -0
  29. package/package.json +3 -3
@@ -78,14 +78,14 @@ function stateModelFactory() {
78
78
  return (_b = (_a = self.blockState.get(blockKey)) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.getByID(id);
79
79
  },
80
80
  searchFeatureByID(id) {
81
+ var _a;
81
82
  let ret;
82
- self.blockState.forEach(block => {
83
- var _a;
83
+ for (const block of self.blockState.values()) {
84
84
  const val = (_a = block.layout) === null || _a === void 0 ? void 0 : _a.getByID(id);
85
85
  if (val) {
86
86
  ret = val;
87
87
  }
88
- });
88
+ }
89
89
  return ret;
90
90
  },
91
91
  }))
@@ -138,9 +138,9 @@ function stateModelFactory() {
138
138
  self.setError();
139
139
  self.setCurrStatsBpPerPx(0);
140
140
  self.clearFeatureDensityStats();
141
- [...self.blockState.values()].forEach(val => {
141
+ for (const val of self.blockState.values()) {
142
142
  val.doReload();
143
- });
143
+ }
144
144
  superReload();
145
145
  },
146
146
  };
@@ -230,17 +230,17 @@ function stateModelFactory() {
230
230
  if (!view.initialized) {
231
231
  return;
232
232
  }
233
- self.blockDefinitions.contentBlocks.forEach(block => {
233
+ for (const block of self.blockDefinitions.contentBlocks) {
234
234
  blocksPresent[block.key] = true;
235
235
  if (!self.blockState.has(block.key)) {
236
236
  self.addBlock(block.key, block);
237
237
  }
238
- });
239
- self.blockState.forEach((_, key) => {
238
+ }
239
+ for (const key of self.blockState.keys()) {
240
240
  if (!blocksPresent[key]) {
241
241
  self.deleteBlock(key);
242
242
  }
243
- });
243
+ }
244
244
  }));
245
245
  },
246
246
  }))
@@ -20,7 +20,7 @@ export default function LaunchLinearGenomeViewF(pluginManager) {
20
20
  view.setHideHeader(!nav);
21
21
  }
22
22
  if (highlight !== undefined) {
23
- highlight.forEach(async (h) => {
23
+ for (const h of highlight) {
24
24
  const p = parseLocString(h, refName => assemblyManager.isValidRefName(refName, assembly));
25
25
  const { start, end } = p;
26
26
  if (start !== undefined && end !== undefined) {
@@ -31,13 +31,17 @@ export default function LaunchLinearGenomeViewF(pluginManager) {
31
31
  assemblyName: assembly,
32
32
  });
33
33
  }
34
- });
34
+ }
35
35
  }
36
- await handleSelectedRegion({ input: loc, model: view, assembly: asm });
36
+ await handleSelectedRegion({
37
+ input: loc,
38
+ model: view,
39
+ assembly: asm,
40
+ });
37
41
  const idsNotFound = [];
38
- tracks.forEach(track => {
42
+ for (const track of tracks) {
39
43
  tryTrack(view, track, idsNotFound);
40
- });
44
+ }
41
45
  if (idsNotFound.length) {
42
46
  throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
43
47
  }
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from 'react';
3
- import { getSession, stringify } from '@jbrowse/core/util';
4
- import { Tooltip } from '@mui/material';
3
+ import { getSession } from '@jbrowse/core/util';
5
4
  import { observer } from 'mobx-react';
6
5
  import { makeStyles } from 'tss-react/mui';
6
+ import OverviewRubberbandHoverTooltip from './OverviewRubberbandHoverTooltip';
7
7
  import RubberbandSpan from './RubberbandSpan';
8
8
  import { getRelativeX } from './util';
9
9
  const useStyles = makeStyles()({
@@ -22,18 +22,6 @@ const useStyles = makeStyles()({
22
22
  position: 'relative',
23
23
  },
24
24
  });
25
- const HoverTooltip = observer(function ({ model, open, guideX, overview, }) {
26
- var _a;
27
- const { classes } = useStyles();
28
- const { cytobandOffset } = model;
29
- const { assemblyManager } = getSession(model);
30
- const px = overview.pxToBp(guideX - cytobandOffset);
31
- const assembly = assemblyManager.get(px.assemblyName);
32
- const cytoband = (_a = assembly === null || assembly === void 0 ? void 0 : assembly.cytobands) === null || _a === void 0 ? void 0 : _a.find(f => px.coord > f.get('start') &&
33
- px.coord < f.get('end') &&
34
- px.refName === assembly.getCanonicalRefName(f.get('refName')));
35
- return (_jsx(Tooltip, { open: open, placement: "top", title: [stringify(px), cytoband === null || cytoband === void 0 ? void 0 : cytoband.get('name')].join(' '), arrow: true, children: _jsx("div", { className: classes.guide, style: { left: guideX } }) }));
36
- });
37
25
  const OverviewRubberband = observer(function OverviewRubberband({ model, overview, ControlComponent = _jsx("div", {}), }) {
38
26
  const { cytobandOffset } = model;
39
27
  const [startX, setStartX] = useState();
@@ -103,7 +91,7 @@ const OverviewRubberband = observer(function OverviewRubberband({ model, overvie
103
91
  setGuideX(undefined);
104
92
  }
105
93
  if (startX === undefined) {
106
- return (_jsxs("div", { className: classes.rel, children: [guideX !== undefined ? (_jsx(HoverTooltip, { model: model, open: !mouseDragging, overview: overview, guideX: guideX })) : null, _jsx("div", { className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove, children: ControlComponent })] }));
94
+ return (_jsxs("div", { className: classes.rel, children: [guideX !== undefined ? (_jsx(OverviewRubberbandHoverTooltip, { model: model, open: !mouseDragging, overview: overview, guideX: guideX })) : null, _jsx("div", { className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove, children: ControlComponent })] }));
107
95
  }
108
96
  let left = startX || 0;
109
97
  let width = 0;
@@ -0,0 +1,10 @@
1
+ import type { LinearGenomeViewModel } from '..';
2
+ import type { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel';
3
+ type LGV = LinearGenomeViewModel;
4
+ declare const OverviewRubberbandHoverTooltip: ({ model, open, guideX, overview, }: {
5
+ model: LGV;
6
+ open: boolean;
7
+ guideX: number;
8
+ overview: Base1DViewModel;
9
+ }) => import("react/jsx-runtime").JSX.Element;
10
+ export default OverviewRubberbandHoverTooltip;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { getSession, stringify } from '@jbrowse/core/util';
3
+ import { Tooltip } from '@mui/material';
4
+ import { observer } from 'mobx-react';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ const useStyles = makeStyles()({
7
+ rubberbandControl: {
8
+ cursor: 'crosshair',
9
+ width: '100%',
10
+ minHeight: 8,
11
+ },
12
+ guide: {
13
+ pointerEvents: 'none',
14
+ height: '100%',
15
+ width: 1,
16
+ position: 'absolute',
17
+ },
18
+ rel: {
19
+ position: 'relative',
20
+ },
21
+ });
22
+ const OverviewRubberbandHoverTooltip = observer(function ({ model, open, guideX, overview, }) {
23
+ var _a;
24
+ const { classes } = useStyles();
25
+ const { cytobandOffset } = model;
26
+ const { assemblyManager } = getSession(model);
27
+ const px = overview.pxToBp(guideX - cytobandOffset);
28
+ const assembly = assemblyManager.get(px.assemblyName);
29
+ const cytoband = (_a = assembly === null || assembly === void 0 ? void 0 : assembly.cytobands) === null || _a === void 0 ? void 0 : _a.find(f => px.coord > f.get('start') &&
30
+ px.coord < f.get('end') &&
31
+ px.refName === assembly.getCanonicalRefName(f.get('refName')));
32
+ return (_jsx(Tooltip, { open: open, placement: "top", title: [stringify(px), cytoband === null || cytoband === void 0 ? void 0 : cytoband.get('name')].join(' '), arrow: true, children: _jsx("div", { className: classes.guide, style: { left: guideX } }) }));
33
+ });
34
+ export default OverviewRubberbandHoverTooltip;
@@ -1,14 +1,11 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useRef } from 'react';
3
- import { Menu, VIEW_HEADER_HEIGHT } from '@jbrowse/core/ui';
4
- import { getSession } from '@jbrowse/core/util';
5
- import { isSessionWithMultipleViews } from '@jbrowse/product-core';
3
+ import { Menu } from '@jbrowse/core/ui';
6
4
  import { observer } from 'mobx-react';
7
5
  import { makeStyles } from 'tss-react/mui';
8
6
  import RubberbandSpan from './RubberbandSpan';
9
7
  import VerticalGuide from './VerticalGuide';
10
8
  import { useRangeSelect } from './useRangeSelect';
11
- import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT } from '../consts';
12
9
  const useStyles = makeStyles()({
13
10
  rubberbandControl: {
14
11
  cursor: 'crosshair',
@@ -20,28 +17,13 @@ const useStyles = makeStyles()({
20
17
  const Rubberband = observer(function ({ model, ControlComponent = _jsx("div", {}), }) {
21
18
  const ref = useRef(null);
22
19
  const { classes } = useStyles();
23
- const session = getSession(model);
20
+ const { stickyViewHeaders, rubberbandTop } = model;
24
21
  const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown, mouseOut, } = useRangeSelect(ref, model);
25
- let stickyViewHeaders = false;
26
- if (isSessionWithMultipleViews(session)) {
27
- ;
28
- ({ stickyViewHeaders } = session);
29
- }
30
- let rubberbandControlTop = 0;
31
- if (stickyViewHeaders) {
32
- rubberbandControlTop = VIEW_HEADER_HEIGHT;
33
- if (!model.hideHeader) {
34
- rubberbandControlTop += HEADER_BAR_HEIGHT;
35
- if (!model.hideHeaderOverview) {
36
- rubberbandControlTop += HEADER_OVERVIEW_HEIGHT;
37
- }
38
- }
39
- }
40
- return (_jsxs(_Fragment, { children: [guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandControlTop, sticky: stickyViewHeaders })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
22
+ return (_jsxs(_Fragment, { children: [guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
41
23
  left: anchorPosition.clientX,
42
24
  top: anchorPosition.clientY,
43
25
  }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, _jsx("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, style: {
44
- top: rubberbandControlTop,
26
+ top: rubberbandTop,
45
27
  position: stickyViewHeaders ? 'sticky' : undefined,
46
28
  }, ref: ref, onMouseDown: mouseDown, onMouseMove: mouseMove, onMouseOut: mouseOut, children: ControlComponent })] }));
47
29
  });
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
3
  import { stringify, toLocale } from '@jbrowse/core/util';
4
- import { Popover, Typography, alpha } from '@mui/material';
4
+ import { Typography, alpha } from '@mui/material';
5
5
  import { makeStyles } from 'tss-react/mui';
6
+ import RubberbandTooltip from './RubberbandTooltip';
6
7
  const useStyles = makeStyles()(theme => {
7
8
  const { tertiary } = theme.palette;
8
9
  const background = alpha(tertiary.light, 0.7);
@@ -20,32 +21,14 @@ const useStyles = makeStyles()(theme => {
20
21
  minHeight: 8,
21
22
  },
22
23
  rubberbandText: {
23
- color: tertiary.contrastText,
24
- },
25
- popover: {
26
- mouseEvents: 'none',
27
- cursor: 'crosshair',
28
- },
29
- paper: {
30
- paddingLeft: theme.spacing(1),
31
- paddingRight: theme.spacing(1),
24
+ color: theme.palette.tertiary.contrastText,
32
25
  },
33
26
  };
34
27
  });
35
- function Tooltip({ anchorEl, side, text, }) {
36
- const { classes } = useStyles();
37
- return (_jsx(Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: anchorEl, anchorOrigin: {
38
- vertical: 'top',
39
- horizontal: side === 'left' ? 'right' : 'left',
40
- }, transformOrigin: {
41
- vertical: 'bottom',
42
- horizontal: side === 'left' ? 'left' : 'right',
43
- }, keepMounted: true, disableRestoreFocus: true, children: _jsx(Typography, { children: text }) }));
44
- }
45
28
  export default function RubberbandSpan({ leftBpOffset, rightBpOffset, numOfBpSelected, left, width, top = 0, sticky = false, }) {
46
29
  const { classes } = useStyles();
47
30
  const [anchorEl, setAnchorEl] = useState(null);
48
- return (_jsxs(_Fragment, { children: [anchorEl ? (_jsxs(_Fragment, { children: [_jsx(Tooltip, { side: "left", anchorEl: anchorEl, text: stringify(leftBpOffset) }), _jsx(Tooltip, { side: "right", anchorEl: anchorEl, text: stringify(rightBpOffset) })] })) : null, _jsx("div", { className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? (_jsxs(Typography, { ref: el => {
31
+ return (_jsxs(_Fragment, { children: [anchorEl ? (_jsxs(_Fragment, { children: [_jsx(RubberbandTooltip, { side: "left", anchorEl: anchorEl, text: stringify(leftBpOffset) }), _jsx(RubberbandTooltip, { side: "right", anchorEl: anchorEl, text: stringify(rightBpOffset) })] })) : null, _jsx("div", { className: classes.rubberband, style: { left, width }, children: numOfBpSelected ? (_jsxs(Typography, { ref: el => {
49
32
  setAnchorEl(el);
50
33
  }, variant: "h6", className: classes.rubberbandText, style: {
51
34
  top,
@@ -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,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Popover, Typography } from '@mui/material';
3
+ import { makeStyles } from 'tss-react/mui';
4
+ const useStyles = makeStyles()(theme => {
5
+ return {
6
+ popover: {
7
+ mouseEvents: 'none',
8
+ cursor: 'crosshair',
9
+ },
10
+ paper: {
11
+ paddingLeft: theme.spacing(1),
12
+ paddingRight: theme.spacing(1),
13
+ },
14
+ };
15
+ });
16
+ export default function RubberbandTooltip({ anchorEl, side, text, }) {
17
+ const { classes } = useStyles();
18
+ return (_jsx(Popover, { className: classes.popover, classes: { paper: classes.paper }, open: true, anchorEl: anchorEl, anchorOrigin: {
19
+ vertical: 'top',
20
+ horizontal: side === 'left' ? 'left' : 'right',
21
+ }, transformOrigin: {
22
+ vertical: 'bottom',
23
+ horizontal: side === 'left' ? 'right' : 'left',
24
+ }, keepMounted: true, disableRestoreFocus: true, children: _jsx(Typography, { children: text }) }));
25
+ }
@@ -24,7 +24,7 @@ const TracksContainer = observer(function TracksContainer({ children, model, })
24
24
  const { classes } = useStyles();
25
25
  const { pluginManager } = getEnv(model);
26
26
  const { mouseDown: mouseDown1, mouseUp } = useSideScroll(model);
27
- const { stickyViewHeaders, pinnedTracksTop, showGridlines, showCenterLine } = model;
27
+ const { stickyViewHeaders, rubberbandTop, showGridlines, showCenterLine } = model;
28
28
  const ref = useRef(null);
29
29
  const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown: mouseDown2, } = useRangeSelect(ref, model, true);
30
30
  useWheelScroll(ref, model);
@@ -32,7 +32,7 @@ const TracksContainer = observer(function TracksContainer({ children, model, })
32
32
  return (_jsxs("div", { ref: ref, "data-testid": "tracksContainer", className: classes.tracksContainer, onMouseDown: event => {
33
33
  mouseDown1(event);
34
34
  mouseDown2(event);
35
- }, onMouseMove: mouseMove, onMouseUp: mouseUp, children: [showGridlines ? _jsx(Gridlines, { model: model }) : null, _jsx(Suspense, { fallback: null, children: showCenterLine ? _jsx(CenterLine, { model: model }) : null }), guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(Suspense, { fallback: null, children: _jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: pinnedTracksTop, sticky: stickyViewHeaders }) })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
35
+ }, onMouseMove: mouseMove, onMouseUp: mouseUp, children: [showGridlines ? _jsx(Gridlines, { model: model }) : null, _jsx(Suspense, { fallback: null, children: showCenterLine ? _jsx(CenterLine, { model: model }) : null }), guideX !== undefined ? (_jsx(VerticalGuide, { model: model, coordX: guideX })) : rubberbandOn ? (_jsx(Suspense, { fallback: null, children: _jsx(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, numOfBpSelected: numOfBpSelected, width: width, left: left, top: rubberbandTop, sticky: stickyViewHeaders }) })) : null, anchorPosition ? (_jsx(Menu, { anchorReference: "anchorPosition", anchorPosition: {
36
36
  left: anchorPosition.clientX,
37
37
  top: anchorPosition.clientY,
38
38
  }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, _jsx(Rubberband, { model: model, ControlComponent: _jsx(Scalebar, { model: model, style: {
@@ -1,11 +1,8 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { VIEW_HEADER_HEIGHT } from '@jbrowse/core/ui';
3
- import { getSession, stringify } from '@jbrowse/core/util';
4
- import { isSessionWithMultipleViews } from '@jbrowse/product-core';
2
+ import { stringify } from '@jbrowse/core/util';
5
3
  import { Tooltip } from '@mui/material';
6
4
  import { observer } from 'mobx-react';
7
5
  import { makeStyles } from 'tss-react/mui';
8
- import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT } from '../consts';
9
6
  const useStyles = makeStyles()({
10
7
  guide: {
11
8
  pointerEvents: 'none',
@@ -13,7 +10,7 @@ const useStyles = makeStyles()({
13
10
  width: 1,
14
11
  position: 'absolute',
15
12
  background: 'red',
16
- zIndex: 4,
13
+ zIndex: 1001,
17
14
  },
18
15
  tooltipTarget: {
19
16
  position: 'sticky',
@@ -22,25 +19,10 @@ const useStyles = makeStyles()({
22
19
  });
23
20
  const VerticalGuide = observer(function VerticalGuide({ model, coordX, }) {
24
21
  const { classes } = useStyles();
25
- const session = getSession(model);
26
- let stickyViewHeaders = false;
27
- if (isSessionWithMultipleViews(session)) {
28
- ;
29
- ({ stickyViewHeaders } = session);
30
- }
31
- let tooltipTop = 0;
32
- if (stickyViewHeaders) {
33
- tooltipTop = VIEW_HEADER_HEIGHT;
34
- if (!model.hideHeader) {
35
- tooltipTop += HEADER_BAR_HEIGHT;
36
- if (!model.hideHeaderOverview) {
37
- tooltipTop += HEADER_OVERVIEW_HEIGHT;
38
- }
39
- }
40
- }
22
+ const { stickyViewHeaders, rubberbandTop } = model;
41
23
  return (_jsxs(_Fragment, { children: [_jsx(Tooltip, { open: true, placement: "top", title: stringify(model.pxToBp(coordX)), arrow: true, children: _jsx("div", { className: classes.tooltipTarget, style: {
42
24
  left: coordX + 6,
43
- top: tooltipTop,
25
+ top: rubberbandTop,
44
26
  position: stickyViewHeaders ? 'sticky' : undefined,
45
27
  } }) }), _jsx("div", { className: classes.guide, style: { left: coordX } })] }));
46
28
  });
@@ -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
  } & {
@@ -58,6 +59,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
58
59
  readonly interRegionPaddingWidth: number;
59
60
  readonly assemblyNames: string[];
60
61
  readonly stickyViewHeaders: boolean;
62
+ readonly rubberbandTop: number;
61
63
  readonly pinnedTracksTop: number;
62
64
  } & {
63
65
  scaleBarDisplayPrefix(): string | undefined;
@@ -144,6 +146,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
144
146
  setDraggingTrackId(idx?: string): void;
145
147
  setScaleFactor(factor: number): void;
146
148
  clearView(): void;
149
+ setInit(arg?: InitState): void;
147
150
  exportSvg(opts?: ExportSvgOptions): Promise<void>;
148
151
  } & {
149
152
  slide: (viewWidths: number) => void;
@@ -164,7 +167,6 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
164
167
  readonly coarseVisibleLocStrings: string;
165
168
  } & {
166
169
  setCoarseDynamicBlocks(blocks: BlockSet): void;
167
- afterAttach(): void;
168
170
  } & {
169
171
  moveTo(start?: BpOffset, end?: BpOffset): void;
170
172
  navToLocString(input: string, optAssemblyName?: string): Promise<void>;
@@ -210,6 +212,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
210
212
  } | undefined;
211
213
  } & {
212
214
  afterCreate(): void;
215
+ afterAttach(): void;
213
216
  }, import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
214
217
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
215
218
  displayName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -232,7 +235,28 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
232
235
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<HighlightType, HighlightType, HighlightType>>, [undefined]>;
233
236
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
234
237
  showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
235
- }>>, 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
+ }>;
236
260
  export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>;
237
261
  export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>;
238
262
  export { default as LinearGenomeView, default as ReactComponent, } from './components/LinearGenomeView';
@@ -53,6 +53,7 @@ export function stateModelFactory(pluginManager) {
53
53
  highlight: types.optional(types.array(types.frozen()), []),
54
54
  colorByCDS: types.optional(types.boolean, () => localStorageGetBoolean('lgv-colorByCDS', false)),
55
55
  showTrackOutlines: types.optional(types.boolean, () => localStorageGetBoolean('lgv-showTrackOutlines', true)),
56
+ init: types.frozen(),
56
57
  }))
57
58
  .volatile(() => ({
58
59
  volatileWidth: undefined,
@@ -101,10 +102,10 @@ export function stateModelFactory(pluginManager) {
101
102
  ? session.stickyViewHeaders
102
103
  : false;
103
104
  },
104
- get pinnedTracksTop() {
105
+ get rubberbandTop() {
105
106
  let pinnedTracksTop = 0;
106
107
  if (this.stickyViewHeaders) {
107
- pinnedTracksTop = VIEW_HEADER_HEIGHT + SCALE_BAR_HEIGHT;
108
+ pinnedTracksTop = VIEW_HEADER_HEIGHT;
108
109
  if (!self.hideHeader) {
109
110
  pinnedTracksTop += HEADER_BAR_HEIGHT;
110
111
  if (!self.hideHeaderOverview) {
@@ -114,6 +115,9 @@ export function stateModelFactory(pluginManager) {
114
115
  }
115
116
  return pinnedTracksTop;
116
117
  },
118
+ get pinnedTracksTop() {
119
+ return this.rubberbandTop + SCALE_BAR_HEIGHT;
120
+ },
117
121
  }))
118
122
  .views(self => ({
119
123
  scaleBarDisplayPrefix() {
@@ -227,32 +231,32 @@ export function stateModelFactory(pluginManager) {
227
231
  return results;
228
232
  },
229
233
  rewriteOnClicks(trackType, viewMenuActions) {
230
- viewMenuActions.forEach(action => {
234
+ for (const action of viewMenuActions) {
231
235
  if ('subMenu' in action) {
232
236
  this.rewriteOnClicks(trackType, action.subMenu);
233
237
  }
234
238
  if ('onClick' in action) {
235
239
  const holdOnClick = action.onClick;
236
240
  action.onClick = (...args) => {
237
- self.tracks.forEach(track => {
241
+ for (const track of self.tracks) {
238
242
  if (track.type === trackType) {
239
243
  holdOnClick.apply(track, [track, ...args]);
240
244
  }
241
- });
245
+ }
242
246
  };
243
247
  }
244
- });
248
+ }
245
249
  },
246
250
  get trackTypeActions() {
247
251
  const allActions = new Map();
248
- self.tracks.forEach(track => {
252
+ for (const track of self.tracks) {
249
253
  const trackInMap = allActions.get(track.type);
250
254
  if (!trackInMap) {
251
255
  const viewMenuActions = structuredClone(track.viewMenuActions);
252
256
  this.rewriteOnClicks(track.type, viewMenuActions);
253
257
  allActions.set(track.type, viewMenuActions);
254
258
  }
255
- });
259
+ }
256
260
  return allActions;
257
261
  },
258
262
  }))
@@ -377,11 +381,13 @@ export function stateModelFactory(pluginManager) {
377
381
  hideTrack(trackId) {
378
382
  const schema = pluginManager.pluggableConfigSchemaType('track');
379
383
  const conf = resolveIdentifier(schema, getRoot(self), trackId);
380
- const t = self.tracks.filter(t => t.configuration === conf);
384
+ const tracks = self.tracks.filter(t => t.configuration === conf);
381
385
  transaction(() => {
382
- t.forEach(t => self.tracks.remove(t));
386
+ for (const track of tracks) {
387
+ self.tracks.remove(track);
388
+ }
383
389
  });
384
- return t.length;
390
+ return tracks.length;
385
391
  },
386
392
  }))
387
393
  .actions(self => ({
@@ -522,6 +528,9 @@ export function stateModelFactory(pluginManager) {
522
528
  self.scrollTo(0);
523
529
  self.zoomTo(10);
524
530
  },
531
+ setInit(arg) {
532
+ self.init = arg;
533
+ },
525
534
  async exportSvg(opts = {}) {
526
535
  const { renderToSvg } = await import('./svgcomponents/SVGLinearGenomeView');
527
536
  const html = await renderToSvg(self, opts);
@@ -742,7 +751,9 @@ export function stateModelFactory(pluginManager) {
742
751
  for (const [key, value] of self.trackTypeActions.entries()) {
743
752
  if (value.length) {
744
753
  menuItems.push({ type: 'divider' }, { type: 'subHeader', label: key });
745
- value.forEach(action => menuItems.push(action));
754
+ for (const action of value) {
755
+ menuItems.push(action);
756
+ }
746
757
  }
747
758
  }
748
759
  return menuItems;
@@ -784,20 +795,6 @@ export function stateModelFactory(pluginManager) {
784
795
  self.coarseDynamicBlocks = blocks.contentBlocks;
785
796
  self.coarseTotalBp = blocks.totalBp;
786
797
  },
787
- afterAttach() {
788
- addDisposer(self, autorun(() => {
789
- if (self.initialized) {
790
- this.setCoarseDynamicBlocks(self.dynamicBlocks);
791
- }
792
- }, { delay: 150 }));
793
- addDisposer(self, autorun(() => {
794
- const s = (s) => JSON.stringify(s);
795
- const { showCytobandsSetting, showCenterLine, colorByCDS } = self;
796
- localStorageSetItem('lgv-showCytobands', s(showCytobandsSetting));
797
- localStorageSetItem('lgv-showCenterLine', s(showCenterLine));
798
- localStorageSetItem('lgv-colorByCDS', s(colorByCDS));
799
- }));
800
- },
801
798
  }))
802
799
  .actions(self => ({
803
800
  moveTo(start, end) {
@@ -964,6 +961,33 @@ export function stateModelFactory(pluginManager) {
964
961
  document.removeEventListener('keydown', handler);
965
962
  });
966
963
  },
964
+ afterAttach() {
965
+ addDisposer(self, autorun(() => {
966
+ var _a;
967
+ const { init } = self;
968
+ if (init) {
969
+ self
970
+ .navToLocString(init.loc, init.assembly)
971
+ .catch((e) => {
972
+ getSession(self).notifyError(`${e}`, e);
973
+ });
974
+ (_a = init.tracks) === null || _a === void 0 ? void 0 : _a.map(t => self.showTrack(t));
975
+ self.setInit(undefined);
976
+ }
977
+ }));
978
+ addDisposer(self, autorun(() => {
979
+ if (self.initialized) {
980
+ self.setCoarseDynamicBlocks(self.dynamicBlocks);
981
+ }
982
+ }, { delay: 150 }));
983
+ addDisposer(self, autorun(() => {
984
+ const s = (s) => JSON.stringify(s);
985
+ const { showCytobandsSetting, showCenterLine, colorByCDS } = self;
986
+ localStorageSetItem('lgv-showCytobands', s(showCytobandsSetting));
987
+ localStorageSetItem('lgv-showCenterLine', s(showCenterLine));
988
+ localStorageSetItem('lgv-colorByCDS', s(colorByCDS));
989
+ }));
990
+ },
967
991
  }))
968
992
  .preProcessSnapshot(snap => {
969
993
  if (!snap) {
@@ -976,6 +1000,15 @@ export function stateModelFactory(pluginManager) {
976
1000
  : [highlight],
977
1001
  ...rest,
978
1002
  };
1003
+ })
1004
+ .postProcessSnapshot(snap => {
1005
+ if (!snap) {
1006
+ return snap;
1007
+ }
1008
+ else {
1009
+ const { init, ...rest } = snap;
1010
+ return rest;
1011
+ }
979
1012
  });
980
1013
  }
981
1014
  export { default as LinearGenomeView, default as ReactComponent, } from './components/LinearGenomeView';
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-linear-genome-view",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "JBrowse 2 linear genome view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -38,7 +38,7 @@
38
38
  "useSrc": "node ../../scripts/useSrc.js"
39
39
  },
40
40
  "dependencies": {
41
- "@jbrowse/core": "^3.1.0",
41
+ "@jbrowse/core": "^3.2.0",
42
42
  "@mui/icons-material": "^6.0.0",
43
43
  "@mui/material": "^6.0.0",
44
44
  "@types/file-saver": "^2.0.1",
@@ -58,5 +58,5 @@
58
58
  "access": "public"
59
59
  },
60
60
  "module": "esm/index.js",
61
- "gitHead": "91492049ddea0aed90eb24d3c066c2d9f5a6b189"
61
+ "gitHead": "c750e3f56706a490c19ba75abd807fec5e38aebf"
62
62
  }