@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.
Files changed (52) hide show
  1. package/esm/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
  2. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -1
  3. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +2 -2
  4. package/esm/LinearPileupDisplay/components/GroupByDialog.js +127 -93
  5. package/esm/LinearReadArcsDisplay/model.d.ts +5 -0
  6. package/esm/LinearReadCloudDisplay/components/LinearReadCloudReactComponent.js +6 -7
  7. package/esm/LinearReadCloudDisplay/model.d.ts +5 -2
  8. package/esm/LinearReadCloudDisplay/model.js +4 -11
  9. package/esm/LinearReadCloudDisplay/renderSvg.js +4 -5
  10. package/esm/LinearSNPCoverageDisplay/model.js +2 -2
  11. package/esm/PileupRenderer/makeImageData.js +3 -4
  12. package/esm/RenderLinearReadArcsDisplayRPC/drawFeatsRPC.d.ts +2 -1
  13. package/esm/RenderLinearReadArcsDisplayRPC/drawFeatsRPC.js +3 -4
  14. package/esm/RenderLinearReadArcsDisplayRPC/executeRenderLinearReadArcsDisplay.js +5 -4
  15. package/esm/RenderLinearReadCloudDisplayRPC/RenderLinearReadCloudDisplay.d.ts +0 -1
  16. package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCloud.d.ts +3 -4
  17. package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCloud.js +7 -20
  18. package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCommon.d.ts +2 -2
  19. package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCommon.js +3 -3
  20. package/esm/RenderLinearReadCloudDisplayRPC/drawLongReadChains.d.ts +3 -2
  21. package/esm/RenderLinearReadCloudDisplayRPC/drawLongReadChains.js +3 -4
  22. package/esm/RenderLinearReadCloudDisplayRPC/drawPairChains.d.ts +3 -2
  23. package/esm/RenderLinearReadCloudDisplayRPC/drawPairChains.js +4 -5
  24. package/esm/RenderLinearReadCloudDisplayRPC/executeRenderLinearReadCloudDisplay.js +7 -6
  25. package/esm/SNPCoverageRenderer/buildClickMap.d.ts +5 -0
  26. package/esm/SNPCoverageRenderer/buildClickMap.js +17 -0
  27. package/esm/SNPCoverageRenderer/calculateModificationCounts.d.ts +1 -19
  28. package/esm/SNPCoverageRenderer/calculateModificationCounts.js +1 -6
  29. package/esm/SNPCoverageRenderer/constants.d.ts +12 -0
  30. package/esm/SNPCoverageRenderer/constants.js +12 -0
  31. package/esm/SNPCoverageRenderer/createInterbaseItem.d.ts +7 -0
  32. package/esm/SNPCoverageRenderer/createInterbaseItem.js +13 -0
  33. package/esm/SNPCoverageRenderer/drawCrossHatches.d.ts +3 -0
  34. package/esm/SNPCoverageRenderer/drawCrossHatches.js +10 -0
  35. package/esm/SNPCoverageRenderer/drawNoncovEvents.d.ts +3 -0
  36. package/esm/SNPCoverageRenderer/drawNoncovEvents.js +56 -0
  37. package/esm/SNPCoverageRenderer/drawSecondPassMethylation.d.ts +2 -0
  38. package/esm/SNPCoverageRenderer/drawSecondPassMethylation.js +30 -0
  39. package/esm/SNPCoverageRenderer/drawSecondPassModifications.d.ts +6 -0
  40. package/esm/SNPCoverageRenderer/drawSecondPassModifications.js +85 -0
  41. package/esm/SNPCoverageRenderer/drawSecondPassSNPs.d.ts +2 -0
  42. package/esm/SNPCoverageRenderer/drawSecondPassSNPs.js +64 -0
  43. package/esm/SNPCoverageRenderer/drawStackedBars.d.ts +3 -0
  44. package/esm/SNPCoverageRenderer/drawStackedBars.js +10 -0
  45. package/esm/SNPCoverageRenderer/makeImage.d.ts +1 -1
  46. package/esm/SNPCoverageRenderer/makeImage.js +10 -306
  47. package/esm/SNPCoverageRenderer/types.d.ts +62 -1
  48. package/esm/shared/LinearReadDisplayBaseMixin.d.ts +5 -0
  49. package/esm/shared/createRPCRenderingSetup.d.ts +1 -0
  50. package/esm/shared/createRPCRenderingSetup.js +6 -1
  51. package/esm/shared/menuItems.js +3 -3
  52. 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(): number[] | null | undefined;
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 FilterListIcon from '@mui/icons-material/ClearAll';
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: FilterListIcon,
462
+ icon: ClearAllIcon,
463
463
  onClick: () => {
464
464
  getSession(self).queueDialog(handleClose => [
465
465
  FilterByTagDialog,
@@ -1,27 +1,115 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
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 = /^[A-Za-z][A-Za-z0-9]$/.exec(tag);
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
- try {
24
- if (!isInvalid) {
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
- catch (e) {
37
- console.error(e);
38
- setError(e);
39
- }
40
- finally {
41
- setLoading(false);
123
+ catch (e) {
124
+ console.error(e);
125
+ setError(e);
126
+ }
127
+ finally {
128
+ setLoading(false);
129
+ }
42
130
  }
43
131
  })();
44
- }, [model, isInvalid, debouncedTag]);
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 ? (_jsxs("div", { children: [_jsxs("div", { children: ["Found unique ", tag, " values:"] }), _jsx("div", { children: tagSet.join(', ') })] })) : null] })) : null] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", color: "primary", type: "submit", disabled: !tagSet, autoFocus: true, onClick: () => {
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 = structuredClone(getSnapshot(track.configuration));
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
- if (tagSet) {
61
- const ret = [...tagSet, undefined];
62
- for (const tagValue of ret) {
63
- const t1 = `${trackConf.trackId}-${tag}:${tagValue}-${Date.now()}-sessionTrack`;
64
- session.addTrackConf({
65
- ...trackConf,
66
- trackId: t1,
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
- const t1 = `${trackConf.trackId}-${tag}:(-)-${Date.now()}-sessionTrack`;
92
- const t2 = `${trackConf.trackId}-${tag}:(+)-${Date.now()}-sessionTrack`;
93
- session.addTrackConf({
94
- ...trackConf,
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 }), model.drawCloud && model.cloudTicks ? (_jsx("svg", { style: {
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: 60,
246
- zIndex: 100,
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 || !self.cloudDomain || !self.showYScalebar) {
72
+ if (!self.drawCloud ||
73
+ self.cloudMaxDistance === undefined ||
74
+ !self.showYScalebar) {
81
75
  return undefined;
82
76
  }
83
- return calculateCloudTicks(self.cloudDomain, self.height);
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 cloudDomain = rendering.cloudMaxDistance !== undefined && self.drawCloud
41
- ? [1, rendering.cloudMaxDistance]
42
- : null;
43
- const cloudTicks = cloudDomain && self.showYScalebar
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 FilterListIcon from '@mui/icons-material/FilterList';
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: FilterListIcon,
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, createStopTokenChecker, } from '@jbrowse/core/util/stopToken';
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 { stopToken, config, showSoftClip, colorBy, theme: configTheme, } = renderArgs;
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(lastCheck);
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
- stopToken?: string;
22
+ stopTokenCheck?: LastStopTokenCheck;
22
23
  }
23
24
  export declare function drawFeatsRPC(params: DrawFeatsRPCParams): void;
24
25
  export {};
@@ -1,4 +1,4 @@
1
- import { checkStopToken2, createStopTokenChecker, } from '@jbrowse/core/util/stopToken';
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, stopToken, } = params;
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(lastCheck);
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 { checkStopToken } from '@jbrowse/core/util/stopToken';
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
- checkStopToken(stopToken);
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
- checkStopToken(stopToken);
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
- stopToken,
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(minDistance: number, maxDistance: number, height: number): import("d3-scale").ScaleLogarithmic<number, number, never>;
13
- export declare function calculateCloudTicks(domain: [number, number], height: number): CloudTicks;
14
- export declare function calculateCloudYOffsetsUtil(computedChains: ComputedChain[], height: number, cloudDomain?: [number, 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
  };