@jbrowse/plugin-alignments 4.0.4 → 4.1.3
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/esm/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
- package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -1
- package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +2 -2
- package/esm/LinearPileupDisplay/components/GroupByDialog.js +127 -93
- package/esm/LinearReadArcsDisplay/model.d.ts +5 -0
- package/esm/LinearReadCloudDisplay/components/LinearReadCloudReactComponent.js +6 -7
- package/esm/LinearReadCloudDisplay/model.d.ts +5 -2
- package/esm/LinearReadCloudDisplay/model.js +4 -11
- package/esm/LinearReadCloudDisplay/renderSvg.js +4 -5
- package/esm/LinearSNPCoverageDisplay/model.js +2 -2
- package/esm/PileupRenderer/makeImageData.js +3 -4
- package/esm/RenderLinearReadArcsDisplayRPC/drawFeatsRPC.d.ts +2 -1
- package/esm/RenderLinearReadArcsDisplayRPC/drawFeatsRPC.js +3 -4
- package/esm/RenderLinearReadArcsDisplayRPC/executeRenderLinearReadArcsDisplay.js +5 -4
- package/esm/RenderLinearReadCloudDisplayRPC/RenderLinearReadCloudDisplay.d.ts +0 -1
- package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCloud.d.ts +3 -4
- package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCloud.js +7 -20
- package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCommon.d.ts +2 -2
- package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCommon.js +3 -3
- package/esm/RenderLinearReadCloudDisplayRPC/drawLongReadChains.d.ts +3 -2
- package/esm/RenderLinearReadCloudDisplayRPC/drawLongReadChains.js +3 -4
- package/esm/RenderLinearReadCloudDisplayRPC/drawPairChains.d.ts +3 -2
- package/esm/RenderLinearReadCloudDisplayRPC/drawPairChains.js +4 -5
- package/esm/RenderLinearReadCloudDisplayRPC/executeRenderLinearReadCloudDisplay.js +7 -6
- package/esm/SNPCoverageRenderer/buildClickMap.d.ts +5 -0
- package/esm/SNPCoverageRenderer/buildClickMap.js +17 -0
- package/esm/SNPCoverageRenderer/calculateModificationCounts.d.ts +1 -19
- package/esm/SNPCoverageRenderer/calculateModificationCounts.js +1 -6
- package/esm/SNPCoverageRenderer/constants.d.ts +12 -0
- package/esm/SNPCoverageRenderer/constants.js +12 -0
- package/esm/SNPCoverageRenderer/createInterbaseItem.d.ts +7 -0
- package/esm/SNPCoverageRenderer/createInterbaseItem.js +13 -0
- package/esm/SNPCoverageRenderer/drawCrossHatches.d.ts +3 -0
- package/esm/SNPCoverageRenderer/drawCrossHatches.js +10 -0
- package/esm/SNPCoverageRenderer/drawNoncovEvents.d.ts +3 -0
- package/esm/SNPCoverageRenderer/drawNoncovEvents.js +56 -0
- package/esm/SNPCoverageRenderer/drawSecondPassMethylation.d.ts +2 -0
- package/esm/SNPCoverageRenderer/drawSecondPassMethylation.js +30 -0
- package/esm/SNPCoverageRenderer/drawSecondPassModifications.d.ts +6 -0
- package/esm/SNPCoverageRenderer/drawSecondPassModifications.js +85 -0
- package/esm/SNPCoverageRenderer/drawSecondPassSNPs.d.ts +2 -0
- package/esm/SNPCoverageRenderer/drawSecondPassSNPs.js +64 -0
- package/esm/SNPCoverageRenderer/drawStackedBars.d.ts +3 -0
- package/esm/SNPCoverageRenderer/drawStackedBars.js +10 -0
- package/esm/SNPCoverageRenderer/makeImage.d.ts +1 -1
- package/esm/SNPCoverageRenderer/makeImage.js +10 -306
- package/esm/SNPCoverageRenderer/types.d.ts +62 -1
- package/esm/shared/LinearReadDisplayBaseMixin.d.ts +5 -0
- package/esm/shared/createRPCRenderingSetup.d.ts +1 -0
- package/esm/shared/createRPCRenderingSetup.js +6 -1
- package/esm/shared/menuItems.js +3 -3
- package/package.json +10 -9
|
@@ -87,8 +87,8 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
87
87
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>, [undefined]>;
|
|
88
88
|
descriptions: import("@jbrowse/mobx-state-tree").IType<Record<string, unknown> | undefined, Record<string, unknown> | undefined, Record<string, unknown> | undefined>;
|
|
89
89
|
}>> & import("@jbrowse/mobx-state-tree/dist/internal").NonEmptyObject & import("@jbrowse/mobx-state-tree")._NotCustomized, {
|
|
90
|
-
id: string;
|
|
91
90
|
type: "BaseFeatureWidget";
|
|
91
|
+
id: string;
|
|
92
92
|
track: import("@jbrowse/mobx-state-tree").ReferenceIdentifier | undefined;
|
|
93
93
|
view: import("@jbrowse/mobx-state-tree").ReferenceIdentifier | undefined;
|
|
94
94
|
trackId: string | undefined;
|
|
@@ -14,7 +14,7 @@ export default class CramSlightlyLazyFeature implements Feature {
|
|
|
14
14
|
get flags(): number;
|
|
15
15
|
get strand(): 1 | -1;
|
|
16
16
|
get qual(): string;
|
|
17
|
-
get qualRaw():
|
|
17
|
+
get qualRaw(): Uint8Array<ArrayBufferLike> | null | undefined;
|
|
18
18
|
get refName(): string;
|
|
19
19
|
get pair_orientation(): string | null | undefined;
|
|
20
20
|
get template_length(): number | undefined;
|
|
@@ -5,7 +5,7 @@ import { SimpleFeature, getContainingTrack, getContainingView, getSession, isSes
|
|
|
5
5
|
import { getRpcSessionId } from '@jbrowse/core/util/tracks';
|
|
6
6
|
import { cast, isAlive, types } from '@jbrowse/mobx-state-tree';
|
|
7
7
|
import { BaseLinearDisplay } from '@jbrowse/plugin-linear-genome-view';
|
|
8
|
-
import
|
|
8
|
+
import ClearAllIcon from '@mui/icons-material/ClearAll';
|
|
9
9
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
|
10
10
|
import MenuOpenIcon from '@mui/icons-material/MenuOpen';
|
|
11
11
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
|
@@ -459,7 +459,7 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
|
|
|
459
459
|
},
|
|
460
460
|
{
|
|
461
461
|
label: 'Filter by...',
|
|
462
|
-
icon:
|
|
462
|
+
icon: ClearAllIcon,
|
|
463
463
|
onClick: () => {
|
|
464
464
|
getSession(self).queueDialog(handleClose => [
|
|
465
465
|
FilterByTagDialog,
|
|
@@ -1,27 +1,115 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Dialog, ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
4
4
|
import { getContainingTrack, getContainingView, getSession, useDebounce, } from '@jbrowse/core/util';
|
|
5
|
-
import { getSnapshot } from '@jbrowse/mobx-state-tree';
|
|
5
|
+
import { getSnapshot, isStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
6
6
|
import { Button, DialogActions, DialogContent, MenuItem, TextField, Typography, } from '@mui/material';
|
|
7
7
|
import { observer } from 'mobx-react';
|
|
8
8
|
import { getUniqueTags } from "../../shared/getUniqueTags.js";
|
|
9
9
|
import { defaultFilterFlags, negFlags, posFlags } from "../../shared/util.js";
|
|
10
|
+
const TAG_REGEX = /^[A-Za-z][A-Za-z0-9]$/;
|
|
11
|
+
function TagResults({ tag, tagSet }) {
|
|
12
|
+
if (tagSet.length === 0) {
|
|
13
|
+
return (_jsxs(Typography, { color: "warning.main", children: ["No values found for tag ", tag, " in the current region"] }));
|
|
14
|
+
}
|
|
15
|
+
return (_jsxs("div", { children: [_jsxs("div", { children: ["Found unique ", tag, " values:"] }), _jsx("div", { children: tagSet.join(', ') })] }));
|
|
16
|
+
}
|
|
17
|
+
function createTrackId(baseId, suffix) {
|
|
18
|
+
return `${baseId}-${suffix}-${Date.now()}-sessionTrack`;
|
|
19
|
+
}
|
|
20
|
+
function createTagBasedTracks({ trackConf, tag, tagSet, session, view, }) {
|
|
21
|
+
const values = [...tagSet, undefined];
|
|
22
|
+
for (const tagValue of values) {
|
|
23
|
+
const trackId = createTrackId(trackConf.trackId, `${tag}:${tagValue}`);
|
|
24
|
+
session.addTrackConf({
|
|
25
|
+
...trackConf,
|
|
26
|
+
trackId,
|
|
27
|
+
name: `${trackConf.name} (${tag}:${tagValue})`,
|
|
28
|
+
displays: [
|
|
29
|
+
{
|
|
30
|
+
displayId: `${trackId}-LinearAlignmentsDisplay`,
|
|
31
|
+
type: 'LinearAlignmentsDisplay',
|
|
32
|
+
pileupDisplay: {
|
|
33
|
+
displayId: `${trackId}-LinearAlignmentsDisplay-LinearPileupDisplay`,
|
|
34
|
+
type: 'LinearPileupDisplay',
|
|
35
|
+
filterBy: {
|
|
36
|
+
...defaultFilterFlags,
|
|
37
|
+
tagFilter: {
|
|
38
|
+
tag,
|
|
39
|
+
value: tagValue,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
view.showTrack(trackId);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function createStrandBasedTracks({ trackConf, session, view, }) {
|
|
50
|
+
const negTrackId = createTrackId(trackConf.trackId, 'strand:(-)');
|
|
51
|
+
const posTrackId = createTrackId(trackConf.trackId, 'strand:(+)');
|
|
52
|
+
session.addTrackConf({
|
|
53
|
+
...trackConf,
|
|
54
|
+
trackId: negTrackId,
|
|
55
|
+
name: `${trackConf.name} (-)`,
|
|
56
|
+
displays: [
|
|
57
|
+
{
|
|
58
|
+
displayId: `${negTrackId}-LinearAlignmentsDisplay`,
|
|
59
|
+
type: 'LinearAlignmentsDisplay',
|
|
60
|
+
pileupDisplay: {
|
|
61
|
+
displayId: `${negTrackId}-LinearAlignmentsDisplay-LinearPileupDisplay`,
|
|
62
|
+
type: 'LinearPileupDisplay',
|
|
63
|
+
filterBy: negFlags,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
displayId: `${negTrackId}-LinearSNPCoverageDisplay`,
|
|
68
|
+
type: 'LinearSNPCoverageDisplay',
|
|
69
|
+
filterBy: negFlags,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
session.addTrackConf({
|
|
74
|
+
...trackConf,
|
|
75
|
+
trackId: posTrackId,
|
|
76
|
+
name: `${trackConf.name} (+)`,
|
|
77
|
+
displays: [
|
|
78
|
+
{
|
|
79
|
+
displayId: `${posTrackId}-LinearAlignmentsDisplay`,
|
|
80
|
+
type: 'LinearAlignmentsDisplay',
|
|
81
|
+
pileupDisplay: {
|
|
82
|
+
displayId: `${posTrackId}-LinearAlignmentsDisplay-LinearPileupDisplay`,
|
|
83
|
+
type: 'LinearPileupDisplay',
|
|
84
|
+
filterBy: posFlags,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
displayId: `${posTrackId}-LinearSNPCoverageDisplay`,
|
|
89
|
+
type: 'LinearSNPCoverageDisplay',
|
|
90
|
+
filterBy: posFlags,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
});
|
|
94
|
+
view.showTrack(negTrackId);
|
|
95
|
+
view.showTrack(posTrackId);
|
|
96
|
+
}
|
|
10
97
|
const GroupByTagDialog = observer(function GroupByTagDialog(props) {
|
|
11
98
|
const { model, handleClose } = props;
|
|
12
99
|
const [tag, setGroupByTag] = useState('');
|
|
13
100
|
const [tagSet, setGroupByTagSet] = useState();
|
|
14
101
|
const [loading, setLoading] = useState(false);
|
|
15
102
|
const [error, setError] = useState();
|
|
16
|
-
const validTag =
|
|
103
|
+
const validTag = TAG_REGEX.exec(tag);
|
|
17
104
|
const isInvalid = tag.length === 2 && !validTag;
|
|
18
105
|
const debouncedTag = useDebounce(tag, 1000);
|
|
19
106
|
const [type, setType] = useState('');
|
|
20
107
|
useEffect(() => {
|
|
21
108
|
;
|
|
22
109
|
(async () => {
|
|
23
|
-
|
|
24
|
-
|
|
110
|
+
const isValidTag = TAG_REGEX.test(debouncedTag);
|
|
111
|
+
if (type === 'tag' && isValidTag) {
|
|
112
|
+
try {
|
|
25
113
|
setError(undefined);
|
|
26
114
|
setLoading(true);
|
|
27
115
|
const vals = await getUniqueTags({
|
|
@@ -32,16 +120,23 @@ const GroupByTagDialog = observer(function GroupByTagDialog(props) {
|
|
|
32
120
|
});
|
|
33
121
|
setGroupByTagSet(vals);
|
|
34
122
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
123
|
+
catch (e) {
|
|
124
|
+
console.error(e);
|
|
125
|
+
setError(e);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
setLoading(false);
|
|
129
|
+
}
|
|
42
130
|
}
|
|
43
131
|
})();
|
|
44
|
-
}, [model,
|
|
132
|
+
}, [model, type, debouncedTag]);
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (type !== 'tag') {
|
|
135
|
+
setGroupByTagSet(undefined);
|
|
136
|
+
setError(undefined);
|
|
137
|
+
setLoading(false);
|
|
138
|
+
}
|
|
139
|
+
}, [type]);
|
|
45
140
|
return (_jsxs(Dialog, { open: true, onClose: handleClose, title: "Group by", children: [_jsxs(DialogContent, { children: [_jsx(Typography, { children: "NOTE: this will create new session tracks with the \"filter by\" set to the values chosen here rather than affecting the current track state" }), _jsxs(TextField, { fullWidth: true, value: type, onChange: event => {
|
|
46
141
|
setType(event.target.value);
|
|
47
142
|
}, label: "Group by...", select: true, children: [_jsx(MenuItem, { value: "strand", children: "Strand" }), _jsx(MenuItem, { value: "tag", children: "Tag" })] }), type === 'tag' ? (_jsxs(_Fragment, { children: [_jsx(Typography, { color: "textSecondary", children: "Examples: HP for haplotype, RG for read group, etc." }), _jsx(TextField, { value: tag, onChange: event => {
|
|
@@ -51,93 +146,32 @@ const GroupByTagDialog = observer(function GroupByTagDialog(props) {
|
|
|
51
146
|
maxLength: 2,
|
|
52
147
|
'data-testid': 'group-tag-name-input',
|
|
53
148
|
},
|
|
54
|
-
} }), error ? (_jsx(ErrorMessage, { error: error })) : loading ? (_jsx(LoadingEllipses, { message: "Loading unique tags" })) : tagSet ? (
|
|
149
|
+
} }), error ? (_jsx(ErrorMessage, { error: error })) : loading ? (_jsx(LoadingEllipses, { message: "Loading unique tags" })) : tagSet ? (_jsx(TagResults, { tag: tag, tagSet: tagSet })) : null] })) : null] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", color: "primary", type: "submit", disabled: !type ||
|
|
150
|
+
loading ||
|
|
151
|
+
(type === 'tag' && (!tagSet || tagSet.length === 0)), autoFocus: true, onClick: () => {
|
|
55
152
|
const track = getContainingTrack(model);
|
|
56
|
-
const trackConf =
|
|
153
|
+
const trackConf = isStateTreeNode(track.configuration)
|
|
154
|
+
? structuredClone(getSnapshot(track.configuration))
|
|
155
|
+
: track.configuration;
|
|
57
156
|
const session = getSession(model);
|
|
58
157
|
const view = getContainingView(model);
|
|
59
|
-
if (type === 'tag') {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
name: `${trackConf.name} (${tag}:${tagValue})`,
|
|
68
|
-
displays: [
|
|
69
|
-
{
|
|
70
|
-
displayId: `${t1}-LinearAlignmentsDisplay`,
|
|
71
|
-
type: 'LinearAlignmentsDisplay',
|
|
72
|
-
pileupDisplay: {
|
|
73
|
-
displayId: `${t1}-LinearAlignmentsDisplay-LinearPileupDisplay`,
|
|
74
|
-
type: 'LinearPileupDisplay',
|
|
75
|
-
filterBy: {
|
|
76
|
-
...defaultFilterFlags,
|
|
77
|
-
tagFilter: {
|
|
78
|
-
tag,
|
|
79
|
-
value: tagValue,
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
});
|
|
86
|
-
view.showTrack(t1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
158
|
+
if (type === 'tag' && tagSet) {
|
|
159
|
+
createTagBasedTracks({
|
|
160
|
+
trackConf,
|
|
161
|
+
tag,
|
|
162
|
+
tagSet,
|
|
163
|
+
session,
|
|
164
|
+
view,
|
|
165
|
+
});
|
|
89
166
|
}
|
|
90
167
|
else if (type === 'strand') {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
trackId: t1,
|
|
96
|
-
name: `${trackConf.name} (-)`,
|
|
97
|
-
displays: [
|
|
98
|
-
{
|
|
99
|
-
displayId: `${t1}-LinearAlignmentsDisplay`,
|
|
100
|
-
type: 'LinearAlignmentsDisplay',
|
|
101
|
-
pileupDisplay: {
|
|
102
|
-
displayId: `${t1}-LinearAlignmentsDisplay-LinearPileupDisplay`,
|
|
103
|
-
type: 'LinearPileupDisplay',
|
|
104
|
-
filterBy: negFlags,
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
displayId: `${t1}-LinearSNPCoverageDisplay`,
|
|
109
|
-
type: 'LinearSNPCoverageDisplay',
|
|
110
|
-
filterBy: negFlags,
|
|
111
|
-
},
|
|
112
|
-
],
|
|
168
|
+
createStrandBasedTracks({
|
|
169
|
+
trackConf,
|
|
170
|
+
session,
|
|
171
|
+
view,
|
|
113
172
|
});
|
|
114
|
-
session.addTrackConf({
|
|
115
|
-
...trackConf,
|
|
116
|
-
trackId: t2,
|
|
117
|
-
name: `${trackConf.name} (+)`,
|
|
118
|
-
displays: [
|
|
119
|
-
{
|
|
120
|
-
displayId: `${t2}-LinearAlignmentsDisplay`,
|
|
121
|
-
type: 'LinearAlignmentsDisplay',
|
|
122
|
-
pileupDisplay: {
|
|
123
|
-
displayId: `${t2}-LinearAlignmentsDisplay-LinearPileupDisplay`,
|
|
124
|
-
type: 'LinearPileupDisplay',
|
|
125
|
-
filterBy: posFlags,
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
displayId: `${t2}-LinearSNPCoverageDisplay`,
|
|
130
|
-
type: 'LinearSNPCoverageDisplay',
|
|
131
|
-
filterBy: posFlags,
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
});
|
|
135
|
-
view.showTrack(t1);
|
|
136
|
-
view.showTrack(t2);
|
|
137
173
|
}
|
|
138
174
|
handleClose();
|
|
139
|
-
}, children: "Submit" }), _jsx(Button, { variant: "contained", color: "secondary", onClick:
|
|
140
|
-
handleClose();
|
|
141
|
-
}, children: "Cancel" })] })] }));
|
|
175
|
+
}, children: "Submit" }), _jsx(Button, { variant: "contained", color: "secondary", onClick: handleClose, children: "Cancel" })] })] }));
|
|
142
176
|
});
|
|
143
177
|
export default GroupByTagDialog;
|
|
@@ -233,19 +233,24 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
233
233
|
} & {
|
|
234
234
|
loading: boolean;
|
|
235
235
|
lastDrawnOffsetPx: number | undefined;
|
|
236
|
+
lastDrawnBpPerPx: number | undefined;
|
|
236
237
|
ref: HTMLCanvasElement | null;
|
|
237
238
|
renderingImageData: ImageBitmap | undefined;
|
|
238
239
|
renderingStopToken: import("@jbrowse/core/util").StopToken | undefined;
|
|
239
240
|
statusMessage: string | undefined;
|
|
241
|
+
canvasDrawn: boolean;
|
|
240
242
|
} & {
|
|
241
243
|
readonly drawn: boolean;
|
|
244
|
+
readonly fullyDrawn: boolean;
|
|
242
245
|
} & {
|
|
243
246
|
setLastDrawnOffsetPx(n: number): void;
|
|
247
|
+
setLastDrawnBpPerPx(n: number): void;
|
|
244
248
|
setLoading(f: boolean): void;
|
|
245
249
|
setRef(ref: HTMLCanvasElement | null): void;
|
|
246
250
|
setRenderingImageData(imageData: ImageBitmap | undefined): void;
|
|
247
251
|
setRenderingStopToken(token?: import("@jbrowse/core/util").StopToken): void;
|
|
248
252
|
setStatusMessage(msg?: string): void;
|
|
253
|
+
setCanvasDrawn(drawn: boolean): void;
|
|
249
254
|
} & {
|
|
250
255
|
beforeDestroy(): void;
|
|
251
256
|
} & {
|
|
@@ -236,17 +236,16 @@ const Cloud = observer(function Cloud({ model, }) {
|
|
|
236
236
|
width,
|
|
237
237
|
height,
|
|
238
238
|
cursor: hasHover ? 'pointer' : undefined,
|
|
239
|
-
}, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onClick: onClick, children: [_jsx(CloudCanvases, { model: model, width: width, height: height }), _jsx(FeatureHighlights, { selectedFeatureBounds: selectedFeatureBounds, hoveredFeature: hoveredFeature }),
|
|
239
|
+
}, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onClick: onClick, children: [_jsx(CloudCanvases, { model: model, width: width, height: height }), _jsx(FeatureHighlights, { selectedFeatureBounds: selectedFeatureBounds, hoveredFeature: hoveredFeature }), hoveredMismatchData && mousePosition ? (_jsx(MismatchTooltip, { mismatchData: hoveredMismatchData, mousePosition: mousePosition })) : hoveredFeatureData && mousePosition ? (_jsx(FeatureTooltip, { hoveredFeatureData: hoveredFeatureData, hasSupplementary: hoveredHasSupplementary, mousePosition: mousePosition })) : null] }));
|
|
240
|
+
});
|
|
241
|
+
const LinearReadCloudReactComponent = observer(function LinearReadCloudReactComponent({ model, }) {
|
|
242
|
+
return (_jsxs("div", { children: [_jsx(BaseDisplayComponent, { model: model, children: _jsx(Cloud, { model: model }) }), model.drawCloud && model.cloudTicks ? (_jsx("svg", { style: {
|
|
240
243
|
position: 'absolute',
|
|
241
244
|
top: 0,
|
|
242
245
|
left: 50,
|
|
243
246
|
pointerEvents: 'none',
|
|
244
247
|
height: model.cloudTicks.height,
|
|
245
|
-
width:
|
|
246
|
-
|
|
247
|
-
}, children: _jsx("g", { transform: "translate(55, 0)", children: _jsx(CloudYScaleBar, { model: model, orientation: "left" }) }) })) : null, hoveredMismatchData && mousePosition ? (_jsx(MismatchTooltip, { mismatchData: hoveredMismatchData, mousePosition: mousePosition })) : hoveredFeatureData && mousePosition ? (_jsx(FeatureTooltip, { hoveredFeatureData: hoveredFeatureData, hasSupplementary: hoveredHasSupplementary, mousePosition: mousePosition })) : null] }));
|
|
248
|
-
});
|
|
249
|
-
const LinearReadCloudReactComponent = observer(function LinearReadCloudReactComponent({ model, }) {
|
|
250
|
-
return (_jsx(BaseDisplayComponent, { model: model, children: _jsx(Cloud, { model: model }) }));
|
|
248
|
+
width: 50,
|
|
249
|
+
}, children: _jsx("g", { transform: "translate(45, 0)", children: _jsx(CloudYScaleBar, { model: model, orientation: "left" }) }) })) : null] }));
|
|
251
250
|
});
|
|
252
251
|
export default LinearReadCloudReactComponent;
|
|
@@ -242,19 +242,24 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
242
242
|
} & {
|
|
243
243
|
loading: boolean;
|
|
244
244
|
lastDrawnOffsetPx: number | undefined;
|
|
245
|
+
lastDrawnBpPerPx: number | undefined;
|
|
245
246
|
ref: HTMLCanvasElement | null;
|
|
246
247
|
renderingImageData: ImageBitmap | undefined;
|
|
247
248
|
renderingStopToken: import("@jbrowse/core/util").StopToken | undefined;
|
|
248
249
|
statusMessage: string | undefined;
|
|
250
|
+
canvasDrawn: boolean;
|
|
249
251
|
} & {
|
|
250
252
|
readonly drawn: boolean;
|
|
253
|
+
readonly fullyDrawn: boolean;
|
|
251
254
|
} & {
|
|
252
255
|
setLastDrawnOffsetPx(n: number): void;
|
|
256
|
+
setLastDrawnBpPerPx(n: number): void;
|
|
253
257
|
setLoading(f: boolean): void;
|
|
254
258
|
setRef(ref: HTMLCanvasElement | null): void;
|
|
255
259
|
setRenderingImageData(imageData: ImageBitmap | undefined): void;
|
|
256
260
|
setRenderingStopToken(token?: import("@jbrowse/core/util").StopToken): void;
|
|
257
261
|
setStatusMessage(msg?: string): void;
|
|
262
|
+
setCanvasDrawn(drawn: boolean): void;
|
|
258
263
|
} & {
|
|
259
264
|
beforeDestroy(): void;
|
|
260
265
|
} & {
|
|
@@ -311,8 +316,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
|
|
|
311
316
|
readonly hideLargeIndels: any;
|
|
312
317
|
} & {
|
|
313
318
|
readonly modificationThreshold: any;
|
|
314
|
-
readonly cloudDomain: [number, number] | undefined;
|
|
315
|
-
} & {
|
|
316
319
|
readonly cloudTicks: import("../RenderLinearReadCloudDisplayRPC/drawFeatsCloud.ts").CloudTicks | undefined;
|
|
317
320
|
} & {
|
|
318
321
|
setNoSpacing(flag?: boolean): void;
|
|
@@ -68,19 +68,13 @@ function stateModelFactory(configSchema) {
|
|
|
68
68
|
get modificationThreshold() {
|
|
69
69
|
return self.colorBy?.modifications?.threshold ?? 10;
|
|
70
70
|
},
|
|
71
|
-
get cloudDomain() {
|
|
72
|
-
if (self.cloudMaxDistance === undefined) {
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
75
|
-
return [1, self.cloudMaxDistance];
|
|
76
|
-
},
|
|
77
|
-
}))
|
|
78
|
-
.views(self => ({
|
|
79
71
|
get cloudTicks() {
|
|
80
|
-
if (!self.drawCloud ||
|
|
72
|
+
if (!self.drawCloud ||
|
|
73
|
+
self.cloudMaxDistance === undefined ||
|
|
74
|
+
!self.showYScalebar) {
|
|
81
75
|
return undefined;
|
|
82
76
|
}
|
|
83
|
-
return calculateCloudTicks(self.
|
|
77
|
+
return calculateCloudTicks(self.cloudMaxDistance, self.height);
|
|
84
78
|
},
|
|
85
79
|
}))
|
|
86
80
|
.actions(self => ({
|
|
@@ -166,7 +160,6 @@ function stateModelFactory(configSchema) {
|
|
|
166
160
|
hideMismatches: self.hideMismatches,
|
|
167
161
|
hideLargeIndels: self.hideLargeIndels,
|
|
168
162
|
showOutline: self.showOutline,
|
|
169
|
-
cloudDomain: self.cloudDomain,
|
|
170
163
|
visibleModifications: Object.fromEntries(self.visibleModifications.toJSON()),
|
|
171
164
|
};
|
|
172
165
|
},
|
|
@@ -37,11 +37,10 @@ export async function renderSvg(self, opts) {
|
|
|
37
37
|
const visibleWidth = view.width;
|
|
38
38
|
const clipId = `clip-${self.id}-svg`;
|
|
39
39
|
const legendItems = self.showLegend ? self.legendItems() : [];
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
? calculateCloudTicks(cloudDomain, height)
|
|
40
|
+
const cloudTicks = rendering.cloudMaxDistance !== undefined &&
|
|
41
|
+
self.drawCloud &&
|
|
42
|
+
self.showYScalebar
|
|
43
|
+
? calculateCloudTicks(rendering.cloudMaxDistance, height)
|
|
45
44
|
: null;
|
|
46
45
|
return (_jsxs(_Fragment, { children: [_jsx("defs", { children: _jsx("clipPath", { id: clipId, children: _jsx("rect", { x: 0, y: 0, width: visibleWidth, height: height }) }) }), _jsx("g", { clipPath: `url(#${clipId})`, children: _jsx("g", { transform: `translate(${Math.max(0, -view.offsetPx)} 0)`, children: _jsx(ReactRendering, { rendering: finalRendering }) }) }), cloudTicks ? (_jsx("g", { transform: `translate(${Math.max(-view.offsetPx, 0)})`, children: _jsx(CloudYScaleBar, { model: { cloudTicks }, orientation: "left" }) })) : null, legendItems.length > 0 ? (_jsx(SVGLegend, { items: legendItems, width: visibleWidth, legendAreaWidth: opts.legendWidth })) : null] }));
|
|
47
46
|
}
|
|
@@ -4,7 +4,7 @@ import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/rendere
|
|
|
4
4
|
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
5
5
|
import { cast, getSnapshot, isAlive, types } from '@jbrowse/mobx-state-tree';
|
|
6
6
|
import { linearWiggleDisplayModelFactory } from '@jbrowse/plugin-wiggle';
|
|
7
|
-
import
|
|
7
|
+
import ClearAllIcon from '@mui/icons-material/ClearAll';
|
|
8
8
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
|
9
9
|
import { SharedModificationsMixin } from "../shared/SharedModificationsMixin.js";
|
|
10
10
|
import { getUniqueModifications } from "../shared/getUniqueModifications.js";
|
|
@@ -268,7 +268,7 @@ function stateModelFactory(pluginManager, configSchema) {
|
|
|
268
268
|
},
|
|
269
269
|
{
|
|
270
270
|
label: 'Filter arcs by score...',
|
|
271
|
-
icon:
|
|
271
|
+
icon: ClearAllIcon,
|
|
272
272
|
onClick: () => {
|
|
273
273
|
getSession(self).queueDialog(handleClose => [
|
|
274
274
|
FilterArcsByScoreDialog,
|
|
@@ -3,7 +3,7 @@ import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
|
|
|
3
3
|
import { createJBrowseTheme } from '@jbrowse/core/ui';
|
|
4
4
|
import { renderToAbstractCanvas } from '@jbrowse/core/util';
|
|
5
5
|
import Flatbush from '@jbrowse/core/util/flatbush';
|
|
6
|
-
import { checkStopToken2
|
|
6
|
+
import { checkStopToken2 } from '@jbrowse/core/util/stopToken';
|
|
7
7
|
import { layoutFeats } from "./layoutFeatures.js";
|
|
8
8
|
import { renderAlignment } from "./renderers/renderAlignment.js";
|
|
9
9
|
import { renderMismatchesCallback } from "./renderers/renderMismatchesCallback.js";
|
|
@@ -29,7 +29,7 @@ async function fetchRegionSequence(renderArgs, pluginManager) {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
function renderFeatures({ ctx, layoutRecords, canvasWidth, renderArgs, }) {
|
|
32
|
-
const {
|
|
32
|
+
const { stopTokenCheck, config, showSoftClip, colorBy, theme: configTheme, } = renderArgs;
|
|
33
33
|
const mismatchAlpha = readConfObject(config, 'mismatchAlpha');
|
|
34
34
|
const minSubfeatureWidth = readConfObject(config, 'minSubfeatureWidth');
|
|
35
35
|
const largeInsertionIndicatorScale = readConfObject(config, 'largeInsertionIndicatorScale');
|
|
@@ -46,7 +46,6 @@ function renderFeatures({ ctx, layoutRecords, canvasWidth, renderArgs, }) {
|
|
|
46
46
|
const drawIndels = shouldDrawIndels();
|
|
47
47
|
const coords = [];
|
|
48
48
|
const items = [];
|
|
49
|
-
const lastCheck = createStopTokenChecker(stopToken);
|
|
50
49
|
for (const feat of layoutRecords) {
|
|
51
50
|
const alignmentRet = renderAlignment({
|
|
52
51
|
ctx,
|
|
@@ -101,7 +100,7 @@ function renderFeatures({ ctx, layoutRecords, canvasWidth, renderArgs, }) {
|
|
|
101
100
|
canvasWidth,
|
|
102
101
|
});
|
|
103
102
|
}
|
|
104
|
-
checkStopToken2(
|
|
103
|
+
checkStopToken2(stopTokenCheck);
|
|
105
104
|
}
|
|
106
105
|
const flatbush = new Flatbush(Math.max(items.length, 1));
|
|
107
106
|
if (coords.length) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ChainData, ColorBy } from '../shared/types.ts';
|
|
2
|
+
import type { LastStopTokenCheck } from '@jbrowse/core/util';
|
|
2
3
|
interface DrawFeatsRPCParams {
|
|
3
4
|
ctx: CanvasRenderingContext2D;
|
|
4
5
|
width: number;
|
|
@@ -18,7 +19,7 @@ interface DrawFeatsRPCParams {
|
|
|
18
19
|
} | undefined;
|
|
19
20
|
};
|
|
20
21
|
offsetPx: number;
|
|
21
|
-
|
|
22
|
+
stopTokenCheck?: LastStopTokenCheck;
|
|
22
23
|
}
|
|
23
24
|
export declare function drawFeatsRPC(params: DrawFeatsRPCParams): void;
|
|
24
25
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { checkStopToken2
|
|
1
|
+
import { checkStopToken2 } from '@jbrowse/core/util/stopToken';
|
|
2
2
|
import { featurizeSA, getTag } from "../MismatchParser/index.js";
|
|
3
3
|
import { drawVerticalLine, extractCoreFeat, extractCoreFeatBasic, filterAndSortLongReadChain, filterPairedChain, getMateInfo, getStrandRelativeFirstClipLength, jitter, toCoreFeat, toCoreFeatBasic, } from "../shared/arcUtils.js";
|
|
4
4
|
import { getPairedInsertSizeAndOrientationColor, getPairedInsertSizeColor, getPairedOrientationColor, } from "../shared/color.js";
|
|
@@ -63,7 +63,7 @@ function drawBezierArc(ctx, startX, endX, destY, jitterVal) {
|
|
|
63
63
|
ctx.stroke();
|
|
64
64
|
}
|
|
65
65
|
export function drawFeatsRPC(params) {
|
|
66
|
-
const { ctx, height, chainData, colorBy, drawInter, drawLongRange, lineWidth, jitter: jitterVal, view, offsetPx,
|
|
66
|
+
const { ctx, height, chainData, colorBy, drawInter, drawLongRange, lineWidth, jitter: jitterVal, view, offsetPx, stopTokenCheck, } = params;
|
|
67
67
|
const { chains, stats } = chainData;
|
|
68
68
|
const colorByType = colorBy.type;
|
|
69
69
|
const hasPaired = hasPairedReads(chainData);
|
|
@@ -136,7 +136,6 @@ export function drawFeatsRPC(params) {
|
|
|
136
136
|
draw(extractCoreFeat(filtered[i]), extractCoreFeatBasic(filtered[i + 1]), false);
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
const lastCheck = createStopTokenChecker(stopToken);
|
|
140
139
|
for (const chain of chains) {
|
|
141
140
|
if (chain.length === 1 && drawLongRange) {
|
|
142
141
|
const f = chain[0];
|
|
@@ -151,6 +150,6 @@ export function drawFeatsRPC(params) {
|
|
|
151
150
|
else {
|
|
152
151
|
drawMultiFeatureChain(chain);
|
|
153
152
|
}
|
|
154
|
-
checkStopToken2(
|
|
153
|
+
checkStopToken2(stopTokenCheck);
|
|
155
154
|
}
|
|
156
155
|
}
|
|
@@ -3,7 +3,7 @@ import { collectTransferables, dedupe, groupBy, max, min, renderToAbstractCanvas
|
|
|
3
3
|
import { bpToPx } from '@jbrowse/core/util/Base1DUtils';
|
|
4
4
|
import Base1DView from '@jbrowse/core/util/Base1DViewModel';
|
|
5
5
|
import { rpcResult } from '@jbrowse/core/util/librpc';
|
|
6
|
-
import {
|
|
6
|
+
import { checkStopToken2, createStopTokenChecker, } from '@jbrowse/core/util/stopToken';
|
|
7
7
|
import { getSnapshot } from '@jbrowse/mobx-state-tree';
|
|
8
8
|
import { firstValueFrom } from 'rxjs';
|
|
9
9
|
import { toArray } from 'rxjs/operators';
|
|
@@ -11,6 +11,7 @@ import { drawFeatsRPC } from "./drawFeatsRPC.js";
|
|
|
11
11
|
import { getInsertSizeStats } from "../shared/insertSizeStats.js";
|
|
12
12
|
export async function executeRenderLinearReadArcsDisplay({ pluginManager, args, }) {
|
|
13
13
|
const { sessionId, view: viewSnapshot, adapterConfig, sequenceAdapter, colorBy, drawInter, drawLongRange, lineWidth, jitter, height, highResolutionScaling, exportSVG, statusCallback = () => { }, stopToken, } = args;
|
|
14
|
+
const stopTokenCheck = createStopTokenChecker(stopToken);
|
|
14
15
|
const view = Base1DView.create(viewSnapshot);
|
|
15
16
|
if (viewSnapshot.width) {
|
|
16
17
|
view.setVolatileWidth(viewSnapshot.width);
|
|
@@ -39,7 +40,7 @@ export async function executeRenderLinearReadArcsDisplay({ pluginManager, args,
|
|
|
39
40
|
dataAdapter.setSequenceAdapterConfig(sequenceAdapter);
|
|
40
41
|
}
|
|
41
42
|
const featuresArray = await updateStatus('Fetching alignments', statusCallback, () => firstValueFrom(dataAdapter.getFeaturesInMultipleRegions(regions, args).pipe(toArray())));
|
|
42
|
-
|
|
43
|
+
checkStopToken2(stopTokenCheck);
|
|
43
44
|
const { chains, stats } = await updateStatus('Processing alignments', statusCallback, async () => {
|
|
44
45
|
const deduped = dedupe(featuresArray, f => f.id());
|
|
45
46
|
const filtered = deduped.filter(f => {
|
|
@@ -78,7 +79,7 @@ export async function executeRenderLinearReadArcsDisplay({ pluginManager, args,
|
|
|
78
79
|
chains,
|
|
79
80
|
stats,
|
|
80
81
|
};
|
|
81
|
-
|
|
82
|
+
checkStopToken2(stopTokenCheck);
|
|
82
83
|
const renderOpts = {
|
|
83
84
|
highResolutionScaling,
|
|
84
85
|
exportSVG,
|
|
@@ -96,7 +97,7 @@ export async function executeRenderLinearReadArcsDisplay({ pluginManager, args,
|
|
|
96
97
|
jitter,
|
|
97
98
|
view: viewSnap,
|
|
98
99
|
offsetPx,
|
|
99
|
-
|
|
100
|
+
stopTokenCheck,
|
|
100
101
|
});
|
|
101
102
|
return undefined;
|
|
102
103
|
}));
|
|
@@ -20,7 +20,6 @@ export interface RenderLinearReadCloudDisplayArgs {
|
|
|
20
20
|
flipStrandLongReadChains: boolean;
|
|
21
21
|
trackMaxHeight?: number;
|
|
22
22
|
cloudModeHeight?: number;
|
|
23
|
-
cloudDomain?: [number, number];
|
|
24
23
|
highResolutionScaling?: number;
|
|
25
24
|
exportSVG?: {
|
|
26
25
|
rasterizeLayers?: boolean;
|
|
@@ -6,12 +6,11 @@ export interface CloudTicks {
|
|
|
6
6
|
y: number;
|
|
7
7
|
}[];
|
|
8
8
|
height: number;
|
|
9
|
-
minDistance: number;
|
|
10
9
|
maxDistance: number;
|
|
11
10
|
}
|
|
12
|
-
export declare function createCloudScale(
|
|
13
|
-
export declare function calculateCloudTicks(
|
|
14
|
-
export declare function calculateCloudYOffsetsUtil(computedChains: ComputedChain[], height: number
|
|
11
|
+
export declare function createCloudScale(maxDistance: number, height: number): import("d3-scale").ScaleLogarithmic<number, number, never>;
|
|
12
|
+
export declare function calculateCloudTicks(maxDistance: number, height: number): CloudTicks;
|
|
13
|
+
export declare function calculateCloudYOffsetsUtil(computedChains: ComputedChain[], height: number): {
|
|
15
14
|
chainYOffsets: Map<string, number>;
|
|
16
15
|
cloudMaxDistance: number;
|
|
17
16
|
};
|