react-msaview 3.1.12 → 3.2.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 (186) hide show
  1. package/bundle/index.js +32 -31
  2. package/dist/colorSchemes.d.ts +2 -2
  3. package/dist/colorSchemes.js +3 -4
  4. package/dist/colorSchemes.js.map +1 -1
  5. package/dist/components/Loading.d.ts +1 -1
  6. package/dist/components/Loading.js +4 -4
  7. package/dist/components/Loading.js.map +1 -1
  8. package/dist/components/MSAView.d.ts +1 -1
  9. package/dist/components/MSAView.js +13 -9
  10. package/dist/components/MSAView.js.map +1 -1
  11. package/dist/components/ResizeHandles.d.ts +1 -1
  12. package/dist/components/ResizeHandles.js +2 -2
  13. package/dist/components/TextTrack.d.ts +1 -1
  14. package/dist/components/Track.d.ts +1 -1
  15. package/dist/components/VerticalScrollbar.d.ts +6 -0
  16. package/dist/components/VerticalScrollbar.js +65 -0
  17. package/dist/components/VerticalScrollbar.js.map +1 -0
  18. package/dist/components/dialogs/AddTrackDialog.d.ts +1 -1
  19. package/dist/components/dialogs/DomainDialog.d.ts +1 -1
  20. package/dist/components/dialogs/DomainDialog.js +2 -2
  21. package/dist/components/dialogs/DomainDialog.js.map +1 -1
  22. package/dist/components/dialogs/ExportSVGDialog.d.ts +1 -1
  23. package/dist/components/dialogs/FeatureDialog.d.ts +1 -1
  24. package/dist/components/dialogs/FeatureDialog.js.map +1 -1
  25. package/dist/components/dialogs/{InterProScanPanel.d.ts → InterProScanDialog.d.ts} +1 -1
  26. package/dist/components/dialogs/{InterProScanPanel.js → InterProScanDialog.js} +4 -3
  27. package/dist/components/dialogs/InterProScanDialog.js.map +1 -0
  28. package/dist/components/dialogs/MetadataDialog.d.ts +1 -1
  29. package/dist/components/dialogs/SettingsDialog.d.ts +1 -1
  30. package/dist/components/dialogs/SettingsDialog.js +10 -1
  31. package/dist/components/dialogs/SettingsDialog.js.map +1 -1
  32. package/dist/components/dialogs/TracklistDialog.d.ts +1 -1
  33. package/dist/components/dialogs/UserProvidedDomainsDialog.d.ts +7 -0
  34. package/dist/components/dialogs/UserProvidedDomainsDialog.js +58 -0
  35. package/dist/components/dialogs/UserProvidedDomainsDialog.js.map +1 -0
  36. package/dist/components/header/Header.d.ts +1 -1
  37. package/dist/components/header/Header.js +8 -3
  38. package/dist/components/header/Header.js.map +1 -1
  39. package/dist/components/header/HeaderInfoArea.d.ts +1 -1
  40. package/dist/components/header/HeaderMenu.d.ts +1 -1
  41. package/dist/components/header/HeaderMenuExtra.d.ts +1 -1
  42. package/dist/components/header/HeaderMenuExtra.js +30 -28
  43. package/dist/components/header/HeaderMenuExtra.js.map +1 -1
  44. package/dist/components/header/HeaderStatusArea.d.ts +2 -2
  45. package/dist/components/header/HeaderStatusArea.js +1 -1
  46. package/dist/components/header/HeaderStatusArea.js.map +1 -1
  47. package/dist/components/header/MultiAlignmentSelector.d.ts +1 -1
  48. package/dist/components/header/ZoomControls.js +31 -1
  49. package/dist/components/header/ZoomControls.js.map +1 -1
  50. package/dist/components/import/ImportForm.d.ts +1 -1
  51. package/dist/components/import/ImportForm.js +1 -1
  52. package/dist/components/import/ImportForm.js.map +1 -1
  53. package/dist/components/import/ImportFormExamples.d.ts +1 -1
  54. package/dist/components/import/ImportFormExamples.js +10 -8
  55. package/dist/components/import/ImportFormExamples.js.map +1 -1
  56. package/dist/components/import/util.d.ts +2 -2
  57. package/dist/components/minimap/Minimap.d.ts +1 -1
  58. package/dist/components/minimap/Minimap.js +14 -15
  59. package/dist/components/minimap/Minimap.js.map +1 -1
  60. package/dist/components/minimap/MinimapSVG.d.ts +1 -1
  61. package/dist/components/minimap/MinimapSVG.js +1 -1
  62. package/dist/components/minimap/MinimapSVG.js.map +1 -1
  63. package/dist/components/msa/MSACanvas.d.ts +1 -1
  64. package/dist/components/msa/MSACanvas.js +3 -3
  65. package/dist/components/msa/MSACanvas.js.map +1 -1
  66. package/dist/components/msa/MSACanvasBlock.d.ts +3 -3
  67. package/dist/components/msa/MSACanvasBlock.js +4 -3
  68. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  69. package/dist/components/msa/MSAMouseoverCanvas.d.ts +2 -2
  70. package/dist/components/msa/MSAMouseoverCanvas.js +1 -1
  71. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  72. package/dist/components/msa/MSAPanel.d.ts +1 -1
  73. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +1 -1
  74. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +1 -2
  75. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  76. package/dist/components/msa/renderMSABlock.d.ts +2 -2
  77. package/dist/components/msa/renderMSABlock.js +12 -12
  78. package/dist/components/msa/renderMSABlock.js.map +1 -1
  79. package/dist/components/msa/renderMSAMouseover.d.ts +1 -1
  80. package/dist/components/tree/TreeBranchMenu.d.ts +1 -1
  81. package/dist/components/tree/TreeCanvas.d.ts +1 -1
  82. package/dist/components/tree/TreeCanvas.js +13 -12
  83. package/dist/components/tree/TreeCanvas.js.map +1 -1
  84. package/dist/components/tree/TreeCanvasBlock.d.ts +1 -1
  85. package/dist/components/tree/TreeCanvasBlock.js +2 -1
  86. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  87. package/dist/components/tree/TreeNodeMenu.d.ts +1 -1
  88. package/dist/components/tree/TreeNodeMenu.js +2 -2
  89. package/dist/components/tree/TreeNodeMenu.js.map +1 -1
  90. package/dist/components/tree/TreePanel.d.ts +1 -1
  91. package/dist/components/tree/TreeRuler.d.ts +1 -1
  92. package/dist/components/tree/dialogs/TreeNodeInfoDialog.d.ts +1 -1
  93. package/dist/components/tree/renderTreeCanvas.d.ts +3 -3
  94. package/dist/components/tree/renderTreeCanvas.js +25 -9
  95. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  96. package/dist/components/util.js +1 -1
  97. package/dist/components/util.js.map +1 -1
  98. package/dist/launchInterProScan.d.ts +1 -1
  99. package/dist/launchInterProScan.js +7 -9
  100. package/dist/launchInterProScan.js.map +1 -1
  101. package/dist/model/DataModel.d.ts +5 -1
  102. package/dist/model/DataModel.js +10 -1
  103. package/dist/model/DataModel.js.map +1 -1
  104. package/dist/model/DialogQueue.d.ts +1 -1
  105. package/dist/model.d.ts +141 -24
  106. package/dist/model.js +236 -50
  107. package/dist/model.js.map +1 -1
  108. package/dist/parseNewick.js +1 -1
  109. package/dist/parseNewick.js.map +1 -1
  110. package/dist/parsers/ClustalMSA.d.ts +1 -1
  111. package/dist/parsers/FastaMSA.d.ts +1 -1
  112. package/dist/parsers/StockholmMSA.d.ts +1 -1
  113. package/dist/parsers/StockholmMSA.js.map +1 -1
  114. package/dist/renderToSvg.d.ts +2 -2
  115. package/dist/renderToSvg.js +3 -5
  116. package/dist/renderToSvg.js.map +1 -1
  117. package/dist/reparseTree.d.ts +1 -1
  118. package/dist/util.d.ts +2 -2
  119. package/dist/util.js +0 -2
  120. package/dist/util.js.map +1 -1
  121. package/dist/version.d.ts +1 -1
  122. package/dist/version.js +1 -1
  123. package/dist/version.js.map +1 -1
  124. package/package.json +5 -2
  125. package/src/colorSchemes.ts +3 -2
  126. package/src/components/Checkbox2.tsx +1 -1
  127. package/src/components/Loading.tsx +11 -5
  128. package/src/components/MSAView.tsx +27 -18
  129. package/src/components/ResizeHandles.tsx +3 -3
  130. package/src/components/TextTrack.tsx +1 -1
  131. package/src/components/Track.tsx +1 -1
  132. package/src/components/VerticalScrollbar.tsx +85 -0
  133. package/src/components/dialogs/AddTrackDialog.tsx +2 -2
  134. package/src/components/dialogs/DomainDialog.tsx +3 -3
  135. package/src/components/dialogs/ExportSVGDialog.tsx +1 -1
  136. package/src/components/dialogs/FeatureDialog.tsx +3 -3
  137. package/src/components/dialogs/{InterProScanPanel.tsx → InterProScanDialog.tsx} +11 -4
  138. package/src/components/dialogs/MetadataDialog.tsx +1 -1
  139. package/src/components/dialogs/SettingsDialog.tsx +38 -3
  140. package/src/components/dialogs/TracklistDialog.tsx +1 -1
  141. package/src/components/dialogs/UserProvidedDomainsDialog.tsx +133 -0
  142. package/src/components/header/Header.tsx +9 -4
  143. package/src/components/header/HeaderInfoArea.tsx +1 -1
  144. package/src/components/header/HeaderMenu.tsx +1 -1
  145. package/src/components/header/HeaderMenuExtra.tsx +36 -32
  146. package/src/components/header/HeaderStatusArea.tsx +2 -6
  147. package/src/components/header/MultiAlignmentSelector.tsx +1 -1
  148. package/src/components/header/ZoomControls.tsx +34 -0
  149. package/src/components/import/ImportForm.tsx +3 -3
  150. package/src/components/import/ImportFormExamples.tsx +19 -17
  151. package/src/components/import/util.ts +2 -2
  152. package/src/components/minimap/Minimap.tsx +15 -22
  153. package/src/components/minimap/MinimapSVG.tsx +2 -2
  154. package/src/components/msa/MSACanvas.tsx +11 -4
  155. package/src/components/msa/MSACanvasBlock.tsx +5 -4
  156. package/src/components/msa/MSAMouseoverCanvas.tsx +2 -6
  157. package/src/components/msa/MSAPanel.tsx +1 -1
  158. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +4 -5
  159. package/src/components/msa/renderMSABlock.ts +37 -17
  160. package/src/components/msa/renderMSAMouseover.ts +1 -1
  161. package/src/components/tree/TreeBranchMenu.tsx +1 -1
  162. package/src/components/tree/TreeCanvas.tsx +15 -16
  163. package/src/components/tree/TreeCanvasBlock.tsx +3 -2
  164. package/src/components/tree/TreeNodeMenu.tsx +3 -3
  165. package/src/components/tree/TreePanel.tsx +1 -1
  166. package/src/components/tree/TreeRuler.tsx +1 -1
  167. package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +1 -1
  168. package/src/components/tree/renderTreeCanvas.ts +32 -12
  169. package/src/components/util.ts +1 -1
  170. package/src/launchInterProScan.ts +8 -10
  171. package/src/model/DataModel.ts +10 -0
  172. package/src/model/DialogQueue.ts +1 -1
  173. package/src/model.ts +262 -62
  174. package/src/parseNewick.ts +1 -1
  175. package/src/parsers/ClustalMSA.ts +1 -1
  176. package/src/parsers/FastaMSA.ts +1 -1
  177. package/src/parsers/StockholmMSA.ts +1 -1
  178. package/src/renderToSvg.tsx +6 -6
  179. package/src/reparseTree.ts +1 -1
  180. package/src/util.ts +2 -4
  181. package/src/version.ts +1 -1
  182. package/dist/components/dialogs/InterProScanPanel.js.map +0 -1
  183. package/dist/components/dialogs/UserProvidedResultPanel.d.ts +0 -7
  184. package/dist/components/dialogs/UserProvidedResultPanel.js +0 -56
  185. package/dist/components/dialogs/UserProvidedResultPanel.js.map +0 -1
  186. package/src/components/dialogs/UserProvidedResultPanel.tsx +0 -119
@@ -2,12 +2,19 @@ import React, { useEffect, useState, useRef } from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
 
4
4
  // locals
5
- import { MsaViewModel } from '../../model'
5
+ import type { MsaViewModel } from '../../model'
6
6
  import MSACanvasBlock from './MSACanvasBlock'
7
7
  import Loading from './Loading'
8
8
 
9
9
  const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
10
- const { MSA, msaFilehandle, height, msaAreaWidth, blocks2d } = model
10
+ const {
11
+ MSA,
12
+ verticalScrollbarWidth,
13
+ msaFilehandle,
14
+ height,
15
+ msaAreaWidth,
16
+ blocks2d,
17
+ } = model
11
18
  const ref = useRef<HTMLDivElement>(null)
12
19
  // wheel
13
20
  const scheduled = useRef(false)
@@ -39,7 +46,7 @@ const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
39
46
  event.preventDefault()
40
47
  event.stopPropagation()
41
48
  }
42
- curr.addEventListener('wheel', onWheel)
49
+ curr.addEventListener('wheel', onWheel, { passive: false })
43
50
  return () => {
44
51
  curr.removeEventListener('wheel', onWheel)
45
52
  }
@@ -115,7 +122,7 @@ const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
115
122
  style={{
116
123
  position: 'relative',
117
124
  height,
118
- width: msaAreaWidth,
125
+ width: msaAreaWidth - verticalScrollbarWidth,
119
126
  overflow: 'hidden',
120
127
  }}
121
128
  >
@@ -5,11 +5,11 @@ import { observer } from 'mobx-react'
5
5
 
6
6
  // locals
7
7
  import { renderMSABlock } from './renderMSABlock'
8
- import { MsaViewModel } from '../../model'
8
+ import type { MsaViewModel } from '../../model'
9
9
  import { colorContrast } from '../../util'
10
10
  import { renderBoxFeatureCanvasBlock } from './renderBoxFeatureCanvasBlock'
11
11
 
12
- const MSABlock = observer(function ({
12
+ const MSACanvasBlock = observer(function ({
13
13
  model,
14
14
  offsetX,
15
15
  offsetY,
@@ -45,7 +45,8 @@ const MSABlock = observer(function ({
45
45
  return autorun(() => {
46
46
  ctx.resetTransform()
47
47
  ctx.clearRect(0, 0, blockSize, blockSize)
48
- if (model.showDomains) {
48
+ const { actuallyShowDomains } = model
49
+ if (actuallyShowDomains) {
49
50
  renderBoxFeatureCanvasBlock({
50
51
  ctx,
51
52
  offsetX,
@@ -107,4 +108,4 @@ const MSABlock = observer(function ({
107
108
  )
108
109
  })
109
110
 
110
- export default MSABlock
111
+ export default MSACanvasBlock
@@ -3,14 +3,10 @@ import { observer } from 'mobx-react'
3
3
  import { autorun } from 'mobx'
4
4
 
5
5
  // locals
6
- import { MsaViewModel } from '../../model'
6
+ import type { MsaViewModel } from '../../model'
7
7
  import { renderMouseover } from './renderMSAMouseover'
8
8
 
9
- const MSAMouseoverCanvas = observer(function ({
10
- model,
11
- }: {
12
- model: MsaViewModel
13
- }) {
9
+ const MSAMouseoverCanvas = observer(({ model }: { model: MsaViewModel }) => {
14
10
  const ref = useRef<HTMLCanvasElement>(null)
15
11
  const { height, width } = model
16
12
  useEffect(() => {
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react'
5
5
  import MSACanvas from './MSACanvas'
6
6
  import MSAMouseoverCanvas from './MSAMouseoverCanvas'
7
7
  // types
8
- import { MsaViewModel } from '../../model'
8
+ import type { MsaViewModel } from '../../model'
9
9
 
10
10
  const MSAPanel = observer(function ({ model }: { model: MsaViewModel }) {
11
11
  return (
@@ -1,8 +1,8 @@
1
- import { HierarchyNode } from 'd3-hierarchy'
1
+ import type { HierarchyNode } from 'd3-hierarchy'
2
2
 
3
3
  // locals
4
- import { MsaViewModel } from '../../model'
5
- import { NodeWithIdsAndLength } from '../../util'
4
+ import type { MsaViewModel } from '../../model'
5
+ import type { NodeWithIdsAndLength } from '../../util'
6
6
 
7
7
  export function renderBoxFeatureCanvasBlock({
8
8
  model,
@@ -19,7 +19,7 @@ export function renderBoxFeatureCanvasBlock({
19
19
  highResScaleFactorOverride?: number
20
20
  blockSizeYOverride?: number
21
21
  }) {
22
- const { hierarchy, blockSize, rowHeight, highResScaleFactor, showDomains } =
22
+ const { leaves, blockSize, rowHeight, highResScaleFactor, showDomains } =
23
23
  model
24
24
  if (showDomains) {
25
25
  const k = highResScaleFactorOverride || highResScaleFactor
@@ -28,7 +28,6 @@ export function renderBoxFeatureCanvasBlock({
28
28
  ctx.scale(k, k)
29
29
  ctx.translate(-offsetX, rowHeight / 2 - offsetY)
30
30
 
31
- const leaves = hierarchy.leaves()
32
31
  const yStart = Math.max(0, Math.floor((offsetY - rowHeight) / rowHeight))
33
32
  const yEnd = Math.max(0, Math.ceil((offsetY + by + rowHeight) / rowHeight))
34
33
  const visibleLeaves = leaves.slice(yStart, yEnd)
@@ -1,10 +1,10 @@
1
- import { HierarchyNode } from 'd3-hierarchy'
2
- import { Theme } from '@mui/material'
1
+ import type { HierarchyNode } from 'd3-hierarchy'
2
+ import type { Theme } from '@mui/material'
3
3
 
4
4
  // locals
5
- import { MsaViewModel } from '../../model'
5
+ import type { MsaViewModel } from '../../model'
6
6
  import { getClustalXColor, getPercentIdentityColor } from '../../colorSchemes'
7
- import { NodeWithIdsAndLength } from '../../util'
7
+ import type { NodeWithIdsAndLength } from '../../util'
8
8
 
9
9
  export function renderMSABlock({
10
10
  model,
@@ -28,13 +28,13 @@ export function renderMSABlock({
28
28
  blockSizeYOverride?: number
29
29
  }) {
30
30
  const {
31
- hierarchy,
32
31
  colWidth,
33
32
  blockSize,
34
33
  rowHeight,
35
34
  fontSize,
36
35
  highResScaleFactor,
37
- showDomains,
36
+ actuallyShowDomains,
37
+ leaves,
38
38
  } = model
39
39
  const k = highResScaleFactorOverride || highResScaleFactor
40
40
  const bx = blockSizeXOverride || blockSize
@@ -45,15 +45,13 @@ export function renderMSABlock({
45
45
  ctx.textAlign = 'center'
46
46
  ctx.font = ctx.font.replace(/\d+px/, `${fontSize}px`)
47
47
 
48
- const leaves = hierarchy.leaves()
49
-
50
48
  const yStart = Math.max(0, Math.floor((offsetY - rowHeight) / rowHeight))
51
49
  const yEnd = Math.max(0, Math.ceil((offsetY + by + rowHeight) / rowHeight))
52
50
  const xStart = Math.max(0, Math.floor(offsetX / colWidth))
53
51
  const xEnd = Math.max(0, Math.ceil((offsetX + bx) / colWidth))
54
52
  const visibleLeaves = leaves.slice(yStart, yEnd)
55
53
 
56
- if (!showDomains) {
54
+ if (!actuallyShowDomains) {
57
55
  drawTiles({
58
56
  model,
59
57
  ctx,
@@ -101,6 +99,7 @@ function drawTiles({
101
99
  colorSchemeName,
102
100
  colorScheme,
103
101
  colStats,
102
+ colStatsSums,
104
103
  columns,
105
104
  colWidth,
106
105
  rowHeight,
@@ -116,19 +115,30 @@ function drawTiles({
116
115
  const letter = str[i]
117
116
  const color =
118
117
  colorSchemeName === 'clustalx_protein_dynamic'
119
- ? getClustalXColor(colStats[xStart + i], model, name, xStart + i)
118
+ ? getClustalXColor(
119
+ colStats[xStart + i],
120
+ colStatsSums[xStart + i],
121
+ model,
122
+ name,
123
+ xStart + i,
124
+ )
120
125
  : colorSchemeName === 'percent_identity_dynamic'
121
126
  ? getPercentIdentityColor(
122
127
  colStats[xStart + i],
128
+ colStatsSums[xStart + i],
123
129
  model,
124
130
  name,
125
131
  xStart + i,
126
132
  )
127
133
  : colorScheme[letter.toUpperCase()]
128
134
  if (bgColor) {
129
- const x = i * colWidth + offsetX - (offsetX % colWidth)
130
135
  ctx.fillStyle = color || theme.palette.background.default
131
- ctx.fillRect(x, y - rowHeight, colWidth, rowHeight)
136
+ ctx.fillRect(
137
+ i * colWidth + offsetX - (offsetX % colWidth),
138
+ y - rowHeight,
139
+ colWidth,
140
+ rowHeight,
141
+ )
132
142
  }
133
143
  }
134
144
  }
@@ -152,9 +162,17 @@ function drawText({
152
162
  xStart: number
153
163
  xEnd: number
154
164
  }) {
155
- const { bgColor, showDomains, colorScheme, columns, colWidth, rowHeight } =
156
- model
157
- if (rowHeight >= 5 && colWidth > rowHeight / 2) {
165
+ const {
166
+ bgColor,
167
+ actuallyShowDomains,
168
+ showMsaLetters,
169
+ colorScheme,
170
+ columns,
171
+ colWidth,
172
+ contrastLettering,
173
+ rowHeight,
174
+ } = model
175
+ if (showMsaLetters) {
158
176
  for (const node of visibleLeaves) {
159
177
  const {
160
178
  data: { name },
@@ -164,11 +182,13 @@ function drawText({
164
182
  for (let i = 0; i < str?.length; i++) {
165
183
  const letter = str[i]
166
184
  const color = colorScheme[letter.toUpperCase()]
167
- const contrast = contrastScheme[letter.toUpperCase()] || 'black'
185
+ const contrast = contrastLettering
186
+ ? contrastScheme[letter.toUpperCase()] || 'black'
187
+ : 'black'
168
188
  const x = i * colWidth + offsetX - (offsetX % colWidth)
169
189
 
170
190
  // note: -rowHeight/4 matches +rowHeight/4 in tree
171
- ctx.fillStyle = showDomains
191
+ ctx.fillStyle = actuallyShowDomains
172
192
  ? 'black'
173
193
  : bgColor
174
194
  ? contrast
@@ -1,4 +1,4 @@
1
- import { MsaViewModel } from '../../model'
1
+ import type { MsaViewModel } from '../../model'
2
2
 
3
3
  const hoverColor = 'rgba(0,0,0,0.15)'
4
4
  const highlightColor = 'rgba(128,128,0,0.2)'
@@ -3,7 +3,7 @@ import { Menu, MenuItem } from '@mui/material'
3
3
  import { observer } from 'mobx-react'
4
4
 
5
5
  // locals
6
- import { MsaViewModel } from '../../model'
6
+ import type { MsaViewModel } from '../../model'
7
7
 
8
8
  interface Node {
9
9
  x: number
@@ -1,8 +1,9 @@
1
- import React, { useEffect, useRef, useState } from 'react'
1
+ import React from 'react'
2
+ import { useEffect, useRef, useState } from 'react'
2
3
  import { observer } from 'mobx-react'
3
4
 
4
5
  // locals
5
- import { MsaViewModel } from '../../model'
6
+ import type { MsaViewModel } from '../../model'
6
7
  import TreeCanvasBlock from './TreeCanvasBlock'
7
8
  import { padding } from './renderTreeCanvas'
8
9
 
@@ -48,7 +49,8 @@ const TreeCanvas = observer(function ({ model }: { model: MsaViewModel }) {
48
49
  const distanceY = currY - prevY.current
49
50
  if (distanceY) {
50
51
  // use rAF to make it so multiple event handlers aren't fired per-frame
51
- // see https://calendar.perfplanet.com/2013/the-runtime-performance-checklist/
52
+ // see
53
+ // https://calendar.perfplanet.com/2013/the-runtime-performance-checklist/
52
54
  if (!scheduled.current) {
53
55
  scheduled.current = true
54
56
  window.requestAnimationFrame(() => {
@@ -92,23 +94,20 @@ const TreeCanvas = observer(function ({ model }: { model: MsaViewModel }) {
92
94
  }
93
95
  }
94
96
 
95
- // this local mouseup is used in addition to the global because sometimes
96
- // the global add/remove are not called in time, resulting in issue #533
97
- function mouseUp(event: React.MouseEvent) {
98
- event.preventDefault()
99
- setMouseDragging(false)
100
- }
101
-
102
- function mouseLeave(event: React.MouseEvent) {
103
- event.preventDefault()
104
- }
105
-
106
97
  return (
107
98
  <div
108
99
  ref={ref}
109
100
  onMouseDown={mouseDown}
110
- onMouseUp={mouseUp}
111
- onMouseLeave={mouseLeave}
101
+ onMouseUp={event => {
102
+ // this local mouseup is used in addition to the global because
103
+ // sometimes the global add/remove are not called in time, resulting in
104
+ // issue #533
105
+ event.preventDefault()
106
+ setMouseDragging(false)
107
+ }}
108
+ onMouseLeave={event => {
109
+ event.preventDefault()
110
+ }}
112
111
  style={{
113
112
  height,
114
113
  position: 'relative',
@@ -1,11 +1,12 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react'
1
+ import React from 'react'
2
+ import { useCallback, useEffect, useRef, useState } from 'react'
2
3
  import { autorun } from 'mobx'
3
4
  import { observer } from 'mobx-react'
4
5
  import { useTheme } from '@mui/material'
5
6
  import RBush from 'rbush'
6
7
 
7
8
  // locals
8
- import { MsaViewModel } from '../../model'
9
+ import type { MsaViewModel } from '../../model'
9
10
  import TreeNodeMenu from './TreeNodeMenu'
10
11
  import TreeBranchMenu from './TreeBranchMenu'
11
12
  import { padding, renderTreeCanvas } from './renderTreeCanvas'
@@ -3,7 +3,7 @@ import { Menu, MenuItem } from '@mui/material'
3
3
  import { observer } from 'mobx-react'
4
4
 
5
5
  // locals
6
- import { MsaViewModel } from '../../model'
6
+ import type { MsaViewModel } from '../../model'
7
7
 
8
8
  // lazies
9
9
  const TreeNodeInfoDialog = lazy(() => import('./dialogs/TreeNodeInfoDialog'))
@@ -17,7 +17,7 @@ const TreeMenu = observer(function ({
17
17
  model: MsaViewModel
18
18
  onClose: () => void
19
19
  }) {
20
- const { collapsed, collapsed2 } = model
20
+ const { collapsed, collapsedLeaves } = model
21
21
  return (
22
22
  <Menu
23
23
  anchorReference="anchorPosition"
@@ -66,7 +66,7 @@ const TreeMenu = observer(function ({
66
66
  onClose()
67
67
  }}
68
68
  >
69
- {collapsed.includes(node.id) || collapsed2.includes(node.id)
69
+ {collapsed.includes(node.id) || collapsedLeaves.includes(node.id)
70
70
  ? 'Show node'
71
71
  : 'Hide node'}
72
72
  </MenuItem>
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
 
4
- import { MsaViewModel } from '../../model'
4
+ import type { MsaViewModel } from '../../model'
5
5
  import TreeCanvas from './TreeCanvas'
6
6
 
7
7
  const TreePanel = observer(function ({ model }: { model: MsaViewModel }) {
@@ -2,7 +2,7 @@ import React from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
 
4
4
  // locals
5
- import { MsaViewModel } from '../../model'
5
+ import type { MsaViewModel } from '../../model'
6
6
 
7
7
  const TreeRuler = observer(({ model }: { model: MsaViewModel }) => {
8
8
  const { treeAreaWidth } = model
@@ -8,7 +8,7 @@ import {
8
8
  } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
9
9
 
10
10
  // locals
11
- import { MsaViewModel } from '../../../model'
11
+ import type { MsaViewModel } from '../../../model'
12
12
  import SequenceTextArea from '../../SequenceTextArea'
13
13
 
14
14
  export default observer(function ({
@@ -1,8 +1,8 @@
1
- import RBush from 'rbush'
2
- import { Theme } from '@mui/material'
1
+ import type RBush from 'rbush'
2
+ import type { Theme } from '@mui/material'
3
3
 
4
4
  // locals
5
- import { MsaViewModel } from '../../model'
5
+ import type { MsaViewModel } from '../../model'
6
6
 
7
7
  export const padding = 600
8
8
 
@@ -38,6 +38,9 @@ export function renderTree({
38
38
  ctx.strokeStyle = theme.palette.text.primary
39
39
  for (const link of hierarchy.links()) {
40
40
  const { source, target } = link
41
+ if (target.height === 0 && !showBranchLen) {
42
+ continue
43
+ }
41
44
  const sy = source.x!
42
45
  const ty = target.x!
43
46
  // @ts-expect-error
@@ -87,10 +90,9 @@ export function renderNodeBubbles({
87
90
  // @ts-expect-error
88
91
  const { [val]: x, data } = node
89
92
  const y = node.x!
90
- const { branchset, id = '', name = '' } = data
93
+ const { id = '', name = '' } = data
91
94
  if (
92
- !id.endsWith('-leafnode') &&
93
- branchset.length &&
95
+ node.height > 1 &&
94
96
  y > offsetY - extendBounds &&
95
97
  y < offsetY + by + extendBounds
96
98
  ) {
@@ -134,13 +136,19 @@ export function renderTreeLabels({
134
136
  showBranchLen,
135
137
  treeMetadata,
136
138
  hierarchy,
139
+ collapsed,
140
+ collapsedLeaves,
137
141
  blockSize,
138
142
  labelsAlignRight,
139
143
  drawTree,
140
144
  treeAreaWidth,
145
+ treeWidth,
141
146
  treeAreaWidthMinusMargin,
142
147
  marginLeft,
148
+ leaves,
143
149
  noTree,
150
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
151
+ rowHeight: _rowHeight, // this is needed for redrawing after zoom change
144
152
  } = model
145
153
  const by = blockSizeYOverride || blockSize
146
154
  if (labelsAlignRight) {
@@ -149,7 +157,7 @@ export function renderTreeLabels({
149
157
  } else {
150
158
  ctx.textAlign = 'start'
151
159
  }
152
- for (const node of hierarchy.leaves()) {
160
+ for (const node of leaves) {
153
161
  const {
154
162
  data: { name, id },
155
163
  // @ts-expect-error
@@ -162,7 +170,18 @@ export function renderTreeLabels({
162
170
  if (y > offsetY - extendBounds && y < offsetY + by + extendBounds) {
163
171
  // note: +rowHeight/4 matches with -rowHeight/4 in msa
164
172
  const yp = y + fontSize / 4
165
- const xp = (showBranchLen ? len : x) || 0
173
+ let xp = (showBranchLen ? len : x) || 0
174
+ if (
175
+ !showBranchLen &&
176
+ !collapsed.includes(id) &&
177
+ !collapsedLeaves.includes(id)
178
+ ) {
179
+ // this subtraction is a hack to compensate for the leafnode rendering
180
+ // glitch (issue #71). the context is that an extra leaf node is added
181
+ // so that 'collapsing/hiding leaf nodes is possible' but this causes
182
+ // weird workarounds
183
+ xp -= treeWidth / hierarchy.height
184
+ }
166
185
 
167
186
  const { width } = ctx.measureText(displayName)
168
187
  const height = ctx.measureText('M').width // use an 'em' for height
@@ -223,13 +242,12 @@ export function renderTreeCanvas({
223
242
  const {
224
243
  noTree,
225
244
  drawTree,
226
- drawLabels,
227
245
  drawNodeBubbles,
228
246
  treeWidth,
229
247
  highResScaleFactor,
230
248
  blockSize,
231
249
  fontSize,
232
- rowHeight,
250
+ showTreeText,
233
251
  marginLeft,
234
252
  nref,
235
253
  } = model
@@ -243,7 +261,9 @@ export function renderTreeCanvas({
243
261
  // is updated and in order to convince bundlers like not to delete unused
244
262
  // usage with propertyReadSideEffects
245
263
  const k =
246
- nref < 0 ? -Infinity : highResScaleFactorOverride || highResScaleFactor
264
+ nref < 0
265
+ ? Number.NEGATIVE_INFINITY
266
+ : highResScaleFactorOverride || highResScaleFactor
247
267
  ctx.scale(k, k)
248
268
  ctx.clearRect(0, 0, treeWidth + padding, by)
249
269
  ctx.translate(marginLeft, -offsetY)
@@ -272,7 +292,7 @@ export function renderTreeCanvas({
272
292
  }
273
293
  }
274
294
 
275
- if (rowHeight >= 5 && drawLabels) {
295
+ if (showTreeText) {
276
296
  renderTreeLabels({
277
297
  ctx,
278
298
  offsetY,
@@ -10,7 +10,7 @@ export function chooseGridPitch(
10
10
  ) {
11
11
  scale = Math.abs(scale)
12
12
  const minMajorPitchBp = minMajorPitchPx * scale
13
- const majorMagnitude = parseInt(
13
+ const majorMagnitude = Number.parseInt(
14
14
  Number(minMajorPitchBp).toExponential().split(/e/i)[1],
15
15
  10,
16
16
  )
@@ -1,8 +1,8 @@
1
1
  import { getSession } from '@jbrowse/core/util'
2
2
  import { jsonfetch, textfetch, timeout } from './fetchUtils'
3
- import { MsaViewModel } from './model'
3
+ import type { MsaViewModel } from './model'
4
4
 
5
- const base = `https://www.ebi.ac.uk/Tools/services/rest`
5
+ const base = 'https://www.ebi.ac.uk/Tools/services/rest'
6
6
 
7
7
  export interface InterProScanResults {
8
8
  matches: {
@@ -65,7 +65,6 @@ async function wait({
65
65
  }) {
66
66
  const url = `${base}/iprscan5/status/${jobId}`
67
67
  try {
68
- // eslint-disable-next-line no-constant-condition
69
68
  while (true) {
70
69
  for (let i = 0; i < 10; i++) {
71
70
  await timeout(1000)
@@ -75,6 +74,9 @@ async function wait({
75
74
  if (result.includes('FINISHED')) {
76
75
  break
77
76
  }
77
+ if (result.includes('FAILURE')) {
78
+ throw new Error(`Failed to run: jobId ${jobId}`)
79
+ }
78
80
  }
79
81
  } finally {
80
82
  onProgress()
@@ -107,9 +109,8 @@ export async function launchInterProScan({
107
109
  model,
108
110
  })
109
111
  return result
110
- } else {
111
- throw new Error('unknown algorithm')
112
112
  }
113
+ throw new Error('unknown algorithm')
113
114
  } finally {
114
115
  onProgress()
115
116
  }
@@ -124,14 +125,11 @@ export async function loadInterProScanResultsWithStatus({
124
125
  }) {
125
126
  try {
126
127
  model.setStatus({
127
- msg:
128
- 'Downloading results of ' +
129
- jobId +
130
- ' (for larger sequences this can be slow, click status to download and upload in the manual tab)',
128
+ msg: `Downloading results of ${jobId} (for larger sequences this can be slow, click status to download and upload in the manual tab)`,
131
129
  url: `https://www.ebi.ac.uk/Tools/services/rest/iprscan5/result/${jobId}/json`,
132
130
  })
133
131
  const ret = await loadInterProScanResults(jobId)
134
- model.setLoadedInterProAnnotations(
132
+ model.setInterProAnnotations(
135
133
  Object.fromEntries(ret.results.map(r => [r.xref[0].id, r])),
136
134
  )
137
135
  model.setShowDomains(true)
@@ -43,4 +43,14 @@ export function DataModelF() {
43
43
  self.treeMetadata = treeMetadata
44
44
  },
45
45
  }))
46
+ .postProcessSnapshot(snap => {
47
+ const { tree, msa, treeMetadata } = snap
48
+ const max = 50_000
49
+ return {
50
+ tree: tree && tree.length > max ? undefined : tree,
51
+ msa: msa && msa.length > max ? undefined : msa,
52
+ treeMetadata:
53
+ treeMetadata && treeMetadata.length > max ? undefined : treeMetadata,
54
+ }
55
+ })
46
56
  }
@@ -1,4 +1,4 @@
1
- import { DialogComponentType } from '@jbrowse/core/util'
1
+ import type { DialogComponentType } from '@jbrowse/core/util'
2
2
  import { types } from 'mobx-state-tree'
3
3
 
4
4
  /**