@jbrowse/plugin-linear-comparative-view 2.11.1 → 2.12.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/util.js +1 -1
- package/dist/LGVSyntenyDisplay/configSchemaF.d.ts +5 -0
- package/dist/LGVSyntenyDisplay/model.d.ts +7 -3
- package/dist/LinearComparativeView/model.d.ts +11 -36
- package/dist/LinearComparativeView/model.js +0 -23
- package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +54 -101
- package/dist/LinearSyntenyDisplay/components/util.d.ts +10 -0
- package/dist/LinearSyntenyDisplay/components/util.js +87 -1
- package/dist/LinearSyntenyView/components/ImportForm/index.js +1 -0
- package/dist/LinearSyntenyView/model.d.ts +39 -139
- package/dist/LinearSyntenyView/model.js +0 -8
- package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +5 -3
- package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js +2 -4
- package/esm/LGVSyntenyDisplay/components/util.js +1 -1
- package/esm/LGVSyntenyDisplay/configSchemaF.d.ts +5 -0
- package/esm/LGVSyntenyDisplay/model.d.ts +7 -3
- package/esm/LinearComparativeView/model.d.ts +11 -36
- package/esm/LinearComparativeView/model.js +1 -24
- package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +54 -101
- package/esm/LinearSyntenyDisplay/components/util.d.ts +10 -0
- package/esm/LinearSyntenyDisplay/components/util.js +84 -1
- package/esm/LinearSyntenyView/components/ImportForm/index.js +1 -0
- package/esm/LinearSyntenyView/model.d.ts +39 -139
- package/esm/LinearSyntenyView/model.js +0 -8
- package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +5 -3
- package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js +2 -4
- package/package.json +2 -2
|
@@ -48,5 +48,10 @@ declare function configSchemaF(pluginManager: PluginManager): import("@jbrowse/c
|
|
|
48
48
|
defaultValue: string;
|
|
49
49
|
contextVariable: string[];
|
|
50
50
|
};
|
|
51
|
+
jexlFilters: {
|
|
52
|
+
type: string;
|
|
53
|
+
description: string;
|
|
54
|
+
defaultValue: never[];
|
|
55
|
+
};
|
|
51
56
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>, undefined>>, undefined>>;
|
|
52
57
|
export default configSchemaF;
|
|
@@ -85,9 +85,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
85
85
|
height: {
|
|
86
86
|
type: string;
|
|
87
87
|
defaultValue: number;
|
|
88
|
-
description: string;
|
|
89
|
-
* #method
|
|
90
|
-
*/
|
|
88
|
+
description: string;
|
|
91
89
|
};
|
|
92
90
|
mouseover: {
|
|
93
91
|
type: string;
|
|
@@ -95,6 +93,11 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
95
93
|
defaultValue: string;
|
|
96
94
|
contextVariable: string[];
|
|
97
95
|
};
|
|
96
|
+
jexlFilters: {
|
|
97
|
+
type: string;
|
|
98
|
+
description: string;
|
|
99
|
+
defaultValue: never[];
|
|
100
|
+
};
|
|
98
101
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
99
102
|
} & {
|
|
100
103
|
configuration: AnyConfigurationSchemaType;
|
|
@@ -240,6 +243,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
240
243
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
241
244
|
deleteBlock(key: string): void;
|
|
242
245
|
selectFeature(feature: import("@jbrowse/core/util").Feature): void;
|
|
246
|
+
navToFeature(feature: import("@jbrowse/core/util").Feature): void;
|
|
243
247
|
clearFeatureSelection(): void;
|
|
244
248
|
setFeatureIdUnderMouse(feature?: string | undefined): void;
|
|
245
249
|
setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature | undefined): void;
|
|
@@ -17,7 +17,6 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
17
17
|
type: import("mobx-state-tree").ISimpleType<"LinearComparativeView">;
|
|
18
18
|
trackSelectorType: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
19
19
|
showIntraviewLinks: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
20
|
-
linkViews: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
21
20
|
interactToggled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
22
21
|
middleComparativeHeight: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
23
22
|
tracks: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IAnyType>;
|
|
@@ -30,16 +29,7 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
30
29
|
type: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
31
30
|
offsetPx: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
32
31
|
bpPerPx: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
33
|
-
displayedRegions: import("mobx-state-tree").
|
|
34
|
-
refName: import("mobx-state-tree").ISimpleType<string>;
|
|
35
|
-
start: import("mobx-state-tree").ISimpleType<number>;
|
|
36
|
-
end: import("mobx-state-tree").ISimpleType<number>;
|
|
37
|
-
reversed: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
38
|
-
} & {
|
|
39
|
-
assemblyName: import("mobx-state-tree").ISimpleType<string>;
|
|
40
|
-
}, {
|
|
41
|
-
setRefName(newRefName: string): void;
|
|
42
|
-
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
32
|
+
displayedRegions: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IType<import("@jbrowse/core/util").Region[], import("@jbrowse/core/util").Region[], import("@jbrowse/core/util").Region[]>, [undefined]>;
|
|
43
33
|
tracks: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IAnyType>;
|
|
44
34
|
hideHeader: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
45
35
|
hideHeaderOverview: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
@@ -140,6 +130,7 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
140
130
|
getSelectedRegions(leftOffset?: import("@jbrowse/plugin-linear-genome-view/src/LinearGenomeView").BpOffset | undefined, rightOffset?: import("@jbrowse/plugin-linear-genome-view/src/LinearGenomeView").BpOffset | undefined): {
|
|
141
131
|
start: number;
|
|
142
132
|
end: number;
|
|
133
|
+
type: string;
|
|
143
134
|
regionNumber?: number | undefined;
|
|
144
135
|
reversed?: boolean | undefined;
|
|
145
136
|
refName: string;
|
|
@@ -197,14 +188,13 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
197
188
|
lowerCaseRefNameAliases: {
|
|
198
189
|
[x: string]: string | undefined;
|
|
199
190
|
} | undefined;
|
|
200
|
-
cytobands: import("@jbrowse/core/util").Feature[] | undefined;
|
|
191
|
+
cytobands: import("@jbrowse/core/util").Feature[] | undefined; /**
|
|
192
|
+
* #property
|
|
193
|
+
*/
|
|
201
194
|
} & {
|
|
202
195
|
getConf(arg: string): any;
|
|
203
196
|
} & {
|
|
204
197
|
readonly initialized: boolean;
|
|
205
|
-
/**
|
|
206
|
-
* #property
|
|
207
|
-
*/
|
|
208
198
|
readonly name: string;
|
|
209
199
|
readonly regions: import("@jbrowse/core/assemblyManager/assembly").BasicRegion[] | undefined;
|
|
210
200
|
readonly aliases: string[];
|
|
@@ -262,14 +252,13 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
262
252
|
lowerCaseRefNameAliases: {
|
|
263
253
|
[x: string]: string | undefined;
|
|
264
254
|
} | undefined;
|
|
265
|
-
cytobands: import("@jbrowse/core/util").Feature[] | undefined;
|
|
255
|
+
cytobands: import("@jbrowse/core/util").Feature[] | undefined; /**
|
|
256
|
+
* #property
|
|
257
|
+
*/
|
|
266
258
|
} & {
|
|
267
259
|
getConf(arg: string): any;
|
|
268
260
|
} & {
|
|
269
261
|
readonly initialized: boolean;
|
|
270
|
-
/**
|
|
271
|
-
* #property
|
|
272
|
-
*/
|
|
273
262
|
readonly name: string;
|
|
274
263
|
readonly regions: import("@jbrowse/core/assemblyManager/assembly").BasicRegion[] | undefined;
|
|
275
264
|
readonly aliases: string[];
|
|
@@ -339,7 +328,7 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
339
328
|
offset: number;
|
|
340
329
|
start: number;
|
|
341
330
|
end: number;
|
|
342
|
-
reversed
|
|
331
|
+
reversed?: boolean | undefined;
|
|
343
332
|
};
|
|
344
333
|
readonly centerLineInfo: {
|
|
345
334
|
coord: number;
|
|
@@ -350,7 +339,7 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
350
339
|
offset: number;
|
|
351
340
|
start: number;
|
|
352
341
|
end: number;
|
|
353
|
-
reversed
|
|
342
|
+
reversed?: boolean | undefined;
|
|
354
343
|
} | undefined;
|
|
355
344
|
} & {
|
|
356
345
|
afterCreate(): void;
|
|
@@ -363,16 +352,7 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
363
352
|
type: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
364
353
|
offsetPx: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
365
354
|
bpPerPx: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
366
|
-
displayedRegions: import("mobx-state-tree").
|
|
367
|
-
refName: import("mobx-state-tree").ISimpleType<string>;
|
|
368
|
-
start: import("mobx-state-tree").ISimpleType<number>;
|
|
369
|
-
end: import("mobx-state-tree").ISimpleType<number>;
|
|
370
|
-
reversed: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
371
|
-
} & {
|
|
372
|
-
assemblyName: import("mobx-state-tree").ISimpleType<string>;
|
|
373
|
-
}, {
|
|
374
|
-
setRefName(newRefName: string): void;
|
|
375
|
-
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
355
|
+
displayedRegions: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IType<import("@jbrowse/core/util").Region[], import("@jbrowse/core/util").Region[], import("@jbrowse/core/util").Region[]>, [undefined]>;
|
|
376
356
|
tracks: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IAnyType>;
|
|
377
357
|
hideHeader: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
378
358
|
hideHeaderOverview: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
@@ -414,7 +394,6 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
414
394
|
*/
|
|
415
395
|
readonly assemblyNames: string[];
|
|
416
396
|
} & {
|
|
417
|
-
afterAttach(): void;
|
|
418
397
|
beforeDestroy(): void;
|
|
419
398
|
onSubviewAction(actionName: string, path: string, args?: unknown[]): void;
|
|
420
399
|
/**
|
|
@@ -439,10 +418,6 @@ declare function stateModelFactory(pluginManager: PluginManager): import("mobx-s
|
|
|
439
418
|
* #action
|
|
440
419
|
*/
|
|
441
420
|
setMiddleComparativeHeight(n: number): number;
|
|
442
|
-
/**
|
|
443
|
-
* #action
|
|
444
|
-
*/
|
|
445
|
-
toggleLinkViews(): void;
|
|
446
421
|
/**
|
|
447
422
|
* #action
|
|
448
423
|
*/
|
|
@@ -62,10 +62,6 @@ function stateModelFactory(pluginManager) {
|
|
|
62
62
|
* #property
|
|
63
63
|
*/
|
|
64
64
|
showIntraviewLinks: true,
|
|
65
|
-
/**
|
|
66
|
-
* #property
|
|
67
|
-
*/
|
|
68
|
-
linkViews: false,
|
|
69
65
|
/**
|
|
70
66
|
* #property
|
|
71
67
|
*/
|
|
@@ -126,19 +122,6 @@ function stateModelFactory(pluginManager) {
|
|
|
126
122
|
},
|
|
127
123
|
}))
|
|
128
124
|
.actions(self => ({
|
|
129
|
-
afterAttach() {
|
|
130
|
-
(0, mobx_state_tree_1.addDisposer)(self, (0, mobx_state_tree_1.onAction)(self, param => {
|
|
131
|
-
if (self.linkViews) {
|
|
132
|
-
const { name, path, args } = param;
|
|
133
|
-
// doesn't link showTrack/hideTrack, doesn't make sense in
|
|
134
|
-
// synteny views most time
|
|
135
|
-
const actions = ['horizontalScroll', 'zoomTo', 'setScaleFactor'];
|
|
136
|
-
if (actions.includes(name) && path) {
|
|
137
|
-
this.onSubviewAction(name, path, args);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}));
|
|
141
|
-
},
|
|
142
125
|
// automatically removes session assemblies associated with this view
|
|
143
126
|
// e.g. read vs ref
|
|
144
127
|
beforeDestroy() {
|
|
@@ -191,12 +174,6 @@ function stateModelFactory(pluginManager) {
|
|
|
191
174
|
self.middleComparativeHeight = n;
|
|
192
175
|
return self.middleComparativeHeight;
|
|
193
176
|
},
|
|
194
|
-
/**
|
|
195
|
-
* #action
|
|
196
|
-
*/
|
|
197
|
-
toggleLinkViews() {
|
|
198
|
-
self.linkViews = !self.linkViews;
|
|
199
|
-
},
|
|
200
177
|
/**
|
|
201
178
|
* #action
|
|
202
179
|
*/
|
|
@@ -35,6 +35,7 @@ const mui_1 = require("tss-react/mui");
|
|
|
35
35
|
const SyntenyTooltip_1 = __importDefault(require("./SyntenyTooltip"));
|
|
36
36
|
const drawSynteny_1 = require("../drawSynteny");
|
|
37
37
|
const SyntenyContextMenu_1 = __importDefault(require("./SyntenyContextMenu"));
|
|
38
|
+
const util_2 = require("./util");
|
|
38
39
|
const useStyles = (0, mui_1.makeStyles)()({
|
|
39
40
|
pix: {
|
|
40
41
|
imageRendering: 'pixelated',
|
|
@@ -59,30 +60,44 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
|
|
|
59
60
|
const view = (0, util_1.getContainingView)(model);
|
|
60
61
|
const height = view.middleComparativeHeight;
|
|
61
62
|
const width = view.width;
|
|
63
|
+
const delta = (0, react_1.useRef)(0);
|
|
64
|
+
const timeout = (0, react_1.useRef)();
|
|
62
65
|
const [anchorEl, setAnchorEl] = (0, react_1.useState)();
|
|
63
66
|
const [tooltip, setTooltip] = (0, react_1.useState)('');
|
|
64
67
|
const [currX, setCurrX] = (0, react_1.useState)();
|
|
65
68
|
const [mouseCurrDownX, setMouseCurrDownX] = (0, react_1.useState)();
|
|
66
69
|
const [mouseInitialDownX, setMouseInitialDownX] = (0, react_1.useState)();
|
|
67
70
|
const [currY, setCurrY] = (0, react_1.useState)();
|
|
71
|
+
const { mouseoverId } = model;
|
|
68
72
|
// these useCallbacks avoid new refs from being created on any mouseover, etc.
|
|
69
73
|
const k1 = (0, react_1.useCallback)((ref) => model.setMouseoverCanvasRef(ref),
|
|
70
74
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
75
|
[model, height, width]);
|
|
72
|
-
const k2 = (0, react_1.useCallback)((ref) =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
const k2 = (0, react_1.useCallback)((ref) => {
|
|
77
|
+
model.setMainCanvasRef(ref);
|
|
78
|
+
function onWheel(event) {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
if (event.ctrlKey === true) {
|
|
81
|
+
delta.current += event.deltaY / 500;
|
|
82
|
+
for (const v of view.views) {
|
|
83
|
+
v.setScaleFactor(delta.current < 0 ? 1 - delta.current : 1 / (1 + delta.current));
|
|
84
|
+
}
|
|
85
|
+
if (timeout.current) {
|
|
86
|
+
clearTimeout(timeout.current);
|
|
87
|
+
}
|
|
88
|
+
timeout.current = setTimeout(() => {
|
|
89
|
+
for (const v of view.views) {
|
|
90
|
+
v.setScaleFactor(1);
|
|
91
|
+
v.zoomTo(delta.current > 0
|
|
92
|
+
? v.bpPerPx * (1 + delta.current)
|
|
93
|
+
: v.bpPerPx / (1 - delta.current), event.clientX - ((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().left) || 0));
|
|
94
|
+
}
|
|
95
|
+
delta.current = 0;
|
|
96
|
+
}, 300);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
84
99
|
if (Math.abs(event.deltaY) < Math.abs(event.deltaX)) {
|
|
85
|
-
xOffset.current += event.deltaX;
|
|
100
|
+
xOffset.current += event.deltaX / 2;
|
|
86
101
|
}
|
|
87
102
|
if (currScrollFrame.current === undefined) {
|
|
88
103
|
currScrollFrame.current = requestAnimationFrame(() => {
|
|
@@ -95,7 +110,28 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
|
|
|
95
110
|
});
|
|
96
111
|
});
|
|
97
112
|
}
|
|
98
|
-
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (ref) {
|
|
116
|
+
ref.addEventListener('wheel', onWheel);
|
|
117
|
+
// this is a react 19-ism to have a cleanup in the ref callback
|
|
118
|
+
// https://react.dev/blog/2024/04/25/react-19#cleanup-functions-for-refs
|
|
119
|
+
// note: it warns in earlier versions of react
|
|
120
|
+
return () => ref.removeEventListener('wheel', onWheel);
|
|
121
|
+
}
|
|
122
|
+
return () => { };
|
|
123
|
+
},
|
|
124
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
125
|
+
[model, height, width]);
|
|
126
|
+
const k3 = (0, react_1.useCallback)((ref) => model.setClickMapCanvasRef(ref),
|
|
127
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
128
|
+
[model, height, width]);
|
|
129
|
+
const k4 = (0, react_1.useCallback)((ref) => model.setCigarClickMapCanvasRef(ref),
|
|
130
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
131
|
+
[model, height, width]);
|
|
132
|
+
return (react_1.default.createElement("div", { className: classes.rel },
|
|
133
|
+
react_1.default.createElement("canvas", { ref: k1, width: width, height: height, className: cx(classes.abs, classes.none) }),
|
|
134
|
+
react_1.default.createElement("canvas", { ref: k2, onMouseMove: event => {
|
|
99
135
|
var _a;
|
|
100
136
|
if (mouseCurrDownX !== undefined) {
|
|
101
137
|
xOffset.current += mouseCurrDownX - event.clientX;
|
|
@@ -141,7 +177,7 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
|
|
|
141
177
|
const { f, cigar } = model.featPositions[id];
|
|
142
178
|
const unitMultiplier2 = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / cigar.length);
|
|
143
179
|
const cigarIdx = (0, drawSynteny_1.getId)(r2, g2, b2, unitMultiplier2);
|
|
144
|
-
setTooltip(getTooltip(f, cigar[cigarIdx], cigar[cigarIdx + 1]));
|
|
180
|
+
setTooltip((0, util_2.getTooltip)(f, cigar[cigarIdx], cigar[cigarIdx + 1]));
|
|
145
181
|
}
|
|
146
182
|
}
|
|
147
183
|
}, onMouseLeave: () => {
|
|
@@ -155,95 +191,12 @@ const LinearSyntenyRendering = (0, mobx_react_1.observer)(function ({ model, })
|
|
|
155
191
|
setMouseCurrDownX(undefined);
|
|
156
192
|
if (mouseInitialDownX !== undefined &&
|
|
157
193
|
Math.abs(evt.clientX - mouseInitialDownX) < 5) {
|
|
158
|
-
|
|
194
|
+
(0, util_2.onSynClick)(evt, model);
|
|
159
195
|
}
|
|
160
|
-
}, onContextMenu: evt =>
|
|
161
|
-
onSyntenyContextClick(evt, model, setAnchorEl);
|
|
162
|
-
}, "data-testid": "synteny_canvas", className: classes.abs, width: width, height: height }),
|
|
196
|
+
}, onContextMenu: evt => (0, util_2.onSynContextClick)(evt, model, setAnchorEl), "data-testid": "synteny_canvas", className: classes.abs, width: width, height: height }),
|
|
163
197
|
react_1.default.createElement("canvas", { ref: k3, className: classes.pix, width: width, height: height }),
|
|
164
198
|
react_1.default.createElement("canvas", { ref: k4, className: classes.pix, width: width, height: height }),
|
|
165
|
-
|
|
199
|
+
mouseoverId && tooltip && currX && currY ? (react_1.default.createElement(SyntenyTooltip_1.default, { title: tooltip })) : null,
|
|
166
200
|
anchorEl ? (react_1.default.createElement(SyntenyContextMenu_1.default, { model: model, anchorEl: anchorEl, onClose: () => setAnchorEl(undefined) })) : null));
|
|
167
201
|
});
|
|
168
|
-
function onSyntenyClick(event, model) {
|
|
169
|
-
const ref1 = model.clickMapCanvas;
|
|
170
|
-
const ref2 = model.cigarClickMapCanvas;
|
|
171
|
-
if (!ref1 || !ref2) {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
const rect = ref1.getBoundingClientRect();
|
|
175
|
-
const ctx1 = ref1.getContext('2d');
|
|
176
|
-
const ctx2 = ref2.getContext('2d');
|
|
177
|
-
if (!ctx1 || !ctx2) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
const x = event.clientX - rect.left;
|
|
181
|
-
const y = event.clientY - rect.top;
|
|
182
|
-
const [r1, g1, b1] = ctx1.getImageData(x, y, 1, 1).data;
|
|
183
|
-
const unitMultiplier = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / model.numFeats);
|
|
184
|
-
const id = (0, drawSynteny_1.getId)(r1, g1, b1, unitMultiplier);
|
|
185
|
-
const feat = model.featPositions[id];
|
|
186
|
-
if (feat) {
|
|
187
|
-
const { f } = feat;
|
|
188
|
-
model.setClickId(f.id());
|
|
189
|
-
const session = (0, util_1.getSession)(model);
|
|
190
|
-
if ((0, util_1.isSessionModelWithWidgets)(session)) {
|
|
191
|
-
session.showWidget(session.addWidget('SyntenyFeatureWidget', 'syntenyFeature', {
|
|
192
|
-
featureData: {
|
|
193
|
-
feature1: f.toJSON(),
|
|
194
|
-
feature2: f.get('mate'),
|
|
195
|
-
},
|
|
196
|
-
}));
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return feat;
|
|
200
|
-
}
|
|
201
|
-
function onSyntenyContextClick(event, model, setAnchorEl) {
|
|
202
|
-
event.preventDefault();
|
|
203
|
-
const ref1 = model.clickMapCanvas;
|
|
204
|
-
const ref2 = model.cigarClickMapCanvas;
|
|
205
|
-
if (!ref1 || !ref2) {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const rect = ref1.getBoundingClientRect();
|
|
209
|
-
const ctx1 = ref1.getContext('2d');
|
|
210
|
-
const ctx2 = ref2.getContext('2d');
|
|
211
|
-
if (!ctx1 || !ctx2) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
const { clientX, clientY } = event;
|
|
215
|
-
const x = clientX - rect.left;
|
|
216
|
-
const y = clientY - rect.top;
|
|
217
|
-
const [r1, g1, b1] = ctx1.getImageData(x, y, 1, 1).data;
|
|
218
|
-
const unitMultiplier = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / model.numFeats);
|
|
219
|
-
const id = (0, drawSynteny_1.getId)(r1, g1, b1, unitMultiplier);
|
|
220
|
-
const f = model.featPositions[id];
|
|
221
|
-
if (f) {
|
|
222
|
-
model.setClickId(f.f.id());
|
|
223
|
-
setAnchorEl({ clientX, clientY, feature: f });
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
function getTooltip(f, cigarOp, cigarOpLen) {
|
|
227
|
-
// @ts-expect-error
|
|
228
|
-
const f1 = f.toJSON();
|
|
229
|
-
const f2 = f1.mate;
|
|
230
|
-
const l1 = f1.end - f1.start;
|
|
231
|
-
const l2 = f2.end - f2.start;
|
|
232
|
-
const identity = f1.identity;
|
|
233
|
-
const n1 = f1.name;
|
|
234
|
-
const n2 = f2.name;
|
|
235
|
-
return [
|
|
236
|
-
`Loc1: ${(0, util_1.assembleLocString)(f1)}`,
|
|
237
|
-
`Loc2: ${(0, util_1.assembleLocString)(f2)}`,
|
|
238
|
-
`Inverted: ${f1.strand === -1}`,
|
|
239
|
-
`Query len: ${l1.toLocaleString('en-US')}`,
|
|
240
|
-
`Target len: ${l2.toLocaleString('en-US')}`,
|
|
241
|
-
identity ? `Identity: ${identity.toPrecision(2)}` : '',
|
|
242
|
-
cigarOp ? `CIGAR operator: ${cigarOp}${cigarOpLen}` : '',
|
|
243
|
-
n1 ? `Name 1: ${n1}` : '',
|
|
244
|
-
n2 ? `Name 1: ${n2}` : '',
|
|
245
|
-
]
|
|
246
|
-
.filter(f => !!f)
|
|
247
|
-
.join('<br/>');
|
|
248
|
-
}
|
|
249
202
|
exports.default = LinearSyntenyRendering;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { Feature } from '@jbrowse/core/util';
|
|
3
|
+
import { LinearSyntenyDisplayModel } from '../model';
|
|
2
4
|
interface Pos {
|
|
3
5
|
offsetPx: number;
|
|
4
6
|
}
|
|
7
|
+
export interface ClickCoord {
|
|
8
|
+
clientX: number;
|
|
9
|
+
clientY: number;
|
|
10
|
+
feature: any;
|
|
11
|
+
}
|
|
5
12
|
interface FeatPos {
|
|
6
13
|
p11: Pos;
|
|
7
14
|
p12: Pos;
|
|
@@ -24,4 +31,7 @@ export declare function drawMatchSimple({ feature, ctx, offsets, cb, height, dra
|
|
|
24
31
|
export declare function draw(ctx: CanvasRenderingContext2D, x1: number, x2: number, y1: number, x3: number, x4: number, y2: number, mid: number, drawCurves?: boolean): void;
|
|
25
32
|
export declare function drawBox(ctx: CanvasRenderingContext2D, x1: number, x2: number, y1: number, x3: number, x4: number, y2: number): void;
|
|
26
33
|
export declare function drawBezierBox(ctx: CanvasRenderingContext2D, x1: number, x2: number, y1: number, x3: number, x4: number, y2: number, mid: number): void;
|
|
34
|
+
export declare function onSynClick(event: React.MouseEvent, model: LinearSyntenyDisplayModel): import("../model").FeatPos | undefined;
|
|
35
|
+
export declare function onSynContextClick(event: React.MouseEvent, model: LinearSyntenyDisplayModel, setAnchorEl: (arg: ClickCoord) => void): void;
|
|
36
|
+
export declare function getTooltip(f: Feature, cigarOp?: string, cigarOpLen?: string): string;
|
|
27
37
|
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.drawBezierBox = exports.drawBox = exports.draw = exports.drawMatchSimple = void 0;
|
|
3
|
+
exports.getTooltip = exports.onSynContextClick = exports.onSynClick = exports.drawBezierBox = exports.drawBox = exports.draw = exports.drawMatchSimple = void 0;
|
|
4
4
|
const util_1 = require("@jbrowse/core/util");
|
|
5
|
+
// locals
|
|
6
|
+
const drawSynteny_1 = require("../drawSynteny");
|
|
5
7
|
function drawMatchSimple({ feature, ctx, offsets, cb, height, drawCurves, oobLimit, viewWidth, hideTiny, }) {
|
|
6
8
|
const { p11, p12, p21, p22 } = feature;
|
|
7
9
|
const x11 = p11.offsetPx - offsets[0];
|
|
@@ -81,3 +83,87 @@ function drawBezierBox(ctx, x1, x2, y1, x3, x4, y2, mid) {
|
|
|
81
83
|
ctx.fill();
|
|
82
84
|
}
|
|
83
85
|
exports.drawBezierBox = drawBezierBox;
|
|
86
|
+
function onSynClick(event, model) {
|
|
87
|
+
const ref1 = model.clickMapCanvas;
|
|
88
|
+
const ref2 = model.cigarClickMapCanvas;
|
|
89
|
+
if (!ref1 || !ref2) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const rect = ref1.getBoundingClientRect();
|
|
93
|
+
const ctx1 = ref1.getContext('2d');
|
|
94
|
+
const ctx2 = ref2.getContext('2d');
|
|
95
|
+
if (!ctx1 || !ctx2) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const x = event.clientX - rect.left;
|
|
99
|
+
const y = event.clientY - rect.top;
|
|
100
|
+
const [r1, g1, b1] = ctx1.getImageData(x, y, 1, 1).data;
|
|
101
|
+
const unitMultiplier = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / model.numFeats);
|
|
102
|
+
const id = (0, drawSynteny_1.getId)(r1, g1, b1, unitMultiplier);
|
|
103
|
+
const feat = model.featPositions[id];
|
|
104
|
+
if (feat) {
|
|
105
|
+
const { f } = feat;
|
|
106
|
+
model.setClickId(f.id());
|
|
107
|
+
const session = (0, util_1.getSession)(model);
|
|
108
|
+
if ((0, util_1.isSessionModelWithWidgets)(session)) {
|
|
109
|
+
session.showWidget(session.addWidget('SyntenyFeatureWidget', 'syntenyFeature', {
|
|
110
|
+
featureData: {
|
|
111
|
+
feature1: f.toJSON(),
|
|
112
|
+
feature2: f.get('mate'),
|
|
113
|
+
},
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return feat;
|
|
118
|
+
}
|
|
119
|
+
exports.onSynClick = onSynClick;
|
|
120
|
+
function onSynContextClick(event, model, setAnchorEl) {
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
const ref1 = model.clickMapCanvas;
|
|
123
|
+
const ref2 = model.cigarClickMapCanvas;
|
|
124
|
+
if (!ref1 || !ref2) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const rect = ref1.getBoundingClientRect();
|
|
128
|
+
const ctx1 = ref1.getContext('2d');
|
|
129
|
+
const ctx2 = ref2.getContext('2d');
|
|
130
|
+
if (!ctx1 || !ctx2) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const { clientX, clientY } = event;
|
|
134
|
+
const x = clientX - rect.left;
|
|
135
|
+
const y = clientY - rect.top;
|
|
136
|
+
const [r1, g1, b1] = ctx1.getImageData(x, y, 1, 1).data;
|
|
137
|
+
const unitMultiplier = Math.floor(drawSynteny_1.MAX_COLOR_RANGE / model.numFeats);
|
|
138
|
+
const id = (0, drawSynteny_1.getId)(r1, g1, b1, unitMultiplier);
|
|
139
|
+
const f = model.featPositions[id];
|
|
140
|
+
if (f) {
|
|
141
|
+
model.setClickId(f.f.id());
|
|
142
|
+
setAnchorEl({ clientX, clientY, feature: f });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.onSynContextClick = onSynContextClick;
|
|
146
|
+
function getTooltip(f, cigarOp, cigarOpLen) {
|
|
147
|
+
// @ts-expect-error
|
|
148
|
+
const f1 = f.toJSON();
|
|
149
|
+
const f2 = f1.mate;
|
|
150
|
+
const l1 = f1.end - f1.start;
|
|
151
|
+
const l2 = f2.end - f2.start;
|
|
152
|
+
const identity = f1.identity;
|
|
153
|
+
const n1 = f1.name;
|
|
154
|
+
const n2 = f2.name;
|
|
155
|
+
return [
|
|
156
|
+
`Loc1: ${(0, util_1.assembleLocString)(f1)}`,
|
|
157
|
+
`Loc2: ${(0, util_1.assembleLocString)(f2)}`,
|
|
158
|
+
`Inverted: ${f1.strand === -1}`,
|
|
159
|
+
`Query len: ${l1.toLocaleString('en-US')}`,
|
|
160
|
+
`Target len: ${l2.toLocaleString('en-US')}`,
|
|
161
|
+
identity ? `Identity: ${identity.toPrecision(2)}` : '',
|
|
162
|
+
cigarOp ? `CIGAR operator: ${cigarOp}${cigarOpLen}` : '',
|
|
163
|
+
n1 ? `Name 1: ${n1}` : '',
|
|
164
|
+
n2 ? `Name 1: ${n2}` : '',
|
|
165
|
+
]
|
|
166
|
+
.filter(f => !!f)
|
|
167
|
+
.join('<br/>');
|
|
168
|
+
}
|
|
169
|
+
exports.getTooltip = getTooltip;
|
|
@@ -93,6 +93,7 @@ const LinearSyntenyViewImportForm = (0, mobx_react_1.observer)(function ({ model
|
|
|
93
93
|
};
|
|
94
94
|
})));
|
|
95
95
|
model.views.forEach(view => view.setWidth(model.width));
|
|
96
|
+
model.views.forEach(view => view.showAllRegions());
|
|
96
97
|
if (sessionTrackData) {
|
|
97
98
|
session.addTrackConf(sessionTrackData);
|
|
98
99
|
model.toggleTrack(sessionTrackData.trackId);
|