@jbrowse/plugin-linear-genome-view 2.7.1 → 2.8.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/components/Tooltip.js +4 -2
  2. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +18 -11
  3. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +25 -2
  4. package/dist/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
  5. package/dist/BaseLinearDisplay/models/renderSvg.js +2 -1
  6. package/dist/LinearBasicDisplay/model.d.ts +3 -1
  7. package/dist/LinearGenomeView/components/LinearGenomeView.js +29 -7
  8. package/dist/LinearGenomeView/components/OverviewRubberband.js +5 -2
  9. package/dist/LinearGenomeView/components/SearchBox.js +24 -23
  10. package/dist/LinearGenomeView/components/TrackLabelContainer.js +2 -2
  11. package/dist/LinearGenomeView/model.d.ts +7 -1
  12. package/dist/LinearGenomeView/model.js +30 -19
  13. package/dist/index.d.ts +52 -15
  14. package/dist/index.js +19 -0
  15. package/esm/BaseLinearDisplay/components/Tooltip.js +4 -2
  16. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +18 -11
  17. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +1 -1
  18. package/esm/BaseLinearDisplay/models/renderSvg.d.ts +1 -1
  19. package/esm/BaseLinearDisplay/models/renderSvg.js +1 -1
  20. package/esm/LinearBasicDisplay/model.d.ts +3 -1
  21. package/esm/LinearGenomeView/components/LinearGenomeView.js +29 -7
  22. package/esm/LinearGenomeView/components/OverviewRubberband.js +5 -2
  23. package/esm/LinearGenomeView/components/SearchBox.js +24 -23
  24. package/esm/LinearGenomeView/components/TrackLabelContainer.js +2 -2
  25. package/esm/LinearGenomeView/model.d.ts +7 -1
  26. package/esm/LinearGenomeView/model.js +30 -19
  27. package/esm/index.d.ts +52 -15
  28. package/esm/index.js +19 -0
  29. package/package.json +2 -2
@@ -53,7 +53,8 @@ const TooltipContents = react_1.default.forwardRef(function TooltipContents2({ m
53
53
  return (react_1.default.createElement("div", { ref: ref }, react_1.default.isValidElement(message) ? (message) : message ? (react_1.default.createElement(ui_1.SanitizedHTML, { html: String(message) })) : null));
54
54
  });
55
55
  const Tooltip = (0, mobx_react_1.observer)(({ model, clientMouseCoord, }) => {
56
- const { classes } = useStyles();
56
+ var _a, _b;
57
+ const { theme, classes } = useStyles();
57
58
  const { featureUnderMouse } = model;
58
59
  const [width, setWidth] = (0, react_1.useState)(0);
59
60
  const [popperElt, setPopperElt] = (0, react_1.useState)(null);
@@ -79,7 +80,8 @@ const Tooltip = (0, mobx_react_1.observer)(({ model, clientMouseCoord, }) => {
79
80
  const contents = featureUnderMouse
80
81
  ? (0, configuration_1.getConf)(model, 'mouseover', { feature: featureUnderMouse })
81
82
  : undefined;
82
- return featureUnderMouse && contents ? (react_1.default.createElement(material_1.Portal, null,
83
+ const popperTheme = (_a = theme === null || theme === void 0 ? void 0 : theme.components) === null || _a === void 0 ? void 0 : _a.MuiPopper;
84
+ return featureUnderMouse && contents ? (react_1.default.createElement(material_1.Portal, { container: (_b = popperTheme === null || popperTheme === void 0 ? void 0 : popperTheme.defaultProps) === null || _b === void 0 ? void 0 : _b.container },
83
85
  react_1.default.createElement("div", { ref: setPopperElt, className: classes.tooltip,
84
86
  // zIndex needed to go over widget drawer
85
87
  style: { ...styles.popper, zIndex: 100000 }, ...attributes.popper },
@@ -69,7 +69,11 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
69
69
  setMessage(messageText: string): void;
70
70
  setRendered(props: {
71
71
  reactElement: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
72
- features: Map<string, Feature>;
72
+ features: Map<string, Feature>; /**
73
+ * #getter
74
+ * a CompositeMap of `featureId -> feature obj` that
75
+ * just looks in all the block data for that feature
76
+ */
73
77
  layout: any;
74
78
  maxHeightReached: boolean;
75
79
  renderProps: any;
@@ -128,7 +132,9 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
128
132
  message: string | undefined;
129
133
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
130
134
  onHorizontalScroll?: Function | undefined;
131
- blockState?: Record<string, any> | undefined;
135
+ blockState?: Record<string, any> | undefined; /**
136
+ * #property
137
+ */
132
138
  }>;
133
139
  readonly DisplayBlurb: React.FC<{
134
140
  model: {
@@ -136,7 +142,9 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
136
142
  type: string;
137
143
  rpcDriverName: string | undefined;
138
144
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
139
- rendererTypeName: string;
145
+ rendererTypeName: string; /**
146
+ * #getter
147
+ */
140
148
  error: unknown;
141
149
  message: string | undefined;
142
150
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
@@ -144,9 +152,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
144
152
  type: import("mobx-state-tree").ISimpleType<string>;
145
153
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
146
154
  }, {
147
- rendererTypeName: string; /**
148
- * #getter
149
- */
155
+ rendererTypeName: string;
150
156
  error: unknown;
151
157
  message: string | undefined;
152
158
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
@@ -179,10 +185,7 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
179
185
  } & {
180
186
  readonly currentBytesRequested: number;
181
187
  readonly currentFeatureScreenDensity: number;
182
- readonly maxFeatureScreenDensity: any; /**
183
- * #property
184
- * updated via autorun
185
- */
188
+ readonly maxFeatureScreenDensity: any;
186
189
  readonly featureDensityStatsReady: boolean;
187
190
  readonly maxAllowableBytes: number;
188
191
  } & {
@@ -358,7 +361,11 @@ export declare const BaseLinearDisplay: import("mobx-state-tree").IModelType<{
358
361
  setMessage(messageText: string): void;
359
362
  setRendered(props: {
360
363
  reactElement: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
361
- features: Map<string, Feature>;
364
+ features: Map<string, Feature>; /**
365
+ * #getter
366
+ * a CompositeMap of `featureId -> feature obj` that
367
+ * just looks in all the block data for that feature
368
+ */
362
369
  layout: any;
363
370
  maxHeightReached: boolean;
364
371
  renderProps: any;
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -16,7 +39,6 @@ const MenuOpen_1 = __importDefault(require("@mui/icons-material/MenuOpen"));
16
39
  const BaseLinearDisplay_1 = require("../components/BaseLinearDisplay");
17
40
  const serverSideRenderedBlock_1 = __importDefault(require("./serverSideRenderedBlock"));
18
41
  const configSchema_1 = __importDefault(require("./configSchema"));
19
- const renderSvg_1 = __importDefault(require("./renderSvg"));
20
42
  const TrackHeightMixin_1 = __importDefault(require("./TrackHeightMixin"));
21
43
  const FeatureDensityMixin_1 = __importDefault(require("./FeatureDensityMixin"));
22
44
  /**
@@ -296,7 +318,8 @@ function stateModelFactory() {
296
318
  * #method
297
319
  */
298
320
  async renderSvg(opts) {
299
- return (0, renderSvg_1.default)(self, opts);
321
+ const { renderBaseLinearDisplaySvg } = await Promise.resolve().then(() => __importStar(require('./renderSvg')));
322
+ return renderBaseLinearDisplaySvg(self, opts);
300
323
  },
301
324
  afterAttach() {
302
325
  // watch the parent's blocks to update our block state when they change,
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { ThemeOptions } from '@mui/material';
3
3
  import { ExportSvgOptions } from '../../LinearGenomeView';
4
4
  import { BaseLinearDisplayModel } from './BaseLinearDisplayModel';
5
- export default function renderBaseLinearDisplaySvg(self: BaseLinearDisplayModel, opts: ExportSvgOptions & {
5
+ export declare function renderBaseLinearDisplaySvg(self: BaseLinearDisplayModel, opts: ExportSvgOptions & {
6
6
  overrideHeight: number;
7
7
  theme: ThemeOptions;
8
8
  }): Promise<React.JSX.Element>;
@@ -26,6 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.renderBaseLinearDisplaySvg = void 0;
29
30
  const react_1 = __importDefault(require("react"));
30
31
  const util_1 = require("@jbrowse/core/util");
31
32
  const serverSideRenderedBlock_1 = __importStar(require("./serverSideRenderedBlock"));
@@ -79,4 +80,4 @@ async function renderBaseLinearDisplaySvg(self, opts) {
79
80
  react_1.default.createElement(util_1.ReactRendering, { rendering: rendering })))));
80
81
  })));
81
82
  }
82
- exports.default = renderBaseLinearDisplaySvg;
83
+ exports.renderBaseLinearDisplaySvg = renderBaseLinearDisplaySvg;
@@ -219,7 +219,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
219
219
  featureIdUnderMouse: string | undefined;
220
220
  contextMenuFeature: import("@jbrowse/core/util").Feature | undefined;
221
221
  } & {
222
- readonly blockType: "dynamicBlocks" | "staticBlocks";
222
+ readonly blockType: "dynamicBlocks" | "staticBlocks"; /**
223
+ * #getter
224
+ */
223
225
  readonly blockDefinitions: import("@jbrowse/core/util/blockTypes").BlockSet;
224
226
  } & {
225
227
  readonly renderDelay: number;
@@ -30,12 +30,12 @@ const react_1 = __importStar(require("react"));
30
30
  const material_1 = require("@mui/material");
31
31
  const mui_1 = require("tss-react/mui");
32
32
  const ui_1 = require("@jbrowse/core/ui");
33
+ const util_1 = require("@jbrowse/core/util");
33
34
  const mobx_react_1 = require("mobx-react");
34
35
  // icons
35
36
  const Icons_1 = require("@jbrowse/core/ui/Icons");
36
37
  const TrackContainer_1 = __importDefault(require("./TrackContainer"));
37
38
  const TracksContainer_1 = __importDefault(require("./TracksContainer"));
38
- const util_1 = require("@jbrowse/core/util");
39
39
  const ImportForm = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./ImportForm'))));
40
40
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
41
41
  note: {
@@ -43,14 +43,28 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
43
43
  paddingTop: theme.spacing(1),
44
44
  paddingBottom: theme.spacing(1),
45
45
  },
46
+ rel: {
47
+ position: 'relative',
48
+ },
49
+ top: {
50
+ zIndex: 1000,
51
+ },
46
52
  }));
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
+ }
47
60
  const LinearGenomeView = (0, mobx_react_1.observer)(({ model }) => {
48
61
  const { tracks, error, initialized, hasDisplayedRegions } = model;
49
- const { classes } = useStyles();
50
62
  const ref = (0, react_1.useRef)(null);
51
63
  const session = (0, util_1.getSession)(model);
64
+ const { classes } = useStyles();
52
65
  (0, react_1.useEffect)(() => {
53
- // sets the focused view id based on a click within the LGV; necessary for subviews to be focused properly
66
+ // sets the focused view id based on a click within the LGV;
67
+ // necessary for subviews to be focused properly
54
68
  function handleSelectView(e) {
55
69
  var _a, _b;
56
70
  if (e.target instanceof Element && ((_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
@@ -72,11 +86,19 @@ const LinearGenomeView = (0, mobx_react_1.observer)(({ model }) => {
72
86
  }
73
87
  const MiniControlsComponent = model.MiniControlsComponent();
74
88
  const HeaderComponent = model.HeaderComponent();
75
- return (react_1.default.createElement("div", { style: { position: 'relative' }, ref: ref },
89
+ return (react_1.default.createElement("div", { className: classes.rel, ref: ref, onMouseLeave: () => session.setHovered(undefined), onMouseMove: event => {
90
+ const c = ref.current;
91
+ if (!c) {
92
+ return;
93
+ }
94
+ const { tracks } = model;
95
+ const leftPx = event.clientX - c.getBoundingClientRect().left;
96
+ const hoverPosition = model.pxToBp(leftPx);
97
+ const hoverFeature = tracks.find(t => t.displays[0].featureUnderMouse);
98
+ session.setHovered({ hoverPosition, hoverFeature });
99
+ } },
76
100
  react_1.default.createElement(HeaderComponent, { model: model }),
77
101
  react_1.default.createElement(MiniControlsComponent, { model: model }),
78
- react_1.default.createElement(TracksContainer_1.default, { model: model }, !tracks.length ? (react_1.default.createElement(material_1.Paper, { variant: "outlined", className: classes.note }, !model.hideNoTracksActive ? (react_1.default.createElement(react_1.default.Fragment, null,
79
- react_1.default.createElement(material_1.Typography, null, "No tracks active."),
80
- react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: model.activateTrackSelector, style: { zIndex: 1000 }, startIcon: react_1.default.createElement(Icons_1.TrackSelector, null) }, "Open track selector"))) : (react_1.default.createElement("div", { style: { height: '48px' } })))) : (tracks.map(track => (react_1.default.createElement(TrackContainer_1.default, { key: track.id, model: model, track: track })))))));
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 })))))));
81
103
  });
82
104
  exports.default = LinearGenomeView;
@@ -46,6 +46,9 @@ const useStyles = (0, mui_1.makeStyles)()({
46
46
  position: 'absolute',
47
47
  zIndex: 10,
48
48
  },
49
+ rel: {
50
+ position: 'relative',
51
+ },
49
52
  });
50
53
  const HoverTooltip = (0, mobx_react_1.observer)(function ({ model, open, guideX, overview, }) {
51
54
  var _a;
@@ -131,7 +134,7 @@ const OverviewRubberband = (0, mobx_react_1.observer)(function OverviewRubberban
131
134
  setGuideX(undefined);
132
135
  }
133
136
  if (startX === undefined) {
134
- return (react_1.default.createElement("div", { style: { position: 'relative' } },
137
+ return (react_1.default.createElement("div", { className: classes.rel },
135
138
  guideX !== undefined ? (react_1.default.createElement(HoverTooltip, { model: model, open: !mouseDragging, overview: overview, guideX: guideX })) : null,
136
139
  react_1.default.createElement("div", { className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove }, ControlComponent)));
137
140
  }
@@ -152,7 +155,7 @@ const OverviewRubberband = (0, mobx_react_1.observer)(function OverviewRubberban
152
155
  [leftBpOffset, rightBpOffset] = [rightBpOffset, leftBpOffset];
153
156
  }
154
157
  }
155
- return (react_1.default.createElement("div", { style: { position: 'relative' } },
158
+ return (react_1.default.createElement("div", { className: classes.rel },
156
159
  leftBpOffset && rightBpOffset ? (react_1.default.createElement(RubberbandSpan_1.default, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, width: Math.abs(width), left: left })) : null,
157
160
  react_1.default.createElement("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove }, ControlComponent)));
158
161
  });
@@ -17,6 +17,11 @@ const useStyles = (0, mui_1.makeStyles)()(() => ({
17
17
  minWidth: 100,
18
18
  },
19
19
  }));
20
+ function checkRef(str, allRefs) {
21
+ const [ref, rest] = (0, util_2.splitLast)(str, ':');
22
+ return (allRefs.includes(str) ||
23
+ (allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10))));
24
+ }
20
25
  const SearchBox = (0, mobx_react_1.observer)(function ({ model, showHelp, }) {
21
26
  const { classes } = useStyles();
22
27
  const theme = (0, material_1.useTheme)();
@@ -44,38 +49,34 @@ const SearchBox = (0, mobx_react_1.observer)(function ({ model, showHelp, }) {
44
49
  async function handleSelectedRegion(option) {
45
50
  var _a;
46
51
  try {
52
+ const input = option.getLabel();
53
+ const allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNamesWithLowerCase) || [];
47
54
  if (option.hasLocation()) {
48
55
  await navToOption(option);
49
56
  }
50
57
  else if ((_a = option.results) === null || _a === void 0 ? void 0 : _a.length) {
51
58
  model.setSearchResults(option.results, option.getLabel());
52
59
  }
60
+ else if (input.split(' ').every(entry => checkRef(entry, allRefs))) {
61
+ await model.navToLocString(input, assemblyName);
62
+ }
53
63
  else {
54
- const input = option.getLabel();
55
- const [ref, rest] = (0, util_2.splitLast)(input, ':');
56
- const allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNamesWithLowerCase) || [];
57
- if (allRefs.includes(input) ||
58
- (allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10)))) {
59
- await model.navToLocString(input, assemblyName);
64
+ const results = await (0, util_2.fetchResults)({
65
+ queryString: input,
66
+ searchType: 'exact',
67
+ searchScope,
68
+ rankSearchResults,
69
+ textSearchManager,
70
+ assembly,
71
+ });
72
+ if (results.length > 1) {
73
+ model.setSearchResults(results, input.toLowerCase());
74
+ }
75
+ else if (results.length === 1) {
76
+ await navToOption(results[0]);
60
77
  }
61
78
  else {
62
- const results = await (0, util_2.fetchResults)({
63
- queryString: input,
64
- searchType: 'exact',
65
- searchScope,
66
- rankSearchResults,
67
- textSearchManager,
68
- assembly,
69
- });
70
- if (results.length > 1) {
71
- model.setSearchResults(results, input.toLowerCase());
72
- }
73
- else if (results.length === 1) {
74
- await navToOption(results[0]);
75
- }
76
- else {
77
- await model.navToLocString(input, assemblyName);
78
- }
79
+ await model.navToLocString(input, assemblyName);
79
80
  }
80
81
  }
81
82
  }
@@ -23,9 +23,9 @@ const TrackLabelContainer = (0, mobx_react_1.observer)(function ({ track, view,
23
23
  const { classes, cx } = useStyles();
24
24
  const display = track.displays[0];
25
25
  const { trackLabel, trackLabelOverlap, trackLabelOffset } = classes;
26
- const labelStyle = view.trackLabels !== 'overlapping' || display.prefersOffset
26
+ const labelStyle = view.trackLabelsSetting !== 'overlapping' || display.prefersOffset
27
27
  ? trackLabelOffset
28
28
  : trackLabelOverlap;
29
- return view.trackLabels !== 'hidden' ? (react_1.default.createElement(TrackLabel_1.default, { track: track, className: cx(trackLabel, labelStyle) })) : null;
29
+ return view.trackLabelsSetting !== 'hidden' ? (react_1.default.createElement(TrackLabel_1.default, { track: track, className: cx(trackLabel, labelStyle) })) : null;
30
30
  });
31
31
  exports.default = TrackLabelContainer;
@@ -71,9 +71,9 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
71
71
  hideHeaderOverview: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
72
72
  hideNoTracksActive: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
73
73
  trackSelectorType: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
74
- trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
75
74
  showCenterLine: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
76
75
  showCytobandsSetting: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
76
+ trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
77
77
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
78
78
  }, {
79
79
  width: number;
@@ -96,6 +96,12 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
96
96
  leftOffset: BpOffset | undefined;
97
97
  rightOffset: BpOffset | undefined;
98
98
  } & {
99
+ /**
100
+ * #getter
101
+ * this is the effective value of the track labels setting, incorporating
102
+ * both the config and view state. use this instead of view.trackLabels
103
+ */
104
+ readonly trackLabelsSetting: any;
99
105
  /**
100
106
  * #getter
101
107
  */
@@ -85,7 +85,7 @@ exports.WIDGET_HEIGHT = 32;
85
85
  */
86
86
  function stateModelFactory(pluginManager) {
87
87
  return mobx_state_tree_1.types
88
- .compose(models_1.BaseViewModel, mobx_state_tree_1.types.model('LinearGenomeView', {
88
+ .compose('LinearGenomeView', models_1.BaseViewModel, mobx_state_tree_1.types.model({
89
89
  /**
90
90
  * #property
91
91
  */
@@ -137,12 +137,6 @@ function stateModelFactory(pluginManager) {
137
137
  * #property
138
138
  */
139
139
  trackSelectorType: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.enumeration(['hierarchical']), 'hierarchical'),
140
- /**
141
- * #property
142
- * how to display the track labels, can be "overlapping", "offset", or
143
- * "hidden"
144
- */
145
- trackLabels: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, () => (0, util_1.localStorageGetItem)('lgv-trackLabels') || 'overlapping'),
146
140
  /**
147
141
  * #property
148
142
  * show the "center line"
@@ -153,6 +147,15 @@ function stateModelFactory(pluginManager) {
153
147
  * show the "cytobands" in the overview scale bar
154
148
  */
155
149
  showCytobandsSetting: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => Boolean(JSON.parse((0, util_1.localStorageGetItem)('lgv-showCytobands') || 'true'))),
150
+ /**
151
+ * #property
152
+ * how to display the track labels, can be "overlapping", "offset", or
153
+ * "hidden", or empty string "" (which results in conf being used). see
154
+ * LinearGenomeViewPlugin
155
+ * https://jbrowse.org/jb2/docs/config/lineargenomeviewplugin/ docs for
156
+ * how conf is used
157
+ */
158
+ trackLabels: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, () => (0, util_1.localStorageGetItem)('lgv-trackLabels') || ''),
156
159
  /**
157
160
  * #property
158
161
  * show the "gridlines" in the track area
@@ -175,6 +178,18 @@ function stateModelFactory(pluginManager) {
175
178
  rightOffset: undefined,
176
179
  }))
177
180
  .views(self => ({
181
+ /**
182
+ * #getter
183
+ * this is the effective value of the track labels setting, incorporating
184
+ * both the config and view state. use this instead of view.trackLabels
185
+ */
186
+ get trackLabelsSetting() {
187
+ const sessionSetting = (0, configuration_1.getConf)((0, util_1.getSession)(self), [
188
+ 'LinearGenomeViewPlugin',
189
+ 'trackLabels',
190
+ ]);
191
+ return self.trackLabels || sessionSetting;
192
+ },
178
193
  /**
179
194
  * #getter
180
195
  */
@@ -615,6 +630,7 @@ function stateModelFactory(pluginManager) {
615
630
  * #action
616
631
  */
617
632
  setTrackLabels(setting) {
633
+ localStorage.setItem('lgv-trackLabels', setting);
618
634
  self.trackLabels = setting;
619
635
  },
620
636
  /**
@@ -945,21 +961,21 @@ function stateModelFactory(pluginManager) {
945
961
  label: 'Overlapping',
946
962
  icon: Visibility_1.default,
947
963
  type: 'radio',
948
- checked: self.trackLabels === 'overlapping',
964
+ checked: self.trackLabelsSetting === 'overlapping',
949
965
  onClick: () => self.setTrackLabels('overlapping'),
950
966
  },
951
967
  {
952
968
  label: 'Offset',
953
969
  icon: Visibility_1.default,
954
970
  type: 'radio',
955
- checked: self.trackLabels === 'offset',
971
+ checked: self.trackLabelsSetting === 'offset',
956
972
  onClick: () => self.setTrackLabels('offset'),
957
973
  },
958
974
  {
959
975
  label: 'Hidden',
960
976
  icon: Visibility_1.default,
961
977
  type: 'radio',
962
- checked: self.trackLabels === 'hidden',
978
+ checked: self.trackLabelsSetting === 'hidden',
963
979
  onClick: () => self.setTrackLabels('hidden'),
964
980
  },
965
981
  ],
@@ -1050,9 +1066,8 @@ function stateModelFactory(pluginManager) {
1050
1066
  }, { delay: 150 }));
1051
1067
  (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
1052
1068
  const s = (s) => JSON.stringify(s);
1053
- const { trackLabels, showCytobandsSetting, showCenterLine } = self;
1069
+ const { showCytobandsSetting, showCenterLine } = self;
1054
1070
  if (typeof localStorage !== 'undefined') {
1055
- localStorage.setItem('lgv-trackLabels', trackLabels);
1056
1071
  localStorage.setItem('lgv-showCytobands', s(showCytobandsSetting));
1057
1072
  localStorage.setItem('lgv-showCenterLine', s(showCenterLine));
1058
1073
  }
@@ -1264,22 +1279,18 @@ function stateModelFactory(pluginManager) {
1264
1279
  if (session.focusedViewId === self.id && (e.ctrlKey || e.metaKey)) {
1265
1280
  if (e.code === 'ArrowLeft') {
1266
1281
  e.preventDefault();
1267
- // pan left
1268
1282
  self.slide(-0.9);
1269
1283
  }
1270
- if (e.code === 'ArrowRight') {
1284
+ else if (e.code === 'ArrowRight') {
1271
1285
  e.preventDefault();
1272
- // pan right
1273
1286
  self.slide(0.9);
1274
1287
  }
1275
- if (e.code === 'ArrowUp' && self.scaleFactor === 1) {
1288
+ else if (e.code === 'ArrowUp' && self.scaleFactor === 1) {
1276
1289
  e.preventDefault();
1277
- // zoom in
1278
1290
  self.zoom(self.bpPerPx / 2);
1279
1291
  }
1280
- if (e.code === 'ArrowDown' && self.scaleFactor === 1) {
1292
+ else if (e.code === 'ArrowDown' && self.scaleFactor === 1) {
1281
1293
  e.preventDefault();
1282
- // zoom out
1283
1294
  self.zoom(self.bpPerPx * 2);
1284
1295
  }
1285
1296
  }