react-msaview 5.1.1 → 5.2.1

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 (190) hide show
  1. package/README.md +41 -8
  2. package/bundle/index.js +17 -17
  3. package/bundle/index.js.LICENSE.txt +1 -1
  4. package/bundle/index.js.map +1 -1
  5. package/dist/calculateBlocks.d.ts +4 -10
  6. package/dist/calculateBlocks.js +12 -20
  7. package/dist/calculateBlocks.js.map +1 -1
  8. package/dist/components/ConservationTrack.js +20 -37
  9. package/dist/components/ConservationTrack.js.map +1 -1
  10. package/dist/components/MSAView.js +8 -1
  11. package/dist/components/MSAView.js.map +1 -1
  12. package/dist/components/ResizeHandles.d.ts +3 -0
  13. package/dist/components/ResizeHandles.js +60 -105
  14. package/dist/components/ResizeHandles.js.map +1 -1
  15. package/dist/components/TextTrack.js +25 -34
  16. package/dist/components/TextTrack.js.map +1 -1
  17. package/dist/components/Track.js +1 -1
  18. package/dist/components/Track.js.map +1 -1
  19. package/dist/components/VerticalScrollbar.js +2 -2
  20. package/dist/components/VerticalScrollbar.js.map +1 -1
  21. package/dist/components/dialogs/ExportSVGDialog.js +20 -20
  22. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  23. package/dist/components/dialogs/InterProScanDialog.js +6 -1
  24. package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
  25. package/dist/components/dialogs/UserProvidedDomainsDialog.js +1 -2
  26. package/dist/components/dialogs/UserProvidedDomainsDialog.js.map +1 -1
  27. package/dist/components/header/ColorSchemeMenu.js +1 -1
  28. package/dist/components/header/ColorSchemeMenu.js.map +1 -1
  29. package/dist/components/header/FileMenu.js +3 -2
  30. package/dist/components/header/FileMenu.js.map +1 -1
  31. package/dist/components/header/Header.js +1 -1
  32. package/dist/components/header/HeaderInfoArea.js +28 -8
  33. package/dist/components/header/HeaderInfoArea.js.map +1 -1
  34. package/dist/components/header/MSASettingsMenu.js +1 -1
  35. package/dist/components/header/MSASettingsMenu.js.map +1 -1
  36. package/dist/components/header/TreeSettingsMenu.js +1 -1
  37. package/dist/components/header/TreeSettingsMenu.js.map +1 -1
  38. package/dist/components/header/ZoomControls.js +7 -2
  39. package/dist/components/header/ZoomControls.js.map +1 -1
  40. package/dist/components/header/ZoomMenu.js +9 -0
  41. package/dist/components/header/ZoomMenu.js.map +1 -1
  42. package/dist/components/header/settingsMenuItems.js +24 -8
  43. package/dist/components/header/settingsMenuItems.js.map +1 -1
  44. package/dist/components/minimap/Minimap.js +6 -17
  45. package/dist/components/minimap/Minimap.js.map +1 -1
  46. package/dist/components/minimap/MinimapSVG.js +7 -17
  47. package/dist/components/minimap/MinimapSVG.js.map +1 -1
  48. package/dist/components/minimap/minimapLayout.d.ts +9 -0
  49. package/dist/components/minimap/minimapLayout.js +15 -0
  50. package/dist/components/minimap/minimapLayout.js.map +1 -0
  51. package/dist/components/msa/MSACanvas.js +6 -1
  52. package/dist/components/msa/MSACanvas.js.map +1 -1
  53. package/dist/components/msa/MSACanvasBlock.js +5 -1
  54. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  55. package/dist/components/msa/MSAMouseoverCanvas.js +2 -2
  56. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  57. package/dist/components/msa/getVisibleLeaves.d.ts +6 -0
  58. package/dist/components/msa/getVisibleLeaves.js +9 -0
  59. package/dist/components/msa/getVisibleLeaves.js.map +1 -0
  60. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +2 -1
  61. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +5 -6
  62. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  63. package/dist/components/msa/renderMSABlock.d.ts +2 -1
  64. package/dist/components/msa/renderMSABlock.js +100 -88
  65. package/dist/components/msa/renderMSABlock.js.map +1 -1
  66. package/dist/components/msa/renderMSAMouseover.js +5 -4
  67. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  68. package/dist/components/msa/visibleColRange.d.ts +8 -0
  69. package/dist/components/msa/visibleColRange.js +10 -0
  70. package/dist/components/msa/visibleColRange.js.map +1 -0
  71. package/dist/components/renderCtx.d.ts +7 -0
  72. package/dist/components/renderCtx.js +2 -0
  73. package/dist/components/renderCtx.js.map +1 -0
  74. package/dist/components/tracks/renderTracksSvg.d.ts +6 -5
  75. package/dist/components/tracks/renderTracksSvg.js +13 -5
  76. package/dist/components/tracks/renderTracksSvg.js.map +1 -1
  77. package/dist/components/tree/TreeCanvas.js.map +1 -1
  78. package/dist/components/tree/TreeCanvasBlock.js +2 -10
  79. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  80. package/dist/components/tree/renderTreeCanvas.d.ts +5 -4
  81. package/dist/components/tree/renderTreeCanvas.js +18 -26
  82. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  83. package/dist/components/util.d.ts +0 -14
  84. package/dist/components/util.js +0 -58
  85. package/dist/components/util.js.map +1 -1
  86. package/dist/constants.d.ts +4 -0
  87. package/dist/constants.js +7 -0
  88. package/dist/constants.js.map +1 -1
  89. package/dist/flatToTree.js +6 -0
  90. package/dist/flatToTree.js.map +1 -1
  91. package/dist/hierarchy.d.ts +3 -1
  92. package/dist/hierarchy.js +142 -89
  93. package/dist/hierarchy.js.map +1 -1
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.js +8 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/launchInterProScan.js +22 -9
  98. package/dist/launchInterProScan.js.map +1 -1
  99. package/dist/measureTextCanvas.js +2 -1
  100. package/dist/measureTextCanvas.js.map +1 -1
  101. package/dist/model.d.ts +234 -176
  102. package/dist/model.js +285 -259
  103. package/dist/model.js.map +1 -1
  104. package/dist/parseAsn1.js +8 -2
  105. package/dist/parseAsn1.js.map +1 -1
  106. package/dist/renderToSvg.d.ts +1 -1
  107. package/dist/renderToSvg.js +43 -46
  108. package/dist/renderToSvg.js.map +1 -1
  109. package/dist/rowCoordinateCalculations.d.ts +0 -9
  110. package/dist/rowCoordinateCalculations.js +0 -20
  111. package/dist/rowCoordinateCalculations.js.map +1 -1
  112. package/dist/setFontSize.d.ts +3 -0
  113. package/dist/setFontSize.js +14 -0
  114. package/dist/setFontSize.js.map +1 -0
  115. package/dist/useDevicePixelRatio.d.ts +1 -0
  116. package/dist/useDevicePixelRatio.js +27 -0
  117. package/dist/useDevicePixelRatio.js.map +1 -0
  118. package/dist/useWheelScroll.d.ts +3 -1
  119. package/dist/useWheelScroll.js +64 -22
  120. package/dist/useWheelScroll.js.map +1 -1
  121. package/dist/util.d.ts +5 -0
  122. package/dist/util.js +59 -1
  123. package/dist/util.js.map +1 -1
  124. package/dist/version.d.ts +1 -1
  125. package/dist/version.js +1 -1
  126. package/dist/webpack.js +0 -1
  127. package/dist/webpack.js.map +1 -1
  128. package/dist/wheelZoom.d.ts +4 -0
  129. package/dist/wheelZoom.js +43 -0
  130. package/dist/wheelZoom.js.map +1 -0
  131. package/package.json +5 -5
  132. package/src/calculateBlocks.ts +18 -51
  133. package/src/components/ConservationTrack.tsx +20 -45
  134. package/src/components/MSAView.tsx +10 -1
  135. package/src/components/ResizeHandles.tsx +101 -113
  136. package/src/components/TextTrack.tsx +31 -38
  137. package/src/components/Track.tsx +1 -1
  138. package/src/components/VerticalScrollbar.tsx +2 -2
  139. package/src/components/dialogs/ExportSVGDialog.tsx +27 -17
  140. package/src/components/dialogs/InterProScanDialog.tsx +6 -1
  141. package/src/components/dialogs/UserProvidedDomainsDialog.tsx +1 -2
  142. package/src/components/header/ColorSchemeMenu.tsx +1 -0
  143. package/src/components/header/FileMenu.tsx +3 -1
  144. package/src/components/header/Header.tsx +1 -1
  145. package/src/components/header/HeaderInfoArea.tsx +32 -7
  146. package/src/components/header/MSASettingsMenu.tsx +1 -0
  147. package/src/components/header/TreeSettingsMenu.tsx +1 -0
  148. package/src/components/header/ZoomControls.tsx +14 -1
  149. package/src/components/header/ZoomMenu.tsx +10 -0
  150. package/src/components/header/settingsMenuItems.ts +24 -8
  151. package/src/components/minimap/Minimap.tsx +6 -20
  152. package/src/components/minimap/MinimapSVG.tsx +10 -27
  153. package/src/components/minimap/minimapLayout.ts +17 -0
  154. package/src/components/msa/MSACanvas.tsx +9 -0
  155. package/src/components/msa/MSACanvasBlock.tsx +7 -1
  156. package/src/components/msa/MSAMouseoverCanvas.tsx +4 -3
  157. package/src/components/msa/getVisibleLeaves.ts +21 -0
  158. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +9 -9
  159. package/src/components/msa/renderMSABlock.ts +123 -125
  160. package/src/components/msa/renderMSAMouseover.ts +5 -4
  161. package/src/components/msa/visibleColRange.ts +17 -0
  162. package/src/components/renderCtx.ts +29 -0
  163. package/src/components/tracks/renderTracksSvg.ts +20 -10
  164. package/src/components/tree/TreeCanvas.tsx +3 -1
  165. package/src/components/tree/TreeCanvasBlock.tsx +2 -12
  166. package/src/components/tree/renderTreeCanvas.ts +27 -30
  167. package/src/components/util.ts +0 -81
  168. package/src/constants.ts +8 -0
  169. package/src/flatToTree.test.ts +30 -0
  170. package/src/flatToTree.ts +10 -1
  171. package/src/hierarchy.test.ts +53 -1
  172. package/src/hierarchy.ts +153 -100
  173. package/src/index.ts +8 -0
  174. package/src/launchInterProScan.ts +33 -11
  175. package/src/measureTextCanvas.ts +3 -1
  176. package/src/model.ts +359 -306
  177. package/src/parseAsn1.test.ts +6 -0
  178. package/src/parseAsn1.ts +11 -3
  179. package/src/renderToSvg.tsx +99 -95
  180. package/src/rowCoordinateCalculations.test.ts +0 -51
  181. package/src/rowCoordinateCalculations.ts +0 -23
  182. package/src/setFontSize.test.ts +33 -0
  183. package/src/setFontSize.ts +20 -0
  184. package/src/useDevicePixelRatio.ts +29 -0
  185. package/src/useWheelScroll.ts +79 -21
  186. package/src/util.ts +60 -1
  187. package/src/version.ts +1 -1
  188. package/src/webpack.ts +0 -1
  189. package/src/wheelZoom.test.ts +46 -0
  190. package/src/wheelZoom.ts +47 -0
@@ -8,19 +8,25 @@ export function msaSettingsMenuItems(model: MsaViewModel): MenuItem[] {
8
8
  label: 'Draw letters',
9
9
  type: 'checkbox',
10
10
  checked: drawMsaLetters,
11
- onClick: () => { model.setDrawMsaLetters(!drawMsaLetters) },
11
+ onClick: () => {
12
+ model.setDrawMsaLetters(!drawMsaLetters)
13
+ },
12
14
  },
13
15
  {
14
16
  label: 'Color letters instead of background of tiles',
15
17
  type: 'checkbox',
16
18
  checked: !bgColor,
17
- onClick: () => { model.setBgColor(!bgColor) },
19
+ onClick: () => {
20
+ model.setBgColor(!bgColor)
21
+ },
18
22
  },
19
23
  {
20
24
  label: 'Enable hiding gappy columns?',
21
25
  type: 'checkbox',
22
26
  checked: hideGaps,
23
- onClick: () => { model.setHideGaps(!hideGaps) },
27
+ onClick: () => {
28
+ model.setHideGaps(!hideGaps)
29
+ },
24
30
  },
25
31
  ]
26
32
  }
@@ -38,31 +44,41 @@ export function treeSettingsMenuItems(model: MsaViewModel): MenuItem[] {
38
44
  label: 'Show branch length',
39
45
  type: 'checkbox',
40
46
  checked: showBranchLen,
41
- onClick: () => { model.setShowBranchLen(!showBranchLen) },
47
+ onClick: () => {
48
+ model.setShowBranchLen(!showBranchLen)
49
+ },
42
50
  },
43
51
  {
44
52
  label: 'Show tree',
45
53
  type: 'checkbox',
46
54
  checked: drawTree,
47
- onClick: () => { model.setDrawTree(!drawTree) },
55
+ onClick: () => {
56
+ model.setDrawTree(!drawTree)
57
+ },
48
58
  },
49
59
  {
50
60
  label: 'Draw clickable bubbles on tree branches',
51
61
  type: 'checkbox',
52
62
  checked: drawNodeBubbles,
53
- onClick: () => { model.setDrawNodeBubbles(!drawNodeBubbles) },
63
+ onClick: () => {
64
+ model.setDrawNodeBubbles(!drawNodeBubbles)
65
+ },
54
66
  },
55
67
  {
56
68
  label: 'Tree labels align right',
57
69
  type: 'checkbox',
58
70
  checked: labelsAlignRight,
59
- onClick: () => { model.setLabelsAlignRight(!labelsAlignRight) },
71
+ onClick: () => {
72
+ model.setLabelsAlignRight(!labelsAlignRight)
73
+ },
60
74
  },
61
75
  {
62
76
  label: 'Draw labels',
63
77
  type: 'checkbox',
64
78
  checked: drawLabels,
65
- onClick: () => { model.setDrawLabels(!drawLabels) },
79
+ onClick: () => {
80
+ model.setDrawLabels(!drawLabels)
81
+ },
66
82
  },
67
83
  ]
68
84
  }
@@ -2,20 +2,16 @@ import React, { useCallback, useState } from 'react'
2
2
 
3
3
  import { observer } from 'mobx-react'
4
4
 
5
+ import { MINIMAP_BAR_HEIGHT, getMinimapLayout } from './minimapLayout.ts'
5
6
  import { useDragScroll } from '../../useDragScroll.ts'
6
7
 
7
8
  import type { MsaViewModel } from '../../model.ts'
8
9
 
9
10
  const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
10
11
  const [hovered, setHovered] = useState(false)
11
- const { scrollX, msaAreaWidth, minimapHeight, colWidth, numColumns } = model
12
- const unit = msaAreaWidth / numColumns / colWidth
13
- const left = -scrollX
14
- const right = left + msaAreaWidth
15
- const s = left * unit
16
- const e = right * unit
12
+ const { minimapHeight } = model
13
+ const { unit, s, w, polygonHeight, polygonPoints } = getMinimapLayout(model)
17
14
  const fill = 'rgba(66, 119, 127, 0.3)'
18
- const w = Math.max(e - s, 20)
19
15
 
20
16
  const { startDrag } = useDragScroll(
21
17
  'x',
@@ -27,8 +23,6 @@ const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
27
23
  ),
28
24
  )
29
25
 
30
- const barHeight = 12
31
- const polygonHeight = minimapHeight - barHeight
32
26
  return (
33
27
  <div
34
28
  style={{
@@ -39,7 +33,7 @@ const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
39
33
  >
40
34
  <div
41
35
  style={{
42
- height: barHeight,
36
+ height: MINIMAP_BAR_HEIGHT,
43
37
  boxSizing: 'border-box',
44
38
  border: '1px solid #555',
45
39
  }}
@@ -51,7 +45,7 @@ const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
51
45
  left: Math.max(0, s),
52
46
  background: hovered ? 'rgba(66,119,127,0.6)' : fill,
53
47
  cursor: 'pointer',
54
- height: barHeight,
48
+ height: MINIMAP_BAR_HEIGHT,
55
49
  width: w,
56
50
  zIndex: 100,
57
51
  }}
@@ -67,15 +61,7 @@ const Minimap = observer(function ({ model }: { model: MsaViewModel }) {
67
61
  />
68
62
 
69
63
  <svg height={polygonHeight} style={{ width: '100%' }}>
70
- <polygon
71
- fill={fill}
72
- points={[
73
- [s + w, 0],
74
- [s, 0],
75
- [0, polygonHeight],
76
- [msaAreaWidth, polygonHeight],
77
- ].toString()}
78
- />
64
+ <polygon fill={fill} points={polygonPoints} />
79
65
  </svg>
80
66
  </div>
81
67
  )
@@ -2,25 +2,13 @@ import React from 'react'
2
2
 
3
3
  import { observer } from 'mobx-react'
4
4
 
5
+ import { MINIMAP_BAR_HEIGHT, getMinimapLayout } from './minimapLayout.ts'
6
+
5
7
  import type { MsaViewModel } from '../../model.ts'
6
8
 
7
9
  const MinimapSVG = observer(({ model }: { model: MsaViewModel }) => {
8
- const {
9
- scrollX,
10
- msaAreaWidth: W,
11
- minimapHeight: H,
12
- colWidth,
13
- numColumns,
14
- } = model
15
-
16
- const BAR_HEIGHT = 12
17
- const H2 = H - 12
18
-
19
- const unit = W / numColumns / colWidth
20
- const left = -scrollX
21
- const right = left + W
22
- const s = left * unit
23
- const e = right * unit
10
+ const { msaAreaWidth } = model
11
+ const { s, w, polygonPoints } = getMinimapLayout(model)
24
12
  const fillColor = 'rgb(66, 119, 127)'
25
13
  const fillOpacity = 0.3
26
14
 
@@ -29,30 +17,25 @@ const MinimapSVG = observer(({ model }: { model: MsaViewModel }) => {
29
17
  <rect
30
18
  x={0}
31
19
  y={0}
32
- width={W}
33
- height={BAR_HEIGHT}
20
+ width={msaAreaWidth}
21
+ height={MINIMAP_BAR_HEIGHT}
34
22
  stroke="#555"
35
23
  fill="none"
36
24
  />
37
25
  <rect
38
26
  x={Math.max(0, s)}
39
27
  y={0}
40
- width={e - s}
41
- height={BAR_HEIGHT}
28
+ width={w}
29
+ height={MINIMAP_BAR_HEIGHT}
42
30
  fill={fillColor}
43
31
  fillOpacity={fillOpacity}
44
32
  stroke="#555"
45
33
  />
46
- <g transform={`translate(0 ${BAR_HEIGHT})`}>
34
+ <g transform={`translate(0 ${MINIMAP_BAR_HEIGHT})`}>
47
35
  <polygon
48
36
  fill={fillColor}
49
37
  fillOpacity={fillOpacity}
50
- points={[
51
- [e, 0],
52
- [s, 0],
53
- [0, H2],
54
- [W, H2],
55
- ].toString()}
38
+ points={polygonPoints}
56
39
  />
57
40
  </g>
58
41
  </>
@@ -0,0 +1,17 @@
1
+ import type { MsaViewModel } from '../../model.ts'
2
+
3
+ export const MINIMAP_BAR_HEIGHT = 12
4
+
5
+ // viewport-rectangle and trapezoid geometry shared by the interactive Minimap
6
+ // and the static MinimapSVG (used for SVG export)
7
+ export function getMinimapLayout(model: MsaViewModel) {
8
+ const { scrollX, msaAreaWidth, minimapHeight, colWidth, numColumns } = model
9
+ const unit = msaAreaWidth / numColumns / colWidth
10
+ const left = -scrollX
11
+ const s = left * unit
12
+ const e = (left + msaAreaWidth) * unit
13
+ const w = Math.max(e - s, 20)
14
+ const polygonHeight = minimapHeight - MINIMAP_BAR_HEIGHT
15
+ const polygonPoints = `${s + w},0 ${s},0 0,${polygonHeight} ${msaAreaWidth},${polygonHeight}`
16
+ return { unit, s, w, polygonHeight, polygonPoints }
17
+ }
@@ -16,6 +16,7 @@ const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
16
16
  height,
17
17
  msaAreaWidth,
18
18
  blocks2d,
19
+ scrollZoom,
19
20
  } = model
20
21
  const ref = useRef<HTMLDivElement>(null)
21
22
  const onScrollX = useCallback(
@@ -30,10 +31,18 @@ const MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {
30
31
  },
31
32
  [model],
32
33
  )
34
+ const onZoom = useCallback(
35
+ (scaleFactor: number, offsetX: number, offsetY: number) => {
36
+ model.zoomToPos(scaleFactor, offsetX, offsetY)
37
+ },
38
+ [model],
39
+ )
33
40
  const { onMouseDown, onMouseUp } = useWheelScroll({
34
41
  ref,
35
42
  onScrollX,
36
43
  onScrollY,
44
+ onZoom,
45
+ scrollZoom,
37
46
  })
38
47
 
39
48
  return (
@@ -97,7 +97,6 @@ const MSACanvasBlock = observer(function ({
97
97
  ref={ref}
98
98
  onMouseMove={event => {
99
99
  if (ref.current) {
100
- setMousePosition({ x: event.clientX, y: event.clientY })
101
100
  const { col, row } = eventToColRow(
102
101
  event,
103
102
  ref.current,
@@ -117,6 +116,13 @@ const MSACanvasBlock = observer(function ({
117
116
  } else {
118
117
  model.setMousePos(undefined, undefined)
119
118
  }
119
+ // only track client coords when an insertion is hovered (the only
120
+ // consumer is the tooltip below); avoids a re-render on every move
121
+ setMousePosition(
122
+ model.hoveredInsertion
123
+ ? { x: event.clientX, y: event.clientY }
124
+ : undefined,
125
+ )
120
126
  }
121
127
  }}
122
128
  onClick={event => {
@@ -14,7 +14,8 @@ const MSAMouseoverCanvas = observer(function ({
14
14
  model: MsaViewModel
15
15
  }) {
16
16
  const ref = useRef<HTMLCanvasElement>(null)
17
- const { height, msaAreaWidth, verticalScrollbarWidth } = model
17
+ const { height, msaAreaWidth, verticalScrollbarWidth, highResScaleFactor } =
18
+ model
18
19
  const width = msaAreaWidth - verticalScrollbarWidth
19
20
  useEffect(() => {
20
21
  const ctx = ref.current?.getContext('2d')
@@ -31,8 +32,8 @@ const MSAMouseoverCanvas = observer(function ({
31
32
  <canvas
32
33
  ref={ref}
33
34
  id="mouseover"
34
- width={width}
35
- height={height}
35
+ width={width * highResScaleFactor}
36
+ height={height * highResScaleFactor}
36
37
  style={{
37
38
  position: 'absolute',
38
39
  top: 0,
@@ -0,0 +1,21 @@
1
+ import type { MsaViewModel } from '../../model.ts'
2
+
3
+ // The slice of leaves whose rows intersect a block of height blockSizeY at
4
+ // vertical offset offsetY, padded by one row on each side.
5
+ export function getVisibleLeaves({
6
+ model,
7
+ offsetY,
8
+ blockSizeY,
9
+ }: {
10
+ model: MsaViewModel
11
+ offsetY: number
12
+ blockSizeY: number
13
+ }) {
14
+ const { leaves, rowHeight } = model
15
+ const yStart = Math.max(0, Math.floor((offsetY - rowHeight) / rowHeight))
16
+ const yEnd = Math.max(
17
+ 0,
18
+ Math.ceil((offsetY + blockSizeY + rowHeight) / rowHeight),
19
+ )
20
+ return leaves.slice(yStart, yEnd)
21
+ }
@@ -1,6 +1,9 @@
1
+ import { getVisibleLeaves } from './getVisibleLeaves.ts'
2
+
1
3
  import type { HierarchyNode } from '../../hierarchy.ts'
2
4
  import type { MsaViewModel } from '../../model.ts'
3
5
  import type { NodeWithIdsAndLength } from '../../types.ts'
6
+ import type { RenderCtx } from '../renderCtx.ts'
4
7
 
5
8
  export function renderBoxFeatureCanvasBlock({
6
9
  model,
@@ -13,22 +16,19 @@ export function renderBoxFeatureCanvasBlock({
13
16
  offsetX: number
14
17
  offsetY: number
15
18
  model: MsaViewModel
16
- ctx: CanvasRenderingContext2D
19
+ ctx: RenderCtx
17
20
  highResScaleFactorOverride?: number
18
21
  blockSizeYOverride?: number
19
22
  }) {
20
- const { leaves, blockSize, rowHeight, highResScaleFactor, showDomains } =
21
- model
23
+ const { blockSize, rowHeight, highResScaleFactor, showDomains } = model
22
24
  if (showDomains) {
23
- const k = highResScaleFactorOverride || highResScaleFactor
24
- const by = blockSizeYOverride || blockSize
25
+ const k = highResScaleFactorOverride ?? highResScaleFactor
26
+ const by = blockSizeYOverride ?? blockSize
25
27
  ctx.resetTransform()
26
28
  ctx.scale(k, k)
27
29
  ctx.translate(-offsetX, rowHeight / 2 - offsetY)
28
30
 
29
- const yStart = Math.max(0, Math.floor((offsetY - rowHeight) / rowHeight))
30
- const yEnd = Math.max(0, Math.ceil((offsetY + by + rowHeight) / rowHeight))
31
- const visibleLeaves = leaves.slice(yStart, yEnd)
31
+ const visibleLeaves = getVisibleLeaves({ model, offsetY, blockSizeY: by })
32
32
 
33
33
  drawTiles({
34
34
  model,
@@ -44,7 +44,7 @@ function drawTiles({
44
44
  visibleLeaves,
45
45
  }: {
46
46
  model: MsaViewModel
47
- ctx: CanvasRenderingContext2D
47
+ ctx: RenderCtx
48
48
  visibleLeaves: HierarchyNode<NodeWithIdsAndLength>[]
49
49
  }) {
50
50
  const {