@jbrowse/plugin-breakpoint-split-view 2.7.1 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,10 @@
1
- import { Feature } from '@jbrowse/core/util';
1
+ import { Feature, Region } from '@jbrowse/core/util';
2
2
  import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType';
3
- import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
4
- type LGV = LinearGenomeViewModel;
3
+ import { IStateTreeNode } from 'mobx-state-tree';
5
4
  export default class BreakpointSplitViewType extends ViewType {
6
- snapshotFromBreakendFeature(feature: Feature, view: LGV): {
5
+ snapshotFromBreakendFeature(feature: Feature, view: {
6
+ displayedRegions: Region[];
7
+ } & IStateTreeNode): {
7
8
  type: string;
8
9
  views: {
9
10
  type: string;
@@ -18,6 +19,6 @@ export default class BreakpointSplitViewType extends ViewType {
18
19
  offsetPx: number;
19
20
  }[];
20
21
  displayName: string;
22
+ featureData: unknown;
21
23
  };
22
24
  }
23
- export {};
@@ -24,8 +24,7 @@ class BreakpointSplitViewType extends ViewType_1.default {
24
24
  if (!assembly.regions) {
25
25
  throw new Error(`assembly ${assemblyName} regions not loaded`);
26
26
  }
27
- const { getCanonicalRefName } = assembly;
28
- const featureRefName = getCanonicalRefName(feature.get('refName'));
27
+ const featureRefName = assembly.getCanonicalRefName(feature.get('refName'));
29
28
  const topRegion = assembly.regions.find(f => f.refName === featureRefName);
30
29
  let mateRefName;
31
30
  let startMod = 0;
@@ -34,12 +33,12 @@ class BreakpointSplitViewType extends ViewType_1.default {
34
33
  if (alt === '<TRA>') {
35
34
  const INFO = feature.get('INFO');
36
35
  endPos = INFO.END[0] - 1;
37
- mateRefName = getCanonicalRefName(INFO.CHR2[0]);
36
+ mateRefName = assembly.getCanonicalRefName(INFO.CHR2[0]);
38
37
  }
39
38
  else if (bnd === null || bnd === void 0 ? void 0 : bnd.MatePosition) {
40
39
  const matePosition = bnd.MatePosition.split(':');
41
40
  endPos = +matePosition[1] - 1;
42
- mateRefName = getCanonicalRefName(matePosition[0]);
41
+ mateRefName = assembly.getCanonicalRefName(matePosition[0]);
43
42
  if (bnd.Join === 'left') {
44
43
  startMod = -1;
45
44
  }
@@ -50,7 +49,7 @@ class BreakpointSplitViewType extends ViewType_1.default {
50
49
  else if (feature.get('mate')) {
51
50
  // a generic 'mate' feature
52
51
  const mate = feature.get('mate');
53
- mateRefName = getCanonicalRefName(mate.refName);
52
+ mateRefName = assembly.getCanonicalRefName(mate.refName);
54
53
  endPos = mate.start;
55
54
  }
56
55
  if (!mateRefName) {
@@ -85,6 +84,7 @@ class BreakpointSplitViewType extends ViewType_1.default {
85
84
  },
86
85
  ],
87
86
  displayName: `${feature.get('name') || feature.get('id') || 'breakend'} split detail`,
87
+ featureData: undefined,
88
88
  };
89
89
  }
90
90
  }
@@ -1,36 +1,13 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const react_1 = __importStar(require("react"));
6
+ const react_1 = __importDefault(require("react"));
30
7
  const mobx_react_1 = require("mobx-react");
31
8
  const mobx_state_tree_1 = require("mobx-state-tree");
32
9
  const mui_1 = require("tss-react/mui");
33
- const Overlay_1 = __importDefault(require("./Overlay"));
10
+ const BreakpointSplitViewOverlay_1 = __importDefault(require("./BreakpointSplitViewOverlay"));
34
11
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
35
12
  viewDivider: {
36
13
  background: theme.palette.secondary.main,
@@ -39,50 +16,32 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
39
16
  container: {
40
17
  display: 'grid',
41
18
  },
42
- overlay: {
43
- display: 'flex',
44
- width: '100%',
45
- gridArea: '1/1',
46
- '& path': {
47
- cursor: 'crosshair',
48
- fill: 'none',
49
- },
50
- },
51
19
  content: {
52
20
  gridArea: '1/1',
53
21
  },
54
22
  }));
55
- const BreakpointSplitView = (0, mobx_react_1.observer)(function ({ model, }) {
23
+ const BreakpointSplitViewLevels = (0, mobx_react_1.observer)(function ({ model, }) {
56
24
  const { classes } = useStyles();
57
25
  const { views } = model;
58
26
  const { pluginManager } = (0, mobx_state_tree_1.getEnv)(model);
59
- const ref = (0, react_1.useRef)(null);
27
+ return (react_1.default.createElement("div", { className: classes.content },
28
+ react_1.default.createElement("div", { style: { position: 'relative' } }, views.map((view, idx) => {
29
+ const { ReactComponent } = pluginManager.getViewType(view.type);
30
+ const viewComponent = react_1.default.createElement(ReactComponent, { key: view.id, model: view });
31
+ if (idx === views.length - 1) {
32
+ return viewComponent;
33
+ }
34
+ return [
35
+ viewComponent,
36
+ react_1.default.createElement("div", { key: `${view.id}-divider`, className: classes.viewDivider }),
37
+ ];
38
+ }))));
39
+ });
40
+ const BreakpointSplitView = (0, mobx_react_1.observer)(function ({ model, }) {
41
+ const { classes } = useStyles();
60
42
  return (react_1.default.createElement("div", null,
61
43
  react_1.default.createElement("div", { className: classes.container },
62
- react_1.default.createElement("div", { className: classes.content },
63
- react_1.default.createElement("div", { style: { position: 'relative' } }, views.map((view, idx) => {
64
- const { ReactComponent } = pluginManager.getViewType(view.type);
65
- const viewComponent = (react_1.default.createElement(ReactComponent, { key: view.id, model: view }));
66
- if (idx === views.length - 1) {
67
- return viewComponent;
68
- }
69
- return [
70
- viewComponent,
71
- react_1.default.createElement("div", { key: `${view.id}-divider`, className: classes.viewDivider }),
72
- ];
73
- }))),
74
- react_1.default.createElement("div", { className: classes.overlay },
75
- react_1.default.createElement("svg", { ref: ref, style: {
76
- width: '100%',
77
- zIndex: 10,
78
- pointerEvents: model.interactToggled ? undefined : 'none',
79
- } }, model.matchedTracks.map(track => (
80
- // note: we must pass ref down, because the child component
81
- // needs to getBoundingClientRect on the this components SVG,
82
- // and we cannot rely on using getBoundingClientRect in this
83
- // component to make sure this works because if it gets
84
- // shifted around by another element, this will not re-render
85
- // necessarily
86
- react_1.default.createElement(Overlay_1.default, { parentRef: ref, key: track.configuration.trackId, model: model, trackId: track.configuration.trackId }))))))));
44
+ react_1.default.createElement(BreakpointSplitViewLevels, { model: model }),
45
+ react_1.default.createElement(BreakpointSplitViewOverlay_1.default, { model: model }))));
87
46
  });
88
47
  exports.default = BreakpointSplitView;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { BreakpointViewModel } from '../model';
3
+ declare const BreakpointSplitViewOverlay: ({ model, }: {
4
+ model: BreakpointViewModel;
5
+ }) => React.JSX.Element;
6
+ export default BreakpointSplitViewOverlay;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const react_1 = __importStar(require("react"));
30
+ const mui_1 = require("tss-react/mui");
31
+ const Overlay_1 = __importDefault(require("./Overlay"));
32
+ const mobx_react_1 = require("mobx-react");
33
+ const useStyles = (0, mui_1.makeStyles)()({
34
+ overlay: {
35
+ display: 'flex',
36
+ width: '100%',
37
+ gridArea: '1/1',
38
+ '& path': {
39
+ cursor: 'crosshair',
40
+ fill: 'none',
41
+ },
42
+ },
43
+ });
44
+ const BreakpointSplitViewOverlay = (0, mobx_react_1.observer)(function ({ model, }) {
45
+ const { classes } = useStyles();
46
+ const { matchedTracks, interactToggled } = model;
47
+ const ref = (0, react_1.useRef)(null);
48
+ return (react_1.default.createElement("div", { className: classes.overlay },
49
+ react_1.default.createElement("svg", { ref: ref, style: {
50
+ width: '100%',
51
+ zIndex: 10,
52
+ pointerEvents: interactToggled ? undefined : 'none',
53
+ } }, matchedTracks.map(track => (
54
+ // note: we must pass ref down, because the child component needs to
55
+ // getBoundingClientRect on the this components SVG, and we cannot
56
+ // rely on using getBoundingClientRect in this component to make
57
+ // sure this works because if it gets shifted around by another
58
+ // element, this will not re-render necessarily
59
+ react_1.default.createElement(Overlay_1.default, { parentRef: ref, key: track.configuration.trackId, model: model, trackId: track.configuration.trackId }))))));
60
+ });
61
+ exports.default = BreakpointSplitViewOverlay;
@@ -24,6 +24,9 @@ export interface Breakend {
24
24
  MatePosition: string;
25
25
  }
26
26
  export type LayoutRecord = [number, number, number, number];
27
+ /**
28
+ * #stateModel BreakpointSplitView
29
+ */
27
30
  export default function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
28
31
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
29
32
  displayName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -59,9 +62,9 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
59
62
  hideHeaderOverview: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
60
63
  hideNoTracksActive: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
61
64
  trackSelectorType: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
62
- trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
63
65
  showCenterLine: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
64
66
  showCytobandsSetting: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
67
+ trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
65
68
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
66
69
  }, {
67
70
  width: number;
@@ -84,6 +87,7 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
84
87
  leftOffset: import("@jbrowse/plugin-linear-genome-view/src/LinearGenomeView").BpOffset | undefined;
85
88
  rightOffset: import("@jbrowse/plugin-linear-genome-view/src/LinearGenomeView").BpOffset | undefined;
86
89
  } & {
90
+ readonly trackLabelsSetting: any;
87
91
  readonly width: number;
88
92
  readonly interRegionPaddingWidth: number;
89
93
  readonly assemblyNames: string[];
@@ -242,10 +246,32 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
242
246
  */
243
247
  exportSvg(opts?: ExportSvgOptions): Promise<void>;
244
248
  } & {
249
+ /**
250
+ * #getter
251
+ * Find all track ids that match across multiple views
252
+ */
245
253
  readonly matchedTracks: any[];
254
+ /**
255
+ * #method
256
+ * Get tracks with a given trackId across multiple views
257
+ */
246
258
  getMatchedTracks(trackConfigId: string): any[];
259
+ /**
260
+ * #method
261
+ *
262
+ * Translocation features are handled differently
263
+ * since they do not have a mate e.g. they are one sided
264
+ */
247
265
  hasTranslocations(trackConfigId: string): Feature | undefined;
266
+ /**
267
+ * #method
268
+ * Get a composite map of featureId-\>feature map for a track across
269
+ * multiple views
270
+ */
248
271
  getTrackFeatures(trackConfigId: string): Map<string, Feature>;
272
+ /**
273
+ * #method
274
+ */
249
275
  getMatchedFeaturesInLayout(trackConfigId: string, features: Feature[][]): {
250
276
  feature: Feature;
251
277
  layout: LayoutRecord | undefined;
@@ -254,15 +280,39 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
254
280
  } & {
255
281
  afterAttach(): void;
256
282
  onSubviewAction(actionName: string, path: string, args?: unknown[]): void;
283
+ /**
284
+ * #action
285
+ */
257
286
  setWidth(newWidth: number): void;
287
+ /**
288
+ * #action
289
+ */
258
290
  removeView(view: LGV): void;
291
+ /**
292
+ * #action
293
+ */
259
294
  closeView(): void;
295
+ /**
296
+ * #action
297
+ */
260
298
  toggleInteract(): void;
299
+ /**
300
+ * #action
301
+ */
261
302
  toggleIntraviewLinks(): void;
303
+ /**
304
+ * #action
305
+ */
262
306
  toggleLinkViews(): void;
307
+ /**
308
+ * #action
309
+ */
263
310
  setMatchedTrackFeatures(obj: Record<string, Feature[][]>): void;
264
311
  } & {
265
312
  afterAttach(): void;
313
+ /**
314
+ * #method
315
+ */
266
316
  menuItems(): ({
267
317
  label: string;
268
318
  subMenu: import("@jbrowse/core/ui").MenuItem[];
@@ -59,20 +59,44 @@ async function getBlockFeatures(model, track) {
59
59
  regions: view.staticBlocks.contentBlocks,
60
60
  })).flat()));
61
61
  }
62
+ /**
63
+ * #stateModel BreakpointSplitView
64
+ */
62
65
  function stateModelFactory(pluginManager) {
63
66
  const minHeight = 40;
64
67
  const defaultHeight = 400;
65
- const model = mobx_state_tree_1.types
66
- .model('BreakpointSplitView', {
68
+ return mobx_state_tree_1.types
69
+ .compose('BreakpointSplitView', models_1.BaseViewModel, mobx_state_tree_1.types.model({
70
+ /**
71
+ * #property
72
+ */
67
73
  type: mobx_state_tree_1.types.literal('BreakpointSplitView'),
74
+ /**
75
+ * #property
76
+ */
68
77
  height: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.refinement('viewHeight', mobx_state_tree_1.types.number, (n) => n >= minHeight), defaultHeight),
78
+ /**
79
+ * #property
80
+ */
69
81
  trackSelectorType: 'hierarchical',
82
+ /**
83
+ * #property
84
+ */
70
85
  showIntraviewLinks: true,
86
+ /**
87
+ * #property
88
+ */
71
89
  linkViews: false,
90
+ /**
91
+ * #property
92
+ */
72
93
  interactToggled: false,
94
+ /**
95
+ * #property
96
+ */
73
97
  views: mobx_state_tree_1.types.array(pluginManager.getViewType('LinearGenomeView')
74
98
  .stateModel),
75
- })
99
+ }))
76
100
  .volatile(() => ({
77
101
  width: 800,
78
102
  matchedTrackFeatures: {},
@@ -90,27 +114,43 @@ function stateModelFactory(pluginManager) {
90
114
  },
91
115
  }))
92
116
  .views(self => ({
93
- // Find all track ids that match across multiple views
117
+ /**
118
+ * #getter
119
+ * Find all track ids that match across multiple views
120
+ */
94
121
  get matchedTracks() {
95
122
  return (0, util_2.intersect)(elt => elt.configuration.trackId, ...self.views.map(view => view.tracks));
96
123
  },
97
- // Get tracks with a given trackId across multiple views
124
+ /**
125
+ * #method
126
+ * Get tracks with a given trackId across multiple views
127
+ */
98
128
  getMatchedTracks(trackConfigId) {
99
129
  return self.views
100
130
  .map(view => view.getTrack(trackConfigId))
101
131
  .filter(f => !!f);
102
132
  },
103
- // Translocation features are handled differently
104
- // since they do not have a mate e.g. they are one sided
133
+ /**
134
+ * #method
135
+ *
136
+ * Translocation features are handled differently
137
+ * since they do not have a mate e.g. they are one sided
138
+ */
105
139
  hasTranslocations(trackConfigId) {
106
140
  return [...this.getTrackFeatures(trackConfigId).values()].find(f => f.get('type') === 'translocation');
107
141
  },
108
- // Get a composite map of featureId->feature map for a track across
109
- // multiple views
142
+ /**
143
+ * #method
144
+ * Get a composite map of featureId-\>feature map for a track across
145
+ * multiple views
146
+ */
110
147
  getTrackFeatures(trackConfigId) {
111
148
  var _a;
112
149
  return new Map((_a = self.matchedTrackFeatures[trackConfigId]) === null || _a === void 0 ? void 0 : _a.flat().map(f => [f.id(), f]));
113
150
  },
151
+ /**
152
+ * #method
153
+ */
114
154
  getMatchedFeaturesInLayout(trackConfigId, features) {
115
155
  // use reverse to search the second track first
116
156
  const tracks = this.getMatchedTracks(trackConfigId);
@@ -157,26 +197,47 @@ function stateModelFactory(pluginManager) {
157
197
  }
158
198
  });
159
199
  },
200
+ /**
201
+ * #action
202
+ */
160
203
  setWidth(newWidth) {
161
204
  self.width = newWidth;
162
205
  self.views.forEach(v => v.setWidth(newWidth));
163
206
  },
207
+ /**
208
+ * #action
209
+ */
164
210
  removeView(view) {
165
211
  self.views.remove(view);
166
212
  },
213
+ /**
214
+ * #action
215
+ */
167
216
  closeView() {
168
217
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
169
218
  (0, mobx_state_tree_1.getParent)(self, 2).removeView(self);
170
219
  },
220
+ /**
221
+ * #action
222
+ */
171
223
  toggleInteract() {
172
224
  self.interactToggled = !self.interactToggled;
173
225
  },
226
+ /**
227
+ * #action
228
+ */
174
229
  toggleIntraviewLinks() {
175
230
  self.showIntraviewLinks = !self.showIntraviewLinks;
176
231
  },
232
+ /**
233
+ * #action
234
+ */
177
235
  toggleLinkViews() {
178
236
  self.linkViews = !self.linkViews;
179
237
  },
238
+ /**
239
+ * #action
240
+ */
180
241
  setMatchedTrackFeatures(obj) {
181
242
  self.matchedTrackFeatures = obj;
182
243
  },
@@ -200,6 +261,9 @@ function stateModelFactory(pluginManager) {
200
261
  }
201
262
  }));
202
263
  },
264
+ /**
265
+ * #method
266
+ */
203
267
  menuItems() {
204
268
  return [
205
269
  ...self.views
@@ -240,6 +304,5 @@ function stateModelFactory(pluginManager) {
240
304
  ];
241
305
  },
242
306
  }));
243
- return mobx_state_tree_1.types.compose(models_1.BaseViewModel, model);
244
307
  }
245
308
  exports.default = stateModelFactory;
@@ -1,9 +1,10 @@
1
- import { Feature } from '@jbrowse/core/util';
1
+ import { Feature, Region } from '@jbrowse/core/util';
2
2
  import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType';
3
- import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
4
- type LGV = LinearGenomeViewModel;
3
+ import { IStateTreeNode } from 'mobx-state-tree';
5
4
  export default class BreakpointSplitViewType extends ViewType {
6
- snapshotFromBreakendFeature(feature: Feature, view: LGV): {
5
+ snapshotFromBreakendFeature(feature: Feature, view: {
6
+ displayedRegions: Region[];
7
+ } & IStateTreeNode): {
7
8
  type: string;
8
9
  views: {
9
10
  type: string;
@@ -18,6 +19,6 @@ export default class BreakpointSplitViewType extends ViewType {
18
19
  offsetPx: number;
19
20
  }[];
20
21
  displayName: string;
22
+ featureData: unknown;
21
23
  };
22
24
  }
23
- export {};
@@ -19,8 +19,7 @@ export default class BreakpointSplitViewType extends ViewType {
19
19
  if (!assembly.regions) {
20
20
  throw new Error(`assembly ${assemblyName} regions not loaded`);
21
21
  }
22
- const { getCanonicalRefName } = assembly;
23
- const featureRefName = getCanonicalRefName(feature.get('refName'));
22
+ const featureRefName = assembly.getCanonicalRefName(feature.get('refName'));
24
23
  const topRegion = assembly.regions.find(f => f.refName === featureRefName);
25
24
  let mateRefName;
26
25
  let startMod = 0;
@@ -29,12 +28,12 @@ export default class BreakpointSplitViewType extends ViewType {
29
28
  if (alt === '<TRA>') {
30
29
  const INFO = feature.get('INFO');
31
30
  endPos = INFO.END[0] - 1;
32
- mateRefName = getCanonicalRefName(INFO.CHR2[0]);
31
+ mateRefName = assembly.getCanonicalRefName(INFO.CHR2[0]);
33
32
  }
34
33
  else if (bnd === null || bnd === void 0 ? void 0 : bnd.MatePosition) {
35
34
  const matePosition = bnd.MatePosition.split(':');
36
35
  endPos = +matePosition[1] - 1;
37
- mateRefName = getCanonicalRefName(matePosition[0]);
36
+ mateRefName = assembly.getCanonicalRefName(matePosition[0]);
38
37
  if (bnd.Join === 'left') {
39
38
  startMod = -1;
40
39
  }
@@ -45,7 +44,7 @@ export default class BreakpointSplitViewType extends ViewType {
45
44
  else if (feature.get('mate')) {
46
45
  // a generic 'mate' feature
47
46
  const mate = feature.get('mate');
48
- mateRefName = getCanonicalRefName(mate.refName);
47
+ mateRefName = assembly.getCanonicalRefName(mate.refName);
49
48
  endPos = mate.start;
50
49
  }
51
50
  if (!mateRefName) {
@@ -80,6 +79,7 @@ export default class BreakpointSplitViewType extends ViewType {
80
79
  },
81
80
  ],
82
81
  displayName: `${feature.get('name') || feature.get('id') || 'breakend'} split detail`,
82
+ featureData: undefined,
83
83
  };
84
84
  }
85
85
  }
@@ -1,8 +1,8 @@
1
- import React, { useRef } from 'react';
1
+ import React from 'react';
2
2
  import { observer } from 'mobx-react';
3
3
  import { getEnv } from 'mobx-state-tree';
4
4
  import { makeStyles } from 'tss-react/mui';
5
- import Overlay from './Overlay';
5
+ import BreakpointSplitViewOverlay from './BreakpointSplitViewOverlay';
6
6
  const useStyles = makeStyles()(theme => ({
7
7
  viewDivider: {
8
8
  background: theme.palette.secondary.main,
@@ -11,50 +11,32 @@ const useStyles = makeStyles()(theme => ({
11
11
  container: {
12
12
  display: 'grid',
13
13
  },
14
- overlay: {
15
- display: 'flex',
16
- width: '100%',
17
- gridArea: '1/1',
18
- '& path': {
19
- cursor: 'crosshair',
20
- fill: 'none',
21
- },
22
- },
23
14
  content: {
24
15
  gridArea: '1/1',
25
16
  },
26
17
  }));
27
- const BreakpointSplitView = observer(function ({ model, }) {
18
+ const BreakpointSplitViewLevels = observer(function ({ model, }) {
28
19
  const { classes } = useStyles();
29
20
  const { views } = model;
30
21
  const { pluginManager } = getEnv(model);
31
- const ref = useRef(null);
22
+ return (React.createElement("div", { className: classes.content },
23
+ React.createElement("div", { style: { position: 'relative' } }, views.map((view, idx) => {
24
+ const { ReactComponent } = pluginManager.getViewType(view.type);
25
+ const viewComponent = React.createElement(ReactComponent, { key: view.id, model: view });
26
+ if (idx === views.length - 1) {
27
+ return viewComponent;
28
+ }
29
+ return [
30
+ viewComponent,
31
+ React.createElement("div", { key: `${view.id}-divider`, className: classes.viewDivider }),
32
+ ];
33
+ }))));
34
+ });
35
+ const BreakpointSplitView = observer(function ({ model, }) {
36
+ const { classes } = useStyles();
32
37
  return (React.createElement("div", null,
33
38
  React.createElement("div", { className: classes.container },
34
- React.createElement("div", { className: classes.content },
35
- React.createElement("div", { style: { position: 'relative' } }, views.map((view, idx) => {
36
- const { ReactComponent } = pluginManager.getViewType(view.type);
37
- const viewComponent = (React.createElement(ReactComponent, { key: view.id, model: view }));
38
- if (idx === views.length - 1) {
39
- return viewComponent;
40
- }
41
- return [
42
- viewComponent,
43
- React.createElement("div", { key: `${view.id}-divider`, className: classes.viewDivider }),
44
- ];
45
- }))),
46
- React.createElement("div", { className: classes.overlay },
47
- React.createElement("svg", { ref: ref, style: {
48
- width: '100%',
49
- zIndex: 10,
50
- pointerEvents: model.interactToggled ? undefined : 'none',
51
- } }, model.matchedTracks.map(track => (
52
- // note: we must pass ref down, because the child component
53
- // needs to getBoundingClientRect on the this components SVG,
54
- // and we cannot rely on using getBoundingClientRect in this
55
- // component to make sure this works because if it gets
56
- // shifted around by another element, this will not re-render
57
- // necessarily
58
- React.createElement(Overlay, { parentRef: ref, key: track.configuration.trackId, model: model, trackId: track.configuration.trackId }))))))));
39
+ React.createElement(BreakpointSplitViewLevels, { model: model }),
40
+ React.createElement(BreakpointSplitViewOverlay, { model: model }))));
59
41
  });
60
42
  export default BreakpointSplitView;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { BreakpointViewModel } from '../model';
3
+ declare const BreakpointSplitViewOverlay: ({ model, }: {
4
+ model: BreakpointViewModel;
5
+ }) => React.JSX.Element;
6
+ export default BreakpointSplitViewOverlay;
@@ -0,0 +1,33 @@
1
+ import React, { useRef } from 'react';
2
+ import { makeStyles } from 'tss-react/mui';
3
+ import Overlay from './Overlay';
4
+ import { observer } from 'mobx-react';
5
+ const useStyles = makeStyles()({
6
+ overlay: {
7
+ display: 'flex',
8
+ width: '100%',
9
+ gridArea: '1/1',
10
+ '& path': {
11
+ cursor: 'crosshair',
12
+ fill: 'none',
13
+ },
14
+ },
15
+ });
16
+ const BreakpointSplitViewOverlay = observer(function ({ model, }) {
17
+ const { classes } = useStyles();
18
+ const { matchedTracks, interactToggled } = model;
19
+ const ref = useRef(null);
20
+ return (React.createElement("div", { className: classes.overlay },
21
+ React.createElement("svg", { ref: ref, style: {
22
+ width: '100%',
23
+ zIndex: 10,
24
+ pointerEvents: interactToggled ? undefined : 'none',
25
+ } }, matchedTracks.map(track => (
26
+ // note: we must pass ref down, because the child component needs to
27
+ // getBoundingClientRect on the this components SVG, and we cannot
28
+ // rely on using getBoundingClientRect in this component to make
29
+ // sure this works because if it gets shifted around by another
30
+ // element, this will not re-render necessarily
31
+ React.createElement(Overlay, { parentRef: ref, key: track.configuration.trackId, model: model, trackId: track.configuration.trackId }))))));
32
+ });
33
+ export default BreakpointSplitViewOverlay;
@@ -24,6 +24,9 @@ export interface Breakend {
24
24
  MatePosition: string;
25
25
  }
26
26
  export type LayoutRecord = [number, number, number, number];
27
+ /**
28
+ * #stateModel BreakpointSplitView
29
+ */
27
30
  export default function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
28
31
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
29
32
  displayName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -59,9 +62,9 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
59
62
  hideHeaderOverview: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
60
63
  hideNoTracksActive: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
61
64
  trackSelectorType: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
62
- trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
63
65
  showCenterLine: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
64
66
  showCytobandsSetting: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
67
+ trackLabels: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
65
68
  showGridlines: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
66
69
  }, {
67
70
  width: number;
@@ -84,6 +87,7 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
84
87
  leftOffset: import("@jbrowse/plugin-linear-genome-view/src/LinearGenomeView").BpOffset | undefined;
85
88
  rightOffset: import("@jbrowse/plugin-linear-genome-view/src/LinearGenomeView").BpOffset | undefined;
86
89
  } & {
90
+ readonly trackLabelsSetting: any;
87
91
  readonly width: number;
88
92
  readonly interRegionPaddingWidth: number;
89
93
  readonly assemblyNames: string[];
@@ -242,10 +246,32 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
242
246
  */
243
247
  exportSvg(opts?: ExportSvgOptions): Promise<void>;
244
248
  } & {
249
+ /**
250
+ * #getter
251
+ * Find all track ids that match across multiple views
252
+ */
245
253
  readonly matchedTracks: any[];
254
+ /**
255
+ * #method
256
+ * Get tracks with a given trackId across multiple views
257
+ */
246
258
  getMatchedTracks(trackConfigId: string): any[];
259
+ /**
260
+ * #method
261
+ *
262
+ * Translocation features are handled differently
263
+ * since they do not have a mate e.g. they are one sided
264
+ */
247
265
  hasTranslocations(trackConfigId: string): Feature | undefined;
266
+ /**
267
+ * #method
268
+ * Get a composite map of featureId-\>feature map for a track across
269
+ * multiple views
270
+ */
248
271
  getTrackFeatures(trackConfigId: string): Map<string, Feature>;
272
+ /**
273
+ * #method
274
+ */
249
275
  getMatchedFeaturesInLayout(trackConfigId: string, features: Feature[][]): {
250
276
  feature: Feature;
251
277
  layout: LayoutRecord | undefined;
@@ -254,15 +280,39 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
254
280
  } & {
255
281
  afterAttach(): void;
256
282
  onSubviewAction(actionName: string, path: string, args?: unknown[]): void;
283
+ /**
284
+ * #action
285
+ */
257
286
  setWidth(newWidth: number): void;
287
+ /**
288
+ * #action
289
+ */
258
290
  removeView(view: LGV): void;
291
+ /**
292
+ * #action
293
+ */
259
294
  closeView(): void;
295
+ /**
296
+ * #action
297
+ */
260
298
  toggleInteract(): void;
299
+ /**
300
+ * #action
301
+ */
261
302
  toggleIntraviewLinks(): void;
303
+ /**
304
+ * #action
305
+ */
262
306
  toggleLinkViews(): void;
307
+ /**
308
+ * #action
309
+ */
263
310
  setMatchedTrackFeatures(obj: Record<string, Feature[][]>): void;
264
311
  } & {
265
312
  afterAttach(): void;
313
+ /**
314
+ * #method
315
+ */
266
316
  menuItems(): ({
267
317
  label: string;
268
318
  subMenu: import("@jbrowse/core/ui").MenuItem[];
@@ -31,20 +31,44 @@ async function getBlockFeatures(model, track) {
31
31
  regions: view.staticBlocks.contentBlocks,
32
32
  })).flat()));
33
33
  }
34
+ /**
35
+ * #stateModel BreakpointSplitView
36
+ */
34
37
  export default function stateModelFactory(pluginManager) {
35
38
  const minHeight = 40;
36
39
  const defaultHeight = 400;
37
- const model = types
38
- .model('BreakpointSplitView', {
40
+ return types
41
+ .compose('BreakpointSplitView', BaseViewModel, types.model({
42
+ /**
43
+ * #property
44
+ */
39
45
  type: types.literal('BreakpointSplitView'),
46
+ /**
47
+ * #property
48
+ */
40
49
  height: types.optional(types.refinement('viewHeight', types.number, (n) => n >= minHeight), defaultHeight),
50
+ /**
51
+ * #property
52
+ */
41
53
  trackSelectorType: 'hierarchical',
54
+ /**
55
+ * #property
56
+ */
42
57
  showIntraviewLinks: true,
58
+ /**
59
+ * #property
60
+ */
43
61
  linkViews: false,
62
+ /**
63
+ * #property
64
+ */
44
65
  interactToggled: false,
66
+ /**
67
+ * #property
68
+ */
45
69
  views: types.array(pluginManager.getViewType('LinearGenomeView')
46
70
  .stateModel),
47
- })
71
+ }))
48
72
  .volatile(() => ({
49
73
  width: 800,
50
74
  matchedTrackFeatures: {},
@@ -62,27 +86,43 @@ export default function stateModelFactory(pluginManager) {
62
86
  },
63
87
  }))
64
88
  .views(self => ({
65
- // Find all track ids that match across multiple views
89
+ /**
90
+ * #getter
91
+ * Find all track ids that match across multiple views
92
+ */
66
93
  get matchedTracks() {
67
94
  return intersect(elt => elt.configuration.trackId, ...self.views.map(view => view.tracks));
68
95
  },
69
- // Get tracks with a given trackId across multiple views
96
+ /**
97
+ * #method
98
+ * Get tracks with a given trackId across multiple views
99
+ */
70
100
  getMatchedTracks(trackConfigId) {
71
101
  return self.views
72
102
  .map(view => view.getTrack(trackConfigId))
73
103
  .filter(f => !!f);
74
104
  },
75
- // Translocation features are handled differently
76
- // since they do not have a mate e.g. they are one sided
105
+ /**
106
+ * #method
107
+ *
108
+ * Translocation features are handled differently
109
+ * since they do not have a mate e.g. they are one sided
110
+ */
77
111
  hasTranslocations(trackConfigId) {
78
112
  return [...this.getTrackFeatures(trackConfigId).values()].find(f => f.get('type') === 'translocation');
79
113
  },
80
- // Get a composite map of featureId->feature map for a track across
81
- // multiple views
114
+ /**
115
+ * #method
116
+ * Get a composite map of featureId-\>feature map for a track across
117
+ * multiple views
118
+ */
82
119
  getTrackFeatures(trackConfigId) {
83
120
  var _a;
84
121
  return new Map((_a = self.matchedTrackFeatures[trackConfigId]) === null || _a === void 0 ? void 0 : _a.flat().map(f => [f.id(), f]));
85
122
  },
123
+ /**
124
+ * #method
125
+ */
86
126
  getMatchedFeaturesInLayout(trackConfigId, features) {
87
127
  // use reverse to search the second track first
88
128
  const tracks = this.getMatchedTracks(trackConfigId);
@@ -129,26 +169,47 @@ export default function stateModelFactory(pluginManager) {
129
169
  }
130
170
  });
131
171
  },
172
+ /**
173
+ * #action
174
+ */
132
175
  setWidth(newWidth) {
133
176
  self.width = newWidth;
134
177
  self.views.forEach(v => v.setWidth(newWidth));
135
178
  },
179
+ /**
180
+ * #action
181
+ */
136
182
  removeView(view) {
137
183
  self.views.remove(view);
138
184
  },
185
+ /**
186
+ * #action
187
+ */
139
188
  closeView() {
140
189
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
141
190
  getParent(self, 2).removeView(self);
142
191
  },
192
+ /**
193
+ * #action
194
+ */
143
195
  toggleInteract() {
144
196
  self.interactToggled = !self.interactToggled;
145
197
  },
198
+ /**
199
+ * #action
200
+ */
146
201
  toggleIntraviewLinks() {
147
202
  self.showIntraviewLinks = !self.showIntraviewLinks;
148
203
  },
204
+ /**
205
+ * #action
206
+ */
149
207
  toggleLinkViews() {
150
208
  self.linkViews = !self.linkViews;
151
209
  },
210
+ /**
211
+ * #action
212
+ */
152
213
  setMatchedTrackFeatures(obj) {
153
214
  self.matchedTrackFeatures = obj;
154
215
  },
@@ -172,6 +233,9 @@ export default function stateModelFactory(pluginManager) {
172
233
  }
173
234
  }));
174
235
  },
236
+ /**
237
+ * #method
238
+ */
175
239
  menuItems() {
176
240
  return [
177
241
  ...self.views
@@ -212,5 +276,4 @@ export default function stateModelFactory(pluginManager) {
212
276
  ];
213
277
  },
214
278
  }));
215
- return types.compose(BaseViewModel, model);
216
279
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-breakpoint-split-view",
3
- "version": "2.7.1",
3
+ "version": "2.8.0",
4
4
  "description": "JBrowse 2 breakpoint detail split view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -58,5 +58,5 @@
58
58
  "publishConfig": {
59
59
  "access": "public"
60
60
  },
61
- "gitHead": "2cda1611eebd12517f2a3cfc1b612face27005d4"
61
+ "gitHead": "ee8c2bdc8bd4f1a70b1eefda984f04a2830d9ca0"
62
62
  }