@jbrowse/plugin-linear-genome-view 2.12.3 → 2.13.1

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.
@@ -27,16 +27,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = __importStar(require("react"));
30
- const material_1 = require("@mui/material");
31
30
  const mui_1 = require("tss-react/mui");
32
31
  const ui_1 = require("@jbrowse/core/ui");
33
32
  const util_1 = require("@jbrowse/core/util");
34
33
  const mobx_react_1 = require("mobx-react");
35
- // icons
36
- const Icons_1 = require("@jbrowse/core/ui/Icons");
37
34
  const TrackContainer_1 = __importDefault(require("./TrackContainer"));
38
35
  const TracksContainer_1 = __importDefault(require("./TracksContainer"));
39
36
  const ImportForm = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./ImportForm'))));
37
+ const NoTracksActiveButton = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./NoTracksActiveButton'))));
40
38
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
41
39
  note: {
42
40
  textAlign: 'center',
@@ -50,13 +48,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
50
48
  zIndex: 1000,
51
49
  },
52
50
  }));
53
- function NoTracksActive({ model }) {
54
- const { classes } = useStyles();
55
- const { hideNoTracksActive } = model;
56
- return (react_1.default.createElement(material_1.Paper, { className: classes.note }, !hideNoTracksActive ? (react_1.default.createElement(react_1.default.Fragment, null,
57
- react_1.default.createElement(material_1.Typography, null, "No tracks active."),
58
- react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: () => model.activateTrackSelector(), className: classes.top, startIcon: react_1.default.createElement(Icons_1.TrackSelector, null) }, "Open track selector"))) : (react_1.default.createElement("div", { style: { height: '48px' } }))));
59
- }
60
51
  const LinearGenomeView = (0, mobx_react_1.observer)(({ model }) => {
61
52
  const { tracks, error, initialized, hasDisplayedRegions } = model;
62
53
  const ref = (0, react_1.useRef)(null);
@@ -99,6 +90,7 @@ const LinearGenomeView = (0, mobx_react_1.observer)(({ model }) => {
99
90
  } },
100
91
  react_1.default.createElement(HeaderComponent, { model: model }),
101
92
  react_1.default.createElement(MiniControlsComponent, { model: model }),
102
- react_1.default.createElement(TracksContainer_1.default, { model: model }, !tracks.length ? (react_1.default.createElement(NoTracksActive, { model: model })) : (tracks.map(track => (react_1.default.createElement(TrackContainer_1.default, { key: track.id, model: model, track: track })))))));
93
+ react_1.default.createElement(TracksContainer_1.default, { model: model }, !tracks.length ? (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(react_1.default.Fragment, null) },
94
+ react_1.default.createElement(NoTracksActiveButton, { model: model }))) : (tracks.map(track => (react_1.default.createElement(TrackContainer_1.default, { key: track.id, model: model, track: track })))))));
103
95
  });
104
96
  exports.default = LinearGenomeView;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { LinearGenomeViewModel } from '..';
3
+ declare const NoTracksActiveButton: ({ model, }: {
4
+ model: LinearGenomeViewModel;
5
+ }) => React.JSX.Element;
6
+ export default NoTracksActiveButton;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const material_1 = require("@mui/material");
8
+ const mui_1 = require("tss-react/mui");
9
+ const mobx_react_1 = require("mobx-react");
10
+ // icons
11
+ const Icons_1 = require("@jbrowse/core/ui/Icons");
12
+ const useStyles = (0, mui_1.makeStyles)()(theme => ({
13
+ note: {
14
+ textAlign: 'center',
15
+ paddingTop: theme.spacing(1),
16
+ paddingBottom: theme.spacing(1),
17
+ },
18
+ top: {
19
+ zIndex: 1000,
20
+ },
21
+ }));
22
+ const NoTracksActiveButton = (0, mobx_react_1.observer)(function ({ model, }) {
23
+ const { classes } = useStyles();
24
+ const { hideNoTracksActive } = model;
25
+ return (react_1.default.createElement(material_1.Paper, { className: classes.note }, !hideNoTracksActive ? (react_1.default.createElement(react_1.default.Fragment, null,
26
+ react_1.default.createElement(material_1.Typography, null, "No tracks active."),
27
+ react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: () => model.activateTrackSelector(), className: classes.top, startIcon: react_1.default.createElement(Icons_1.TrackSelector, null) }, "Open track selector"))) : (react_1.default.createElement("div", { style: { height: '48px' } }))));
28
+ });
29
+ exports.default = NoTracksActiveButton;
@@ -7,9 +7,9 @@ const material_1 = require("@mui/material");
7
7
  const mui_1 = require("tss-react/mui");
8
8
  const mobx_react_1 = require("mobx-react");
9
9
  const react_1 = __importDefault(require("react"));
10
+ const util_1 = require("@jbrowse/core/util");
10
11
  const Block_1 = require("../../BaseLinearDisplay/components/Block");
11
- const util_1 = require("../util");
12
- const util_2 = require("@jbrowse/core/util");
12
+ const util_2 = require("../util");
13
13
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
14
14
  scalebarContainer: {
15
15
  overflow: 'hidden',
@@ -50,39 +50,45 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
50
50
  background: theme.palette.background.paper,
51
51
  },
52
52
  }));
53
- const RenderedRefNameLabels = (0, mobx_react_1.observer)(({ model }) => {
53
+ const RenderedRefNameLabels = (0, mobx_react_1.observer)(function ({ model }) {
54
54
  const { classes } = useStyles();
55
+ const { staticBlocks, offsetPx, scaleBarDisplayPrefix } = model;
55
56
  // find the block that needs pinning to the left side for context
56
57
  let lastLeftBlock = 0;
57
- model.staticBlocks.forEach((block, i) => {
58
- if (block.offsetPx - model.offsetPx < 0) {
58
+ staticBlocks.forEach((block, i) => {
59
+ if (block.offsetPx - offsetPx < 0) {
59
60
  lastLeftBlock = i;
60
61
  }
61
62
  });
62
- return (react_1.default.createElement(react_1.default.Fragment, null, model.staticBlocks.map((block, index) => {
63
- return block.type === 'ContentBlock' &&
64
- (block.isLeftEndOfDisplayedRegion || index === lastLeftBlock) ? (react_1.default.createElement(material_1.Typography, { key: `refLabel-${block.key}-${index}`, style: {
65
- left: index === lastLeftBlock
66
- ? Math.max(0, -model.offsetPx)
67
- : block.offsetPx - model.offsetPx - 1,
68
- paddingLeft: index === lastLeftBlock ? 0 : 1,
69
- }, className: classes.refLabel, "data-testid": `refLabel-${block.refName}` }, block.refName)) : null;
70
- })));
63
+ const val = scaleBarDisplayPrefix();
64
+ return (react_1.default.createElement(react_1.default.Fragment, null,
65
+ staticBlocks.blocks[0].type !== 'ContentBlock' && val ? (react_1.default.createElement(material_1.Typography, { style: { left: 0, zIndex: 100 }, className: classes.refLabel }, val)) : null,
66
+ staticBlocks.map((block, index) => {
67
+ return block.type === 'ContentBlock' &&
68
+ (block.isLeftEndOfDisplayedRegion || index === lastLeftBlock) ? (react_1.default.createElement(material_1.Typography, { key: `refLabel-${block.key}-${index}`, style: {
69
+ left: index === lastLeftBlock
70
+ ? Math.max(0, -offsetPx)
71
+ : block.offsetPx - offsetPx - 1,
72
+ paddingLeft: index === lastLeftBlock ? 0 : 1,
73
+ }, className: classes.refLabel, "data-testid": `refLabel-${block.refName}` },
74
+ index === lastLeftBlock && val ? `${val}:` : '',
75
+ block.refName)) : null;
76
+ })));
71
77
  });
72
78
  const RenderedBlockTicks = function ({ block, bpPerPx, }) {
73
79
  const { classes } = useStyles();
74
80
  const { reversed, start, end } = block;
75
- const ticks = (0, util_1.makeTicks)(start, end, bpPerPx, true, false);
81
+ const ticks = (0, util_2.makeTicks)(start, end, bpPerPx, true, false);
76
82
  return (react_1.default.createElement(Block_1.ContentBlock, { block: block }, ticks.map(({ type, base }) => {
77
83
  if (type === 'major') {
78
84
  const x = (reversed ? end - base : base - start) / bpPerPx;
79
85
  const baseNumber = base + 1;
80
- return (react_1.default.createElement("div", { key: base, className: classes.tick, style: { left: x } }, baseNumber ? (react_1.default.createElement(material_1.Typography, { className: classes.majorTickLabel }, (0, util_2.getTickDisplayStr)(baseNumber, bpPerPx))) : null));
86
+ return (react_1.default.createElement("div", { key: base, className: classes.tick, style: { left: x } }, baseNumber ? (react_1.default.createElement(material_1.Typography, { className: classes.majorTickLabel }, (0, util_1.getTickDisplayStr)(baseNumber, bpPerPx))) : null));
81
87
  }
82
88
  return null;
83
89
  })));
84
90
  };
85
- const RenderedScalebarLabels = (0, mobx_react_1.observer)(({ model }) => {
91
+ const RenderedScalebarLabels = (0, mobx_react_1.observer)(function ({ model }) {
86
92
  const { staticBlocks, bpPerPx } = model;
87
93
  return (react_1.default.createElement(react_1.default.Fragment, null, staticBlocks.map((block, idx) => {
88
94
  const { key, widthPx } = block;
@@ -49,9 +49,9 @@ const useStyles = (0, mui_1.makeStyles)()({
49
49
  const TrackContainer = (0, mobx_react_1.observer)(function ({ model, track, }) {
50
50
  const { classes } = useStyles();
51
51
  const display = track.displays[0];
52
- const { draggingTrackId } = model;
52
+ const { draggingTrackId, showTrackOutlines } = model;
53
53
  const ref = (0, react_1.useRef)(null);
54
- return (react_1.default.createElement(material_1.Paper, { ref: ref, className: classes.root, variant: "outlined", onClick: event => {
54
+ return (react_1.default.createElement(material_1.Paper, { ref: ref, className: classes.root, variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
55
55
  var _a;
56
56
  if (event.detail === 2 && !track.displays[0].featureIdUnderMouse) {
57
57
  const left = ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0;
@@ -74,6 +74,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
74
74
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
75
75
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<ParsedLocString>, Required<ParsedLocString>, Required<ParsedLocString>>>, [undefined]>;
76
76
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
77
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
77
78
  }, {
78
79
  width: number;
79
80
  } & {
@@ -114,6 +115,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
114
115
  */
115
116
  readonly assemblyNames: string[];
116
117
  } & {
118
+ /**
119
+ * #method
120
+ */
121
+ scaleBarDisplayPrefix(): string;
117
122
  /**
118
123
  * #method
119
124
  */
@@ -216,6 +221,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
216
221
  */
217
222
  readonly trackTypeActions: Map<string, MenuItem[]>;
218
223
  } & {
224
+ /**
225
+ * #action
226
+ */
227
+ setShowTrackOutlines(arg: boolean): void;
219
228
  /**
220
229
  * #action
221
230
  */
@@ -615,6 +624,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
615
624
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
616
625
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<ParsedLocString>, Required<ParsedLocString>, Required<ParsedLocString>>>, [undefined]>;
617
626
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
627
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
618
628
  }>>, import("mobx-state-tree")._NotCustomized>;
619
629
  export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>;
620
630
  export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>;
@@ -177,6 +177,11 @@ function stateModelFactory(pluginManager) {
177
177
  * color by CDS
178
178
  */
179
179
  colorByCDS: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => Boolean(JSON.parse((0, util_1.localStorageGetItem)('lgv-colorByCDS') || 'false'))),
180
+ /**
181
+ * #property
182
+ * color by CDS
183
+ */
184
+ showTrackOutlines: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => Boolean(JSON.parse((0, util_1.localStorageGetItem)('lgv-showTrackOutlines') || 'true'))),
180
185
  }))
181
186
  .volatile(() => ({
182
187
  volatileWidth: undefined,
@@ -231,6 +236,15 @@ function stateModelFactory(pluginManager) {
231
236
  },
232
237
  }))
233
238
  .views(self => ({
239
+ /**
240
+ * #method
241
+ */
242
+ scaleBarDisplayPrefix() {
243
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
244
+ return (0, mobx_state_tree_1.getParent)(self, 2).type === 'LinearSyntenyView'
245
+ ? self.assemblyNames[0]
246
+ : '';
247
+ },
234
248
  /**
235
249
  * #method
236
250
  */
@@ -250,8 +264,7 @@ function stateModelFactory(pluginManager) {
250
264
  */
251
265
  get assemblyErrors() {
252
266
  const { assemblyManager } = (0, util_1.getSession)(self);
253
- const { assemblyNames } = self;
254
- return assemblyNames
267
+ return self.assemblyNames
255
268
  .map(a => { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.error; })
256
269
  .filter(f => !!f)
257
270
  .join(', ');
@@ -438,6 +451,12 @@ function stateModelFactory(pluginManager) {
438
451
  },
439
452
  }))
440
453
  .actions(self => ({
454
+ /**
455
+ * #action
456
+ */
457
+ setShowTrackOutlines(arg) {
458
+ self.showTrackOutlines = arg;
459
+ },
441
460
  /**
442
461
  * #action
443
462
  */
@@ -1014,6 +1033,12 @@ function stateModelFactory(pluginManager) {
1014
1033
  checked: !self.hideHeader,
1015
1034
  onClick: () => self.setHideHeader(!self.hideHeader),
1016
1035
  },
1036
+ {
1037
+ label: 'Show track outlines',
1038
+ type: 'checkbox',
1039
+ checked: self.showTrackOutlines,
1040
+ onClick: () => self.setShowTrackOutlines(!self.showTrackOutlines),
1041
+ },
1017
1042
  {
1018
1043
  label: 'Show header overview',
1019
1044
  type: 'checkbox',
@@ -23,9 +23,9 @@ export declare function makeTicks(start: number, end: number, bpPerPx: number, e
23
23
  export declare function generateLocations(regions: ParsedLocString[] | undefined, assemblyManager: AssemblyManager, assemblyName?: string): Promise<{
24
24
  assemblyName: string;
25
25
  parentRegion: import("@jbrowse/core/assemblyManager/assembly").BasicRegion;
26
- end?: number;
27
- start?: number;
28
- reversed?: boolean;
26
+ end?: number | undefined;
27
+ start?: number | undefined;
28
+ reversed?: boolean | undefined;
29
29
  refName: string;
30
30
  }[]>;
31
31
  /**
package/dist/index.d.ts CHANGED
@@ -380,6 +380,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
380
380
  showGridlines: boolean;
381
381
  highlight: import("mobx-state-tree").IMSTArray<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>> & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>>, [undefined]>>;
382
382
  colorByCDS: boolean;
383
+ showTrackOutlines: boolean;
383
384
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
384
385
  width: number;
385
386
  } & {
@@ -406,6 +407,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
406
407
  readonly interRegionPaddingWidth: number;
407
408
  readonly assemblyNames: string[];
408
409
  } & {
410
+ scaleBarDisplayPrefix(): string;
409
411
  MiniControlsComponent(): import("react").FC<any>;
410
412
  HeaderComponent(): import("react").FC<any>;
411
413
  readonly assemblyErrors: string;
@@ -435,6 +437,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
435
437
  rewriteOnClicks(trackType: string, viewMenuActions: import("@jbrowse/core/ui").MenuItem[]): void;
436
438
  readonly trackTypeActions: Map<string, import("@jbrowse/core/ui").MenuItem[]>;
437
439
  } & {
440
+ setShowTrackOutlines(arg: boolean): void;
438
441
  setColorByCDS(flag: boolean): void;
439
442
  setShowCytobands(flag: boolean): void;
440
443
  setWidth(newWidth: number): void;
@@ -575,6 +578,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
575
578
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
576
579
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>>, [undefined]>;
577
580
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
581
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
578
582
  }, {
579
583
  width: number;
580
584
  } & {
@@ -601,6 +605,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
601
605
  readonly interRegionPaddingWidth: number;
602
606
  readonly assemblyNames: string[];
603
607
  } & {
608
+ scaleBarDisplayPrefix(): string;
604
609
  MiniControlsComponent(): import("react").FC<any>;
605
610
  HeaderComponent(): import("react").FC<any>;
606
611
  readonly assemblyErrors: string;
@@ -630,6 +635,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
630
635
  rewriteOnClicks(trackType: string, viewMenuActions: import("@jbrowse/core/ui").MenuItem[]): void;
631
636
  readonly trackTypeActions: Map<string, import("@jbrowse/core/ui").MenuItem[]>;
632
637
  } & {
638
+ setShowTrackOutlines(arg: boolean): void;
633
639
  setColorByCDS(flag: boolean): void;
634
640
  setShowCytobands(flag: boolean): void;
635
641
  setWidth(newWidth: number): void;
@@ -770,6 +776,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
770
776
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
771
777
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>>, [undefined]>;
772
778
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
779
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
773
780
  }>>, import("mobx-state-tree")._NotCustomized>>;
774
781
  }) => import("react").JSX.Element;
775
782
  };
@@ -1,14 +1,12 @@
1
- import React, { lazy, useEffect, useRef } from 'react';
2
- import { Button, Paper, Typography } from '@mui/material';
1
+ import React, { lazy, Suspense, useEffect, useRef } from 'react';
3
2
  import { makeStyles } from 'tss-react/mui';
4
3
  import { LoadingEllipses } from '@jbrowse/core/ui';
5
4
  import { getSession } from '@jbrowse/core/util';
6
5
  import { observer } from 'mobx-react';
7
- // icons
8
- import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
9
6
  import TrackContainer from './TrackContainer';
10
7
  import TracksContainer from './TracksContainer';
11
8
  const ImportForm = lazy(() => import('./ImportForm'));
9
+ const NoTracksActiveButton = lazy(() => import('./NoTracksActiveButton'));
12
10
  const useStyles = makeStyles()(theme => ({
13
11
  note: {
14
12
  textAlign: 'center',
@@ -22,13 +20,6 @@ const useStyles = makeStyles()(theme => ({
22
20
  zIndex: 1000,
23
21
  },
24
22
  }));
25
- function NoTracksActive({ model }) {
26
- const { classes } = useStyles();
27
- const { hideNoTracksActive } = model;
28
- return (React.createElement(Paper, { className: classes.note }, !hideNoTracksActive ? (React.createElement(React.Fragment, null,
29
- React.createElement(Typography, null, "No tracks active."),
30
- React.createElement(Button, { variant: "contained", color: "primary", onClick: () => model.activateTrackSelector(), className: classes.top, startIcon: React.createElement(TrackSelectorIcon, null) }, "Open track selector"))) : (React.createElement("div", { style: { height: '48px' } }))));
31
- }
32
23
  const LinearGenomeView = observer(({ model }) => {
33
24
  const { tracks, error, initialized, hasDisplayedRegions } = model;
34
25
  const ref = useRef(null);
@@ -71,6 +62,7 @@ const LinearGenomeView = observer(({ model }) => {
71
62
  } },
72
63
  React.createElement(HeaderComponent, { model: model }),
73
64
  React.createElement(MiniControlsComponent, { model: model }),
74
- React.createElement(TracksContainer, { model: model }, !tracks.length ? (React.createElement(NoTracksActive, { model: model })) : (tracks.map(track => (React.createElement(TrackContainer, { key: track.id, model: model, track: track })))))));
65
+ React.createElement(TracksContainer, { model: model }, !tracks.length ? (React.createElement(Suspense, { fallback: React.createElement(React.Fragment, null) },
66
+ React.createElement(NoTracksActiveButton, { model: model }))) : (tracks.map(track => (React.createElement(TrackContainer, { key: track.id, model: model, track: track })))))));
75
67
  });
76
68
  export default LinearGenomeView;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { LinearGenomeViewModel } from '..';
3
+ declare const NoTracksActiveButton: ({ model, }: {
4
+ model: LinearGenomeViewModel;
5
+ }) => React.JSX.Element;
6
+ export default NoTracksActiveButton;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Button, Paper, Typography } from '@mui/material';
3
+ import { makeStyles } from 'tss-react/mui';
4
+ import { observer } from 'mobx-react';
5
+ // icons
6
+ import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
7
+ const useStyles = makeStyles()(theme => ({
8
+ note: {
9
+ textAlign: 'center',
10
+ paddingTop: theme.spacing(1),
11
+ paddingBottom: theme.spacing(1),
12
+ },
13
+ top: {
14
+ zIndex: 1000,
15
+ },
16
+ }));
17
+ const NoTracksActiveButton = observer(function ({ model, }) {
18
+ const { classes } = useStyles();
19
+ const { hideNoTracksActive } = model;
20
+ return (React.createElement(Paper, { className: classes.note }, !hideNoTracksActive ? (React.createElement(React.Fragment, null,
21
+ React.createElement(Typography, null, "No tracks active."),
22
+ React.createElement(Button, { variant: "contained", color: "primary", onClick: () => model.activateTrackSelector(), className: classes.top, startIcon: React.createElement(TrackSelectorIcon, null) }, "Open track selector"))) : (React.createElement("div", { style: { height: '48px' } }))));
23
+ });
24
+ export default NoTracksActiveButton;
@@ -2,9 +2,9 @@ import { Paper, Typography } from '@mui/material';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
  import { observer } from 'mobx-react';
4
4
  import React from 'react';
5
+ import { getTickDisplayStr } from '@jbrowse/core/util';
5
6
  import { ContentBlock as ContentBlockComponent, ElidedBlock as ElidedBlockComponent, InterRegionPaddingBlock as InterRegionPaddingBlockComponent, } from '../../BaseLinearDisplay/components/Block';
6
7
  import { makeTicks } from '../util';
7
- import { getTickDisplayStr } from '@jbrowse/core/util';
8
8
  const useStyles = makeStyles()(theme => ({
9
9
  scalebarContainer: {
10
10
  overflow: 'hidden',
@@ -45,24 +45,30 @@ const useStyles = makeStyles()(theme => ({
45
45
  background: theme.palette.background.paper,
46
46
  },
47
47
  }));
48
- const RenderedRefNameLabels = observer(({ model }) => {
48
+ const RenderedRefNameLabels = observer(function ({ model }) {
49
49
  const { classes } = useStyles();
50
+ const { staticBlocks, offsetPx, scaleBarDisplayPrefix } = model;
50
51
  // find the block that needs pinning to the left side for context
51
52
  let lastLeftBlock = 0;
52
- model.staticBlocks.forEach((block, i) => {
53
- if (block.offsetPx - model.offsetPx < 0) {
53
+ staticBlocks.forEach((block, i) => {
54
+ if (block.offsetPx - offsetPx < 0) {
54
55
  lastLeftBlock = i;
55
56
  }
56
57
  });
57
- return (React.createElement(React.Fragment, null, model.staticBlocks.map((block, index) => {
58
- return block.type === 'ContentBlock' &&
59
- (block.isLeftEndOfDisplayedRegion || index === lastLeftBlock) ? (React.createElement(Typography, { key: `refLabel-${block.key}-${index}`, style: {
60
- left: index === lastLeftBlock
61
- ? Math.max(0, -model.offsetPx)
62
- : block.offsetPx - model.offsetPx - 1,
63
- paddingLeft: index === lastLeftBlock ? 0 : 1,
64
- }, className: classes.refLabel, "data-testid": `refLabel-${block.refName}` }, block.refName)) : null;
65
- })));
58
+ const val = scaleBarDisplayPrefix();
59
+ return (React.createElement(React.Fragment, null,
60
+ staticBlocks.blocks[0].type !== 'ContentBlock' && val ? (React.createElement(Typography, { style: { left: 0, zIndex: 100 }, className: classes.refLabel }, val)) : null,
61
+ staticBlocks.map((block, index) => {
62
+ return block.type === 'ContentBlock' &&
63
+ (block.isLeftEndOfDisplayedRegion || index === lastLeftBlock) ? (React.createElement(Typography, { key: `refLabel-${block.key}-${index}`, style: {
64
+ left: index === lastLeftBlock
65
+ ? Math.max(0, -offsetPx)
66
+ : block.offsetPx - offsetPx - 1,
67
+ paddingLeft: index === lastLeftBlock ? 0 : 1,
68
+ }, className: classes.refLabel, "data-testid": `refLabel-${block.refName}` },
69
+ index === lastLeftBlock && val ? `${val}:` : '',
70
+ block.refName)) : null;
71
+ })));
66
72
  });
67
73
  const RenderedBlockTicks = function ({ block, bpPerPx, }) {
68
74
  const { classes } = useStyles();
@@ -77,7 +83,7 @@ const RenderedBlockTicks = function ({ block, bpPerPx, }) {
77
83
  return null;
78
84
  })));
79
85
  };
80
- const RenderedScalebarLabels = observer(({ model }) => {
86
+ const RenderedScalebarLabels = observer(function ({ model }) {
81
87
  const { staticBlocks, bpPerPx } = model;
82
88
  return (React.createElement(React.Fragment, null, staticBlocks.map((block, idx) => {
83
89
  const { key, widthPx } = block;
@@ -21,9 +21,9 @@ const useStyles = makeStyles()({
21
21
  const TrackContainer = observer(function ({ model, track, }) {
22
22
  const { classes } = useStyles();
23
23
  const display = track.displays[0];
24
- const { draggingTrackId } = model;
24
+ const { draggingTrackId, showTrackOutlines } = model;
25
25
  const ref = useRef(null);
26
- return (React.createElement(Paper, { ref: ref, className: classes.root, variant: "outlined", onClick: event => {
26
+ return (React.createElement(Paper, { ref: ref, className: classes.root, variant: showTrackOutlines ? 'outlined' : undefined, elevation: showTrackOutlines ? undefined : 0, onClick: event => {
27
27
  var _a;
28
28
  if (event.detail === 2 && !track.displays[0].featureIdUnderMouse) {
29
29
  const left = ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0;
@@ -74,6 +74,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
74
74
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
75
75
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<ParsedLocString>, Required<ParsedLocString>, Required<ParsedLocString>>>, [undefined]>;
76
76
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
77
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
77
78
  }, {
78
79
  width: number;
79
80
  } & {
@@ -114,6 +115,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
114
115
  */
115
116
  readonly assemblyNames: string[];
116
117
  } & {
118
+ /**
119
+ * #method
120
+ */
121
+ scaleBarDisplayPrefix(): string;
117
122
  /**
118
123
  * #method
119
124
  */
@@ -216,6 +221,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
216
221
  */
217
222
  readonly trackTypeActions: Map<string, MenuItem[]>;
218
223
  } & {
224
+ /**
225
+ * #action
226
+ */
227
+ setShowTrackOutlines(arg: boolean): void;
219
228
  /**
220
229
  * #action
221
230
  */
@@ -615,6 +624,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
615
624
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
616
625
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<ParsedLocString>, Required<ParsedLocString>, Required<ParsedLocString>>>, [undefined]>;
617
626
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
627
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
618
628
  }>>, import("mobx-state-tree")._NotCustomized>;
619
629
  export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>;
620
630
  export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>;
@@ -7,7 +7,7 @@ import calculateDynamicBlocks from '@jbrowse/core/util/calculateDynamicBlocks';
7
7
  import calculateStaticBlocks from '@jbrowse/core/util/calculateStaticBlocks';
8
8
  import { getParentRenderProps } from '@jbrowse/core/util/tracks';
9
9
  import { when, transaction, autorun } from 'mobx';
10
- import { addDisposer, cast, getSnapshot, getRoot, resolveIdentifier, types, } from 'mobx-state-tree';
10
+ import { addDisposer, cast, getSnapshot, getRoot, resolveIdentifier, types, getParent, } from 'mobx-state-tree';
11
11
  import Base1DView from '@jbrowse/core/util/Base1DViewModel';
12
12
  import { moveTo, pxToBp, bpToPx } from '@jbrowse/core/util/Base1DUtils';
13
13
  import { saveAs } from 'file-saver';
@@ -147,6 +147,11 @@ export function stateModelFactory(pluginManager) {
147
147
  * color by CDS
148
148
  */
149
149
  colorByCDS: types.optional(types.boolean, () => Boolean(JSON.parse(localStorageGetItem('lgv-colorByCDS') || 'false'))),
150
+ /**
151
+ * #property
152
+ * color by CDS
153
+ */
154
+ showTrackOutlines: types.optional(types.boolean, () => Boolean(JSON.parse(localStorageGetItem('lgv-showTrackOutlines') || 'true'))),
150
155
  }))
151
156
  .volatile(() => ({
152
157
  volatileWidth: undefined,
@@ -201,6 +206,15 @@ export function stateModelFactory(pluginManager) {
201
206
  },
202
207
  }))
203
208
  .views(self => ({
209
+ /**
210
+ * #method
211
+ */
212
+ scaleBarDisplayPrefix() {
213
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
214
+ return getParent(self, 2).type === 'LinearSyntenyView'
215
+ ? self.assemblyNames[0]
216
+ : '';
217
+ },
204
218
  /**
205
219
  * #method
206
220
  */
@@ -220,8 +234,7 @@ export function stateModelFactory(pluginManager) {
220
234
  */
221
235
  get assemblyErrors() {
222
236
  const { assemblyManager } = getSession(self);
223
- const { assemblyNames } = self;
224
- return assemblyNames
237
+ return self.assemblyNames
225
238
  .map(a => { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.error; })
226
239
  .filter(f => !!f)
227
240
  .join(', ');
@@ -408,6 +421,12 @@ export function stateModelFactory(pluginManager) {
408
421
  },
409
422
  }))
410
423
  .actions(self => ({
424
+ /**
425
+ * #action
426
+ */
427
+ setShowTrackOutlines(arg) {
428
+ self.showTrackOutlines = arg;
429
+ },
411
430
  /**
412
431
  * #action
413
432
  */
@@ -984,6 +1003,12 @@ export function stateModelFactory(pluginManager) {
984
1003
  checked: !self.hideHeader,
985
1004
  onClick: () => self.setHideHeader(!self.hideHeader),
986
1005
  },
1006
+ {
1007
+ label: 'Show track outlines',
1008
+ type: 'checkbox',
1009
+ checked: self.showTrackOutlines,
1010
+ onClick: () => self.setShowTrackOutlines(!self.showTrackOutlines),
1011
+ },
987
1012
  {
988
1013
  label: 'Show header overview',
989
1014
  type: 'checkbox',
@@ -23,9 +23,9 @@ export declare function makeTicks(start: number, end: number, bpPerPx: number, e
23
23
  export declare function generateLocations(regions: ParsedLocString[] | undefined, assemblyManager: AssemblyManager, assemblyName?: string): Promise<{
24
24
  assemblyName: string;
25
25
  parentRegion: import("@jbrowse/core/assemblyManager/assembly").BasicRegion;
26
- end?: number;
27
- start?: number;
28
- reversed?: boolean;
26
+ end?: number | undefined;
27
+ start?: number | undefined;
28
+ reversed?: boolean | undefined;
29
29
  refName: string;
30
30
  }[]>;
31
31
  /**
package/esm/index.d.ts CHANGED
@@ -380,6 +380,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
380
380
  showGridlines: boolean;
381
381
  highlight: import("mobx-state-tree").IMSTArray<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>> & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>>, [undefined]>>;
382
382
  colorByCDS: boolean;
383
+ showTrackOutlines: boolean;
383
384
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
384
385
  width: number;
385
386
  } & {
@@ -406,6 +407,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
406
407
  readonly interRegionPaddingWidth: number;
407
408
  readonly assemblyNames: string[];
408
409
  } & {
410
+ scaleBarDisplayPrefix(): string;
409
411
  MiniControlsComponent(): import("react").FC<any>;
410
412
  HeaderComponent(): import("react").FC<any>;
411
413
  readonly assemblyErrors: string;
@@ -435,6 +437,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
435
437
  rewriteOnClicks(trackType: string, viewMenuActions: import("@jbrowse/core/ui").MenuItem[]): void;
436
438
  readonly trackTypeActions: Map<string, import("@jbrowse/core/ui").MenuItem[]>;
437
439
  } & {
440
+ setShowTrackOutlines(arg: boolean): void;
438
441
  setColorByCDS(flag: boolean): void;
439
442
  setShowCytobands(flag: boolean): void;
440
443
  setWidth(newWidth: number): void;
@@ -575,6 +578,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
575
578
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
576
579
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>>, [undefined]>;
577
580
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
581
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
578
582
  }, {
579
583
  width: number;
580
584
  } & {
@@ -601,6 +605,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
601
605
  readonly interRegionPaddingWidth: number;
602
606
  readonly assemblyNames: string[];
603
607
  } & {
608
+ scaleBarDisplayPrefix(): string;
604
609
  MiniControlsComponent(): import("react").FC<any>;
605
610
  HeaderComponent(): import("react").FC<any>;
606
611
  readonly assemblyErrors: string;
@@ -630,6 +635,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
630
635
  rewriteOnClicks(trackType: string, viewMenuActions: import("@jbrowse/core/ui").MenuItem[]): void;
631
636
  readonly trackTypeActions: Map<string, import("@jbrowse/core/ui").MenuItem[]>;
632
637
  } & {
638
+ setShowTrackOutlines(arg: boolean): void;
633
639
  setColorByCDS(flag: boolean): void;
634
640
  setShowCytobands(flag: boolean): void;
635
641
  setWidth(newWidth: number): void;
@@ -770,6 +776,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
770
776
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
771
777
  highlight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").IType<Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>, Required<import("@jbrowse/core/util").ParsedLocString>>>, [undefined]>;
772
778
  colorByCDS: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
779
+ showTrackOutlines: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
773
780
  }>>, import("mobx-state-tree")._NotCustomized>>;
774
781
  }) => import("react").JSX.Element;
775
782
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-linear-genome-view",
3
- "version": "2.12.3",
3
+ "version": "2.13.1",
4
4
  "description": "JBrowse 2 linear genome view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -61,5 +61,5 @@
61
61
  "access": "public"
62
62
  },
63
63
  "module": "esm/index.js",
64
- "gitHead": "2775490221cde56af344acebb0afa7e14531cd81"
64
+ "gitHead": "fcebca71cc1d066654603e1a9accfa6c6d4f764d"
65
65
  }