@jbrowse/plugin-linear-comparative-view 2.16.0 → 2.17.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 (43) hide show
  1. package/dist/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.d.ts +2 -1
  2. package/dist/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.js +4 -2
  3. package/dist/LGVSyntenyDisplay/components/util.d.ts +4 -1
  4. package/dist/LGVSyntenyDisplay/components/util.js +7 -15
  5. package/dist/LGVSyntenyDisplay/model.d.ts +30 -34
  6. package/dist/LGVSyntenyDisplay/model.js +23 -1
  7. package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +28 -5
  8. package/dist/LinearComparativeDisplay/stateModelFactory.js +14 -3
  9. package/dist/LinearSyntenyDisplay/afterAttach.js +2 -3
  10. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +21 -15
  11. package/dist/LinearSyntenyDisplay/components/SyntenyContextMenu.js +2 -4
  12. package/dist/LinearSyntenyDisplay/components/util.d.ts +5 -1
  13. package/dist/LinearSyntenyDisplay/components/util.js +7 -9
  14. package/dist/LinearSyntenyDisplay/drawSynteny.js +7 -9
  15. package/dist/LinearSyntenyDisplay/model.d.ts +48 -11
  16. package/dist/LinearSyntenyDisplay/model.js +38 -22
  17. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +14 -0
  18. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js +100 -0
  19. package/dist/SyntenyFeatureDetail/index.d.ts +2 -0
  20. package/dist/SyntenyFeatureDetail/index.js +56 -0
  21. package/dist/index.js +2 -0
  22. package/esm/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.d.ts +2 -1
  23. package/esm/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.js +4 -2
  24. package/esm/LGVSyntenyDisplay/components/util.d.ts +4 -1
  25. package/esm/LGVSyntenyDisplay/components/util.js +8 -16
  26. package/esm/LGVSyntenyDisplay/model.d.ts +30 -34
  27. package/esm/LGVSyntenyDisplay/model.js +25 -3
  28. package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +28 -5
  29. package/esm/LinearComparativeDisplay/stateModelFactory.js +14 -3
  30. package/esm/LinearSyntenyDisplay/afterAttach.js +3 -4
  31. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +21 -15
  32. package/esm/LinearSyntenyDisplay/components/SyntenyContextMenu.js +2 -4
  33. package/esm/LinearSyntenyDisplay/components/util.d.ts +5 -1
  34. package/esm/LinearSyntenyDisplay/components/util.js +7 -9
  35. package/esm/LinearSyntenyDisplay/drawSynteny.js +7 -9
  36. package/esm/LinearSyntenyDisplay/model.d.ts +48 -11
  37. package/esm/LinearSyntenyDisplay/model.js +39 -23
  38. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +14 -0
  39. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js +72 -0
  40. package/esm/SyntenyFeatureDetail/index.d.ts +2 -0
  41. package/esm/SyntenyFeatureDetail/index.js +27 -0
  42. package/esm/index.js +2 -0
  43. package/package.json +3 -3
@@ -6,7 +6,6 @@ exports.drawRef = drawRef;
6
6
  exports.drawMouseoverSynteny = drawMouseoverSynteny;
7
7
  const util_1 = require("@jbrowse/core/util");
8
8
  const util_2 = require("./components/util");
9
- const mobx_state_tree_1 = require("mobx-state-tree");
10
9
  exports.MAX_COLOR_RANGE = 255 * 255 * 255; // max color range
11
10
  function makeColor(idx) {
12
11
  const r = Math.floor(idx / (255 * 255)) % 255;
@@ -30,11 +29,9 @@ function getId(r, g, b, unitMultiplier) {
30
29
  function drawRef(model, ctx1, ctx3) {
31
30
  var _a;
32
31
  const view = (0, util_1.getContainingView)(model);
33
- // @ts-expect-error
34
- const level = (0, mobx_state_tree_1.getParent)(model, 4).level;
35
32
  const drawCurves = view.drawCurves;
36
33
  const drawCIGAR = view.drawCIGAR;
37
- const { height, featPositions } = model;
34
+ const { level, height, featPositions } = model;
38
35
  const width = view.width;
39
36
  const bpPerPxs = view.views.map(v => v.bpPerPx);
40
37
  if (ctx3) {
@@ -150,9 +147,11 @@ function drawRef(model, ctx1, ctx3) {
150
147
  colorMap[(continuingFlag && d1 > 1) || d2 > 1 ? op : 'M'];
151
148
  continuingFlag = false;
152
149
  (0, util_2.draw)(ctx1, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
150
+ ctx1.fill();
153
151
  if (ctx3) {
154
152
  ctx3.fillStyle = makeColor(idx);
155
153
  (0, util_2.draw)(ctx3, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
154
+ ctx3.fill();
156
155
  }
157
156
  }
158
157
  }
@@ -160,6 +159,7 @@ function drawRef(model, ctx1, ctx3) {
160
159
  }
161
160
  else {
162
161
  (0, util_2.draw)(ctx1, x11, x12, y1, x22, x21, y2, mid, drawCurves);
162
+ ctx1.fill();
163
163
  }
164
164
  }
165
165
  }
@@ -193,7 +193,7 @@ function drawRef(model, ctx1, ctx3) {
193
193
  }
194
194
  function drawMouseoverSynteny(model) {
195
195
  var _a;
196
- const { clickId, mouseoverId } = model;
196
+ const { level, clickId, mouseoverId } = model;
197
197
  const highResolutionScaling = 1;
198
198
  const view = (0, util_1.getContainingView)(model);
199
199
  const drawCurves = view.drawCurves;
@@ -201,17 +201,16 @@ function drawMouseoverSynteny(model) {
201
201
  const width = view.width;
202
202
  const ctx = (_a = model.mouseoverCanvas) === null || _a === void 0 ? void 0 : _a.getContext('2d');
203
203
  const offsets = view.views.map(v => v.offsetPx);
204
- // @ts-expect-error
205
- const level = (0, mobx_state_tree_1.getParent)(model, 4).level;
206
204
  if (!ctx) {
207
205
  return;
208
206
  }
209
207
  ctx.resetTransform();
210
208
  ctx.scale(highResolutionScaling, highResolutionScaling);
211
209
  ctx.clearRect(0, 0, width, height);
210
+ ctx.strokeStyle = 'rgba(0, 0, 0, 0.9)';
211
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
212
212
  const feature1 = model.featMap[mouseoverId || ''];
213
213
  if (feature1) {
214
- ctx.fillStyle = 'rgb(0,0,0,0.1)';
215
214
  (0, util_2.drawMatchSimple)({
216
215
  cb: ctx => {
217
216
  ctx.fill();
@@ -228,7 +227,6 @@ function drawMouseoverSynteny(model) {
228
227
  }
229
228
  const feature2 = model.featMap[clickId || ''];
230
229
  if (feature2) {
231
- ctx.strokeStyle = 'rgb(0, 0, 0, 0.9)';
232
230
  (0, util_2.drawMatchSimple)({
233
231
  cb: ctx => {
234
232
  ctx.stroke();
@@ -68,9 +68,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
68
68
  rendererTypeName: string;
69
69
  error: unknown;
70
70
  message: string | undefined;
71
- } & import("mobx-state-tree" /**
72
- * #action
73
- */).IStateTreeNode<import("mobx-state-tree").IModelType<{
71
+ } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
74
72
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
75
73
  type: import("mobx-state-tree").ISimpleType<string>;
76
74
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -98,6 +96,8 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
98
96
  features: Feature[] | undefined;
99
97
  message: string | undefined;
100
98
  } & {
99
+ readonly level: number;
100
+ readonly height: number;
101
101
  renderProps(): {
102
102
  rpcDriverName: string | undefined;
103
103
  displayModel: {
@@ -113,7 +113,12 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
113
113
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
114
114
  [x: string]: any;
115
115
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
116
- } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
116
+ } & import("mobx-state-tree" /**
117
+ * #volatile
118
+ * canvas for drawing mouseover shading this is separate from the other
119
+ * code for speed: don't have to redraw entire canvas to do a feature's
120
+ * mouseover shading
121
+ */).IStateTreeNode<AnyConfigurationSchemaType>);
117
122
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
118
123
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
119
124
  rendererTypeName: string;
@@ -150,9 +155,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
150
155
  rendererTypeName: string;
151
156
  error: unknown;
152
157
  message: string | undefined;
153
- } & import("mobx-state-tree" /**
154
- * #action
155
- */).IStateTreeNode<import("mobx-state-tree").IModelType<{
158
+ } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
156
159
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
157
160
  type: import("mobx-state-tree").ISimpleType<string>;
158
161
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -261,13 +264,51 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
261
264
  } & {
262
265
  afterAttach(): void;
263
266
  } & {
267
+ /**
268
+ * #volatile
269
+ * canvas used for drawing visible screen
270
+ */
264
271
  mainCanvas: HTMLCanvasElement | null;
272
+ /**
273
+ * #volatile
274
+ * canvas used for drawing click map with feature ids this renders a
275
+ * unique color per alignment, so that it can be re-traced after a
276
+ * feature click with getImageData at that pixel
277
+ */
265
278
  clickMapCanvas: HTMLCanvasElement | null;
279
+ /**
280
+ * #volatile
281
+ * canvas used for drawing click map with cigar data this can show if you
282
+ * are mousing over a insertion/deletion. it is similar in purpose to the
283
+ * clickMapRef but was not feasible to pack this into the clickMapRef
284
+ */
266
285
  cigarClickMapCanvas: HTMLCanvasElement | null;
286
+ /**
287
+ * #volatile
288
+ * canvas for drawing mouseover shading this is separate from the other
289
+ * code for speed: don't have to redraw entire canvas to do a feature's
290
+ * mouseover shading
291
+ */
267
292
  mouseoverCanvas: HTMLCanvasElement | null;
293
+ /**
294
+ * #volatile
295
+ * assigned by reaction
296
+ */
268
297
  featPositions: FeatPos[];
298
+ /**
299
+ * #volatile
300
+ * currently mouse'd over feature
301
+ */
269
302
  mouseoverId: string | undefined;
303
+ /**
304
+ * #volatile
305
+ * currently click'd over feature
306
+ */
270
307
  clickId: string | undefined;
308
+ /**
309
+ * #volatile
310
+ * currently mouseover'd CIGAR subfeature
311
+ */
271
312
  cigarMouseoverId: number;
272
313
  } & {
273
314
  /**
@@ -311,10 +352,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
311
352
  * #getter
312
353
  */
313
354
  readonly trackIds: string[];
314
- /**
315
- * #getter
316
- */
317
- readonly height: number;
318
355
  /**
319
356
  * #getter
320
357
  */
@@ -48,28 +48,51 @@ function stateModelFactory(configSchema) {
48
48
  configuration: (0, configuration_1.ConfigurationReference)(configSchema),
49
49
  }))
50
50
  .volatile(() => ({
51
- // canvas used for drawing visible screen
51
+ /**
52
+ * #volatile
53
+ * canvas used for drawing visible screen
54
+ */
52
55
  mainCanvas: null,
53
- // canvas used for drawing click map with feature ids
54
- // this renders a unique color per alignment, so that it can be re-traced
55
- // after a feature click with getImageData at that pixel
56
+ /**
57
+ * #volatile
58
+ * canvas used for drawing click map with feature ids this renders a
59
+ * unique color per alignment, so that it can be re-traced after a
60
+ * feature click with getImageData at that pixel
61
+ */
56
62
  clickMapCanvas: null,
57
- // canvas used for drawing click map with cigar data
58
- // this can show if you are mousing over a insertion/deletion. it is similar
59
- // in purpose to the clickMapRef but was not feasible to pack this into the
60
- // clickMapRef
63
+ /**
64
+ * #volatile
65
+ * canvas used for drawing click map with cigar data this can show if you
66
+ * are mousing over a insertion/deletion. it is similar in purpose to the
67
+ * clickMapRef but was not feasible to pack this into the clickMapRef
68
+ */
61
69
  cigarClickMapCanvas: null,
62
- // canvas for drawing mouseover shading
63
- // this is separate from the other code for speed: don't have to redraw
64
- // entire canvas to do a feature's mouseover shading
70
+ /**
71
+ * #volatile
72
+ * canvas for drawing mouseover shading this is separate from the other
73
+ * code for speed: don't have to redraw entire canvas to do a feature's
74
+ * mouseover shading
75
+ */
65
76
  mouseoverCanvas: null,
66
- // assigned by reaction
77
+ /**
78
+ * #volatile
79
+ * assigned by reaction
80
+ */
67
81
  featPositions: [],
68
- // currently mouse'd over feature
82
+ /**
83
+ * #volatile
84
+ * currently mouse'd over feature
85
+ */
69
86
  mouseoverId: undefined,
70
- // currently click'd over feature
87
+ /**
88
+ * #volatile
89
+ * currently click'd over feature
90
+ */
71
91
  clickId: undefined,
72
- // currently mouseover'd CIGAR subfeature
92
+ /**
93
+ * #volatile
94
+ * currently mouseover'd CIGAR subfeature
95
+ */
73
96
  cigarMouseoverId: -1,
74
97
  }))
75
98
  .actions(self => ({
@@ -139,13 +162,6 @@ function stateModelFactory(configSchema) {
139
162
  get trackIds() {
140
163
  return (0, configuration_1.getConf)(self, 'trackIds');
141
164
  },
142
- /**
143
- * #getter
144
- */
145
- get height() {
146
- // @ts-expect-error
147
- return (0, mobx_state_tree_1.getParent)(self, 4).height;
148
- },
149
165
  /**
150
166
  * #getter
151
167
  */
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { SimpleFeatureSerialized } from '@jbrowse/core/util';
3
+ interface SyntenyFeatureDetailModel {
4
+ trackId: string;
5
+ featureData: SimpleFeatureSerialized;
6
+ level?: number;
7
+ view: {
8
+ type: string;
9
+ };
10
+ }
11
+ declare const SyntenyFeatureDetail: ({ model, }: {
12
+ model: SyntenyFeatureDetailModel;
13
+ }) => React.JSX.Element;
14
+ export default SyntenyFeatureDetail;
@@ -0,0 +1,100 @@
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 material_1 = require("@mui/material");
31
+ const mobx_react_1 = require("mobx-react");
32
+ // locals
33
+ const BaseCard_1 = __importDefault(require("@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/BaseCard"));
34
+ const BaseFeatureDetail_1 = __importDefault(require("@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail"));
35
+ const util_1 = require("@jbrowse/core/util");
36
+ // lazies
37
+ const LaunchSyntenyViewDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../LGVSyntenyDisplay/components/LaunchSyntenyViewDialog'))));
38
+ const CustomLinker = (0, mobx_react_1.observer)(function ({ model, }) {
39
+ const { featureData, view, level, trackId } = model;
40
+ return (react_1.default.createElement("ul", null,
41
+ view.type === 'LinearSyntenyView' ? (react_1.default.createElement("li", null,
42
+ react_1.default.createElement(material_1.Link, { href: "#", onClick: event => {
43
+ var _a, _b;
44
+ event.preventDefault();
45
+ const { views } = view;
46
+ if (level !== undefined) {
47
+ // level is "pre-known", and stored in the SyntenyFeatureWidget
48
+ // model state e.g. when clicking on a feature from a
49
+ // LinearSyntenyRendering
50
+ (_a = views[level]) === null || _a === void 0 ? void 0 : _a.navTo(featureData);
51
+ (_b = views[level + 1]) === null || _b === void 0 ? void 0 : _b.navTo(featureData.mate);
52
+ }
53
+ else {
54
+ // best effort to find the right level. this is triggered for
55
+ // example if a user clicks on a feature in a LGVSyntenyDisplay
56
+ // in an existing LinearSyntenyView, there is no real proper
57
+ // level "pre-known" to this situation
58
+ const f1 = featureData;
59
+ const f2 = featureData.mate;
60
+ const r1 = f1.assemblyName;
61
+ const r2 = f2.assemblyName;
62
+ const v1 = views.find(view => view.assemblyNames[0] === r1);
63
+ const v2 = views.find(view => view.assemblyNames[0] === r2);
64
+ if (!v1 || !v2) {
65
+ (0, util_1.getSession)(model).notify([
66
+ v1
67
+ ? `Unable to find ${(0, util_1.assembleLocString)(f1)} in synteny view`
68
+ : '',
69
+ v2
70
+ ? `Unable to find ${(0, util_1.assembleLocString)(f2)} in synteny view`
71
+ : '',
72
+ ].join(' ... '));
73
+ }
74
+ v1 === null || v1 === void 0 ? void 0 : v1.navTo(f1);
75
+ v2 === null || v2 === void 0 ? void 0 : v2.navTo(f2);
76
+ }
77
+ } }, "Center view on this feature"))) : null,
78
+ react_1.default.createElement("li", null,
79
+ react_1.default.createElement(material_1.Link, { href: "#", onClick: event => {
80
+ event.preventDefault();
81
+ const session = (0, util_1.getSession)(model);
82
+ const feature = new util_1.SimpleFeature(featureData);
83
+ session.queueDialog(handleClose => [
84
+ LaunchSyntenyViewDialog,
85
+ {
86
+ model,
87
+ feature,
88
+ trackId,
89
+ handleClose,
90
+ },
91
+ ]);
92
+ } }, "Launch new linear synteny view on this feature"))));
93
+ });
94
+ const SyntenyFeatureDetail = (0, mobx_react_1.observer)(function ({ model, }) {
95
+ return (react_1.default.createElement(material_1.Paper, { "data-testid": "alignment-side-drawer" },
96
+ react_1.default.createElement(BaseFeatureDetail_1.default, { title: "Feature", model: model }),
97
+ react_1.default.createElement(BaseCard_1.default, { title: "Link to view" },
98
+ react_1.default.createElement(CustomLinker, { model: model }))));
99
+ });
100
+ exports.default = SyntenyFeatureDetail;
@@ -0,0 +1,2 @@
1
+ import PluginManager from '@jbrowse/core/PluginManager';
2
+ export default function SyntenyFeatureWidgetF(pluginManager: PluginManager): void;
@@ -0,0 +1,56 @@
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
+ exports.default = SyntenyFeatureWidgetF;
30
+ const react_1 = require("react");
31
+ const configuration_1 = require("@jbrowse/core/configuration");
32
+ const WidgetType_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/WidgetType"));
33
+ const mobx_state_tree_1 = require("mobx-state-tree");
34
+ const BaseFeatureWidget_1 = require("@jbrowse/core/BaseFeatureWidget");
35
+ const configSchema = (0, configuration_1.ConfigurationSchema)('SyntenyFeatureWidget', {});
36
+ function stateModelF(pluginManager) {
37
+ return mobx_state_tree_1.types.compose((0, BaseFeatureWidget_1.stateModelFactory)(pluginManager), mobx_state_tree_1.types.model('SyntenyFeatureWidget', {
38
+ /**
39
+ * #property
40
+ */
41
+ type: mobx_state_tree_1.types.literal('SyntenyFeatureWidget'),
42
+ /**
43
+ * #property
44
+ */
45
+ level: mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.number),
46
+ }));
47
+ }
48
+ function SyntenyFeatureWidgetF(pluginManager) {
49
+ pluginManager.addWidgetType(() => new WidgetType_1.default({
50
+ name: 'SyntenyFeatureWidget',
51
+ heading: 'Synteny feature details',
52
+ configSchema,
53
+ stateModel: stateModelF(pluginManager),
54
+ ReactComponent: (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./SyntenyFeatureDetail')))),
55
+ }));
56
+ }
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ const LinearSyntenyViewHelper_1 = __importDefault(require("./LinearSyntenyViewHe
15
15
  const LaunchLinearSyntenyView_1 = __importDefault(require("./LaunchLinearSyntenyView"));
16
16
  const SyntenyTrack_1 = __importDefault(require("./SyntenyTrack"));
17
17
  const LinearReadVsRef_1 = __importDefault(require("./LinearReadVsRef"));
18
+ const SyntenyFeatureDetail_1 = __importDefault(require("./SyntenyFeatureDetail"));
18
19
  class LinearComparativeViewPlugin extends Plugin_1.default {
19
20
  constructor() {
20
21
  super(...arguments);
@@ -26,6 +27,7 @@ class LinearComparativeViewPlugin extends Plugin_1.default {
26
27
  (0, LinearSyntenyView_1.default)(pluginManager);
27
28
  (0, LinearComparativeDisplay_1.default)(pluginManager);
28
29
  (0, LinearSyntenyDisplay_1.default)(pluginManager);
30
+ (0, SyntenyFeatureDetail_1.default)(pluginManager);
29
31
  (0, LGVSyntenyDisplay_1.default)(pluginManager);
30
32
  (0, LaunchLinearSyntenyView_1.default)(pluginManager);
31
33
  (0, SyntenyTrack_1.default)(pluginManager);
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Feature } from '@jbrowse/core/util';
3
- export default function LaunchSyntenyViewDialog({ model, feature, handleClose, }: {
3
+ export default function LaunchSyntenyViewDialog({ model, feature, trackId, handleClose, }: {
4
4
  model: unknown;
5
5
  feature: Feature;
6
+ trackId: string;
6
7
  handleClose: () => void;
7
8
  }): React.JSX.Element;
@@ -2,15 +2,16 @@ import React, { useState } from 'react';
2
2
  import { Dialog } from '@jbrowse/core/ui';
3
3
  import { getSession } from '@jbrowse/core/util';
4
4
  import { Button, Checkbox, DialogActions, DialogContent, FormControlLabel, TextField, } from '@mui/material';
5
- import { navToSynteny } from './util';
6
5
  import { makeStyles } from 'tss-react/mui';
6
+ // locals
7
+ import { navToSynteny } from './util';
7
8
  const useStyles = makeStyles()({
8
9
  padding: {
9
10
  margin: 10,
10
11
  border: '1px solid #ccc',
11
12
  },
12
13
  });
13
- export default function LaunchSyntenyViewDialog({ model, feature, handleClose, }) {
14
+ export default function LaunchSyntenyViewDialog({ model, feature, trackId, handleClose, }) {
14
15
  const { classes } = useStyles();
15
16
  const inverted = feature.get('strand') === -1;
16
17
  const [horizontallyFlip, setHorizontallyFlip] = useState(inverted);
@@ -33,6 +34,7 @@ export default function LaunchSyntenyViewDialog({ model, feature, handleClose, }
33
34
  feature,
34
35
  windowSize: +windowSize,
35
36
  horizontallyFlip,
37
+ trackId,
36
38
  model,
37
39
  });
38
40
  }
@@ -1,8 +1,11 @@
1
1
  import { Feature } from '@jbrowse/core/util';
2
2
  import { IAnyStateTreeNode } from 'mobx-state-tree';
3
- export declare function navToSynteny({ feature, windowSize: ws, model, horizontallyFlip, }: {
3
+ import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
4
+ export declare function navToSynteny({ feature, windowSize: ws, model, trackId, view, horizontallyFlip, }: {
4
5
  windowSize: number;
6
+ trackId: string;
5
7
  horizontallyFlip: boolean;
6
8
  feature: Feature;
9
+ view?: LinearGenomeViewModel;
7
10
  model: IAnyStateTreeNode;
8
11
  }): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { getSession, getContainingTrack, getContainingView, } from '@jbrowse/core/util';
1
+ import { getSession } from '@jbrowse/core/util';
2
2
  import { MismatchParser } from '@jbrowse/plugin-alignments';
3
3
  const { parseCigar } = MismatchParser;
4
4
  function f(n) {
@@ -27,18 +27,13 @@ function findPosInCigar(cigar, startX) {
27
27
  }
28
28
  return [featX, mateX];
29
29
  }
30
- export async function navToSynteny({ feature, windowSize: ws, model, horizontallyFlip, }) {
30
+ export async function navToSynteny({ feature, windowSize: ws, model, trackId, view, horizontallyFlip, }) {
31
31
  const session = getSession(model);
32
- const track = getContainingTrack(model);
33
- const view = getContainingView(model);
34
- const reg = view.dynamicBlocks.contentBlocks[0];
35
- if (!reg) {
36
- throw new Error('no visible region');
37
- }
32
+ const reg = view === null || view === void 0 ? void 0 : view.dynamicBlocks.contentBlocks[0];
38
33
  const cigar = feature.get('CIGAR');
39
34
  const strand = feature.get('strand');
40
- const regStart = reg.start;
41
- const regEnd = reg.end;
35
+ const featRef = feature.get('refName');
36
+ const featAsm = feature.get('assemblyName');
42
37
  const featStart = feature.get('start');
43
38
  const featEnd = feature.get('end');
44
39
  const mate = feature.get('mate');
@@ -46,13 +41,13 @@ export async function navToSynteny({ feature, windowSize: ws, model, horizontall
46
41
  const mateEnd = mate.end;
47
42
  const mateAsm = mate.assemblyName;
48
43
  const mateRef = mate.refName;
49
- const featAsm = reg.assemblyName;
50
- const featRef = reg.refName;
51
44
  let rMateStart;
52
45
  let rMateEnd;
53
46
  let rFeatStart;
54
47
  let rFeatEnd;
55
- if (cigar) {
48
+ if (reg && cigar) {
49
+ const regStart = reg.start;
50
+ const regEnd = reg.end;
56
51
  const p = parseCigar(cigar);
57
52
  const [fStartX, mStartX] = findPosInCigar(p, regStart - featStart);
58
53
  const [fEndX, mEndX] = findPosInCigar(p, regEnd - featStart);
@@ -69,17 +64,14 @@ export async function navToSynteny({ feature, windowSize: ws, model, horizontall
69
64
  rMateStart = mateStart;
70
65
  rMateEnd = mateEnd;
71
66
  }
72
- const trackId = track.configuration.trackId;
73
67
  const view2 = session.addView('LinearSyntenyView', {
74
68
  type: 'LinearSyntenyView',
75
69
  views: [
76
70
  {
77
- id: `${Math.random()}`,
78
71
  type: 'LinearGenomeView',
79
72
  hideHeader: true,
80
73
  },
81
74
  {
82
- id: `${Math.random()}`,
83
75
  type: 'LinearGenomeView',
84
76
  hideHeader: true,
85
77
  },