@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.
- package/dist/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.d.ts +2 -1
- package/dist/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.js +4 -2
- package/dist/LGVSyntenyDisplay/components/util.d.ts +4 -1
- package/dist/LGVSyntenyDisplay/components/util.js +7 -15
- package/dist/LGVSyntenyDisplay/model.d.ts +30 -34
- package/dist/LGVSyntenyDisplay/model.js +23 -1
- package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +28 -5
- package/dist/LinearComparativeDisplay/stateModelFactory.js +14 -3
- package/dist/LinearSyntenyDisplay/afterAttach.js +2 -3
- package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +21 -15
- package/dist/LinearSyntenyDisplay/components/SyntenyContextMenu.js +2 -4
- package/dist/LinearSyntenyDisplay/components/util.d.ts +5 -1
- package/dist/LinearSyntenyDisplay/components/util.js +7 -9
- package/dist/LinearSyntenyDisplay/drawSynteny.js +7 -9
- package/dist/LinearSyntenyDisplay/model.d.ts +48 -11
- package/dist/LinearSyntenyDisplay/model.js +38 -22
- package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +14 -0
- package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js +100 -0
- package/dist/SyntenyFeatureDetail/index.d.ts +2 -0
- package/dist/SyntenyFeatureDetail/index.js +56 -0
- package/dist/index.js +2 -0
- package/esm/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.d.ts +2 -1
- package/esm/LGVSyntenyDisplay/components/LaunchSyntenyViewDialog.js +4 -2
- package/esm/LGVSyntenyDisplay/components/util.d.ts +4 -1
- package/esm/LGVSyntenyDisplay/components/util.js +8 -16
- package/esm/LGVSyntenyDisplay/model.d.ts +30 -34
- package/esm/LGVSyntenyDisplay/model.js +25 -3
- package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +28 -5
- package/esm/LinearComparativeDisplay/stateModelFactory.js +14 -3
- package/esm/LinearSyntenyDisplay/afterAttach.js +3 -4
- package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +21 -15
- package/esm/LinearSyntenyDisplay/components/SyntenyContextMenu.js +2 -4
- package/esm/LinearSyntenyDisplay/components/util.d.ts +5 -1
- package/esm/LinearSyntenyDisplay/components/util.js +7 -9
- package/esm/LinearSyntenyDisplay/drawSynteny.js +7 -9
- package/esm/LinearSyntenyDisplay/model.d.ts +48 -11
- package/esm/LinearSyntenyDisplay/model.js +39 -23
- package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +14 -0
- package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js +72 -0
- package/esm/SyntenyFeatureDetail/index.d.ts +2 -0
- package/esm/SyntenyFeatureDetail/index.js +27 -0
- package/esm/index.js +2 -0
- 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"
|
|
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
|
-
|
|
51
|
+
/**
|
|
52
|
+
* #volatile
|
|
53
|
+
* canvas used for drawing visible screen
|
|
54
|
+
*/
|
|
52
55
|
mainCanvas: null,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
77
|
+
/**
|
|
78
|
+
* #volatile
|
|
79
|
+
* assigned by reaction
|
|
80
|
+
*/
|
|
67
81
|
featPositions: [],
|
|
68
|
-
|
|
82
|
+
/**
|
|
83
|
+
* #volatile
|
|
84
|
+
* currently mouse'd over feature
|
|
85
|
+
*/
|
|
69
86
|
mouseoverId: undefined,
|
|
70
|
-
|
|
87
|
+
/**
|
|
88
|
+
* #volatile
|
|
89
|
+
* currently click'd over feature
|
|
90
|
+
*/
|
|
71
91
|
clickId: undefined,
|
|
72
|
-
|
|
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,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
|
-
|
|
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
|
|
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
|
|
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
|
|
41
|
-
const
|
|
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
|
},
|