@jbrowse/plugin-linear-genome-view 2.10.3 → 2.11.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 (80) hide show
  1. package/dist/BaseLinearDisplay/components/Tooltip.js +1 -0
  2. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -1
  3. package/dist/BasicTrack/index.d.ts +1 -2
  4. package/dist/BasicTrack/index.js +3 -2
  5. package/dist/FeatureTrack/index.d.ts +1 -2
  6. package/dist/FeatureTrack/index.js +3 -2
  7. package/dist/LaunchLinearGenomeView/index.d.ts +1 -2
  8. package/dist/LaunchLinearGenomeView/index.js +17 -8
  9. package/dist/LinearBareDisplay/index.d.ts +1 -2
  10. package/dist/LinearBareDisplay/index.js +3 -2
  11. package/dist/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -1
  12. package/dist/LinearBasicDisplay/index.d.ts +1 -2
  13. package/dist/LinearBasicDisplay/index.js +3 -2
  14. package/dist/LinearGenomeView/components/Cytobands.d.ts +1 -125
  15. package/dist/LinearGenomeView/components/Cytobands.js +11 -12
  16. package/dist/LinearGenomeView/components/ExportSvgDialog.js +9 -5
  17. package/dist/LinearGenomeView/components/Highlight.d.ts +3 -3
  18. package/dist/LinearGenomeView/components/Highlight.js +21 -17
  19. package/dist/LinearGenomeView/components/MiniControls.js +13 -15
  20. package/dist/LinearGenomeView/components/OverviewHighlight.d.ts +1 -1
  21. package/dist/LinearGenomeView/components/OverviewHighlight.js +20 -11
  22. package/dist/LinearGenomeView/components/OverviewRubberband.d.ts +1 -1
  23. package/dist/LinearGenomeView/components/OverviewScalebar.js +4 -1
  24. package/dist/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +1 -1
  25. package/dist/LinearGenomeView/components/OverviewScalebarPolygon.js +2 -1
  26. package/dist/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +9 -9
  27. package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js +28 -35
  28. package/dist/LinearGenomeView/components/Rubberband.d.ts +1 -1
  29. package/dist/LinearGenomeView/components/SearchBox.d.ts +1 -1
  30. package/dist/LinearGenomeView/components/SearchResultsTable.js +1 -1
  31. package/dist/LinearGenomeView/components/TrackContainer.js +10 -23
  32. package/dist/LinearGenomeView/components/TrackLabel.js +33 -6
  33. package/dist/LinearGenomeView/components/ZoomControls.js +4 -4
  34. package/dist/LinearGenomeView/model.d.ts +67 -7
  35. package/dist/LinearGenomeView/model.js +102 -16
  36. package/dist/LinearGenomeView/svgcomponents/SVGHeader.js +1 -1
  37. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +1 -1
  38. package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js +1 -1
  39. package/dist/index.d.ts +159 -21
  40. package/esm/BaseLinearDisplay/components/Tooltip.js +1 -0
  41. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -1
  42. package/esm/BasicTrack/index.d.ts +1 -2
  43. package/esm/BasicTrack/index.js +2 -2
  44. package/esm/FeatureTrack/index.d.ts +1 -2
  45. package/esm/FeatureTrack/index.js +2 -2
  46. package/esm/LaunchLinearGenomeView/index.d.ts +1 -2
  47. package/esm/LaunchLinearGenomeView/index.js +16 -8
  48. package/esm/LinearBareDisplay/index.d.ts +1 -2
  49. package/esm/LinearBareDisplay/index.js +2 -2
  50. package/esm/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -1
  51. package/esm/LinearBasicDisplay/index.d.ts +1 -2
  52. package/esm/LinearBasicDisplay/index.js +2 -2
  53. package/esm/LinearGenomeView/components/Cytobands.d.ts +1 -125
  54. package/esm/LinearGenomeView/components/Cytobands.js +11 -12
  55. package/esm/LinearGenomeView/components/ExportSvgDialog.js +9 -5
  56. package/esm/LinearGenomeView/components/Highlight.d.ts +3 -3
  57. package/esm/LinearGenomeView/components/Highlight.js +21 -17
  58. package/esm/LinearGenomeView/components/MiniControls.js +14 -16
  59. package/esm/LinearGenomeView/components/OverviewHighlight.d.ts +1 -1
  60. package/esm/LinearGenomeView/components/OverviewHighlight.js +20 -11
  61. package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +1 -1
  62. package/esm/LinearGenomeView/components/OverviewScalebar.js +5 -2
  63. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +1 -1
  64. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +2 -1
  65. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +9 -9
  66. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +28 -35
  67. package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -1
  68. package/esm/LinearGenomeView/components/SearchBox.d.ts +1 -1
  69. package/esm/LinearGenomeView/components/SearchResultsTable.js +1 -1
  70. package/esm/LinearGenomeView/components/TrackContainer.js +10 -23
  71. package/esm/LinearGenomeView/components/TrackLabel.js +33 -6
  72. package/esm/LinearGenomeView/components/TracksContainer.js +2 -2
  73. package/esm/LinearGenomeView/components/ZoomControls.js +4 -4
  74. package/esm/LinearGenomeView/model.d.ts +67 -7
  75. package/esm/LinearGenomeView/model.js +103 -17
  76. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +1 -1
  77. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +1 -1
  78. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +2 -2
  79. package/esm/index.d.ts +159 -21
  80. package/package.json +2 -2
@@ -4,131 +4,7 @@ import { ContentBlock } from '@jbrowse/core/util/blockTypes';
4
4
  import { Assembly } from '@jbrowse/core/assemblyManager/assembly';
5
5
  declare const Cytobands: ({ overview, block, assembly, }: {
6
6
  overview: Base1DViewModel;
7
- assembly?: ({
8
- configuration: any;
9
- } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
10
- error: unknown;
11
- loaded: boolean;
12
- loadingP: Promise<void> | undefined;
13
- volatileRegions: import("@jbrowse/core/assemblyManager/assembly").BasicRegion[] | undefined;
14
- refNameAliases: {
15
- [x: string]: string | undefined;
16
- } | undefined;
17
- lowerCaseRefNameAliases: {
18
- [x: string]: string | undefined;
19
- } | undefined;
20
- cytobands: import("@jbrowse/core/util").Feature[] | undefined;
21
- } & {
22
- getConf(arg: string): any;
23
- } & {
24
- readonly initialized: boolean;
25
- readonly name: string;
26
- readonly regions: import("@jbrowse/core/assemblyManager/assembly").BasicRegion[] | undefined;
27
- readonly aliases: string[];
28
- readonly displayName: string | undefined;
29
- hasName(name: string): boolean;
30
- readonly allAliases: string[];
31
- readonly allRefNames: string[] | undefined;
32
- readonly lowerCaseRefNames: string[] | undefined;
33
- readonly allRefNamesWithLowerCase: string[] | undefined;
34
- readonly rpcManager: import("@jbrowse/core/rpc/RpcManager").default;
35
- readonly refNameColors: string[];
36
- } & {
37
- readonly refNames: string[] | undefined;
38
- } & {
39
- getCanonicalRefName(refName: string): string | undefined;
40
- getRefNameColor(refName: string): string | undefined;
41
- isValidRefName(refName: string): boolean;
42
- } & {
43
- setLoaded({ adapterRegionsWithAssembly, refNameAliases, lowerCaseRefNameAliases, cytobands, }: import("@jbrowse/core/assemblyManager/assembly").Loading): void;
44
- setError(e: unknown): void;
45
- setRegions(regions: import("@jbrowse/core/util").Region[]): void;
46
- setRefNameAliases(aliases: {
47
- [x: string]: string | undefined;
48
- }, lcAliases: {
49
- [x: string]: string | undefined;
50
- }): void;
51
- setCytobands(cytobands: import("@jbrowse/core/util").Feature[]): void;
52
- setLoadingP(p?: Promise<void> | undefined): void;
53
- load(): Promise<void>;
54
- loadPre(): Promise<void>;
55
- } & {
56
- getAdapterMapEntry(adapterConf: {
57
- [x: string]: unknown;
58
- }, options: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<import("@jbrowse/core/assemblyManager/assembly").RefNameMap>;
59
- getRefNameMapForAdapter(adapterConf: {
60
- [x: string]: unknown;
61
- }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
62
- [x: string]: string | undefined;
63
- }>;
64
- getReverseRefNameMapForAdapter(adapterConf: {
65
- [x: string]: unknown;
66
- }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
67
- [x: string]: string | undefined;
68
- }>;
69
- } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
70
- configuration: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
71
- }, {
72
- error: unknown;
73
- loaded: boolean;
74
- loadingP: Promise<void> | undefined;
75
- volatileRegions: import("@jbrowse/core/assemblyManager/assembly").BasicRegion[] | undefined;
76
- refNameAliases: {
77
- [x: string]: string | undefined;
78
- } | undefined;
79
- lowerCaseRefNameAliases: {
80
- [x: string]: string | undefined;
81
- } | undefined;
82
- cytobands: import("@jbrowse/core/util").Feature[] | undefined;
83
- } & {
84
- getConf(arg: string): any;
85
- } & {
86
- readonly initialized: boolean;
87
- readonly name: string;
88
- readonly regions: import("@jbrowse/core/assemblyManager/assembly").BasicRegion[] | undefined;
89
- readonly aliases: string[];
90
- readonly displayName: string | undefined;
91
- hasName(name: string): boolean;
92
- readonly allAliases: string[];
93
- readonly allRefNames: string[] | undefined;
94
- readonly lowerCaseRefNames: string[] | undefined;
95
- readonly allRefNamesWithLowerCase: string[] | undefined;
96
- readonly rpcManager: import("@jbrowse/core/rpc/RpcManager").default;
97
- readonly refNameColors: string[];
98
- } & {
99
- readonly refNames: string[] | undefined;
100
- } & {
101
- getCanonicalRefName(refName: string): string | undefined;
102
- getRefNameColor(refName: string): string | undefined;
103
- isValidRefName(refName: string): boolean;
104
- } & {
105
- setLoaded({ adapterRegionsWithAssembly, refNameAliases, lowerCaseRefNameAliases, cytobands, }: import("@jbrowse/core/assemblyManager/assembly").Loading): void;
106
- setError(e: unknown): void;
107
- setRegions(regions: import("@jbrowse/core/util").Region[]): void;
108
- setRefNameAliases(aliases: {
109
- [x: string]: string | undefined;
110
- }, lcAliases: {
111
- [x: string]: string | undefined;
112
- }): void;
113
- setCytobands(cytobands: import("@jbrowse/core/util").Feature[]): void;
114
- setLoadingP(p?: Promise<void> | undefined): void;
115
- load(): Promise<void>;
116
- loadPre(): Promise<void>;
117
- } & {
118
- getAdapterMapEntry(adapterConf: {
119
- [x: string]: unknown;
120
- }, options: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<import("@jbrowse/core/assemblyManager/assembly").RefNameMap>;
121
- getRefNameMapForAdapter(adapterConf: {
122
- [x: string]: unknown;
123
- }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
124
- [x: string]: string | undefined;
125
- }>;
126
- getReverseRefNameMapForAdapter(adapterConf: {
127
- [x: string]: unknown;
128
- }, opts: import("@jbrowse/core/data_adapters/BaseAdapter").BaseOptions): Promise<{
129
- [x: string]: string | undefined;
130
- }>;
131
- }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>) | undefined;
7
+ assembly?: Assembly;
132
8
  block: ContentBlock;
133
9
  }) => React.JSX.Element;
134
10
  export default Cytobands;
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
3
3
  // locals
4
4
  import { HEADER_OVERVIEW_HEIGHT } from '..';
5
5
  import { getCytobands } from './util';
6
+ import { getFillProps } from '@jbrowse/core/util';
6
7
  // rounded rect from https://stackoverflow.com/a/45889603/2129219
7
8
  // prettier-ignore
8
9
  function rightRoundedRect(x, y, width, height, radius) {
@@ -63,28 +64,26 @@ const Cytobands = observer(function ({ overview, block, assembly, }) {
63
64
  const e = overview.bpToPx({ refName, coord: end }) || 0;
64
65
  const l = Math.min(s, e);
65
66
  const w = Math.abs(e - s);
66
- const c = colorMap[type];
67
+ const c = colorMap[type] || 'black';
67
68
  if (type === 'acen' && !centromereSeen) {
68
69
  centromereSeen = true; // the next acen entry is drawn with different right triangle
69
- const tri = reversed
70
- ? rightTriangle(s - w, 0, w, h)
71
- : leftTriangle(s, 0, w, h);
72
- return React.createElement("polygon", { key: k, points: tri, fill: c });
70
+ return (React.createElement("polygon", { key: k, points: reversed
71
+ ? rightTriangle(s - w, 0, w, h)
72
+ : leftTriangle(s, 0, w, h), ...getFillProps(c) }));
73
73
  }
74
74
  else if (type === 'acen' && centromereSeen) {
75
- const tri = reversed
76
- ? leftTriangle(s - w, 0, w, h)
77
- : rightTriangle(s, 0, w, h);
78
- return React.createElement("polygon", { key: k, points: tri, fill: c });
75
+ return (React.createElement("polygon", { key: k, points: reversed
76
+ ? leftTriangle(s - w, 0, w, h)
77
+ : rightTriangle(s, 0, w, h), ...getFillProps(c) }));
79
78
  }
80
79
  else if (lcap === index) {
81
- return React.createElement("path", { key: k, d: leftRoundedRect(l, 0, w, h, 8), fill: c });
80
+ return (React.createElement("path", { key: k, d: leftRoundedRect(l, 0, w, h, 8), ...getFillProps(c) }));
82
81
  }
83
82
  else if (rcap === index) {
84
- return React.createElement("path", { key: k, d: rightRoundedRect(l, 0, w, h, 8), fill: c });
83
+ return (React.createElement("path", { key: k, d: rightRoundedRect(l, 0, w, h, 8), ...getFillProps(c) }));
85
84
  }
86
85
  else {
87
- return React.createElement("rect", { key: k, x: l, y: 0, width: w, height: h, fill: c });
86
+ return (React.createElement("rect", { key: k, x: l, y: 0, width: w, height: h, ...getFillProps(c) }));
88
87
  }
89
88
  })));
90
89
  });
@@ -10,6 +10,10 @@ function LoadingMessage() {
10
10
  function useSvgLocal(key, val) {
11
11
  return useLocalStorage('svg-' + key, val);
12
12
  }
13
+ function TextField2({ children, ...rest }) {
14
+ return (React.createElement("div", null,
15
+ React.createElement(TextField, { ...rest }, children)));
16
+ }
13
17
  export default function ExportSvgDialog({ model, handleClose, }) {
14
18
  const session = getSession(model);
15
19
  const offscreenCanvas = typeof OffscreenCanvas !== 'undefined';
@@ -22,15 +26,13 @@ export default function ExportSvgDialog({ model, handleClose, }) {
22
26
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Export SVG" },
23
27
  React.createElement(DialogContent, null,
24
28
  error ? (React.createElement(ErrorMessage, { error: error })) : loading ? (React.createElement(LoadingMessage, null)) : null,
25
- React.createElement(TextField, { helperText: "filename", value: filename, onChange: event => setFilename(event.target.value) }),
26
- React.createElement("br", null),
27
- React.createElement(TextField, { select: true, label: "Track label positioning", variant: "outlined", style: { width: 150 }, value: trackLabels, onChange: event => setTrackLabels(event.target.value) },
29
+ React.createElement(TextField2, { helperText: "filename", value: filename, onChange: event => setFilename(event.target.value) }),
30
+ React.createElement(TextField2, { select: true, label: "Track label positioning", variant: "outlined", style: { width: 150 }, value: trackLabels, onChange: event => setTrackLabels(event.target.value) },
28
31
  React.createElement(MenuItem, { value: "offset" }, "Offset"),
29
32
  React.createElement(MenuItem, { value: "overlay" }, "Overlay"),
30
33
  React.createElement(MenuItem, { value: "left" }, "Left"),
31
34
  React.createElement(MenuItem, { value: "none" }, "None")),
32
- React.createElement("br", null),
33
- session.allThemes ? (React.createElement(TextField, { select: true, label: "Theme", variant: "outlined", value: themeName, onChange: event => setThemeName(event.target.value) }, Object.entries(session.allThemes()).map(([key, val]) => (React.createElement(MenuItem, { key: key, value: key },
35
+ session.allThemes ? (React.createElement(TextField2, { select: true, label: "Theme", variant: "outlined", value: themeName, onChange: event => setThemeName(event.target.value) }, Object.entries(session.allThemes()).map(([key, val]) => (React.createElement(MenuItem, { key: key, value: key },
34
36
  // @ts-expect-error
35
37
  val.name || '(Unknown name)'))))) : null,
36
38
  offscreenCanvas ? (React.createElement(FormControlLabel, { control: React.createElement(Checkbox, { checked: rasterizeLayers, onChange: () => setRasterizeLayers(val => !val) }), label: "Rasterize canvas based tracks? File may be much larger if this is turned off" })) : (React.createElement(Typography, null, "Note: rasterizing layers not yet supported in this browser, so SVG size may be large"))),
@@ -51,6 +53,8 @@ export default function ExportSvgDialog({ model, handleClose, }) {
51
53
  catch (e) {
52
54
  console.error(e);
53
55
  setError(e);
56
+ }
57
+ finally {
54
58
  setLoading(false);
55
59
  }
56
60
  } }, "Submit"))));
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { LinearGenomeViewModel } from '../model';
3
3
  type LGV = LinearGenomeViewModel;
4
- declare const Highlight: ({ model }: {
4
+ declare const HighlightGroup: ({ model, }: {
5
5
  model: LGV;
6
- }) => React.JSX.Element | null;
7
- export default Highlight;
6
+ }) => React.JSX.Element[];
7
+ export default HighlightGroup;
@@ -10,28 +10,28 @@ import LinkIcon from '@mui/icons-material/Link';
10
10
  import CloseIcon from '@mui/icons-material/Close';
11
11
  import BookmarkIcon from '@mui/icons-material/Bookmark';
12
12
  const useStyles = makeStyles()(theme => {
13
- var _a, _b, _c, _d, _e, _f;
13
+ var _a, _b;
14
14
  return ({
15
15
  highlight: {
16
16
  height: '100%',
17
17
  position: 'absolute',
18
- background: `${colord((_b = (_a = theme.palette.quaternary) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
18
+ overflow: 'hidden',
19
+ background: `${colord((_b = (_a = theme.palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
19
20
  .alpha(0.35)
20
21
  .toRgbString()}`,
21
- borderLeft: `1px solid ${(_d = (_c = theme.palette.quaternary) === null || _c === void 0 ? void 0 : _c.main) !== null && _d !== void 0 ? _d : 'goldenrod'}`,
22
- borderRight: `1px solid ${(_f = (_e = theme.palette.quaternary) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : 'goldenrod'}`,
23
22
  },
24
23
  });
25
24
  });
26
- const Highlight = observer(function Highlight({ model }) {
27
- var _a, _b;
25
+ const Highlight = observer(function Highlight({ model, highlight, }) {
26
+ var _a, _b, _c;
28
27
  const { classes } = useStyles();
29
28
  const [open, setOpen] = useState(false);
30
29
  const anchorEl = useRef(null);
31
- const color = (_b = (_a = useTheme().palette.quaternary) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod';
30
+ const color = (_b = (_a = useTheme().palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod';
32
31
  const session = getSession(model);
32
+ const { assemblyManager } = session;
33
33
  const dismissHighlight = () => {
34
- model.setHighlight(undefined);
34
+ model.removeHighlight(highlight);
35
35
  };
36
36
  const menuItems = [
37
37
  {
@@ -48,7 +48,7 @@ const Highlight = observer(function Highlight({ model }) {
48
48
  bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
49
49
  }
50
50
  // @ts-ignore
51
- bookmarkWidget.addBookmark(model.highlight);
51
+ bookmarkWidget.addBookmark(highlight);
52
52
  dismissHighlight();
53
53
  },
54
54
  },
@@ -56,9 +56,6 @@ const Highlight = observer(function Highlight({ model }) {
56
56
  function handleClose() {
57
57
  setOpen(false);
58
58
  }
59
- if (!model.highlight) {
60
- return null;
61
- }
62
59
  // coords
63
60
  const mapCoords = (r) => {
64
61
  const s = model.bpToPx({
@@ -76,19 +73,26 @@ const Highlight = observer(function Highlight({ model }) {
76
73
  }
77
74
  : undefined;
78
75
  };
79
- const h = mapCoords(model.highlight);
80
- return (React.createElement(React.Fragment, null, h ? (React.createElement("div", { className: classes.highlight, style: {
76
+ const asm = assemblyManager.get(highlight === null || highlight === void 0 ? void 0 : highlight.assemblyName);
77
+ const h = mapCoords({
78
+ ...highlight,
79
+ refName: (_c = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(highlight.refName)) !== null && _c !== void 0 ? _c : highlight.refName,
80
+ });
81
+ return h ? (React.createElement("div", { className: classes.highlight, style: {
81
82
  left: h.left,
82
83
  width: h.width,
83
84
  } },
84
85
  React.createElement(Tooltip, { title: 'Highlighted from URL parameter', arrow: true },
85
- React.createElement(IconButton, { ref: anchorEl, onClick: () => setOpen(true) },
86
+ React.createElement(IconButton, { ref: anchorEl, onClick: () => setOpen(true), style: { zIndex: 3 } },
86
87
  React.createElement(LinkIcon, { fontSize: "small", sx: {
87
88
  color: `${colord(color).darken(0.2).toRgbString()}`,
88
89
  } }))),
89
90
  React.createElement(Menu, { anchorEl: anchorEl.current, onMenuItemClick: (_event, callback) => {
90
91
  callback(session);
91
92
  handleClose();
92
- }, open: open, onClose: handleClose, menuItems: menuItems }))) : null));
93
+ }, open: open, onClose: handleClose, menuItems: menuItems }))) : null;
94
+ });
95
+ const HighlightGroup = observer(function HighlightGroup({ model, }) {
96
+ return model.highlight.map((highlight, idx) => (React.createElement(Highlight, { key: JSON.stringify(highlight) + '-' + idx, model: model, highlight: highlight })));
93
97
  });
94
- export default Highlight;
98
+ export default HighlightGroup;
@@ -1,13 +1,13 @@
1
1
  import React from 'react';
2
2
  import { observer } from 'mobx-react';
3
- import { IconButton, Paper } from '@mui/material';
3
+ import { IconButton, Paper, alpha } from '@mui/material';
4
+ import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ import { getSession } from '@jbrowse/core/util';
4
7
  // icons
5
8
  import ZoomIn from '@mui/icons-material/ZoomIn';
6
9
  import ZoomOut from '@mui/icons-material/ZoomOut';
7
10
  import ArrowDown from '@mui/icons-material/KeyboardArrowDown';
8
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
9
- import { makeStyles } from 'tss-react/mui';
10
- import { getSession } from '@jbrowse/core/util';
11
11
  const useStyles = makeStyles()(theme => ({
12
12
  background: {
13
13
  position: 'absolute',
@@ -16,22 +16,20 @@ const useStyles = makeStyles()(theme => ({
16
16
  background: theme.palette.background.paper,
17
17
  },
18
18
  focusedBackground: {
19
- background: theme.palette.secondary.light,
20
- svg: {
21
- fill: theme.palette.secondary.contrastText,
22
- },
19
+ background: alpha(theme.palette.secondary.light, 0.2),
23
20
  },
24
21
  }));
25
22
  const MiniControls = observer(function ({ model, }) {
26
- const { classes, cx } = useStyles();
23
+ const { classes } = useStyles();
27
24
  const { id, bpPerPx, maxBpPerPx, minBpPerPx, scaleFactor, hideHeader } = model;
28
25
  const { focusedViewId } = getSession(model);
29
- return hideHeader ? (React.createElement(Paper, { className: cx(classes.background, focusedViewId === id ? classes.focusedBackground : undefined) },
30
- React.createElement(CascadingMenuButton, { menuItems: model.menuItems() },
31
- React.createElement(ArrowDown, { fontSize: "small" })),
32
- React.createElement(IconButton, { "data-testid": "zoom_out", onClick: () => model.zoom(bpPerPx * 2), disabled: bpPerPx >= maxBpPerPx - 0.0001 || scaleFactor !== 1 },
33
- React.createElement(ZoomOut, { fontSize: "small" })),
34
- React.createElement(IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1 },
35
- React.createElement(ZoomIn, { fontSize: "small" })))) : null;
26
+ return hideHeader ? (React.createElement(Paper, { className: classes.background },
27
+ React.createElement(Paper, { className: focusedViewId === id ? classes.focusedBackground : undefined },
28
+ React.createElement(CascadingMenuButton, { menuItems: model.menuItems() },
29
+ React.createElement(ArrowDown, { fontSize: "small" })),
30
+ React.createElement(IconButton, { "data-testid": "zoom_out", onClick: () => model.zoom(bpPerPx * 2), disabled: bpPerPx >= maxBpPerPx - 0.0001 || scaleFactor !== 1 },
31
+ React.createElement(ZoomOut, { fontSize: "small" })),
32
+ React.createElement(IconButton, { "data-testid": "zoom_in", onClick: () => model.zoom(bpPerPx / 2), disabled: bpPerPx <= minBpPerPx + 0.0001 || scaleFactor !== 1 },
33
+ React.createElement(ZoomIn, { fontSize: "small" }))))) : null;
36
34
  });
37
35
  export default MiniControls;
@@ -5,5 +5,5 @@ type LGV = LinearGenomeViewModel;
5
5
  declare const OverviewHighlight: ({ model, overview, }: {
6
6
  model: LGV;
7
7
  overview: Base1DViewModel;
8
- }) => React.JSX.Element | null;
8
+ }) => React.JSX.Element[];
9
9
  export default OverviewHighlight;
@@ -2,23 +2,26 @@ import React from 'react';
2
2
  import { observer } from 'mobx-react';
3
3
  import { makeStyles } from 'tss-react/mui';
4
4
  import { colord } from '@jbrowse/core/util/colord';
5
+ import { getSession, notEmpty, } from '@jbrowse/core/util';
5
6
  const useStyles = makeStyles()(theme => {
6
7
  var _a, _b, _c, _d, _e, _f;
7
8
  return ({
8
9
  highlight: {
9
10
  height: '100%',
10
11
  position: 'absolute',
11
- background: `${colord((_b = (_a = theme.palette.quaternary) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
12
+ background: `${colord((_b = (_a = theme.palette.highlight) === null || _a === void 0 ? void 0 : _a.main) !== null && _b !== void 0 ? _b : 'goldenrod')
12
13
  .alpha(0.35)
13
14
  .toRgbString()}`,
14
- borderLeft: `1px solid ${(_d = (_c = theme.palette.quaternary) === null || _c === void 0 ? void 0 : _c.main) !== null && _d !== void 0 ? _d : 'goldenrod'}`,
15
- borderRight: `1px solid ${(_f = (_e = theme.palette.quaternary) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : 'goldenrod'}`,
15
+ borderLeft: `1px solid ${(_d = (_c = theme.palette.highlight) === null || _c === void 0 ? void 0 : _c.main) !== null && _d !== void 0 ? _d : 'goldenrod'}`,
16
+ borderRight: `1px solid ${(_f = (_e = theme.palette.highlight) === null || _e === void 0 ? void 0 : _e.main) !== null && _f !== void 0 ? _f : 'goldenrod'}`,
16
17
  },
17
18
  });
18
19
  });
19
20
  const OverviewHighlight = observer(function OverviewHighlight({ model, overview, }) {
20
21
  const { classes } = useStyles();
21
22
  const { cytobandOffset } = model;
23
+ const session = getSession(model);
24
+ const { assemblyManager } = session;
22
25
  // coords
23
26
  const mapCoords = (r) => {
24
27
  const s = overview.bpToPx({
@@ -36,13 +39,19 @@ const OverviewHighlight = observer(function OverviewHighlight({ model, overview,
36
39
  }
37
40
  : undefined;
38
41
  };
39
- if (!model.highlight) {
40
- return null;
41
- }
42
- const h = mapCoords(model.highlight);
43
- return (React.createElement(React.Fragment, null, h ? (React.createElement("div", { className: classes.highlight, style: {
44
- width: h.width,
45
- left: h.left,
46
- } })) : null));
42
+ return model.highlight
43
+ .map(h => {
44
+ var _a;
45
+ const asm = assemblyManager.get(h === null || h === void 0 ? void 0 : h.assemblyName);
46
+ return mapCoords({
47
+ ...h,
48
+ refName: (_a = asm === null || asm === void 0 ? void 0 : asm.getCanonicalRefName(h.refName)) !== null && _a !== void 0 ? _a : h.refName,
49
+ });
50
+ })
51
+ .filter(notEmpty)
52
+ .map(({ left, width }, idx) => (React.createElement("div", { key: `${left}_${width}_${idx}`, className: classes.highlight, style: {
53
+ width: width,
54
+ left: left,
55
+ } })));
47
56
  });
48
57
  export default OverviewHighlight;
@@ -5,6 +5,6 @@ type LGV = LinearGenomeViewModel;
5
5
  declare const OverviewRubberband: ({ model, overview, ControlComponent, }: {
6
6
  model: LGV;
7
7
  overview: Base1DViewModel;
8
- ControlComponent?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
8
+ ControlComponent?: React.ReactElement;
9
9
  }) => React.JSX.Element;
10
10
  export default OverviewRubberband;
@@ -4,7 +4,7 @@ import { makeStyles } from 'tss-react/mui';
4
4
  import { observer } from 'mobx-react';
5
5
  // core
6
6
  import Base1DView from '@jbrowse/core/util/Base1DViewModel';
7
- import { getSession, getTickDisplayStr } from '@jbrowse/core/util';
7
+ import { getEnv, getSession, getTickDisplayStr } from '@jbrowse/core/util';
8
8
  import { ContentBlock } from '@jbrowse/core/util/blockTypes';
9
9
  // locals
10
10
  import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT, } from '..';
@@ -118,6 +118,7 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
118
118
  const { classes } = useStyles();
119
119
  const theme = useTheme();
120
120
  const { dynamicBlocks, showCytobands, cytobandOffset } = model;
121
+ const { pluginManager } = getEnv(model);
121
122
  const visibleRegions = dynamicBlocks.contentBlocks;
122
123
  const overviewVisibleRegions = overview.dynamicBlocks;
123
124
  const { tertiary, primary } = theme.palette;
@@ -138,6 +139,7 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
138
139
  }) || 0;
139
140
  const color = showCytobands ? '#f00' : scalebarColor;
140
141
  const transparency = showCytobands ? 0.1 : 0.3;
142
+ const additional = pluginManager.evaluateExtensionPoint('LinearGenomeView-OverviewScalebarComponent', undefined, { model, overview });
141
143
  return (React.createElement("div", { className: classes.scalebar },
142
144
  React.createElement("div", { className: classes.scalebarVisibleRegion, style: {
143
145
  width: lastOverviewPx - firstOverviewPx,
@@ -153,7 +155,8 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
153
155
  backgroundImage: 'repeating-linear-gradient(90deg, transparent, transparent 1px, rgba(255,255,255,.5) 1px, rgba(255,255,255,.5) 3px)',
154
156
  } })) : (React.createElement(OverviewBox, { scale: scale, block: block, model: model, overview: overview, key: `${JSON.stringify(block)}-${idx}` }));
155
157
  }),
156
- React.createElement(OverviewHighlight, { model: model, overview: overview })));
158
+ React.createElement(OverviewHighlight, { model: model, overview: overview }),
159
+ additional));
157
160
  });
158
161
  const OverviewScalebar = observer(function ({ model, children, }) {
159
162
  const { classes } = useStyles();
@@ -4,6 +4,6 @@ import { LinearGenomeViewModel } from '..';
4
4
  declare const OverviewScalebarPolygon: ({ model, overview, useOffset, }: {
5
5
  model: LinearGenomeViewModel;
6
6
  overview: Base1DViewModel;
7
- useOffset?: boolean | undefined;
7
+ useOffset?: boolean;
8
8
  }) => React.JSX.Element | null;
9
9
  export default OverviewScalebarPolygon;
@@ -3,6 +3,7 @@ import { useTheme, alpha } from '@mui/material';
3
3
  import { observer } from 'mobx-react';
4
4
  // locals
5
5
  import { HEADER_BAR_HEIGHT } from '..';
6
+ import { getFillProps, getStrokeProps } from '@jbrowse/core/util';
6
7
  const OverviewScalebarPolygon = observer(function ({ model, overview, useOffset = true, }) {
7
8
  const theme = useTheme();
8
9
  const multiplier = Number(useOffset);
@@ -36,6 +37,6 @@ const OverviewScalebarPolygon = observer(function ({ model, overview, useOffset
36
37
  [topRight, 0],
37
38
  [topLeft, 0],
38
39
  ];
39
- return (React.createElement("polygon", { points: points.toString(), fill: alpha(polygonColor, 0.3), stroke: alpha(polygonColor, 0.8) }));
40
+ return (React.createElement("polygon", { points: points.toString(), ...getFillProps(alpha(polygonColor, 0.3)), ...getStrokeProps(alpha(polygonColor, 0.8)) }));
40
41
  });
41
42
  export default OverviewScalebarPolygon;
@@ -4,15 +4,15 @@ import { TextFieldProps as TFP } from '@mui/material';
4
4
  import { LinearGenomeViewModel } from '../../model';
5
5
  declare const RefNameAutocomplete: ({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp, minWidth, maxWidth, TextFieldProps, }: {
6
6
  model: LinearGenomeViewModel;
7
- onSelect?: ((region: BaseResult) => void) | undefined;
8
- onChange?: ((val: string) => void) | undefined;
9
- assemblyName?: string | undefined;
10
- value?: string | undefined;
7
+ onSelect?: (region: BaseResult) => void;
8
+ onChange?: (val: string) => void;
9
+ assemblyName?: string;
10
+ value?: string;
11
11
  fetchResults: (query: string) => Promise<BaseResult[]>;
12
- style?: React.CSSProperties | undefined;
13
- minWidth?: number | undefined;
14
- maxWidth?: number | undefined;
15
- showHelp?: boolean | undefined;
16
- TextFieldProps?: TFP | undefined;
12
+ style?: React.CSSProperties;
13
+ minWidth?: number;
14
+ maxWidth?: number;
15
+ showHelp?: boolean;
16
+ TextFieldProps?: TFP;
17
17
  }) => React.JSX.Element;
18
18
  export default RefNameAutocomplete;
@@ -17,7 +17,8 @@ const RefNameAutocomplete = observer(function ({ model, onSelect, assemblyName,
17
17
  const assembly = assemblyName ? assemblyManager.get(assemblyName) : undefined;
18
18
  const { coarseVisibleLocStrings, hasDisplayedRegions } = model;
19
19
  useEffect(() => {
20
- let active = true;
20
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
21
+ ;
21
22
  (async () => {
22
23
  try {
23
24
  if (debouncedSearch === '' || !assemblyName) {
@@ -25,21 +26,14 @@ const RefNameAutocomplete = observer(function ({ model, onSelect, assemblyName,
25
26
  }
26
27
  setLoaded(false);
27
28
  const results = await fetchResults(debouncedSearch);
28
- if (active) {
29
- setLoaded(true);
30
- setSearchOptions(getDeduplicatedResult(results));
31
- }
29
+ setLoaded(true);
30
+ setSearchOptions(getDeduplicatedResult(results));
32
31
  }
33
32
  catch (e) {
34
33
  console.error(e);
35
- if (active) {
36
- session.notify(`${e}`, 'error');
37
- }
34
+ session.notifyError(`${e}`, e);
38
35
  }
39
36
  })();
40
- return () => {
41
- active = false;
42
- };
43
37
  }, [assemblyName, fetchResults, debouncedSearch, session, model]);
44
38
  const inputBoxVal = coarseVisibleLocStrings || value || '';
45
39
  // heuristic, text width + 60 accommodates help icon and search icon
@@ -54,29 +48,28 @@ const RefNameAutocomplete = observer(function ({ model, onSelect, assemblyName,
54
48
  }))) || [], [regions]);
55
49
  // notes on implementation:
56
50
  // The selectOnFocus setting helps highlight the field when clicked
57
- return (React.createElement(React.Fragment, null,
58
- React.createElement(Autocomplete, { "data-testid": "autocomplete", disableListWrap: true, disableClearable: true, disabled: !assemblyName, freeSolo: true, includeInputInList: true, selectOnFocus: true, style: { ...style, width }, value: inputBoxVal, loading: !loaded, inputValue: inputValue, onInputChange: (_event, newInputValue) => {
59
- setInputValue(newInputValue);
60
- onChange === null || onChange === void 0 ? void 0 : onChange(newInputValue);
61
- }, loadingText: "loading results", open: open, onOpen: () => setOpen(true), onClose: () => {
62
- setOpen(false);
63
- setLoaded(true);
64
- if (hasDisplayedRegions) {
65
- setCurrentSearch('');
66
- setSearchOptions(undefined);
67
- }
68
- }, onChange: (_event, selectedOption) => {
69
- if (!selectedOption || !assemblyName) {
70
- return;
71
- }
72
- if (typeof selectedOption === 'string') {
73
- // handles string inputs on keyPress enter
74
- onSelect === null || onSelect === void 0 ? void 0 : onSelect(new BaseResult({ label: selectedOption }));
75
- }
76
- else {
77
- onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedOption.result);
78
- }
79
- setInputValue(inputBoxVal);
80
- }, options: (searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.length) ? searchOptions : regionOptions, 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() })));
51
+ return (React.createElement(Autocomplete, { "data-testid": "autocomplete", disableListWrap: true, disableClearable: true, disabled: !assemblyName, freeSolo: true, includeInputInList: true, selectOnFocus: true, style: { ...style, width }, value: inputBoxVal, loading: !loaded, inputValue: inputValue, onInputChange: (_event, newInputValue) => {
52
+ setInputValue(newInputValue);
53
+ onChange === null || onChange === void 0 ? void 0 : onChange(newInputValue);
54
+ }, loadingText: "loading results", open: open, onOpen: () => setOpen(true), onClose: () => {
55
+ setOpen(false);
56
+ setLoaded(true);
57
+ if (hasDisplayedRegions) {
58
+ setCurrentSearch('');
59
+ setSearchOptions(undefined);
60
+ }
61
+ }, onChange: (_event, selectedOption) => {
62
+ if (!selectedOption || !assemblyName) {
63
+ return;
64
+ }
65
+ if (typeof selectedOption === 'string') {
66
+ // handles string inputs on keyPress enter
67
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(new BaseResult({ label: selectedOption }));
68
+ }
69
+ else {
70
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedOption.result);
71
+ }
72
+ setInputValue(inputBoxVal);
73
+ }, options: (searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.length) ? searchOptions : regionOptions, 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() }));
81
74
  });
82
75
  export default RefNameAutocomplete;
@@ -3,6 +3,6 @@ import { LinearGenomeViewModel } from '..';
3
3
  type LGV = LinearGenomeViewModel;
4
4
  declare const Rubberband: ({ model, ControlComponent, }: {
5
5
  model: LGV;
6
- ControlComponent?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
6
+ ControlComponent?: React.ReactElement;
7
7
  }) => React.JSX.Element;
8
8
  export default Rubberband;