@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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
|
|
2
|
+
import { Feature } from '@jbrowse/core/util';
|
|
2
3
|
/**
|
|
3
4
|
* #stateModel LGVSyntenyDisplay
|
|
4
5
|
* displays location of "synteny" feature in a plain LGV, allowing linking out
|
|
@@ -10,7 +11,14 @@ import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
|
|
|
10
11
|
declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("mobx-state-tree").IModelType<{
|
|
11
12
|
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
12
13
|
type: import("mobx-state-tree").ISimpleType<string>;
|
|
13
|
-
rpcDriverName: import("mobx-state-tree"
|
|
14
|
+
rpcDriverName: import("mobx-state-tree" /**
|
|
15
|
+
* #stateModel LGVSyntenyDisplay
|
|
16
|
+
* displays location of "synteny" feature in a plain LGV, allowing linking out
|
|
17
|
+
* to external synteny views
|
|
18
|
+
*
|
|
19
|
+
* extends
|
|
20
|
+
* - [SharedLinearPileupDisplayMixin](../sharedlinearpileupdisplaymixin)
|
|
21
|
+
*/).IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
14
22
|
} & {
|
|
15
23
|
heightPreConfig: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
16
24
|
} & {
|
|
@@ -38,7 +46,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
38
46
|
renderInProgress: AbortController | undefined;
|
|
39
47
|
filled: boolean;
|
|
40
48
|
reactElement: React.ReactElement | undefined;
|
|
41
|
-
features: Map<string,
|
|
49
|
+
features: Map<string, Feature> | undefined;
|
|
42
50
|
layout: any;
|
|
43
51
|
status: string;
|
|
44
52
|
error: unknown;
|
|
@@ -63,7 +71,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
63
71
|
setMessage(messageText: string): void;
|
|
64
72
|
setRendered(props: {
|
|
65
73
|
reactElement: React.ReactElement;
|
|
66
|
-
features: Map<string,
|
|
74
|
+
features: Map<string, Feature>;
|
|
67
75
|
layout: any;
|
|
68
76
|
maxHeightReached: boolean;
|
|
69
77
|
renderProps: any;
|
|
@@ -106,20 +114,8 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
106
114
|
noSpacing: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<boolean>>;
|
|
107
115
|
fadeLikelihood: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<boolean>>;
|
|
108
116
|
trackMaxHeight: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
109
|
-
colorBy: import("mobx-state-tree").
|
|
110
|
-
|
|
111
|
-
tag: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
112
|
-
extra: import("mobx-state-tree").IType<any, any, any>;
|
|
113
|
-
}, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
114
|
-
filterBy: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IModelType<{
|
|
115
|
-
flagInclude: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
116
|
-
flagExclude: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
117
|
-
readName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
118
|
-
tagFilter: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
|
|
119
|
-
tag: import("mobx-state-tree").ISimpleType<string>;
|
|
120
|
-
value: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
121
|
-
}, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
122
|
-
}, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>, [undefined]>;
|
|
117
|
+
colorBy: import("mobx-state-tree").IType<import("@jbrowse/plugin-alignments/src/shared/types").ColorBy | undefined, import("@jbrowse/plugin-alignments/src/shared/types").ColorBy | undefined, import("@jbrowse/plugin-alignments/src/shared/types").ColorBy | undefined>;
|
|
118
|
+
filterBy: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IType<import("@jbrowse/plugin-alignments/src/shared/types").FilterBy, import("@jbrowse/plugin-alignments/src/shared/types").FilterBy, import("@jbrowse/plugin-alignments/src/shared/types").FilterBy>, [undefined]>;
|
|
123
119
|
jexlFilters: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>, [undefined]>;
|
|
124
120
|
} & {
|
|
125
121
|
/**
|
|
@@ -223,7 +219,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
223
219
|
regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): import("react").JSX.Element | null;
|
|
224
220
|
} & {
|
|
225
221
|
featureIdUnderMouse: undefined | string;
|
|
226
|
-
contextMenuFeature: undefined |
|
|
222
|
+
contextMenuFeature: undefined | Feature;
|
|
227
223
|
} & {
|
|
228
224
|
readonly DisplayMessageComponent: import("react").FC<any> | undefined;
|
|
229
225
|
readonly blockType: "dynamicBlocks" | "staticBlocks";
|
|
@@ -233,19 +229,19 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
233
229
|
readonly TooltipComponent: import("@jbrowse/core/util").AnyReactComponentType;
|
|
234
230
|
readonly selectedFeatureId: string | undefined;
|
|
235
231
|
} & {
|
|
236
|
-
readonly features: import("@jbrowse/core/util/compositeMap").default<string,
|
|
237
|
-
readonly featureUnderMouse:
|
|
232
|
+
readonly features: import("@jbrowse/core/util/compositeMap").default<string, Feature>;
|
|
233
|
+
readonly featureUnderMouse: Feature | undefined;
|
|
238
234
|
getFeatureOverlapping(blockKey: string, x: number, y: number): string | undefined;
|
|
239
235
|
getFeatureByID(blockKey: string, id: string): [number, number, number, number] | undefined;
|
|
240
236
|
searchFeatureByID(id: string): [number, number, number, number] | undefined;
|
|
241
237
|
} & {
|
|
242
238
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
243
239
|
deleteBlock(key: string): void;
|
|
244
|
-
selectFeature(feature:
|
|
245
|
-
navToFeature(feature:
|
|
240
|
+
selectFeature(feature: Feature): void;
|
|
241
|
+
navToFeature(feature: Feature): void;
|
|
246
242
|
clearFeatureSelection(): void;
|
|
247
243
|
setFeatureIdUnderMouse(feature?: string): void;
|
|
248
|
-
setContextMenuFeature(feature?:
|
|
244
|
+
setContextMenuFeature(feature?: Feature): void;
|
|
249
245
|
} & {
|
|
250
246
|
reload(): Promise<void>;
|
|
251
247
|
} & {
|
|
@@ -257,7 +253,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
257
253
|
afterAttach(): void;
|
|
258
254
|
} & {
|
|
259
255
|
colorTagMap: import("mobx").ObservableMap<string, string>;
|
|
260
|
-
featureUnderMouseVolatile: undefined |
|
|
256
|
+
featureUnderMouseVolatile: undefined | Feature;
|
|
261
257
|
tagsReady: boolean;
|
|
262
258
|
} & {
|
|
263
259
|
readonly autorunReady: boolean;
|
|
@@ -266,17 +262,13 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
266
262
|
setMaxHeight(n?: number): void;
|
|
267
263
|
setFeatureHeight(n?: number): void;
|
|
268
264
|
setNoSpacing(flag?: boolean): void;
|
|
269
|
-
setColorScheme(colorScheme:
|
|
270
|
-
type: string;
|
|
271
|
-
tag?: string;
|
|
272
|
-
extra?: import("@jbrowse/plugin-alignments/src/shared/color").ExtraColorBy;
|
|
273
|
-
}): void;
|
|
265
|
+
setColorScheme(colorScheme: import("@jbrowse/plugin-alignments/src/shared/types").ColorBy): void;
|
|
274
266
|
updateColorTagMap(uniqueTag: string[]): void;
|
|
275
|
-
setFeatureUnderMouse(feat?:
|
|
276
|
-
selectFeature(feature:
|
|
277
|
-
copyFeatureToClipboard(feature:
|
|
267
|
+
setFeatureUnderMouse(feat?: Feature): void;
|
|
268
|
+
selectFeature(feature: Feature): void;
|
|
269
|
+
copyFeatureToClipboard(feature: Feature): void;
|
|
278
270
|
setConfig(conf: import("@jbrowse/core/configuration").AnyConfigurationModel): void;
|
|
279
|
-
setFilterBy(filter: import("@jbrowse/plugin-alignments/src/shared").
|
|
271
|
+
setFilterBy(filter: import("@jbrowse/plugin-alignments/src/shared/types").FilterBy): void;
|
|
280
272
|
setJexlFilters(filters: string[]): void;
|
|
281
273
|
} & {
|
|
282
274
|
readonly rendererConfig: {
|
|
@@ -293,7 +285,7 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
293
285
|
} & {
|
|
294
286
|
readonly maxHeight: any;
|
|
295
287
|
readonly featureHeightSetting: any;
|
|
296
|
-
readonly featureUnderMouse:
|
|
288
|
+
readonly featureUnderMouse: Feature | undefined;
|
|
297
289
|
renderReady(): boolean;
|
|
298
290
|
readonly filters: import("@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain").default;
|
|
299
291
|
} & {
|
|
@@ -352,6 +344,10 @@ declare function stateModelFactory(schema: AnyConfigurationSchemaType): import("
|
|
|
352
344
|
}[];
|
|
353
345
|
})[];
|
|
354
346
|
} & {
|
|
347
|
+
/**
|
|
348
|
+
* #action
|
|
349
|
+
*/
|
|
350
|
+
selectFeature(feature: Feature): void;
|
|
355
351
|
afterCreate(): void;
|
|
356
352
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
|
|
357
353
|
export default stateModelFactory;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { lazy } from 'react';
|
|
2
|
-
import { ConfigurationReference, } from '@jbrowse/core/configuration';
|
|
3
|
-
import { getSession } from '@jbrowse/core/util';
|
|
2
|
+
import { ConfigurationReference, getConf, } from '@jbrowse/core/configuration';
|
|
3
|
+
import { getContainingTrack, getContainingView, getSession, isSessionModelWithWidgets, } from '@jbrowse/core/util';
|
|
4
4
|
import { SharedLinearPileupDisplayMixin } from '@jbrowse/plugin-alignments';
|
|
5
5
|
import { types } from 'mobx-state-tree';
|
|
6
6
|
const LaunchSyntenyViewDialog = lazy(() => import('./components/LaunchSyntenyViewDialog'));
|
|
@@ -37,12 +37,13 @@ function stateModelFactory(schema) {
|
|
|
37
37
|
...(feature
|
|
38
38
|
? [
|
|
39
39
|
{
|
|
40
|
-
label: '
|
|
40
|
+
label: 'Launch synteny view for this position',
|
|
41
41
|
onClick: () => {
|
|
42
42
|
getSession(self).queueDialog(handleClose => [
|
|
43
43
|
LaunchSyntenyViewDialog,
|
|
44
44
|
{
|
|
45
45
|
model: self,
|
|
46
|
+
trackId: getConf(getContainingTrack(self), 'trackId'),
|
|
46
47
|
handleClose,
|
|
47
48
|
feature,
|
|
48
49
|
},
|
|
@@ -73,6 +74,27 @@ function stateModelFactory(schema) {
|
|
|
73
74
|
};
|
|
74
75
|
})
|
|
75
76
|
.actions(self => ({
|
|
77
|
+
/**
|
|
78
|
+
* #action
|
|
79
|
+
*/
|
|
80
|
+
selectFeature(feature) {
|
|
81
|
+
const session = getSession(self);
|
|
82
|
+
if (isSessionModelWithWidgets(session)) {
|
|
83
|
+
const r2 = getContainingView(self);
|
|
84
|
+
let r3 = r2;
|
|
85
|
+
try {
|
|
86
|
+
r3 = getContainingView(r3);
|
|
87
|
+
}
|
|
88
|
+
catch (e) { }
|
|
89
|
+
const featureWidget = session.addWidget('SyntenyFeatureWidget', 'syntenyFeature', {
|
|
90
|
+
featureData: feature.toJSON(),
|
|
91
|
+
view: r3,
|
|
92
|
+
track: getContainingTrack(self),
|
|
93
|
+
});
|
|
94
|
+
session.showWidget(featureWidget);
|
|
95
|
+
}
|
|
96
|
+
session.setSelection(feature);
|
|
97
|
+
},
|
|
76
98
|
afterCreate() {
|
|
77
99
|
// use color by stand to help indicate inversions better on first load,
|
|
78
100
|
// otherwise use selected orientation
|
|
@@ -43,7 +43,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
43
43
|
message: string | undefined;
|
|
44
44
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
45
45
|
onHorizontalScroll?: () => void;
|
|
46
|
-
blockState
|
|
46
|
+
blockState? /**
|
|
47
|
+
* #action
|
|
48
|
+
* controlled by a reaction
|
|
49
|
+
*/: Record<string, any>;
|
|
47
50
|
}>;
|
|
48
51
|
readonly DisplayBlurb: React.FC<{
|
|
49
52
|
model: {
|
|
@@ -55,7 +58,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
55
58
|
error: unknown;
|
|
56
59
|
message: string | undefined;
|
|
57
60
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
58
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree"
|
|
61
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree" /**
|
|
62
|
+
* #action
|
|
63
|
+
* controlled by a reaction
|
|
64
|
+
*/).ISimpleType<string>, [undefined]>;
|
|
59
65
|
type: import("mobx-state-tree").ISimpleType<string>;
|
|
60
66
|
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
61
67
|
}, {
|
|
@@ -82,6 +88,14 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
82
88
|
features: Feature[] | undefined;
|
|
83
89
|
message: string | undefined;
|
|
84
90
|
} & {
|
|
91
|
+
/**
|
|
92
|
+
* #getter
|
|
93
|
+
*/
|
|
94
|
+
readonly level: number;
|
|
95
|
+
/**
|
|
96
|
+
* #getter
|
|
97
|
+
*/
|
|
98
|
+
readonly height: number;
|
|
85
99
|
/**
|
|
86
100
|
* #getter
|
|
87
101
|
*/
|
|
@@ -126,7 +140,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
126
140
|
message: string | undefined;
|
|
127
141
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
128
142
|
onHorizontalScroll?: () => void;
|
|
129
|
-
blockState
|
|
143
|
+
blockState? /**
|
|
144
|
+
* #action
|
|
145
|
+
* controlled by a reaction
|
|
146
|
+
*/: Record<string, any>;
|
|
130
147
|
}>;
|
|
131
148
|
readonly DisplayBlurb: React.FC<{
|
|
132
149
|
model: {
|
|
@@ -138,7 +155,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
138
155
|
error: unknown;
|
|
139
156
|
message: string | undefined;
|
|
140
157
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
141
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree"
|
|
158
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree" /**
|
|
159
|
+
* #action
|
|
160
|
+
* controlled by a reaction
|
|
161
|
+
*/).ISimpleType<string>, [undefined]>;
|
|
142
162
|
type: import("mobx-state-tree").ISimpleType<string>;
|
|
143
163
|
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
144
164
|
}, {
|
|
@@ -201,7 +221,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
201
221
|
message: string | undefined;
|
|
202
222
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
203
223
|
onHorizontalScroll?: () => void;
|
|
204
|
-
blockState
|
|
224
|
+
blockState? /**
|
|
225
|
+
* #action
|
|
226
|
+
* controlled by a reaction
|
|
227
|
+
*/: Record<string, any>;
|
|
205
228
|
}>;
|
|
206
229
|
readonly DisplayBlurb: React.FC<{
|
|
207
230
|
model: {
|
|
@@ -26,6 +26,18 @@ function stateModelFactory(configSchema) {
|
|
|
26
26
|
message: undefined,
|
|
27
27
|
}))
|
|
28
28
|
.views(self => ({
|
|
29
|
+
/**
|
|
30
|
+
* #getter
|
|
31
|
+
*/
|
|
32
|
+
get level() {
|
|
33
|
+
return getParent(self, 4).level;
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* #getter
|
|
37
|
+
*/
|
|
38
|
+
get height() {
|
|
39
|
+
return getParent(self, 4).height;
|
|
40
|
+
},
|
|
29
41
|
/**
|
|
30
42
|
* #getter
|
|
31
43
|
*/
|
|
@@ -131,7 +143,7 @@ function renderBlockData(self) {
|
|
|
131
143
|
// renderProps is something under our control. Compare to
|
|
132
144
|
// serverSideRenderedBlock
|
|
133
145
|
readConfObject(self.configuration);
|
|
134
|
-
const { adapterConfig } = self;
|
|
146
|
+
const { level, adapterConfig } = self;
|
|
135
147
|
const parent = getContainingView(self);
|
|
136
148
|
const sessionId = getRpcSessionId(self);
|
|
137
149
|
getSnapshot(parent);
|
|
@@ -140,8 +152,7 @@ function renderBlockData(self) {
|
|
|
140
152
|
rpcManager,
|
|
141
153
|
renderProps: {
|
|
142
154
|
...display.renderProps(),
|
|
143
|
-
|
|
144
|
-
level: getParent(self, 4).level,
|
|
155
|
+
level,
|
|
145
156
|
view: parent,
|
|
146
157
|
adapterConfig,
|
|
147
158
|
sessionId,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { reaction, autorun } from 'mobx';
|
|
2
|
+
import { addDisposer, getSnapshot } from 'mobx-state-tree';
|
|
2
3
|
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
3
4
|
import { bpToPx } from '@jbrowse/core/util/Base1DUtils';
|
|
4
5
|
import { MismatchParser } from '@jbrowse/plugin-alignments';
|
|
5
|
-
import { reaction, autorun } from 'mobx';
|
|
6
6
|
import { drawMouseoverSynteny, drawRef } from './drawSynteny';
|
|
7
7
|
export function doAfterAttach(self) {
|
|
8
8
|
addDisposer(self, autorun(() => {
|
|
@@ -48,10 +48,9 @@ export function doAfterAttach(self) {
|
|
|
48
48
|
if (!initialized) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
+
const { level } = self;
|
|
51
52
|
const { assemblyManager } = getSession(self);
|
|
52
53
|
const view = getContainingView(self);
|
|
53
|
-
// @ts-expect-error
|
|
54
|
-
const level = getParent(self, 4).level;
|
|
55
54
|
const viewSnaps = view.views.map(view => ({
|
|
56
55
|
...getSnapshot(view),
|
|
57
56
|
width: view.width,
|
|
@@ -27,6 +27,7 @@ const useStyles = makeStyles()({
|
|
|
27
27
|
});
|
|
28
28
|
const LinearSyntenyRendering = observer(function ({ model, }) {
|
|
29
29
|
const { classes } = useStyles();
|
|
30
|
+
const { mouseoverId, height } = model;
|
|
30
31
|
const xOffset = useRef(0);
|
|
31
32
|
const view = getContainingView(model);
|
|
32
33
|
const width = view.width;
|
|
@@ -39,20 +40,19 @@ const LinearSyntenyRendering = observer(function ({ model, }) {
|
|
|
39
40
|
const [mouseCurrDownX, setMouseCurrDownX] = useState();
|
|
40
41
|
const [mouseInitialDownX, setMouseInitialDownX] = useState();
|
|
41
42
|
const [currY, setCurrY] = useState();
|
|
42
|
-
const
|
|
43
|
-
const k2p = useRef();
|
|
43
|
+
const mainSyntenyCanvasRefp = useRef();
|
|
44
44
|
// these useCallbacks avoid new refs from being created on any mouseover,
|
|
45
45
|
// etc.
|
|
46
46
|
// biome-ignore lint/correctness/useExhaustiveDependencies:
|
|
47
|
-
const
|
|
47
|
+
const mouseoverDetectionCanvasRef = useCallback((ref) => {
|
|
48
48
|
model.setMouseoverCanvasRef(ref);
|
|
49
49
|
},
|
|
50
50
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
51
51
|
[model, height, width]);
|
|
52
52
|
// biome-ignore lint/correctness/useExhaustiveDependencies:
|
|
53
|
-
const
|
|
53
|
+
const mainSyntenyCanvasRef = useCallback((ref) => {
|
|
54
54
|
model.setMainCanvasRef(ref);
|
|
55
|
-
|
|
55
|
+
mainSyntenyCanvasRefp.current = ref; // this ref is additionally used in useEffect below
|
|
56
56
|
},
|
|
57
57
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
58
|
[model, height, width]);
|
|
@@ -75,7 +75,9 @@ const LinearSyntenyRendering = observer(function ({ model, }) {
|
|
|
75
75
|
v.setScaleFactor(1);
|
|
76
76
|
v.zoomTo(delta.current > 0
|
|
77
77
|
? v.bpPerPx * (1 + delta.current)
|
|
78
|
-
: v.bpPerPx / (1 - delta.current), event.clientX -
|
|
78
|
+
: v.bpPerPx / (1 - delta.current), event.clientX -
|
|
79
|
+
(((_a = mainSyntenyCanvasRefp.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) ||
|
|
80
|
+
0));
|
|
79
81
|
}
|
|
80
82
|
delta.current = 0;
|
|
81
83
|
}, 300);
|
|
@@ -98,28 +100,28 @@ const LinearSyntenyRendering = observer(function ({ model, }) {
|
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
|
-
(_a =
|
|
103
|
+
(_a = mainSyntenyCanvasRefp.current) === null || _a === void 0 ? void 0 : _a.addEventListener('wheel', onWheel);
|
|
102
104
|
return () => {
|
|
103
105
|
var _a;
|
|
104
|
-
(_a =
|
|
106
|
+
(_a = mainSyntenyCanvasRefp.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('wheel', onWheel);
|
|
105
107
|
};
|
|
106
108
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
107
109
|
}, [model, height, width]);
|
|
108
110
|
// biome-ignore lint/correctness/useExhaustiveDependencies:
|
|
109
|
-
const
|
|
111
|
+
const clickMapCanvasRef = useCallback((ref) => {
|
|
110
112
|
model.setClickMapCanvasRef(ref);
|
|
111
113
|
},
|
|
112
114
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
113
115
|
[model, height, width]);
|
|
114
116
|
// biome-ignore lint/correctness/useExhaustiveDependencies:
|
|
115
|
-
const
|
|
117
|
+
const cigarClickMapCanvasRef = useCallback((ref) => {
|
|
116
118
|
model.setCigarClickMapCanvasRef(ref);
|
|
117
119
|
},
|
|
118
120
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
119
121
|
[model, height, width]);
|
|
120
122
|
return (React.createElement("div", { className: classes.rel },
|
|
121
|
-
React.createElement("canvas", { ref:
|
|
122
|
-
React.createElement("canvas", { ref:
|
|
123
|
+
React.createElement("canvas", { ref: mouseoverDetectionCanvasRef, width: width, height: height, className: classes.mouseoverCanvas }),
|
|
124
|
+
React.createElement("canvas", { ref: mainSyntenyCanvasRef, onMouseMove: event => {
|
|
123
125
|
var _a;
|
|
124
126
|
if (mouseCurrDownX !== undefined) {
|
|
125
127
|
xOffset.current += mouseCurrDownX - event.clientX;
|
|
@@ -166,7 +168,11 @@ const LinearSyntenyRendering = observer(function ({ model, }) {
|
|
|
166
168
|
const { f, cigar } = model.featPositions[id];
|
|
167
169
|
const unitMultiplier2 = Math.floor(MAX_COLOR_RANGE / cigar.length);
|
|
168
170
|
const cigarIdx = getId(r2, g2, b2, unitMultiplier2);
|
|
169
|
-
setTooltip(getTooltip(
|
|
171
|
+
setTooltip(getTooltip({
|
|
172
|
+
feature: f,
|
|
173
|
+
cigarOp: cigar[cigarIdx],
|
|
174
|
+
cigarOpLen: cigar[cigarIdx + 1],
|
|
175
|
+
}));
|
|
170
176
|
}
|
|
171
177
|
}
|
|
172
178
|
}, onMouseLeave: () => {
|
|
@@ -185,8 +191,8 @@ const LinearSyntenyRendering = observer(function ({ model, }) {
|
|
|
185
191
|
}, onContextMenu: evt => {
|
|
186
192
|
onSynContextClick(evt, model, setAnchorEl);
|
|
187
193
|
}, "data-testid": "synteny_canvas", className: classes.mainCanvas, width: width, height: height }),
|
|
188
|
-
React.createElement("canvas", { ref:
|
|
189
|
-
React.createElement("canvas", { ref:
|
|
194
|
+
React.createElement("canvas", { ref: clickMapCanvasRef, className: classes.pix, width: width, height: height }),
|
|
195
|
+
React.createElement("canvas", { ref: cigarClickMapCanvasRef, className: classes.pix, width: width, height: height }),
|
|
190
196
|
mouseoverId && tooltip && currX && currY ? (React.createElement(SyntenyTooltip, { title: tooltip })) : null,
|
|
191
197
|
anchorEl ? (React.createElement(SyntenyContextMenu, { model: model, anchorEl: anchorEl, onClose: () => {
|
|
192
198
|
setAnchorEl(undefined);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
3
3
|
import { Menu } from '@jbrowse/core/ui';
|
|
4
|
-
import { getParent } from 'mobx-state-tree';
|
|
5
4
|
export default function SyntenyContextMenu({ model, onClose, anchorEl, }) {
|
|
6
5
|
const view = getContainingView(model);
|
|
7
6
|
const { clientX, clientY, feature } = anchorEl;
|
|
@@ -30,13 +29,12 @@ export default function SyntenyContextMenu({ model, onClose, anchorEl, }) {
|
|
|
30
29
|
label: 'Center on feature',
|
|
31
30
|
onClick: () => {
|
|
32
31
|
const { f } = feature;
|
|
33
|
-
const track = getParent(model, 4);
|
|
34
32
|
const start = f.get('start');
|
|
35
33
|
const end = f.get('end');
|
|
36
34
|
const refName = f.get('refName');
|
|
37
35
|
const mate = f.get('mate');
|
|
38
|
-
const l1 = view.views[
|
|
39
|
-
const l2 = view.views[
|
|
36
|
+
const l1 = view.views[model.level];
|
|
37
|
+
const l2 = view.views[model.level + 1];
|
|
40
38
|
l1.navToLocString(`${refName}:${start}-${end}`).catch((e) => {
|
|
41
39
|
const err = `${l1.assemblyNames[0]}:${e}`;
|
|
42
40
|
console.error(err);
|
|
@@ -36,5 +36,9 @@ export declare function drawBox(ctx: CanvasRenderingContext2D, x1: number, x2: n
|
|
|
36
36
|
export declare function drawBezierBox(ctx: CanvasRenderingContext2D, x1: number, x2: number, y1: number, x3: number, x4: number, y2: number, mid: number): void;
|
|
37
37
|
export declare function onSynClick(event: React.MouseEvent, model: LinearSyntenyDisplayModel): import("../model").FeatPos | undefined;
|
|
38
38
|
export declare function onSynContextClick(event: React.MouseEvent, model: LinearSyntenyDisplayModel, setAnchorEl: (arg: ClickCoord) => void): void;
|
|
39
|
-
export declare function getTooltip(
|
|
39
|
+
export declare function getTooltip({ feature, cigarOp, cigarOpLen, }: {
|
|
40
|
+
feature: Feature;
|
|
41
|
+
cigarOp?: string;
|
|
42
|
+
cigarOpLen?: string;
|
|
43
|
+
}): string;
|
|
40
44
|
export {};
|
|
@@ -54,7 +54,6 @@ export function drawBox(ctx, x1, x2, y1, x3, x4, y2) {
|
|
|
54
54
|
ctx.lineTo(x3, y2);
|
|
55
55
|
ctx.lineTo(x4, y2);
|
|
56
56
|
ctx.closePath();
|
|
57
|
-
ctx.fill();
|
|
58
57
|
}
|
|
59
58
|
export function drawBezierBox(ctx, x1, x2, y1, x3, x4, y2, mid) {
|
|
60
59
|
const len1 = Math.abs(x1 - x2);
|
|
@@ -74,13 +73,11 @@ export function drawBezierBox(ctx, x1, x2, y1, x3, x4, y2, mid) {
|
|
|
74
73
|
ctx.lineTo(x4, y2);
|
|
75
74
|
ctx.bezierCurveTo(x4, mid, x1, mid, x1, y1);
|
|
76
75
|
ctx.closePath();
|
|
77
|
-
ctx.fill();
|
|
78
76
|
}
|
|
79
77
|
export function onSynClick(event, model) {
|
|
80
78
|
const view = getContainingView(model);
|
|
81
79
|
const track = getContainingTrack(model);
|
|
82
|
-
const ref1 = model
|
|
83
|
-
const ref2 = model.cigarClickMapCanvas;
|
|
80
|
+
const { featPositions, numFeats, clickMapCanvas: ref1, cigarClickMapCanvas: ref2, level, } = model;
|
|
84
81
|
if (!ref1 || !ref2) {
|
|
85
82
|
return;
|
|
86
83
|
}
|
|
@@ -93,18 +90,19 @@ export function onSynClick(event, model) {
|
|
|
93
90
|
const x = event.clientX - rect.left;
|
|
94
91
|
const y = event.clientY - rect.top;
|
|
95
92
|
const [r1, g1, b1] = ctx1.getImageData(x, y, 1, 1).data;
|
|
96
|
-
const unitMultiplier = Math.floor(MAX_COLOR_RANGE /
|
|
93
|
+
const unitMultiplier = Math.floor(MAX_COLOR_RANGE / numFeats);
|
|
97
94
|
const id = getId(r1, g1, b1, unitMultiplier);
|
|
98
|
-
const feat =
|
|
95
|
+
const feat = featPositions[id];
|
|
99
96
|
if (feat) {
|
|
100
97
|
const { f } = feat;
|
|
101
98
|
model.setClickId(f.id());
|
|
102
99
|
const session = getSession(model);
|
|
103
100
|
if (isSessionModelWithWidgets(session)) {
|
|
104
|
-
session.showWidget(session.addWidget('
|
|
101
|
+
session.showWidget(session.addWidget('SyntenyFeatureWidget', 'syntenyFeature', {
|
|
105
102
|
view,
|
|
106
103
|
track,
|
|
107
104
|
featureData: f.toJSON(),
|
|
105
|
+
level,
|
|
108
106
|
}));
|
|
109
107
|
}
|
|
110
108
|
}
|
|
@@ -135,9 +133,9 @@ export function onSynContextClick(event, model, setAnchorEl) {
|
|
|
135
133
|
setAnchorEl({ clientX, clientY, feature: f });
|
|
136
134
|
}
|
|
137
135
|
}
|
|
138
|
-
export function getTooltip(
|
|
136
|
+
export function getTooltip({ feature, cigarOp, cigarOpLen, }) {
|
|
139
137
|
// @ts-expect-error
|
|
140
|
-
const f1 =
|
|
138
|
+
const f1 = feature.toJSON();
|
|
141
139
|
const f2 = f1.mate;
|
|
142
140
|
const l1 = f1.end - f1.start;
|
|
143
141
|
const l2 = f2.end - f2.start;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { doesIntersect2, getContainingView } from '@jbrowse/core/util';
|
|
2
2
|
import { draw, drawMatchSimple } from './components/util';
|
|
3
|
-
import { getParent } from 'mobx-state-tree';
|
|
4
3
|
export const MAX_COLOR_RANGE = 255 * 255 * 255; // max color range
|
|
5
4
|
function makeColor(idx) {
|
|
6
5
|
const r = Math.floor(idx / (255 * 255)) % 255;
|
|
@@ -24,11 +23,9 @@ export function getId(r, g, b, unitMultiplier) {
|
|
|
24
23
|
export function drawRef(model, ctx1, ctx3) {
|
|
25
24
|
var _a;
|
|
26
25
|
const view = getContainingView(model);
|
|
27
|
-
// @ts-expect-error
|
|
28
|
-
const level = getParent(model, 4).level;
|
|
29
26
|
const drawCurves = view.drawCurves;
|
|
30
27
|
const drawCIGAR = view.drawCIGAR;
|
|
31
|
-
const { height, featPositions } = model;
|
|
28
|
+
const { level, height, featPositions } = model;
|
|
32
29
|
const width = view.width;
|
|
33
30
|
const bpPerPxs = view.views.map(v => v.bpPerPx);
|
|
34
31
|
if (ctx3) {
|
|
@@ -144,9 +141,11 @@ export function drawRef(model, ctx1, ctx3) {
|
|
|
144
141
|
colorMap[(continuingFlag && d1 > 1) || d2 > 1 ? op : 'M'];
|
|
145
142
|
continuingFlag = false;
|
|
146
143
|
draw(ctx1, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
|
|
144
|
+
ctx1.fill();
|
|
147
145
|
if (ctx3) {
|
|
148
146
|
ctx3.fillStyle = makeColor(idx);
|
|
149
147
|
draw(ctx3, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
|
|
148
|
+
ctx3.fill();
|
|
150
149
|
}
|
|
151
150
|
}
|
|
152
151
|
}
|
|
@@ -154,6 +153,7 @@ export function drawRef(model, ctx1, ctx3) {
|
|
|
154
153
|
}
|
|
155
154
|
else {
|
|
156
155
|
draw(ctx1, x11, x12, y1, x22, x21, y2, mid, drawCurves);
|
|
156
|
+
ctx1.fill();
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
}
|
|
@@ -187,7 +187,7 @@ export function drawRef(model, ctx1, ctx3) {
|
|
|
187
187
|
}
|
|
188
188
|
export function drawMouseoverSynteny(model) {
|
|
189
189
|
var _a;
|
|
190
|
-
const { clickId, mouseoverId } = model;
|
|
190
|
+
const { level, clickId, mouseoverId } = model;
|
|
191
191
|
const highResolutionScaling = 1;
|
|
192
192
|
const view = getContainingView(model);
|
|
193
193
|
const drawCurves = view.drawCurves;
|
|
@@ -195,17 +195,16 @@ export function drawMouseoverSynteny(model) {
|
|
|
195
195
|
const width = view.width;
|
|
196
196
|
const ctx = (_a = model.mouseoverCanvas) === null || _a === void 0 ? void 0 : _a.getContext('2d');
|
|
197
197
|
const offsets = view.views.map(v => v.offsetPx);
|
|
198
|
-
// @ts-expect-error
|
|
199
|
-
const level = getParent(model, 4).level;
|
|
200
198
|
if (!ctx) {
|
|
201
199
|
return;
|
|
202
200
|
}
|
|
203
201
|
ctx.resetTransform();
|
|
204
202
|
ctx.scale(highResolutionScaling, highResolutionScaling);
|
|
205
203
|
ctx.clearRect(0, 0, width, height);
|
|
204
|
+
ctx.strokeStyle = 'rgba(0, 0, 0, 0.9)';
|
|
205
|
+
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
|
|
206
206
|
const feature1 = model.featMap[mouseoverId || ''];
|
|
207
207
|
if (feature1) {
|
|
208
|
-
ctx.fillStyle = 'rgb(0,0,0,0.1)';
|
|
209
208
|
drawMatchSimple({
|
|
210
209
|
cb: ctx => {
|
|
211
210
|
ctx.fill();
|
|
@@ -222,7 +221,6 @@ export function drawMouseoverSynteny(model) {
|
|
|
222
221
|
}
|
|
223
222
|
const feature2 = model.featMap[clickId || ''];
|
|
224
223
|
if (feature2) {
|
|
225
|
-
ctx.strokeStyle = 'rgb(0, 0, 0, 0.9)';
|
|
226
224
|
drawMatchSimple({
|
|
227
225
|
cb: ctx => {
|
|
228
226
|
ctx.stroke();
|