@jbrowse/plugin-alignments 2.5.0 → 2.6.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 (402) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -1
  2. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureFlags.d.ts +2 -1
  3. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureFlags.js +2 -1
  4. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureFlags.js.map +1 -1
  5. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureSuppAligns.d.ts +2 -1
  6. package/dist/BamAdapter/BamAdapter.d.ts +1 -1
  7. package/dist/BamAdapter/BamAdapter.js +25 -30
  8. package/dist/BamAdapter/BamAdapter.js.map +1 -1
  9. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +1 -1
  10. package/dist/CramAdapter/CramAdapter.js +48 -46
  11. package/dist/CramAdapter/CramAdapter.js.map +1 -1
  12. package/dist/CramAdapter/CramSlightlyLazyFeature.js +3 -5
  13. package/dist/CramAdapter/CramSlightlyLazyFeature.js.map +1 -1
  14. package/dist/CramAdapter/CramTestAdapters.js +1 -1
  15. package/dist/CramAdapter/CramTestAdapters.js.map +1 -1
  16. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +2 -1
  17. package/dist/LinearAlignmentsDisplay/models/model.d.ts +16 -6
  18. package/dist/LinearAlignmentsDisplay/models/model.js +2 -1
  19. package/dist/LinearAlignmentsDisplay/models/model.js.map +1 -1
  20. package/dist/LinearPileupDisplay/components/ColorByModifications.d.ts +2 -1
  21. package/dist/LinearPileupDisplay/components/ColorByModifications.js +3 -23
  22. package/dist/LinearPileupDisplay/components/ColorByModifications.js.map +1 -1
  23. package/dist/LinearPileupDisplay/components/ColorByTag.d.ts +2 -1
  24. package/dist/LinearPileupDisplay/components/ColorByTag.js +2 -6
  25. package/dist/LinearPileupDisplay/components/ColorByTag.js.map +1 -1
  26. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.d.ts +3 -2
  27. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +6 -6
  28. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js.map +1 -1
  29. package/dist/LinearPileupDisplay/components/ModificationsTable.d.ts +4 -0
  30. package/dist/LinearPileupDisplay/components/ModificationsTable.js +29 -0
  31. package/dist/LinearPileupDisplay/components/ModificationsTable.js.map +1 -0
  32. package/dist/LinearPileupDisplay/components/SetFeatureHeight.d.ts +2 -1
  33. package/dist/LinearPileupDisplay/components/SetMaxHeight.d.ts +2 -1
  34. package/dist/LinearPileupDisplay/components/SortByTag.d.ts +2 -1
  35. package/dist/LinearPileupDisplay/model.d.ts +101 -78
  36. package/dist/LinearPileupDisplay/model.js +161 -115
  37. package/dist/LinearPileupDisplay/model.js.map +1 -1
  38. package/dist/LinearReadArcsDisplay/components/ReactComponent.d.ts +2 -1
  39. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +36 -39
  40. package/dist/LinearReadArcsDisplay/components/ReactComponent.js.map +1 -1
  41. package/dist/LinearReadArcsDisplay/configSchema.d.ts +0 -3
  42. package/dist/LinearReadArcsDisplay/drawFeats.d.ts +2 -15
  43. package/dist/LinearReadArcsDisplay/drawFeats.js +56 -64
  44. package/dist/LinearReadArcsDisplay/drawFeats.js.map +1 -1
  45. package/dist/LinearReadArcsDisplay/model.d.ts +52 -244
  46. package/dist/LinearReadArcsDisplay/model.js +65 -115
  47. package/dist/LinearReadArcsDisplay/model.js.map +1 -1
  48. package/dist/LinearReadArcsDisplay/util.d.ts +2 -0
  49. package/dist/LinearReadArcsDisplay/util.js +13 -0
  50. package/dist/LinearReadArcsDisplay/util.js.map +1 -0
  51. package/dist/LinearReadCloudDisplay/components/ReactComponent.d.ts +2 -1
  52. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +34 -36
  53. package/dist/LinearReadCloudDisplay/components/ReactComponent.js.map +1 -1
  54. package/dist/LinearReadCloudDisplay/configSchema.d.ts +3 -1
  55. package/dist/LinearReadCloudDisplay/drawFeats.d.ts +2 -12
  56. package/dist/LinearReadCloudDisplay/drawFeats.js +11 -127
  57. package/dist/LinearReadCloudDisplay/drawFeats.js.map +1 -1
  58. package/dist/LinearReadCloudDisplay/drawLongReadChains.d.ts +11 -0
  59. package/dist/LinearReadCloudDisplay/drawLongReadChains.js +69 -0
  60. package/dist/LinearReadCloudDisplay/drawLongReadChains.js.map +1 -0
  61. package/dist/LinearReadCloudDisplay/drawPairChains.d.ts +17 -0
  62. package/dist/LinearReadCloudDisplay/drawPairChains.js +100 -0
  63. package/dist/LinearReadCloudDisplay/drawPairChains.js.map +1 -0
  64. package/dist/LinearReadCloudDisplay/model.d.ts +60 -238
  65. package/dist/LinearReadCloudDisplay/model.js +55 -92
  66. package/dist/LinearReadCloudDisplay/model.js.map +1 -1
  67. package/dist/LinearReadCloudDisplay/util.d.ts +2 -0
  68. package/dist/LinearReadCloudDisplay/util.js +35 -0
  69. package/dist/LinearReadCloudDisplay/util.js.map +1 -0
  70. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +2 -1
  71. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +134 -74
  72. package/dist/LinearSNPCoverageDisplay/models/model.js +46 -33
  73. package/dist/LinearSNPCoverageDisplay/models/model.js.map +1 -1
  74. package/dist/MismatchParser/index.d.ts +7 -2
  75. package/dist/MismatchParser/index.js +44 -5
  76. package/dist/MismatchParser/index.js.map +1 -1
  77. package/dist/PileupRPC/methods/GetReducedFeatures.d.ts +15 -2
  78. package/dist/PileupRPC/methods/GetReducedFeatures.js +1 -8
  79. package/dist/PileupRPC/methods/GetReducedFeatures.js.map +1 -1
  80. package/dist/PileupRenderer/PileupRenderer.d.ts +4 -117
  81. package/dist/PileupRenderer/PileupRenderer.js +18 -761
  82. package/dist/PileupRenderer/PileupRenderer.js.map +1 -1
  83. package/dist/PileupRenderer/colorBy.d.ts +7 -0
  84. package/dist/PileupRenderer/colorBy.js +69 -0
  85. package/dist/PileupRenderer/colorBy.js.map +1 -0
  86. package/dist/PileupRenderer/components/PileupRendering.d.ts +7 -2
  87. package/dist/PileupRenderer/components/PileupRendering.js +17 -18
  88. package/dist/PileupRenderer/components/PileupRendering.js.map +1 -1
  89. package/dist/PileupRenderer/getAlignmentShapeColor.d.ts +10 -0
  90. package/dist/PileupRenderer/getAlignmentShapeColor.js +60 -0
  91. package/dist/PileupRenderer/getAlignmentShapeColor.js.map +1 -0
  92. package/dist/PileupRenderer/index.js +1 -1
  93. package/dist/PileupRenderer/index.js.map +1 -1
  94. package/dist/PileupRenderer/layoutFeature.d.ts +18 -0
  95. package/dist/PileupRenderer/layoutFeature.js +41 -0
  96. package/dist/PileupRenderer/layoutFeature.js.map +1 -0
  97. package/dist/PileupRenderer/layoutFeatures.d.ts +2 -0
  98. package/dist/PileupRenderer/layoutFeatures.js +35 -0
  99. package/dist/PileupRenderer/layoutFeatures.js.map +1 -0
  100. package/dist/PileupRenderer/makeImageData.d.ts +17 -0
  101. package/dist/PileupRenderer/makeImageData.js +64 -0
  102. package/dist/PileupRenderer/makeImageData.js.map +1 -0
  103. package/dist/PileupRenderer/renderAlignment.d.ts +13 -0
  104. package/dist/PileupRenderer/renderAlignment.js +72 -0
  105. package/dist/PileupRenderer/renderAlignment.js.map +1 -0
  106. package/dist/PileupRenderer/renderAlignmentShape.d.ts +7 -0
  107. package/dist/PileupRenderer/renderAlignmentShape.js +41 -0
  108. package/dist/PileupRenderer/renderAlignmentShape.js.map +1 -0
  109. package/dist/PileupRenderer/renderMethylation.d.ts +11 -0
  110. package/dist/PileupRenderer/renderMethylation.js +63 -0
  111. package/dist/PileupRenderer/renderMethylation.js.map +1 -0
  112. package/dist/PileupRenderer/renderMismatches.d.ts +21 -0
  113. package/dist/PileupRenderer/renderMismatches.js +135 -0
  114. package/dist/PileupRenderer/renderMismatches.js.map +1 -0
  115. package/dist/PileupRenderer/renderModifications.d.ts +11 -0
  116. package/dist/PileupRenderer/renderModifications.js +54 -0
  117. package/dist/PileupRenderer/renderModifications.js.map +1 -0
  118. package/dist/PileupRenderer/renderPerBaseLettering.d.ts +13 -0
  119. package/dist/PileupRenderer/renderPerBaseLettering.js +47 -0
  120. package/dist/PileupRenderer/renderPerBaseLettering.js.map +1 -0
  121. package/dist/PileupRenderer/renderPerBaseQuality.d.ts +9 -0
  122. package/dist/PileupRenderer/renderPerBaseQuality.js +39 -0
  123. package/dist/PileupRenderer/renderPerBaseQuality.js.map +1 -0
  124. package/dist/PileupRenderer/renderSoftClipping.d.ts +13 -0
  125. package/dist/PileupRenderer/renderSoftClipping.js +48 -0
  126. package/dist/PileupRenderer/renderSoftClipping.js.map +1 -0
  127. package/dist/PileupRenderer/sortUtil.js +1 -2
  128. package/dist/PileupRenderer/sortUtil.js.map +1 -1
  129. package/dist/PileupRenderer/util.d.ts +24 -0
  130. package/dist/PileupRenderer/util.js +51 -0
  131. package/dist/PileupRenderer/util.js.map +1 -0
  132. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +0 -2
  133. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +0 -3
  134. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js.map +1 -1
  135. package/dist/SNPCoverageAdapter/generateCoverageBins.d.ts +3 -43
  136. package/dist/SNPCoverageAdapter/generateCoverageBins.js +72 -49
  137. package/dist/SNPCoverageAdapter/generateCoverageBins.js.map +1 -1
  138. package/dist/SNPCoverageAdapter/index.js +0 -2
  139. package/dist/SNPCoverageAdapter/index.js.map +1 -1
  140. package/dist/SNPCoverageAdapter/util.d.ts +29 -0
  141. package/dist/SNPCoverageAdapter/util.js +3 -0
  142. package/dist/SNPCoverageAdapter/util.js.map +1 -0
  143. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +1 -1
  144. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +2 -2
  145. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js.map +1 -1
  146. package/dist/SNPCoverageRenderer/configSchema.d.ts +5 -0
  147. package/dist/SNPCoverageRenderer/configSchema.js +5 -0
  148. package/dist/SNPCoverageRenderer/configSchema.js.map +1 -1
  149. package/dist/shared/BaseDisplayComponent.d.ts +8 -0
  150. package/dist/shared/BaseDisplayComponent.js +49 -0
  151. package/dist/shared/BaseDisplayComponent.js.map +1 -0
  152. package/dist/shared/FilterByTag.d.ts +13 -11
  153. package/dist/shared/FilterByTag.js +8 -13
  154. package/dist/shared/FilterByTag.js.map +1 -1
  155. package/dist/shared/afterAttach.d.ts +2 -0
  156. package/dist/shared/afterAttach.js +44 -0
  157. package/dist/shared/afterAttach.js.map +1 -0
  158. package/dist/shared/color.d.ts +44 -6
  159. package/dist/shared/color.js +57 -23
  160. package/dist/shared/color.js.map +1 -1
  161. package/dist/shared/fetchChains.d.ts +3 -2
  162. package/dist/shared/fetchChains.js +14 -20
  163. package/dist/shared/fetchChains.js.map +1 -1
  164. package/dist/shared/renderSvg.d.ts +7 -0
  165. package/dist/shared/renderSvg.js +69 -0
  166. package/dist/shared/renderSvg.js.map +1 -0
  167. package/dist/shared/util.d.ts +2 -0
  168. package/dist/shared/util.js +13 -0
  169. package/dist/shared/util.js.map +1 -0
  170. package/dist/util.d.ts +16 -2
  171. package/dist/util.js +45 -4
  172. package/dist/util.js.map +1 -1
  173. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -1
  174. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureFlags.d.ts +2 -1
  175. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureFlags.js +3 -2
  176. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureFlags.js.map +1 -1
  177. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureSuppAligns.d.ts +2 -1
  178. package/esm/BamAdapter/BamAdapter.d.ts +1 -1
  179. package/esm/BamAdapter/BamAdapter.js +25 -30
  180. package/esm/BamAdapter/BamAdapter.js.map +1 -1
  181. package/esm/BamAdapter/BamSlightlyLazyFeature.d.ts +1 -1
  182. package/esm/CramAdapter/CramAdapter.js +49 -47
  183. package/esm/CramAdapter/CramAdapter.js.map +1 -1
  184. package/esm/CramAdapter/CramSlightlyLazyFeature.js +3 -5
  185. package/esm/CramAdapter/CramSlightlyLazyFeature.js.map +1 -1
  186. package/esm/CramAdapter/CramTestAdapters.js +1 -1
  187. package/esm/CramAdapter/CramTestAdapters.js.map +1 -1
  188. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +2 -1
  189. package/esm/LinearAlignmentsDisplay/models/model.d.ts +16 -6
  190. package/esm/LinearAlignmentsDisplay/models/model.js +2 -1
  191. package/esm/LinearAlignmentsDisplay/models/model.js.map +1 -1
  192. package/esm/LinearPileupDisplay/components/ColorByModifications.d.ts +2 -1
  193. package/esm/LinearPileupDisplay/components/ColorByModifications.js +2 -22
  194. package/esm/LinearPileupDisplay/components/ColorByModifications.js.map +1 -1
  195. package/esm/LinearPileupDisplay/components/ColorByTag.d.ts +2 -1
  196. package/esm/LinearPileupDisplay/components/ColorByTag.js +2 -6
  197. package/esm/LinearPileupDisplay/components/ColorByTag.js.map +1 -1
  198. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.d.ts +3 -2
  199. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +6 -6
  200. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js.map +1 -1
  201. package/esm/LinearPileupDisplay/components/ModificationsTable.d.ts +4 -0
  202. package/esm/LinearPileupDisplay/components/ModificationsTable.js +23 -0
  203. package/esm/LinearPileupDisplay/components/ModificationsTable.js.map +1 -0
  204. package/esm/LinearPileupDisplay/components/SetFeatureHeight.d.ts +2 -1
  205. package/esm/LinearPileupDisplay/components/SetMaxHeight.d.ts +2 -1
  206. package/esm/LinearPileupDisplay/components/SortByTag.d.ts +2 -1
  207. package/esm/LinearPileupDisplay/model.d.ts +101 -78
  208. package/esm/LinearPileupDisplay/model.js +162 -116
  209. package/esm/LinearPileupDisplay/model.js.map +1 -1
  210. package/esm/LinearReadArcsDisplay/components/ReactComponent.d.ts +2 -1
  211. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +13 -39
  212. package/esm/LinearReadArcsDisplay/components/ReactComponent.js.map +1 -1
  213. package/esm/LinearReadArcsDisplay/configSchema.d.ts +0 -3
  214. package/esm/LinearReadArcsDisplay/drawFeats.d.ts +2 -15
  215. package/esm/LinearReadArcsDisplay/drawFeats.js +54 -61
  216. package/esm/LinearReadArcsDisplay/drawFeats.js.map +1 -1
  217. package/esm/LinearReadArcsDisplay/model.d.ts +52 -244
  218. package/esm/LinearReadArcsDisplay/model.js +69 -119
  219. package/esm/LinearReadArcsDisplay/model.js.map +1 -1
  220. package/esm/LinearReadArcsDisplay/util.d.ts +2 -0
  221. package/esm/LinearReadArcsDisplay/util.js +9 -0
  222. package/esm/LinearReadArcsDisplay/util.js.map +1 -0
  223. package/esm/LinearReadCloudDisplay/components/ReactComponent.d.ts +2 -1
  224. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +11 -36
  225. package/esm/LinearReadCloudDisplay/components/ReactComponent.js.map +1 -1
  226. package/esm/LinearReadCloudDisplay/configSchema.d.ts +3 -1
  227. package/esm/LinearReadCloudDisplay/drawFeats.d.ts +2 -12
  228. package/esm/LinearReadCloudDisplay/drawFeats.js +9 -126
  229. package/esm/LinearReadCloudDisplay/drawFeats.js.map +1 -1
  230. package/esm/LinearReadCloudDisplay/drawLongReadChains.d.ts +11 -0
  231. package/esm/LinearReadCloudDisplay/drawLongReadChains.js +65 -0
  232. package/esm/LinearReadCloudDisplay/drawLongReadChains.js.map +1 -0
  233. package/esm/LinearReadCloudDisplay/drawPairChains.d.ts +17 -0
  234. package/esm/LinearReadCloudDisplay/drawPairChains.js +95 -0
  235. package/esm/LinearReadCloudDisplay/drawPairChains.js.map +1 -0
  236. package/esm/LinearReadCloudDisplay/model.d.ts +60 -238
  237. package/esm/LinearReadCloudDisplay/model.js +59 -96
  238. package/esm/LinearReadCloudDisplay/model.js.map +1 -1
  239. package/esm/LinearReadCloudDisplay/util.d.ts +2 -0
  240. package/esm/LinearReadCloudDisplay/util.js +30 -0
  241. package/esm/LinearReadCloudDisplay/util.js.map +1 -0
  242. package/esm/LinearSNPCoverageDisplay/components/Tooltip.d.ts +2 -1
  243. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +134 -74
  244. package/esm/LinearSNPCoverageDisplay/models/model.js +48 -35
  245. package/esm/LinearSNPCoverageDisplay/models/model.js.map +1 -1
  246. package/esm/MismatchParser/index.d.ts +7 -2
  247. package/esm/MismatchParser/index.js +41 -4
  248. package/esm/MismatchParser/index.js.map +1 -1
  249. package/esm/PileupRPC/methods/GetReducedFeatures.d.ts +15 -2
  250. package/esm/PileupRPC/methods/GetReducedFeatures.js +2 -9
  251. package/esm/PileupRPC/methods/GetReducedFeatures.js.map +1 -1
  252. package/esm/PileupRenderer/PileupRenderer.d.ts +4 -117
  253. package/esm/PileupRenderer/PileupRenderer.js +20 -763
  254. package/esm/PileupRenderer/PileupRenderer.js.map +1 -1
  255. package/esm/PileupRenderer/colorBy.d.ts +7 -0
  256. package/esm/PileupRenderer/colorBy.js +61 -0
  257. package/esm/PileupRenderer/colorBy.js.map +1 -0
  258. package/esm/PileupRenderer/components/PileupRendering.d.ts +7 -2
  259. package/esm/PileupRenderer/components/PileupRendering.js +17 -18
  260. package/esm/PileupRenderer/components/PileupRendering.js.map +1 -1
  261. package/esm/PileupRenderer/getAlignmentShapeColor.d.ts +10 -0
  262. package/esm/PileupRenderer/getAlignmentShapeColor.js +56 -0
  263. package/esm/PileupRenderer/getAlignmentShapeColor.js.map +1 -0
  264. package/esm/PileupRenderer/index.js +1 -1
  265. package/esm/PileupRenderer/index.js.map +1 -1
  266. package/esm/PileupRenderer/layoutFeature.d.ts +18 -0
  267. package/esm/PileupRenderer/layoutFeature.js +37 -0
  268. package/esm/PileupRenderer/layoutFeature.js.map +1 -0
  269. package/esm/PileupRenderer/layoutFeatures.d.ts +2 -0
  270. package/esm/PileupRenderer/layoutFeatures.js +31 -0
  271. package/esm/PileupRenderer/layoutFeatures.js.map +1 -0
  272. package/esm/PileupRenderer/makeImageData.d.ts +17 -0
  273. package/esm/PileupRenderer/makeImageData.js +60 -0
  274. package/esm/PileupRenderer/makeImageData.js.map +1 -0
  275. package/esm/PileupRenderer/renderAlignment.d.ts +13 -0
  276. package/esm/PileupRenderer/renderAlignment.js +68 -0
  277. package/esm/PileupRenderer/renderAlignment.js.map +1 -0
  278. package/esm/PileupRenderer/renderAlignmentShape.d.ts +7 -0
  279. package/esm/PileupRenderer/renderAlignmentShape.js +37 -0
  280. package/esm/PileupRenderer/renderAlignmentShape.js.map +1 -0
  281. package/esm/PileupRenderer/renderMethylation.d.ts +11 -0
  282. package/esm/PileupRenderer/renderMethylation.js +59 -0
  283. package/esm/PileupRenderer/renderMethylation.js.map +1 -0
  284. package/esm/PileupRenderer/renderMismatches.d.ts +21 -0
  285. package/esm/PileupRenderer/renderMismatches.js +131 -0
  286. package/esm/PileupRenderer/renderMismatches.js.map +1 -0
  287. package/esm/PileupRenderer/renderModifications.d.ts +11 -0
  288. package/esm/PileupRenderer/renderModifications.js +50 -0
  289. package/esm/PileupRenderer/renderModifications.js.map +1 -0
  290. package/esm/PileupRenderer/renderPerBaseLettering.d.ts +13 -0
  291. package/esm/PileupRenderer/renderPerBaseLettering.js +43 -0
  292. package/esm/PileupRenderer/renderPerBaseLettering.js.map +1 -0
  293. package/esm/PileupRenderer/renderPerBaseQuality.d.ts +9 -0
  294. package/esm/PileupRenderer/renderPerBaseQuality.js +35 -0
  295. package/esm/PileupRenderer/renderPerBaseQuality.js.map +1 -0
  296. package/esm/PileupRenderer/renderSoftClipping.d.ts +13 -0
  297. package/esm/PileupRenderer/renderSoftClipping.js +44 -0
  298. package/esm/PileupRenderer/renderSoftClipping.js.map +1 -0
  299. package/esm/PileupRenderer/sortUtil.js +1 -2
  300. package/esm/PileupRenderer/sortUtil.js.map +1 -1
  301. package/esm/PileupRenderer/util.d.ts +24 -0
  302. package/esm/PileupRenderer/util.js +42 -0
  303. package/esm/PileupRenderer/util.js.map +1 -0
  304. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +0 -2
  305. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +0 -2
  306. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js.map +1 -1
  307. package/esm/SNPCoverageAdapter/generateCoverageBins.d.ts +3 -43
  308. package/esm/SNPCoverageAdapter/generateCoverageBins.js +73 -50
  309. package/esm/SNPCoverageAdapter/generateCoverageBins.js.map +1 -1
  310. package/esm/SNPCoverageAdapter/index.js +0 -2
  311. package/esm/SNPCoverageAdapter/index.js.map +1 -1
  312. package/esm/SNPCoverageAdapter/util.d.ts +29 -0
  313. package/esm/SNPCoverageAdapter/util.js +2 -0
  314. package/esm/SNPCoverageAdapter/util.js.map +1 -0
  315. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +1 -1
  316. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +2 -2
  317. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js.map +1 -1
  318. package/esm/SNPCoverageRenderer/configSchema.d.ts +5 -0
  319. package/esm/SNPCoverageRenderer/configSchema.js +5 -0
  320. package/esm/SNPCoverageRenderer/configSchema.js.map +1 -1
  321. package/esm/shared/BaseDisplayComponent.d.ts +8 -0
  322. package/esm/shared/BaseDisplayComponent.js +44 -0
  323. package/esm/shared/BaseDisplayComponent.js.map +1 -0
  324. package/esm/shared/FilterByTag.d.ts +13 -11
  325. package/esm/shared/FilterByTag.js +8 -13
  326. package/esm/shared/FilterByTag.js.map +1 -1
  327. package/esm/shared/afterAttach.d.ts +2 -0
  328. package/esm/shared/afterAttach.js +40 -0
  329. package/esm/shared/afterAttach.js.map +1 -0
  330. package/esm/shared/color.d.ts +44 -6
  331. package/esm/shared/color.js +54 -20
  332. package/esm/shared/color.js.map +1 -1
  333. package/esm/shared/fetchChains.d.ts +3 -2
  334. package/esm/shared/fetchChains.js +14 -20
  335. package/esm/shared/fetchChains.js.map +1 -1
  336. package/esm/shared/renderSvg.d.ts +7 -0
  337. package/esm/shared/renderSvg.js +39 -0
  338. package/esm/shared/renderSvg.js.map +1 -0
  339. package/esm/shared/util.d.ts +2 -0
  340. package/esm/shared/util.js +9 -0
  341. package/esm/shared/util.js.map +1 -0
  342. package/esm/util.d.ts +16 -2
  343. package/esm/util.js +42 -3
  344. package/esm/util.js.map +1 -1
  345. package/package.json +3 -3
  346. package/src/AlignmentsFeatureDetail/AlignmentsFeatureFlags.tsx +3 -5
  347. package/src/BamAdapter/BamAdapter.ts +41 -42
  348. package/src/CombinationTest.test.ts +2 -2
  349. package/src/CramAdapter/CramAdapter.ts +66 -55
  350. package/src/CramAdapter/CramSlightlyLazyFeature.ts +2 -5
  351. package/src/CramAdapter/CramTestAdapters.ts +1 -1
  352. package/src/LinearAlignmentsDisplay/models/model.tsx +5 -1
  353. package/src/LinearPileupDisplay/components/ColorByModifications.tsx +3 -39
  354. package/src/LinearPileupDisplay/components/ColorByTag.tsx +1 -6
  355. package/src/LinearPileupDisplay/components/LinearPileupDisplayBlurb.tsx +10 -11
  356. package/src/LinearPileupDisplay/components/ModificationsTable.tsx +38 -0
  357. package/src/LinearPileupDisplay/model.ts +199 -152
  358. package/src/LinearReadArcsDisplay/components/ReactComponent.tsx +23 -61
  359. package/src/LinearReadArcsDisplay/drawFeats.ts +77 -85
  360. package/src/LinearReadArcsDisplay/model.tsx +77 -155
  361. package/src/LinearReadArcsDisplay/util.ts +10 -0
  362. package/src/LinearReadCloudDisplay/components/ReactComponent.tsx +21 -59
  363. package/src/LinearReadCloudDisplay/drawFeats.ts +12 -167
  364. package/src/LinearReadCloudDisplay/drawLongReadChains.ts +85 -0
  365. package/src/LinearReadCloudDisplay/drawPairChains.ts +139 -0
  366. package/src/LinearReadCloudDisplay/model.tsx +72 -131
  367. package/src/LinearReadCloudDisplay/util.ts +47 -0
  368. package/src/LinearSNPCoverageDisplay/models/model.ts +63 -50
  369. package/src/MismatchParser/index.ts +46 -4
  370. package/src/PileupRPC/methods/GetReducedFeatures.ts +2 -10
  371. package/src/PileupRenderer/PileupRenderer.ts +23 -1200
  372. package/src/PileupRenderer/colorBy.ts +74 -0
  373. package/src/PileupRenderer/components/PileupRendering.tsx +20 -25
  374. package/src/PileupRenderer/getAlignmentShapeColor.ts +87 -0
  375. package/src/PileupRenderer/index.ts +1 -1
  376. package/src/PileupRenderer/layoutFeature.ts +83 -0
  377. package/src/PileupRenderer/layoutFeatures.ts +44 -0
  378. package/src/PileupRenderer/makeImageData.ts +93 -0
  379. package/src/PileupRenderer/renderAlignment.ts +97 -0
  380. package/src/PileupRenderer/renderAlignmentShape.ts +45 -0
  381. package/src/PileupRenderer/renderMethylation.ts +75 -0
  382. package/src/PileupRenderer/renderMismatches.ts +206 -0
  383. package/src/PileupRenderer/renderModifications.ts +74 -0
  384. package/src/PileupRenderer/renderPerBaseLettering.ts +67 -0
  385. package/src/PileupRenderer/renderPerBaseQuality.ts +46 -0
  386. package/src/PileupRenderer/renderSoftClipping.ts +78 -0
  387. package/src/PileupRenderer/sortUtil.ts +1 -3
  388. package/src/PileupRenderer/util.ts +63 -0
  389. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +0 -3
  390. package/src/SNPCoverageAdapter/generateCoverageBins.ts +111 -100
  391. package/src/SNPCoverageAdapter/index.ts +0 -2
  392. package/src/SNPCoverageAdapter/util.ts +33 -0
  393. package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +3 -3
  394. package/src/SNPCoverageRenderer/configSchema.ts +6 -0
  395. package/src/shared/BaseDisplayComponent.tsx +83 -0
  396. package/src/shared/FilterByTag.tsx +13 -23
  397. package/src/shared/afterAttach.tsx +66 -0
  398. package/src/shared/color.ts +59 -20
  399. package/src/shared/fetchChains.ts +23 -24
  400. package/src/shared/renderSvg.tsx +64 -0
  401. package/src/shared/util.ts +10 -0
  402. package/src/util.ts +54 -5
@@ -1,84 +1,30 @@
1
- import { Theme } from '@mui/material/styles'
2
1
  import BoxRendererType, {
3
2
  RenderArgsDeserialized as BoxRenderArgsDeserialized,
4
3
  } from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType'
5
- import { createJBrowseTheme } from '@jbrowse/core/ui'
6
4
  import {
7
- bpSpanPx,
8
- iterMap,
9
- measureText,
10
- Region,
11
5
  Feature,
6
+ Region,
7
+ notEmpty,
8
+ renderToAbstractCanvas,
12
9
  } from '@jbrowse/core/util'
13
- import { renderToAbstractCanvas } from '@jbrowse/core/util/offscreenCanvasUtils'
14
10
  import { BaseLayout } from '@jbrowse/core/util/layouts/BaseLayout'
15
11
  import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'
16
- import {
17
- readConfObject,
18
- AnyConfigurationModel,
19
- } from '@jbrowse/core/configuration'
20
-
21
- // locals
22
- import {
23
- Mismatch,
24
- parseCigar,
25
- getModificationPositions,
26
- getNextRefPos,
27
- } from '../MismatchParser'
28
- import { sortFeature } from './sortUtil'
29
- import {
30
- getTagAlt,
31
- orientationTypes,
32
- fetchSequence,
33
- shouldFetchReferenceSequence,
34
- } from '../util'
35
12
  import {
36
13
  PileupLayoutSession,
37
14
  PileupLayoutSessionProps,
38
15
  } from './PileupLayoutSession'
39
16
  import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
40
17
 
41
- function fillRect(
42
- ctx: CanvasRenderingContext2D,
43
- l: number,
44
- t: number,
45
- w: number,
46
- h: number,
47
- cw: number,
48
- color?: string,
49
- ) {
50
- if (l + w < 0 || l > cw) {
51
- return
52
- } else {
53
- if (color) {
54
- ctx.fillStyle = color
55
- }
56
- ctx.fillRect(l, t, w, h)
57
- }
58
- }
59
-
60
- function getColorBaseMap(theme: Theme) {
61
- const { bases } = theme.palette
62
- return {
63
- A: bases.A.main,
64
- C: bases.C.main,
65
- G: bases.G.main,
66
- T: bases.T.main,
67
- deletion: '#808080', // gray
68
- }
69
- }
70
-
71
- function getContrastBaseMap(theme: Theme) {
72
- const map = getColorBaseMap(theme)
73
- return Object.fromEntries(
74
- Object.entries(map).map(([k, v]) => [k, theme.palette.getContrastText(v)]),
75
- )
76
- }
18
+ // locals
19
+ import { fetchSequence, shouldFetchReferenceSequence } from '../util'
20
+ import { layoutFeats } from './layoutFeatures'
21
+ import { makeImageData } from './makeImageData'
22
+ import { readConfObject } from '@jbrowse/core/configuration'
77
23
 
78
24
  export interface RenderArgsDeserialized extends BoxRenderArgsDeserialized {
79
25
  colorBy?: { type: string; tag?: string }
80
26
  colorTagMap?: Record<string, string>
81
- modificationTagMap?: Record<string, string>
27
+ modificationTagMap?: Record<string, string | undefined>
82
28
  sortedBy?: {
83
29
  type: string
84
30
  pos: number
@@ -97,130 +43,25 @@ export interface RenderArgsDeserializedWithFeaturesAndLayout
97
43
  regionSequence?: string
98
44
  }
99
45
 
100
- interface LayoutRecord {
101
- feature: Feature
102
- leftPx: number
103
- rightPx: number
104
- topPx: number
105
- heightPx: number
106
- }
107
-
108
- const alignmentColoring: { [key: string]: string } = {
109
- color_fwd_strand_not_proper: '#ECC8C8',
110
- color_rev_strand_not_proper: '#BEBED8',
111
- color_fwd_strand: '#EC8B8B',
112
- color_rev_strand: '#8F8FD8',
113
- color_fwd_missing_mate: '#D11919',
114
- color_rev_missing_mate: '#1919D1',
115
- color_fwd_diff_chr: '#000',
116
- color_rev_diff_chr: '#969696',
117
- color_pair_lr: '#c8c8c8',
118
- color_pair_rr: 'navy',
119
- color_pair_rl: 'teal',
120
- color_pair_ll: 'green',
121
- color_nostrand: '#c8c8c8',
122
- color_interchrom: 'orange',
123
- color_longinsert: 'red',
124
- color_shortinsert: 'pink',
125
- }
126
-
127
- interface LayoutFeature {
128
- heightPx: number
129
- topPx: number
130
- feature: Feature
131
- }
132
-
133
- function shouldDrawSNPsMuted(type?: string) {
134
- return ['methylation', 'modifications'].includes(type || '')
135
- }
136
-
137
- function shouldDrawIndels(type?: string) {
138
- return true
139
- }
140
-
141
46
  export default class PileupRenderer extends BoxRendererType {
142
47
  supportsSVG = true
143
48
 
144
- // get width and height of chars the height is an approximation: width
145
- // letter M is approximately the height
146
- getCharWidthHeight() {
147
- const charWidth = measureText('A')
148
- const charHeight = measureText('M') - 2
149
- return { charWidth, charHeight }
150
- }
151
-
152
- layoutFeature({
153
- feature,
154
- layout,
155
- bpPerPx,
156
- region,
157
- showSoftClip,
158
- heightPx,
159
- displayMode,
160
- }: {
161
- feature: Feature
162
- layout: BaseLayout<Feature>
163
- bpPerPx: number
164
- region: Region
165
- showSoftClip?: boolean
166
- heightPx: number
167
- displayMode: string
168
- }): LayoutRecord | null {
169
- let expansionBefore = 0
170
- let expansionAfter = 0
171
-
172
- // Expand the start and end of feature when softclipping enabled
173
- if (showSoftClip) {
174
- const mismatches = feature.get('mismatches') as Mismatch[] | undefined
175
- const seq = feature.get('seq') as string | undefined
176
- if (seq && mismatches) {
177
- for (let i = 0; i < mismatches.length; i += 1) {
178
- const { type, start, cliplen = 0 } = mismatches[i]
179
- if (type === 'softclip') {
180
- start === 0
181
- ? (expansionBefore = cliplen)
182
- : (expansionAfter = cliplen)
183
- }
184
- }
185
- }
186
- }
187
- const s = feature.get('start') - expansionBefore
188
- const e = feature.get('end') + expansionAfter
189
-
190
- const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx)
191
-
192
- if (displayMode === 'compact') {
193
- heightPx /= 3
194
- }
195
- if (feature.get('refName') !== region.refName) {
196
- throw new Error(
197
- `feature ${feature.id()} is not on the current region's reference sequence ${
198
- region.refName
199
- }`,
200
- )
201
- }
202
- const topPx = layout.addRect(feature.id(), s, e, heightPx, feature)
203
- if (topPx === null) {
204
- return null
205
- }
206
-
207
- return {
208
- feature,
209
- leftPx,
210
- rightPx,
211
- topPx: displayMode === 'collapse' ? 0 : topPx,
212
- heightPx,
49
+ async fetchSequence(renderProps: RenderArgsDeserialized) {
50
+ const { sessionId, regions, adapterConfig } = renderProps
51
+ const { sequenceAdapter } = adapterConfig
52
+ if (!sequenceAdapter) {
53
+ return undefined
213
54
  }
55
+ const pm = this.pluginManager
56
+ const { dataAdapter } = await getAdapter(pm, sessionId, sequenceAdapter)
57
+ const [region] = regions
58
+ return fetchSequence(region, dataAdapter as BaseFeatureDataAdapter)
214
59
  }
215
60
 
216
- // expands region for clipping to use. possible improvement: use average read
217
- // size to set the heuristic maxClippingSize expansion (e.g. short reads
218
- // don't have to expand a softclipping size a lot, but long reads might)
219
61
  getExpandedRegion(region: Region, renderArgs: RenderArgsDeserialized) {
220
62
  const { config, showSoftClip } = renderArgs
221
-
222
- const maxClippingSize = readConfObject(config, 'maxClippingSize')
223
63
  const { start, end } = region
64
+ const maxClippingSize = readConfObject(config, 'maxClippingSize')
224
65
  const bpExpansion = showSoftClip ? Math.round(maxClippingSize) : 0
225
66
 
226
67
  return {
@@ -231,1029 +72,13 @@ export default class PileupRenderer extends BoxRendererType {
231
72
  }
232
73
  }
233
74
 
234
- colorByOrientation(feature: Feature, config: AnyConfigurationModel) {
235
- return alignmentColoring[
236
- this.getOrientation(feature, config) || 'color_nostrand'
237
- ]
238
- }
239
-
240
- getOrientation(feature: Feature, config: AnyConfigurationModel) {
241
- const orientationType = readConfObject(config, 'orientationType') as
242
- | 'fr'
243
- | 'ff'
244
- | 'rf'
245
- const type = orientationTypes[orientationType]
246
- const orientation = type[feature.get('pair_orientation') as string]
247
- const map: { [key: string]: string } = {
248
- LR: 'color_pair_lr',
249
- RR: 'color_pair_rr',
250
- RL: 'color_pair_rl',
251
- LL: 'color_pair_ll',
252
- }
253
- return map[orientation]
254
- }
255
-
256
- colorByInsertSize(feature: Feature, _config: AnyConfigurationModel) {
257
- return feature.get('is_paired') &&
258
- feature.get('refName') !== feature.get('next_ref')
259
- ? '#555'
260
- : `hsl(${Math.abs(feature.get('template_length')) / 10},50%,50%)`
261
- }
262
-
263
- colorByStranded(feature: Feature, _config: AnyConfigurationModel) {
264
- const flags = feature.get('flags')
265
- const strand = feature.get('strand')
266
- // is paired
267
- if (flags & 1) {
268
- const revflag = flags & 64
269
- const flipper = revflag ? -1 : 1
270
- // proper pairing
271
- if (flags & 2) {
272
- return strand * flipper === 1 ? 'color_rev_strand' : 'color_fwd_strand'
273
- }
274
- if (feature.get('multi_segment_next_segment_unmapped')) {
275
- return strand * flipper === 1
276
- ? 'color_rev_missing_mate'
277
- : 'color_fwd_missing_mate'
278
- }
279
- if (feature.get('refName') === feature.get('next_refName')) {
280
- return strand * flipper === 1
281
- ? 'color_rev_strand_not_proper'
282
- : 'color_fwd_strand_not_proper'
283
- }
284
- // should only leave aberrant chr
285
- return strand === 1 ? 'color_fwd_diff_chr' : 'color_rev_diff_chr'
286
- }
287
- return strand === 1 ? 'color_fwd_strand' : 'color_rev_strand'
288
- }
289
-
290
- colorByPerBaseLettering({
291
- ctx,
292
- feat,
293
- region,
294
- bpPerPx,
295
- colorForBase,
296
- contrastForBase,
297
- charWidth,
298
- charHeight,
299
- canvasWidth,
300
- }: {
301
- ctx: CanvasRenderingContext2D
302
- feat: LayoutFeature
303
- region: Region
304
- bpPerPx: number
305
- colorForBase: Record<string, string>
306
- contrastForBase: Record<string, string>
307
- charWidth: number
308
- charHeight: number
309
- canvasWidth: number
310
- }) {
311
- const heightLim = charHeight - 2
312
- const { feature, topPx, heightPx } = feat
313
- const seq = feature.get('seq') as string | undefined
314
- const cigarOps = parseCigar(feature.get('CIGAR'))
315
- const w = 1 / bpPerPx
316
- const start = feature.get('start')
317
- let soffset = 0 // sequence offset
318
- let roffset = 0 // reference offset
319
-
320
- if (!seq) {
321
- return
322
- }
323
- for (let i = 0; i < cigarOps.length; i += 2) {
324
- const len = +cigarOps[i]
325
- const op = cigarOps[i + 1]
326
- if (op === 'S' || op === 'I') {
327
- soffset += len
328
- } else if (op === 'D' || op === 'N') {
329
- roffset += len
330
- } else if (op === 'M' || op === 'X' || op === '=') {
331
- for (let m = 0; m < len; m++) {
332
- const letter = seq[soffset + m]
333
- const r = start + roffset + m
334
- const [leftPx] = bpSpanPx(r, r + 1, region, bpPerPx)
335
- fillRect(
336
- ctx,
337
- leftPx,
338
- topPx,
339
- w + 0.5,
340
- heightPx,
341
- canvasWidth,
342
- colorForBase[letter],
343
- )
344
-
345
- if (w >= charWidth && heightPx >= heightLim) {
346
- // normal SNP coloring
347
- ctx.fillStyle = contrastForBase[letter]
348
-
349
- ctx.fillText(
350
- letter,
351
- leftPx + (w - charWidth) / 2 + 1,
352
- topPx + heightPx,
353
- )
354
- }
355
- }
356
- soffset += len
357
- roffset += len
358
- }
359
- }
360
- }
361
- colorByPerBaseQuality({
362
- ctx,
363
- feat,
364
- region,
365
- bpPerPx,
366
- canvasWidth,
367
- }: {
368
- ctx: CanvasRenderingContext2D
369
- feat: LayoutFeature
370
- region: Region
371
- bpPerPx: number
372
- canvasWidth: number
373
- }) {
374
- const { feature, topPx, heightPx } = feat
375
- const qual: string = feature.get('qual') || ''
376
- const scores = qual.split(' ').map(val => +val)
377
- const cigarOps = parseCigar(feature.get('CIGAR'))
378
- const width = 1 / bpPerPx
379
- const start = feature.get('start')
380
- let soffset = 0 // sequence offset
381
- let roffset = 0 // reference offset
382
-
383
- for (let i = 0; i < cigarOps.length; i += 2) {
384
- const len = +cigarOps[i]
385
- const op = cigarOps[i + 1]
386
- if (op === 'S' || op === 'I') {
387
- soffset += len
388
- } else if (op === 'D' || op === 'N') {
389
- roffset += len
390
- } else if (op === 'M' || op === 'X' || op === '=') {
391
- for (let m = 0; m < len; m++) {
392
- const score = scores[soffset + m]
393
- const [leftPx] = bpSpanPx(
394
- start + roffset + m,
395
- start + roffset + m + 1,
396
- region,
397
- bpPerPx,
398
- )
399
- fillRect(
400
- ctx,
401
- leftPx,
402
- topPx,
403
- width + 0.5,
404
- heightPx,
405
- canvasWidth,
406
- `hsl(${score === 255 ? 150 : score * 1.5},55%,50%)`,
407
- )
408
- }
409
- soffset += len
410
- roffset += len
411
- }
412
- }
413
- }
414
-
415
- // ML stores probabilities as array of numerics and MP is scaled phred scores
416
- // https://github.com/samtools/hts-specs/pull/418/files#diff-e765c6479316309f56b636f88189cdde8c40b854c7bdcce9ee7fe87a4e76febcR596
417
- //
418
- // if we have ML or Ml, it is an 8bit probability, divide by 255
419
- //
420
- // if we have MP or Mp it is phred scaled ASCII, which can go up to 90 but
421
- // has very high likelihood basecalls at that point, we really only care
422
- // about low qual calls <20 approx
423
- //
424
- colorByModifications({
425
- ctx,
426
- feat,
427
- region,
428
- bpPerPx,
429
- renderArgs,
430
- canvasWidth,
431
- }: {
432
- ctx: CanvasRenderingContext2D
433
- feat: LayoutFeature
434
- region: Region
435
- bpPerPx: number
436
- renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
437
- canvasWidth: number
438
- }) {
439
- const { feature, topPx, heightPx } = feat
440
- const { Color, modificationTagMap = {} } = renderArgs
441
-
442
- const mm = (getTagAlt(feature, 'MM', 'Mm') as string) || ''
443
-
444
- const ml = (getTagAlt(feature, 'ML', 'Ml') as number[] | string) || []
445
-
446
- const probabilities = ml
447
- ? (typeof ml === 'string' ? ml.split(',').map(e => +e) : ml).map(
448
- e => e / 255,
449
- )
450
- : (getTagAlt(feature, 'MP', 'Mp') as string)
451
- .split('')
452
- .map(s => s.charCodeAt(0) - 33)
453
- .map(elt => Math.min(1, elt / 50))
454
-
455
- const cigar = feature.get('CIGAR')
456
- const start = feature.get('start')
457
- const seq = feature.get('seq') as string | undefined
458
- const strand = feature.get('strand')
459
- const cigarOps = parseCigar(cigar)
460
- if (!seq) {
461
- return
462
- }
463
-
464
- const modifications = getModificationPositions(mm, seq, strand)
465
-
466
- // probIndex applies across multiple modifications e.g.
467
- let probIndex = 0
468
- for (const { type, positions } of modifications) {
469
- const col = modificationTagMap[type] || 'black'
470
-
471
- // @ts-expect-error
472
- const base = Color(col)
473
- for (const readPos of getNextRefPos(cigarOps, positions)) {
474
- const r = start + readPos
475
- const [leftPx, rightPx] = bpSpanPx(r, r + 1, region, bpPerPx)
476
-
477
- // give it a little boost of 0.1 to not make them fully
478
- // invisible to avoid confusion
479
- const prob = probabilities[probIndex]
480
-
481
- fillRect(
482
- ctx,
483
- leftPx,
484
- topPx,
485
- rightPx - leftPx + 0.5,
486
- heightPx,
487
- canvasWidth,
488
- prob && prob !== 1
489
- ? base
490
- .alpha(prob + 0.1)
491
- .hsl()
492
- .string()
493
- : col,
494
- )
495
- probIndex++
496
- }
497
- }
498
- }
499
-
500
- // Color by methylation is slightly modified version of color by
501
- // modifications that focuses on CpG sites, with non-methylated CpG colored
502
- // blue
503
- colorByMethylation({
504
- ctx,
505
- feat,
506
- region,
507
- bpPerPx,
508
- renderArgs,
509
- canvasWidth,
510
- }: {
511
- ctx: CanvasRenderingContext2D
512
- feat: LayoutFeature
513
- region: Region
514
- bpPerPx: number
515
- renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
516
- canvasWidth: number
517
- }) {
518
- const { regionSequence } = renderArgs
519
- const { feature, topPx, heightPx } = feat
520
-
521
- const mm: string = getTagAlt(feature, 'MM', 'Mm') || ''
522
-
523
- if (!regionSequence) {
524
- throw new Error('region sequence required for methylation')
525
- }
526
-
527
- const cigar = feature.get('CIGAR')
528
- const fstart = feature.get('start')
529
- const fend = feature.get('end')
530
- const seq = feature.get('seq') as string | undefined
531
- const strand = feature.get('strand')
532
- const cigarOps = parseCigar(cigar)
533
-
534
- if (!seq) {
535
- return
536
- }
537
-
538
- const methBins = new Array(region.end - region.start).fill(0)
539
- const modifications = getModificationPositions(mm, seq, strand)
540
- for (let i = 0; i < modifications.length; i++) {
541
- const { type, positions } = modifications[i]
542
- if (type === 'm' && positions) {
543
- for (const pos of getNextRefPos(cigarOps, positions)) {
544
- const epos = pos + fstart - region.start
545
- if (epos >= 0 && epos < methBins.length) {
546
- methBins[epos] = 1
547
- }
548
- }
549
- }
550
- }
551
-
552
- for (let j = fstart; j < fend; j++) {
553
- const i = j - region.start
554
- if (i >= 0 && i < methBins.length) {
555
- const l1 = regionSequence[i].toLowerCase()
556
- const l2 = regionSequence[i + 1].toLowerCase()
557
-
558
- // if we are zoomed out, display just a block over the cpg
559
- if (bpPerPx > 2) {
560
- if (l1 === 'c' && l2 === 'g') {
561
- const s = region.start + i
562
- const [leftPx, rightPx] = bpSpanPx(s, s + 2, region, bpPerPx)
563
- fillRect(
564
- ctx,
565
- leftPx,
566
- topPx,
567
- rightPx - leftPx + 0.5,
568
- heightPx,
569
- canvasWidth,
570
- methBins[i] || methBins[i + 1] ? 'red' : 'blue',
571
- )
572
- }
573
- }
574
- // if we are zoomed in, color the c inside the cpg
575
- else {
576
- // color
577
- if (l1 === 'c' && l2 === 'g') {
578
- const s = region.start + i
579
- const [leftPx, rightPx] = bpSpanPx(s, s + 1, region, bpPerPx)
580
- fillRect(
581
- ctx,
582
- leftPx,
583
- topPx,
584
- rightPx - leftPx + 0.5,
585
- heightPx,
586
- canvasWidth,
587
- methBins[i] ? 'red' : 'blue',
588
- )
589
-
590
- const [leftPx2, rightPx2] = bpSpanPx(s + 1, s + 2, region, bpPerPx)
591
- fillRect(
592
- ctx,
593
- leftPx2,
594
- topPx,
595
- rightPx2 - leftPx2 + 0.5,
596
- heightPx,
597
- canvasWidth,
598
- methBins[i + 1] ? 'red' : 'blue',
599
- )
600
- }
601
- }
602
- }
603
- }
604
- }
605
-
606
- drawRect(
607
- ctx: CanvasRenderingContext2D,
608
- feat: LayoutFeature,
609
- props: RenderArgsDeserialized,
610
- ) {
611
- const { regions, bpPerPx } = props
612
- const { heightPx, topPx, feature } = feat
613
- const [region] = regions
614
- const [leftPx, rightPx] = bpSpanPx(
615
- feature.get('start'),
616
- feature.get('end'),
617
- region,
618
- bpPerPx,
619
- )
620
- const flip = region.reversed ? -1 : 1
621
- const strand = feature.get('strand') * flip
622
- if (bpPerPx < 10) {
623
- if (strand === -1) {
624
- ctx.beginPath()
625
- ctx.moveTo(leftPx - 5, topPx + heightPx / 2)
626
- ctx.lineTo(leftPx, topPx + heightPx)
627
- ctx.lineTo(rightPx, topPx + heightPx)
628
- ctx.lineTo(rightPx, topPx)
629
- ctx.lineTo(leftPx, topPx)
630
- ctx.closePath()
631
- ctx.fill()
632
- } else {
633
- ctx.beginPath()
634
- ctx.moveTo(leftPx, topPx)
635
- ctx.lineTo(leftPx, topPx + heightPx)
636
- ctx.lineTo(rightPx, topPx + heightPx)
637
- ctx.lineTo(rightPx + 5, topPx + heightPx / 2)
638
- ctx.lineTo(rightPx, topPx)
639
- ctx.closePath()
640
- ctx.fill()
641
- }
642
- } else {
643
- ctx.fillRect(leftPx, topPx, rightPx - leftPx, heightPx)
644
- }
645
- }
646
-
647
- drawAlignmentRect({
648
- ctx,
649
- feat,
650
- renderArgs,
651
- colorForBase,
652
- contrastForBase,
653
- charWidth,
654
- charHeight,
655
- defaultColor,
656
- theme,
657
- canvasWidth,
658
- }: {
659
- ctx: CanvasRenderingContext2D
660
- feat: LayoutFeature
661
- renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
662
- colorForBase: Record<string, string>
663
- contrastForBase: Record<string, string>
664
- charWidth: number
665
- charHeight: number
666
- defaultColor: boolean
667
- canvasWidth: number
668
- theme: Theme
669
- }) {
670
- const { config, bpPerPx, regions, colorBy, colorTagMap = {} } = renderArgs
671
- const { tag = '', type: colorType = '' } = colorBy || {}
672
- const { feature } = feat
673
- const region = regions[0]
674
-
675
- // first pass for simple color changes that change the color of the
676
- // alignment
677
- switch (colorType) {
678
- case 'insertSize':
679
- ctx.fillStyle = this.colorByInsertSize(feature, config)
680
- break
681
- case 'strand':
682
- ctx.fillStyle = feature.get('strand') === -1 ? '#8F8FD8' : '#EC8B8B'
683
- break
684
- case 'mappingQuality':
685
- ctx.fillStyle = `hsl(${feature.get('mq')},50%,50%)`
686
- break
687
-
688
- case 'pairOrientation':
689
- ctx.fillStyle = this.colorByOrientation(feature, config)
690
- break
691
- case 'stranded':
692
- ctx.fillStyle = alignmentColoring[this.colorByStranded(feature, config)]
693
- break
694
- case 'xs':
695
- case 'tag': {
696
- const tags = feature.get('tags')
697
- const val = tags ? tags[tag] : feature.get(tag)
698
-
699
- // special for for XS/TS tag
700
- if (tag === 'XS' || tag === 'TS') {
701
- const map: { [key: string]: string | undefined } = {
702
- '-': 'color_rev_strand',
703
- '+': 'color_fwd_strand',
704
- }
705
- ctx.fillStyle = alignmentColoring[map[val] || 'color_nostrand']
706
- }
707
-
708
- // lower case 'ts' from minimap2 is flipped from xs
709
- if (tag === 'ts') {
710
- const map: { [key: string]: string } = {
711
- '-':
712
- feature.get('strand') === -1
713
- ? 'color_fwd_strand'
714
- : 'color_rev_strand',
715
- '+':
716
- feature.get('strand') === -1
717
- ? 'color_rev_strand'
718
- : 'color_fwd_strand',
719
- }
720
- ctx.fillStyle = alignmentColoring[map[val] || 'color_nostrand']
721
- }
722
-
723
- // tag is not one of the autofilled tags, has color-value pairs from
724
- // fetchValues
725
- else {
726
- const foundValue = colorTagMap[val]
727
- ctx.fillStyle = foundValue || alignmentColoring['color_nostrand']
728
- }
729
- break
730
- }
731
- case 'insertSizeAndPairOrientation': {
732
- break
733
- }
734
-
735
- case 'modifications':
736
- case 'methylation': {
737
- // this coloring is similar to igv.js, and is helpful to color negative
738
- // strand reads differently because their c-g will be flipped (e.g. g-c
739
- // read right to left)
740
- ctx.fillStyle = feature.get('flags') & 16 ? '#c8dcc8' : '#c8c8c8'
741
- break
742
- }
743
-
744
- default: {
745
- ctx.fillStyle = defaultColor
746
- ? 'lightgrey'
747
- : readConfObject(config, 'color', { feature })
748
- break
749
- }
750
- }
751
-
752
- this.drawRect(ctx, feat, renderArgs)
753
-
754
- // second pass for color types that render per-base things that go over the
755
- // existing drawing
756
- switch (colorType) {
757
- case 'perBaseQuality':
758
- this.colorByPerBaseQuality({
759
- ctx,
760
- feat,
761
- region,
762
- bpPerPx,
763
- canvasWidth,
764
- })
765
- break
766
-
767
- case 'perBaseLettering':
768
- this.colorByPerBaseLettering({
769
- ctx,
770
- feat,
771
- region,
772
- bpPerPx,
773
- colorForBase,
774
- contrastForBase,
775
- charWidth,
776
- charHeight,
777
- canvasWidth,
778
- })
779
- break
780
-
781
- case 'modifications':
782
- this.colorByModifications({
783
- ctx,
784
- feat,
785
- region,
786
- bpPerPx,
787
- renderArgs,
788
- canvasWidth,
789
- })
790
- break
791
-
792
- case 'methylation':
793
- this.colorByMethylation({
794
- ctx,
795
- feat,
796
- region,
797
- bpPerPx,
798
- renderArgs,
799
- canvasWidth,
800
- })
801
- break
802
- }
803
- }
804
-
805
- drawMismatches({
806
- ctx,
807
- feat,
808
- renderArgs,
809
- minSubfeatureWidth,
810
- largeInsertionIndicatorScale,
811
- mismatchAlpha,
812
- charWidth,
813
- charHeight,
814
- colorForBase,
815
- contrastForBase,
816
- canvasWidth,
817
- drawSNPsMuted,
818
- drawIndels = true,
819
- }: {
820
- ctx: CanvasRenderingContext2D
821
- feat: LayoutFeature
822
- renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
823
- colorForBase: { [key: string]: string }
824
- contrastForBase: { [key: string]: string }
825
- mismatchAlpha?: boolean
826
- drawIndels?: boolean
827
- drawSNPsMuted?: boolean
828
- minSubfeatureWidth: number
829
- largeInsertionIndicatorScale: number
830
- charWidth: number
831
- charHeight: number
832
- canvasWidth: number
833
- theme: Theme
834
- }) {
835
- const { Color, bpPerPx, regions } = renderArgs
836
- const { heightPx, topPx, feature } = feat
837
- const [region] = regions
838
- const start = feature.get('start')
839
-
840
- const pxPerBp = Math.min(1 / bpPerPx, 2)
841
- const w = Math.max(minSubfeatureWidth, pxPerBp)
842
- const mismatches = feature.get('mismatches') as Mismatch[] | undefined
843
- const heightLim = charHeight - 2
844
-
845
- // extraHorizontallyFlippedOffset is used to draw interbase items, which
846
- // are located to the left when forward and right when reversed
847
- const extraHorizontallyFlippedOffset = region.reversed
848
- ? 1 / bpPerPx + 1
849
- : -1
850
-
851
- if (!mismatches) {
852
- return
853
- }
854
-
855
- // two pass rendering: first pass, draw all the mismatches except wide
856
- // insertion markers
857
- for (let i = 0; i < mismatches.length; i += 1) {
858
- const mismatch = mismatches[i]
859
- const mstart = start + mismatch.start
860
- const mlen = mismatch.length
861
- const mbase = mismatch.base
862
- const [leftPx, rightPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx)
863
- const widthPx = Math.max(minSubfeatureWidth, Math.abs(leftPx - rightPx))
864
- if (mismatch.type === 'mismatch') {
865
- if (!drawSNPsMuted) {
866
- const baseColor = colorForBase[mismatch.base] || '#888'
867
-
868
- fillRect(
869
- ctx,
870
- Math.round(leftPx),
871
- topPx,
872
- widthPx,
873
- heightPx,
874
- canvasWidth,
875
-
876
- mismatchAlpha
877
- ? mismatch.qual === undefined
878
- ? baseColor
879
- : // @ts-expect-error
880
- Color(baseColor)
881
- .alpha(Math.min(1, mismatch.qual / 50))
882
- .hsl()
883
- .string()
884
- : baseColor,
885
- )
886
- }
887
-
888
- if (widthPx >= charWidth && heightPx >= heightLim) {
889
- // normal SNP coloring
890
- const contrastColor = drawSNPsMuted
891
- ? 'black'
892
- : contrastForBase[mismatch.base] || 'black'
893
- ctx.fillStyle = mismatchAlpha
894
- ? mismatch.qual === undefined
895
- ? contrastColor
896
- : // @ts-expect-error
897
- Color(contrastColor)
898
- .alpha(Math.min(1, mismatch.qual / 50))
899
- .hsl()
900
- .string()
901
- : contrastColor
902
- ctx.fillText(
903
- mbase,
904
- leftPx + (widthPx - charWidth) / 2 + 1,
905
- topPx + heightPx,
906
- )
907
- }
908
- } else if (mismatch.type === 'deletion' && drawIndels) {
909
- fillRect(
910
- ctx,
911
- leftPx,
912
- topPx,
913
- Math.abs(leftPx - rightPx),
914
- heightPx,
915
- canvasWidth,
916
- colorForBase.deletion,
917
- )
918
- const txt = `${mismatch.length}`
919
- const rwidth = measureText(txt, 10)
920
- if (widthPx >= rwidth && heightPx >= heightLim) {
921
- ctx.fillStyle = contrastForBase.deletion
922
- ctx.fillText(
923
- txt,
924
- (leftPx + rightPx) / 2 - rwidth / 2,
925
- topPx + heightPx,
926
- )
927
- }
928
- } else if (mismatch.type === 'insertion' && drawIndels) {
929
- ctx.fillStyle = 'purple'
930
- const pos = leftPx + extraHorizontallyFlippedOffset
931
- const len = +mismatch.base || mismatch.length
932
- const insW = Math.max(0, Math.min(1.2, 1 / bpPerPx))
933
- if (len < 10) {
934
- fillRect(ctx, pos, topPx, insW, heightPx, canvasWidth, 'purple')
935
- if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
936
- fillRect(ctx, pos - insW, topPx, insW * 3, 1, canvasWidth)
937
- fillRect(
938
- ctx,
939
- pos - insW,
940
- topPx + heightPx - 1,
941
- insW * 3,
942
- 1,
943
- canvasWidth,
944
- )
945
- ctx.fillText(`(${mismatch.base})`, pos + 3, topPx + heightPx)
946
- }
947
- }
948
- } else if (mismatch.type === 'hardclip' || mismatch.type === 'softclip') {
949
- const pos = leftPx + extraHorizontallyFlippedOffset
950
- fillRect(
951
- ctx,
952
- pos,
953
- topPx,
954
- w,
955
- heightPx,
956
- canvasWidth,
957
- mismatch.type === 'hardclip' ? 'red' : 'blue',
958
- )
959
- if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
960
- fillRect(ctx, pos - w, topPx, w * 3, 1, canvasWidth)
961
- fillRect(ctx, pos - w, topPx + heightPx - 1, w * 3, 1, canvasWidth)
962
- ctx.fillText(`(${mismatch.base})`, pos + 3, topPx + heightPx)
963
- }
964
- } else if (mismatch.type === 'skip') {
965
- // fix to avoid bad rendering note that this was also related to chrome
966
- // bug https://bugs.chromium.org/p/chromium/issues/detail?id=1131528
967
- // also affected firefox ref #1236 #2750
968
- if (leftPx + widthPx > 0) {
969
- // make small exons more visible when zoomed far out
970
- const adjustPx = widthPx - (bpPerPx > 10 ? 1.5 : 0)
971
- ctx.clearRect(leftPx, topPx, adjustPx, heightPx)
972
- fillRect(
973
- ctx,
974
- Math.max(0, leftPx),
975
- topPx + heightPx / 2 - 1,
976
- adjustPx + (leftPx < 0 ? leftPx : 0),
977
- 2,
978
- canvasWidth,
979
- '#333',
980
- )
981
- }
982
- }
983
- }
984
-
985
- // second pass, draw wide insertion markers on top
986
- if (drawIndels) {
987
- for (let i = 0; i < mismatches.length; i += 1) {
988
- const mismatch = mismatches[i]
989
- const mstart = start + mismatch.start
990
- const mlen = mismatch.length
991
- const [leftPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx)
992
- const len = +mismatch.base || mismatch.length
993
- const txt = `${len}`
994
- if (mismatch.type === 'insertion' && len >= 10) {
995
- if (bpPerPx > largeInsertionIndicatorScale) {
996
- fillRect(ctx, leftPx - 1, topPx, 2, heightPx, canvasWidth, 'purple')
997
- } else if (heightPx > charHeight) {
998
- const rwidth = measureText(txt)
999
- const padding = 5
1000
- fillRect(
1001
- ctx,
1002
- leftPx - rwidth / 2 - padding,
1003
- topPx,
1004
- rwidth + 2 * padding,
1005
- heightPx,
1006
- canvasWidth,
1007
- 'purple',
1008
- )
1009
- ctx.fillStyle = 'white'
1010
- ctx.fillText(txt, leftPx - rwidth / 2, topPx + heightPx)
1011
- } else {
1012
- const padding = 2
1013
- fillRect(
1014
- ctx,
1015
- leftPx - padding,
1016
- topPx,
1017
- 2 * padding,
1018
- heightPx,
1019
- canvasWidth,
1020
- 'purple',
1021
- )
1022
- }
1023
- }
1024
- }
1025
- }
1026
- }
1027
-
1028
- drawSoftClipping({
1029
- ctx,
1030
- feat,
1031
- renderArgs,
1032
- config,
1033
- theme,
1034
- canvasWidth,
1035
- }: {
1036
- ctx: CanvasRenderingContext2D
1037
- feat: LayoutFeature
1038
- renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
1039
- config: AnyConfigurationModel
1040
- theme: Theme
1041
- canvasWidth: number
1042
- }) {
1043
- const { feature, topPx, heightPx } = feat
1044
- const { regions, bpPerPx } = renderArgs
1045
- const [region] = regions
1046
- const minFeatWidth = readConfObject(config, 'minSubfeatureWidth')
1047
- const mismatches = feature.get('mismatches') as Mismatch[] | undefined
1048
- const seq = feature.get('seq') as string | undefined
1049
- const { charWidth, charHeight } = this.getCharWidthHeight()
1050
- const { bases } = theme.palette
1051
- const colorForBase: { [key: string]: string } = {
1052
- A: bases.A.main,
1053
- C: bases.C.main,
1054
- G: bases.G.main,
1055
- T: bases.T.main,
1056
- deletion: '#808080', // gray
1057
- }
1058
-
1059
- // Display all bases softclipped off in lightened colors
1060
- if (!(seq && mismatches)) {
1061
- return
1062
- }
1063
- mismatches
1064
- .filter(mismatch => mismatch.type === 'softclip')
1065
- .forEach(mismatch => {
1066
- const len = mismatch.cliplen || 0
1067
- const s = feature.get('start')
1068
- const start = mismatch.start === 0 ? s - len : s + mismatch.start
1069
-
1070
- for (let k = 0; k < len; k += 1) {
1071
- const base = seq.charAt(k + mismatch.start)
1072
-
1073
- // If softclip length+start is longer than sequence, no need to
1074
- // continue showing base
1075
- if (!base) {
1076
- return
1077
- }
1078
-
1079
- const [leftPx, rightPx] = bpSpanPx(
1080
- start + k,
1081
- start + k + 1,
1082
- region,
1083
- bpPerPx,
1084
- )
1085
- const widthPx = Math.max(minFeatWidth, rightPx - leftPx)
1086
-
1087
- // Black accounts for IUPAC ambiguity code bases such as N that
1088
- // show in soft clipping
1089
- const baseColor = colorForBase[base] || '#000000'
1090
- ctx.fillStyle = baseColor
1091
- fillRect(ctx, leftPx, topPx, widthPx, heightPx, canvasWidth)
1092
-
1093
- if (widthPx >= charWidth && heightPx >= charHeight - 5) {
1094
- ctx.fillStyle = theme.palette.getContrastText(baseColor)
1095
- ctx.fillText(
1096
- base,
1097
- leftPx + (widthPx - charWidth) / 2 + 1,
1098
- topPx + heightPx,
1099
- )
1100
- }
1101
- }
1102
- })
1103
- }
1104
-
1105
- makeImageData({
1106
- ctx,
1107
- layoutRecords,
1108
- canvasWidth,
1109
- renderArgs,
1110
- }: {
1111
- ctx: CanvasRenderingContext2D
1112
- canvasWidth: number
1113
- layoutRecords: (LayoutFeature | null)[]
1114
- renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
1115
- }) {
1116
- const {
1117
- layout,
1118
- config,
1119
- showSoftClip,
1120
- colorBy,
1121
- theme: configTheme,
1122
- } = renderArgs
1123
- const mismatchAlpha = readConfObject(config, 'mismatchAlpha')
1124
- const minSubfeatureWidth = readConfObject(config, 'minSubfeatureWidth')
1125
- const largeInsertionIndicatorScale = readConfObject(
1126
- config,
1127
- 'largeInsertionIndicatorScale',
1128
- )
1129
- const defaultColor = readConfObject(config, 'color') === '#f0f'
1130
-
1131
- const theme = createJBrowseTheme(configTheme)
1132
- const colorForBase = getColorBaseMap(theme)
1133
- const contrastForBase = getContrastBaseMap(theme)
1134
- if (!layout) {
1135
- throw new Error(`layout required`)
1136
- }
1137
- if (!layout.addRect) {
1138
- throw new Error('invalid layout object')
1139
- }
1140
- ctx.font = 'bold 10px Courier New,monospace'
1141
-
1142
- const { charWidth, charHeight } = this.getCharWidthHeight()
1143
- const drawSNPsMuted = shouldDrawSNPsMuted(colorBy?.type)
1144
- const drawIndels = shouldDrawIndels(colorBy?.type)
1145
- for (let i = 0; i < layoutRecords.length; i++) {
1146
- const feat = layoutRecords[i]
1147
- if (feat === null) {
1148
- continue
1149
- }
1150
-
1151
- this.drawAlignmentRect({
1152
- ctx,
1153
- feat,
1154
- renderArgs,
1155
- defaultColor,
1156
- colorForBase,
1157
- contrastForBase,
1158
- charWidth,
1159
- charHeight,
1160
- canvasWidth,
1161
- theme,
1162
- })
1163
- this.drawMismatches({
1164
- ctx,
1165
- feat,
1166
- renderArgs,
1167
- mismatchAlpha,
1168
- drawSNPsMuted,
1169
- drawIndels,
1170
- largeInsertionIndicatorScale,
1171
- minSubfeatureWidth,
1172
- charWidth,
1173
- charHeight,
1174
- colorForBase,
1175
- contrastForBase,
1176
- canvasWidth,
1177
- theme,
1178
- })
1179
- if (showSoftClip) {
1180
- this.drawSoftClipping({
1181
- ctx,
1182
- feat,
1183
- renderArgs,
1184
- config,
1185
- theme,
1186
- canvasWidth,
1187
- })
1188
- }
1189
- }
1190
- }
1191
-
1192
- // we perform a full layout before render as a separate method because the
1193
- // layout determines the height of the canvas that we use to render
1194
- layoutFeats(props: RenderArgsDeserializedWithFeaturesAndLayout) {
1195
- const {
1196
- layout,
1197
- features,
1198
- sortedBy,
1199
- config,
1200
- bpPerPx,
1201
- showSoftClip,
1202
- regions,
1203
- } = props
1204
- const [region] = regions
1205
- if (!layout) {
1206
- throw new Error(`layout required`)
1207
- }
1208
- if (!layout.addRect) {
1209
- throw new Error('invalid layout object')
1210
- }
1211
-
1212
- const featureMap =
1213
- sortedBy?.type && region.start === sortedBy.pos
1214
- ? sortFeature(features, sortedBy)
1215
- : features
1216
-
1217
- const heightPx = readConfObject(config, 'height')
1218
- const displayMode = readConfObject(config, 'displayMode')
1219
- return iterMap(
1220
- featureMap.values(),
1221
- feature =>
1222
- this.layoutFeature({
1223
- feature,
1224
- layout,
1225
- bpPerPx,
1226
- region,
1227
- showSoftClip,
1228
- heightPx,
1229
- displayMode,
1230
- }),
1231
- featureMap.size,
1232
- )
1233
- }
1234
-
1235
- async fetchSequence(renderProps: RenderArgsDeserialized) {
1236
- const { sessionId, regions, adapterConfig } = renderProps
1237
- const { sequenceAdapter } = adapterConfig
1238
- if (!sequenceAdapter) {
1239
- return undefined
1240
- }
1241
- const { dataAdapter } = await getAdapter(
1242
- this.pluginManager,
1243
- sessionId,
1244
- sequenceAdapter,
1245
- )
1246
- const [region] = regions
1247
- return fetchSequence(region, dataAdapter as BaseFeatureDataAdapter)
1248
- }
1249
-
1250
75
  async render(renderProps: RenderArgsDeserialized) {
1251
76
  const features = await this.getFeatures(renderProps)
1252
77
  const layout = this.createLayoutInWorker(renderProps)
1253
78
  const { regions, bpPerPx } = renderProps
1254
79
  const [region] = regions
1255
80
 
1256
- const layoutRecords = this.layoutFeats({
81
+ const layoutRecords = layoutFeats({
1257
82
  ...renderProps,
1258
83
  features,
1259
84
  layout,
@@ -1265,15 +90,13 @@ export default class PileupRenderer extends BoxRendererType {
1265
90
  features.size && shouldFetchReferenceSequence(renderProps.colorBy?.type)
1266
91
  ? await this.fetchSequence(renderProps)
1267
92
  : undefined
1268
- const { end, start } = region
1269
-
1270
- const width = (end - start) / bpPerPx
93
+ const width = (region.end - region.start) / bpPerPx
1271
94
  const height = Math.max(layout.getTotalHeight(), 1)
1272
95
  const Color = await import('color').then(f => f.default)
1273
96
  const res = await renderToAbstractCanvas(width, height, renderProps, ctx =>
1274
- this.makeImageData({
97
+ makeImageData({
1275
98
  ctx,
1276
- layoutRecords,
99
+ layoutRecords: layoutRecords.filter(notEmpty),
1277
100
  canvasWidth: width,
1278
101
  renderArgs: {
1279
102
  ...renderProps,