@jbrowse/plugin-alignments 4.0.3 → 4.1.1

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 (27) hide show
  1. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -1
  2. package/esm/LinearAlignmentsDisplay/model.d.ts +3 -0
  3. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +20 -1
  4. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +24 -16
  5. package/esm/LinearPileupDisplay/components/GroupByDialog.js +127 -93
  6. package/esm/LinearPileupDisplay/doAfterAttach.js +3 -3
  7. package/esm/LinearPileupDisplay/model.d.ts +29 -2
  8. package/esm/LinearPileupDisplay/model.js +11 -13
  9. package/esm/LinearPileupDisplay/sharedDoAfterAttach.js +1 -1
  10. package/esm/LinearReadArcsDisplay/model.d.ts +8 -0
  11. package/esm/LinearReadCloudDisplay/components/LinearReadCloudReactComponent.js +6 -7
  12. package/esm/LinearReadCloudDisplay/model.d.ts +8 -2
  13. package/esm/LinearReadCloudDisplay/model.js +4 -11
  14. package/esm/LinearReadCloudDisplay/renderSvg.js +4 -5
  15. package/esm/LinearSNPCoverageDisplay/model.js +11 -12
  16. package/esm/RenderLinearReadCloudDisplayRPC/RenderLinearReadCloudDisplay.d.ts +0 -1
  17. package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCloud.d.ts +3 -4
  18. package/esm/RenderLinearReadCloudDisplayRPC/drawFeatsCloud.js +7 -20
  19. package/esm/RenderLinearReadCloudDisplayRPC/executeRenderLinearReadCloudDisplay.js +2 -2
  20. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +6 -2
  21. package/esm/SNPCoverageAdapter/generateCoverageBinsPrefixSum.js +1 -1
  22. package/esm/shared/LinearReadDisplayBaseMixin.d.ts +5 -0
  23. package/esm/shared/createRPCRenderingSetup.d.ts +1 -0
  24. package/esm/shared/createRPCRenderingSetup.js +17 -7
  25. package/esm/shared/menuItems.js +3 -3
  26. package/esm/shared/types.d.ts +0 -1
  27. package/package.json +10 -9
@@ -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;
@@ -64,6 +64,7 @@ declare function stateModelFactory(pluginManager: PluginManager, configSchema: A
64
64
  }> | null;
65
65
  readonly adapterConfig: any;
66
66
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
67
+ readonly isMinimized: boolean;
67
68
  readonly parentDisplay: any;
68
69
  readonly effectiveRpcDriverName: any;
69
70
  } & {
@@ -120,6 +121,7 @@ declare function stateModelFactory(pluginManager: PluginManager, configSchema: A
120
121
  }> | null;
121
122
  readonly adapterConfig: any;
122
123
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
124
+ readonly isMinimized: boolean;
123
125
  readonly parentDisplay: any;
124
126
  readonly effectiveRpcDriverName: any;
125
127
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -173,6 +175,7 @@ declare function stateModelFactory(pluginManager: PluginManager, configSchema: A
173
175
  }> | null;
174
176
  readonly adapterConfig: any;
175
177
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
178
+ readonly isMinimized: boolean;
176
179
  readonly parentDisplay: any;
177
180
  readonly effectiveRpcDriverName: any;
178
181
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -148,6 +148,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
148
148
  }> | null;
149
149
  readonly adapterConfig: any;
150
150
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
151
+ readonly isMinimized: boolean;
151
152
  readonly parentDisplay: any;
152
153
  readonly effectiveRpcDriverName: any;
153
154
  } & {
@@ -204,6 +205,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
204
205
  }> | null;
205
206
  readonly adapterConfig: any;
206
207
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
208
+ readonly isMinimized: boolean;
207
209
  readonly parentDisplay: any;
208
210
  readonly effectiveRpcDriverName: any;
209
211
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -257,6 +259,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
257
259
  }> | null;
258
260
  readonly adapterConfig: any;
259
261
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
262
+ readonly isMinimized: boolean;
260
263
  readonly parentDisplay: any;
261
264
  readonly effectiveRpcDriverName: any;
262
265
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -538,6 +541,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
538
541
  }> | null;
539
542
  readonly adapterConfig: any;
540
543
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
544
+ readonly isMinimized: boolean;
541
545
  readonly parentDisplay: any;
542
546
  readonly effectiveRpcDriverName: any;
543
547
  } & {
@@ -594,6 +598,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
594
598
  }> | null;
595
599
  readonly adapterConfig: any;
596
600
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
601
+ readonly isMinimized: boolean;
597
602
  readonly parentDisplay: any;
598
603
  readonly effectiveRpcDriverName: any;
599
604
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -647,6 +652,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
647
652
  }> | null;
648
653
  readonly adapterConfig: any;
649
654
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
655
+ readonly isMinimized: boolean;
650
656
  readonly parentDisplay: any;
651
657
  readonly effectiveRpcDriverName: any;
652
658
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -873,6 +879,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
873
879
  }> | null;
874
880
  readonly adapterConfig: any;
875
881
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
882
+ readonly isMinimized: boolean;
876
883
  readonly parentDisplay: any;
877
884
  readonly effectiveRpcDriverName: any;
878
885
  } & {
@@ -929,6 +936,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
929
936
  }> | null;
930
937
  readonly adapterConfig: any;
931
938
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
939
+ readonly isMinimized: boolean;
932
940
  readonly parentDisplay: any;
933
941
  readonly effectiveRpcDriverName: any;
934
942
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -982,6 +990,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
982
990
  }> | null;
983
991
  readonly adapterConfig: any;
984
992
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
993
+ readonly isMinimized: boolean;
985
994
  readonly parentDisplay: any;
986
995
  readonly effectiveRpcDriverName: any;
987
996
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -1114,10 +1123,18 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
1114
1123
  setHideLargeIndels(arg: boolean): void;
1115
1124
  } & {
1116
1125
  copyFeatureToClipboard(feature: Feature): Promise<void>;
1117
- readonly rendererConfig: any;
1126
+ readonly rendererConfig: {
1127
+ height: any;
1128
+ noSpacing: any;
1129
+ maxHeight: any;
1130
+ hideSmallIndels: any;
1131
+ hideMismatches: any;
1132
+ hideLargeIndels: any;
1133
+ };
1118
1134
  } & {
1119
1135
  readonly maxHeight: any;
1120
1136
  readonly featureHeightSetting: any;
1137
+ readonly noSpacingSetting: any;
1121
1138
  readonly featureUnderMouse: Feature | undefined;
1122
1139
  renderReady(): boolean;
1123
1140
  readonly filters: SerializableFilterChain;
@@ -1207,6 +1224,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
1207
1224
  }> | null;
1208
1225
  readonly adapterConfig: any;
1209
1226
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
1227
+ readonly isMinimized: boolean;
1210
1228
  readonly parentDisplay: any;
1211
1229
  readonly effectiveRpcDriverName: any;
1212
1230
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -1260,6 +1278,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
1260
1278
  }> | null;
1261
1279
  readonly adapterConfig: any;
1262
1280
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
1281
+ readonly isMinimized: boolean;
1263
1282
  readonly parentDisplay: any;
1264
1283
  readonly effectiveRpcDriverName: any;
1265
1284
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -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';
@@ -52,6 +52,9 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
52
52
  }))
53
53
  .views(self => ({
54
54
  get autorunReady() {
55
+ if (self.isMinimized) {
56
+ return false;
57
+ }
55
58
  const view = getContainingView(self);
56
59
  return (view.initialized && self.featureDensityStatsReadyAndRegionNotTooLarge);
57
60
  },
@@ -152,25 +155,27 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
152
155
  session.notify('Copied to clipboard', 'success');
153
156
  },
154
157
  get rendererConfig() {
155
- const { featureHeight: height, noSpacing, hideSmallIndels, hideMismatches, hideLargeIndels, trackMaxHeight: maxHeight, rendererTypeName, } = self;
156
- const configBlob = getConf(self, ['renderers', rendererTypeName]) || {};
158
+ const { featureHeight, noSpacing, hideSmallIndels, hideMismatches, hideLargeIndels, trackMaxHeight, rendererTypeName, } = self;
159
+ const conf = self.configuration.renderers?.[rendererTypeName];
157
160
  return {
158
- ...configBlob,
159
- ...(hideSmallIndels !== undefined ? { hideSmallIndels } : {}),
160
- ...(hideMismatches !== undefined ? { hideMismatches } : {}),
161
- ...(hideLargeIndels !== undefined ? { hideLargeIndels } : {}),
162
- ...(height !== undefined ? { height } : {}),
163
- ...(noSpacing !== undefined ? { noSpacing } : {}),
164
- ...(maxHeight !== undefined ? { maxHeight } : {}),
161
+ height: featureHeight ?? readConfObject(conf, 'height'),
162
+ noSpacing: noSpacing ?? readConfObject(conf, 'noSpacing'),
163
+ maxHeight: trackMaxHeight ?? readConfObject(conf, 'maxHeight'),
164
+ hideSmallIndels: hideSmallIndels ?? readConfObject(conf, 'hideSmallIndels'),
165
+ hideMismatches: hideMismatches ?? readConfObject(conf, 'hideMismatches'),
166
+ hideLargeIndels: hideLargeIndels ?? readConfObject(conf, 'hideLargeIndels'),
165
167
  };
166
168
  },
167
169
  }))
168
170
  .views(self => ({
169
171
  get maxHeight() {
170
- return readConfObject(self.rendererConfig, 'maxHeight');
172
+ return self.rendererConfig.maxHeight;
171
173
  },
172
174
  get featureHeightSetting() {
173
- return readConfObject(self.rendererConfig, 'height');
175
+ return self.rendererConfig.height;
176
+ },
177
+ get noSpacingSetting() {
178
+ return self.rendererConfig.noSpacing;
174
179
  },
175
180
  get featureUnderMouse() {
176
181
  return self.featureUnderMouseVolatile;
@@ -391,7 +396,8 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
391
396
  {
392
397
  label: 'Normal',
393
398
  type: 'radio',
394
- checked: self.featureHeight === 7 && self.noSpacing === false,
399
+ checked: self.featureHeightSetting === 7 &&
400
+ self.noSpacingSetting === false,
395
401
  onClick: () => {
396
402
  self.setFeatureHeight(7);
397
403
  self.setNoSpacing(false);
@@ -400,7 +406,8 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
400
406
  {
401
407
  label: 'Compact',
402
408
  type: 'radio',
403
- checked: self.featureHeight === 2 && self.noSpacing === true,
409
+ checked: self.featureHeightSetting === 2 &&
410
+ self.noSpacingSetting === true,
404
411
  onClick: () => {
405
412
  self.setFeatureHeight(2);
406
413
  self.setNoSpacing(true);
@@ -409,7 +416,8 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
409
416
  {
410
417
  label: 'Super-compact',
411
418
  type: 'radio',
412
- checked: self.featureHeight === 1 && self.noSpacing === true,
419
+ checked: self.featureHeightSetting === 1 &&
420
+ self.noSpacingSetting === true,
413
421
  onClick: () => {
414
422
  self.setFeatureHeight(1);
415
423
  self.setNoSpacing(true);
@@ -451,7 +459,7 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
451
459
  },
452
460
  {
453
461
  label: 'Filter by...',
454
- icon: FilterListIcon,
462
+ icon: ClearAllIcon,
455
463
  onClick: () => {
456
464
  getSession(self).queueDialog(handleClose => [
457
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;
@@ -5,21 +5,21 @@ import { setupModificationsAutorun } from "../shared/setupModificationsAutorun.j
5
5
  import { createAutorun } from "../util.js";
6
6
  export function doAfterAttach(model) {
7
7
  createAutorun(model, async () => {
8
- const view = getContainingView(model);
9
8
  if (!model.autorunReady) {
10
9
  return;
11
10
  }
11
+ const view = getContainingView(model);
12
12
  model.setCurrSortBpPerPx(view.bpPerPx);
13
13
  }, {
14
14
  delay: 1000,
15
15
  name: 'CurrBpPerPx',
16
16
  });
17
17
  createAutorun(model, async () => {
18
- const { rpcManager } = getSession(model);
19
- const view = getContainingView(model);
20
18
  if (!model.autorunReady) {
21
19
  return;
22
20
  }
21
+ const { rpcManager } = getSession(model);
22
+ const view = getContainingView(model);
23
23
  const { sortedBy, adapterConfig, rendererType, sortReady } = model;
24
24
  const { bpPerPx } = view;
25
25
  if (sortedBy && (!sortReady || model.currSortBpPerPx === view.bpPerPx)) {
@@ -151,6 +151,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
151
151
  }> | null;
152
152
  readonly adapterConfig: any;
153
153
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
154
+ readonly isMinimized: boolean;
154
155
  readonly parentDisplay: any;
155
156
  readonly effectiveRpcDriverName: any;
156
157
  } & {
@@ -207,6 +208,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
207
208
  }> | null;
208
209
  readonly adapterConfig: any;
209
210
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
211
+ readonly isMinimized: boolean;
210
212
  readonly parentDisplay: any;
211
213
  readonly effectiveRpcDriverName: any;
212
214
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -260,6 +262,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
260
262
  }> | null;
261
263
  readonly adapterConfig: any;
262
264
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
265
+ readonly isMinimized: boolean;
263
266
  readonly parentDisplay: any;
264
267
  readonly effectiveRpcDriverName: any;
265
268
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -541,6 +544,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
541
544
  }> | null;
542
545
  readonly adapterConfig: any;
543
546
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
547
+ readonly isMinimized: boolean;
544
548
  readonly parentDisplay: any;
545
549
  readonly effectiveRpcDriverName: any;
546
550
  } & {
@@ -597,6 +601,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
597
601
  }> | null;
598
602
  readonly adapterConfig: any;
599
603
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
604
+ readonly isMinimized: boolean;
600
605
  readonly parentDisplay: any;
601
606
  readonly effectiveRpcDriverName: any;
602
607
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -650,6 +655,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
650
655
  }> | null;
651
656
  readonly adapterConfig: any;
652
657
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
658
+ readonly isMinimized: boolean;
653
659
  readonly parentDisplay: any;
654
660
  readonly effectiveRpcDriverName: any;
655
661
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -876,6 +882,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
876
882
  }> | null;
877
883
  readonly adapterConfig: any;
878
884
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
885
+ readonly isMinimized: boolean;
879
886
  readonly parentDisplay: any;
880
887
  readonly effectiveRpcDriverName: any;
881
888
  } & {
@@ -932,6 +939,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
932
939
  }> | null;
933
940
  readonly adapterConfig: any;
934
941
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
942
+ readonly isMinimized: boolean;
935
943
  readonly parentDisplay: any;
936
944
  readonly effectiveRpcDriverName: any;
937
945
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -985,6 +993,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
985
993
  }> | null;
986
994
  readonly adapterConfig: any;
987
995
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
996
+ readonly isMinimized: boolean;
988
997
  readonly parentDisplay: any;
989
998
  readonly effectiveRpcDriverName: any;
990
999
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -1117,10 +1126,18 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
1117
1126
  setHideLargeIndels(arg: boolean): void;
1118
1127
  } & {
1119
1128
  copyFeatureToClipboard(feature: import("@jbrowse/core/util").Feature): Promise<void>;
1120
- readonly rendererConfig: any;
1129
+ readonly rendererConfig: {
1130
+ height: any;
1131
+ noSpacing: any;
1132
+ maxHeight: any;
1133
+ hideSmallIndels: any;
1134
+ hideMismatches: any;
1135
+ hideLargeIndels: any;
1136
+ };
1121
1137
  } & {
1122
1138
  readonly maxHeight: any;
1123
1139
  readonly featureHeightSetting: any;
1140
+ readonly noSpacingSetting: any;
1124
1141
  readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
1125
1142
  renderReady(): boolean;
1126
1143
  readonly filters: import("@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain").default;
@@ -1210,6 +1227,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
1210
1227
  }> | null;
1211
1228
  readonly adapterConfig: any;
1212
1229
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
1230
+ readonly isMinimized: boolean;
1213
1231
  readonly parentDisplay: any;
1214
1232
  readonly effectiveRpcDriverName: any;
1215
1233
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -1263,6 +1281,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
1263
1281
  }> | null;
1264
1282
  readonly adapterConfig: any;
1265
1283
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
1284
+ readonly isMinimized: boolean;
1266
1285
  readonly parentDisplay: any;
1267
1286
  readonly effectiveRpcDriverName: any;
1268
1287
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -1351,7 +1370,15 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
1351
1370
  reload(): void;
1352
1371
  } & {
1353
1372
  readonly modificationThreshold: any;
1354
- readonly rendererConfig: any;
1373
+ readonly rendererConfig: {
1374
+ height: any;
1375
+ noSpacing: any;
1376
+ maxHeight: any;
1377
+ mismatchAlpha: any;
1378
+ hideSmallIndels: any;
1379
+ hideMismatches: any;
1380
+ hideLargeIndels: any;
1381
+ };
1355
1382
  } & {
1356
1383
  readonly mismatchAlphaSetting: any;
1357
1384
  renderReady(): boolean;
@@ -1,5 +1,5 @@
1
1
  import { lazy } from 'react';
2
- import { ConfigurationReference, getConf, readConfObject, } from '@jbrowse/core/configuration';
2
+ import { ConfigurationReference, readConfObject, } from '@jbrowse/core/configuration';
3
3
  import { getContainingView, getSession } from '@jbrowse/core/util';
4
4
  import { types } from '@jbrowse/mobx-state-tree';
5
5
  import ColorLensIcon from '@mui/icons-material/ColorLens';
@@ -91,18 +91,16 @@ function stateModelFactory(configSchema) {
91
91
  return self.colorBy?.modifications?.threshold ?? 10;
92
92
  },
93
93
  get rendererConfig() {
94
- const { featureHeight, noSpacing, trackMaxHeight, mismatchAlpha, rendererTypeName, hideSmallIndels, hideMismatches, } = self;
95
- const configBlob = getConf(self, ['renderers', rendererTypeName]) || {};
94
+ const { featureHeight, noSpacing, trackMaxHeight, mismatchAlpha, hideSmallIndels, hideMismatches, hideLargeIndels, } = self;
95
+ const conf = self.configuration.renderers?.PileupRenderer;
96
96
  return {
97
- ...configBlob,
98
- ...(featureHeight !== undefined ? { height: featureHeight } : {}),
99
- ...(hideSmallIndels !== undefined ? { hideSmallIndels } : {}),
100
- ...(hideMismatches !== undefined ? { hideMismatches } : {}),
101
- ...(noSpacing !== undefined ? { noSpacing } : {}),
102
- ...(mismatchAlpha !== undefined ? { mismatchAlpha } : {}),
103
- ...(trackMaxHeight !== undefined
104
- ? { maxHeight: trackMaxHeight }
105
- : {}),
97
+ height: featureHeight ?? readConfObject(conf, 'height'),
98
+ noSpacing: noSpacing ?? readConfObject(conf, 'noSpacing'),
99
+ maxHeight: trackMaxHeight ?? readConfObject(conf, 'maxHeight'),
100
+ mismatchAlpha: mismatchAlpha ?? readConfObject(conf, 'mismatchAlpha'),
101
+ hideSmallIndels: hideSmallIndels ?? readConfObject(conf, 'hideSmallIndels'),
102
+ hideMismatches: hideMismatches ?? readConfObject(conf, 'hideMismatches'),
103
+ hideLargeIndels: hideLargeIndels ?? readConfObject(conf, 'hideLargeIndels'),
106
104
  };
107
105
  },
108
106
  }))
@@ -110,7 +108,7 @@ function stateModelFactory(configSchema) {
110
108
  const { renderReady: superRenderReady } = self;
111
109
  return {
112
110
  get mismatchAlphaSetting() {
113
- return readConfObject(self.rendererConfig, 'mismatchAlpha');
111
+ return self.rendererConfig.mismatchAlpha;
114
112
  },
115
113
  renderReady() {
116
114
  const view = getContainingView(self);
@@ -4,10 +4,10 @@ import { getUniqueTags } from "../shared/getUniqueTags.js";
4
4
  import { createAutorun } from "../util.js";
5
5
  export function sharedDoAfterAttach(self) {
6
6
  createAutorun(self, async () => {
7
- const view = getContainingView(self);
8
7
  if (!self.autorunReady) {
9
8
  return;
10
9
  }
10
+ const view = getContainingView(self);
11
11
  const { colorBy, tagsReady } = self;
12
12
  const { staticBlocks } = view;
13
13
  if (colorBy?.tag && !tagsReady) {
@@ -70,6 +70,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
70
70
  }> | null;
71
71
  readonly adapterConfig: any;
72
72
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
73
+ readonly isMinimized: boolean;
73
74
  readonly parentDisplay: any;
74
75
  readonly effectiveRpcDriverName: any;
75
76
  } & {
@@ -126,6 +127,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
126
127
  }> | null;
127
128
  readonly adapterConfig: any;
128
129
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
130
+ readonly isMinimized: boolean;
129
131
  readonly parentDisplay: any;
130
132
  readonly effectiveRpcDriverName: any;
131
133
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -179,6 +181,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
179
181
  }> | null;
180
182
  readonly adapterConfig: any;
181
183
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
184
+ readonly isMinimized: boolean;
182
185
  readonly parentDisplay: any;
183
186
  readonly effectiveRpcDriverName: any;
184
187
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -230,19 +233,24 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
230
233
  } & {
231
234
  loading: boolean;
232
235
  lastDrawnOffsetPx: number | undefined;
236
+ lastDrawnBpPerPx: number | undefined;
233
237
  ref: HTMLCanvasElement | null;
234
238
  renderingImageData: ImageBitmap | undefined;
235
239
  renderingStopToken: import("@jbrowse/core/util").StopToken | undefined;
236
240
  statusMessage: string | undefined;
241
+ canvasDrawn: boolean;
237
242
  } & {
238
243
  readonly drawn: boolean;
244
+ readonly fullyDrawn: boolean;
239
245
  } & {
240
246
  setLastDrawnOffsetPx(n: number): void;
247
+ setLastDrawnBpPerPx(n: number): void;
241
248
  setLoading(f: boolean): void;
242
249
  setRef(ref: HTMLCanvasElement | null): void;
243
250
  setRenderingImageData(imageData: ImageBitmap | undefined): void;
244
251
  setRenderingStopToken(token?: import("@jbrowse/core/util").StopToken): void;
245
252
  setStatusMessage(msg?: string): void;
253
+ setCanvasDrawn(drawn: boolean): void;
246
254
  } & {
247
255
  beforeDestroy(): void;
248
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;
@@ -79,6 +79,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
79
79
  }> | null;
80
80
  readonly adapterConfig: any;
81
81
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
82
+ readonly isMinimized: boolean;
82
83
  readonly parentDisplay: any;
83
84
  readonly effectiveRpcDriverName: any;
84
85
  } & {
@@ -135,6 +136,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
135
136
  }> | null;
136
137
  readonly adapterConfig: any;
137
138
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
139
+ readonly isMinimized: boolean;
138
140
  readonly parentDisplay: any;
139
141
  readonly effectiveRpcDriverName: any;
140
142
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -188,6 +190,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
188
190
  }> | null;
189
191
  readonly adapterConfig: any;
190
192
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
193
+ readonly isMinimized: boolean;
191
194
  readonly parentDisplay: any;
192
195
  readonly effectiveRpcDriverName: any;
193
196
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -239,19 +242,24 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
239
242
  } & {
240
243
  loading: boolean;
241
244
  lastDrawnOffsetPx: number | undefined;
245
+ lastDrawnBpPerPx: number | undefined;
242
246
  ref: HTMLCanvasElement | null;
243
247
  renderingImageData: ImageBitmap | undefined;
244
248
  renderingStopToken: import("@jbrowse/core/util").StopToken | undefined;
245
249
  statusMessage: string | undefined;
250
+ canvasDrawn: boolean;
246
251
  } & {
247
252
  readonly drawn: boolean;
253
+ readonly fullyDrawn: boolean;
248
254
  } & {
249
255
  setLastDrawnOffsetPx(n: number): void;
256
+ setLastDrawnBpPerPx(n: number): void;
250
257
  setLoading(f: boolean): void;
251
258
  setRef(ref: HTMLCanvasElement | null): void;
252
259
  setRenderingImageData(imageData: ImageBitmap | undefined): void;
253
260
  setRenderingStopToken(token?: import("@jbrowse/core/util").StopToken): void;
254
261
  setStatusMessage(msg?: string): void;
262
+ setCanvasDrawn(drawn: boolean): void;
255
263
  } & {
256
264
  beforeDestroy(): void;
257
265
  } & {
@@ -308,8 +316,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
308
316
  readonly hideLargeIndels: any;
309
317
  } & {
310
318
  readonly modificationThreshold: any;
311
- readonly cloudDomain: [number, number] | undefined;
312
- } & {
313
319
  readonly cloudTicks: import("../RenderLinearReadCloudDisplayRPC/drawFeatsCloud.ts").CloudTicks | undefined;
314
320
  } & {
315
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";
@@ -61,17 +61,18 @@ function stateModelFactory(pluginManager, configSchema) {
61
61
  return self.colorBy?.modifications?.threshold ?? 10;
62
62
  },
63
63
  get rendererConfig() {
64
- const configBlob = getConf(self, ['renderers', self.rendererTypeName]) || {};
65
64
  const { showArcs, showInterbaseCounts, showInterbaseIndicators } = self;
65
+ const conf = self.configuration.renderers?.[self.rendererTypeName];
66
66
  return {
67
- ...configBlob,
68
- showInterbaseCounts: showInterbaseCounts ?? configBlob.showInterbaseCounts,
69
- showInterbaseIndicators: showInterbaseIndicators ?? configBlob.showInterbaseIndicators,
70
- showArcs: showArcs ?? configBlob.showArcs,
67
+ showInterbaseCounts: showInterbaseCounts ??
68
+ readConfObject(conf, 'showInterbaseCounts'),
69
+ showInterbaseIndicators: showInterbaseIndicators ??
70
+ readConfObject(conf, 'showInterbaseIndicators'),
71
+ showArcs: showArcs ?? readConfObject(conf, 'showArcs'),
71
72
  };
72
73
  },
73
74
  get showArcsSetting() {
74
- return (self.showArcs ?? readConfObject(this.rendererConfig, 'showArcs'));
75
+ return this.rendererConfig.showArcs;
75
76
  },
76
77
  get skipFeatures() {
77
78
  if (!this.showArcsSetting) {
@@ -92,12 +93,10 @@ function stateModelFactory(pluginManager, configSchema) {
92
93
  return [...skipFeaturesMap.values()];
93
94
  },
94
95
  get showInterbaseCountsSetting() {
95
- return (self.showInterbaseCounts ??
96
- readConfObject(this.rendererConfig, 'showInterbaseCounts'));
96
+ return this.rendererConfig.showInterbaseCounts;
97
97
  },
98
98
  get showInterbaseIndicatorsSetting() {
99
- return (self.showInterbaseIndicators ??
100
- readConfObject(this.rendererConfig, 'showInterbaseIndicators'));
99
+ return this.rendererConfig.showInterbaseIndicators;
101
100
  },
102
101
  get autorunReady() {
103
102
  const view = getContainingView(self);
@@ -269,7 +268,7 @@ function stateModelFactory(pluginManager, configSchema) {
269
268
  },
270
269
  {
271
270
  label: 'Filter arcs by score...',
272
- icon: FilterListIcon,
271
+ icon: ClearAllIcon,
273
272
  onClick: () => {
274
273
  getSession(self).queueDialog(handleClose => [
275
274
  FilterArcsByScoreDialog,
@@ -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
  };
@@ -1,37 +1,24 @@
1
1
  import { scaleLog } from '@mui/x-charts-vendor/d3-scale';
2
2
  export const CLOUD_HEIGHT_PADDING = 20;
3
3
  const DEFAULT_MAX_DISTANCE = 1000;
4
- export function createCloudScale(minDistance, maxDistance, height) {
4
+ export function createCloudScale(maxDistance, height) {
5
5
  return scaleLog()
6
6
  .base(2)
7
- .domain([Math.max(1, minDistance), Math.max(2, maxDistance)])
7
+ .domain([1, Math.max(2, maxDistance)])
8
8
  .range([0, height - CLOUD_HEIGHT_PADDING])
9
9
  .clamp(true);
10
10
  }
11
- export function calculateCloudTicks(domain, height) {
12
- const [minDistance, maxDistance] = domain;
13
- const scale = createCloudScale(minDistance, maxDistance, height);
11
+ export function calculateCloudTicks(maxDistance, height) {
12
+ const scale = createCloudScale(maxDistance, height);
14
13
  const tickValues = scale.ticks(6);
15
14
  const ticks = tickValues.map(value => ({
16
15
  value,
17
16
  y: scale(value),
18
17
  }));
19
- return { ticks, height, minDistance, maxDistance };
18
+ return { ticks, height, maxDistance };
20
19
  }
21
- export function calculateCloudYOffsetsUtil(computedChains, height, cloudDomain) {
20
+ export function calculateCloudYOffsetsUtil(computedChains, height) {
22
21
  const chainYOffsets = new Map();
23
- if (cloudDomain) {
24
- const [, maxDistance] = cloudDomain;
25
- const scale = createCloudScale(1, maxDistance, height);
26
- for (const { id, distance } of computedChains) {
27
- const top = distance > 0 ? scale(distance) : 0;
28
- chainYOffsets.set(id, top);
29
- }
30
- return {
31
- chainYOffsets,
32
- cloudMaxDistance: maxDistance,
33
- };
34
- }
35
22
  let maxDistance = Number.MIN_VALUE;
36
23
  for (const { distance } of computedChains) {
37
24
  if (distance > 0) {
@@ -41,7 +28,7 @@ export function calculateCloudYOffsetsUtil(computedChains, height, cloudDomain)
41
28
  if (maxDistance === Number.MIN_VALUE) {
42
29
  maxDistance = DEFAULT_MAX_DISTANCE;
43
30
  }
44
- const scale = createCloudScale(1, maxDistance, height);
31
+ const scale = createCloudScale(maxDistance, height);
45
32
  for (const { id, distance } of computedChains) {
46
33
  const top = distance > 0 ? scale(distance) : 0;
47
34
  chainYOffsets.set(id, top);
@@ -12,7 +12,7 @@ import { computeChainBounds, drawFeatsCore, filterChains, sortComputedChains, }
12
12
  import { calculateStackYOffsetsUtil } from "./drawFeatsStack.js";
13
13
  import { getInsertSizeStats } from "../shared/insertSizeStats.js";
14
14
  export async function executeRenderLinearReadCloudDisplay({ pluginManager, args, }) {
15
- const { sessionId, view: viewSnapshot, adapterConfig, sequenceAdapter, config, theme, featureHeight, noSpacing, drawCloud, colorBy, drawSingletons, drawProperPairs, flipStrandLongReadChains, trackMaxHeight, cloudModeHeight, cloudDomain, highResolutionScaling, exportSVG, statusCallback = () => { }, stopToken, visibleModifications, hideSmallIndels, hideMismatches, hideLargeIndels, showOutline, } = args;
15
+ const { sessionId, view: viewSnapshot, adapterConfig, sequenceAdapter, config, theme, featureHeight, noSpacing, drawCloud, colorBy, drawSingletons, drawProperPairs, flipStrandLongReadChains, trackMaxHeight, cloudModeHeight, highResolutionScaling, exportSVG, statusCallback = () => { }, stopToken, visibleModifications, hideSmallIndels, hideMismatches, hideLargeIndels, showOutline, } = args;
16
16
  const view = Base1DView.create(viewSnapshot);
17
17
  if (viewSnapshot.width) {
18
18
  view.setVolatileWidth(viewSnapshot.width);
@@ -125,7 +125,7 @@ export async function executeRenderLinearReadCloudDisplay({ pluginManager, args,
125
125
  view: viewSnap,
126
126
  calculateYOffsets: (chains) => {
127
127
  return drawCloud
128
- ? calculateCloudYOffsetsUtil(chains, actualHeight, cloudDomain)
128
+ ? calculateCloudYOffsetsUtil(chains, actualHeight)
129
129
  : calculateStackYOffsetsUtil(chains, featureHeight, noSpacing, trackMaxHeight ?? 1200);
130
130
  },
131
131
  });
@@ -156,10 +156,14 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
156
156
  }
157
157
  async getCoverageBins(region, opts = {}) {
158
158
  const { bpPerPx, statsEstimationMode } = opts;
159
- if (this.lastBpPerPx !== undefined && this.lastBpPerPx !== bpPerPx) {
159
+ if (bpPerPx !== undefined &&
160
+ this.lastBpPerPx !== undefined &&
161
+ this.lastBpPerPx !== bpPerPx) {
160
162
  this.cache.clear();
161
163
  }
162
- this.lastBpPerPx = bpPerPx;
164
+ if (bpPerPx !== undefined) {
165
+ this.lastBpPerPx = bpPerPx;
166
+ }
163
167
  if (statsEstimationMode) {
164
168
  const regionFilterKey = makeRegionFilterKey(region, opts);
165
169
  for (const key of this.cache.keys()) {
@@ -79,6 +79,7 @@ export async function generateCoverageBinsPrefixSum({ fetchSequence, features, r
79
79
  for (let i = 0, l = features.length; i < l; i++) {
80
80
  processFeature(region, features[i], skipmap, noncovEvents, snpEvents);
81
81
  }
82
+ featureCtx.feature = undefined;
82
83
  const deletionDepth = new Int32Array(regionSize);
83
84
  let dd = 0;
84
85
  for (let i = 0; i < regionSize; i++) {
@@ -346,7 +347,6 @@ function mismatchHandler(type, start, refLen, base, _qual, altbase, interbaseLen
346
347
  const hash = `${mstart}_${mend}_${effectiveStrand}`;
347
348
  if (skipmap[hash] === undefined) {
348
349
  skipmap[hash] = {
349
- feature: feature,
350
350
  start: mstart,
351
351
  end: mend,
352
352
  strand: fstrand,
@@ -5,19 +5,24 @@ export declare function LinearReadDisplayBaseMixin(): import("@jbrowse/mobx-stat
5
5
  }, {
6
6
  loading: boolean;
7
7
  lastDrawnOffsetPx: number | undefined;
8
+ lastDrawnBpPerPx: number | undefined;
8
9
  ref: HTMLCanvasElement | null;
9
10
  renderingImageData: ImageBitmap | undefined;
10
11
  renderingStopToken: import("@jbrowse/core/util").StopToken | undefined;
11
12
  statusMessage: string | undefined;
13
+ canvasDrawn: boolean;
12
14
  } & {
13
15
  readonly drawn: boolean;
16
+ readonly fullyDrawn: boolean;
14
17
  } & {
15
18
  setLastDrawnOffsetPx(n: number): void;
19
+ setLastDrawnBpPerPx(n: number): void;
16
20
  setLoading(f: boolean): void;
17
21
  setRef(ref: HTMLCanvasElement | null): void;
18
22
  setRenderingImageData(imageData: ImageBitmap | undefined): void;
19
23
  setRenderingStopToken(token?: import("@jbrowse/core/util").StopToken): void;
20
24
  setStatusMessage(msg?: string): void;
25
+ setCanvasDrawn(drawn: boolean): void;
21
26
  } & {
22
27
  beforeDestroy(): void;
23
28
  } & {
@@ -20,6 +20,7 @@ export interface RPCRenderableModel {
20
20
  ref: HTMLCanvasElement | null;
21
21
  renderingImageData?: ImageBitmap;
22
22
  setStatusMessage?: (msg: string) => void;
23
+ setCanvasDrawn?: (drawn: boolean) => void;
23
24
  }
24
25
  export interface RPCRenderSetupParams<T extends RPCRenderableModel, R = Record<string, unknown>> {
25
26
  self: T;
@@ -33,18 +33,24 @@ export function createRPCRenderFunction({ self, rpcMethodName, getRPCParams, onR
33
33
  const stopToken = createStopToken();
34
34
  self.setRenderingStopToken(stopToken);
35
35
  self.setLoading(true);
36
- const viewSnapshot = structuredClone({
37
- ...getSnapshot(view),
38
- staticBlocks: view.staticBlocks,
36
+ self.setCanvasDrawn?.(false);
37
+ const viewSnapshot = {
38
+ displayedRegions: structuredClone(view.displayedRegions),
39
+ bpPerPx: view.bpPerPx,
40
+ offsetPx: view.offsetPx,
41
+ interRegionPaddingWidth: view.interRegionPaddingWidth,
42
+ minimumBlockWidth: view.minimumBlockWidth,
39
43
  width: view.width,
40
- });
44
+ };
41
45
  const sessionId = getRpcSessionId(self);
46
+ const adapterConfig = self.adapterConfig;
47
+ const config = getSnapshot(self.configuration);
42
48
  const result = (await rpcManager.call(sessionId, rpcMethodName, {
43
49
  sessionId,
44
50
  view: viewSnapshot,
45
- adapterConfig: self.adapterConfig,
51
+ adapterConfig,
46
52
  sequenceAdapter,
47
- config: getSnapshot(self.configuration),
53
+ config,
48
54
  statusCallback: (msg) => {
49
55
  if (isAlive(self)) {
50
56
  self.setStatusMessage?.(msg);
@@ -64,6 +70,7 @@ export function createRPCRenderFunction({ self, rpcMethodName, getRPCParams, onR
64
70
  }
65
71
  catch (error) {
66
72
  if (!isAbortException(error)) {
73
+ console.error(error);
67
74
  self.setError(error);
68
75
  }
69
76
  }
@@ -75,7 +82,10 @@ export function createRPCRenderFunction({ self, rpcMethodName, getRPCParams, onR
75
82
  }
76
83
  export function setupCanvasRenderingAutorun(self) {
77
84
  createAutorun(self, async () => {
78
- drawCanvasImageData(self.ref, self.renderingImageData);
85
+ const success = drawCanvasImageData(self.ref, self.renderingImageData);
86
+ if (isAlive(self)) {
87
+ self.setCanvasDrawn?.(success);
88
+ }
79
89
  }, {
80
90
  name: 'CanvasRenderAutorun',
81
91
  });
@@ -1,6 +1,6 @@
1
1
  import { lazy } from 'react';
2
2
  import { getSession } from '@jbrowse/core/util';
3
- import FilterListIcon from '@mui/icons-material/ClearAll';
3
+ import ClearAllIcon from '@mui/icons-material/ClearAll';
4
4
  import PaletteIcon from '@mui/icons-material/Palette';
5
5
  import { modificationData } from "./modificationData.js";
6
6
  const FilterByTagDialog = lazy(() => import("./components/FilterByTagDialog.js"));
@@ -150,7 +150,7 @@ export function getColorSchemeMenuItem(model) {
150
150
  export function getFilterByMenuItem(model) {
151
151
  return {
152
152
  label: 'Filter by',
153
- icon: FilterListIcon,
153
+ icon: ClearAllIcon,
154
154
  onClick: () => {
155
155
  getSession(model).queueDialog((handleClose) => [
156
156
  FilterByTagDialog,
@@ -162,7 +162,7 @@ export function getFilterByMenuItem(model) {
162
162
  export function getEditFiltersMenuItem(model) {
163
163
  return {
164
164
  label: 'Edit filters',
165
- icon: FilterListIcon,
165
+ icon: ClearAllIcon,
166
166
  type: 'subMenu',
167
167
  subMenu: [
168
168
  {
@@ -2,7 +2,6 @@ import type { MismatchCallback } from './forEachMismatchTypes.ts';
2
2
  import type { Feature } from '@jbrowse/core/util';
3
3
  export type SkipMap = Record<string, {
4
4
  score: number;
5
- feature: unknown;
6
5
  start: number;
7
6
  end: number;
8
7
  strand: number;
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-alignments",
3
- "version": "4.0.3",
3
+ "version": "4.1.1",
4
+ "type": "module",
4
5
  "description": "JBrowse 2 alignments adapters, tracks, etc.",
5
6
  "keywords": [
6
7
  "jbrowse",
@@ -21,11 +22,11 @@
21
22
  ],
22
23
  "dependencies": {
23
24
  "@gmod/bam": "^7.1.15",
24
- "@gmod/cram": "^7.0.3",
25
+ "@gmod/cram": "^8.0.0",
25
26
  "@jbrowse/mobx-state-tree": "^5.5.0",
26
- "@mui/icons-material": "^7.3.6",
27
- "@mui/material": "^7.3.6",
28
- "@mui/x-charts-vendor": "^8.23.0",
27
+ "@mui/icons-material": "^7.3.7",
28
+ "@mui/material": "^7.3.7",
29
+ "@mui/x-charts-vendor": "^8.26.0",
29
30
  "canvas2svg": "^1.0.16",
30
31
  "copy-to-clipboard": "^3.3.3",
31
32
  "fast-deep-equal": "^3.1.3",
@@ -33,10 +34,10 @@
33
34
  "mobx": "^6.15.0",
34
35
  "mobx-react": "^9.2.1",
35
36
  "rxjs": "^7.8.2",
36
- "@jbrowse/sv-core": "^4.0.3",
37
- "@jbrowse/plugin-linear-genome-view": "^4.0.3",
38
- "@jbrowse/core": "^4.0.3",
39
- "@jbrowse/plugin-wiggle": "^4.0.3"
37
+ "@jbrowse/core": "^4.1.1",
38
+ "@jbrowse/plugin-linear-genome-view": "^4.1.1",
39
+ "@jbrowse/plugin-wiggle": "^4.1.1",
40
+ "@jbrowse/sv-core": "^4.1.1"
40
41
  },
41
42
  "peerDependencies": {
42
43
  "react": ">=18.0.0"