@jbrowse/plugin-alignments 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +7 -3
  2. package/dist/AlignmentsFeatureDetail/Flags.d.ts +1 -3
  3. package/dist/AlignmentsFeatureDetail/Flags.js +1 -2
  4. package/dist/AlignmentsFeatureDetail/LinkedPairedAlignments.d.ts +1 -1
  5. package/dist/AlignmentsFeatureDetail/LinkedPairedAlignments.js +1 -1
  6. package/dist/AlignmentsFeatureDetail/stateModelFactory.d.ts +9 -6
  7. package/dist/AlignmentsFeatureDetail/stateModelFactory.js +1 -2
  8. package/dist/BamAdapter/BamAdapter.d.ts +0 -1
  9. package/dist/BamAdapter/BamAdapter.js +0 -1
  10. package/dist/CramAdapter/CramAdapter.d.ts +0 -1
  11. package/dist/CramAdapter/CramAdapter.js +0 -1
  12. package/dist/CramAdapter/CramTestAdapters.d.ts +0 -1
  13. package/dist/CramAdapter/CramTestAdapters.js +0 -1
  14. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +1 -1
  15. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +6 -4
  16. package/dist/LinearPileupDisplay/model.d.ts +1 -1
  17. package/dist/PileupRenderer/PileupRenderer.d.ts +4 -4
  18. package/dist/PileupRenderer/makeImageData.js +9 -14
  19. package/dist/PileupRenderer/renderModifications.js +25 -29
  20. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +0 -1
  21. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +0 -1
  22. package/dist/SNPCoverageAdapter/processModifications.js +34 -38
  23. package/dist/SNPCoverageRenderer/makeImage.js +25 -36
  24. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +8 -4
  25. package/esm/AlignmentsFeatureDetail/Flags.d.ts +1 -3
  26. package/esm/AlignmentsFeatureDetail/Flags.js +1 -2
  27. package/esm/AlignmentsFeatureDetail/LinkedPairedAlignments.d.ts +1 -1
  28. package/esm/AlignmentsFeatureDetail/LinkedPairedAlignments.js +1 -1
  29. package/esm/AlignmentsFeatureDetail/stateModelFactory.d.ts +9 -6
  30. package/esm/AlignmentsFeatureDetail/stateModelFactory.js +1 -2
  31. package/esm/BamAdapter/BamAdapter.d.ts +0 -1
  32. package/esm/BamAdapter/BamAdapter.js +0 -1
  33. package/esm/CramAdapter/CramAdapter.d.ts +0 -1
  34. package/esm/CramAdapter/CramAdapter.js +0 -1
  35. package/esm/CramAdapter/CramTestAdapters.d.ts +0 -1
  36. package/esm/CramAdapter/CramTestAdapters.js +0 -1
  37. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +1 -1
  38. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +6 -4
  39. package/esm/LinearPileupDisplay/model.d.ts +1 -1
  40. package/esm/PileupRenderer/PileupRenderer.d.ts +4 -4
  41. package/esm/PileupRenderer/makeImageData.js +3 -8
  42. package/esm/PileupRenderer/renderModifications.js +25 -29
  43. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +0 -1
  44. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +0 -1
  45. package/esm/SNPCoverageAdapter/processModifications.js +34 -38
  46. package/esm/SNPCoverageRenderer/makeImage.js +26 -37
  47. package/package.json +11 -11
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { lazy } from 'react';
3
3
  import FeatureDetails from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails';
4
4
  import { Paper } from '@mui/material';
@@ -10,12 +10,16 @@ import { tags } from './tagInfo';
10
10
  import { getTag } from './util';
11
11
  const SupplementaryAlignments = lazy(() => import('./SupplementaryAlignments'));
12
12
  const LinkedPairedAlignments = lazy(() => import('./LinkedPairedAlignments'));
13
+ const FeatDefined = observer(function (props) {
14
+ const { model, feat } = props;
15
+ const flags = feat.flags;
16
+ const SA = getTag('SA', feat);
17
+ return (_jsxs(Paper, { "data-testid": "alignment-side-drawer", children: [_jsx(FeatureDetails, { ...props, descriptions: { tags }, feature: feat, formatter: (value, key) => key === 'next_segment_position' ? (_jsx(PairLink, { model: model, locString: value })) : (_jsx(Formatter, { value: value })) }), SA !== undefined ? (_jsx(SupplementaryAlignments, { model: model, tag: SA, feature: feat })) : null, flags != null ? (_jsxs(_Fragment, { children: [flags & 1 ? (_jsx(LinkedPairedAlignments, { model: model, feature: feat })) : null, _jsx(Flags, { flags: flags, ...props })] })) : null] }));
18
+ });
13
19
  const AlignmentsFeatureDetails = observer(function (props) {
14
20
  const { model } = props;
15
21
  const { featureData } = model;
16
22
  const feat = structuredClone(featureData);
17
- const SA = getTag('SA', feat);
18
- const { flags } = feat;
19
- return (_jsxs(Paper, { "data-testid": "alignment-side-drawer", children: [_jsx(FeatureDetails, { ...props, descriptions: { tags }, feature: feat, formatter: (value, key) => key === 'next_segment_position' ? (_jsx(PairLink, { model: model, locString: value })) : (_jsx(Formatter, { value: value })) }), SA !== undefined ? (_jsx(SupplementaryAlignments, { model: model, tag: SA, feature: feat })) : null, flags & 1 ? (_jsx(LinkedPairedAlignments, { model: model, feature: feat })) : null, flags !== undefined ? _jsx(Flags, { feature: feat, ...props }) : null] }));
23
+ return feat ? (_jsx(FeatDefined, { feat: feat, ...props })) : (_jsx("div", { children: "No feature loaded, may not be available after page refresh because it was too large for localStorage" }));
20
24
  });
21
25
  export default AlignmentsFeatureDetails;
@@ -1,5 +1,3 @@
1
1
  export default function AlignmentFlags(props: {
2
- feature: {
3
- flags: number;
4
- };
2
+ flags: number;
5
3
  }): import("react/jsx-runtime").JSX.Element;
@@ -26,8 +26,7 @@ const flagNames = [
26
26
  ];
27
27
  export default function AlignmentFlags(props) {
28
28
  const { classes } = useStyles();
29
- const { feature } = props;
30
- const { flags } = feature;
29
+ const { flags } = props;
31
30
  return (_jsxs(BaseCard, { ...props, title: "Flags", children: [_jsx(SimpleField, { name: "Flag", value: flags }), _jsx(FormGroup, { children: flagNames.map((name, idx) => {
32
31
  const val = flags & (1 << idx);
33
32
  const key = `${name}_${val}`;
@@ -3,4 +3,4 @@ import type { SimpleFeatureSerialized } from '@jbrowse/core/util';
3
3
  export default function SuppAlignments(props: {
4
4
  model: AlignmentFeatureWidgetModel;
5
5
  feature: SimpleFeatureSerialized;
6
- }): import("react/jsx-runtime").JSX.Element;
6
+ }): import("react/jsx-runtime").JSX.Element | null;
@@ -12,5 +12,5 @@ export default function SuppAlignments(props) {
12
12
  }
13
13
  catch (e) {
14
14
  }
15
- return (_jsx(BaseCard, { ...props, title: "Paired alignments", children: hasBreakendSplitView ? (_jsx(LaunchPairedEndBreakpointSplitViewPanel, { model: model, feature: feature })) : null }));
15
+ return hasBreakendSplitView ? (_jsx(BaseCard, { ...props, title: "Paired alignments", children: _jsx(LaunchPairedEndBreakpointSplitViewPanel, { model: model, feature: feature }) })) : null;
16
16
  }
@@ -3,9 +3,9 @@ import type { Instance } from 'mobx-state-tree';
3
3
  export declare function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
4
4
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
5
5
  type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
6
- featureData: import("mobx-state-tree").IType<any, any, any>;
6
+ featureData: import("mobx-state-tree").IType<import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat>;
7
7
  formattedFields: import("mobx-state-tree").IType<any, any, any>;
8
- unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
8
+ unformattedFeatureData: import("mobx-state-tree").IType<import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat>;
9
9
  view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
10
10
  track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
11
11
  trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -35,14 +35,15 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
35
35
  } & {
36
36
  afterAttach(): void;
37
37
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>, [undefined]>;
38
+ descriptions: import("mobx-state-tree").IType<Record<string, unknown> | undefined, Record<string, unknown> | undefined, Record<string, unknown> | undefined>;
38
39
  } & {
39
40
  type: import("mobx-state-tree").ISimpleType<"AlignmentsFeatureWidget">;
40
41
  }, {
41
42
  error: unknown;
42
43
  } & {
43
- setFeatureData(featureData: Record<string, unknown>): void;
44
+ setFeatureData(featureData: import("@jbrowse/core/util").SimpleFeatureSerialized): void;
44
45
  clearFeatureData(): void;
45
- setFormattedData(feat: Record<string, unknown>): void;
46
+ setFormattedData(feat: import("@jbrowse/core/util").SimpleFeatureSerialized): void;
46
47
  setExtra(type?: string, trackId?: string, maxDepth?: number): void;
47
48
  setError(e: unknown): void;
48
49
  } & {
@@ -52,9 +53,9 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
52
53
  } & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
53
54
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
54
55
  type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
55
- featureData: import("mobx-state-tree").IType<any, any, any>;
56
+ featureData: import("mobx-state-tree").IType<import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat>;
56
57
  formattedFields: import("mobx-state-tree").IType<any, any, any>;
57
- unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
58
+ unformattedFeatureData: import("mobx-state-tree").IType<import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat, import("@jbrowse/core/BaseFeatureWidget/types").MaybeSerializedFeat>;
58
59
  view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
59
60
  track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
60
61
  trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -84,6 +85,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
84
85
  } & {
85
86
  afterAttach(): void;
86
87
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>, [undefined]>;
88
+ descriptions: import("mobx-state-tree").IType<Record<string, unknown> | undefined, Record<string, unknown> | undefined, Record<string, unknown> | undefined>;
87
89
  }>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
88
90
  type: "BaseFeatureWidget";
89
91
  id: string;
@@ -94,6 +96,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
94
96
  maxDepth: number | undefined;
95
97
  sequenceFeatureDetails: import("mobx-state-tree").ModelSnapshotType<{}>;
96
98
  formattedFields: any;
99
+ descriptions: Record<string, unknown> | undefined;
97
100
  finalizedFeatureData: any;
98
101
  } & import("mobx-state-tree")._NotCustomized>;
99
102
  export type AlignmentFeatureWidgetStateModel = ReturnType<typeof stateModelFactory>;
@@ -1,8 +1,7 @@
1
1
  import { stateModelFactory as baseModelFactory } from '@jbrowse/core/BaseFeatureWidget';
2
2
  import { types } from 'mobx-state-tree';
3
3
  export function stateModelFactory(pluginManager) {
4
- const baseModel = baseModelFactory(pluginManager);
5
- return types.compose(baseModel, types.model('AlignmentsFeatureWidget', {
4
+ return types.compose(baseModelFactory(pluginManager), types.model('AlignmentsFeatureWidget', {
6
5
  type: types.literal('AlignmentsFeatureWidget'),
7
6
  }));
8
7
  }
@@ -39,7 +39,6 @@ export default class BamAdapter extends BaseFeatureDataAdapter {
39
39
  bytes: number;
40
40
  fetchSizeLimit: any;
41
41
  }>;
42
- freeResources(): void;
43
42
  refIdToName(refId: number): string | undefined;
44
43
  }
45
44
  export {};
@@ -168,7 +168,6 @@ export default class BamAdapter extends BaseFeatureDataAdapter {
168
168
  }
169
169
  return super.getMultiRegionFeatureDensityStats(regions, opts);
170
170
  }
171
- freeResources() { }
172
171
  refIdToName(refId) {
173
172
  var _a;
174
173
  return (_a = this.samHeader) === null || _a === void 0 ? void 0 : _a.idToName[refId];
@@ -43,7 +43,6 @@ export default class CramAdapter extends BaseFeatureDataAdapter {
43
43
  }, opts?: BaseOptions & {
44
44
  filterBy: FilterBy;
45
45
  }): import("rxjs").Observable<Feature>;
46
- freeResources(): void;
47
46
  cramRecordToFeature(record: CramRecord): CramSlightlyLazyFeature;
48
47
  getMultiRegionFeatureDensityStats(regions: Region[], opts?: BaseOptions): Promise<{
49
48
  bytes: number;
@@ -197,7 +197,6 @@ export default class CramAdapter extends BaseFeatureDataAdapter {
197
197
  });
198
198
  }, stopToken);
199
199
  }
200
- freeResources() { }
201
200
  cramRecordToFeature(record) {
202
201
  return new CramSlightlyLazyFeature(record, this);
203
202
  }
@@ -24,6 +24,5 @@ export declare class SequenceAdapter extends BaseFeatureDataAdapter {
24
24
  start: number;
25
25
  end: number;
26
26
  }): Observable<SimpleFeature>;
27
- freeResources(): void;
28
27
  }
29
28
  export {};
@@ -73,5 +73,4 @@ export class SequenceAdapter extends BaseFeatureDataAdapter {
73
73
  return { unsubscribe: () => { } };
74
74
  });
75
75
  }
76
- freeResources() { }
77
76
  }
@@ -201,7 +201,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
201
201
  } & {
202
202
  addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
203
203
  deleteBlock(key: string): void;
204
- selectFeature(feature: Feature): void;
204
+ selectFeature(feature: Feature): Promise<void>;
205
205
  navToFeature(feature: Feature): void;
206
206
  clearFeatureSelection(): void;
207
207
  setFeatureIdUnderMouse(feature?: string): void;
@@ -186,7 +186,9 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
186
186
  icon: MenuOpenIcon,
187
187
  onClick: () => {
188
188
  self.clearFeatureSelection();
189
- self.selectFeature(feat);
189
+ self.selectFeature(feat).catch((e) => {
190
+ getSession(self).notifyError(`${e}`, e);
191
+ });
190
192
  },
191
193
  },
192
194
  {
@@ -232,13 +234,13 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
232
234
  rendererType: 'PileupRenderer',
233
235
  }));
234
236
  if (isAlive(self) && feature) {
235
- self.selectFeature(new SimpleFeature(feature));
237
+ await self.selectFeature(new SimpleFeature(feature));
236
238
  }
237
239
  }
238
240
  }
239
241
  catch (e) {
240
242
  console.error(e);
241
- session.notify(`${e}`);
243
+ session.notifyError(`${e}`, e);
242
244
  }
243
245
  },
244
246
  onClick() {
@@ -267,7 +269,7 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
267
269
  }
268
270
  catch (e) {
269
271
  console.error(e);
270
- session.notify(`${e}`);
272
+ session.notifyError(`${e}`, e);
271
273
  }
272
274
  },
273
275
  };
@@ -205,7 +205,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
205
205
  } & {
206
206
  addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
207
207
  deleteBlock(key: string): void;
208
- selectFeature(feature: import("@jbrowse/core/util").Feature): void;
208
+ selectFeature(feature: import("@jbrowse/core/util").Feature): Promise<void>;
209
209
  navToFeature(feature: import("@jbrowse/core/util").Feature): void;
210
210
  clearFeatureSelection(): void;
211
211
  setFeatureIdUnderMouse(feature?: string): void;
@@ -20,7 +20,7 @@ export default class PileupRenderer extends BoxRendererType {
20
20
  width: number;
21
21
  maxHeightReached: boolean;
22
22
  containsNoTransferables: boolean;
23
- canvasRecordedData: any;
23
+ canvasRecordedData: Record<string, unknown>;
24
24
  reactElement?: React.ReactElement;
25
25
  html?: string;
26
26
  } | {
@@ -30,7 +30,8 @@ export default class PileupRenderer extends BoxRendererType {
30
30
  width: number;
31
31
  maxHeightReached: boolean;
32
32
  containsNoTransferables: boolean;
33
- reactElement: import("react/jsx-runtime").JSX.Element;
33
+ imageData: any;
34
+ reactElement?: React.ReactElement;
34
35
  html?: string;
35
36
  } | {
36
37
  features: Map<any, any>;
@@ -39,8 +40,7 @@ export default class PileupRenderer extends BoxRendererType {
39
40
  width: number;
40
41
  maxHeightReached: boolean;
41
42
  containsNoTransferables: boolean;
42
- imageData: any;
43
- reactElement?: React.ReactElement;
43
+ reactElement: React.ReactElement;
44
44
  html?: string;
45
45
  }>;
46
46
  createLayoutSession(args: PileupLayoutSessionProps): PileupLayoutSession;
@@ -1,6 +1,6 @@
1
1
  import { readConfObject } from '@jbrowse/core/configuration';
2
2
  import { createJBrowseTheme } from '@jbrowse/core/ui';
3
- import { checkStopToken } from '@jbrowse/core/util/stopToken';
3
+ import { forEachWithStopTokenCheck } from '@jbrowse/core/util';
4
4
  import { renderAlignment } from './renderAlignment';
5
5
  import { renderMismatches } from './renderMismatches';
6
6
  import { renderSoftClipping } from './renderSoftClipping';
@@ -19,12 +19,7 @@ export function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, })
19
19
  const { charWidth, charHeight } = getCharWidthHeight();
20
20
  const drawSNPsMuted = shouldDrawSNPsMuted(colorBy === null || colorBy === void 0 ? void 0 : colorBy.type);
21
21
  const drawIndels = shouldDrawIndels();
22
- let start = performance.now();
23
- for (const feat of layoutRecords) {
24
- if (performance.now() - start > 400) {
25
- checkStopToken(stopToken);
26
- start = performance.now();
27
- }
22
+ forEachWithStopTokenCheck(layoutRecords, stopToken, feat => {
28
23
  renderAlignment({
29
24
  ctx,
30
25
  feat,
@@ -63,6 +58,6 @@ export function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, })
63
58
  canvasWidth,
64
59
  });
65
60
  }
66
- }
61
+ });
67
62
  return undefined;
68
63
  }
@@ -3,7 +3,7 @@ import { fillRect } from './util';
3
3
  import { getMaxProbModAtEachPosition } from '../shared/getMaximumModificationAtEachPosition';
4
4
  import { alphaColor } from '../shared/util';
5
5
  export function renderModifications({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, cigarOps, }) {
6
- var _a, _b;
6
+ var _a, _b, _c;
7
7
  const { feature, topPx, heightPx } = feat;
8
8
  const { colorBy, visibleModifications = {} } = renderArgs;
9
9
  const seq = feature.get('seq');
@@ -13,33 +13,29 @@ export function renderModifications({ ctx, feat, region, bpPerPx, renderArgs, ca
13
13
  const start = feature.get('start');
14
14
  const isolatedModification = (_a = colorBy === null || colorBy === void 0 ? void 0 : colorBy.modifications) === null || _a === void 0 ? void 0 : _a.isolatedModification;
15
15
  const twoColor = (_b = colorBy === null || colorBy === void 0 ? void 0 : colorBy.modifications) === null || _b === void 0 ? void 0 : _b.twoColor;
16
- const probs = getMaxProbModAtEachPosition(feature, cigarOps);
17
- if (probs) {
18
- let pos = 0;
19
- for (const { allProbs, prob, type } of probs) {
20
- const r = start + pos;
21
- const [leftPx, rightPx] = bpSpanPx(r, r + 1, region, bpPerPx);
22
- const mod = visibleModifications[type];
23
- if (!mod) {
24
- console.warn(`${type} not known yet`);
25
- return;
26
- }
27
- if (isolatedModification && mod.type !== isolatedModification) {
28
- return;
29
- }
30
- const col = mod.color || 'black';
31
- const s = 1 - sum(allProbs);
32
- if (twoColor && s > max(allProbs)) {
33
- const c = alphaColor('blue', s);
34
- const w = rightPx - leftPx + 0.5;
35
- fillRect(ctx, leftPx, topPx, w, heightPx, canvasWidth, c);
36
- }
37
- else {
38
- const c = alphaColor(col, prob);
39
- const w = rightPx - leftPx + 0.5;
40
- fillRect(ctx, leftPx, topPx, w, heightPx, canvasWidth, c);
41
- }
42
- pos++;
16
+ (_c = getMaxProbModAtEachPosition(feature, cigarOps)) === null || _c === void 0 ? void 0 : _c.forEach(({ allProbs, prob, type }, pos) => {
17
+ const r = start + pos;
18
+ const [leftPx, rightPx] = bpSpanPx(r, r + 1, region, bpPerPx);
19
+ const mod = visibleModifications[type];
20
+ if (!mod) {
21
+ console.warn(`${type} not known yet`);
22
+ return;
43
23
  }
44
- }
24
+ if (isolatedModification && mod.type !== isolatedModification) {
25
+ return;
26
+ }
27
+ const col = mod.color || 'black';
28
+ const s = 1 - sum(allProbs);
29
+ if (twoColor && s > max(allProbs)) {
30
+ const c = alphaColor('blue', s);
31
+ const w = rightPx - leftPx + 0.5;
32
+ fillRect(ctx, leftPx, topPx, w, heightPx, canvasWidth, c);
33
+ }
34
+ else {
35
+ const c = alphaColor(col, prob);
36
+ const w = rightPx - leftPx + 0.5;
37
+ fillRect(ctx, leftPx, topPx, w, heightPx, canvasWidth, c);
38
+ }
39
+ pos++;
40
+ });
45
41
  }
@@ -11,5 +11,4 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
11
11
  getFeatures(region: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
12
12
  getMultiRegionFeatureDensityStats(regions: Region[], opts?: BaseOptions): Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats>;
13
13
  getRefNames(opts?: BaseOptions): Promise<string[]>;
14
- freeResources(): void;
15
14
  }
@@ -80,5 +80,4 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
80
80
  const { subadapter } = await this.configure();
81
81
  return subadapter.getRefNames(opts);
82
82
  }
83
- freeResources() { }
84
83
  }
@@ -2,50 +2,46 @@ import { max, sum } from '@jbrowse/core/util';
2
2
  import { incWithProbabilities } from './util';
3
3
  import { getMaxProbModAtEachPosition } from '../shared/getMaximumModificationAtEachPosition';
4
4
  export function processModifications({ feature, colorBy, region, bins, regionSequence, }) {
5
- var _a, _b;
5
+ var _a, _b, _c;
6
6
  const fstart = feature.get('start');
7
7
  const fstrand = feature.get('strand');
8
8
  const fend = feature.get('end');
9
9
  const twoColor = (_a = colorBy === null || colorBy === void 0 ? void 0 : colorBy.modifications) === null || _a === void 0 ? void 0 : _a.twoColor;
10
10
  const isolatedModification = (_b = colorBy === null || colorBy === void 0 ? void 0 : colorBy.modifications) === null || _b === void 0 ? void 0 : _b.isolatedModification;
11
- const probs = getMaxProbModAtEachPosition(feature);
12
- if (probs) {
13
- let pos = 0;
14
- for (const { type, prob, allProbs } of probs) {
15
- if (isolatedModification && type !== isolatedModification) {
16
- return;
11
+ (_c = getMaxProbModAtEachPosition(feature)) === null || _c === void 0 ? void 0 : _c.forEach(({ allProbs, prob, type }, pos) => {
12
+ if (isolatedModification && type !== isolatedModification) {
13
+ return;
14
+ }
15
+ const epos = pos + fstart - region.start;
16
+ if (epos >= 0 && epos < bins.length && pos + fstart < fend) {
17
+ if (bins[epos] === undefined) {
18
+ bins[epos] = {
19
+ depth: 0,
20
+ readsCounted: 0,
21
+ snps: {},
22
+ ref: {
23
+ probabilities: [],
24
+ entryDepth: 0,
25
+ '-1': 0,
26
+ 0: 0,
27
+ 1: 0,
28
+ },
29
+ mods: {},
30
+ nonmods: {},
31
+ delskips: {},
32
+ noncov: {},
33
+ };
34
+ }
35
+ const s = 1 - sum(allProbs);
36
+ const bin = bins[epos];
37
+ bin.refbase = regionSequence[epos];
38
+ if (twoColor && s > max(allProbs)) {
39
+ incWithProbabilities(bin, fstrand, 'nonmods', `nonmod_${type}`, s);
17
40
  }
18
- const epos = pos + fstart - region.start;
19
- if (epos >= 0 && epos < bins.length && pos + fstart < fend) {
20
- if (bins[epos] === undefined) {
21
- bins[epos] = {
22
- depth: 0,
23
- readsCounted: 0,
24
- snps: {},
25
- ref: {
26
- probabilities: [],
27
- entryDepth: 0,
28
- '-1': 0,
29
- 0: 0,
30
- 1: 0,
31
- },
32
- mods: {},
33
- nonmods: {},
34
- delskips: {},
35
- noncov: {},
36
- };
37
- }
38
- const s = 1 - sum(allProbs);
39
- const bin = bins[epos];
40
- bin.refbase = regionSequence[epos];
41
- if (twoColor && s > max(allProbs)) {
42
- incWithProbabilities(bin, fstrand, 'nonmods', `nonmod_${type}`, s);
43
- }
44
- else {
45
- incWithProbabilities(bin, fstrand, 'mods', `mod_${type}`, prob);
46
- }
41
+ else {
42
+ incWithProbabilities(bin, fstrand, 'mods', `mod_${type}`, prob);
47
43
  }
48
- pos++;
49
44
  }
50
- }
45
+ pos++;
46
+ });
51
47
  }
@@ -1,7 +1,6 @@
1
1
  import { readConfObject } from '@jbrowse/core/configuration';
2
2
  import { createJBrowseTheme } from '@jbrowse/core/ui';
3
- import { bpSpanPx, featureSpanPx } from '@jbrowse/core/util';
4
- import { checkStopToken } from '@jbrowse/core/util/stopToken';
3
+ import { bpSpanPx, featureSpanPx, forEachWithStopTokenCheck, } from '@jbrowse/core/util';
5
4
  import { YSCALEBAR_LABEL_OFFSET, getOrigin, getScale, } from '@jbrowse/plugin-wiggle';
6
5
  import { alphaColor } from '../shared/util';
7
6
  const INTERBASE_INDICATOR_WIDTH = 7;
@@ -15,7 +14,7 @@ const complementBase = {
15
14
  };
16
15
  const fudgeFactor = 0.6;
17
16
  export async function makeImage(ctx, props) {
18
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
17
+ var _a;
19
18
  const { features, regions, bpPerPx, colorBy, displayCrossHatches, visibleModifications = {}, scaleOpts, height: unadjustedHeight, theme: configTheme, config: cfg, ticks, stopToken, } = props;
20
19
  const theme = createJBrowseTheme(configTheme);
21
20
  const region = regions[0];
@@ -53,35 +52,25 @@ export async function makeImage(ctx, props) {
53
52
  cpg_meth: 'red',
54
53
  cpg_unmeth: 'blue',
55
54
  };
56
- const feats = [...features.values()];
57
55
  ctx.fillStyle = colorMap.total;
58
- let start = performance.now();
59
- for (const feature of feats) {
56
+ forEachWithStopTokenCheck(features.values(), stopToken, feature => {
60
57
  if (feature.get('type') === 'skip') {
61
- continue;
58
+ return;
62
59
  }
63
60
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
64
61
  const w = rightPx - leftPx + fudgeFactor;
65
62
  const score = feature.get('score');
66
63
  ctx.fillRect(leftPx, toY(score), w, toHeight(score));
67
- if (performance.now() - start > 400) {
68
- checkStopToken(stopToken);
69
- start = performance.now();
70
- }
71
- }
64
+ });
72
65
  let prevTotal = 0;
73
66
  const extraHorizontallyFlippedOffset = region.reversed ? 1 / bpPerPx : 0;
74
67
  const drawingModifications = colorBy.type === 'modifications';
75
68
  const drawingMethylation = colorBy.type === 'methylation';
76
69
  const isolatedModification = (_a = colorBy.modifications) === null || _a === void 0 ? void 0 : _a.isolatedModification;
77
- start = performance.now();
78
- for (const feature of feats) {
79
- const now = performance.now();
80
- if (now - start > 400) {
81
- checkStopToken(stopToken);
82
- }
70
+ forEachWithStopTokenCheck(features.values(), stopToken, feature => {
71
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
83
72
  if (feature.get('type') === 'skip') {
84
- continue;
73
+ return;
85
74
  }
86
75
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
87
76
  const snpinfo = feature.get('snpinfo');
@@ -89,7 +78,7 @@ export async function makeImage(ctx, props) {
89
78
  const score0 = feature.get('score');
90
79
  if (drawingModifications) {
91
80
  let curr = 0;
92
- const refbase = (_b = snpinfo.refbase) === null || _b === void 0 ? void 0 : _b.toUpperCase();
81
+ const refbase = (_a = snpinfo.refbase) === null || _a === void 0 ? void 0 : _a.toUpperCase();
93
82
  const { nonmods, mods, snps, ref } = snpinfo;
94
83
  for (const m of Object.keys(nonmods).sort().reverse()) {
95
84
  const mod = visibleModifications[m.replace('nonmod_', '')] ||
@@ -104,14 +93,14 @@ export async function makeImage(ctx, props) {
104
93
  const cmp = complementBase[mod.base];
105
94
  const detectable = mod.base === 'N'
106
95
  ? score0
107
- : (((_c = snps[mod.base]) === null || _c === void 0 ? void 0 : _c.entryDepth) || 0) +
108
- (((_d = snps[cmp]) === null || _d === void 0 ? void 0 : _d.entryDepth) || 0) +
96
+ : (((_b = snps[mod.base]) === null || _b === void 0 ? void 0 : _b.entryDepth) || 0) +
97
+ (((_c = snps[cmp]) === null || _c === void 0 ? void 0 : _c.entryDepth) || 0) +
109
98
  (refbase === mod.base ? ref['1'] : 0) +
110
99
  (refbase === cmp ? ref['-1'] : 0);
111
100
  const modifiable = mod.base === 'N'
112
101
  ? score0
113
- : (((_e = snps[mod.base]) === null || _e === void 0 ? void 0 : _e.entryDepth) || 0) +
114
- (((_f = snps[cmp]) === null || _f === void 0 ? void 0 : _f.entryDepth) || 0) +
102
+ : (((_d = snps[mod.base]) === null || _d === void 0 ? void 0 : _d.entryDepth) || 0) +
103
+ (((_e = snps[cmp]) === null || _e === void 0 ? void 0 : _e.entryDepth) || 0) +
115
104
  (refbase === mod.base ? ref.entryDepth : 0) +
116
105
  (refbase === cmp ? ref.entryDepth : 0);
117
106
  const { entryDepth, avgProbability = 0 } = snpinfo.nonmods[m];
@@ -136,14 +125,14 @@ export async function makeImage(ctx, props) {
136
125
  const cmp = complementBase[mod.base];
137
126
  const detectable = mod.base === 'N'
138
127
  ? score0
139
- : (((_g = snps[mod.base]) === null || _g === void 0 ? void 0 : _g.entryDepth) || 0) +
140
- (((_h = snps[cmp]) === null || _h === void 0 ? void 0 : _h.entryDepth) || 0) +
128
+ : (((_f = snps[mod.base]) === null || _f === void 0 ? void 0 : _f.entryDepth) || 0) +
129
+ (((_g = snps[cmp]) === null || _g === void 0 ? void 0 : _g.entryDepth) || 0) +
141
130
  (refbase === mod.base ? ref['1'] : 0) +
142
131
  (refbase === cmp ? ref['-1'] : 0);
143
132
  const modifiable = mod.base === 'N'
144
133
  ? score0
145
- : (((_j = snps[mod.base]) === null || _j === void 0 ? void 0 : _j.entryDepth) || 0) +
146
- (((_k = snps[cmp]) === null || _k === void 0 ? void 0 : _k.entryDepth) || 0) +
134
+ : (((_h = snps[mod.base]) === null || _h === void 0 ? void 0 : _h.entryDepth) || 0) +
135
+ (((_j = snps[cmp]) === null || _j === void 0 ? void 0 : _j.entryDepth) || 0) +
147
136
  (refbase === mod.base ? ref.entryDepth : 0) +
148
137
  (refbase === cmp ? ref.entryDepth : 0);
149
138
  const { entryDepth, avgProbability = 0 } = mods[m];
@@ -225,17 +214,17 @@ export async function makeImage(ctx, props) {
225
214
  }
226
215
  }
227
216
  prevTotal = score0;
228
- }
217
+ });
229
218
  if (showArcs) {
230
- for (const f of feats) {
231
- if (f.get('type') !== 'skip') {
232
- continue;
219
+ forEachWithStopTokenCheck(features.values(), stopToken, feature => {
220
+ if (feature.get('type') !== 'skip') {
221
+ return;
233
222
  }
234
- const s = f.get('start');
235
- const e = f.get('end');
223
+ const s = feature.get('start');
224
+ const e = feature.get('end');
236
225
  const [left, right] = bpSpanPx(s, e, region, bpPerPx);
237
226
  ctx.beginPath();
238
- const effectiveStrand = f.get('effectiveStrand');
227
+ const effectiveStrand = feature.get('effectiveStrand');
239
228
  const pos = 'rgba(255,200,200,0.7)';
240
229
  const neg = 'rgba(200,200,255,0.7)';
241
230
  const neutral = 'rgba(200,200,200,0.7)';
@@ -248,11 +237,11 @@ export async function makeImage(ctx, props) {
248
237
  else {
249
238
  ctx.strokeStyle = neutral;
250
239
  }
251
- ctx.lineWidth = Math.log(f.get('score') + 1);
240
+ ctx.lineWidth = Math.log(feature.get('score') + 1);
252
241
  ctx.moveTo(left, height - offset * 2);
253
242
  ctx.bezierCurveTo(left, 0, right, 0, right, height - offset * 2);
254
243
  ctx.stroke();
255
- }
244
+ });
256
245
  }
257
246
  if (displayCrossHatches) {
258
247
  ctx.lineWidth = 1;