@jbrowse/plugin-linear-comparative-view 2.15.3 → 2.16.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 (101) hide show
  1. package/dist/LaunchLinearSyntenyView.js +41 -11
  2. package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +14 -9
  3. package/dist/LinearComparativeDisplay/stateModelFactory.js +8 -9
  4. package/dist/LinearComparativeView/components/Header.d.ts +2 -3
  5. package/dist/LinearComparativeView/components/Header.js +72 -62
  6. package/dist/LinearComparativeView/components/HeaderSearchBoxes.d.ts +6 -0
  7. package/dist/LinearComparativeView/components/HeaderSearchBoxes.js +34 -0
  8. package/dist/LinearComparativeView/components/LinearComparativeRenderArea.d.ts +6 -0
  9. package/dist/LinearComparativeView/components/LinearComparativeRenderArea.js +61 -0
  10. package/dist/LinearComparativeView/components/LinearComparativeView.d.ts +2 -4
  11. package/dist/LinearComparativeView/components/LinearComparativeView.js +3 -67
  12. package/dist/LinearComparativeView/components/Rubberband.js +1 -1
  13. package/dist/LinearComparativeView/index.js +3 -0
  14. package/dist/LinearComparativeView/model.d.ts +265 -12
  15. package/dist/LinearComparativeView/model.js +45 -75
  16. package/dist/LinearSyntenyDisplay/afterAttach.js +5 -3
  17. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +32 -24
  18. package/dist/LinearSyntenyDisplay/components/SyntenyContextMenu.js +12 -6
  19. package/dist/LinearSyntenyDisplay/components/util.d.ts +2 -1
  20. package/dist/LinearSyntenyDisplay/components/util.js +5 -5
  21. package/dist/LinearSyntenyDisplay/drawSynteny.d.ts +1 -1
  22. package/dist/LinearSyntenyDisplay/drawSynteny.js +28 -22
  23. package/dist/LinearSyntenyDisplay/index.js +1 -1
  24. package/dist/LinearSyntenyDisplay/model.d.ts +12 -11
  25. package/dist/LinearSyntenyDisplay/model.js +7 -0
  26. package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.d.ts → AddCustomTrack.d.ts} +2 -3
  27. package/dist/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.js → AddCustomTrack.js} +3 -3
  28. package/dist/LinearSyntenyView/components/ImportForm/LinearSyntenyImportForm.js +195 -0
  29. package/dist/LinearSyntenyView/components/ImportForm/Spacer.d.ts +2 -0
  30. package/dist/LinearSyntenyView/components/ImportForm/Spacer.js +10 -0
  31. package/dist/LinearSyntenyView/components/ImportForm/TrackSelector.d.ts +10 -0
  32. package/dist/LinearSyntenyView/components/ImportForm/{ImportSyntenyTrackSelector.js → TrackSelector.js} +15 -20
  33. package/dist/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.d.ts +14 -0
  34. package/dist/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.js +52 -0
  35. package/dist/LinearSyntenyView/components/LinearSyntenyView.js +3 -3
  36. package/dist/LinearSyntenyView/index.js +1 -1
  37. package/dist/LinearSyntenyView/model.d.ts +267 -9
  38. package/dist/LinearSyntenyView/model.js +2 -2
  39. package/dist/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
  40. package/dist/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.js +19 -0
  41. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +1 -3
  42. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +36 -27
  43. package/dist/LinearSyntenyViewHelper/index.d.ts +2 -0
  44. package/dist/LinearSyntenyViewHelper/index.js +25 -0
  45. package/dist/LinearSyntenyViewHelper/stateModelFactory.d.ts +30 -0
  46. package/dist/LinearSyntenyViewHelper/stateModelFactory.js +105 -0
  47. package/dist/index.js +2 -0
  48. package/esm/LaunchLinearSyntenyView.js +41 -11
  49. package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +14 -9
  50. package/esm/LinearComparativeDisplay/stateModelFactory.js +9 -10
  51. package/esm/LinearComparativeView/components/Header.d.ts +2 -3
  52. package/esm/LinearComparativeView/components/Header.js +73 -63
  53. package/esm/LinearComparativeView/components/HeaderSearchBoxes.d.ts +6 -0
  54. package/esm/LinearComparativeView/components/HeaderSearchBoxes.js +29 -0
  55. package/esm/LinearComparativeView/components/LinearComparativeRenderArea.d.ts +6 -0
  56. package/esm/LinearComparativeView/components/LinearComparativeRenderArea.js +56 -0
  57. package/esm/LinearComparativeView/components/LinearComparativeView.d.ts +2 -4
  58. package/esm/LinearComparativeView/components/LinearComparativeView.js +3 -67
  59. package/esm/LinearComparativeView/components/Rubberband.js +1 -1
  60. package/esm/LinearComparativeView/index.js +3 -0
  61. package/esm/LinearComparativeView/model.d.ts +265 -12
  62. package/esm/LinearComparativeView/model.js +47 -77
  63. package/esm/LinearSyntenyDisplay/afterAttach.js +6 -4
  64. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +33 -25
  65. package/esm/LinearSyntenyDisplay/components/SyntenyContextMenu.js +12 -6
  66. package/esm/LinearSyntenyDisplay/components/util.d.ts +2 -1
  67. package/esm/LinearSyntenyDisplay/components/util.js +5 -5
  68. package/esm/LinearSyntenyDisplay/drawSynteny.d.ts +1 -1
  69. package/esm/LinearSyntenyDisplay/drawSynteny.js +28 -22
  70. package/esm/LinearSyntenyDisplay/index.js +1 -1
  71. package/esm/LinearSyntenyDisplay/model.d.ts +12 -11
  72. package/esm/LinearSyntenyDisplay/model.js +8 -1
  73. package/esm/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.d.ts → AddCustomTrack.d.ts} +2 -3
  74. package/esm/LinearSyntenyView/components/ImportForm/{ImportCustomTrack.js → AddCustomTrack.js} +3 -3
  75. package/esm/LinearSyntenyView/components/ImportForm/LinearSyntenyImportForm.js +167 -0
  76. package/esm/LinearSyntenyView/components/ImportForm/Spacer.d.ts +2 -0
  77. package/esm/LinearSyntenyView/components/ImportForm/Spacer.js +4 -0
  78. package/esm/LinearSyntenyView/components/ImportForm/TrackSelector.d.ts +10 -0
  79. package/esm/LinearSyntenyView/components/ImportForm/{ImportSyntenyTrackSelector.js → TrackSelector.js} +15 -20
  80. package/esm/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.d.ts +14 -0
  81. package/esm/LinearSyntenyView/components/ImportForm/TrackSelectorUtil.js +23 -0
  82. package/esm/LinearSyntenyView/components/LinearSyntenyView.js +3 -3
  83. package/esm/LinearSyntenyView/index.js +1 -1
  84. package/esm/LinearSyntenyView/model.d.ts +267 -9
  85. package/esm/LinearSyntenyView/model.js +2 -2
  86. package/esm/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
  87. package/esm/LinearSyntenyView/svgcomponents/SVGLinearGenomeView.js +13 -0
  88. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +1 -3
  89. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +38 -29
  90. package/esm/LinearSyntenyViewHelper/index.d.ts +2 -0
  91. package/esm/LinearSyntenyViewHelper/index.js +19 -0
  92. package/esm/LinearSyntenyViewHelper/stateModelFactory.d.ts +30 -0
  93. package/esm/LinearSyntenyViewHelper/stateModelFactory.js +102 -0
  94. package/esm/index.js +2 -0
  95. package/package.json +2 -2
  96. package/dist/LinearSyntenyView/components/ImportForm/ImportSyntenyTrackSelector.d.ts +0 -9
  97. package/dist/LinearSyntenyView/components/ImportForm/index.js +0 -138
  98. package/esm/LinearSyntenyView/components/ImportForm/ImportSyntenyTrackSelector.d.ts +0 -9
  99. package/esm/LinearSyntenyView/components/ImportForm/index.js +0 -110
  100. /package/dist/LinearSyntenyView/components/ImportForm/{index.d.ts → LinearSyntenyImportForm.d.ts} +0 -0
  101. /package/esm/LinearSyntenyView/components/ImportForm/{index.d.ts → LinearSyntenyImportForm.d.ts} +0 -0
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ const LinearComparativeView_1 = __importDefault(require("./LinearComparativeView
11
11
  const LinearSyntenyDisplay_1 = __importDefault(require("./LinearSyntenyDisplay"));
12
12
  const LGVSyntenyDisplay_1 = __importDefault(require("./LGVSyntenyDisplay"));
13
13
  const LinearSyntenyView_1 = __importDefault(require("./LinearSyntenyView"));
14
+ const LinearSyntenyViewHelper_1 = __importDefault(require("./LinearSyntenyViewHelper"));
14
15
  const LaunchLinearSyntenyView_1 = __importDefault(require("./LaunchLinearSyntenyView"));
15
16
  const SyntenyTrack_1 = __importDefault(require("./SyntenyTrack"));
16
17
  const LinearReadVsRef_1 = __importDefault(require("./LinearReadVsRef"));
@@ -20,6 +21,7 @@ class LinearComparativeViewPlugin extends Plugin_1.default {
20
21
  this.name = 'LinearComparativeViewPlugin';
21
22
  }
22
23
  install(pluginManager) {
24
+ (0, LinearSyntenyViewHelper_1.default)(pluginManager);
23
25
  (0, LinearComparativeView_1.default)(pluginManager);
24
26
  (0, LinearSyntenyView_1.default)(pluginManager);
25
27
  (0, LinearComparativeDisplay_1.default)(pluginManager);
@@ -1,4 +1,8 @@
1
+ import { notEmpty } from '@jbrowse/core/util';
1
2
  import { when } from 'mobx';
3
+ function makeMultiDimArray(str) {
4
+ return Array.isArray(str[0]) ? str : [str];
5
+ }
2
6
  export default function LaunchLinearSyntenyView(pluginManager) {
3
7
  pluginManager.addToExtensionPoint('LaunchView-LinearSyntenyView',
4
8
  // @ts-expect-error
@@ -21,7 +25,7 @@ export default function LaunchLinearSyntenyView(pluginManager) {
21
25
  };
22
26
  })));
23
27
  await Promise.all(model.views.map(view => when(() => view.initialized)));
24
- const idsNotFound = [];
28
+ let idsNotFound = [];
25
29
  await Promise.all(views.map(async (data, idx) => {
26
30
  const view = model.views[idx];
27
31
  const { assembly, loc, tracks = [] } = data;
@@ -30,14 +34,23 @@ export default function LaunchLinearSyntenyView(pluginManager) {
30
34
  throw new Error(`Assembly ${data.assembly} failed to load`);
31
35
  }
32
36
  await view.navToSearchString({ input: loc, assembly: asm });
33
- tracks.forEach(track => {
34
- tryTrack(view, track, idsNotFound);
35
- });
37
+ idsNotFound = [
38
+ ...idsNotFound,
39
+ ...tracks.map(trackId => tryTrackLGV({
40
+ model: view,
41
+ trackId,
42
+ })),
43
+ ];
36
44
  }));
37
- tracks.forEach(track => {
38
- tryTrack(model, track, idsNotFound);
39
- });
40
- if (idsNotFound.length) {
45
+ idsNotFound = [
46
+ ...idsNotFound,
47
+ ...makeMultiDimArray(tracks).flatMap((trackSet, level) => trackSet.map(trackId => tryTrackSynteny({
48
+ model,
49
+ trackId,
50
+ level,
51
+ }))),
52
+ ];
53
+ if (idsNotFound.filter(notEmpty).length) {
41
54
  throw new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`);
42
55
  }
43
56
  }
@@ -47,16 +60,33 @@ export default function LaunchLinearSyntenyView(pluginManager) {
47
60
  }
48
61
  });
49
62
  }
50
- function tryTrack(model, trackId, idsNotFound) {
63
+ function tryTrackLGV({ model, trackId, }) {
51
64
  try {
52
65
  model.showTrack(trackId);
53
66
  }
54
67
  catch (e) {
55
- if (/Could not resolve identifier/.exec(`${e}`)) {
56
- idsNotFound.push(trackId);
68
+ if (/Could not resolve identifier/.exec(`${e}`) ||
69
+ /track not found/.exec(`${e}`)) {
70
+ return trackId;
71
+ }
72
+ else {
73
+ throw e;
74
+ }
75
+ }
76
+ return undefined;
77
+ }
78
+ function tryTrackSynteny({ model, trackId, level, }) {
79
+ try {
80
+ model.showTrack(trackId, level);
81
+ }
82
+ catch (e) {
83
+ if (/Could not resolve identifier/.exec(`${e}`) ||
84
+ /track not found/.exec(`${e}`)) {
85
+ return trackId;
57
86
  }
58
87
  else {
59
88
  throw e;
60
89
  }
61
90
  }
91
+ return undefined;
62
92
  }
@@ -11,9 +11,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
11
11
  type: import("mobx-state-tree").ISimpleType<string>;
12
12
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
13
13
  } & {
14
+ /**
15
+ * #property
16
+ */
14
17
  type: import("mobx-state-tree").ISimpleType<"LinearComparativeDisplay">;
18
+ /**
19
+ * #property
20
+ */
15
21
  configuration: AnyConfigurationSchemaType;
16
- height: import("mobx-state-tree").IType<number | undefined, number, number>;
17
22
  }, {
18
23
  rendererTypeName: string;
19
24
  error: unknown;
@@ -24,9 +29,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
24
29
  id: string;
25
30
  type: string;
26
31
  rpcDriverName: string | undefined;
27
- } & import("mobx-state-tree/dist/internal" /**
28
- * #property
29
- */).NonEmptyObject & {
32
+ } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
30
33
  rendererTypeName: string;
31
34
  error: unknown;
32
35
  message: string | undefined;
@@ -99,7 +102,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
99
102
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
100
103
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
101
104
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
102
- height: number;
103
105
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
104
106
  rendererTypeName: string;
105
107
  error: unknown;
@@ -110,9 +112,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
110
112
  id: string;
111
113
  type: string;
112
114
  rpcDriverName: string | undefined;
113
- } & import("mobx-state-tree/dist/internal" /**
114
- * #property
115
- */).NonEmptyObject & {
115
+ } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
116
116
  rendererTypeName: string;
117
117
  error: unknown;
118
118
  message: string | undefined;
@@ -169,9 +169,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
169
169
  type: import("mobx-state-tree").ISimpleType<string>;
170
170
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
171
171
  } & {
172
+ /**
173
+ * #property
174
+ */
172
175
  type: import("mobx-state-tree").ISimpleType<"LinearComparativeDisplay">;
176
+ /**
177
+ * #property
178
+ */
173
179
  configuration: AnyConfigurationSchemaType;
174
- height: import("mobx-state-tree").IType<number | undefined, number, number>;
175
180
  }, {
176
181
  rendererTypeName: string;
177
182
  error: unknown;
@@ -1,5 +1,5 @@
1
1
  import { readConfObject, ConfigurationReference, } from '@jbrowse/core/configuration';
2
- import { types, getSnapshot } from 'mobx-state-tree';
2
+ import { types, getSnapshot, getParent } from 'mobx-state-tree';
3
3
  import { dedupe, getContainingView, getSession, makeAbortableReaction, } from '@jbrowse/core/util';
4
4
  import { getRpcSessionId } from '@jbrowse/core/util/tracks';
5
5
  import { BaseDisplay } from '@jbrowse/core/pluggableElementTypes/models';
@@ -19,10 +19,6 @@ function stateModelFactory(configSchema) {
19
19
  * #property
20
20
  */
21
21
  configuration: ConfigurationReference(configSchema),
22
- /**
23
- * #property
24
- */
25
- height: 100,
26
22
  }))
27
23
  .volatile(( /* self */) => ({
28
24
  renderInProgress: undefined,
@@ -131,8 +127,9 @@ function stateModelFactory(configSchema) {
131
127
  function renderBlockData(self) {
132
128
  const { rpcManager } = getSession(self);
133
129
  const display = self;
134
- // Alternative to readConfObject(config) is below used because renderProps is
135
- // something under our control. Compare to serverSideRenderedBlock
130
+ // Alternative to readConfObject(config) is below used because
131
+ // renderProps is something under our control. Compare to
132
+ // serverSideRenderedBlock
136
133
  readConfObject(self.configuration);
137
134
  const { adapterConfig } = self;
138
135
  const parent = getContainingView(self);
@@ -143,6 +140,8 @@ function renderBlockData(self) {
143
140
  rpcManager,
144
141
  renderProps: {
145
142
  ...display.renderProps(),
143
+ // @ts-expect-error
144
+ level: getParent(self, 4).level,
146
145
  view: parent,
147
146
  adapterConfig,
148
147
  sessionId,
@@ -157,10 +156,10 @@ async function renderBlockEffect(props) {
157
156
  return;
158
157
  }
159
158
  const { rpcManager, renderProps } = props;
160
- const { adapterConfig } = renderProps;
161
- const view0 = renderProps.view.views[0];
159
+ const { adapterConfig, level } = renderProps;
160
+ const view = renderProps.view.views[level];
162
161
  const features = (await rpcManager.call('getFeats', 'CoreGetFeatures', {
163
- regions: view0.staticBlocks.contentBlocks,
162
+ regions: view.staticBlocks.contentBlocks,
164
163
  sessionId: 'getFeats',
165
164
  adapterConfig,
166
165
  }));
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { LinearComparativeViewModel } from '../model';
3
- type LCV = LinearComparativeViewModel;
4
- declare const Header: ({ model }: {
5
- model: LCV;
3
+ declare const Header: ({ model, }: {
4
+ model: LinearComparativeViewModel;
6
5
  }) => React.JSX.Element;
7
6
  export default Header;
@@ -1,74 +1,84 @@
1
1
  import React, { useState } from 'react';
2
- import { IconButton, Typography } from '@mui/material';
3
- import { makeStyles } from 'tss-react/mui';
4
- import { SearchBox } from '@jbrowse/plugin-linear-genome-view';
5
2
  import { observer } from 'mobx-react';
6
- import { Menu } from '@jbrowse/core/ui';
3
+ import { FormGroup } from '@mui/material';
4
+ import { makeStyles } from 'tss-react/mui';
5
+ import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
7
6
  // icons
8
7
  import MoreVertIcon from '@mui/icons-material/MoreVert';
8
+ import SearchIcon from '@mui/icons-material/Search';
9
9
  import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
10
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
11
- const useStyles = makeStyles()(() => ({
12
- headerBar: {
13
- gridArea: '1/1/auto/span 2',
14
- display: 'flex',
15
- },
16
- spacer: {
17
- flexGrow: 1,
18
- },
19
- iconButton: {
20
- margin: 5,
21
- },
22
- bp: {
23
- display: 'flex',
24
- alignItems: 'center',
25
- marginLeft: 10,
26
- },
27
- searchContainer: {
28
- marginLeft: 5,
29
- },
30
- searchBox: {
31
- display: 'flex',
10
+ import HeaderSearchBoxes from './HeaderSearchBoxes';
11
+ const useStyles = makeStyles()({
12
+ inline: {
13
+ display: 'inline-flex',
32
14
  },
33
- }));
34
- const TrackSelector = observer(({ model }) => {
35
- return (React.createElement(CascadingMenuButton, { menuItems: [
36
- {
37
- label: 'Synteny track selector',
38
- onClick: () => model.activateTrackSelector(),
39
- },
40
- ...model.views.map((view, idx) => ({
41
- label: `View ${idx + 1} track selector`,
42
- onClick: () => view.activateTrackSelector(),
43
- })),
44
- ] },
45
- React.createElement(TrackSelectorIcon, null)));
46
15
  });
47
- const Header = observer(function ({ model }) {
16
+ const Header = observer(function ({ model, }) {
48
17
  const { classes } = useStyles();
49
- const [menuAnchorEl, setMenuAnchorEl] = useState();
50
- const anyShowHeaders = model.views.some(view => !view.hideHeader);
51
- return (React.createElement("div", { className: classes.headerBar },
52
- React.createElement(TrackSelector, { model: model }),
53
- React.createElement(IconButton, { onClick: event => {
54
- setMenuAnchorEl(event.currentTarget);
55
- }, className: classes.iconButton },
18
+ const { views } = model;
19
+ const [showSearchBoxes, setShowSearchBoxes] = useState(views.length <= 3);
20
+ const [sideBySide, setSideBySide] = useState(views.length <= 3);
21
+ return (React.createElement(FormGroup, { row: true },
22
+ React.createElement(CascadingMenuButton, { menuItems: [
23
+ {
24
+ label: 'Synteny track selectors',
25
+ type: 'subMenu',
26
+ subMenu: views.slice(0, -1).map((_, idx) => ({
27
+ label: `Row ${idx + 1}->${idx + 2} (${views[idx].assemblyNames.join(',')}->${views[idx + 1].assemblyNames.join(',')})`,
28
+ onClick: () => {
29
+ model.activateTrackSelector(idx);
30
+ },
31
+ })),
32
+ },
33
+ {
34
+ label: 'Row track selectors',
35
+ type: 'subMenu',
36
+ subMenu: views.map((view, idx) => ({
37
+ label: `Row ${idx + 1} track selector (${view.assemblyNames.join(',')})`,
38
+ onClick: () => view.activateTrackSelector(),
39
+ })),
40
+ },
41
+ ] },
42
+ React.createElement(TrackSelectorIcon, null)),
43
+ React.createElement(CascadingMenuButton, { menuItems: [
44
+ {
45
+ label: 'Row view menus',
46
+ type: 'subMenu',
47
+ subMenu: views.map((view, idx) => ({
48
+ label: `View ${idx + 1} Menu`,
49
+ subMenu: view.menuItems(),
50
+ })),
51
+ },
52
+ ...model.headerMenuItems(),
53
+ ] },
56
54
  React.createElement(MoreVertIcon, null)),
57
- !anyShowHeaders
58
- ? model.views.map(view => (React.createElement("div", { key: view.id, className: classes.searchBox },
59
- React.createElement("div", { className: classes.searchContainer },
60
- React.createElement(SearchBox, { model: view, showHelp: false })),
61
- React.createElement("div", { className: classes.bp },
62
- React.createElement(Typography, { variant: "body2", color: "textSecondary", className: classes.bp },
63
- Math.round(view.coarseTotalBp).toLocaleString('en-US'),
64
- " bp")))))
65
- : null,
66
- React.createElement("div", { className: classes.spacer }),
67
- menuAnchorEl ? (React.createElement(Menu, { anchorEl: menuAnchorEl, open: true, onMenuItemClick: (_event, callback) => {
68
- callback();
69
- setMenuAnchorEl(undefined);
70
- }, menuItems: model.headerMenuItems(), onClose: () => {
71
- setMenuAnchorEl(undefined);
72
- } })) : null));
55
+ React.createElement(CascadingMenuButton, { menuItems: [
56
+ {
57
+ label: 'Show search boxes',
58
+ type: 'checkbox',
59
+ checked: showSearchBoxes,
60
+ onClick: () => {
61
+ setShowSearchBoxes(!showSearchBoxes);
62
+ },
63
+ },
64
+ {
65
+ label: 'Orientation - Side-by-side',
66
+ type: 'radio',
67
+ checked: sideBySide,
68
+ onClick: () => {
69
+ setSideBySide(!sideBySide);
70
+ },
71
+ },
72
+ {
73
+ label: 'Orientation - Vertical',
74
+ type: 'radio',
75
+ checked: !sideBySide,
76
+ onClick: () => {
77
+ setSideBySide(!sideBySide);
78
+ },
79
+ },
80
+ ] },
81
+ React.createElement(SearchIcon, null)),
82
+ showSearchBoxes ? (React.createElement("span", { className: sideBySide ? classes.inline : undefined }, views.map(view => (React.createElement(HeaderSearchBoxes, { key: view.id, view: view }))))) : null));
73
83
  });
74
84
  export default Header;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
3
+ declare const HeaderSearchBoxes: ({ view, }: {
4
+ view: LinearGenomeViewModel;
5
+ }) => React.JSX.Element;
6
+ export default HeaderSearchBoxes;
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { Typography } from '@mui/material';
4
+ import { makeStyles } from 'tss-react/mui';
5
+ // jbrowse
6
+ import { SearchBox, } from '@jbrowse/plugin-linear-genome-view';
7
+ import { toLocale } from '@jbrowse/core/util';
8
+ const useStyles = makeStyles()(() => ({
9
+ bp: {
10
+ display: 'flex',
11
+ alignItems: 'center',
12
+ marginLeft: 10,
13
+ },
14
+ searchBox: {
15
+ display: 'flex',
16
+ },
17
+ }));
18
+ const HeaderSearchBoxes = observer(function ({ view, }) {
19
+ const { classes } = useStyles();
20
+ const { assemblyNames, coarseTotalBp } = view;
21
+ return (React.createElement("span", { className: classes.searchBox },
22
+ React.createElement(SearchBox, { model: view, showHelp: false }),
23
+ React.createElement(Typography, { variant: "body2", color: "textSecondary", className: classes.bp },
24
+ assemblyNames.join(','),
25
+ " ",
26
+ toLocale(Math.round(coarseTotalBp)),
27
+ " bp")));
28
+ });
29
+ export default HeaderSearchBoxes;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { LinearComparativeViewModel } from '../model';
3
+ declare const LinearComparativeRenderArea: ({ model, }: {
4
+ model: LinearComparativeViewModel;
5
+ }) => React.JSX.Element;
6
+ export default LinearComparativeRenderArea;
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { makeStyles } from 'tss-react/mui';
3
+ import { observer } from 'mobx-react';
4
+ import { getEnv } from '@jbrowse/core/util';
5
+ import { ResizeHandle } from '@jbrowse/core/ui';
6
+ import { getConf } from '@jbrowse/core/configuration';
7
+ const useStyles = makeStyles()({
8
+ container: {
9
+ display: 'grid',
10
+ },
11
+ overlay: {
12
+ zIndex: 100,
13
+ gridArea: '1/1',
14
+ },
15
+ resizeHandle: {
16
+ height: 4,
17
+ background: '#ccc',
18
+ },
19
+ });
20
+ function View({ view }) {
21
+ const { pluginManager } = getEnv(view);
22
+ const { ReactComponent } = pluginManager.getViewType(view.type);
23
+ return React.createElement(ReactComponent, { model: view });
24
+ }
25
+ const LinearComparativeRenderArea = observer(function ({ model, }) {
26
+ const { classes } = useStyles();
27
+ const { views, levels } = model;
28
+ const RenderList = [
29
+ React.createElement(View, { key: views[0].id, view: views[0] }),
30
+ ];
31
+ for (let i = 1; i < views.length; i++) {
32
+ const view = views[i];
33
+ const level = levels[i - 1];
34
+ RenderList.push(React.createElement(React.Fragment, { key: view.id },
35
+ React.createElement("div", { className: classes.container },
36
+ React.createElement(Overlays, { model: model, level: i - 1 })),
37
+ React.createElement(ResizeHandle, { onDrag: n => level === null || level === void 0 ? void 0 : level.setHeight(level.height + n), className: classes.resizeHandle }),
38
+ React.createElement(View, { view: view })));
39
+ }
40
+ return React.createElement("div", { className: classes.container }, RenderList);
41
+ });
42
+ const Overlays = observer(function ({ model, level, }) {
43
+ var _a;
44
+ const { classes } = useStyles();
45
+ return (React.createElement(React.Fragment, null, (_a = model.levels[level]) === null || _a === void 0 ? void 0 : _a.tracks.map(track => {
46
+ const [display] = track.displays;
47
+ const { RenderingComponent } = display;
48
+ const trackId = getConf(track, 'trackId');
49
+ return RenderingComponent ? (React.createElement("div", { className: classes.overlay, key: trackId, style: {
50
+ height: display.height,
51
+ overflow: 'hidden',
52
+ } },
53
+ React.createElement(RenderingComponent, { model: display }))) : null;
54
+ })));
55
+ });
56
+ export default LinearComparativeRenderArea;
@@ -1,8 +1,6 @@
1
1
  import React from 'react';
2
2
  import { LinearComparativeViewModel } from '../model';
3
- type LCV = LinearComparativeViewModel;
4
- declare const LinearComparativeView: (props: {
5
- ExtraButtons?: React.ReactNode;
6
- model: LCV;
3
+ declare const LinearComparativeView: ({ model, }: {
4
+ model: LinearComparativeViewModel;
7
5
  }) => React.JSX.Element;
8
6
  export default LinearComparativeView;
@@ -1,29 +1,10 @@
1
1
  import React from 'react';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
  import { observer } from 'mobx-react';
4
- import { getConf } from '@jbrowse/core/configuration';
5
- import { getEnv } from '@jbrowse/core/util';
6
- import { ResizeHandle } from '@jbrowse/core/ui';
7
4
  import Rubberband from './Rubberband';
8
5
  import Header from './Header';
6
+ import LinearComparativeRenderArea from './LinearComparativeRenderArea';
9
7
  const useStyles = makeStyles()(theme => ({
10
- container: {
11
- display: 'grid',
12
- },
13
- overlay: {
14
- zIndex: 100,
15
- gridArea: '1/1',
16
- },
17
- content: {
18
- gridArea: '1/1',
19
- position: 'relative',
20
- },
21
- grid: {
22
- display: 'grid',
23
- },
24
- relative: {
25
- position: 'relative',
26
- },
27
8
  // this helps keep the vertical guide inside the parent view container,
28
9
  // similar style exists in the single LGV's trackscontainer
29
10
  rubberbandContainer: {
@@ -39,56 +20,11 @@ const useStyles = makeStyles()(theme => ({
39
20
  },
40
21
  },
41
22
  }));
42
- const Overlays = observer(({ model }) => {
23
+ const LinearComparativeView = observer(function ({ model, }) {
43
24
  const { classes } = useStyles();
44
- return (React.createElement(React.Fragment, null, model.tracks.map(track => {
45
- const [display] = track.displays;
46
- const { RenderingComponent } = display;
47
- const trackId = getConf(track, 'trackId');
48
- return RenderingComponent ? (React.createElement("div", { className: classes.overlay, key: trackId, style: {
49
- height: model.middleComparativeHeight,
50
- overflow: 'hidden',
51
- } },
52
- React.createElement(RenderingComponent, { model: display }))) : null;
53
- })));
54
- });
55
- // The comparative is in the middle of the views
56
- const MiddleComparativeView = observer(({ model }) => {
57
- const { classes } = useStyles();
58
- const { views } = model;
59
- const { pluginManager } = getEnv(model);
60
- const { ReactComponent } = pluginManager.getViewType(views[0].type);
61
25
  return (React.createElement("div", { className: classes.rubberbandContainer },
62
26
  React.createElement(Header, { model: model }),
63
27
  React.createElement(Rubberband, { model: model, ControlComponent: React.createElement("div", { className: classes.rubberbandDiv }) }),
64
- React.createElement("div", { className: classes.container },
65
- React.createElement(ReactComponent, { model: views[0] }),
66
- React.createElement("div", { className: classes.grid },
67
- React.createElement(Overlays, { model: model })),
68
- React.createElement(ResizeHandle, { onDrag: n => model.setMiddleComparativeHeight(model.middleComparativeHeight + n), style: {
69
- height: 4,
70
- background: '#ccc',
71
- } }),
72
- React.createElement(ReactComponent, { model: views[1] }))));
73
- });
74
- const OverlayComparativeView = observer(({ model }) => {
75
- const { classes } = useStyles();
76
- const { views } = model;
77
- const { pluginManager } = getEnv(model);
78
- return (React.createElement("div", { className: classes.rubberbandContainer },
79
- React.createElement(Header, { model: model }),
80
- React.createElement(Rubberband, { model: model, ControlComponent: React.createElement("div", { className: classes.rubberbandDiv }) }),
81
- React.createElement("div", { className: classes.container },
82
- React.createElement("div", { className: classes.content },
83
- React.createElement("div", { className: classes.relative }, views.map(view => {
84
- const { ReactComponent } = pluginManager.getViewType(view.type);
85
- return React.createElement(ReactComponent, { key: view.id, model: view });
86
- })),
87
- React.createElement(Overlays, { model: model })))));
88
- });
89
- const LinearComparativeView = observer(function (props) {
90
- const { model } = props;
91
- const middle = model.tracks.some(({ displays }) => displays.some((d) => getConf(d, 'middle')));
92
- return middle ? (React.createElement(MiddleComparativeView, { ...props })) : (React.createElement(OverlayComparativeView, { ...props }));
28
+ React.createElement(LinearComparativeRenderArea, { model: model })));
93
29
  });
94
30
  export default LinearComparativeView;
@@ -140,7 +140,7 @@ const LinearComparativeRubberband = observer(function Rubberband({ model, Contro
140
140
  React.createElement("div", { ref: controlsRef, className: classes.rubberbandControl, onMouseDown: mouseDown, onMouseOut: mouseOut, onMouseMove: mouseMove }, ControlComponent)));
141
141
  }
142
142
  const right = anchorPosition ? anchorPosition.offsetX : currentX || 0;
143
- const left = right < startX ? right : startX;
143
+ const left = Math.min(right, startX);
144
144
  const width = Math.abs(right - startX);
145
145
  const { views } = model;
146
146
  const leftBpOffset = views.map(view => view.pxToBp(left));
@@ -5,6 +5,9 @@ export default function LinearComparativeViewF(pluginManager) {
5
5
  pluginManager.addViewType(() => {
6
6
  return new ViewType({
7
7
  name: 'LinearComparativeView',
8
+ viewMetadata: {
9
+ hiddenFromGUI: true,
10
+ },
8
11
  displayName: 'Linear comparative view',
9
12
  stateModel: modelFactory(pluginManager),
10
13
  ReactComponent: lazy(() => import('./components/LinearComparativeView')),