@jbrowse/plugin-alignments 1.7.9 → 2.0.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 (294) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +192 -207
  2. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js.map +1 -0
  3. package/dist/AlignmentsFeatureDetail/index.d.ts +28 -3
  4. package/dist/AlignmentsFeatureDetail/index.js +48 -55
  5. package/dist/AlignmentsFeatureDetail/index.js.map +1 -0
  6. package/dist/AlignmentsTrack/index.js +24 -32
  7. package/dist/AlignmentsTrack/index.js.map +1 -0
  8. package/dist/BamAdapter/BamAdapter.js +345 -585
  9. package/dist/BamAdapter/BamAdapter.js.map +1 -0
  10. package/dist/BamAdapter/BamSlightlyLazyFeature.js +143 -174
  11. package/dist/BamAdapter/BamSlightlyLazyFeature.js.map +1 -0
  12. package/dist/BamAdapter/MismatchParser.js +340 -416
  13. package/dist/BamAdapter/MismatchParser.js.map +1 -0
  14. package/dist/BamAdapter/configSchema.js +33 -46
  15. package/dist/BamAdapter/configSchema.js.map +1 -0
  16. package/dist/BamAdapter/index.js +36 -32
  17. package/dist/BamAdapter/index.js.map +1 -0
  18. package/dist/CramAdapter/CramAdapter.js +376 -644
  19. package/dist/CramAdapter/CramAdapter.js.map +1 -0
  20. package/dist/CramAdapter/CramSlightlyLazyFeature.js +374 -439
  21. package/dist/CramAdapter/CramSlightlyLazyFeature.js.map +1 -0
  22. package/dist/CramAdapter/CramTestAdapters.js +169 -227
  23. package/dist/CramAdapter/CramTestAdapters.js.map +1 -0
  24. package/dist/CramAdapter/configSchema.js +28 -38
  25. package/dist/CramAdapter/configSchema.js.map +1 -0
  26. package/dist/CramAdapter/index.js +37 -32
  27. package/dist/CramAdapter/index.js.map +1 -0
  28. package/dist/HtsgetBamAdapter/HtsgetBamAdapter.js +91 -93
  29. package/dist/HtsgetBamAdapter/HtsgetBamAdapter.js.map +1 -0
  30. package/dist/HtsgetBamAdapter/configSchema.js +19 -29
  31. package/dist/HtsgetBamAdapter/configSchema.js.map +1 -0
  32. package/dist/HtsgetBamAdapter/index.js +44 -38
  33. package/dist/HtsgetBamAdapter/index.js.map +1 -0
  34. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +36 -65
  35. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js.map +1 -0
  36. package/dist/LinearAlignmentsDisplay/index.js +22 -28
  37. package/dist/LinearAlignmentsDisplay/index.js.map +1 -0
  38. package/dist/LinearAlignmentsDisplay/models/configSchema.js +12 -23
  39. package/dist/LinearAlignmentsDisplay/models/configSchema.js.map +1 -0
  40. package/dist/LinearAlignmentsDisplay/models/model.d.ts +10 -10
  41. package/dist/LinearAlignmentsDisplay/models/model.js +257 -245
  42. package/dist/LinearAlignmentsDisplay/models/model.js.map +1 -0
  43. package/dist/LinearPileupDisplay/components/ColorByModifications.js +98 -116
  44. package/dist/LinearPileupDisplay/components/ColorByModifications.js.map +1 -0
  45. package/dist/LinearPileupDisplay/components/ColorByTag.js +82 -91
  46. package/dist/LinearPileupDisplay/components/ColorByTag.js.map +1 -0
  47. package/dist/LinearPileupDisplay/components/FilterByTag.js +156 -192
  48. package/dist/LinearPileupDisplay/components/FilterByTag.js.map +1 -0
  49. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +15 -29
  50. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js.map +1 -0
  51. package/dist/LinearPileupDisplay/components/SetFeatureHeight.js +79 -93
  52. package/dist/LinearPileupDisplay/components/SetFeatureHeight.js.map +1 -0
  53. package/dist/LinearPileupDisplay/components/SetMaxHeight.js +78 -81
  54. package/dist/LinearPileupDisplay/components/SetMaxHeight.js.map +1 -0
  55. package/dist/LinearPileupDisplay/components/SortByTag.js +80 -88
  56. package/dist/LinearPileupDisplay/components/SortByTag.js.map +1 -0
  57. package/dist/LinearPileupDisplay/configSchema.js +40 -42
  58. package/dist/LinearPileupDisplay/configSchema.js.map +1 -0
  59. package/dist/LinearPileupDisplay/index.js +21 -27
  60. package/dist/LinearPileupDisplay/index.js.map +1 -0
  61. package/dist/LinearPileupDisplay/model.d.ts +33 -20
  62. package/dist/LinearPileupDisplay/model.js +702 -716
  63. package/dist/LinearPileupDisplay/model.js.map +1 -0
  64. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  65. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +105 -57
  66. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js.map +1 -0
  67. package/dist/LinearSNPCoverageDisplay/index.js +21 -27
  68. package/dist/LinearSNPCoverageDisplay/index.js.map +1 -0
  69. package/dist/LinearSNPCoverageDisplay/models/configSchema.js +45 -55
  70. package/dist/LinearSNPCoverageDisplay/models/configSchema.js.map +1 -0
  71. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +14 -12
  72. package/dist/LinearSNPCoverageDisplay/models/model.js +257 -230
  73. package/dist/LinearSNPCoverageDisplay/models/model.js.map +1 -0
  74. package/dist/NestedFrequencyTable.js +104 -139
  75. package/dist/NestedFrequencyTable.js.map +1 -0
  76. package/dist/PileupRPC/rpcMethods.js +199 -278
  77. package/dist/PileupRPC/rpcMethods.js.map +1 -0
  78. package/dist/PileupRenderer/PileupLayoutSession.js +56 -76
  79. package/dist/PileupRenderer/PileupLayoutSession.js.map +1 -0
  80. package/dist/PileupRenderer/PileupRenderer.d.ts +56 -11
  81. package/dist/PileupRenderer/PileupRenderer.js +942 -1134
  82. package/dist/PileupRenderer/PileupRenderer.js.map +1 -0
  83. package/dist/PileupRenderer/components/PileupRendering.d.ts +1 -1
  84. package/dist/PileupRenderer/components/PileupRendering.js +173 -253
  85. package/dist/PileupRenderer/components/PileupRendering.js.map +1 -0
  86. package/dist/PileupRenderer/configSchema.js +65 -71
  87. package/dist/PileupRenderer/configSchema.js.map +1 -0
  88. package/dist/PileupRenderer/index.js +17 -22
  89. package/dist/PileupRenderer/index.js.map +1 -0
  90. package/dist/PileupRenderer/sortUtil.js +83 -107
  91. package/dist/PileupRenderer/sortUtil.js.map +1 -0
  92. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +2 -0
  93. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +436 -586
  94. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js.map +1 -0
  95. package/dist/SNPCoverageAdapter/configSchema.js +10 -20
  96. package/dist/SNPCoverageAdapter/configSchema.js.map +1 -0
  97. package/dist/SNPCoverageAdapter/index.js +46 -41
  98. package/dist/SNPCoverageAdapter/index.js.map +1 -0
  99. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +1 -1
  100. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +265 -290
  101. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js.map +1 -0
  102. package/dist/SNPCoverageRenderer/configSchema.js +30 -39
  103. package/dist/SNPCoverageRenderer/configSchema.js.map +1 -0
  104. package/dist/SNPCoverageRenderer/index.js +19 -30
  105. package/dist/SNPCoverageRenderer/index.js.map +1 -0
  106. package/dist/index.js +135 -152
  107. package/dist/index.js.map +1 -0
  108. package/dist/shared.js +84 -92
  109. package/dist/shared.js.map +1 -0
  110. package/dist/util.js +130 -121
  111. package/dist/util.js.map +1 -0
  112. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +6 -0
  113. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +145 -0
  114. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js.map +1 -0
  115. package/esm/AlignmentsFeatureDetail/index.d.ts +38 -0
  116. package/esm/AlignmentsFeatureDetail/index.js +23 -0
  117. package/esm/AlignmentsFeatureDetail/index.js.map +1 -0
  118. package/esm/AlignmentsTrack/index.d.ts +2 -0
  119. package/esm/AlignmentsTrack/index.js +23 -0
  120. package/esm/AlignmentsTrack/index.js.map +1 -0
  121. package/esm/BamAdapter/BamAdapter.d.ts +40 -0
  122. package/esm/BamAdapter/BamAdapter.js +173 -0
  123. package/esm/BamAdapter/BamAdapter.js.map +1 -0
  124. package/esm/BamAdapter/BamSlightlyLazyFeature.d.ts +33 -0
  125. package/esm/BamAdapter/BamSlightlyLazyFeature.js +107 -0
  126. package/esm/BamAdapter/BamSlightlyLazyFeature.js.map +1 -0
  127. package/esm/BamAdapter/MismatchParser.d.ts +25 -0
  128. package/esm/BamAdapter/MismatchParser.js +294 -0
  129. package/esm/BamAdapter/MismatchParser.js.map +1 -0
  130. package/esm/BamAdapter/configSchema.d.ts +2 -0
  131. package/esm/BamAdapter/configSchema.js +31 -0
  132. package/esm/BamAdapter/configSchema.js.map +1 -0
  133. package/esm/BamAdapter/index.d.ts +3 -0
  134. package/esm/BamAdapter/index.js +10 -0
  135. package/esm/BamAdapter/index.js.map +1 -0
  136. package/esm/CramAdapter/CramAdapter.d.ts +53 -0
  137. package/esm/CramAdapter/CramAdapter.js +228 -0
  138. package/esm/CramAdapter/CramAdapter.js.map +1 -0
  139. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +49 -0
  140. package/esm/CramAdapter/CramSlightlyLazyFeature.js +349 -0
  141. package/esm/CramAdapter/CramSlightlyLazyFeature.js.map +1 -0
  142. package/esm/CramAdapter/CramTestAdapters.d.ts +29 -0
  143. package/esm/CramAdapter/CramTestAdapters.js +70 -0
  144. package/esm/CramAdapter/CramTestAdapters.js.map +1 -0
  145. package/esm/CramAdapter/configSchema.d.ts +3 -0
  146. package/esm/CramAdapter/configSchema.js +26 -0
  147. package/esm/CramAdapter/configSchema.js.map +1 -0
  148. package/esm/CramAdapter/index.d.ts +3 -0
  149. package/esm/CramAdapter/index.js +11 -0
  150. package/esm/CramAdapter/index.js.map +1 -0
  151. package/esm/HtsgetBamAdapter/HtsgetBamAdapter.d.ts +9 -0
  152. package/esm/HtsgetBamAdapter/HtsgetBamAdapter.js +27 -0
  153. package/esm/HtsgetBamAdapter/HtsgetBamAdapter.js.map +1 -0
  154. package/esm/HtsgetBamAdapter/configSchema.d.ts +2 -0
  155. package/esm/HtsgetBamAdapter/configSchema.js +17 -0
  156. package/esm/HtsgetBamAdapter/configSchema.js.map +1 -0
  157. package/esm/HtsgetBamAdapter/index.d.ts +3 -0
  158. package/esm/HtsgetBamAdapter/index.js +16 -0
  159. package/esm/HtsgetBamAdapter/index.js.map +1 -0
  160. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +7 -0
  161. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +34 -0
  162. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js.map +1 -0
  163. package/esm/LinearAlignmentsDisplay/index.d.ts +2 -0
  164. package/esm/LinearAlignmentsDisplay/index.js +19 -0
  165. package/esm/LinearAlignmentsDisplay/index.js.map +1 -0
  166. package/esm/LinearAlignmentsDisplay/models/configSchema.d.ts +4 -0
  167. package/esm/LinearAlignmentsDisplay/models/configSchema.js +12 -0
  168. package/esm/LinearAlignmentsDisplay/models/configSchema.js.map +1 -0
  169. package/esm/LinearAlignmentsDisplay/models/model.d.ts +105 -0
  170. package/esm/LinearAlignmentsDisplay/models/model.js +181 -0
  171. package/esm/LinearAlignmentsDisplay/models/model.js.map +1 -0
  172. package/esm/LinearPileupDisplay/components/ColorByModifications.d.ts +14 -0
  173. package/esm/LinearPileupDisplay/components/ColorByModifications.js +71 -0
  174. package/esm/LinearPileupDisplay/components/ColorByModifications.js.map +1 -0
  175. package/esm/LinearPileupDisplay/components/ColorByTag.d.ts +9 -0
  176. package/esm/LinearPileupDisplay/components/ColorByTag.js +45 -0
  177. package/esm/LinearPileupDisplay/components/ColorByTag.js.map +1 -0
  178. package/esm/LinearPileupDisplay/components/FilterByTag.d.ts +18 -0
  179. package/esm/LinearPileupDisplay/components/FilterByTag.js +123 -0
  180. package/esm/LinearPileupDisplay/components/FilterByTag.js.map +1 -0
  181. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.d.ts +13 -0
  182. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +13 -0
  183. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js.map +1 -0
  184. package/esm/LinearPileupDisplay/components/SetFeatureHeight.d.ts +16 -0
  185. package/esm/LinearPileupDisplay/components/SetFeatureHeight.js +41 -0
  186. package/esm/LinearPileupDisplay/components/SetFeatureHeight.js.map +1 -0
  187. package/esm/LinearPileupDisplay/components/SetMaxHeight.d.ts +10 -0
  188. package/esm/LinearPileupDisplay/components/SetMaxHeight.js +43 -0
  189. package/esm/LinearPileupDisplay/components/SetMaxHeight.js.map +1 -0
  190. package/esm/LinearPileupDisplay/components/SortByTag.d.ts +9 -0
  191. package/esm/LinearPileupDisplay/components/SortByTag.js +43 -0
  192. package/esm/LinearPileupDisplay/components/SortByTag.js.map +1 -0
  193. package/esm/LinearPileupDisplay/configSchema.d.ts +6 -0
  194. package/esm/LinearPileupDisplay/configSchema.js +41 -0
  195. package/esm/LinearPileupDisplay/configSchema.js.map +1 -0
  196. package/esm/LinearPileupDisplay/index.d.ts +2 -0
  197. package/esm/LinearPileupDisplay/index.js +18 -0
  198. package/esm/LinearPileupDisplay/index.js.map +1 -0
  199. package/esm/LinearPileupDisplay/model.d.ts +332 -0
  200. package/esm/LinearPileupDisplay/model.js +576 -0
  201. package/esm/LinearPileupDisplay/model.js.map +1 -0
  202. package/esm/LinearSNPCoverageDisplay/components/Tooltip.d.ts +10 -0
  203. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +57 -0
  204. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js.map +1 -0
  205. package/esm/LinearSNPCoverageDisplay/index.d.ts +2 -0
  206. package/esm/LinearSNPCoverageDisplay/index.js +18 -0
  207. package/esm/LinearSNPCoverageDisplay/index.js.map +1 -0
  208. package/esm/LinearSNPCoverageDisplay/models/configSchema.d.ts +2 -0
  209. package/esm/LinearSNPCoverageDisplay/models/configSchema.js +44 -0
  210. package/esm/LinearSNPCoverageDisplay/models/configSchema.js.map +1 -0
  211. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +348 -0
  212. package/esm/LinearSNPCoverageDisplay/models/model.js +185 -0
  213. package/esm/LinearSNPCoverageDisplay/models/model.js.map +1 -0
  214. package/esm/NestedFrequencyTable.d.ts +14 -0
  215. package/esm/NestedFrequencyTable.js +101 -0
  216. package/esm/NestedFrequencyTable.js.map +1 -0
  217. package/esm/PileupRPC/rpcMethods.d.ts +34 -0
  218. package/esm/PileupRPC/rpcMethods.js +70 -0
  219. package/esm/PileupRPC/rpcMethods.js.map +1 -0
  220. package/esm/PileupRenderer/PileupLayoutSession.d.ts +32 -0
  221. package/esm/PileupRenderer/PileupLayoutSession.js +32 -0
  222. package/esm/PileupRenderer/PileupLayoutSession.js.map +1 -0
  223. package/esm/PileupRenderer/PileupRenderer.d.ts +182 -0
  224. package/esm/PileupRenderer/PileupRenderer.js +830 -0
  225. package/esm/PileupRenderer/PileupRenderer.js.map +1 -0
  226. package/esm/PileupRenderer/components/PileupRendering.d.ts +23 -0
  227. package/esm/PileupRenderer/components/PileupRendering.js +138 -0
  228. package/esm/PileupRenderer/components/PileupRendering.js.map +1 -0
  229. package/esm/PileupRenderer/configSchema.d.ts +2 -0
  230. package/esm/PileupRenderer/configSchema.js +64 -0
  231. package/esm/PileupRenderer/configSchema.js.map +1 -0
  232. package/esm/PileupRenderer/index.d.ts +2 -0
  233. package/esm/PileupRenderer/index.js +12 -0
  234. package/esm/PileupRenderer/index.js.map +1 -0
  235. package/esm/PileupRenderer/sortUtil.d.ts +8 -0
  236. package/esm/PileupRenderer/sortUtil.js +80 -0
  237. package/esm/PileupRenderer/sortUtil.js.map +1 -0
  238. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +67 -0
  239. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +259 -0
  240. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js.map +1 -0
  241. package/esm/SNPCoverageAdapter/configSchema.d.ts +3 -0
  242. package/esm/SNPCoverageAdapter/configSchema.js +6 -0
  243. package/esm/SNPCoverageAdapter/configSchema.js.map +1 -0
  244. package/esm/SNPCoverageAdapter/index.d.ts +3 -0
  245. package/esm/SNPCoverageAdapter/index.js +18 -0
  246. package/esm/SNPCoverageAdapter/index.js.map +1 -0
  247. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +20 -0
  248. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +185 -0
  249. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js.map +1 -0
  250. package/esm/SNPCoverageRenderer/configSchema.d.ts +2 -0
  251. package/esm/SNPCoverageRenderer/configSchema.js +29 -0
  252. package/esm/SNPCoverageRenderer/configSchema.js.map +1 -0
  253. package/esm/SNPCoverageRenderer/index.d.ts +3 -0
  254. package/esm/SNPCoverageRenderer/index.js +14 -0
  255. package/esm/SNPCoverageRenderer/index.js.map +1 -0
  256. package/esm/index.d.ts +10 -0
  257. package/esm/index.js +91 -0
  258. package/esm/index.js.map +1 -0
  259. package/esm/shared.d.ts +25 -0
  260. package/esm/shared.js +28 -0
  261. package/esm/shared.js.map +1 -0
  262. package/esm/util.d.ts +19 -0
  263. package/esm/util.js +83 -0
  264. package/esm/util.js.map +1 -0
  265. package/package.json +19 -11
  266. package/src/AlignmentsFeatureDetail/AlignmentsFeatureDetail.tsx +16 -6
  267. package/src/AlignmentsFeatureDetail/__snapshots__/index.test.js.snap +321 -397
  268. package/src/AlignmentsFeatureDetail/index.ts +7 -17
  269. package/src/BamAdapter/MismatchParser.ts +1 -0
  270. package/src/LinearAlignmentsDisplay/components/AlignmentsDisplay.tsx +3 -3
  271. package/src/LinearPileupDisplay/components/ColorByModifications.tsx +7 -7
  272. package/src/LinearPileupDisplay/components/ColorByTag.tsx +5 -5
  273. package/src/LinearPileupDisplay/components/FilterByTag.tsx +5 -5
  274. package/src/LinearPileupDisplay/components/LinearPileupDisplayBlurb.tsx +1 -1
  275. package/src/LinearPileupDisplay/components/SetFeatureHeight.tsx +9 -9
  276. package/src/LinearPileupDisplay/components/SetMaxHeight.tsx +5 -5
  277. package/src/LinearPileupDisplay/components/SortByTag.tsx +5 -5
  278. package/src/LinearPileupDisplay/model.ts +90 -32
  279. package/src/LinearSNPCoverageDisplay/components/Tooltip.tsx +44 -30
  280. package/src/LinearSNPCoverageDisplay/models/model.ts +25 -25
  281. package/src/PileupRenderer/PileupRenderer.tsx +399 -198
  282. package/src/PileupRenderer/components/PileupRendering.tsx +11 -11
  283. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +5 -0
  284. package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +7 -5
  285. package/dist/AlignmentsFeatureDetail/index.test.js +0 -60
  286. package/dist/BamAdapter/BamAdapter.test.js +0 -177
  287. package/dist/BamAdapter/MismatchParser.test.js +0 -251
  288. package/dist/CramAdapter/CramAdapter.test.js +0 -138
  289. package/dist/LinearAlignmentsDisplay/models/configSchema.test.js +0 -83
  290. package/dist/LinearPileupDisplay/configSchema.test.js +0 -92
  291. package/dist/LinearSNPCoverageDisplay/models/configSchema.test.js +0 -62
  292. package/dist/PileupRenderer/components/PileupRendering.test.js +0 -36
  293. package/dist/declare.d.js +0 -1
  294. package/dist/index.test.js +0 -26
@@ -1,4 +1,4 @@
1
- import Color from 'color'
1
+ import { Theme } from '@mui/material/styles'
2
2
  import BoxRendererType, {
3
3
  RenderArgs,
4
4
  RenderArgsSerialized,
@@ -7,7 +7,6 @@ import BoxRendererType, {
7
7
  ResultsSerialized,
8
8
  ResultsDeserialized,
9
9
  } from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType'
10
- import { Theme } from '@material-ui/core'
11
10
  import { createJBrowseTheme } from '@jbrowse/core/ui'
12
11
  import {
13
12
  bpSpanPx,
@@ -44,12 +43,33 @@ import {
44
43
  } from './PileupLayoutSession'
45
44
  import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
46
45
 
46
+ function fillRect(
47
+ ctx: CanvasRenderingContext2D,
48
+ l: number,
49
+ t: number,
50
+ w: number,
51
+ h: number,
52
+ cw: number,
53
+ color?: string,
54
+ ) {
55
+ if (l + w < 0 || l > cw) {
56
+ return
57
+ } else {
58
+ if (color) {
59
+ ctx.fillStyle = color
60
+ }
61
+ ctx.fillRect(l, t, w, h)
62
+ }
63
+ }
64
+
47
65
  function getColorBaseMap(theme: Theme) {
66
+ // @ts-ignore
67
+ const { bases } = theme.palette
48
68
  return {
49
- A: theme.palette.bases.A.main,
50
- C: theme.palette.bases.C.main,
51
- G: theme.palette.bases.G.main,
52
- T: theme.palette.bases.T.main,
69
+ A: bases.A.main,
70
+ C: bases.C.main,
71
+ G: bases.G.main,
72
+ T: bases.T.main,
53
73
  deletion: '#808080', // gray
54
74
  }
55
75
  }
@@ -118,8 +138,8 @@ interface LayoutFeature {
118
138
  feature: Feature
119
139
  }
120
140
 
121
- function shouldDrawSNPs(type?: string) {
122
- return !['methylation', 'modifications'].includes(type || '')
141
+ function shouldDrawSNPsMuted(type?: string) {
142
+ return ['methylation', 'modifications'].includes(type || '')
123
143
  }
124
144
 
125
145
  function shouldDrawIndels(type?: string) {
@@ -133,7 +153,7 @@ export default class PileupRenderer extends BoxRendererType {
133
153
  // letter M is approximately the height
134
154
  getCharWidthHeight(ctx: CanvasRenderingContext2D) {
135
155
  const charWidth = measureText('A')
136
- const charHeight = measureText('M')
156
+ const charHeight = measureText('M') - 2
137
157
  return { charWidth, charHeight }
138
158
  }
139
159
 
@@ -225,7 +245,8 @@ export default class PileupRenderer extends BoxRendererType {
225
245
  )
226
246
 
227
247
  return {
228
- ...region,
248
+ // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
249
+ ...(region as Omit<typeof region, symbol>),
229
250
  start: Math.floor(Math.max(start - bpExpansion, 0)),
230
251
  end: Math.ceil(end + bpExpansion),
231
252
  }
@@ -287,25 +308,32 @@ export default class PileupRenderer extends BoxRendererType {
287
308
  return strand === 1 ? 'color_fwd_strand' : 'color_rev_strand'
288
309
  }
289
310
 
290
- colorByPerBaseLettering(
291
- ctx: CanvasRenderingContext2D,
292
- feat: LayoutFeature,
293
- _config: AnyConfigurationModel,
294
- region: Region,
295
- bpPerPx: number,
296
- props: {
297
- colorForBase: Record<string, string>
298
- contrastForBase: Record<string, string>
299
- charWidth: number
300
- charHeight: number
301
- },
302
- ) {
303
- const { colorForBase, contrastForBase, charWidth, charHeight } = props
311
+ colorByPerBaseLettering({
312
+ ctx,
313
+ feat,
314
+ region,
315
+ bpPerPx,
316
+ colorForBase,
317
+ contrastForBase,
318
+ charWidth,
319
+ charHeight,
320
+ canvasWidth,
321
+ }: {
322
+ ctx: CanvasRenderingContext2D
323
+ feat: LayoutFeature
324
+ region: Region
325
+ bpPerPx: number
326
+ colorForBase: Record<string, string>
327
+ contrastForBase: Record<string, string>
328
+ charWidth: number
329
+ charHeight: number
330
+ canvasWidth: number
331
+ }) {
304
332
  const heightLim = charHeight - 2
305
333
  const { feature, topPx, heightPx } = feat
306
334
  const seq = feature.get('seq') as string
307
335
  const cigarOps = parseCigar(feature.get('CIGAR'))
308
- const widthPx = 1 / bpPerPx
336
+ const w = 1 / bpPerPx
309
337
  const start = feature.get('start')
310
338
  let soffset = 0 // sequence offset
311
339
  let roffset = 0 // reference offset
@@ -320,22 +348,25 @@ export default class PileupRenderer extends BoxRendererType {
320
348
  } else if (op === 'M' || op === 'X' || op === '=') {
321
349
  for (let m = 0; m < len; m++) {
322
350
  const letter = seq[soffset + m]
323
- ctx.fillStyle = colorForBase[letter]
324
- const [leftPx] = bpSpanPx(
325
- start + roffset + m,
326
- start + roffset + m + 1,
327
- region,
328
- bpPerPx,
351
+ const r = start + roffset + m
352
+ const [leftPx] = bpSpanPx(r, r + 1, region, bpPerPx)
353
+ fillRect(
354
+ ctx,
355
+ leftPx,
356
+ topPx,
357
+ w + 0.5,
358
+ heightPx,
359
+ canvasWidth,
360
+ colorForBase[letter],
329
361
  )
330
- ctx.fillRect(leftPx, topPx, widthPx + 0.5, heightPx)
331
362
 
332
- if (widthPx >= charWidth && heightPx >= heightLim) {
363
+ if (w >= charWidth && heightPx >= heightLim) {
333
364
  // normal SNP coloring
334
365
  ctx.fillStyle = contrastForBase[letter]
335
366
 
336
367
  ctx.fillText(
337
368
  letter,
338
- leftPx + (widthPx - charWidth) / 2 + 1,
369
+ leftPx + (w - charWidth) / 2 + 1,
339
370
  topPx + heightPx,
340
371
  )
341
372
  }
@@ -345,13 +376,19 @@ export default class PileupRenderer extends BoxRendererType {
345
376
  }
346
377
  }
347
378
  }
348
- colorByPerBaseQuality(
349
- ctx: CanvasRenderingContext2D,
350
- feat: LayoutFeature,
351
- _config: AnyConfigurationModel,
352
- region: Region,
353
- bpPerPx: number,
354
- ) {
379
+ colorByPerBaseQuality({
380
+ ctx,
381
+ feat,
382
+ region,
383
+ bpPerPx,
384
+ canvasWidth,
385
+ }: {
386
+ ctx: CanvasRenderingContext2D
387
+ feat: LayoutFeature
388
+ region: Region
389
+ bpPerPx: number
390
+ canvasWidth: number
391
+ }) {
355
392
  const { feature, topPx, heightPx } = feat
356
393
  const qual: string = feature.get('qual') || ''
357
394
  const scores = qual.split(' ').map(val => +val)
@@ -371,14 +408,21 @@ export default class PileupRenderer extends BoxRendererType {
371
408
  } else if (op === 'M' || op === 'X' || op === '=') {
372
409
  for (let m = 0; m < len; m++) {
373
410
  const score = scores[soffset + m]
374
- ctx.fillStyle = `hsl(${score === 255 ? 150 : score * 1.5},55%,50%)`
375
411
  const [leftPx] = bpSpanPx(
376
412
  start + roffset + m,
377
413
  start + roffset + m + 1,
378
414
  region,
379
415
  bpPerPx,
380
416
  )
381
- ctx.fillRect(leftPx, topPx, width + 0.5, heightPx)
417
+ fillRect(
418
+ ctx,
419
+ leftPx,
420
+ topPx,
421
+ width + 0.5,
422
+ heightPx,
423
+ canvasWidth,
424
+ `hsl(${score === 255 ? 150 : score * 1.5},55%,50%)`,
425
+ )
382
426
  }
383
427
  soffset += len
384
428
  roffset += len
@@ -395,16 +439,23 @@ export default class PileupRenderer extends BoxRendererType {
395
439
  // has very high likelihood basecalls at that point, we really only care
396
440
  // about low qual calls <20 approx
397
441
  //
398
- colorByModifications(
399
- ctx: CanvasRenderingContext2D,
400
- layoutFeature: LayoutFeature,
401
- _config: AnyConfigurationModel,
402
- region: Region,
403
- bpPerPx: number,
404
- props: RenderArgsDeserializedWithFeaturesAndLayout,
405
- ) {
406
- const { feature, topPx, heightPx } = layoutFeature
407
- const { modificationTagMap = {} } = props
442
+ colorByModifications({
443
+ ctx,
444
+ feat,
445
+ region,
446
+ bpPerPx,
447
+ renderArgs,
448
+ canvasWidth,
449
+ }: {
450
+ ctx: CanvasRenderingContext2D
451
+ feat: LayoutFeature
452
+ region: Region
453
+ bpPerPx: number
454
+ renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
455
+ canvasWidth: number
456
+ }) {
457
+ const { feature, topPx, heightPx } = feat
458
+ const { Color, modificationTagMap = {} } = renderArgs
408
459
 
409
460
  const mm = (getTagAlt(feature, 'MM', 'Mm') as string) || ''
410
461
 
@@ -432,6 +483,8 @@ export default class PileupRenderer extends BoxRendererType {
432
483
  for (let i = 0; i < modifications.length; i++) {
433
484
  const { type, positions } = modifications[i]
434
485
  const col = modificationTagMap[type] || 'black'
486
+
487
+ // @ts-ignore
435
488
  const base = Color(col)
436
489
  for (const readPos of getNextRefPos(cigarOps, positions)) {
437
490
  const r = start + readPos
@@ -440,14 +493,21 @@ export default class PileupRenderer extends BoxRendererType {
440
493
  // give it a little boost of 0.1 to not make them fully
441
494
  // invisible to avoid confusion
442
495
  const prob = probabilities[probIndex]
443
- ctx.fillStyle =
496
+
497
+ fillRect(
498
+ ctx,
499
+ leftPx,
500
+ topPx,
501
+ rightPx - leftPx + 0.5,
502
+ heightPx,
503
+ canvasWidth,
444
504
  prob && prob !== 1
445
505
  ? base
446
506
  .alpha(prob + 0.1)
447
507
  .hsl()
448
508
  .string()
449
- : col
450
- ctx.fillRect(leftPx, topPx, rightPx - leftPx + 0.5, heightPx)
509
+ : col,
510
+ )
451
511
  probIndex++
452
512
  }
453
513
  }
@@ -456,16 +516,23 @@ export default class PileupRenderer extends BoxRendererType {
456
516
  // Color by methylation is slightly modified version of color by
457
517
  // modifications that focuses on CpG sites, with non-methylated CpG colored
458
518
  // blue
459
- colorByMethylation(
460
- ctx: CanvasRenderingContext2D,
461
- layoutFeature: LayoutFeature,
462
- _config: AnyConfigurationModel,
463
- region: Region,
464
- bpPerPx: number,
465
- props: RenderArgsDeserializedWithFeaturesAndLayout,
466
- ) {
467
- const { regionSequence } = props
468
- const { feature, topPx, heightPx } = layoutFeature
519
+ colorByMethylation({
520
+ ctx,
521
+ feat,
522
+ region,
523
+ bpPerPx,
524
+ renderArgs,
525
+ canvasWidth,
526
+ }: {
527
+ ctx: CanvasRenderingContext2D
528
+ feat: LayoutFeature
529
+ region: Region
530
+ bpPerPx: number
531
+ renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
532
+ canvasWidth: number
533
+ }) {
534
+ const { regionSequence } = renderArgs
535
+ const { feature, topPx, heightPx } = feat
469
536
 
470
537
  const mm: string = getTagAlt(feature, 'MM', 'Mm') || ''
471
538
 
@@ -505,8 +572,15 @@ export default class PileupRenderer extends BoxRendererType {
505
572
  if (l1 === 'c' && l2 === 'g') {
506
573
  const s = region.start + i
507
574
  const [leftPx, rightPx] = bpSpanPx(s, s + 2, region, bpPerPx)
508
- ctx.fillStyle = methBins[i] || methBins[i + 1] ? 'red' : 'blue'
509
- ctx.fillRect(leftPx, topPx, rightPx - leftPx + 0.5, heightPx)
575
+ fillRect(
576
+ ctx,
577
+ leftPx,
578
+ topPx,
579
+ rightPx - leftPx + 0.5,
580
+ heightPx,
581
+ canvasWidth,
582
+ methBins[i] || methBins[i + 1] ? 'red' : 'blue',
583
+ )
510
584
  }
511
585
  }
512
586
  // if we are zoomed in, color the c inside the cpg
@@ -515,12 +589,26 @@ export default class PileupRenderer extends BoxRendererType {
515
589
  if (l1 === 'c' && l2 === 'g') {
516
590
  const s = region.start + i
517
591
  const [leftPx, rightPx] = bpSpanPx(s, s + 1, region, bpPerPx)
518
- ctx.fillStyle = methBins[i] ? 'red' : 'blue'
519
- ctx.fillRect(leftPx, topPx, rightPx - leftPx + 0.5, heightPx)
592
+ fillRect(
593
+ ctx,
594
+ leftPx,
595
+ topPx,
596
+ rightPx - leftPx + 0.5,
597
+ heightPx,
598
+ canvasWidth,
599
+ methBins[i] ? 'red' : 'blue',
600
+ )
520
601
 
521
602
  const [leftPx2, rightPx2] = bpSpanPx(s + 1, s + 2, region, bpPerPx)
522
- ctx.fillStyle = methBins[i + 1] ? 'red' : 'blue'
523
- ctx.fillRect(leftPx2, topPx, rightPx2 - leftPx2 + 0.5, heightPx)
603
+ fillRect(
604
+ ctx,
605
+ leftPx2,
606
+ topPx,
607
+ rightPx2 - leftPx2 + 0.5,
608
+ heightPx,
609
+ canvasWidth,
610
+ methBins[i + 1] ? 'red' : 'blue',
611
+ )
524
612
  }
525
613
  }
526
614
  }
@@ -568,29 +656,29 @@ export default class PileupRenderer extends BoxRendererType {
568
656
  }
569
657
  }
570
658
 
571
- drawAlignmentRect(
572
- ctx: CanvasRenderingContext2D,
573
- feat: LayoutFeature,
574
- props: RenderArgsDeserializedWithFeaturesAndLayout & {
575
- colorForBase: Record<string, string>
576
- contrastForBase: Record<string, string>
577
- charWidth: number
578
- charHeight: number
579
- defaultColor: boolean
580
- },
581
- ) {
582
- const {
583
- defaultColor,
584
- config,
585
- bpPerPx,
586
- regions,
587
- colorBy,
588
- colorTagMap = {},
589
- colorForBase,
590
- contrastForBase,
591
- charWidth,
592
- charHeight,
593
- } = props
659
+ drawAlignmentRect({
660
+ ctx,
661
+ feat,
662
+ renderArgs,
663
+ colorForBase,
664
+ contrastForBase,
665
+ charWidth,
666
+ charHeight,
667
+ defaultColor,
668
+ canvasWidth,
669
+ }: {
670
+ ctx: CanvasRenderingContext2D
671
+ feat: LayoutFeature
672
+ renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
673
+ colorForBase: Record<string, string>
674
+ contrastForBase: Record<string, string>
675
+ charWidth: number
676
+ charHeight: number
677
+ defaultColor: boolean
678
+ canvasWidth: number
679
+ }) {
680
+ const { config, bpPerPx, regions, colorBy, colorTagMap = {} } = renderArgs
681
+
594
682
  const { tag = '', type: colorType = '' } = colorBy || {}
595
683
  const { feature } = feat
596
684
  const region = regions[0]
@@ -677,62 +765,89 @@ export default class PileupRenderer extends BoxRendererType {
677
765
  break
678
766
  }
679
767
 
680
- this.drawRect(ctx, feat, props)
768
+ this.drawRect(ctx, feat, renderArgs)
681
769
 
682
770
  // second pass for color types that render per-base things that go over the
683
771
  // existing drawing
684
772
  switch (colorType) {
685
773
  case 'perBaseQuality':
686
- this.colorByPerBaseQuality(ctx, feat, config, region, bpPerPx)
774
+ this.colorByPerBaseQuality({
775
+ ctx,
776
+ feat,
777
+ region,
778
+ bpPerPx,
779
+ canvasWidth,
780
+ })
687
781
  break
688
782
 
689
783
  case 'perBaseLettering':
690
- this.colorByPerBaseLettering(ctx, feat, config, region, bpPerPx, {
784
+ this.colorByPerBaseLettering({
785
+ ctx,
786
+ feat,
787
+ region,
788
+ bpPerPx,
691
789
  colorForBase,
692
790
  contrastForBase,
693
791
  charWidth,
694
792
  charHeight,
793
+ canvasWidth,
695
794
  })
696
795
  break
697
796
 
698
797
  case 'modifications':
699
- this.colorByModifications(ctx, feat, config, region, bpPerPx, props)
798
+ this.colorByModifications({
799
+ ctx,
800
+ feat,
801
+ region,
802
+ bpPerPx,
803
+ renderArgs,
804
+ canvasWidth,
805
+ })
700
806
  break
701
807
 
702
808
  case 'methylation':
703
- this.colorByMethylation(ctx, feat, config, region, bpPerPx, props)
809
+ this.colorByMethylation({
810
+ ctx,
811
+ feat,
812
+ region,
813
+ bpPerPx,
814
+ renderArgs,
815
+ canvasWidth,
816
+ })
704
817
  break
705
818
  }
706
819
  }
707
820
 
708
- drawMismatches(
709
- ctx: CanvasRenderingContext2D,
710
- feat: LayoutFeature,
711
- props: RenderArgsDeserializedWithFeaturesAndLayout,
712
- opts: {
713
- colorForBase: { [key: string]: string }
714
- contrastForBase: { [key: string]: string }
715
- mismatchAlpha?: boolean
716
- drawSNPs?: boolean
717
- drawIndels?: boolean
718
- minSubfeatureWidth: number
719
- largeInsertionIndicatorScale: number
720
- charWidth: number
721
- charHeight: number
722
- },
723
- ) {
724
- const {
725
- minSubfeatureWidth,
726
- largeInsertionIndicatorScale,
727
- mismatchAlpha,
728
- drawSNPs = true,
729
- drawIndels = true,
730
- charWidth,
731
- charHeight,
732
- colorForBase,
733
- contrastForBase,
734
- } = opts
735
- const { bpPerPx, regions } = props
821
+ drawMismatches({
822
+ ctx,
823
+ feat,
824
+ renderArgs,
825
+ minSubfeatureWidth,
826
+ largeInsertionIndicatorScale,
827
+ mismatchAlpha,
828
+ charWidth,
829
+ charHeight,
830
+ colorForBase,
831
+ contrastForBase,
832
+ canvasWidth,
833
+ drawSNPsMuted,
834
+ drawIndels = true,
835
+ }: {
836
+ ctx: CanvasRenderingContext2D
837
+ feat: LayoutFeature
838
+ renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
839
+ colorForBase: { [key: string]: string }
840
+ contrastForBase: { [key: string]: string }
841
+ mismatchAlpha?: boolean
842
+ drawIndels?: boolean
843
+ drawSNPsMuted?: boolean
844
+ minSubfeatureWidth: number
845
+ largeInsertionIndicatorScale: number
846
+ charWidth: number
847
+ charHeight: number
848
+ canvasWidth: number
849
+ }) {
850
+ const { Color, bpPerPx, regions } = renderArgs
736
851
  const { heightPx, topPx, feature } = feat
737
852
  const [region] = regions
738
853
  const start = feature.get('start')
@@ -757,27 +872,39 @@ export default class PileupRenderer extends BoxRendererType {
757
872
  const mbase = mismatch.base
758
873
  const [leftPx, rightPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx)
759
874
  const widthPx = Math.max(minSubfeatureWidth, Math.abs(leftPx - rightPx))
760
- if (mismatch.type === 'mismatch' && drawSNPs) {
761
- const baseColor = colorForBase[mismatch.base] || '#888'
762
-
763
- ctx.fillStyle = !mismatchAlpha
764
- ? baseColor
765
- : mismatch.qual !== undefined
766
- ? Color(baseColor)
767
- .alpha(Math.min(1, mismatch.qual / 50))
768
- .hsl()
769
- .string()
770
- : baseColor
771
-
772
- ctx.fillRect(leftPx, topPx, widthPx, heightPx)
875
+ if (mismatch.type === 'mismatch') {
876
+ if (!drawSNPsMuted) {
877
+ const baseColor = colorForBase[mismatch.base] || '#888'
878
+
879
+ fillRect(
880
+ ctx,
881
+ leftPx,
882
+ topPx,
883
+ widthPx,
884
+ heightPx,
885
+ canvasWidth,
886
+ !mismatchAlpha
887
+ ? baseColor
888
+ : mismatch.qual !== undefined
889
+ ? // @ts-ignore
890
+ Color(baseColor)
891
+ .alpha(Math.min(1, mismatch.qual / 50))
892
+ .hsl()
893
+ .string()
894
+ : baseColor,
895
+ )
896
+ }
773
897
 
774
898
  if (widthPx >= charWidth && heightPx >= heightLim) {
775
899
  // normal SNP coloring
776
- const contrastColor = contrastForBase[mismatch.base] || 'black'
900
+ const contrastColor = drawSNPsMuted
901
+ ? 'black'
902
+ : contrastForBase[mismatch.base] || 'black'
777
903
  ctx.fillStyle = !mismatchAlpha
778
904
  ? contrastColor
779
905
  : mismatch.qual !== undefined
780
- ? Color(contrastColor)
906
+ ? // @ts-ignore
907
+ Color(contrastColor)
781
908
  .alpha(Math.min(1, mismatch.qual / 50))
782
909
  .hsl()
783
910
  .string()
@@ -789,9 +916,15 @@ export default class PileupRenderer extends BoxRendererType {
789
916
  )
790
917
  }
791
918
  } else if (mismatch.type === 'deletion' && drawIndels) {
792
- const baseColor = colorForBase.deletion
793
- ctx.fillStyle = baseColor
794
- ctx.fillRect(leftPx, topPx, widthPx, heightPx)
919
+ fillRect(
920
+ ctx,
921
+ leftPx,
922
+ topPx,
923
+ widthPx,
924
+ heightPx,
925
+ canvasWidth,
926
+ colorForBase.deletion,
927
+ )
795
928
  const txt = `${mismatch.length}`
796
929
  const rwidth = measureText(txt, 10)
797
930
  if (widthPx >= rwidth && heightPx >= heightLim) {
@@ -811,20 +944,34 @@ export default class PileupRenderer extends BoxRendererType {
811
944
  Math.min(1.2, 1 / bpPerPx),
812
945
  )
813
946
  if (len < 10) {
814
- ctx.fillRect(pos, topPx, insW, heightPx)
947
+ fillRect(ctx, pos, topPx, insW, heightPx, canvasWidth, 'purple')
815
948
  if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
816
- ctx.fillRect(pos - insW, topPx, insW * 3, 1)
817
- ctx.fillRect(pos - insW, topPx + heightPx - 1, insW * 3, 1)
949
+ fillRect(ctx, pos - insW, topPx, insW * 3, 1, canvasWidth)
950
+ fillRect(
951
+ ctx,
952
+ pos - insW,
953
+ topPx + heightPx - 1,
954
+ insW * 3,
955
+ 1,
956
+ canvasWidth,
957
+ )
818
958
  ctx.fillText(`(${mismatch.base})`, pos + 3, topPx + heightPx)
819
959
  }
820
960
  }
821
961
  } else if (mismatch.type === 'hardclip' || mismatch.type === 'softclip') {
822
- ctx.fillStyle = mismatch.type === 'hardclip' ? 'red' : 'blue'
823
962
  const pos = leftPx + extraHorizontallyFlippedOffset
824
- ctx.fillRect(pos, topPx, w, heightPx)
963
+ fillRect(
964
+ ctx,
965
+ pos,
966
+ topPx,
967
+ w,
968
+ heightPx,
969
+ canvasWidth,
970
+ mismatch.type === 'hardclip' ? 'red' : 'blue',
971
+ )
825
972
  if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
826
- ctx.fillRect(pos - w, topPx, w * 3, 1)
827
- ctx.fillRect(pos - w, topPx + heightPx - 1, w * 3, 1)
973
+ fillRect(ctx, pos - w, topPx, w * 3, 1, canvasWidth)
974
+ fillRect(ctx, pos - w, topPx + heightPx - 1, w * 3, 1, canvasWidth)
828
975
  ctx.fillText(`(${mismatch.base})`, pos + 3, topPx + heightPx)
829
976
  }
830
977
  } else if (mismatch.type === 'skip') {
@@ -835,12 +982,14 @@ export default class PileupRenderer extends BoxRendererType {
835
982
  // make small exons more visible when zoomed far out
836
983
  const adjustPx = widthPx - (bpPerPx > 10 ? 1.5 : 0)
837
984
  ctx.clearRect(leftPx, topPx, adjustPx, heightPx)
838
- ctx.fillStyle = '#333'
839
- ctx.fillRect(
985
+ fillRect(
986
+ ctx,
840
987
  Math.max(0, leftPx),
841
988
  topPx + heightPx / 2 - 1,
842
989
  adjustPx + (leftPx < 0 ? leftPx : 0),
843
990
  2,
991
+ canvasWidth,
992
+ '#333',
844
993
  )
845
994
  }
846
995
  }
@@ -857,49 +1006,67 @@ export default class PileupRenderer extends BoxRendererType {
857
1006
  const txt = `${len}`
858
1007
  if (mismatch.type === 'insertion' && len >= 10) {
859
1008
  if (bpPerPx > largeInsertionIndicatorScale) {
860
- ctx.fillStyle = 'purple'
861
- ctx.fillRect(leftPx - 1, topPx, 2, heightPx)
1009
+ fillRect(ctx, leftPx - 1, topPx, 2, heightPx, canvasWidth, 'purple')
862
1010
  } else if (heightPx > charHeight) {
863
1011
  const rwidth = measureText(txt)
864
1012
  const padding = 5
865
- ctx.fillStyle = 'purple'
866
- ctx.fillRect(
1013
+ fillRect(
1014
+ ctx,
867
1015
  leftPx - rwidth / 2 - padding,
868
1016
  topPx,
869
1017
  rwidth + 2 * padding,
870
1018
  heightPx,
1019
+ canvasWidth,
1020
+ 'purple',
871
1021
  )
872
1022
  ctx.fillStyle = 'white'
873
1023
  ctx.fillText(txt, leftPx - rwidth / 2, topPx + heightPx)
874
1024
  } else {
875
1025
  const padding = 2
876
- ctx.fillStyle = 'purple'
877
- ctx.fillRect(leftPx - padding, topPx, 2 * padding, heightPx)
1026
+ fillRect(
1027
+ ctx,
1028
+ leftPx - padding,
1029
+ topPx,
1030
+ 2 * padding,
1031
+ heightPx,
1032
+ canvasWidth,
1033
+ 'purple',
1034
+ )
878
1035
  }
879
1036
  }
880
1037
  }
881
1038
  }
882
1039
  }
883
1040
 
884
- drawSoftClipping(
885
- ctx: CanvasRenderingContext2D,
886
- feat: LayoutFeature,
887
- props: RenderArgsDeserializedWithFeaturesAndLayout,
888
- config: AnyConfigurationModel,
889
- theme: Theme,
890
- ) {
1041
+ drawSoftClipping({
1042
+ ctx,
1043
+ feat,
1044
+ renderArgs,
1045
+ config,
1046
+ theme,
1047
+ canvasWidth,
1048
+ }: {
1049
+ ctx: CanvasRenderingContext2D
1050
+ feat: LayoutFeature
1051
+ renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
1052
+ config: AnyConfigurationModel
1053
+ theme: Theme
1054
+ canvasWidth: number
1055
+ }) {
891
1056
  const { feature, topPx, heightPx } = feat
892
- const { regions, bpPerPx } = props
1057
+ const { regions, bpPerPx } = renderArgs
893
1058
  const [region] = regions
894
1059
  const minFeatWidth = readConfObject(config, 'minSubfeatureWidth')
895
1060
  const mismatches: Mismatch[] = feature.get('mismatches')
896
1061
  const seq = feature.get('seq')
897
1062
  const { charWidth, charHeight } = this.getCharWidthHeight(ctx)
1063
+ // @ts-ignore
1064
+ const { bases } = theme.palette
898
1065
  const colorForBase: { [key: string]: string } = {
899
- A: theme.palette.bases.A.main,
900
- C: theme.palette.bases.C.main,
901
- G: theme.palette.bases.G.main,
902
- T: theme.palette.bases.T.main,
1066
+ A: bases.A.main,
1067
+ C: bases.C.main,
1068
+ G: bases.G.main,
1069
+ T: bases.T.main,
903
1070
  deletion: '#808080', // gray
904
1071
  }
905
1072
 
@@ -937,7 +1104,14 @@ export default class PileupRenderer extends BoxRendererType {
937
1104
  // show in soft clipping
938
1105
  const baseColor = colorForBase[base] || '#000000'
939
1106
  ctx.fillStyle = baseColor
940
- ctx.fillRect(softClipLeftPx, topPx, softClipWidthPx, heightPx)
1107
+ fillRect(
1108
+ ctx,
1109
+ softClipLeftPx,
1110
+ topPx,
1111
+ softClipWidthPx,
1112
+ heightPx,
1113
+ canvasWidth,
1114
+ )
941
1115
 
942
1116
  if (softClipWidthPx >= charWidth && heightPx >= charHeight - 5) {
943
1117
  ctx.fillStyle = theme.palette.getContrastText(baseColor)
@@ -952,12 +1126,24 @@ export default class PileupRenderer extends BoxRendererType {
952
1126
  }
953
1127
  }
954
1128
 
955
- makeImageData(
956
- ctx: CanvasRenderingContext2D,
957
- layoutRecords: (LayoutFeature | null)[],
958
- props: RenderArgsDeserializedWithFeaturesAndLayout,
959
- ) {
960
- const { layout, config, showSoftClip, colorBy, theme: configTheme } = props
1129
+ makeImageData({
1130
+ ctx,
1131
+ layoutRecords,
1132
+ canvasWidth,
1133
+ renderArgs,
1134
+ }: {
1135
+ ctx: CanvasRenderingContext2D
1136
+ canvasWidth: number
1137
+ layoutRecords: (LayoutFeature | null)[]
1138
+ renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
1139
+ }) {
1140
+ const {
1141
+ layout,
1142
+ config,
1143
+ showSoftClip,
1144
+ colorBy,
1145
+ theme: configTheme,
1146
+ } = renderArgs
961
1147
  const mismatchAlpha = readConfObject(config, 'mismatchAlpha')
962
1148
  const minSubfeatureWidth = readConfObject(config, 'minSubfeatureWidth')
963
1149
  const largeInsertionIndicatorScale = readConfObject(
@@ -978,7 +1164,7 @@ export default class PileupRenderer extends BoxRendererType {
978
1164
  ctx.font = 'bold 10px Courier New,monospace'
979
1165
 
980
1166
  const { charWidth, charHeight } = this.getCharWidthHeight(ctx)
981
- const drawSNPs = shouldDrawSNPs(colorBy?.type)
1167
+ const drawSNPsMuted = shouldDrawSNPsMuted(colorBy?.type)
982
1168
  const drawIndels = shouldDrawIndels(colorBy?.type)
983
1169
  for (let i = 0; i < layoutRecords.length; i++) {
984
1170
  const feat = layoutRecords[i]
@@ -986,17 +1172,23 @@ export default class PileupRenderer extends BoxRendererType {
986
1172
  continue
987
1173
  }
988
1174
 
989
- this.drawAlignmentRect(ctx, feat, {
990
- ...props,
1175
+ this.drawAlignmentRect({
1176
+ ctx,
1177
+ feat,
1178
+ renderArgs,
991
1179
  defaultColor,
992
1180
  colorForBase,
993
1181
  contrastForBase,
994
1182
  charWidth,
995
1183
  charHeight,
1184
+ canvasWidth,
996
1185
  })
997
- this.drawMismatches(ctx, feat, props, {
1186
+ this.drawMismatches({
1187
+ ctx,
1188
+ feat,
1189
+ renderArgs,
998
1190
  mismatchAlpha,
999
- drawSNPs,
1191
+ drawSNPsMuted,
1000
1192
  drawIndels,
1001
1193
  largeInsertionIndicatorScale,
1002
1194
  minSubfeatureWidth,
@@ -1004,15 +1196,17 @@ export default class PileupRenderer extends BoxRendererType {
1004
1196
  charHeight,
1005
1197
  colorForBase,
1006
1198
  contrastForBase,
1199
+ canvasWidth,
1007
1200
  })
1008
- }
1009
- if (showSoftClip) {
1010
- for (let i = 0; i < layoutRecords.length; i++) {
1011
- const feat = layoutRecords[i]
1012
- if (feat === null) {
1013
- continue
1014
- }
1015
- this.drawSoftClipping(ctx, feat, props, config, theme)
1201
+ if (showSoftClip) {
1202
+ this.drawSoftClipping({
1203
+ ctx,
1204
+ feat,
1205
+ renderArgs,
1206
+ config,
1207
+ theme,
1208
+ canvasWidth,
1209
+ })
1016
1210
  }
1017
1211
  }
1018
1212
  }
@@ -1097,16 +1291,23 @@ export default class PileupRenderer extends BoxRendererType {
1097
1291
 
1098
1292
  const width = (end - start) / bpPerPx
1099
1293
  const height = Math.max(layout.getTotalHeight(), 1)
1294
+ const Color = await import('color').then(f => f.default)
1100
1295
  const res = await renderToAbstractCanvas(
1101
1296
  width,
1102
1297
  height,
1103
1298
  renderProps,
1104
1299
  (ctx: CanvasRenderingContext2D) =>
1105
- this.makeImageData(ctx, layoutRecords, {
1106
- ...renderProps,
1107
- layout,
1108
- features,
1109
- regionSequence,
1300
+ this.makeImageData({
1301
+ ctx,
1302
+ layoutRecords,
1303
+ canvasWidth: width,
1304
+ renderArgs: {
1305
+ ...renderProps,
1306
+ layout,
1307
+ features,
1308
+ regionSequence,
1309
+ Color,
1310
+ },
1110
1311
  }),
1111
1312
  )
1112
1313