@jbrowse/plugin-alignments 2.6.2 → 2.7.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 (133) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -2
  2. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -1
  3. package/dist/AlignmentsFeatureDetail/util.d.ts +1 -3
  4. package/dist/BamAdapter/BamAdapter.d.ts +2 -9
  5. package/dist/CramAdapter/CramAdapter.d.ts +3 -11
  6. package/dist/CramAdapter/CramAdapter.js +2 -1
  7. package/dist/CramAdapter/util.js +3 -6
  8. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +3 -4
  9. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +3 -3
  10. package/dist/LinearAlignmentsDisplay/models/model.d.ts +5 -9
  11. package/dist/LinearAlignmentsDisplay/models/model.js +1 -0
  12. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +514 -0
  13. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +547 -0
  14. package/dist/LinearPileupDisplay/components/ColorByModifications.d.ts +4 -5
  15. package/dist/LinearPileupDisplay/components/ColorByModifications.js +3 -4
  16. package/dist/LinearPileupDisplay/components/ColorByTag.d.ts +7 -5
  17. package/dist/LinearPileupDisplay/components/ColorByTag.js +4 -7
  18. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.d.ts +3 -4
  19. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +2 -2
  20. package/dist/LinearPileupDisplay/components/SetFeatureHeight.d.ts +4 -5
  21. package/dist/LinearPileupDisplay/components/SetFeatureHeight.js +3 -3
  22. package/dist/LinearPileupDisplay/components/SetMaxHeight.d.ts +3 -4
  23. package/dist/LinearPileupDisplay/components/SetMaxHeight.js +3 -3
  24. package/dist/LinearPileupDisplay/components/SortByTag.d.ts +3 -4
  25. package/dist/LinearPileupDisplay/components/SortByTag.js +3 -3
  26. package/dist/LinearPileupDisplay/index.d.ts +1 -0
  27. package/dist/LinearPileupDisplay/index.js +3 -1
  28. package/dist/LinearPileupDisplay/model.d.ts +142 -234
  29. package/dist/LinearPileupDisplay/model.js +50 -446
  30. package/dist/LinearReadArcsDisplay/components/ReactComponent.d.ts +2 -2
  31. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +2 -1
  32. package/dist/LinearReadArcsDisplay/model.d.ts +9 -14
  33. package/dist/LinearReadCloudDisplay/components/ReactComponent.d.ts +2 -2
  34. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +2 -1
  35. package/dist/LinearReadCloudDisplay/drawPairChains.js +1 -2
  36. package/dist/LinearReadCloudDisplay/model.d.ts +13 -15
  37. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  38. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +18 -423
  39. package/dist/LinearSNPCoverageDisplay/models/model.js +18 -0
  40. package/dist/MismatchParser/index.js +6 -8
  41. package/dist/PileupRenderer/PileupRenderer.js +0 -25
  42. package/dist/PileupRenderer/colorBy.js +1 -1
  43. package/dist/PileupRenderer/components/PileupRendering.d.ts +9 -10
  44. package/dist/PileupRenderer/components/PileupRendering.js +3 -5
  45. package/dist/PileupRenderer/getAlignmentShapeColor.js +1 -1
  46. package/dist/PileupRenderer/layoutFeature.js +1 -2
  47. package/dist/PileupRenderer/makeImageData.d.ts +1 -3
  48. package/dist/PileupRenderer/renderMethylation.js +5 -10
  49. package/dist/PileupRenderer/renderMismatches.d.ts +2 -6
  50. package/dist/PileupRenderer/renderMismatches.js +8 -11
  51. package/dist/PileupRenderer/renderModifications.js +4 -8
  52. package/dist/PileupRenderer/renderSoftClipping.js +26 -25
  53. package/dist/PileupRenderer/sortUtil.js +2 -2
  54. package/dist/SNPCoverageAdapter/util.d.ts +9 -13
  55. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +6 -12
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +2 -1
  58. package/dist/shared/BaseDisplayComponent.d.ts +2 -2
  59. package/dist/shared/BaseDisplayComponent.js +2 -1
  60. package/dist/shared/FilterByTag.d.ts +6 -15
  61. package/dist/shared/FilterByTag.js +4 -6
  62. package/dist/shared/color.d.ts +10 -0
  63. package/dist/shared/color.js +7 -1
  64. package/dist/shared/fetchChains.js +1 -0
  65. package/dist/shared/index.d.ts +9 -0
  66. package/dist/util.d.ts +3 -9
  67. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -2
  68. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -1
  69. package/esm/AlignmentsFeatureDetail/util.d.ts +1 -3
  70. package/esm/BamAdapter/BamAdapter.d.ts +2 -9
  71. package/esm/CramAdapter/CramAdapter.d.ts +3 -11
  72. package/esm/CramAdapter/CramAdapter.js +2 -1
  73. package/esm/CramAdapter/util.js +3 -6
  74. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +3 -4
  75. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +3 -3
  76. package/esm/LinearAlignmentsDisplay/models/model.d.ts +5 -9
  77. package/esm/LinearAlignmentsDisplay/models/model.js +1 -0
  78. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +514 -0
  79. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +517 -0
  80. package/esm/LinearPileupDisplay/components/ColorByModifications.d.ts +4 -5
  81. package/esm/LinearPileupDisplay/components/ColorByModifications.js +3 -4
  82. package/esm/LinearPileupDisplay/components/ColorByTag.d.ts +7 -5
  83. package/esm/LinearPileupDisplay/components/ColorByTag.js +4 -7
  84. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.d.ts +3 -4
  85. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +2 -2
  86. package/esm/LinearPileupDisplay/components/SetFeatureHeight.d.ts +4 -5
  87. package/esm/LinearPileupDisplay/components/SetFeatureHeight.js +3 -3
  88. package/esm/LinearPileupDisplay/components/SetMaxHeight.d.ts +3 -4
  89. package/esm/LinearPileupDisplay/components/SetMaxHeight.js +3 -3
  90. package/esm/LinearPileupDisplay/components/SortByTag.d.ts +3 -4
  91. package/esm/LinearPileupDisplay/components/SortByTag.js +3 -3
  92. package/esm/LinearPileupDisplay/index.d.ts +1 -0
  93. package/esm/LinearPileupDisplay/index.js +1 -0
  94. package/esm/LinearPileupDisplay/model.d.ts +142 -234
  95. package/esm/LinearPileupDisplay/model.js +51 -447
  96. package/esm/LinearReadArcsDisplay/components/ReactComponent.d.ts +2 -2
  97. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +2 -1
  98. package/esm/LinearReadArcsDisplay/model.d.ts +9 -14
  99. package/esm/LinearReadCloudDisplay/components/ReactComponent.d.ts +2 -2
  100. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +2 -1
  101. package/esm/LinearReadCloudDisplay/drawPairChains.js +1 -2
  102. package/esm/LinearReadCloudDisplay/model.d.ts +13 -15
  103. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  104. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +18 -423
  105. package/esm/LinearSNPCoverageDisplay/models/model.js +18 -0
  106. package/esm/MismatchParser/index.js +6 -8
  107. package/esm/PileupRenderer/PileupRenderer.js +0 -2
  108. package/esm/PileupRenderer/colorBy.js +1 -1
  109. package/esm/PileupRenderer/components/PileupRendering.d.ts +9 -10
  110. package/esm/PileupRenderer/components/PileupRendering.js +3 -5
  111. package/esm/PileupRenderer/getAlignmentShapeColor.js +1 -1
  112. package/esm/PileupRenderer/layoutFeature.js +1 -2
  113. package/esm/PileupRenderer/makeImageData.d.ts +1 -3
  114. package/esm/PileupRenderer/renderMethylation.js +5 -10
  115. package/esm/PileupRenderer/renderMismatches.d.ts +2 -6
  116. package/esm/PileupRenderer/renderMismatches.js +8 -11
  117. package/esm/PileupRenderer/renderModifications.js +4 -8
  118. package/esm/PileupRenderer/renderSoftClipping.js +26 -25
  119. package/esm/PileupRenderer/sortUtil.js +2 -2
  120. package/esm/SNPCoverageAdapter/util.d.ts +9 -13
  121. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +6 -12
  122. package/esm/index.d.ts +1 -1
  123. package/esm/index.js +1 -1
  124. package/esm/shared/BaseDisplayComponent.d.ts +2 -2
  125. package/esm/shared/BaseDisplayComponent.js +3 -2
  126. package/esm/shared/FilterByTag.d.ts +6 -15
  127. package/esm/shared/FilterByTag.js +4 -6
  128. package/esm/shared/color.d.ts +10 -0
  129. package/esm/shared/color.js +6 -0
  130. package/esm/shared/fetchChains.js +1 -0
  131. package/esm/shared/index.d.ts +9 -0
  132. package/esm/util.d.ts +3 -9
  133. package/package.json +3 -4
@@ -3,6 +3,7 @@ import { observable } from 'mobx';
3
3
  import { getConf, readConfObject, } from '@jbrowse/core/configuration';
4
4
  import { linearWiggleDisplayModelFactory } from '@jbrowse/plugin-wiggle';
5
5
  import { getContainingView } from '@jbrowse/core/util';
6
+ import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
6
7
  // locals
7
8
  import Tooltip from '../components/Tooltip';
8
9
  import { FilterModel, getUniqueModificationValues } from '../../shared';
@@ -44,6 +45,10 @@ function stateModelFactory(pluginManager, configSchema) {
44
45
  type: types.string,
45
46
  tag: types.maybe(types.string),
46
47
  })),
48
+ /**
49
+ * #property
50
+ */
51
+ jexlFilters: types.optional(types.array(types.string), []),
47
52
  }))
48
53
  .volatile(() => ({
49
54
  modificationTagMap: observable.map({}),
@@ -68,6 +73,12 @@ function stateModelFactory(pluginManager, configSchema) {
68
73
  setColorBy(colorBy) {
69
74
  self.colorBy = cast(colorBy);
70
75
  },
76
+ /**
77
+ * #action
78
+ */
79
+ setJexlFilters(filters) {
80
+ self.jexlFilters = cast(filters);
81
+ },
71
82
  /**
72
83
  * #action
73
84
  */
@@ -142,6 +153,7 @@ function stateModelFactory(pluginManager, configSchema) {
142
153
  return {
143
154
  ...superProps,
144
155
  notReady: !this.ready,
156
+ filters: self.filters,
145
157
  modificationTagMap: Object.fromEntries(modificationTagMap.toJSON()),
146
158
  // must use getSnapshot because otherwise changes to e.g. just the
147
159
  // colorBy.type are not read
@@ -264,6 +276,12 @@ function stateModelFactory(pluginManager, configSchema) {
264
276
  },
265
277
  ];
266
278
  },
279
+ /**
280
+ * #getter
281
+ */
282
+ get filters() {
283
+ return new SerializableFilterChain({ filters: self.jexlFilters });
284
+ },
267
285
  };
268
286
  });
269
287
  }
@@ -146,8 +146,7 @@ export function mdToMismatches(mdstring, ops, cigarMismatches, seq, qual) {
146
146
  }
147
147
  // now actually parse the MD string
148
148
  const md = mdstring.match(mdRegex) || [];
149
- for (let i = 0; i < md.length; i++) {
150
- const token = md[i];
149
+ for (const token of md) {
151
150
  const num = +token;
152
151
  if (!Number.isNaN(num)) {
153
152
  curr.start += num;
@@ -157,6 +156,7 @@ export function mdToMismatches(mdstring, ops, cigarMismatches, seq, qual) {
157
156
  }
158
157
  else {
159
158
  // mismatch
159
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
160
160
  for (let j = 0; j < token.length; j += 1) {
161
161
  curr.length = 1;
162
162
  while (lastSkipPos < skips.length) {
@@ -264,8 +264,7 @@ export function getModificationPositions(mm, fseq, fstrand) {
264
264
  const seq = fstrand === -1 ? revcom(fseq) : fseq;
265
265
  const mods = mm.split(';').filter(mod => !!mod);
266
266
  const result = [];
267
- for (let i = 0; i < mods.length; i++) {
268
- const mod = mods[i];
267
+ for (const mod of mods) {
269
268
  const [basemod, ...skips] = mod.split(',');
270
269
  // regexes based on parse_mm.pl from hts-specs
271
270
  const matches = basemod.match(modificationRegex);
@@ -285,12 +284,11 @@ export function getModificationPositions(mm, fseq, fstrand) {
285
284
  // sequence of the read, if we have a modification type e.g. C+m;2 and a
286
285
  // sequence ACGTACGTAC we skip the two instances of C and go to the last
287
286
  // C
288
- for (let j = 0; j < types.length; j++) {
289
- const type = types[j];
287
+ for (const type of types) {
290
288
  let i = 0;
291
289
  const positions = [];
292
- for (let k = 0; k < skips.length; k++) {
293
- let delta = +skips[k];
290
+ for (const d of skips) {
291
+ let delta = +d;
294
292
  do {
295
293
  if (base === 'N' || base === seq[i]) {
296
294
  delta--;
@@ -53,7 +53,6 @@ export default class PileupRenderer extends BoxRendererType {
53
53
  : undefined;
54
54
  const width = (region.end - region.start) / bpPerPx;
55
55
  const height = Math.max(layout.getTotalHeight(), 1);
56
- const Color = await import('color').then(f => f.default);
57
56
  const res = await renderToAbstractCanvas(width, height, renderProps, ctx => makeImageData({
58
57
  ctx,
59
58
  layoutRecords: layoutRecords.filter(notEmpty),
@@ -63,7 +62,6 @@ export default class PileupRenderer extends BoxRendererType {
63
62
  layout,
64
63
  features,
65
64
  regionSequence,
66
- Color,
67
65
  },
68
66
  }));
69
67
  const results = await super.render({
@@ -8,7 +8,7 @@ export function colorByInsertSize(feature) {
8
8
  : `hsl(${Math.abs(feature.get('template_length')) / 10},50%,50%)`;
9
9
  }
10
10
  export function colorByMappingQuality(feature) {
11
- return `hsl(${feature.get('mq')},50%,50%)`;
11
+ return `hsl(${feature.get('score')},50%,50%)`;
12
12
  }
13
13
  function getOrientation(feature, config) {
14
14
  const orientationType = readConfObject(config, 'orientationType');
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Region } from '@jbrowse/core/util/types';
3
3
  import type { BaseLinearDisplayModel } from '@jbrowse/plugin-linear-genome-view';
4
- declare function PileupRendering(props: {
4
+ declare const PileupRendering: (props: {
5
5
  blockKey: string;
6
6
  displayModel: BaseLinearDisplayModel;
7
7
  width: number;
@@ -12,17 +12,16 @@ declare function PileupRendering(props: {
12
12
  type: string;
13
13
  pos: number;
14
14
  refName: string;
15
- };
15
+ } | undefined;
16
16
  colorBy?: {
17
17
  type: string;
18
- tag?: string;
19
- };
18
+ tag?: string | undefined;
19
+ } | undefined;
20
20
  filterBy?: {
21
21
  tagFilter?: {
22
22
  tag: string;
23
- };
24
- };
25
- onMouseMove?: (event: React.MouseEvent, featureId?: string) => void;
26
- }): React.JSX.Element;
27
- declare const _default: typeof PileupRendering;
28
- export default _default;
23
+ } | undefined;
24
+ } | undefined;
25
+ onMouseMove?: ((event: React.MouseEvent, featureId?: string) => void) | undefined;
26
+ }) => React.JSX.Element;
27
+ export default PileupRendering;
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react';
5
5
  // used so that user can click-away-from-feature below the laid out features
6
6
  // (issue #1248)
7
7
  const canvasPadding = 100;
8
- function PileupRendering(props) {
8
+ const PileupRendering = observer(function (props) {
9
9
  var _a;
10
10
  const { onMouseMove, blockKey, displayModel, width, height, regions, bpPerPx, sortedBy, colorBy, filterBy, } = props;
11
11
  const { selectedFeatureId, featureIdUnderMouse, contextMenuFeature } = displayModel;
@@ -108,10 +108,8 @@ function PileupRendering(props) {
108
108
  }
109
109
  function callMouseHandler(handlerName, event) {
110
110
  // @ts-expect-error
111
- // eslint-disable-next-line react/destructuring-assignment
112
111
  const featureHandler = props[`onFeature${handlerName}`];
113
112
  // @ts-expect-error
114
- // eslint-disable-next-line react/destructuring-assignment
115
113
  const canvasHandler = props[`on${handlerName}`];
116
114
  if (featureHandler && featureIdUnderMouse) {
117
115
  featureHandler(event, featureIdUnderMouse);
@@ -132,5 +130,5 @@ function PileupRendering(props) {
132
130
  .join('-')}`, style: { position: 'relative', width: canvasWidth, height } },
133
131
  React.createElement(PrerenderedCanvas, { ...props, style: { position: 'absolute', left: 0, top: 0 } }),
134
132
  React.createElement("canvas", { "data-testid": "pileup_overlay_canvas", width: canvasWidth, height: height + canvasPadding, style: { position: 'absolute', left: 0, top: 0 }, className: "highlightOverlayCanvas", ref: highlightOverlayCanvas, onMouseDown: event => onMouseDown(event), onMouseEnter: event => onMouseEnter(event), onMouseOut: event => onMouseOut(event), onMouseOver: event => onMouseOver(event), onMouseUp: event => onMouseUp(event), onMouseLeave: event => onMouseLeave(event), onMouseMove: event => mouseMove(event), onClick: event => onClick(event), onContextMenu: event => onContextMenu(event), onFocus: () => { }, onBlur: () => { } })));
135
- }
136
- export default observer(PileupRendering);
133
+ });
134
+ export default PileupRendering;
@@ -36,7 +36,7 @@ export function getAlignmentShapeColor({ colorType, tag, feature, config, defaul
36
36
  }[val] || 'color_nostrand'];
37
37
  }
38
38
  else {
39
- return colorTagMap[val] || fillColor['color_nostrand'];
39
+ return colorTagMap[val] || fillColor.color_nostrand;
40
40
  }
41
41
  }
42
42
  case 'insertSizeAndPairOrientation':
@@ -7,8 +7,7 @@ export function layoutFeature({ feature, layout, bpPerPx, region, showSoftClip,
7
7
  const mismatches = feature.get('mismatches');
8
8
  const seq = feature.get('seq');
9
9
  if (seq) {
10
- for (let i = 0; i < mismatches.length; i += 1) {
11
- const { type, start, cliplen = 0 } = mismatches[i];
10
+ for (const { type, start, cliplen = 0 } of mismatches) {
12
11
  if (type === 'softclip') {
13
12
  start === 0 ? (expansionBefore = cliplen) : (expansionAfter = cliplen);
14
13
  }
@@ -1,8 +1,6 @@
1
1
  import { Feature } from '@jbrowse/core/util';
2
2
  import { RenderArgsDeserializedWithFeaturesAndLayout } from './PileupRenderer';
3
- export interface RenderArgsWithColor extends RenderArgsDeserializedWithFeaturesAndLayout {
4
- Color: Awaited<typeof import('color')>;
5
- }
3
+ export type RenderArgsWithColor = RenderArgsDeserializedWithFeaturesAndLayout;
6
4
  interface LayoutFeature {
7
5
  heightPx: number;
8
6
  topPx: number;
@@ -1,11 +1,12 @@
1
1
  import { bpSpanPx } from '@jbrowse/core/util';
2
2
  import { getMethBins } from '../MismatchParser';
3
3
  import { fillRect } from './util';
4
+ import { colord } from '@jbrowse/core/util/colord';
4
5
  // Color by methylation is slightly modified version of color by
5
6
  // modifications that focuses on CpG sites, with non-methylated CpG colored
6
7
  export function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, }) {
7
8
  var _a, _b;
8
- const { regionSequence, Color } = renderArgs;
9
+ const { regionSequence } = renderArgs;
9
10
  const { feature, topPx, heightPx } = feat;
10
11
  if (!regionSequence) {
11
12
  throw new Error('region sequence required for methylation');
@@ -20,15 +21,9 @@ export function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canv
20
21
  function getCol(k) {
21
22
  if (methBins[k]) {
22
23
  const p = methProbs[k] || 0;
23
- return p > 0.5
24
- ? Color('red')
25
- .alpha((p - 0.5) * 2)
26
- .hsl()
27
- .string()
28
- : Color('blue')
29
- .alpha(1 - p * 2)
30
- .hsl()
31
- .string();
24
+ return (p > 0.5
25
+ ? colord('red').alpha((p - 0.5) * 2)
26
+ : colord('blue').alpha(1 - p * 2)).toHslString();
32
27
  }
33
28
  return undefined;
34
29
  }
@@ -4,12 +4,8 @@ export declare function renderMismatches({ ctx, feat, renderArgs, minSubfeatureW
4
4
  ctx: CanvasRenderingContext2D;
5
5
  feat: LayoutFeature;
6
6
  renderArgs: RenderArgsWithColor;
7
- colorForBase: {
8
- [key: string]: string;
9
- };
10
- contrastForBase: {
11
- [key: string]: string;
12
- };
7
+ colorForBase: Record<string, string>;
8
+ contrastForBase: Record<string, string>;
13
9
  mismatchAlpha?: boolean;
14
10
  drawIndels?: boolean;
15
11
  drawSNPsMuted?: boolean;
@@ -1,7 +1,8 @@
1
1
  import { bpSpanPx, measureText } from '@jbrowse/core/util';
2
2
  import { fillRect } from './util';
3
+ import { colord } from '@jbrowse/core/util/colord';
3
4
  export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight, colorForBase, contrastForBase, canvasWidth, drawSNPsMuted, drawIndels = true, }) {
4
- const { Color, bpPerPx, regions } = renderArgs;
5
+ const { bpPerPx, regions } = renderArgs;
5
6
  const { heightPx, topPx, feature } = feat;
6
7
  const [region] = regions;
7
8
  const start = feature.get('start');
@@ -16,8 +17,7 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
16
17
  }
17
18
  // two pass rendering: first pass, draw all the mismatches except wide
18
19
  // insertion markers
19
- for (let i = 0; i < mismatches.length; i += 1) {
20
- const mismatch = mismatches[i];
20
+ for (const mismatch of mismatches) {
21
21
  const mstart = start + mismatch.start;
22
22
  const mlen = mismatch.length;
23
23
  const mbase = mismatch.base;
@@ -29,10 +29,9 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
29
29
  const c = mismatchAlpha
30
30
  ? mismatch.qual === undefined
31
31
  ? baseColor
32
- : Color(baseColor)
32
+ : colord(baseColor)
33
33
  .alpha(Math.min(1, mismatch.qual / 50))
34
- .hsl()
35
- .string()
34
+ .toHslString()
36
35
  : baseColor;
37
36
  fillRect(ctx, Math.round(leftPx), topPx, widthPx, heightPx, canvasWidth, c);
38
37
  }
@@ -44,10 +43,9 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
44
43
  ctx.fillStyle = mismatchAlpha
45
44
  ? mismatch.qual === undefined
46
45
  ? contrastColor
47
- : Color(contrastColor)
46
+ : colord(contrastColor)
48
47
  .alpha(Math.min(1, mismatch.qual / 50))
49
- .hsl()
50
- .string()
48
+ .toHslString()
51
49
  : contrastColor;
52
50
  ctx.fillText(mbase, leftPx + (widthPx - charWidth) / 2 + 1, topPx + heightPx);
53
51
  }
@@ -102,8 +100,7 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
102
100
  }
103
101
  // second pass, draw wide insertion markers on top
104
102
  if (drawIndels) {
105
- for (let i = 0; i < mismatches.length; i += 1) {
106
- const mismatch = mismatches[i];
103
+ for (const mismatch of mismatches) {
107
104
  const mstart = start + mismatch.start;
108
105
  const mlen = mismatch.length;
109
106
  const [leftPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx);
@@ -2,6 +2,7 @@ import { bpSpanPx } from '@jbrowse/core/util';
2
2
  import { getModificationPositions, getModificationProbabilities, getNextRefPos, parseCigar, } from '../MismatchParser';
3
3
  import { getTagAlt } from '../util';
4
4
  import { fillRect } from './util';
5
+ import { colord } from '@jbrowse/core/util/colord';
5
6
  // render modifications stored in MM tag in BAM
6
7
  //
7
8
  // ML stores probabilities as array of numerics and MP is scaled phred scores
@@ -14,7 +15,7 @@ import { fillRect } from './util';
14
15
  // about low qual calls <20 approx
15
16
  export function renderModifications({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, }) {
16
17
  const { feature, topPx, heightPx } = feat;
17
- const { Color, modificationTagMap = {} } = renderArgs;
18
+ const { modificationTagMap = {} } = renderArgs;
18
19
  const seq = feature.get('seq');
19
20
  if (!seq) {
20
21
  return;
@@ -30,17 +31,12 @@ export function renderModifications({ ctx, feat, region, bpPerPx, renderArgs, ca
30
31
  let probIndex = 0;
31
32
  for (const { type, positions } of modifications) {
32
33
  const col = modificationTagMap[type] || 'black';
33
- const base = Color(col);
34
+ const base = colord(col);
34
35
  for (const readPos of getNextRefPos(cigarOps, positions)) {
35
36
  const r = start + readPos;
36
37
  const [leftPx, rightPx] = bpSpanPx(r, r + 1, region, bpPerPx);
37
38
  const prob = (probabilities === null || probabilities === void 0 ? void 0 : probabilities[probIndex]) || 0;
38
- const c = prob !== 1
39
- ? base
40
- .alpha(prob + 0.1)
41
- .hsl()
42
- .string()
43
- : col;
39
+ const c = prob !== 1 ? base.alpha(prob + 0.1).toHslString() : col;
44
40
  const w = rightPx - leftPx + 0.5;
45
41
  fillRect(ctx, leftPx, topPx, w, heightPx, canvasWidth, c);
46
42
  probIndex++;
@@ -13,31 +13,32 @@ export function renderSoftClipping({ ctx, feat, renderArgs, config, theme, color
13
13
  if (!(seq && mismatches)) {
14
14
  return;
15
15
  }
16
- mismatches
17
- .filter(mismatch => mismatch.type === 'softclip')
18
- .forEach(mismatch => {
19
- const len = mismatch.cliplen || 0;
20
- const s = feature.get('start');
21
- const start = mismatch.start === 0 ? s - len : s + mismatch.start;
22
- for (let k = 0; k < len; k += 1) {
23
- const base = seq.charAt(k + mismatch.start);
24
- // If softclip length+start is longer than sequence, no need to
25
- // continue showing base
26
- if (!base) {
27
- return;
28
- }
29
- const s0 = start + k;
30
- const [leftPx, rightPx] = bpSpanPx(s0, s0 + 1, region, bpPerPx);
31
- const widthPx = Math.max(minFeatWidth, rightPx - leftPx);
32
- // Black accounts for IUPAC ambiguity code bases such as N that
33
- // show in soft clipping
34
- const baseColor = colorForBase[base] || '#000000';
35
- ctx.fillStyle = baseColor;
36
- fillRect(ctx, leftPx, topPx, widthPx, heightPx, canvasWidth);
37
- if (widthPx >= charWidth && heightPx >= charHeight - 5) {
38
- ctx.fillStyle = theme.palette.getContrastText(baseColor);
39
- ctx.fillText(base, leftPx + (widthPx - charWidth) / 2 + 1, topPx + heightPx);
16
+ const heightLim = charHeight - 2;
17
+ for (const mismatch of mismatches) {
18
+ if (mismatch.type === 'softclip') {
19
+ const len = mismatch.cliplen || 0;
20
+ const s = feature.get('start');
21
+ const start = mismatch.start === 0 ? s - len : s + mismatch.start;
22
+ for (let k = 0; k < len; k += 1) {
23
+ const base = seq.charAt(k + mismatch.start);
24
+ // If softclip length+start is longer than sequence, no need to
25
+ // continue showing base
26
+ if (!base) {
27
+ return;
28
+ }
29
+ const s0 = start + k;
30
+ const [leftPx, rightPx] = bpSpanPx(s0, s0 + 1, region, bpPerPx);
31
+ const widthPx = Math.max(minFeatWidth, rightPx - leftPx);
32
+ // Black accounts for IUPAC ambiguity code bases such as N that
33
+ // show in soft clipping
34
+ const baseColor = colorForBase[base] || '#000000';
35
+ ctx.fillStyle = baseColor;
36
+ fillRect(ctx, leftPx, topPx, widthPx, heightPx, canvasWidth);
37
+ if (widthPx >= charWidth && heightPx >= heightLim) {
38
+ ctx.fillStyle = theme.palette.getContrastText(baseColor);
39
+ ctx.fillText(base, leftPx + (widthPx - charWidth) / 2 + 1, topPx + heightPx);
40
+ }
40
41
  }
41
42
  }
42
- });
43
+ }
43
44
  }
@@ -56,8 +56,8 @@ export const sortFeature = (features, sortedBy) => {
56
56
  featuresInCenterLine.sort((a, b) => {
57
57
  const aMismatch = baseMap.get(a.id());
58
58
  const bMismatch = baseMap.get(b.id());
59
- const acode = bMismatch && bMismatch.base.toUpperCase();
60
- const bcode = aMismatch && aMismatch.base.toUpperCase();
59
+ const acode = bMismatch === null || bMismatch === void 0 ? void 0 : bMismatch.base.toUpperCase();
60
+ const bcode = aMismatch === null || aMismatch === void 0 ? void 0 : aMismatch.base.toUpperCase();
61
61
  if (acode === bcode && acode === '*') {
62
62
  // @ts-expect-error
63
63
  return aMismatch.length - bMismatch.length;
@@ -1,18 +1,14 @@
1
- export interface SkipMap {
2
- [key: string]: {
3
- score: number;
4
- feature: unknown;
5
- start: number;
6
- end: number;
7
- strand: number;
8
- xs: string;
9
- };
10
- }
1
+ export type SkipMap = Record<string, {
2
+ score: number;
3
+ feature: unknown;
4
+ start: number;
5
+ end: number;
6
+ strand: number;
7
+ xs: string;
8
+ }>;
11
9
  export interface BinType {
12
10
  total?: number;
13
- strands?: {
14
- [key: string]: number;
15
- };
11
+ strands?: Record<string, number>;
16
12
  }
17
13
  export interface Bin {
18
14
  refbase?: string;
@@ -59,8 +59,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
59
59
  // Use two pass rendering, which helps in visualizing the SNPs at higher
60
60
  // bpPerPx First pass: draw the gray background
61
61
  ctx.fillStyle = colorForBase.total;
62
- for (let i = 0; i < coverage.length; i++) {
63
- const feature = coverage[i];
62
+ for (const feature of coverage) {
64
63
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
65
64
  const w = rightPx - leftPx + fudgeFactor;
66
65
  const score = feature.get('score');
@@ -78,8 +77,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
78
77
  // Second pass: draw the SNP data, and add a minimum feature width of 1px
79
78
  // which can be wider than the actual bpPerPx This reduces overdrawing of
80
79
  // the grey background over the SNPs
81
- for (let i = 0; i < coverage.length; i++) {
82
- const feature = coverage[i];
80
+ for (const feature of coverage) {
83
81
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
84
82
  const score = feature.get('score');
85
83
  const snpinfo = feature.get('snpinfo');
@@ -87,8 +85,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
87
85
  const totalScore = snpinfo.total;
88
86
  const keys = Object.keys(snpinfo.cov).sort();
89
87
  let curr = 0;
90
- for (let i = 0; i < keys.length; i++) {
91
- const base = keys[i];
88
+ for (const base of keys) {
92
89
  const { total } = snpinfo.cov[base];
93
90
  ctx.fillStyle =
94
91
  colorForBase[base] ||
@@ -103,8 +100,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
103
100
  const indicatorHeight = 4.5;
104
101
  if (drawInterbaseCounts) {
105
102
  let curr = 0;
106
- for (let i = 0; i < interbaseEvents.length; i++) {
107
- const base = interbaseEvents[i];
103
+ for (const base of interbaseEvents) {
108
104
  const { total } = snpinfo.noncov[base];
109
105
  const r = 0.6;
110
106
  ctx.fillStyle = colorForBase[base];
@@ -116,8 +112,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
116
112
  let accum = 0;
117
113
  let max = 0;
118
114
  let maxBase = '';
119
- for (let i = 0; i < interbaseEvents.length; i++) {
120
- const base = interbaseEvents[i];
115
+ for (const base of interbaseEvents) {
121
116
  const { total } = snpinfo.noncov[base];
122
117
  accum += total;
123
118
  if (total > max) {
@@ -142,8 +137,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
142
137
  prevTotal = totalScore;
143
138
  }
144
139
  if (drawArcs) {
145
- for (let i = 0; i < skips.length; i++) {
146
- const f = skips[i];
140
+ for (const f of skips) {
147
141
  const [left, right] = bpSpanPx(f.get('start'), f.get('end'), region, bpPerPx);
148
142
  ctx.beginPath();
149
143
  const str = f.get('strand');
package/esm/index.d.ts CHANGED
@@ -4,6 +4,6 @@ export default class AlignmentsPlugin extends Plugin {
4
4
  name: string;
5
5
  install(pluginManager: PluginManager): void;
6
6
  }
7
- export { linearPileupDisplayStateModelFactory, linearPileupDisplayConfigSchemaFactory, } from './LinearPileupDisplay';
7
+ export { linearPileupDisplayStateModelFactory, linearPileupDisplayConfigSchemaFactory, SharedLinearPileupDisplayMixin, } from './LinearPileupDisplay';
8
8
  export { type LinearPileupDisplayModel } from './LinearPileupDisplay/model';
9
9
  export * as MismatchParser from './MismatchParser';
package/esm/index.js CHANGED
@@ -40,5 +40,5 @@ export default class AlignmentsPlugin extends Plugin {
40
40
  ].map(f => f(pluginManager));
41
41
  }
42
42
  }
43
- export { linearPileupDisplayStateModelFactory, linearPileupDisplayConfigSchemaFactory, } from './LinearPileupDisplay';
43
+ export { linearPileupDisplayStateModelFactory, linearPileupDisplayConfigSchemaFactory, SharedLinearPileupDisplayMixin, } from './LinearPileupDisplay';
44
44
  export * as MismatchParser from './MismatchParser';
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import { LinearReadCloudDisplayModel } from '../LinearReadCloudDisplay/model';
3
3
  import { LinearReadArcsDisplayModel } from '../LinearReadArcsDisplay/model';
4
- declare const _default: ({ model, children, }: {
4
+ declare const BaseDisplayComponent: ({ model, children, }: {
5
5
  model: LinearReadArcsDisplayModel | LinearReadCloudDisplayModel;
6
6
  children?: React.ReactNode;
7
7
  }) => React.JSX.Element | null;
8
- export default _default;
8
+ export default BaseDisplayComponent;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { LoadingEllipses } from '@jbrowse/core/ui';
3
- import { BlockMsg } from '@jbrowse/plugin-linear-genome-view';
3
+ import { BlockMsg, } from '@jbrowse/plugin-linear-genome-view';
4
4
  import { makeStyles } from 'tss-react/mui';
5
5
  import { observer } from 'mobx-react';
6
6
  import { getContainingView } from '@jbrowse/core/util';
@@ -20,7 +20,7 @@ const useStyles = makeStyles()(theme => {
20
20
  },
21
21
  };
22
22
  });
23
- export default observer(function ({ model, children, }) {
23
+ const BaseDisplayComponent = observer(function ({ model, children, }) {
24
24
  const { error, regionTooLarge } = model;
25
25
  return error ? (React.createElement(BlockMsg, { message: `${error}`, severity: "error", buttonText: "Reload", action: model.reload })) : regionTooLarge ? (model.regionCannotBeRendered()) : (React.createElement(DataDisplay, { model: model }, children));
26
26
  });
@@ -41,3 +41,4 @@ const LoadingBar = observer(function ({ model, }) {
41
41
  return (React.createElement("div", { className: classes.loading },
42
42
  React.createElement(LoadingEllipses, { message: message })));
43
43
  });
44
+ export default BaseDisplayComponent;
@@ -1,19 +1,10 @@
1
1
  import React from 'react';
2
- interface FilterBy {
3
- flagExclude: number;
4
- flagInclude: number;
5
- readName?: string;
6
- tagFilter?: {
7
- tag: string;
8
- value: string;
9
- };
10
- }
11
- declare function FilterByTagDlg(props: {
2
+ import { IFilter } from '.';
3
+ declare const FilterByTagDialog: (props: {
12
4
  model: {
13
- filterBy: FilterBy;
14
- setFilterBy: (arg: FilterBy) => void;
5
+ filterBy: IFilter;
6
+ setFilterBy: (arg: IFilter) => void;
15
7
  };
16
8
  handleClose: () => void;
17
- }): React.JSX.Element;
18
- declare const _default: typeof FilterByTagDlg;
19
- export default _default;
9
+ }) => React.JSX.Element;
10
+ export default FilterByTagDialog;
@@ -45,7 +45,7 @@ function Bitmask(props) {
45
45
  React.createElement("label", { htmlFor: key }, name)));
46
46
  })));
47
47
  }
48
- function FilterByTagDlg(props) {
48
+ const FilterByTagDialog = observer(function (props) {
49
49
  var _a, _b;
50
50
  const { model, handleClose } = props;
51
51
  const { classes } = useStyles();
@@ -74,9 +74,7 @@ function FilterByTagDlg(props) {
74
74
  React.createElement(Bitmask, { flag: flagExclude, setFlag: setFlagExclude })))),
75
75
  React.createElement(Paper, { className: classes.paper, variant: "outlined" },
76
76
  React.createElement(Typography, null, "Filter by tag name and value. Use * in the value field to get all reads containing any value for that tag. Example: filter tag name SA with value * to get all split/supplementary reads. Other examples include HP for haplotype, or RG for read group"),
77
- React.createElement(TextField, { className: classes.field, value: tag, onChange: event => setTag(event.target.value), placeholder: "Enter tag name", inputProps: {
78
- maxLength: 2,
79
- }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '' }),
77
+ React.createElement(TextField, { className: classes.field, value: tag, onChange: event => setTag(event.target.value), placeholder: "Enter tag name", inputProps: { maxLength: 2 }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '' }),
80
78
  React.createElement(TextField, { className: classes.field, value: tagValue, onChange: event => setTagValue(event.target.value), placeholder: "Enter tag value" })),
81
79
  React.createElement(Paper, { className: classes.paper, variant: "outlined" },
82
80
  React.createElement(Typography, null, "Filter by read name"),
@@ -97,5 +95,5 @@ function FilterByTagDlg(props) {
97
95
  handleClose();
98
96
  } }, "Submit"),
99
97
  React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
100
- }
101
- export default observer(FilterByTagDlg);
98
+ });
99
+ export default FilterByTagDialog;