@jbrowse/plugin-alignments 2.13.1 → 2.15.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 (155) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +5 -3
  2. package/dist/AlignmentsFeatureDetail/BreakendOptionDialog.js +12 -4
  3. package/dist/AlignmentsFeatureDetail/Formatter.js +6 -2
  4. package/dist/AlignmentsFeatureDetail/SuppAlignmentsLocStrings.js +4 -2
  5. package/dist/AlignmentsFeatureDetail/getSAFeatures.js +4 -4
  6. package/dist/AlignmentsFeatureDetail/launchBreakpointSplitView.js +2 -2
  7. package/dist/BamAdapter/BamAdapter.js +12 -18
  8. package/dist/BamAdapter/BamSlightlyLazyFeature.js +0 -1
  9. package/dist/CramAdapter/CramAdapter.d.ts +1 -1
  10. package/dist/CramAdapter/CramAdapter.js +7 -6
  11. package/dist/CramAdapter/CramTestAdapters.js +8 -2
  12. package/dist/GuessAlignmentsTypes/index.js +2 -2
  13. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +2 -2
  14. package/dist/LinearAlignmentsDisplay/models/model.d.ts +13 -20
  15. package/dist/LinearAlignmentsDisplay/models/model.js +13 -3
  16. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +9 -4
  17. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +41 -22
  18. package/dist/LinearPileupDisplay/components/{ColorByModifications.js → ColorByModificationsDialog.js} +3 -1
  19. package/dist/LinearPileupDisplay/components/{ColorByTag.js → ColorByTagDialog.js} +4 -2
  20. package/dist/LinearPileupDisplay/components/GroupByDialog.d.ts +11 -0
  21. package/dist/LinearPileupDisplay/components/GroupByDialog.js +129 -0
  22. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +1 -3
  23. package/dist/LinearPileupDisplay/components/{SetFeatureHeight.js → SetFeatureHeightDialog.js} +9 -3
  24. package/{esm/LinearPileupDisplay/components/SetMaxHeight.d.ts → dist/LinearPileupDisplay/components/SetMaxHeightDialog.d.ts} +1 -1
  25. package/dist/LinearPileupDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -3
  26. package/dist/LinearPileupDisplay/components/{SortByTag.d.ts → SortByTagDialog.d.ts} +1 -1
  27. package/dist/LinearPileupDisplay/components/{SortByTag.js → SortByTagDialog.js} +7 -3
  28. package/dist/LinearPileupDisplay/configSchema.js +0 -1
  29. package/dist/LinearPileupDisplay/model.d.ts +58 -46
  30. package/dist/LinearPileupDisplay/model.js +69 -41
  31. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +1 -0
  32. package/dist/LinearReadArcsDisplay/model.d.ts +2 -2
  33. package/dist/LinearReadArcsDisplay/model.js +37 -13
  34. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +4 -1
  35. package/dist/LinearReadCloudDisplay/drawPairChains.js +3 -3
  36. package/dist/LinearReadCloudDisplay/model.d.ts +4 -8
  37. package/dist/LinearReadCloudDisplay/model.js +16 -6
  38. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  39. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  40. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +1 -1
  41. package/dist/LinearSNPCoverageDisplay/models/model.js +15 -5
  42. package/dist/MismatchParser/index.js +12 -10
  43. package/dist/PileupRPC/base.d.ts +1 -1
  44. package/dist/PileupRPC/methods/GetGlobalValueForTag.d.ts +1 -1
  45. package/dist/PileupRPC/methods/GetReducedFeatures.d.ts +3 -3
  46. package/dist/PileupRPC/methods/GetVisibleModifications.d.ts +1 -1
  47. package/dist/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  48. package/dist/PileupRenderer/PileupLayoutSession.js +3 -2
  49. package/dist/PileupRenderer/PileupRenderer.d.ts +1 -1
  50. package/dist/PileupRenderer/PileupRenderer.js +16 -13
  51. package/dist/PileupRenderer/colorBy.js +3 -5
  52. package/dist/PileupRenderer/components/PileupRendering.d.ts +1 -1
  53. package/dist/PileupRenderer/components/PileupRendering.js +65 -60
  54. package/dist/PileupRenderer/getAlignmentShapeColor.js +24 -16
  55. package/dist/PileupRenderer/layoutFeature.js +6 -1
  56. package/dist/PileupRenderer/layoutFeatures.js +1 -7
  57. package/dist/PileupRenderer/makeImageData.d.ts +1 -1
  58. package/dist/PileupRenderer/makeImageData.js +1 -0
  59. package/dist/PileupRenderer/renderAlignmentShape.js +1 -1
  60. package/dist/PileupRenderer/renderMismatches.js +1 -1
  61. package/dist/PileupRenderer/renderSoftClipping.js +1 -1
  62. package/dist/PileupRenderer/util.js +3 -5
  63. package/dist/SNPCoverageAdapter/generateCoverageBins.js +4 -10
  64. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -2
  65. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +2 -5
  66. package/dist/index.js +3 -1
  67. package/dist/shared/BaseDisplayComponent.js +3 -1
  68. package/dist/shared/{FilterByTag.js → FilterByTagDialog.js} +16 -6
  69. package/dist/shared/color.js +2 -2
  70. package/dist/shared/index.d.ts +24 -20
  71. package/dist/shared/index.js +4 -5
  72. package/dist/shared/renderSvg.js +1 -3
  73. package/dist/util.d.ts +1 -1
  74. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +5 -3
  75. package/esm/AlignmentsFeatureDetail/BreakendOptionDialog.js +12 -4
  76. package/esm/AlignmentsFeatureDetail/Formatter.js +6 -2
  77. package/esm/AlignmentsFeatureDetail/SuppAlignmentsLocStrings.js +4 -2
  78. package/esm/AlignmentsFeatureDetail/getSAFeatures.js +4 -4
  79. package/esm/AlignmentsFeatureDetail/launchBreakpointSplitView.js +2 -2
  80. package/esm/BamAdapter/BamAdapter.js +12 -18
  81. package/esm/BamAdapter/BamSlightlyLazyFeature.js +0 -1
  82. package/esm/CramAdapter/CramAdapter.d.ts +1 -1
  83. package/esm/CramAdapter/CramAdapter.js +7 -6
  84. package/esm/CramAdapter/CramTestAdapters.js +8 -2
  85. package/esm/GuessAlignmentsTypes/index.js +2 -2
  86. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +2 -2
  87. package/esm/LinearAlignmentsDisplay/models/model.d.ts +13 -20
  88. package/esm/LinearAlignmentsDisplay/models/model.js +13 -3
  89. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +9 -4
  90. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +42 -23
  91. package/esm/LinearPileupDisplay/components/{ColorByModifications.js → ColorByModificationsDialog.js} +3 -1
  92. package/esm/LinearPileupDisplay/components/{ColorByTag.js → ColorByTagDialog.js} +4 -2
  93. package/esm/LinearPileupDisplay/components/GroupByDialog.d.ts +11 -0
  94. package/esm/LinearPileupDisplay/components/GroupByDialog.js +104 -0
  95. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +1 -3
  96. package/esm/LinearPileupDisplay/components/{SetFeatureHeight.js → SetFeatureHeightDialog.js} +9 -3
  97. package/{dist/LinearPileupDisplay/components/SetMaxHeight.d.ts → esm/LinearPileupDisplay/components/SetMaxHeightDialog.d.ts} +1 -1
  98. package/esm/LinearPileupDisplay/components/{SetMaxHeight.js → SetMaxHeightDialog.js} +7 -3
  99. package/esm/LinearPileupDisplay/components/{SortByTag.d.ts → SortByTagDialog.d.ts} +1 -1
  100. package/esm/LinearPileupDisplay/components/{SortByTag.js → SortByTagDialog.js} +7 -3
  101. package/esm/LinearPileupDisplay/configSchema.js +0 -1
  102. package/esm/LinearPileupDisplay/model.d.ts +58 -46
  103. package/esm/LinearPileupDisplay/model.js +69 -41
  104. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +1 -0
  105. package/esm/LinearReadArcsDisplay/model.d.ts +2 -2
  106. package/esm/LinearReadArcsDisplay/model.js +37 -13
  107. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +4 -1
  108. package/esm/LinearReadCloudDisplay/drawPairChains.js +3 -3
  109. package/esm/LinearReadCloudDisplay/model.d.ts +4 -8
  110. package/esm/LinearReadCloudDisplay/model.js +16 -6
  111. package/esm/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  112. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  113. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +1 -1
  114. package/esm/LinearSNPCoverageDisplay/models/model.js +15 -5
  115. package/esm/MismatchParser/index.js +12 -10
  116. package/esm/PileupRPC/base.d.ts +1 -1
  117. package/esm/PileupRPC/methods/GetGlobalValueForTag.d.ts +1 -1
  118. package/esm/PileupRPC/methods/GetReducedFeatures.d.ts +3 -3
  119. package/esm/PileupRPC/methods/GetVisibleModifications.d.ts +1 -1
  120. package/esm/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  121. package/esm/PileupRenderer/PileupLayoutSession.js +3 -2
  122. package/esm/PileupRenderer/PileupRenderer.d.ts +1 -1
  123. package/esm/PileupRenderer/PileupRenderer.js +16 -13
  124. package/esm/PileupRenderer/colorBy.js +3 -5
  125. package/esm/PileupRenderer/components/PileupRendering.d.ts +1 -1
  126. package/esm/PileupRenderer/components/PileupRendering.js +65 -60
  127. package/esm/PileupRenderer/getAlignmentShapeColor.js +24 -16
  128. package/esm/PileupRenderer/layoutFeature.js +6 -1
  129. package/esm/PileupRenderer/layoutFeatures.js +1 -7
  130. package/esm/PileupRenderer/makeImageData.d.ts +1 -1
  131. package/esm/PileupRenderer/makeImageData.js +1 -0
  132. package/esm/PileupRenderer/renderAlignmentShape.js +1 -1
  133. package/esm/PileupRenderer/renderMismatches.js +1 -1
  134. package/esm/PileupRenderer/renderSoftClipping.js +1 -1
  135. package/esm/PileupRenderer/util.js +3 -5
  136. package/esm/SNPCoverageAdapter/generateCoverageBins.js +4 -10
  137. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -2
  138. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +2 -5
  139. package/esm/index.js +3 -1
  140. package/esm/shared/BaseDisplayComponent.js +3 -1
  141. package/esm/shared/{FilterByTag.js → FilterByTagDialog.js} +16 -6
  142. package/esm/shared/color.js +2 -2
  143. package/esm/shared/index.d.ts +24 -20
  144. package/esm/shared/index.js +4 -5
  145. package/esm/shared/renderSvg.js +1 -3
  146. package/esm/util.d.ts +1 -1
  147. package/package.json +6 -6
  148. /package/dist/LinearPileupDisplay/components/{ColorByModifications.d.ts → ColorByModificationsDialog.d.ts} +0 -0
  149. /package/dist/LinearPileupDisplay/components/{ColorByTag.d.ts → ColorByTagDialog.d.ts} +0 -0
  150. /package/dist/LinearPileupDisplay/components/{SetFeatureHeight.d.ts → SetFeatureHeightDialog.d.ts} +0 -0
  151. /package/dist/shared/{FilterByTag.d.ts → FilterByTagDialog.d.ts} +0 -0
  152. /package/esm/LinearPileupDisplay/components/{ColorByModifications.d.ts → ColorByModificationsDialog.d.ts} +0 -0
  153. /package/esm/LinearPileupDisplay/components/{ColorByTag.d.ts → ColorByTagDialog.d.ts} +0 -0
  154. /package/esm/LinearPileupDisplay/components/{SetFeatureHeight.d.ts → SetFeatureHeightDialog.d.ts} +0 -0
  155. /package/esm/shared/{FilterByTag.d.ts → FilterByTagDialog.d.ts} +0 -0
@@ -2,65 +2,39 @@ import React, { useRef, useState, useEffect } from 'react';
2
2
  import { PrerenderedCanvas } from '@jbrowse/core/ui';
3
3
  import { bpSpanPx } from '@jbrowse/core/util';
4
4
  import { observer } from 'mobx-react';
5
- // used so that user can click-away-from-feature below the laid out features
6
- // (issue #1248)
7
- const canvasPadding = 100;
8
5
  const PileupRendering = observer(function (props) {
9
6
  var _a;
10
7
  const { onMouseMove, blockKey, displayModel, width, height, regions, bpPerPx, sortedBy, colorBy, filterBy, } = props;
11
- const { selectedFeatureId, featureIdUnderMouse, contextMenuFeature } = displayModel;
12
- const [region] = regions;
13
- const highlightOverlayCanvas = useRef(null);
8
+ const { selectedFeatureId, featureIdUnderMouse, contextMenuFeature } = displayModel || {};
9
+ const [firstRender, setFirstRender] = useState(false);
10
+ useEffect(() => {
11
+ setFirstRender(true);
12
+ }, []);
13
+ const region = regions[0];
14
+ const ref = useRef(null);
14
15
  const [mouseIsDown, setMouseIsDown] = useState(false);
15
16
  const [movedDuringLastMouseDown, setMovedDuringLastMouseDown] = useState(false);
16
- useEffect(() => {
17
- var _a, _b;
18
- const canvas = highlightOverlayCanvas.current;
19
- if (!canvas) {
20
- return;
21
- }
22
- const ctx = canvas.getContext('2d');
23
- if (!ctx) {
24
- return;
25
- }
26
- ctx.clearRect(0, 0, canvas.width, canvas.height);
27
- const selectedRect = selectedFeatureId
28
- ? (_a = displayModel.getFeatureByID) === null || _a === void 0 ? void 0 : _a.call(displayModel, blockKey, selectedFeatureId)
29
- : undefined;
30
- if (selectedRect) {
31
- const [leftBp, topPx, rightBp, bottomPx] = selectedRect;
32
- const [leftPx, rightPx] = bpSpanPx(leftBp, rightBp, region, bpPerPx);
33
- const rectTop = Math.round(topPx);
34
- const rectHeight = Math.round(bottomPx - topPx);
35
- ctx.shadowColor = '#222266';
36
- ctx.shadowBlur = 10;
37
- ctx.lineJoin = 'bevel';
38
- ctx.lineWidth = 2;
39
- ctx.strokeStyle = '#00b8ff';
40
- ctx.strokeRect(leftPx - 2, rectTop - 2, rightPx - leftPx + 4, rectHeight + 4);
41
- ctx.clearRect(leftPx, rectTop, rightPx - leftPx, rectHeight);
42
- }
43
- const highlightedFeature = featureIdUnderMouse || (contextMenuFeature === null || contextMenuFeature === void 0 ? void 0 : contextMenuFeature.id());
44
- const highlightedRect = highlightedFeature
45
- ? (_b = displayModel.getFeatureByID) === null || _b === void 0 ? void 0 : _b.call(displayModel, blockKey, highlightedFeature)
46
- : undefined;
47
- if (highlightedRect) {
48
- const [leftBp, topPx, rightBp, bottomPx] = highlightedRect;
49
- const [leftPx, rightPx] = bpSpanPx(leftBp, rightBp, region, bpPerPx);
50
- const rectTop = Math.round(topPx);
51
- const rectHeight = Math.round(bottomPx - topPx);
52
- ctx.fillStyle = '#0003';
53
- ctx.fillRect(leftPx, rectTop, rightPx - leftPx, rectHeight);
54
- }
55
- }, [
56
- bpPerPx,
57
- region,
58
- blockKey,
59
- selectedFeatureId,
60
- displayModel,
61
- featureIdUnderMouse,
62
- contextMenuFeature,
63
- ]);
17
+ const selectedRect = selectedFeatureId
18
+ ? displayModel === null || displayModel === void 0 ? void 0 : displayModel.getFeatureByID(blockKey, selectedFeatureId)
19
+ : undefined;
20
+ const highlightedFeature = featureIdUnderMouse || (contextMenuFeature === null || contextMenuFeature === void 0 ? void 0 : contextMenuFeature.id());
21
+ const highlightedRect = highlightedFeature
22
+ ? displayModel === null || displayModel === void 0 ? void 0 : displayModel.getFeatureByID(blockKey, highlightedFeature)
23
+ : undefined;
24
+ function makeRect(r, offset = 2) {
25
+ const [leftBp, topPx, rightBp, bottomPx] = r;
26
+ const [leftPx, rightPx] = bpSpanPx(leftBp, rightBp, region, bpPerPx);
27
+ const rectTop = Math.round(topPx);
28
+ const rectHeight = Math.round(bottomPx - topPx);
29
+ return {
30
+ left: leftPx - offset,
31
+ top: rectTop - offset,
32
+ width: rightPx - leftPx,
33
+ height: rectHeight,
34
+ };
35
+ }
36
+ const selected = selectedRect ? makeRect(selectedRect) : undefined;
37
+ const highlight = highlightedRect ? makeRect(highlightedRect, 0) : undefined;
64
38
  function onMouseDown(event) {
65
39
  setMouseIsDown(true);
66
40
  setMovedDuringLastMouseDown(false);
@@ -93,18 +67,18 @@ const PileupRendering = observer(function (props) {
93
67
  callMouseHandler('ContextMenu', event);
94
68
  }
95
69
  function mouseMove(event) {
96
- if (!highlightOverlayCanvas.current) {
70
+ if (!ref.current) {
97
71
  return;
98
72
  }
99
73
  if (mouseIsDown) {
100
74
  setMovedDuringLastMouseDown(true);
101
75
  }
102
- const rect = highlightOverlayCanvas.current.getBoundingClientRect();
76
+ const rect = ref.current.getBoundingClientRect();
103
77
  const offsetX = event.clientX - rect.left;
104
78
  const offsetY = event.clientY - rect.top;
105
79
  const px = region.reversed ? width - offsetX : offsetX;
106
80
  const clientBp = region.start + bpPerPx * px;
107
- onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(event, displayModel.getFeatureOverlapping(blockKey, clientBp, offsetY));
81
+ onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(event, displayModel === null || displayModel === void 0 ? void 0 : displayModel.getFeatureOverlapping(blockKey, clientBp, offsetY));
108
82
  }
109
83
  function callMouseHandler(handlerName, event) {
110
84
  // @ts-expect-error
@@ -120,15 +94,46 @@ const PileupRendering = observer(function (props) {
120
94
  }
121
95
  const canvasWidth = Math.ceil(width);
122
96
  // need to call this in render so we get the right observer behavior
123
- return (React.createElement("div", { "data-testid": `pileup-${[
97
+ return (React.createElement("div", { ref: ref, "data-testid": [
98
+ 'pileup-overlay',
124
99
  sortedBy === null || sortedBy === void 0 ? void 0 : sortedBy.type,
125
100
  colorBy === null || colorBy === void 0 ? void 0 : colorBy.type,
126
101
  colorBy === null || colorBy === void 0 ? void 0 : colorBy.tag,
127
102
  (_a = filterBy === null || filterBy === void 0 ? void 0 : filterBy.tagFilter) === null || _a === void 0 ? void 0 : _a.tag,
128
103
  ]
129
104
  .filter(f => !!f)
130
- .join('-')}`, style: { position: 'relative', width: canvasWidth, height } },
105
+ .join('-'), style: { position: 'relative', width: canvasWidth, height }, onMouseDown: event => {
106
+ onMouseDown(event);
107
+ }, onMouseEnter: event => {
108
+ onMouseEnter(event);
109
+ }, onMouseOut: event => {
110
+ onMouseOut(event);
111
+ }, onMouseOver: event => {
112
+ onMouseOver(event);
113
+ }, onMouseUp: event => {
114
+ onMouseUp(event);
115
+ }, onMouseLeave: event => {
116
+ onMouseLeave(event);
117
+ }, onMouseMove: event => {
118
+ mouseMove(event);
119
+ }, onClick: event => {
120
+ onClick(event);
121
+ }, onContextMenu: event => {
122
+ onContextMenu(event);
123
+ }, onFocus: () => { }, onBlur: () => { } },
131
124
  React.createElement(PrerenderedCanvas, { ...props, style: { position: 'absolute', left: 0, top: 0 } }),
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: () => { } })));
125
+ firstRender && highlight ? (React.createElement("div", { style: {
126
+ position: 'absolute',
127
+ backgroundColor: '#0003',
128
+ pointerEvents: 'none',
129
+ ...highlight,
130
+ } })) : null,
131
+ firstRender && selected ? (React.createElement("div", { style: {
132
+ position: 'absolute',
133
+ border: '2px solid #00b8ff',
134
+ boxSizing: 'content-box',
135
+ pointerEvents: 'none',
136
+ ...selected,
137
+ } })) : null));
133
138
  });
134
139
  export default PileupRendering;
@@ -20,24 +20,32 @@ export function getAlignmentShapeColor({ colorType, tag, feature, config, defaul
20
20
  const tags = feature.get('tags');
21
21
  const val = tags ? tags[tag] : feature.get(tag);
22
22
  if (tag === 'XS' || tag === 'TS') {
23
- return fillColor[{
24
- '-': 'color_rev_strand',
25
- '+': 'color_fwd_strand',
26
- }[val] || 'color_nostrand'];
23
+ if (val === '-') {
24
+ return fillColor.color_rev_strand;
25
+ }
26
+ else if (val === '+') {
27
+ return fillColor.color_fwd_strand;
28
+ }
29
+ else {
30
+ return fillColor.color_nostrand;
31
+ }
27
32
  }
28
- else if (tag === 'ts') {
29
- return fillColor[{
30
- '-': feature.get('strand') === -1
31
- ? 'color_fwd_strand'
32
- : 'color_rev_strand',
33
- '+': feature.get('strand') === -1
34
- ? 'color_rev_strand'
35
- : 'color_fwd_strand',
36
- }[val] || 'color_nostrand'];
37
- }
38
- else {
39
- return colorTagMap[val] || fillColor.color_nostrand;
33
+ if (tag === 'ts') {
34
+ if (val === '-') {
35
+ return feature.get('strand') === -1
36
+ ? fillColor.color_fwd_strand
37
+ : fillColor.color_rev_strand;
38
+ }
39
+ else if (val === '+') {
40
+ return feature.get('strand') === -1
41
+ ? fillColor.color_rev_strand
42
+ : fillColor.color_fwd_strand;
43
+ }
44
+ else {
45
+ return fillColor.color_nostrand;
46
+ }
40
47
  }
48
+ return colorTagMap[val] || fillColor.color_nostrand;
41
49
  }
42
50
  case 'insertSizeAndPairOrientation':
43
51
  break;
@@ -9,7 +9,12 @@ export function layoutFeature({ feature, layout, bpPerPx, region, showSoftClip,
9
9
  if (seq) {
10
10
  for (const { type, start, cliplen = 0 } of mismatches) {
11
11
  if (type === 'softclip') {
12
- start === 0 ? (expansionBefore = cliplen) : (expansionAfter = cliplen);
12
+ if (start === 0) {
13
+ expansionBefore = cliplen;
14
+ }
15
+ else {
16
+ expansionAfter = cliplen;
17
+ }
13
18
  }
14
19
  }
15
20
  }
@@ -6,13 +6,7 @@ import { sortFeature } from './sortUtil';
6
6
  // layout determines the height of the canvas that we use to render
7
7
  export function layoutFeats(props) {
8
8
  const { layout, features, sortedBy, config, bpPerPx, showSoftClip, regions } = props;
9
- const [region] = regions;
10
- if (!layout) {
11
- throw new Error(`layout required`);
12
- }
13
- if (!layout.addRect) {
14
- throw new Error('invalid layout object');
15
- }
9
+ const region = regions[0];
16
10
  const featureMap = (sortedBy === null || sortedBy === void 0 ? void 0 : sortedBy.type) && region.start === sortedBy.pos
17
11
  ? sortFeature(features, sortedBy)
18
12
  : features;
@@ -11,5 +11,5 @@ export declare function makeImageData({ ctx, layoutRecords, canvasWidth, renderA
11
11
  canvasWidth: number;
12
12
  layoutRecords: LayoutFeature[];
13
13
  renderArgs: RenderArgsWithColor;
14
- }): void;
14
+ }): undefined;
15
15
  export {};
@@ -56,4 +56,5 @@ export function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, })
56
56
  });
57
57
  }
58
58
  }
59
+ return undefined;
59
60
  }
@@ -2,7 +2,7 @@ import { bpSpanPx } from '@jbrowse/core/util';
2
2
  export function renderAlignmentShape({ ctx, feat, renderArgs, }) {
3
3
  const { regions, bpPerPx } = renderArgs;
4
4
  const { heightPx, topPx, feature } = feat;
5
- const [region] = regions;
5
+ const region = regions[0];
6
6
  const s = feature.get('start');
7
7
  const e = feature.get('end');
8
8
  const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx);
@@ -4,7 +4,7 @@ import { colord } from '@jbrowse/core/util/colord';
4
4
  export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight, colorForBase, contrastForBase, canvasWidth, drawSNPsMuted, drawIndels = true, }) {
5
5
  const { bpPerPx, regions } = renderArgs;
6
6
  const { heightPx, topPx, feature } = feat;
7
- const [region] = regions;
7
+ const region = regions[0];
8
8
  const start = feature.get('start');
9
9
  const pxPerBp = Math.min(1 / bpPerPx, 2);
10
10
  const mismatches = feature.get('mismatches');
@@ -6,7 +6,7 @@ import { fillRect, getCharWidthHeight } from './util';
6
6
  export function renderSoftClipping({ ctx, feat, renderArgs, config, theme, colorForBase, canvasWidth, }) {
7
7
  const { feature, topPx, heightPx } = feat;
8
8
  const { regions, bpPerPx } = renderArgs;
9
- const [region] = regions;
9
+ const region = regions[0];
10
10
  const minFeatWidth = readConfObject(config, 'minSubfeatureWidth');
11
11
  const mismatches = feature.get('mismatches');
12
12
  const seq = feature.get('seq');
@@ -3,12 +3,10 @@ export function fillRect(ctx, l, t, w, h, cw, color) {
3
3
  if (l + w < 0 || l > cw) {
4
4
  return;
5
5
  }
6
- else {
7
- if (color) {
8
- ctx.fillStyle = color;
9
- }
10
- ctx.fillRect(l, t, w, h);
6
+ if (color) {
7
+ ctx.fillStyle = color;
11
8
  }
9
+ ctx.fillRect(l, t, w, h);
12
10
  }
13
11
  export function getColorBaseMap(theme) {
14
12
  const { bases } = theme.palette;
@@ -7,7 +7,6 @@ function mismatchLen(mismatch) {
7
7
  function isInterbase(type) {
8
8
  return type === 'softclip' || type === 'hardclip' || type === 'insertion';
9
9
  }
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
10
  function inc(bin, strand, type, field) {
12
11
  let thisBin = bin[type][field];
13
12
  if (thisBin === undefined) {
@@ -92,12 +91,7 @@ export default async function generateCoverageBins(features, region, opts, fetch
92
91
  };
93
92
  }
94
93
  const bin = bins[epos];
95
- if (bin) {
96
- inc(bin, fstrand, 'cov', mod);
97
- }
98
- else {
99
- console.warn('Undefined position in modifications snpcoverage encountered');
100
- }
94
+ inc(bin, fstrand, 'cov', mod);
101
95
  }
102
96
  }
103
97
  }
@@ -142,14 +136,14 @@ export default async function generateCoverageBins(features, region, opts, fetch
142
136
  }
143
137
  else {
144
138
  if (bin0) {
145
- if (!(dels === null || dels === void 0 ? void 0 : dels.some(d => doesIntersect2(j, j + 1, d.start + fstart, d.start + fstart + d.length)))) {
139
+ if (!dels.some(d => doesIntersect2(j, j + 1, d.start + fstart, d.start + fstart + d.length))) {
146
140
  inc(bin0, fstrand, 'cov', 'unmeth');
147
141
  bin0.ref--;
148
- bin0[fstrand];
142
+ bin0[fstrand]--;
149
143
  }
150
144
  }
151
145
  if (bin1) {
152
- if (!(dels === null || dels === void 0 ? void 0 : dels.some(d => doesIntersect2(j + 1, j + 2, d.start + fstart, d.start + fstart + d.length)))) {
146
+ if (!dels.some(d => doesIntersect2(j + 1, j + 2, d.start + fstart, d.start + fstart + d.length))) {
153
147
  inc(bin1, fstrand, 'cov', 'unmeth');
154
148
  bin1.ref--;
155
149
  bin1[fstrand]--;
@@ -13,8 +13,8 @@ export interface RenderArgsDeserializedWithFeatures extends RenderArgsDeserializ
13
13
  values: number[];
14
14
  };
15
15
  displayCrossHatches: boolean;
16
- modificationTagMap?: Record<string, string | undefined>;
16
+ modificationTagMap?: Record<string, string>;
17
17
  }
18
18
  export default class SNPCoverageRenderer extends WiggleBaseRenderer {
19
- draw(ctx: CanvasRenderingContext2D, props: RenderArgsDeserializedWithFeatures): Promise<void>;
19
+ draw(ctx: CanvasRenderingContext2D, props: RenderArgsDeserializedWithFeatures): Promise<undefined>;
20
20
  }
@@ -9,17 +9,13 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
9
9
  async draw(ctx, props) {
10
10
  const { features, regions, bpPerPx, displayCrossHatches, modificationTagMap = {}, scaleOpts, height: unadjustedHeight, theme: configTheme, config: cfg, ticks, } = props;
11
11
  const theme = createJBrowseTheme(configTheme);
12
- const [region] = regions;
12
+ const region = regions[0];
13
13
  const width = (region.end - region.start) / bpPerPx;
14
14
  // the adjusted height takes into account YSCALEBAR_LABEL_OFFSET from the
15
15
  // wiggle display, and makes the height of the actual drawn area add
16
16
  // "padding" to the top and bottom of the display
17
17
  const offset = YSCALEBAR_LABEL_OFFSET;
18
18
  const height = unadjustedHeight - offset * 2;
19
- const { domain } = scaleOpts;
20
- if (!domain) {
21
- return;
22
- }
23
19
  const opts = { ...scaleOpts, range: [0, height] };
24
20
  const viewScale = getScale(opts);
25
21
  // clipping and insertion indicators, uses a smaller height/2 scale
@@ -176,5 +172,6 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
176
172
  ctx.stroke();
177
173
  });
178
174
  }
175
+ return undefined;
179
176
  }
180
177
  }
package/esm/index.js CHANGED
@@ -37,7 +37,9 @@ export default class AlignmentsPlugin extends Plugin {
37
37
  LinearAlignmentsDisplayF,
38
38
  AlignmentsFeatureWidgetF,
39
39
  GuessAlignmentsTypesF,
40
- ].map(f => f(pluginManager));
40
+ ].map(f => {
41
+ f(pluginManager);
42
+ });
41
43
  }
42
44
  }
43
45
  export { linearPileupDisplayStateModelFactory, linearPileupDisplayConfigSchemaFactory, SharedLinearPileupDisplayMixin, } from './LinearPileupDisplay';
@@ -21,7 +21,9 @@ const useStyles = makeStyles()(theme => ({
21
21
  const BaseDisplayComponent = observer(function ({ model, children, }) {
22
22
  const { error, regionTooLarge } = model;
23
23
  return error ? (React.createElement(BlockMsg, { message: `${error}`, severity: "error", action: React.createElement(Tooltip, { title: "Reload" },
24
- React.createElement(Button, { "data-testid": "reload_button", onClick: () => model.reload() }, "Reload")) })) : regionTooLarge ? (model.regionCannotBeRendered()) : (React.createElement(DataDisplay, { model: model }, children));
24
+ React.createElement(Button, { "data-testid": "reload_button", onClick: () => {
25
+ model.reload();
26
+ } }, "Reload")) })) : regionTooLarge ? (model.regionCannotBeRendered()) : (React.createElement(DataDisplay, { model: model }, children));
25
27
  });
26
28
  const DataDisplay = observer(function ({ model, children, }) {
27
29
  const { drawn, loading } = model;
@@ -29,7 +29,9 @@ const flagNames = [
29
29
  function Bitmask(props) {
30
30
  const { flag = 0, setFlag } = props;
31
31
  return (React.createElement(React.Fragment, null,
32
- React.createElement(TextField, { type: "number", value: flag, onChange: event => setFlag(+event.target.value) }),
32
+ React.createElement(TextField, { type: "number", value: flag, onChange: event => {
33
+ setFlag(+event.target.value);
34
+ } }),
33
35
  flagNames.map((name, index) => {
34
36
  const val = flag & (1 << index);
35
37
  const key = `${name}_${val}`;
@@ -55,7 +57,7 @@ const FilterByTagDialog = observer(function (props) {
55
57
  const [tag, setTag] = useState(((_a = filterBy.tagFilter) === null || _a === void 0 ? void 0 : _a.tag) || '');
56
58
  const [tagValue, setTagValue] = useState(((_b = filterBy.tagFilter) === null || _b === void 0 ? void 0 : _b.value) || '');
57
59
  const [readName, setReadName] = useState(filterBy.readName || '');
58
- const validTag = tag.match(/^[A-Za-z][A-Za-z0-9]$/);
60
+ const validTag = /^[A-Za-z][A-Za-z0-9]$/.exec(tag);
59
61
  const site = 'https://broadinstitute.github.io/picard/explain-flags.html';
60
62
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Filter options" },
61
63
  React.createElement(DialogContent, null,
@@ -74,11 +76,17 @@ const FilterByTagDialog = observer(function (props) {
74
76
  React.createElement(Bitmask, { flag: flagExclude, setFlag: setFlagExclude })))),
75
77
  React.createElement(Paper, { className: classes.paper, variant: "outlined" },
76
78
  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: { maxLength: 2 }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '' }),
78
- React.createElement(TextField, { className: classes.field, value: tagValue, onChange: event => setTagValue(event.target.value), placeholder: "Enter tag value" })),
79
+ React.createElement(TextField, { className: classes.field, value: tag, onChange: event => {
80
+ setTag(event.target.value);
81
+ }, placeholder: "Enter tag name", inputProps: { maxLength: 2 }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '' }),
82
+ React.createElement(TextField, { className: classes.field, value: tagValue, onChange: event => {
83
+ setTagValue(event.target.value);
84
+ }, placeholder: "Enter tag value" })),
79
85
  React.createElement(Paper, { className: classes.paper, variant: "outlined" },
80
86
  React.createElement(Typography, null, "Filter by read name"),
81
- React.createElement(TextField, { className: classes.field, value: readName, onChange: event => setReadName(event.target.value), placeholder: "Enter read name" })),
87
+ React.createElement(TextField, { className: classes.field, value: readName, onChange: event => {
88
+ setReadName(event.target.value);
89
+ }, placeholder: "Enter read name" })),
82
90
  React.createElement(DialogActions, null,
83
91
  React.createElement(Button, { variant: "contained", color: "primary", autoFocus: true, type: "submit", onClick: () => {
84
92
  model.setFilterBy({
@@ -94,6 +102,8 @@ const FilterByTagDialog = observer(function (props) {
94
102
  });
95
103
  handleClose();
96
104
  } }, "Submit"),
97
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
105
+ React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
106
+ handleClose();
107
+ } }, "Cancel")))));
98
108
  });
99
109
  export default FilterByTagDialog;
@@ -50,10 +50,10 @@ export function getPairedInsertSizeColor(f1, f2, stats) {
50
50
  if (sameRef && tlen > ((stats === null || stats === void 0 ? void 0 : stats.upper) || 0)) {
51
51
  return [fillColor.color_longinsert, strokeColor.color_longinsert];
52
52
  }
53
- else if (sameRef && tlen < ((stats === null || stats === void 0 ? void 0 : stats.lower) || 0)) {
53
+ if (sameRef && tlen < ((stats === null || stats === void 0 ? void 0 : stats.lower) || 0)) {
54
54
  return [fillColor.color_shortinsert, strokeColor.color_shortinsert];
55
55
  }
56
- else if (!sameRef) {
56
+ if (!sameRef) {
57
57
  return [fillColor.color_interchrom, strokeColor.color_interchrom];
58
58
  }
59
59
  return undefined;
@@ -1,28 +1,32 @@
1
1
  import { IAnyStateTreeNode } from 'mobx-state-tree';
2
2
  import { BlockSet } from '@jbrowse/core/util/blockTypes';
3
3
  import { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
- export declare function getUniqueTagValues(self: IAnyStateTreeNode & {
5
- adapterConfig: AnyConfigurationModel;
6
- }, colorScheme: {
7
- type: string;
8
- tag?: string;
9
- }, blocks: BlockSet, opts?: {
10
- headers?: Record<string, string>;
11
- signal?: AbortSignal;
12
- filters?: string[];
4
+ export declare function getUniqueTagValues({ self, tag, blocks, opts, }: {
5
+ self: IAnyStateTreeNode & {
6
+ adapterConfig: AnyConfigurationModel;
7
+ };
8
+ tag: string;
9
+ blocks: BlockSet;
10
+ opts?: {
11
+ headers?: Record<string, string>;
12
+ signal?: AbortSignal;
13
+ filters: string[];
14
+ };
13
15
  }): Promise<string[]>;
14
16
  type Track = IAnyStateTreeNode & {
15
17
  configuration: AnyConfigurationModel;
16
18
  };
17
- export declare function getUniqueModificationValues(self: IAnyStateTreeNode & {
18
- parentTrack: Track;
19
- }, adapterConfig: AnyConfigurationModel, colorScheme: {
20
- type: string;
21
- tag?: string;
22
- }, blocks: BlockSet, opts?: {
23
- headers?: Record<string, string>;
24
- signal?: AbortSignal;
25
- filters?: string[];
19
+ export declare function getUniqueModificationValues({ self, adapterConfig, blocks, opts, }: {
20
+ self: IAnyStateTreeNode & {
21
+ parentTrack: Track;
22
+ };
23
+ adapterConfig: AnyConfigurationModel;
24
+ blocks: BlockSet;
25
+ opts?: {
26
+ headers?: Record<string, string>;
27
+ signal?: AbortSignal;
28
+ filters: string[];
29
+ };
26
30
  }): Promise<string[]>;
27
31
  export declare const FilterModel: import("mobx-state-tree").IModelType<{
28
32
  flagInclude: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
@@ -30,7 +34,7 @@ export declare const FilterModel: import("mobx-state-tree").IModelType<{
30
34
  readName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
31
35
  tagFilter: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
32
36
  tag: import("mobx-state-tree").ISimpleType<string>;
33
- value: import("mobx-state-tree").ISimpleType<string>;
37
+ value: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
34
38
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
35
39
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
36
40
  export interface IFilter {
@@ -39,7 +43,7 @@ export interface IFilter {
39
43
  readName?: string;
40
44
  tagFilter?: {
41
45
  tag: string;
42
- value: string;
46
+ value?: string;
43
47
  };
44
48
  }
45
49
  export {};
@@ -1,25 +1,24 @@
1
1
  import { types } from 'mobx-state-tree';
2
2
  import { getSession } from '@jbrowse/core/util';
3
3
  import { getRpcSessionId } from '@jbrowse/core/util/tracks';
4
- export async function getUniqueTagValues(self, colorScheme, blocks, opts) {
4
+ export async function getUniqueTagValues({ self, tag, blocks, opts, }) {
5
5
  const { rpcManager } = getSession(self);
6
6
  const { adapterConfig } = self;
7
7
  const sessionId = getRpcSessionId(self);
8
8
  const values = await rpcManager.call(getRpcSessionId(self), 'PileupGetGlobalValueForTag', {
9
9
  adapterConfig,
10
- tag: colorScheme.tag,
10
+ tag,
11
11
  sessionId,
12
12
  regions: blocks.contentBlocks,
13
13
  ...opts,
14
14
  });
15
15
  return values;
16
16
  }
17
- export async function getUniqueModificationValues(self, adapterConfig, colorScheme, blocks, opts) {
17
+ export async function getUniqueModificationValues({ self, adapterConfig, blocks, opts, }) {
18
18
  const { rpcManager } = getSession(self);
19
19
  const sessionId = getRpcSessionId(self);
20
20
  const values = await rpcManager.call(sessionId, 'PileupGetVisibleModifications', {
21
21
  adapterConfig,
22
- tag: colorScheme.tag,
23
22
  sessionId,
24
23
  regions: blocks.contentBlocks,
25
24
  ...opts,
@@ -32,6 +31,6 @@ export const FilterModel = types.model({
32
31
  readName: types.maybe(types.string),
33
32
  tagFilter: types.maybe(types.model({
34
33
  tag: types.string,
35
- value: types.string,
34
+ value: types.maybe(types.string),
36
35
  })),
37
36
  });
@@ -31,8 +31,6 @@ export async function renderSvg(self, opts, cb) {
31
31
  React.createElement("defs", null,
32
32
  React.createElement("clipPath", { id: clipid },
33
33
  React.createElement("rect", { x: 0, y: 0, width: width, height: height }))),
34
- React.createElement("g", {
35
- /* eslint-disable-next-line react/no-danger */
36
- dangerouslySetInnerHTML: { __html: ctx.getSvg().innerHTML }, clipPath: `url(#${clipid})` })));
34
+ React.createElement("g", { dangerouslySetInnerHTML: { __html: ctx.getSvg().innerHTML }, clipPath: `url(#${clipid})` })));
37
35
  }
38
36
  }
package/esm/util.d.ts CHANGED
@@ -18,7 +18,7 @@ export declare const pairMap: {
18
18
  export declare function getColorWGBS(strand: number, base: string): "#f00" | "#00f" | "#888";
19
19
  export declare function fetchSequence(region: AugmentedRegion, adapter: BaseFeatureDataAdapter): Promise<any>;
20
20
  export declare function shouldFetchReferenceSequence(type?: string): type is "methylation";
21
- export declare const modificationColors: Record<string, string | undefined>;
21
+ export declare const modificationColors: Record<string, string>;
22
22
  type DisplayModel = IAnyStateTreeNode & {
23
23
  setError: (arg: unknown) => void;
24
24
  };