@jbrowse/plugin-linear-genome-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/BaseLinearDisplay/components/LinearBlocks.js +7 -7
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +17 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +21 -0
- package/dist/BaseLinearDisplay/models/configSchema.d.ts +10 -0
- package/dist/BaseLinearDisplay/models/configSchema.js +15 -3
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -0
- package/dist/LinearBareDisplay/configSchema.d.ts +5 -0
- package/dist/LinearBareDisplay/model.d.ts +17 -2
- package/dist/LinearBasicDisplay/components/AddFiltersDialog.d.ts +10 -0
- package/dist/LinearBasicDisplay/components/AddFiltersDialog.js +94 -0
- package/dist/LinearBasicDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -7
- package/dist/LinearBasicDisplay/configSchema.d.ts +5 -0
- package/dist/LinearBasicDisplay/model.d.ts +56 -21
- package/dist/LinearBasicDisplay/model.js +36 -5
- package/dist/LinearGenomeView/components/Gridlines.js +3 -4
- package/dist/LinearGenomeView/components/Highlight.js +20 -21
- package/dist/LinearGenomeView/components/OverviewScalebar.js +1 -2
- package/dist/LinearGenomeView/components/Scalebar.js +4 -5
- package/dist/LinearGenomeView/components/TrackLabel.js +4 -4
- package/dist/LinearGenomeView/components/TrackRenderingContainer.js +10 -5
- package/dist/LinearGenomeView/components/hooks.d.ts +2 -2
- package/dist/LinearGenomeView/components/hooks.js +8 -13
- package/dist/LinearGenomeView/model.d.ts +5 -22
- package/dist/LinearGenomeView/model.js +2 -2
- package/dist/index.d.ts +60 -129
- package/esm/BaseLinearDisplay/components/LinearBlocks.js +7 -7
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +17 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +21 -0
- package/esm/BaseLinearDisplay/models/configSchema.d.ts +10 -0
- package/esm/BaseLinearDisplay/models/configSchema.js +15 -3
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -0
- package/esm/LinearBareDisplay/configSchema.d.ts +5 -0
- package/esm/LinearBareDisplay/model.d.ts +17 -2
- package/esm/LinearBasicDisplay/components/AddFiltersDialog.d.ts +10 -0
- package/esm/LinearBasicDisplay/components/AddFiltersDialog.js +69 -0
- package/esm/LinearBasicDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -7
- package/esm/LinearBasicDisplay/configSchema.d.ts +5 -0
- package/esm/LinearBasicDisplay/model.d.ts +56 -21
- package/esm/LinearBasicDisplay/model.js +37 -6
- package/esm/LinearGenomeView/components/Gridlines.js +3 -4
- package/esm/LinearGenomeView/components/Highlight.js +20 -21
- package/esm/LinearGenomeView/components/OverviewScalebar.js +1 -2
- package/esm/LinearGenomeView/components/Scalebar.js +4 -5
- package/esm/LinearGenomeView/components/TrackLabel.js +4 -4
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js +10 -5
- package/esm/LinearGenomeView/components/hooks.d.ts +2 -2
- package/esm/LinearGenomeView/components/hooks.js +8 -10
- package/esm/LinearGenomeView/model.d.ts +5 -22
- package/esm/LinearGenomeView/model.js +3 -3
- package/esm/index.d.ts +60 -129
- package/package.json +2 -4
- /package/dist/LinearBasicDisplay/components/{SetMaxHeight.d.ts → SetMaxHeightDialog.d.ts} +0 -0
- /package/esm/LinearBasicDisplay/components/{SetMaxHeight.d.ts → SetMaxHeightDialog.d.ts} +0 -0
|
@@ -77,7 +77,9 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
77
77
|
};
|
|
78
78
|
fetchSizeLimit: {
|
|
79
79
|
type: string;
|
|
80
|
-
defaultValue: number;
|
|
80
|
+
defaultValue: number; /**
|
|
81
|
+
* #method
|
|
82
|
+
*/
|
|
81
83
|
description: string;
|
|
82
84
|
};
|
|
83
85
|
height: {
|
|
@@ -91,6 +93,11 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
91
93
|
defaultValue: string;
|
|
92
94
|
contextVariable: string[];
|
|
93
95
|
};
|
|
96
|
+
jexlFilters: {
|
|
97
|
+
type: string;
|
|
98
|
+
description: string;
|
|
99
|
+
defaultValue: never[];
|
|
100
|
+
};
|
|
94
101
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
95
102
|
} & {
|
|
96
103
|
/**
|
|
@@ -215,6 +222,7 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
215
222
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
216
223
|
deleteBlock(key: string): void;
|
|
217
224
|
selectFeature(feature: import("@jbrowse/core/util").Feature): void;
|
|
225
|
+
navToFeature(feature: import("@jbrowse/core/util").Feature): void;
|
|
218
226
|
clearFeatureSelection(): void;
|
|
219
227
|
setFeatureIdUnderMouse(feature?: string | undefined): void;
|
|
220
228
|
setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature | undefined): void;
|
|
@@ -309,7 +317,9 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
309
317
|
};
|
|
310
318
|
fetchSizeLimit: {
|
|
311
319
|
type: string;
|
|
312
|
-
defaultValue: number;
|
|
320
|
+
defaultValue: number; /**
|
|
321
|
+
* #method
|
|
322
|
+
*/
|
|
313
323
|
description: string;
|
|
314
324
|
};
|
|
315
325
|
height: {
|
|
@@ -323,6 +333,11 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
323
333
|
defaultValue: string;
|
|
324
334
|
contextVariable: string[];
|
|
325
335
|
};
|
|
336
|
+
jexlFilters: {
|
|
337
|
+
type: string;
|
|
338
|
+
description: string;
|
|
339
|
+
defaultValue: never[];
|
|
340
|
+
};
|
|
326
341
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
327
342
|
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
328
343
|
type: string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare const AddFiltersDialog: ({ model, handleClose, }: {
|
|
3
|
+
model: {
|
|
4
|
+
jexlFilters?: string[];
|
|
5
|
+
activeFilters: string[];
|
|
6
|
+
setJexlFilters: (arg?: string[]) => void;
|
|
7
|
+
};
|
|
8
|
+
handleClose: () => void;
|
|
9
|
+
}) => React.JSX.Element;
|
|
10
|
+
export default AddFiltersDialog;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
3
|
+
import { Dialog } from '@jbrowse/core/ui';
|
|
4
|
+
import { Button, DialogActions, DialogContent, TextField } from '@mui/material';
|
|
5
|
+
import { makeStyles } from 'tss-react/mui';
|
|
6
|
+
import { stringToJexlExpression } from '@jbrowse/core/util/jexlStrings';
|
|
7
|
+
const useStyles = makeStyles()({
|
|
8
|
+
dialogContent: {
|
|
9
|
+
width: '80em',
|
|
10
|
+
},
|
|
11
|
+
textAreaFont: {
|
|
12
|
+
fontFamily: 'Courier New',
|
|
13
|
+
},
|
|
14
|
+
error: {
|
|
15
|
+
color: 'red',
|
|
16
|
+
fontSize: '0.8em',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
function checkJexl(code) {
|
|
20
|
+
stringToJexlExpression(code);
|
|
21
|
+
}
|
|
22
|
+
const AddFiltersDialog = observer(function ({ model, handleClose, }) {
|
|
23
|
+
const { classes } = useStyles();
|
|
24
|
+
const { activeFilters } = model;
|
|
25
|
+
const [data, setData] = useState(activeFilters.join('\n'));
|
|
26
|
+
const [error, setError] = useState();
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
try {
|
|
29
|
+
data
|
|
30
|
+
.split('\n')
|
|
31
|
+
.map(line => line.trim())
|
|
32
|
+
.filter(line => !!line)
|
|
33
|
+
.map(line => checkJexl(line.trim()));
|
|
34
|
+
setError(undefined);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
console.error(e);
|
|
38
|
+
setError(e);
|
|
39
|
+
}
|
|
40
|
+
}, [data]);
|
|
41
|
+
return (React.createElement(Dialog, { maxWidth: "xl", open: true, onClose: handleClose, title: "Add track filters" },
|
|
42
|
+
React.createElement(DialogContent, null,
|
|
43
|
+
React.createElement("div", null,
|
|
44
|
+
"Add filters, in jexl format, one per line, starting with the string jexl:. Examples:",
|
|
45
|
+
' ',
|
|
46
|
+
React.createElement("ul", null,
|
|
47
|
+
React.createElement("li", null,
|
|
48
|
+
React.createElement("code", null, "jexl:get(feature,'name')=='BRCA1'"),
|
|
49
|
+
" - show only feature where the name attribute is BRCA1"),
|
|
50
|
+
React.createElement("li", null,
|
|
51
|
+
React.createElement("code", null, "jexl:get(feature,'type')=='gene'"),
|
|
52
|
+
" - show only gene type features in a GFF that has many other feature types"),
|
|
53
|
+
React.createElement("li", null,
|
|
54
|
+
React.createElement("code", null, "jexl:get(feature,'score') > 400"),
|
|
55
|
+
" - show only features that have a score greater than 400"))),
|
|
56
|
+
error ? React.createElement("p", { className: classes.error }, `${error}`) : null,
|
|
57
|
+
React.createElement(TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event => setData(event.target.value), InputProps: {
|
|
58
|
+
classes: {
|
|
59
|
+
input: classes.textAreaFont,
|
|
60
|
+
},
|
|
61
|
+
} })),
|
|
62
|
+
React.createElement(DialogActions, null,
|
|
63
|
+
React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, disabled: !!error, onClick: () => {
|
|
64
|
+
model.setJexlFilters(data.split('\n'));
|
|
65
|
+
handleClose();
|
|
66
|
+
} }, "Submit"),
|
|
67
|
+
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel"))));
|
|
68
|
+
});
|
|
69
|
+
export default AddFiltersDialog;
|
|
@@ -15,12 +15,12 @@ const SetMaxHeightDialog = observer(function ({ model, handleClose, }) {
|
|
|
15
15
|
return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Set max height" },
|
|
16
16
|
React.createElement(DialogContent, { className: classes.root },
|
|
17
17
|
React.createElement(Typography, null, "Set max height for the track. For example, you can increase this if the layout says \"Max height reached\""),
|
|
18
|
-
React.createElement(TextField, { value: max, onChange: event => setMax(event.target.value), placeholder: "Enter max score" }),
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
React.createElement(TextField, { value: max, onChange: event => setMax(event.target.value), placeholder: "Enter max score" })),
|
|
19
|
+
React.createElement(DialogActions, null,
|
|
20
|
+
React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
|
|
21
|
+
model.setMaxHeight(max !== '' && !Number.isNaN(+max) ? +max : undefined);
|
|
22
|
+
handleClose();
|
|
23
|
+
} }, "Submit"),
|
|
24
|
+
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel"))));
|
|
25
25
|
});
|
|
26
26
|
export default SetMaxHeightDialog;
|
|
@@ -30,5 +30,10 @@ declare function configSchemaFactory(pluginManager: PluginManager): import("@jbr
|
|
|
30
30
|
defaultValue: string;
|
|
31
31
|
contextVariable: string[];
|
|
32
32
|
};
|
|
33
|
+
jexlFilters: {
|
|
34
|
+
type: string;
|
|
35
|
+
description: string;
|
|
36
|
+
defaultValue: never[];
|
|
37
|
+
};
|
|
33
38
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>;
|
|
34
39
|
export default configSchemaFactory;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
|
|
3
3
|
import { MenuItem } from '@jbrowse/core/ui';
|
|
4
4
|
import { Instance } from 'mobx-state-tree';
|
|
5
|
+
import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
|
|
5
6
|
/**
|
|
6
7
|
* #stateModel LinearBasicDisplay
|
|
7
8
|
* #category display
|
|
@@ -50,11 +51,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
50
51
|
model: {
|
|
51
52
|
error?: unknown;
|
|
52
53
|
reload: () => void;
|
|
53
|
-
message: import("react").ReactNode;
|
|
54
|
-
|
|
55
|
-
status?: string | undefined; /**
|
|
56
|
-
* #getter
|
|
54
|
+
message: import("react").ReactNode; /**
|
|
55
|
+
* #property
|
|
57
56
|
*/
|
|
57
|
+
filled?: boolean | undefined;
|
|
58
|
+
status?: string | undefined;
|
|
58
59
|
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
59
60
|
};
|
|
60
61
|
}) => import("react").JSX.Element | undefined;
|
|
@@ -63,7 +64,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
63
64
|
doReload(): void;
|
|
64
65
|
afterAttach(): void;
|
|
65
66
|
setStatus(message: string): void;
|
|
66
|
-
setLoading(abortController: AbortController): void;
|
|
67
|
+
setLoading(abortController: AbortController): void; /**
|
|
68
|
+
* #getter
|
|
69
|
+
*/
|
|
67
70
|
setMessage(messageText: string): void;
|
|
68
71
|
setRendered(props: {
|
|
69
72
|
reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
@@ -94,10 +97,17 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
94
97
|
};
|
|
95
98
|
mouseover: {
|
|
96
99
|
type: string;
|
|
97
|
-
description: string;
|
|
100
|
+
description: string; /**
|
|
101
|
+
* #property
|
|
102
|
+
*/
|
|
98
103
|
defaultValue: string;
|
|
99
104
|
contextVariable: string[];
|
|
100
105
|
};
|
|
106
|
+
jexlFilters: {
|
|
107
|
+
type: string;
|
|
108
|
+
description: string;
|
|
109
|
+
defaultValue: never[];
|
|
110
|
+
};
|
|
101
111
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
102
112
|
} & {
|
|
103
113
|
/**
|
|
@@ -124,6 +134,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
124
134
|
* #property
|
|
125
135
|
*/
|
|
126
136
|
configuration: AnyConfigurationSchemaType;
|
|
137
|
+
/**
|
|
138
|
+
* #property
|
|
139
|
+
*/
|
|
140
|
+
jexlFilters: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>>;
|
|
127
141
|
}, {
|
|
128
142
|
rendererTypeName: string;
|
|
129
143
|
error: unknown;
|
|
@@ -140,7 +154,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
140
154
|
message: string | undefined;
|
|
141
155
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
142
156
|
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
143
|
-
type: import("mobx-state-tree").ISimpleType<string>;
|
|
157
|
+
type: import("mobx-state-tree").ISimpleType<string>; /**
|
|
158
|
+
* #property
|
|
159
|
+
*/
|
|
144
160
|
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
145
161
|
}, {
|
|
146
162
|
rendererTypeName: string;
|
|
@@ -166,11 +182,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
166
182
|
}, {
|
|
167
183
|
rendererTypeName: string;
|
|
168
184
|
error: unknown;
|
|
169
|
-
message: string | undefined;
|
|
170
|
-
* #action
|
|
171
|
-
*/
|
|
185
|
+
message: string | undefined;
|
|
172
186
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
173
|
-
}> | null;
|
|
187
|
+
}> | null; /**
|
|
188
|
+
* #getter
|
|
189
|
+
*/
|
|
174
190
|
readonly adapterConfig: any;
|
|
175
191
|
readonly parentTrack: any;
|
|
176
192
|
renderProps(): any;
|
|
@@ -208,13 +224,13 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
208
224
|
setCurrStatsBpPerPx(n: number): void;
|
|
209
225
|
setFeatureDensityStatsLimit(stats?: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined): void;
|
|
210
226
|
getFeatureDensityStats(): Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats>;
|
|
211
|
-
setFeatureDensityStatsP(arg: any): void;
|
|
212
|
-
* #method
|
|
213
|
-
*/
|
|
227
|
+
setFeatureDensityStatsP(arg: any): void;
|
|
214
228
|
setFeatureDensityStats(featureDensityStats?: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined): void;
|
|
215
229
|
clearFeatureDensityStats(): void;
|
|
216
230
|
} & {
|
|
217
|
-
readonly regionTooLarge: boolean;
|
|
231
|
+
readonly regionTooLarge: boolean; /**
|
|
232
|
+
* #method
|
|
233
|
+
*/
|
|
218
234
|
readonly regionTooLargeReason: string;
|
|
219
235
|
} & {
|
|
220
236
|
regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
|
|
@@ -240,6 +256,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
240
256
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
241
257
|
deleteBlock(key: string): void;
|
|
242
258
|
selectFeature(feature: import("@jbrowse/core/util").Feature): void;
|
|
259
|
+
navToFeature(feature: import("@jbrowse/core/util").Feature): void;
|
|
243
260
|
clearFeatureSelection(): void;
|
|
244
261
|
setFeatureIdUnderMouse(feature?: string | undefined): void;
|
|
245
262
|
setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature | undefined): void;
|
|
@@ -253,6 +270,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
253
270
|
renderSvg(opts: import("../BaseLinearDisplay").ExportSvgDisplayOptions): Promise<import("react").JSX.Element>;
|
|
254
271
|
afterAttach(): void;
|
|
255
272
|
} & {
|
|
273
|
+
/**
|
|
274
|
+
* #getter
|
|
275
|
+
*/
|
|
276
|
+
readonly activeFilters: any;
|
|
256
277
|
/**
|
|
257
278
|
* #getter
|
|
258
279
|
*/
|
|
@@ -283,6 +304,10 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
283
304
|
setSubschema(slotName: string, data: unknown): any;
|
|
284
305
|
} & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
|
|
285
306
|
} & {
|
|
307
|
+
/**
|
|
308
|
+
* #action
|
|
309
|
+
*/
|
|
310
|
+
setJexlFilters(f?: string[]): void;
|
|
286
311
|
/**
|
|
287
312
|
* #action
|
|
288
313
|
*/
|
|
@@ -309,6 +334,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
309
334
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
310
335
|
setSubschema(slotName: string, data: unknown): any;
|
|
311
336
|
} & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
|
|
337
|
+
filters: SerializableFilterChain;
|
|
312
338
|
};
|
|
313
339
|
/**
|
|
314
340
|
* #method
|
|
@@ -355,11 +381,11 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
355
381
|
model: {
|
|
356
382
|
error?: unknown;
|
|
357
383
|
reload: () => void;
|
|
358
|
-
message: import("react").ReactNode;
|
|
359
|
-
|
|
360
|
-
status?: string | undefined; /**
|
|
361
|
-
* #getter
|
|
384
|
+
message: import("react").ReactNode; /**
|
|
385
|
+
* #property
|
|
362
386
|
*/
|
|
387
|
+
filled?: boolean | undefined;
|
|
388
|
+
status?: string | undefined;
|
|
363
389
|
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
364
390
|
};
|
|
365
391
|
}) => import("react").JSX.Element | undefined;
|
|
@@ -368,7 +394,9 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
368
394
|
doReload(): void;
|
|
369
395
|
afterAttach(): void;
|
|
370
396
|
setStatus(message: string): void;
|
|
371
|
-
setLoading(abortController: AbortController): void;
|
|
397
|
+
setLoading(abortController: AbortController): void; /**
|
|
398
|
+
* #getter
|
|
399
|
+
*/
|
|
372
400
|
setMessage(messageText: string): void;
|
|
373
401
|
setRendered(props: {
|
|
374
402
|
reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
@@ -399,10 +427,17 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
399
427
|
};
|
|
400
428
|
mouseover: {
|
|
401
429
|
type: string;
|
|
402
|
-
description: string;
|
|
430
|
+
description: string; /**
|
|
431
|
+
* #property
|
|
432
|
+
*/
|
|
403
433
|
defaultValue: string;
|
|
404
434
|
contextVariable: string[];
|
|
405
435
|
};
|
|
436
|
+
jexlFilters: {
|
|
437
|
+
type: string;
|
|
438
|
+
description: string;
|
|
439
|
+
defaultValue: never[];
|
|
440
|
+
};
|
|
406
441
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
407
442
|
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
408
443
|
type: string;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { lazy } from 'react';
|
|
2
2
|
import { getConf, ConfigurationReference, } from '@jbrowse/core/configuration';
|
|
3
3
|
import { getSession } from '@jbrowse/core/util';
|
|
4
|
-
import { types, getEnv } from 'mobx-state-tree';
|
|
4
|
+
import { types, getEnv, cast } from 'mobx-state-tree';
|
|
5
5
|
// icons
|
|
6
6
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
|
7
7
|
// locals
|
|
8
8
|
import { BaseLinearDisplay } from '../BaseLinearDisplay';
|
|
9
|
-
|
|
9
|
+
import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
|
|
10
|
+
const SetMaxHeightDialog = lazy(() => import('./components/SetMaxHeightDialog'));
|
|
11
|
+
const AddFiltersDialog = lazy(() => import('./components/AddFiltersDialog'));
|
|
10
12
|
/**
|
|
11
13
|
* #stateModel LinearBasicDisplay
|
|
12
14
|
* #category display
|
|
@@ -43,8 +45,21 @@ function stateModelFactory(configSchema) {
|
|
|
43
45
|
* #property
|
|
44
46
|
*/
|
|
45
47
|
configuration: ConfigurationReference(configSchema),
|
|
48
|
+
/**
|
|
49
|
+
* #property
|
|
50
|
+
*/
|
|
51
|
+
jexlFilters: types.maybe(types.array(types.string)),
|
|
46
52
|
}))
|
|
47
53
|
.views(self => ({
|
|
54
|
+
/**
|
|
55
|
+
* #getter
|
|
56
|
+
*/
|
|
57
|
+
get activeFilters() {
|
|
58
|
+
var _a;
|
|
59
|
+
// config jexlFilters are deferred evaluated so they are prepended with
|
|
60
|
+
// jexl at runtime rather than being stored with jexl in the config
|
|
61
|
+
return ((_a = self.jexlFilters) !== null && _a !== void 0 ? _a : getConf(self, 'jexlFilters').map((r) => `jexl:${r}`));
|
|
62
|
+
},
|
|
48
63
|
/**
|
|
49
64
|
* #getter
|
|
50
65
|
*/
|
|
@@ -97,6 +112,12 @@ function stateModelFactory(configSchema) {
|
|
|
97
112
|
},
|
|
98
113
|
}))
|
|
99
114
|
.actions(self => ({
|
|
115
|
+
/**
|
|
116
|
+
* #action
|
|
117
|
+
*/
|
|
118
|
+
setJexlFilters(f) {
|
|
119
|
+
self.jexlFilters = cast(f);
|
|
120
|
+
},
|
|
100
121
|
/**
|
|
101
122
|
* #action
|
|
102
123
|
*/
|
|
@@ -129,12 +150,13 @@ function stateModelFactory(configSchema) {
|
|
|
129
150
|
* #method
|
|
130
151
|
*/
|
|
131
152
|
renderProps() {
|
|
132
|
-
const config = self.rendererConfig;
|
|
133
153
|
const superProps = superRenderProps();
|
|
134
|
-
const superPropsOmit = superProps;
|
|
135
154
|
return {
|
|
136
|
-
...
|
|
137
|
-
config,
|
|
155
|
+
...superProps,
|
|
156
|
+
config: self.rendererConfig,
|
|
157
|
+
filters: new SerializableFilterChain({
|
|
158
|
+
filters: self.activeFilters,
|
|
159
|
+
}),
|
|
138
160
|
};
|
|
139
161
|
},
|
|
140
162
|
/**
|
|
@@ -179,6 +201,15 @@ function stateModelFactory(configSchema) {
|
|
|
179
201
|
]);
|
|
180
202
|
},
|
|
181
203
|
},
|
|
204
|
+
{
|
|
205
|
+
label: 'Edit filters',
|
|
206
|
+
onClick: () => {
|
|
207
|
+
getSession(self).queueDialog(handleClose => [
|
|
208
|
+
AddFiltersDialog,
|
|
209
|
+
{ model: self, handleClose },
|
|
210
|
+
]);
|
|
211
|
+
},
|
|
212
|
+
},
|
|
182
213
|
];
|
|
183
214
|
},
|
|
184
215
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { ContentBlock, ElidedBlock, InterRegionPaddingBlock, } from '@jbrowse/core/util/blockTypes';
|
|
3
2
|
import { makeStyles } from 'tss-react/mui';
|
|
4
3
|
import { observer } from 'mobx-react';
|
|
5
4
|
import { ContentBlock as ContentBlockComponent, ElidedBlock as ElidedBlockComponent, InterRegionPaddingBlock as InterRegionPaddingBlockComponent, } from '../../BaseLinearDisplay/components/Block';
|
|
@@ -45,13 +44,13 @@ const RenderedVerticalGuides = observer(({ model }) => {
|
|
|
45
44
|
const { staticBlocks, bpPerPx } = model;
|
|
46
45
|
return (React.createElement(React.Fragment, null, staticBlocks.map((block, index) => {
|
|
47
46
|
const k = `${block.key}-${index}`;
|
|
48
|
-
if (block
|
|
47
|
+
if (block.type === 'ContentBlock') {
|
|
49
48
|
return React.createElement(RenderedBlockLines, { key: k, block: block, bpPerPx: bpPerPx });
|
|
50
49
|
}
|
|
51
|
-
else if (block
|
|
50
|
+
else if (block.type === 'ElidedBlock') {
|
|
52
51
|
return React.createElement(ElidedBlockComponent, { key: k, width: block.widthPx });
|
|
53
52
|
}
|
|
54
|
-
else if (block
|
|
53
|
+
else if (block.type === 'InterRegionPaddingBlock') {
|
|
55
54
|
return (React.createElement(InterRegionPaddingBlockComponent, { key: k, width: block.widthPx, boundary: block.variant === 'boundary' }));
|
|
56
55
|
}
|
|
57
56
|
return null;
|
|
@@ -33,26 +33,6 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
|
|
|
33
33
|
const dismissHighlight = () => {
|
|
34
34
|
model.removeHighlight(highlight);
|
|
35
35
|
};
|
|
36
|
-
const menuItems = [
|
|
37
|
-
{
|
|
38
|
-
label: 'Dismiss highlight',
|
|
39
|
-
icon: CloseIcon,
|
|
40
|
-
onClick: () => dismissHighlight(),
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
label: 'Bookmark highlighted region',
|
|
44
|
-
icon: BookmarkIcon,
|
|
45
|
-
onClick: () => {
|
|
46
|
-
let bookmarkWidget = session.widgets.get('GridBookmark');
|
|
47
|
-
if (!bookmarkWidget) {
|
|
48
|
-
bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
49
|
-
}
|
|
50
|
-
// @ts-ignore
|
|
51
|
-
bookmarkWidget.addBookmark(highlight);
|
|
52
|
-
dismissHighlight();
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
];
|
|
56
36
|
function handleClose() {
|
|
57
37
|
setOpen(false);
|
|
58
38
|
}
|
|
@@ -90,7 +70,26 @@ const Highlight = observer(function Highlight({ model, highlight, }) {
|
|
|
90
70
|
React.createElement(Menu, { anchorEl: anchorEl.current, onMenuItemClick: (_event, callback) => {
|
|
91
71
|
callback(session);
|
|
92
72
|
handleClose();
|
|
93
|
-
}, open: open, onClose: handleClose, menuItems:
|
|
73
|
+
}, open: open, onClose: handleClose, menuItems: [
|
|
74
|
+
{
|
|
75
|
+
label: 'Dismiss highlight',
|
|
76
|
+
icon: CloseIcon,
|
|
77
|
+
onClick: () => dismissHighlight(),
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
label: 'Bookmark highlighted region',
|
|
81
|
+
icon: BookmarkIcon,
|
|
82
|
+
onClick: () => {
|
|
83
|
+
let bookmarkWidget = session.widgets.get('GridBookmark');
|
|
84
|
+
if (!bookmarkWidget) {
|
|
85
|
+
bookmarkWidget = session.addWidget('GridBookmarkWidget', 'GridBookmark');
|
|
86
|
+
}
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
bookmarkWidget.addBookmark(highlight);
|
|
89
|
+
dismissHighlight();
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
] }))) : null;
|
|
94
93
|
});
|
|
95
94
|
const HighlightGroup = observer(function HighlightGroup({ model, }) {
|
|
96
95
|
return model.highlight.map((highlight, idx) => (React.createElement(Highlight, { key: JSON.stringify(highlight) + '-' + idx, model: model, highlight: highlight })));
|
|
@@ -5,7 +5,6 @@ import { observer } from 'mobx-react';
|
|
|
5
5
|
// core
|
|
6
6
|
import Base1DView from '@jbrowse/core/util/Base1DViewModel';
|
|
7
7
|
import { getEnv, getSession, getTickDisplayStr } from '@jbrowse/core/util';
|
|
8
|
-
import { ContentBlock } from '@jbrowse/core/util/blockTypes';
|
|
9
8
|
// locals
|
|
10
9
|
import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT, } from '..';
|
|
11
10
|
import { chooseGridPitch } from '../util';
|
|
@@ -148,7 +147,7 @@ const Scalebar = observer(function ({ model, scale, overview, }) {
|
|
|
148
147
|
borderColor: color,
|
|
149
148
|
} }),
|
|
150
149
|
overviewVisibleRegions.map((block, idx) => {
|
|
151
|
-
return !(block
|
|
150
|
+
return !(block.type === 'ContentBlock') ? (React.createElement("div", { key: `${JSON.stringify(block)}-${idx}`, className: classes.scalebarContig, style: {
|
|
152
151
|
width: block.widthPx,
|
|
153
152
|
left: block.offsetPx,
|
|
154
153
|
backgroundColor: '#999',
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Paper, Typography } from '@mui/material';
|
|
2
2
|
import { makeStyles } from 'tss-react/mui';
|
|
3
|
-
import { ContentBlock, ElidedBlock, InterRegionPaddingBlock, } from '@jbrowse/core/util/blockTypes';
|
|
4
3
|
import { observer } from 'mobx-react';
|
|
5
4
|
import React from 'react';
|
|
6
5
|
import { ContentBlock as ContentBlockComponent, ElidedBlock as ElidedBlockComponent, InterRegionPaddingBlock as InterRegionPaddingBlockComponent, } from '../../BaseLinearDisplay/components/Block';
|
|
@@ -56,7 +55,7 @@ const RenderedRefNameLabels = observer(({ model }) => {
|
|
|
56
55
|
}
|
|
57
56
|
});
|
|
58
57
|
return (React.createElement(React.Fragment, null, model.staticBlocks.map((block, index) => {
|
|
59
|
-
return block
|
|
58
|
+
return block.type === 'ContentBlock' &&
|
|
60
59
|
(block.isLeftEndOfDisplayedRegion || index === lastLeftBlock) ? (React.createElement(Typography, { key: `refLabel-${block.key}-${index}`, style: {
|
|
61
60
|
left: index === lastLeftBlock
|
|
62
61
|
? Math.max(0, -model.offsetPx)
|
|
@@ -83,13 +82,13 @@ const RenderedScalebarLabels = observer(({ model }) => {
|
|
|
83
82
|
return (React.createElement(React.Fragment, null, staticBlocks.map((block, idx) => {
|
|
84
83
|
const { key, widthPx } = block;
|
|
85
84
|
const k = `${key}-${idx}`;
|
|
86
|
-
if (block
|
|
85
|
+
if (block.type === 'ContentBlock') {
|
|
87
86
|
return React.createElement(RenderedBlockTicks, { key: k, block: block, bpPerPx: bpPerPx });
|
|
88
87
|
}
|
|
89
|
-
else if (block
|
|
88
|
+
else if (block.type === 'ElidedBlock') {
|
|
90
89
|
return React.createElement(ElidedBlockComponent, { key: k, width: widthPx });
|
|
91
90
|
}
|
|
92
|
-
else if (block
|
|
91
|
+
else if (block.type === 'InterRegionPaddingBlock') {
|
|
93
92
|
return (React.createElement(InterRegionPaddingBlockComponent, { key: k, width: widthPx, style: { background: 'none' }, boundary: block.variant === 'boundary' }));
|
|
94
93
|
}
|
|
95
94
|
return null;
|
|
@@ -25,10 +25,7 @@ const useStyles = makeStyles()(theme => ({
|
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
27
|
trackName: {
|
|
28
|
-
margin: '0 auto',
|
|
29
|
-
width: '90%',
|
|
30
28
|
fontSize: '0.8rem',
|
|
31
|
-
pointerEvents: 'none',
|
|
32
29
|
},
|
|
33
30
|
iconButton: {
|
|
34
31
|
padding: theme.spacing(1),
|
|
@@ -82,7 +79,10 @@ const TrackLabel = observer(React.forwardRef(function TrackLabel2({ track, class
|
|
|
82
79
|
React.createElement(TrackLabelDragHandle, { track: track, trackId: trackId, view: view }),
|
|
83
80
|
React.createElement(IconButton, { onClick: () => view.hideTrack(trackId), className: classes.iconButton, title: "close this track" },
|
|
84
81
|
React.createElement(CloseIcon, { fontSize: "small" })),
|
|
85
|
-
React.createElement(Typography, { variant: "body1", component: "span", className: classes.trackName
|
|
82
|
+
React.createElement(Typography, { variant: "body1", component: "span", className: classes.trackName, onMouseDown: event => {
|
|
83
|
+
// avoid becoming a click-and-drag action on the lgv
|
|
84
|
+
event.stopPropagation();
|
|
85
|
+
} },
|
|
86
86
|
React.createElement(SanitizedHTML, { html: [trackName, minimized ? '(minimized)' : '']
|
|
87
87
|
.filter(f => !!f)
|
|
88
88
|
.join(' ') })),
|
|
@@ -26,19 +26,24 @@ const TrackRenderingContainer = observer(function ({ model, track, onDragEnter,
|
|
|
26
26
|
const { classes } = useStyles();
|
|
27
27
|
const display = track.displays[0];
|
|
28
28
|
const { height, RenderingComponent, DisplayBlurb } = display;
|
|
29
|
+
const { trackRefs, id, scaleFactor } = model;
|
|
29
30
|
const trackId = getConf(track, 'trackId');
|
|
30
31
|
const ref = useRef(null);
|
|
31
32
|
const minimized = track.minimized;
|
|
32
33
|
useEffect(() => {
|
|
33
34
|
if (ref.current) {
|
|
34
|
-
|
|
35
|
+
trackRefs[trackId] = ref.current;
|
|
35
36
|
}
|
|
36
37
|
return () => {
|
|
37
|
-
delete
|
|
38
|
+
delete trackRefs[trackId];
|
|
38
39
|
};
|
|
39
|
-
}, [
|
|
40
|
-
return (React.createElement("div", { className: classes.trackRenderingContainer, style: {
|
|
41
|
-
|
|
40
|
+
}, [trackRefs, trackId]);
|
|
41
|
+
return (React.createElement("div", { className: classes.trackRenderingContainer, style: {
|
|
42
|
+
height: minimized ? 20 : height,
|
|
43
|
+
}, onScroll: evt => display.setScrollTop(evt.currentTarget.scrollTop), onDragEnter: onDragEnter, "data-testid": `trackRenderingContainer-${id}-${trackId}` }, !minimized ? (React.createElement(React.Fragment, null,
|
|
44
|
+
React.createElement("div", { ref: ref, className: classes.renderingComponentContainer, style: {
|
|
45
|
+
transform: scaleFactor !== 1 ? `scaleX(${scaleFactor})` : undefined,
|
|
46
|
+
} },
|
|
42
47
|
React.createElement(Suspense, { fallback: React.createElement(LoadingEllipses, null) },
|
|
43
48
|
React.createElement(RenderingComponent, { model: display, onHorizontalScroll: model.horizontalScroll }))),
|
|
44
49
|
DisplayBlurb ? (React.createElement("div", { style: {
|
|
@@ -42,7 +42,7 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement>, mod
|
|
|
42
42
|
offset: number;
|
|
43
43
|
start: number;
|
|
44
44
|
end: number;
|
|
45
|
-
reversed
|
|
45
|
+
reversed?: boolean | undefined;
|
|
46
46
|
};
|
|
47
47
|
rightBpOffset: {
|
|
48
48
|
coord: number;
|
|
@@ -53,7 +53,7 @@ export declare function useRangeSelect(ref: React.RefObject<HTMLDivElement>, mod
|
|
|
53
53
|
offset: number;
|
|
54
54
|
start: number;
|
|
55
55
|
end: number;
|
|
56
|
-
reversed
|
|
56
|
+
reversed?: boolean | undefined;
|
|
57
57
|
};
|
|
58
58
|
anchorPosition: AnchorPosition | undefined;
|
|
59
59
|
numOfBpSelected: number;
|