@jbrowse/plugin-linear-genome-view 2.6.3 → 2.7.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.
Files changed (121) hide show
  1. package/dist/BaseLinearDisplay/components/LinearBlocks.d.ts +4 -14
  2. package/dist/BaseLinearDisplay/components/LinearBlocks.js +5 -6
  3. package/dist/BaseLinearDisplay/components/Tooltip.js +1 -1
  4. package/dist/BaseLinearDisplay/models/util.d.ts +2 -6
  5. package/dist/LinearBasicDisplay/components/SetMaxHeight.d.ts +4 -5
  6. package/dist/LinearBasicDisplay/components/SetMaxHeight.js +3 -3
  7. package/dist/LinearBasicDisplay/model.d.ts +3 -1
  8. package/dist/LinearGenomeView/components/CenterLine.d.ts +3 -4
  9. package/dist/LinearGenomeView/components/CenterLine.js +3 -3
  10. package/dist/LinearGenomeView/components/Cytobands.d.ts +6 -2
  11. package/dist/LinearGenomeView/components/Cytobands.js +37 -38
  12. package/dist/LinearGenomeView/components/GetSequenceDialog.d.ts +3 -4
  13. package/dist/LinearGenomeView/components/GetSequenceDialog.js +3 -3
  14. package/dist/LinearGenomeView/components/Gridlines.d.ts +3 -4
  15. package/dist/LinearGenomeView/components/Gridlines.js +21 -18
  16. package/dist/LinearGenomeView/components/ImportForm.d.ts +2 -2
  17. package/dist/LinearGenomeView/components/ImportForm.js +2 -1
  18. package/dist/LinearGenomeView/components/LinearGenomeView.js +19 -1
  19. package/dist/LinearGenomeView/components/MiniControls.js +13 -5
  20. package/dist/LinearGenomeView/components/OverviewRubberband.d.ts +2 -2
  21. package/dist/LinearGenomeView/components/OverviewRubberband.js +2 -1
  22. package/dist/LinearGenomeView/components/OverviewScalebar.d.ts +2 -2
  23. package/dist/LinearGenomeView/components/OverviewScalebar.js +41 -13
  24. package/dist/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +2 -2
  25. package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js +2 -1
  26. package/dist/LinearGenomeView/components/RefNameAutocomplete/util.d.ts +1 -3
  27. package/dist/LinearGenomeView/components/Rubberband.d.ts +4 -5
  28. package/dist/LinearGenomeView/components/Rubberband.js +3 -3
  29. package/dist/LinearGenomeView/components/Scalebar.d.ts +2 -2
  30. package/dist/LinearGenomeView/components/Scalebar.js +29 -24
  31. package/dist/LinearGenomeView/components/SearchBox.d.ts +4 -5
  32. package/dist/LinearGenomeView/components/SearchBox.js +3 -3
  33. package/dist/LinearGenomeView/components/SequenceSearchDialog.d.ts +4 -5
  34. package/dist/LinearGenomeView/components/SequenceSearchDialog.js +20 -18
  35. package/dist/LinearGenomeView/components/TrackContainer.d.ts +2 -2
  36. package/dist/LinearGenomeView/components/TrackContainer.js +2 -1
  37. package/dist/LinearGenomeView/components/TrackLabel.d.ts +2 -2
  38. package/dist/LinearGenomeView/components/TrackLabel.js +5 -21
  39. package/dist/LinearGenomeView/components/TrackLabelDragHandle.d.ts +9 -0
  40. package/dist/LinearGenomeView/components/TrackLabelDragHandle.js +32 -0
  41. package/dist/LinearGenomeView/components/TrackRenderingContainer.d.ts +2 -2
  42. package/dist/LinearGenomeView/components/TrackRenderingContainer.js +2 -1
  43. package/dist/LinearGenomeView/components/TracksContainer.d.ts +2 -2
  44. package/dist/LinearGenomeView/components/TracksContainer.js +2 -1
  45. package/dist/LinearGenomeView/components/VerticalGuide.d.ts +3 -4
  46. package/dist/LinearGenomeView/components/VerticalGuide.js +3 -3
  47. package/dist/LinearGenomeView/components/ZoomControls.d.ts +3 -4
  48. package/dist/LinearGenomeView/components/ZoomControls.js +3 -3
  49. package/dist/LinearGenomeView/components/util.d.ts +1 -1
  50. package/dist/LinearGenomeView/index.d.ts +1 -2
  51. package/dist/LinearGenomeView/index.js +3 -2
  52. package/dist/LinearGenomeView/model.d.ts +6 -6
  53. package/dist/LinearGenomeView/model.js +33 -0
  54. package/dist/LinearGenomeView/svgcomponents/SVGBackground.js +2 -2
  55. package/dist/LinearGenomeView/svgcomponents/SVGHeader.js +1 -4
  56. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +1 -0
  57. package/dist/LinearGenomeView/svgcomponents/SVGRuler.js +2 -3
  58. package/dist/LinearGenomeView/svgcomponents/SVGScalebar.js +1 -2
  59. package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js +3 -1
  60. package/dist/index.d.ts +37 -37
  61. package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +4 -14
  62. package/esm/BaseLinearDisplay/components/LinearBlocks.js +5 -5
  63. package/esm/BaseLinearDisplay/components/Tooltip.js +1 -1
  64. package/esm/BaseLinearDisplay/models/util.d.ts +2 -6
  65. package/esm/LinearBasicDisplay/components/SetMaxHeight.d.ts +4 -5
  66. package/esm/LinearBasicDisplay/components/SetMaxHeight.js +3 -3
  67. package/esm/LinearBasicDisplay/model.d.ts +3 -1
  68. package/esm/LinearGenomeView/components/CenterLine.d.ts +3 -4
  69. package/esm/LinearGenomeView/components/CenterLine.js +3 -3
  70. package/esm/LinearGenomeView/components/Cytobands.d.ts +6 -2
  71. package/esm/LinearGenomeView/components/Cytobands.js +37 -38
  72. package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +3 -4
  73. package/esm/LinearGenomeView/components/GetSequenceDialog.js +3 -3
  74. package/esm/LinearGenomeView/components/Gridlines.d.ts +3 -4
  75. package/esm/LinearGenomeView/components/Gridlines.js +21 -18
  76. package/esm/LinearGenomeView/components/ImportForm.d.ts +2 -2
  77. package/esm/LinearGenomeView/components/ImportForm.js +2 -1
  78. package/esm/LinearGenomeView/components/LinearGenomeView.js +20 -2
  79. package/esm/LinearGenomeView/components/MiniControls.js +13 -5
  80. package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +2 -2
  81. package/esm/LinearGenomeView/components/OverviewRubberband.js +2 -1
  82. package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +2 -2
  83. package/esm/LinearGenomeView/components/OverviewScalebar.js +18 -13
  84. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +2 -2
  85. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +2 -1
  86. package/esm/LinearGenomeView/components/RefNameAutocomplete/util.d.ts +1 -3
  87. package/esm/LinearGenomeView/components/Rubberband.d.ts +4 -5
  88. package/esm/LinearGenomeView/components/Rubberband.js +3 -3
  89. package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -2
  90. package/esm/LinearGenomeView/components/Scalebar.js +29 -24
  91. package/esm/LinearGenomeView/components/SearchBox.d.ts +4 -5
  92. package/esm/LinearGenomeView/components/SearchBox.js +3 -3
  93. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +4 -5
  94. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +21 -19
  95. package/esm/LinearGenomeView/components/TrackContainer.d.ts +2 -2
  96. package/esm/LinearGenomeView/components/TrackContainer.js +2 -1
  97. package/esm/LinearGenomeView/components/TrackLabel.d.ts +2 -2
  98. package/esm/LinearGenomeView/components/TrackLabel.js +5 -21
  99. package/esm/LinearGenomeView/components/TrackLabelDragHandle.d.ts +9 -0
  100. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +27 -0
  101. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +2 -2
  102. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +2 -1
  103. package/esm/LinearGenomeView/components/TracksContainer.d.ts +2 -2
  104. package/esm/LinearGenomeView/components/TracksContainer.js +2 -1
  105. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +3 -4
  106. package/esm/LinearGenomeView/components/VerticalGuide.js +3 -3
  107. package/esm/LinearGenomeView/components/ZoomControls.d.ts +3 -4
  108. package/esm/LinearGenomeView/components/ZoomControls.js +3 -3
  109. package/esm/LinearGenomeView/components/util.d.ts +1 -1
  110. package/esm/LinearGenomeView/index.d.ts +1 -2
  111. package/esm/LinearGenomeView/index.js +2 -2
  112. package/esm/LinearGenomeView/model.d.ts +6 -6
  113. package/esm/LinearGenomeView/model.js +33 -0
  114. package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +2 -2
  115. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +2 -5
  116. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +1 -0
  117. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +3 -4
  118. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +2 -3
  119. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +3 -1
  120. package/esm/index.d.ts +37 -37
  121. package/package.json +4 -5
@@ -25,6 +25,20 @@ function leftRoundedRect(x, y, width, height, radius) {
25
25
  + "a" + radius + "," + radius + " 0 0 1 " + radius + "," + (-radius)
26
26
  + "z";
27
27
  }
28
+ function leftTriangle(x, y, width, height) {
29
+ return [
30
+ [x, 0],
31
+ [x + width, height / 2],
32
+ [x, height],
33
+ ].toString();
34
+ }
35
+ function rightTriangle(x, y, width, height) {
36
+ return [
37
+ [x, height / 2],
38
+ [x + width, 0],
39
+ [x + width, height],
40
+ ].toString();
41
+ }
28
42
  const colorMap = {
29
43
  gneg: 'rgb(227,227,227)',
30
44
  gpos25: 'rgb(142,142,142)',
@@ -35,52 +49,37 @@ const colorMap = {
35
49
  stalk: 'rgb(127,127,127)',
36
50
  acen: '#800',
37
51
  };
38
- export default observer(function Cytobands({ overview, block, assembly, }) {
52
+ const Cytobands = observer(function ({ overview, block, assembly, }) {
39
53
  const { offsetPx, reversed } = block;
40
54
  const cytobands = getCytobands(assembly, block.refName);
41
- const coords = cytobands.map(f => {
42
- const { refName, start, end, type } = f;
43
- return [
44
- overview.bpToPx({
45
- refName,
46
- coord: start,
47
- }),
48
- overview.bpToPx({
49
- refName,
50
- coord: end,
51
- }),
52
- type,
53
- ];
54
- });
55
- const arr = cytobands || [];
56
- const lcap = reversed ? arr.length - 1 : 0;
57
- const rcap = reversed ? 0 : arr.length - 1;
58
- let firstCent = true;
59
- return (React.createElement("g", { transform: `translate(-${offsetPx})` }, coords.map(([start, end, type], index) => {
60
- const key = `${start}-${end}-${type}`;
61
- if (type === 'acen' && firstCent) {
62
- firstCent = false;
63
- return (React.createElement("polygon", { key: key, points: [
64
- [start, 0],
65
- [end, HEADER_OVERVIEW_HEIGHT / 2],
66
- [start, HEADER_OVERVIEW_HEIGHT],
67
- ].toString(), fill: colorMap[type] }));
55
+ const lcap = reversed ? cytobands.length - 1 : 0;
56
+ const rcap = reversed ? 0 : cytobands.length - 1;
57
+ const h = HEADER_OVERVIEW_HEIGHT;
58
+ let centromereSeen = false;
59
+ return (React.createElement("g", { transform: `translate(-${offsetPx})` }, cytobands.map((args, index) => {
60
+ const k = JSON.stringify(args);
61
+ const { refName, type, start, end } = args;
62
+ const s = overview.bpToPx({ refName, coord: start }) || 0;
63
+ const e = overview.bpToPx({ refName, coord: end }) || 0;
64
+ const l = Math.min(s, e);
65
+ const w = Math.abs(e - s);
66
+ const c = colorMap[type];
67
+ if (type === 'acen' && !centromereSeen) {
68
+ centromereSeen = true; // the next acen entry is drawn with different right triangle
69
+ return React.createElement("polygon", { key: k, points: leftTriangle(s, 0, w, h), fill: c });
68
70
  }
69
- if (type === 'acen' && !firstCent) {
70
- return (React.createElement("polygon", { key: key, points: [
71
- [start, HEADER_OVERVIEW_HEIGHT / 2],
72
- [end, 0],
73
- [end, HEADER_OVERVIEW_HEIGHT],
74
- ].toString(), fill: colorMap[type] }));
71
+ else if (type === 'acen' && centromereSeen) {
72
+ return React.createElement("polygon", { key: k, points: rightTriangle(s, 0, w, h), fill: c });
75
73
  }
76
- if (lcap === index) {
77
- return (React.createElement("path", { key: key, d: leftRoundedRect(Math.min(start, end), 0, Math.abs(end - start), HEADER_OVERVIEW_HEIGHT, 8), fill: colorMap[type] }));
74
+ else if (lcap === index) {
75
+ return React.createElement("path", { key: k, d: leftRoundedRect(l, 0, w, h, 8), fill: c });
78
76
  }
79
77
  else if (rcap === index) {
80
- return (React.createElement("path", { key: key, d: rightRoundedRect(Math.min(start, end), 0, Math.abs(end - start) - 2, HEADER_OVERVIEW_HEIGHT, 8), fill: colorMap[type] }));
78
+ return React.createElement("path", { key: k, d: rightRoundedRect(l, 0, w, h, 8), fill: c });
81
79
  }
82
80
  else {
83
- return (React.createElement("rect", { key: key, x: Math.min(start, end), y: 0, width: Math.abs(end - start), height: HEADER_OVERVIEW_HEIGHT, fill: colorMap[type] }));
81
+ return React.createElement("rect", { key: k, x: l, y: 0, width: w, height: h, fill: c });
84
82
  }
85
83
  })));
86
84
  });
85
+ export default Cytobands;
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
2
  import { LinearGenomeViewModel } from '..';
3
3
  type LGV = LinearGenomeViewModel;
4
- declare function SequenceDialog({ model, handleClose, }: {
4
+ declare const GetSequenceDialog: ({ model, handleClose, }: {
5
5
  model: LGV;
6
6
  handleClose: () => void;
7
- }): React.JSX.Element;
8
- declare const _default: typeof SequenceDialog;
9
- export default _default;
7
+ }) => React.JSX.Element;
8
+ export default GetSequenceDialog;
@@ -46,7 +46,7 @@ async function fetchSequence(model, regions, signal) {
46
46
  signal,
47
47
  });
48
48
  }
49
- function SequenceDialog({ model, handleClose, }) {
49
+ const GetSequenceDialog = observer(function ({ model, handleClose, }) {
50
50
  const { classes } = useStyles();
51
51
  const session = getSession(model);
52
52
  const [error, setError] = useState();
@@ -142,5 +142,5 @@ function SequenceDialog({ model, handleClose, }) {
142
142
  }), 'jbrowse_ref_seq.fa');
143
143
  }, disabled: loading || !!error, color: "primary", startIcon: React.createElement(GetAppIcon, null) }, "Download FASTA"),
144
144
  React.createElement(Button, { onClick: handleClose, variant: "contained" }, "Close"))));
145
- }
146
- export default observer(SequenceDialog);
145
+ });
146
+ export default GetSequenceDialog;
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
2
  import { LinearGenomeViewModel } from '..';
3
3
  type LGV = LinearGenomeViewModel;
4
- declare function VerticalGuides({ model }: {
4
+ declare const Gridlines: ({ model }: {
5
5
  model: LGV;
6
- }): React.JSX.Element;
7
- declare const _default: typeof VerticalGuides;
8
- export default _default;
6
+ }) => React.JSX.Element;
7
+ export default Gridlines;
@@ -31,30 +31,33 @@ const useStyles = makeStyles()(theme => ({
31
31
  background: theme.palette.divider,
32
32
  },
33
33
  }));
34
- const RenderedVerticalGuides = observer(({ model }) => {
34
+ function RenderedBlockLines({ block, bpPerPx, }) {
35
35
  const { classes, cx } = useStyles();
36
- return (React.createElement(React.Fragment, null, model.staticBlocks.map((block, index) => {
36
+ const ticks = makeTicks(block.start, block.end, bpPerPx);
37
+ return (React.createElement(ContentBlockComponent, { block: block }, ticks.map(({ type, base }) => {
38
+ const x = (block.reversed ? block.end - base : base - block.start) / bpPerPx;
39
+ return (React.createElement("div", { key: base, className: cx(classes.tick, type === 'major' || type === 'labeledMajor'
40
+ ? classes.majorTick
41
+ : classes.minorTick), style: { left: x } }));
42
+ })));
43
+ }
44
+ const RenderedVerticalGuides = observer(({ model }) => {
45
+ const { staticBlocks, bpPerPx } = model;
46
+ return (React.createElement(React.Fragment, null, staticBlocks.map((block, index) => {
47
+ const k = `${block.key}-${index}`;
37
48
  if (block instanceof ContentBlock) {
38
- const ticks = makeTicks(block.start, block.end, model.bpPerPx);
39
- return (React.createElement(ContentBlockComponent, { key: `${block.key}-${index}`, block: block }, ticks.map(tick => {
40
- const x = (block.reversed
41
- ? block.end - tick.base
42
- : tick.base - block.start) / model.bpPerPx;
43
- return (React.createElement("div", { key: tick.base, className: cx(classes.tick, tick.type === 'major' || tick.type === 'labeledMajor'
44
- ? classes.majorTick
45
- : classes.minorTick), style: { left: x } }));
46
- })));
49
+ return React.createElement(RenderedBlockLines, { key: k, block: block, bpPerPx: bpPerPx });
47
50
  }
48
- if (block instanceof ElidedBlock) {
49
- return React.createElement(ElidedBlockComponent, { key: block.key, width: block.widthPx });
51
+ else if (block instanceof ElidedBlock) {
52
+ return React.createElement(ElidedBlockComponent, { key: k, width: block.widthPx });
50
53
  }
51
- if (block instanceof InterRegionPaddingBlock) {
52
- return (React.createElement(InterRegionPaddingBlockComponent, { key: block.key, width: block.widthPx, boundary: block.variant === 'boundary' }));
54
+ else if (block instanceof InterRegionPaddingBlock) {
55
+ return (React.createElement(InterRegionPaddingBlockComponent, { key: k, width: block.widthPx, boundary: block.variant === 'boundary' }));
53
56
  }
54
57
  return null;
55
58
  })));
56
59
  });
57
- function VerticalGuides({ model }) {
60
+ const Gridlines = observer(function ({ model }) {
58
61
  const { classes } = useStyles();
59
62
  // find the block that needs pinning to the left side for context
60
63
  const offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
@@ -66,5 +69,5 @@ function VerticalGuides({ model }) {
66
69
  width: model.staticBlocks.totalWidthPx,
67
70
  } },
68
71
  React.createElement(RenderedVerticalGuides, { model: model }))));
69
- }
70
- export default observer(VerticalGuides);
72
+ });
73
+ export default Gridlines;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { LinearGenomeViewModel } from '..';
3
3
  type LGV = LinearGenomeViewModel;
4
- declare const _default: ({ model }: {
4
+ declare const LinearGenomeViewImportForm: ({ model, }: {
5
5
  model: LGV;
6
6
  }) => React.JSX.Element;
7
- export default _default;
7
+ export default LinearGenomeViewImportForm;
@@ -20,7 +20,7 @@ const useStyles = makeStyles()(theme => ({
20
20
  padding: theme.spacing(4),
21
21
  },
22
22
  }));
23
- export default observer(function ({ model }) {
23
+ const LinearGenomeViewImportForm = observer(function ({ model, }) {
24
24
  var _a;
25
25
  const { classes } = useStyles();
26
26
  const session = getSession(model);
@@ -140,3 +140,4 @@ export default observer(function ({ model }) {
140
140
  model.showAllRegionsInAssembly(selectedAsm);
141
141
  }, variant: "contained", color: "secondary" }, "Show all regions in assembly"))))))));
142
142
  });
143
+ export default LinearGenomeViewImportForm;
@@ -1,4 +1,4 @@
1
- import React, { lazy } from 'react';
1
+ import React, { lazy, useEffect, useRef } from 'react';
2
2
  import { Button, Paper, Typography } from '@mui/material';
3
3
  import { makeStyles } from 'tss-react/mui';
4
4
  import { LoadingEllipses } from '@jbrowse/core/ui';
@@ -7,6 +7,7 @@ import { observer } from 'mobx-react';
7
7
  import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
8
8
  import TrackContainer from './TrackContainer';
9
9
  import TracksContainer from './TracksContainer';
10
+ import { getSession } from '@jbrowse/core/util';
10
11
  const ImportForm = lazy(() => import('./ImportForm'));
11
12
  const useStyles = makeStyles()(theme => ({
12
13
  note: {
@@ -18,6 +19,23 @@ const useStyles = makeStyles()(theme => ({
18
19
  const LinearGenomeView = observer(({ model }) => {
19
20
  const { tracks, error, initialized, hasDisplayedRegions } = model;
20
21
  const { classes } = useStyles();
22
+ const ref = useRef(null);
23
+ const session = getSession(model);
24
+ useEffect(() => {
25
+ // sets the focused view id based on a click within the LGV; necessary for subviews to be focused properly
26
+ function handleSelectView(e) {
27
+ var _a, _b;
28
+ 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))) {
29
+ (_b = session.setFocusedViewId) === null || _b === void 0 ? void 0 : _b.call(session, model.id);
30
+ }
31
+ }
32
+ document.addEventListener('mousedown', handleSelectView);
33
+ document.addEventListener('keydown', handleSelectView);
34
+ return () => {
35
+ document.removeEventListener('mousedown', handleSelectView);
36
+ document.removeEventListener('keydown', handleSelectView);
37
+ };
38
+ }, [session, model]);
21
39
  if (!initialized && !error) {
22
40
  return React.createElement(LoadingEllipses, { variant: "h6" });
23
41
  }
@@ -26,7 +44,7 @@ const LinearGenomeView = observer(({ model }) => {
26
44
  }
27
45
  const MiniControlsComponent = model.MiniControlsComponent();
28
46
  const HeaderComponent = model.HeaderComponent();
29
- return (React.createElement("div", { style: { position: 'relative' } },
47
+ return (React.createElement("div", { style: { position: 'relative' }, ref: ref },
30
48
  React.createElement(HeaderComponent, { model: model }),
31
49
  React.createElement(MiniControlsComponent, { model: model }),
32
50
  React.createElement(TracksContainer, { model: model }, !tracks.length ? (React.createElement(Paper, { variant: "outlined", className: classes.note }, !model.hideNoTracksActive ? (React.createElement(React.Fragment, null,
@@ -7,23 +7,31 @@ import ZoomOut from '@mui/icons-material/ZoomOut';
7
7
  import ArrowDown from '@mui/icons-material/KeyboardArrowDown';
8
8
  import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
9
9
  import { makeStyles } from 'tss-react/mui';
10
+ import { getSession } from '@jbrowse/core/util';
10
11
  const useStyles = makeStyles()(theme => ({
11
- bg: {
12
+ background: {
12
13
  position: 'absolute',
13
14
  right: 0,
14
15
  zIndex: 1001,
15
16
  background: theme.palette.background.paper,
16
17
  },
18
+ focusedBackground: {
19
+ background: theme.palette.secondary.light,
20
+ svg: {
21
+ fill: theme.palette.secondary.contrastText,
22
+ },
23
+ },
17
24
  }));
18
25
  const MiniControls = observer(function ({ model, }) {
19
- const { classes } = useStyles();
20
- const { bpPerPx, maxBpPerPx, minBpPerPx, scaleFactor, hideHeader } = model;
21
- return hideHeader ? (React.createElement(Paper, { className: classes.bg },
26
+ const { classes, cx } = useStyles();
27
+ const { id, bpPerPx, maxBpPerPx, minBpPerPx, scaleFactor, hideHeader } = model;
28
+ const { focusedViewId } = getSession(model);
29
+ return hideHeader ? (React.createElement(Paper, { className: cx(classes.background, focusedViewId === id ? classes.focusedBackground : undefined) },
22
30
  React.createElement(CascadingMenuButton, { menuItems: model.menuItems() },
23
31
  React.createElement(ArrowDown, { fontSize: "small" })),
24
32
  React.createElement(IconButton, { "data-testid": "zoom_out", onClick: () => model.zoom(bpPerPx * 2), disabled: bpPerPx >= maxBpPerPx - 0.0001 || scaleFactor !== 1 },
25
33
  React.createElement(ZoomOut, { fontSize: "small" })),
26
- React.createElement(IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(model.bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1 },
34
+ React.createElement(IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1 },
27
35
  React.createElement(ZoomIn, { fontSize: "small" })))) : null;
28
36
  });
29
37
  export default MiniControls;
@@ -2,9 +2,9 @@ import React from 'react';
2
2
  import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel';
3
3
  import { LinearGenomeViewModel } from '..';
4
4
  type LGV = LinearGenomeViewModel;
5
- declare const _default: ({ model, overview, ControlComponent, }: {
5
+ declare const OverviewRubberband: ({ model, overview, ControlComponent, }: {
6
6
  model: LGV;
7
7
  overview: Base1DViewModel;
8
8
  ControlComponent?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
9
9
  }) => React.JSX.Element;
10
- export default _default;
10
+ export default OverviewRubberband;
@@ -32,7 +32,7 @@ const HoverTooltip = observer(function ({ model, open, guideX, overview, }) {
32
32
  return (React.createElement(Tooltip, { open: open, placement: "top", title: [stringify(px), cytoband === null || cytoband === void 0 ? void 0 : cytoband.get('name')].join(' '), arrow: true },
33
33
  React.createElement("div", { className: classes.guide, style: { left: guideX } })));
34
34
  });
35
- export default observer(function OverviewRubberband({ model, overview, ControlComponent = React.createElement("div", null), }) {
35
+ const OverviewRubberband = observer(function OverviewRubberband({ model, overview, ControlComponent = React.createElement("div", null), }) {
36
36
  const { cytobandOffset } = model;
37
37
  const [startX, setStartX] = useState();
38
38
  const [currentX, setCurrentX] = useState();
@@ -128,3 +128,4 @@ export default observer(function OverviewRubberband({ model, overview, ControlCo
128
128
  leftBpOffset && rightBpOffset ? (React.createElement(RubberbandSpan, { leftBpOffset: leftBpOffset, rightBpOffset: rightBpOffset, width: Math.abs(width), left: left })) : null,
129
129
  React.createElement("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, ref: controlsRef, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove }, ControlComponent)));
130
130
  });
131
+ export default OverviewRubberband;
@@ -7,10 +7,10 @@ declare const Polygon: ({ model, overview, useOffset, }: {
7
7
  useOffset?: boolean | undefined;
8
8
  }) => React.JSX.Element | null;
9
9
  type LGV = LinearGenomeViewModel;
10
- declare const _default: ({ model, children, }: {
10
+ declare const OverviewScalebar: ({ model, children, }: {
11
11
  model: LGV;
12
12
  children: React.ReactNode;
13
13
  }) => React.JSX.Element;
14
- export default _default;
15
14
  export { Polygon };
16
15
  export { default as Cytobands } from './Cytobands';
16
+ export default OverviewScalebar;
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import { Typography, useTheme, alpha } from '@mui/material';
3
3
  import { makeStyles } from 'tss-react/mui';
4
4
  import { observer } from 'mobx-react';
@@ -76,9 +76,7 @@ const Polygon = observer(function ({ model, overview, useOffset = true, }) {
76
76
  if (!contentBlocks.length) {
77
77
  return null;
78
78
  }
79
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
80
79
  const first = contentBlocks.at(0);
81
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
82
80
  const last = contentBlocks.at(-1);
83
81
  const topLeft = (overview.bpToPx({
84
82
  ...first,
@@ -155,9 +153,7 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
155
153
  if (!visibleRegions.length) {
156
154
  return null;
157
155
  }
158
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
159
156
  const first = visibleRegions.at(0);
160
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
161
157
  const last = visibleRegions.at(-1);
162
158
  const firstOverviewPx = overview.bpToPx({
163
159
  ...first,
@@ -185,17 +181,25 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
185
181
  } })) : (React.createElement(OverviewBox, { scale: scale, block: block, model: model, overview: overview, key: `${JSON.stringify(block)}-${idx}` }));
186
182
  })));
187
183
  });
188
- export default observer(function OverviewScalebar({ model, children, }) {
184
+ const OverviewScalebar = observer(function ({ model, children, }) {
189
185
  const { classes } = useStyles();
190
186
  const { totalBp, width, cytobandOffset, displayedRegions } = model;
191
- const overview = Base1DView.create({
192
- displayedRegions: JSON.parse(JSON.stringify(displayedRegions)),
193
- interRegionPaddingWidth: 0,
194
- minimumBlockWidth: model.minimumBlockWidth,
195
- });
196
187
  const modWidth = width - cytobandOffset;
197
- overview.setVolatileWidth(modWidth);
198
- overview.showAllRegions();
188
+ const overview = useMemo(() => {
189
+ const overview = Base1DView.create({
190
+ displayedRegions: JSON.parse(JSON.stringify(displayedRegions)),
191
+ interRegionPaddingWidth: 0,
192
+ minimumBlockWidth: model.minimumBlockWidth,
193
+ });
194
+ overview.setVolatileWidth(modWidth);
195
+ overview.showAllRegions();
196
+ return overview;
197
+ }, [
198
+ JSON.stringify(displayedRegions),
199
+ model.minimumBlockWidth,
200
+ modWidth,
201
+ displayedRegions,
202
+ ]);
199
203
  const scale = totalBp / (modWidth - (displayedRegions.length - 1) * wholeSeqSpacer);
200
204
  return (React.createElement("div", null,
201
205
  React.createElement(OverviewRubberband, { model: model, overview: overview, ControlComponent: React.createElement(Scalebar, { model: model, overview: overview, scale: scale }) }),
@@ -206,3 +210,4 @@ export default observer(function OverviewScalebar({ model, children, }) {
206
210
  });
207
211
  export { Polygon };
208
212
  export { default as Cytobands } from './Cytobands';
213
+ export default OverviewScalebar;
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
3
3
  import { TextFieldProps as TFP } from '@mui/material';
4
4
  import { LinearGenomeViewModel } from '../../model';
5
- declare const _default: ({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp, minWidth, maxWidth, TextFieldProps, }: {
5
+ declare const RefNameAutocomplete: ({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp, minWidth, maxWidth, TextFieldProps, }: {
6
6
  model: LinearGenomeViewModel;
7
7
  onSelect?: ((region: BaseResult) => void) | undefined;
8
8
  onChange?: ((val: string) => void) | undefined;
@@ -15,4 +15,4 @@ declare const _default: ({ model, onSelect, assemblyName, style, fetchResults, o
15
15
  showHelp?: boolean | undefined;
16
16
  TextFieldProps?: TFP | undefined;
17
17
  }) => React.JSX.Element;
18
- export default _default;
18
+ export default RefNameAutocomplete;
@@ -5,7 +5,7 @@ import BaseResult, { RefSequenceResult, } from '@jbrowse/core/TextSearch/BaseRes
5
5
  import { Autocomplete } from '@mui/material';
6
6
  import { getDeduplicatedResult, getFiltered } from './util';
7
7
  import AutocompleteTextField from './AutocompleteTextField';
8
- export default observer(function RefNameAutocomplete({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp = true, minWidth = 200, maxWidth = 550, TextFieldProps = {}, }) {
8
+ const RefNameAutocomplete = observer(function ({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp = true, minWidth = 200, maxWidth = 550, TextFieldProps = {}, }) {
9
9
  var _a;
10
10
  const session = getSession(model);
11
11
  const { assemblyManager } = session;
@@ -80,3 +80,4 @@ export default observer(function RefNameAutocomplete({ model, onSelect, assembly
80
80
  }))) || []
81
81
  : searchOptions, getOptionDisabled: option => option.group === 'limitOption', filterOptions: (opts, { inputValue }) => getFiltered(opts, inputValue), renderInput: params => (React.createElement(AutocompleteTextField, { showHelp: showHelp, params: params, inputBoxVal: inputBoxVal, TextFieldProps: TextFieldProps, setCurrentSearch: setCurrentSearch, setInputValue: setInputValue })), getOptionLabel: opt => typeof opt === 'string' ? opt : opt.result.getDisplayString() })));
82
82
  });
83
+ export default RefNameAutocomplete;
@@ -4,9 +4,7 @@ export interface Option {
4
4
  result: BaseResult;
5
5
  }
6
6
  export declare function getFiltered(opts: Option[], inputValue: string): Option[];
7
- export declare function aggregateResults(results: BaseResult[]): {
8
- [key: string]: BaseResult[];
9
- };
7
+ export declare function aggregateResults(results: BaseResult[]): Record<string, BaseResult[]>;
10
8
  export declare function getDeduplicatedResult(results: BaseResult[]): {
11
9
  result: BaseResult;
12
10
  }[];
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
2
  import { LinearGenomeViewModel } from '..';
3
3
  type LGV = LinearGenomeViewModel;
4
- declare function Rubberband({ model, ControlComponent, }: {
4
+ declare const Rubberband: ({ model, ControlComponent, }: {
5
5
  model: LGV;
6
- ControlComponent?: React.ReactElement;
7
- }): React.JSX.Element;
8
- declare const _default: typeof Rubberband;
9
- export default _default;
6
+ ControlComponent?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
7
+ }) => React.JSX.Element;
8
+ export default Rubberband;
@@ -13,7 +13,7 @@ const useStyles = makeStyles()({
13
13
  minHeight: 8,
14
14
  },
15
15
  });
16
- function Rubberband({ model, ControlComponent = React.createElement("div", null), }) {
16
+ const Rubberband = observer(function ({ model, ControlComponent = React.createElement("div", null), }) {
17
17
  const ref = useRef(null);
18
18
  const { classes } = useStyles();
19
19
  const { guideX, rubberbandOn, leftBpOffset, rightBpOffset, numOfBpSelected, width, left, anchorPosition, handleMenuItemClick, open, handleClose, mouseMove, mouseDown, mouseOut, } = useRangeSelect(ref, model);
@@ -24,5 +24,5 @@ function Rubberband({ model, ControlComponent = React.createElement("div", null)
24
24
  top: anchorPosition.clientY,
25
25
  }, onMenuItemClick: handleMenuItemClick, open: open, onClose: handleClose, menuItems: model.rubberBandMenuItems() })) : null,
26
26
  React.createElement("div", { "data-testid": "rubberband_controls", className: classes.rubberbandControl, ref: ref, onMouseDown: mouseDown, onMouseMove: mouseMove, onMouseOut: mouseOut }, ControlComponent)));
27
- }
28
- export default observer(Rubberband);
27
+ });
28
+ export default Rubberband;
@@ -6,5 +6,5 @@ interface ScalebarProps {
6
6
  style?: React.CSSProperties;
7
7
  className?: string;
8
8
  }
9
- declare const _default: React.ForwardRefExoticComponent<ScalebarProps & React.RefAttributes<HTMLDivElement>>;
10
- export default _default;
9
+ declare const Scalebar: React.ForwardRefExoticComponent<ScalebarProps & React.RefAttributes<HTMLDivElement>>;
10
+ export default Scalebar;
@@ -21,7 +21,7 @@ const useStyles = makeStyles()(theme => ({
21
21
  pointerEvents: 'none',
22
22
  },
23
23
  majorTickLabel: {
24
- fontSize: '11px',
24
+ fontSize: 11,
25
25
  zIndex: 1,
26
26
  background: theme.palette.background.paper,
27
27
  lineHeight: 'normal',
@@ -35,10 +35,10 @@ const useStyles = makeStyles()(theme => ({
35
35
  pointerEvents: 'none',
36
36
  },
37
37
  refLabel: {
38
- fontSize: '11px',
38
+ fontSize: 11,
39
39
  position: 'absolute',
40
- left: '2px',
41
- top: '-1px',
40
+ left: 2,
41
+ top: -1,
42
42
  fontWeight: 'bold',
43
43
  lineHeight: 'normal',
44
44
  zIndex: 1,
@@ -65,32 +65,37 @@ const RenderedRefNameLabels = observer(({ model }) => {
65
65
  }, className: classes.refLabel, "data-testid": `refLabel-${block.refName}` }, block.refName)) : null;
66
66
  })));
67
67
  });
68
- const RenderedScalebarLabels = observer(({ model }) => {
68
+ const RenderedBlockTicks = function ({ block, bpPerPx, }) {
69
69
  const { classes } = useStyles();
70
- const { bpPerPx, staticBlocks } = model;
71
- return (React.createElement(React.Fragment, null, staticBlocks.map((block, index) => {
72
- const { reversed, start, end, key, widthPx } = block;
70
+ const { reversed, start, end } = block;
71
+ const ticks = makeTicks(start, end, bpPerPx, true, false);
72
+ return (React.createElement(ContentBlockComponent, { block: block }, ticks.map(({ type, base }) => {
73
+ if (type === 'major') {
74
+ const x = (reversed ? end - base : base - start) / bpPerPx;
75
+ const baseNumber = base + 1;
76
+ return (React.createElement("div", { key: base, className: classes.tick, style: { left: x } }, baseNumber ? (React.createElement(Typography, { className: classes.majorTickLabel }, getTickDisplayStr(baseNumber, bpPerPx))) : null));
77
+ }
78
+ return null;
79
+ })));
80
+ };
81
+ const RenderedScalebarLabels = observer(({ model }) => {
82
+ const { staticBlocks, bpPerPx } = model;
83
+ return (React.createElement(React.Fragment, null, staticBlocks.map((block, idx) => {
84
+ const { key, widthPx } = block;
85
+ const k = `${key}-${idx}`;
73
86
  if (block instanceof ContentBlock) {
74
- const ticks = makeTicks(start, end, bpPerPx, true, false);
75
- return (React.createElement(ContentBlockComponent, { key: `${key}-${index}`, block: block }, ticks.map(tick => {
76
- if (tick.type === 'major') {
77
- const x = (reversed ? end - tick.base : tick.base - start) / bpPerPx;
78
- const baseNumber = tick.base + 1;
79
- return (React.createElement("div", { key: tick.base, className: classes.tick, style: { left: x } }, baseNumber ? (React.createElement(Typography, { className: classes.majorTickLabel }, getTickDisplayStr(baseNumber, bpPerPx))) : null));
80
- }
81
- return null;
82
- })));
87
+ return React.createElement(RenderedBlockTicks, { key: k, block: block, bpPerPx: bpPerPx });
83
88
  }
84
- if (block instanceof ElidedBlock) {
85
- return React.createElement(ElidedBlockComponent, { key: key, width: widthPx });
89
+ else if (block instanceof ElidedBlock) {
90
+ return React.createElement(ElidedBlockComponent, { key: k, width: widthPx });
86
91
  }
87
- if (block instanceof InterRegionPaddingBlock) {
88
- return (React.createElement(InterRegionPaddingBlockComponent, { key: key, width: widthPx, style: { background: 'none' }, boundary: block.variant === 'boundary' }));
92
+ else if (block instanceof InterRegionPaddingBlock) {
93
+ return (React.createElement(InterRegionPaddingBlockComponent, { key: k, width: widthPx, style: { background: 'none' }, boundary: block.variant === 'boundary' }));
89
94
  }
90
95
  return null;
91
96
  })));
92
97
  });
93
- const Scalebar = React.forwardRef(({ model, style, className, ...other }, ref) => {
98
+ const Scalebar = observer(React.forwardRef(function Scalebar2({ model, style, className, ...other }, ref) {
94
99
  const { classes, cx } = useStyles();
95
100
  const offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
96
101
  return (React.createElement(Paper, { "data-resizer": "true" // used to avoid click-and-drag scrolls on trackscontainer
@@ -107,5 +112,5 @@ const Scalebar = React.forwardRef(({ model, style, className, ...other }, ref) =
107
112
  } },
108
113
  React.createElement(RenderedScalebarLabels, { model: model }))),
109
114
  React.createElement(RenderedRefNameLabels, { model: model })));
110
- });
111
- export default observer(Scalebar);
115
+ }));
116
+ export default Scalebar;
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
2
  import { LinearGenomeViewModel } from '..';
3
- declare function SearchBox({ model, showHelp, }: {
4
- showHelp?: boolean;
3
+ declare const SearchBox: ({ model, showHelp, }: {
4
+ showHelp?: boolean | undefined;
5
5
  model: LinearGenomeViewModel;
6
- }): React.JSX.Element;
7
- declare const _default: typeof SearchBox;
8
- export default _default;
6
+ }) => React.JSX.Element;
7
+ export default SearchBox;
@@ -12,7 +12,7 @@ const useStyles = makeStyles()(() => ({
12
12
  minWidth: 100,
13
13
  },
14
14
  }));
15
- function SearchBox({ model, showHelp, }) {
15
+ const SearchBox = observer(function ({ model, showHelp, }) {
16
16
  const { classes } = useStyles();
17
17
  const theme = useTheme();
18
18
  const session = getSession(model);
@@ -97,5 +97,5 @@ function SearchBox({ model, showHelp, }) {
97
97
  },
98
98
  },
99
99
  } }));
100
- }
101
- export default observer(SearchBox);
100
+ });
101
+ export default SearchBox;
@@ -1,10 +1,9 @@
1
1
  import React from 'react';
2
- declare function SequenceDialog({ model, handleClose, }: {
2
+ declare const SequenceSearchDialog: ({ model, handleClose, }: {
3
3
  model: {
4
4
  assemblyNames: string[];
5
- toggleTrack(trackId: string): void;
5
+ showTrack: (trackId: string) => void;
6
6
  };
7
7
  handleClose: () => void;
8
- }): React.JSX.Element;
9
- declare const _default: typeof SequenceDialog;
10
- export default _default;
8
+ }) => React.JSX.Element;
9
+ export default SequenceSearchDialog;