@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
@@ -3,6 +3,7 @@ import { forwardRef } from 'react';
3
3
  import { Paper } from '@mui/material';
4
4
  import { observer } from 'mobx-react';
5
5
  import { makeStyles } from 'tss-react/mui';
6
+ import Gridlines from './Gridlines';
6
7
  import ScalebarCoordinateLabels from './ScalebarCoordinateLabels';
7
8
  import ScalebarRefNameLabels from './ScalebarRefNameLabels';
8
9
  const useStyles = makeStyles()({
@@ -12,7 +13,6 @@ const useStyles = makeStyles()({
12
13
  },
13
14
  zoomContainer: {
14
15
  position: 'relative',
15
- zIndex: 1,
16
16
  },
17
17
  scalebar: {
18
18
  position: 'absolute',
@@ -24,7 +24,7 @@ const Scalebar = observer(forwardRef(function Scalebar2({ model, style, classNam
24
24
  const { classes, cx } = useStyles();
25
25
  const { staticBlocks, offsetPx, scaleFactor } = model;
26
26
  const offsetLeft = staticBlocks.offsetPx - offsetPx;
27
- return (_jsxs(Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined", ref: ref, style: style, ...other, children: [_jsx("div", { className: classes.zoomContainer, style: {
27
+ return (_jsxs(Paper, { "data-resizer": "true", className: cx(classes.container, className), variant: "outlined", ref: ref, style: style, ...other, children: [_jsx(Gridlines, { model: model, offset: 1 }), _jsx("div", { className: classes.zoomContainer, style: {
28
28
  transform: scaleFactor !== 1 ? `scaleX(${scaleFactor})` : undefined,
29
29
  }, children: _jsx("div", { className: classes.scalebar, style: {
30
30
  left: offsetLeft - 1,
@@ -6,31 +6,36 @@ import { Paper } from '@mui/material';
6
6
  import { observer } from 'mobx-react';
7
7
  import { isAlive } from 'mobx-state-tree';
8
8
  import { makeStyles } from 'tss-react/mui';
9
+ import Gridlines from './Gridlines';
9
10
  import TrackLabelContainer from './TrackLabelContainer';
10
11
  import TrackRenderingContainer from './TrackRenderingContainer';
11
12
  const useStyles = makeStyles()({
12
13
  root: {
13
14
  marginTop: 2,
15
+ overflow: 'hidden',
16
+ position: 'relative',
17
+ },
18
+ unpinnedTrack: {
19
+ background: 'none',
14
20
  },
15
21
  resizeHandle: {
16
22
  height: 3,
17
23
  boxSizing: 'border-box',
18
24
  position: 'relative',
19
- zIndex: 2,
20
25
  },
21
26
  });
22
27
  const TrackContainer = observer(function ({ model, track, }) {
23
- const { classes } = useStyles();
28
+ const { classes, cx } = useStyles();
24
29
  const display = track.displays[0];
25
30
  const { draggingTrackId, showTrackOutlines } = model;
26
31
  const ref = useRef(null);
27
- return (_jsxs(Paper, { ref: ref, className: classes.root, variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
32
+ return (_jsxs(Paper, { ref: ref, className: cx(classes.root, track.pinned ? null : classes.unpinnedTrack), variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
28
33
  var _a;
29
34
  if (event.detail === 2 && !track.displays[0].featureIdUnderMouse) {
30
35
  const left = ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0;
31
36
  model.zoomTo(model.bpPerPx / 2, event.clientX - left, true);
32
37
  }
33
- }, children: [_jsx(TrackLabelContainer, { track: track, view: model }), _jsx(ErrorBoundary, { FallbackComponent: e => _jsx(ErrorMessage, { error: e.error }), children: _jsx(TrackRenderingContainer, { model: model, track: track, onDragEnter: () => {
38
+ }, children: [track.pinned ? _jsx(Gridlines, { model: model, offset: 1 }) : null, _jsx(TrackLabelContainer, { track: track, view: model }), _jsx(ErrorBoundary, { FallbackComponent: e => _jsx(ErrorMessage, { error: e.error }), children: _jsx(TrackRenderingContainer, { model: model, track: track, onDragEnter: () => {
34
39
  if (isAlive(display) &&
35
40
  draggingTrackId !== undefined &&
36
41
  draggingTrackId !== display.id) {
@@ -29,7 +29,7 @@ const TrackLabel = observer(forwardRef(function TrackLabel2({ track, className }
29
29
  const view = getContainingView(track);
30
30
  const session = getSession(track);
31
31
  const trackConf = track.configuration;
32
- const minimized = track.minimized;
32
+ const { minimized } = track;
33
33
  const trackId = getConf(track, 'trackId');
34
34
  const trackName = getTrackName(trackConf, session);
35
35
  return (_jsxs(Paper, { ref: ref, className: cx(className, classes.root), onClick: event => {
@@ -4,7 +4,7 @@ import { makeStyles } from 'tss-react/mui';
4
4
  import TrackLabel from './TrackLabel';
5
5
  const useStyles = makeStyles()({
6
6
  trackLabel: {
7
- zIndex: 3,
7
+ zIndex: 2,
8
8
  },
9
9
  trackLabelOffset: {
10
10
  position: 'relative',
@@ -8,6 +8,7 @@ import KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrow
8
8
  import KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp';
9
9
  import MinimizeIcon from '@mui/icons-material/Minimize';
10
10
  import MoreVertIcon from '@mui/icons-material/MoreVert';
11
+ import PushPinIcon from '@mui/icons-material/PushPin';
11
12
  import { observer } from 'mobx-react';
12
13
  const TrackLabelMenu = observer(function ({ track, }) {
13
14
  var _a;
@@ -15,7 +16,27 @@ const TrackLabelMenu = observer(function ({ track, }) {
15
16
  const session = getSession(track);
16
17
  const trackConf = track.configuration;
17
18
  const minimized = track.minimized;
19
+ const pinned = track.pinned;
20
+ let lgvHasParentView;
21
+ try {
22
+ getContainingView(view);
23
+ lgvHasParentView = true;
24
+ }
25
+ catch (error) {
26
+ lgvHasParentView = false;
27
+ }
18
28
  const items = [
29
+ ...(lgvHasParentView
30
+ ? []
31
+ : [
32
+ {
33
+ label: pinned ? 'Unpin track' : 'Pin track',
34
+ icon: PushPinIcon,
35
+ onClick: () => {
36
+ track.setPinned(!pinned);
37
+ },
38
+ },
39
+ ]),
19
40
  {
20
41
  label: 'Track order',
21
42
  type: 'subMenu',
@@ -17,7 +17,6 @@ const useStyles = makeStyles()({
17
17
  whiteSpace: 'nowrap',
18
18
  position: 'relative',
19
19
  background: 'none',
20
- zIndex: 2,
21
20
  },
22
21
  });
23
22
  const TrackRenderingContainer = observer(function ({ model, track, onDragEnter, }) {
@@ -18,22 +18,21 @@ const RubberbandSpan = lazy(() => import('./RubberbandSpan'));
18
18
  const useStyles = makeStyles()({
19
19
  tracksContainer: {
20
20
  position: 'relative',
21
- overflow: 'hidden',
22
21
  },
23
22
  });
24
23
  const TracksContainer = observer(function TracksContainer({ children, model, }) {
25
24
  const { classes } = useStyles();
26
25
  const { pluginManager } = getEnv(model);
27
26
  const { mouseDown: mouseDown1, mouseUp } = useSideScroll(model);
28
- const { showGridlines, showCenterLine } = model;
27
+ const { stickyViewHeaders, rubberbandTop, showGridlines, showCenterLine } = model;
29
28
  const ref = useRef(null);
30
29
  const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, open, handleMenuItemClick, handleClose, mouseMove, mouseDown: mouseDown2, } = useRangeSelect(ref, model, true);
31
30
  useWheelScroll(ref, model);
32
31
  const additional = pluginManager.evaluateExtensionPoint('LinearGenomeView-TracksContainerComponent', undefined, { model });
33
- return (_jsxs("div", { ref: ref, "data-testid": "trackContainer", className: classes.tracksContainer, onMouseDown: event => {
32
+ return (_jsxs("div", { ref: ref, "data-testid": "tracksContainer", className: classes.tracksContainer, onMouseDown: event => {
34
33
  mouseDown1(event);
35
34
  mouseDown2(event);
36
- }, 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 }) })) : 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: {
37
36
  left: anchorPosition.clientX,
38
37
  top: anchorPosition.clientY,
39
38
  }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null, _jsx(Rubberband, { model: model, ControlComponent: _jsx(Scalebar, { model: model, style: {
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { stringify } from '@jbrowse/core/util';
3
3
  import { Tooltip } from '@mui/material';
4
4
  import { observer } from 'mobx-react';
@@ -9,14 +9,21 @@ const useStyles = makeStyles()({
9
9
  height: '100%',
10
10
  width: 1,
11
11
  position: 'absolute',
12
- zIndex: 10,
12
+ background: 'red',
13
+ zIndex: 1001,
14
+ },
15
+ tooltipTarget: {
16
+ position: 'sticky',
17
+ width: 1,
13
18
  },
14
19
  });
15
20
  const VerticalGuide = observer(function VerticalGuide({ model, coordX, }) {
16
21
  const { classes } = useStyles();
17
- return (_jsx(Tooltip, { open: true, placement: "top", title: stringify(model.pxToBp(coordX)), arrow: true, children: _jsx("div", { className: classes.guide, style: {
18
- left: coordX,
19
- background: 'red',
20
- } }) }));
22
+ const { stickyViewHeaders, rubberbandTop } = model;
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: {
24
+ left: coordX + 6,
25
+ top: rubberbandTop,
26
+ position: stickyViewHeaders ? 'sticky' : undefined,
27
+ } }) }), _jsx("div", { className: classes.guide, style: { left: coordX } })] }));
21
28
  });
22
29
  export 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';
@@ -1,6 +1,7 @@
1
1
  import { lazy } from 'react';
2
2
  import { getConf } from '@jbrowse/core/configuration';
3
3
  import { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models';
4
+ import { VIEW_HEADER_HEIGHT } from '@jbrowse/core/ui';
4
5
  import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
5
6
  import { assembleLocString, clamp, findLast, getSession, isSessionModelWithWidgets, isSessionWithAddTracks, localStorageGetBoolean, localStorageGetItem, localStorageSetItem, measureText, springAnimate, sum, } from '@jbrowse/core/util';
6
7
  import { bpToPx, moveTo, pxToBp } from '@jbrowse/core/util/Base1DUtils';
@@ -9,6 +10,7 @@ import calculateDynamicBlocks from '@jbrowse/core/util/calculateDynamicBlocks';
9
10
  import calculateStaticBlocks from '@jbrowse/core/util/calculateStaticBlocks';
10
11
  import { getParentRenderProps } from '@jbrowse/core/util/tracks';
11
12
  import { ElementId } from '@jbrowse/core/util/types/mst';
13
+ import { isSessionWithMultipleViews } from '@jbrowse/product-core';
12
14
  import FolderOpenIcon from '@mui/icons-material/FolderOpen';
13
15
  import LabelIcon from '@mui/icons-material/Label';
14
16
  import MenuOpenIcon from '@mui/icons-material/MenuOpen';
@@ -51,6 +53,7 @@ export function stateModelFactory(pluginManager) {
51
53
  highlight: types.optional(types.array(types.frozen()), []),
52
54
  colorByCDS: types.optional(types.boolean, () => localStorageGetBoolean('lgv-colorByCDS', false)),
53
55
  showTrackOutlines: types.optional(types.boolean, () => localStorageGetBoolean('lgv-showTrackOutlines', true)),
56
+ init: types.frozen(),
54
57
  }))
55
58
  .volatile(() => ({
56
59
  volatileWidth: undefined,
@@ -66,6 +69,12 @@ export function stateModelFactory(pluginManager) {
66
69
  rightOffset: undefined,
67
70
  }))
68
71
  .views(self => ({
72
+ get pinnedTracks() {
73
+ return self.tracks.filter(t => t.pinned);
74
+ },
75
+ get unpinnedTracks() {
76
+ return self.tracks.filter(t => !t.pinned);
77
+ },
69
78
  get trackLabelsSetting() {
70
79
  const sessionSetting = getConf(getSession(self), [
71
80
  'LinearGenomeViewPlugin',
@@ -87,6 +96,28 @@ export function stateModelFactory(pluginManager) {
87
96
  ...new Set(self.displayedRegions.map(region => region.assemblyName)),
88
97
  ];
89
98
  },
99
+ get stickyViewHeaders() {
100
+ const session = getSession(self);
101
+ return isSessionWithMultipleViews(session)
102
+ ? session.stickyViewHeaders
103
+ : false;
104
+ },
105
+ get rubberbandTop() {
106
+ let pinnedTracksTop = 0;
107
+ if (this.stickyViewHeaders) {
108
+ pinnedTracksTop = VIEW_HEADER_HEIGHT;
109
+ if (!self.hideHeader) {
110
+ pinnedTracksTop += HEADER_BAR_HEIGHT;
111
+ if (!self.hideHeaderOverview) {
112
+ pinnedTracksTop += HEADER_OVERVIEW_HEIGHT;
113
+ }
114
+ }
115
+ }
116
+ return pinnedTracksTop;
117
+ },
118
+ get pinnedTracksTop() {
119
+ return this.rubberbandTop + SCALE_BAR_HEIGHT;
120
+ },
90
121
  }))
91
122
  .views(self => ({
92
123
  scaleBarDisplayPrefix() {
@@ -200,32 +231,32 @@ export function stateModelFactory(pluginManager) {
200
231
  return results;
201
232
  },
202
233
  rewriteOnClicks(trackType, viewMenuActions) {
203
- viewMenuActions.forEach(action => {
234
+ for (const action of viewMenuActions) {
204
235
  if ('subMenu' in action) {
205
236
  this.rewriteOnClicks(trackType, action.subMenu);
206
237
  }
207
238
  if ('onClick' in action) {
208
239
  const holdOnClick = action.onClick;
209
240
  action.onClick = (...args) => {
210
- self.tracks.forEach(track => {
241
+ for (const track of self.tracks) {
211
242
  if (track.type === trackType) {
212
243
  holdOnClick.apply(track, [track, ...args]);
213
244
  }
214
- });
245
+ }
215
246
  };
216
247
  }
217
- });
248
+ }
218
249
  },
219
250
  get trackTypeActions() {
220
251
  const allActions = new Map();
221
- self.tracks.forEach(track => {
252
+ for (const track of self.tracks) {
222
253
  const trackInMap = allActions.get(track.type);
223
254
  if (!trackInMap) {
224
255
  const viewMenuActions = structuredClone(track.viewMenuActions);
225
256
  this.rewriteOnClicks(track.type, viewMenuActions);
226
257
  allActions.set(track.type, viewMenuActions);
227
258
  }
228
- });
259
+ }
229
260
  return allActions;
230
261
  },
231
262
  }))
@@ -350,11 +381,13 @@ export function stateModelFactory(pluginManager) {
350
381
  hideTrack(trackId) {
351
382
  const schema = pluginManager.pluggableConfigSchemaType('track');
352
383
  const conf = resolveIdentifier(schema, getRoot(self), trackId);
353
- const t = self.tracks.filter(t => t.configuration === conf);
384
+ const tracks = self.tracks.filter(t => t.configuration === conf);
354
385
  transaction(() => {
355
- t.forEach(t => self.tracks.remove(t));
386
+ for (const track of tracks) {
387
+ self.tracks.remove(track);
388
+ }
356
389
  });
357
- return t.length;
390
+ return tracks.length;
358
391
  },
359
392
  }))
360
393
  .actions(self => ({
@@ -495,6 +528,9 @@ export function stateModelFactory(pluginManager) {
495
528
  self.scrollTo(0);
496
529
  self.zoomTo(10);
497
530
  },
531
+ setInit(arg) {
532
+ self.init = arg;
533
+ },
498
534
  async exportSvg(opts = {}) {
499
535
  const { renderToSvg } = await import('./svgcomponents/SVGLinearGenomeView');
500
536
  const html = await renderToSvg(self, opts);
@@ -715,7 +751,9 @@ export function stateModelFactory(pluginManager) {
715
751
  for (const [key, value] of self.trackTypeActions.entries()) {
716
752
  if (value.length) {
717
753
  menuItems.push({ type: 'divider' }, { type: 'subHeader', label: key });
718
- value.forEach(action => menuItems.push(action));
754
+ for (const action of value) {
755
+ menuItems.push(action);
756
+ }
719
757
  }
720
758
  }
721
759
  return menuItems;
@@ -757,20 +795,6 @@ export function stateModelFactory(pluginManager) {
757
795
  self.coarseDynamicBlocks = blocks.contentBlocks;
758
796
  self.coarseTotalBp = blocks.totalBp;
759
797
  },
760
- afterAttach() {
761
- addDisposer(self, autorun(() => {
762
- if (self.initialized) {
763
- this.setCoarseDynamicBlocks(self.dynamicBlocks);
764
- }
765
- }, { delay: 150 }));
766
- addDisposer(self, autorun(() => {
767
- const s = (s) => JSON.stringify(s);
768
- const { showCytobandsSetting, showCenterLine, colorByCDS } = self;
769
- localStorageSetItem('lgv-showCytobands', s(showCytobandsSetting));
770
- localStorageSetItem('lgv-showCenterLine', s(showCenterLine));
771
- localStorageSetItem('lgv-colorByCDS', s(colorByCDS));
772
- }));
773
- },
774
798
  }))
775
799
  .actions(self => ({
776
800
  moveTo(start, end) {
@@ -937,6 +961,33 @@ export function stateModelFactory(pluginManager) {
937
961
  document.removeEventListener('keydown', handler);
938
962
  });
939
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
+ },
940
991
  }))
941
992
  .preProcessSnapshot(snap => {
942
993
  if (!snap) {
@@ -949,6 +1000,15 @@ export function stateModelFactory(pluginManager) {
949
1000
  : [highlight],
950
1001
  ...rest,
951
1002
  };
1003
+ })
1004
+ .postProcessSnapshot(snap => {
1005
+ if (!snap) {
1006
+ return snap;
1007
+ }
1008
+ else {
1009
+ const { init, ...rest } = snap;
1010
+ return rest;
1011
+ }
952
1012
  });
953
1013
  }
954
1014
  export { default as LinearGenomeView, default as ReactComponent, } from './components/LinearGenomeView';
@@ -14,12 +14,12 @@ export async function renderToSvg(model, opts) {
14
14
  const session = getSession(model);
15
15
  const { allThemes } = session;
16
16
  const theme = allThemes === null || allThemes === void 0 ? void 0 : allThemes()[themeName];
17
- const { width, tracks, showCytobands } = model;
17
+ const { width, pinnedTracks, unpinnedTracks, tracks, showCytobands } = model;
18
18
  const shift = 50;
19
19
  const c = +showCytobands * cytobandHeight;
20
20
  const offset = headerHeight + rulerHeight + c + 10;
21
21
  const height = totalHeight(tracks, textHeight, trackLabels) + offset + 100;
22
- const displayResults = await Promise.all(tracks.map(async (track) => {
22
+ const displayResults = await Promise.all([...pinnedTracks, ...unpinnedTracks].map(async (track) => {
23
23
  const display = track.displays[0];
24
24
  await when(() => !display.renderProps().notReady);
25
25
  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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-linear-genome-view",
3
- "version": "3.0.5",
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.0.5",
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": "a03749efe19e51609922272b845a331897346789"
61
+ "gitHead": "c750e3f56706a490c19ba75abd807fec5e38aebf"
62
62
  }
@@ -1,4 +0,0 @@
1
- declare const BlockError: ({ model }: {
2
- model: any;
3
- }) => import("react/jsx-runtime").JSX.Element;
4
- export default BlockError;
@@ -1,4 +0,0 @@
1
- declare const BlockError: ({ model }: {
2
- model: any;
3
- }) => import("react/jsx-runtime").JSX.Element;
4
- export default BlockError;