jbrowse-plugin-graphgenomeviewer 7.1.0 → 7.1.2

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 (233) hide show
  1. package/README.md +17 -8
  2. package/dist/chunks/AddTrackWorkflow-RPH4ZFSX.js +2 -0
  3. package/dist/chunks/{AddTrackWorkflow-Q6RY23LF.js.map → AddTrackWorkflow-RPH4ZFSX.js.map} +2 -2
  4. package/dist/chunks/{ChooseSamplesDialog-BNVYBGJQ.js → ChooseSamplesDialog-JRN4YLBY.js} +2 -2
  5. package/dist/chunks/{ChooseWalksDialog-EN3C6AQA.js → ChooseWalksDialog-UXLFZTZJ.js} +2 -2
  6. package/dist/chunks/GbzBaseSyntenyAdapter-LRECKL74.js +2 -0
  7. package/dist/chunks/GbzBaseSyntenyAdapter-LRECKL74.js.map +7 -0
  8. package/dist/chunks/{GraphGenomeView-Z2WZKEEO.js → GraphGenomeView-NJ5XCREB.js} +2 -2
  9. package/dist/chunks/GraphTrackSettingsDialog-47PQ6LM7.js +6 -0
  10. package/dist/chunks/GraphTrackSettingsDialog-47PQ6LM7.js.map +7 -0
  11. package/dist/chunks/{HighlightColorDialog-EYBKFSJU.js → HighlightColorDialog-UK5VDDV6.js} +2 -2
  12. package/dist/chunks/{LinearGraphDisplay-WIBVWRQE.js → LinearGraphDisplay-TXTKAACH.js} +2 -2
  13. package/dist/chunks/MinigraphBubbleAdapter-HW7XQMAI.js +2 -0
  14. package/dist/chunks/MinigraphBubbleAdapter-HW7XQMAI.js.map +7 -0
  15. package/dist/chunks/RgfaTabixAdapter-PSKYWD2X.js +3 -0
  16. package/dist/chunks/RgfaTabixAdapter-PSKYWD2X.js.map +7 -0
  17. package/dist/chunks/{TrackWarningsDialog-QT4YEXGD.js → TrackWarningsDialog-TRYBOIHX.js} +2 -2
  18. package/dist/chunks/WalkTabixSyntenyAdapter-U53JLYVU.js +2 -0
  19. package/dist/chunks/WalkTabixSyntenyAdapter-U53JLYVU.js.map +7 -0
  20. package/dist/chunks/chunk-2MCOY3YG.js +3 -0
  21. package/dist/chunks/chunk-2MCOY3YG.js.map +7 -0
  22. package/dist/chunks/{chunk-EWFJBQDV.js → chunk-5O6YRJHL.js} +2 -2
  23. package/dist/chunks/{chunk-EWFJBQDV.js.map → chunk-5O6YRJHL.js.map} +1 -1
  24. package/dist/chunks/chunk-BUY2PV7D.js +2 -0
  25. package/dist/chunks/chunk-BUY2PV7D.js.map +7 -0
  26. package/dist/chunks/chunk-DVCZ3BOC.js +2 -0
  27. package/dist/chunks/chunk-DVCZ3BOC.js.map +7 -0
  28. package/dist/chunks/{chunk-SAMJE6GH.js → chunk-EGDLEQ47.js} +3 -3
  29. package/dist/chunks/{chunk-SAMJE6GH.js.map → chunk-EGDLEQ47.js.map} +4 -4
  30. package/dist/chunks/chunk-FHZXW7IG.js +2 -0
  31. package/dist/chunks/chunk-FHZXW7IG.js.map +7 -0
  32. package/dist/chunks/{chunk-DZ4OUKQV.js → chunk-FITPB5X6.js} +2 -2
  33. package/dist/chunks/{chunk-DZ4OUKQV.js.map → chunk-FITPB5X6.js.map} +1 -1
  34. package/dist/chunks/chunk-FVK2THE4.js +2 -0
  35. package/dist/chunks/chunk-FVK2THE4.js.map +7 -0
  36. package/dist/chunks/{chunk-AHFQHYJI.js → chunk-IBWORBGY.js} +2 -2
  37. package/dist/chunks/chunk-MND7GAOG.js +2 -0
  38. package/dist/chunks/chunk-MND7GAOG.js.map +7 -0
  39. package/dist/chunks/chunk-MURN3JPK.js +2 -0
  40. package/dist/chunks/chunk-MURN3JPK.js.map +7 -0
  41. package/dist/chunks/{chunk-3Q4RBDCL.js → chunk-N6PQZSAX.js} +1 -1
  42. package/dist/chunks/{chunk-3Q4RBDCL.js.map → chunk-N6PQZSAX.js.map} +1 -1
  43. package/dist/chunks/chunk-NWJYLP6Z.js +4 -0
  44. package/dist/chunks/chunk-NWJYLP6Z.js.map +7 -0
  45. package/dist/chunks/{chunk-YJHYBDYF.js → chunk-S75W27NT.js} +2 -2
  46. package/dist/chunks/{chunk-YJHYBDYF.js.map → chunk-S75W27NT.js.map} +1 -1
  47. package/dist/chunks/{chunk-IXQK7JAW.js → chunk-T4HOC6O3.js} +1 -1
  48. package/dist/chunks/{chunk-IXQK7JAW.js.map → chunk-T4HOC6O3.js.map} +1 -1
  49. package/dist/chunks/{chunk-AU73K7LX.js → chunk-TUKJRVBS.js} +1 -1
  50. package/dist/chunks/{chunk-AU73K7LX.js.map → chunk-TUKJRVBS.js.map} +1 -1
  51. package/dist/chunks/chunk-UGCNPRKC.js +2 -0
  52. package/dist/chunks/{chunk-E3WYW7Z6.js.map → chunk-UGCNPRKC.js.map} +2 -2
  53. package/dist/chunks/{chunk-YSTMDXXX.js → chunk-VJ3SO4CH.js} +1 -1
  54. package/dist/chunks/{chunk-YSTMDXXX.js.map → chunk-VJ3SO4CH.js.map} +1 -1
  55. package/dist/chunks/{chunk-XT766CZ5.js → chunk-W6EQLQ6H.js} +1 -1
  56. package/dist/chunks/{chunk-XT766CZ5.js.map → chunk-W6EQLQ6H.js.map} +1 -1
  57. package/dist/chunks/chunk-WAMBI7OX.js +2 -0
  58. package/dist/chunks/chunk-WAMBI7OX.js.map +7 -0
  59. package/dist/chunks/chunk-WCGVUZWP.js +2 -0
  60. package/dist/chunks/chunk-WCGVUZWP.js.map +7 -0
  61. package/dist/chunks/chunk-WEGWTC52.js +2 -0
  62. package/dist/chunks/chunk-WEGWTC52.js.map +7 -0
  63. package/dist/chunks/chunk-YU7T5WOQ.js +2 -0
  64. package/dist/chunks/{chunk-6OPB7FOJ.js.map → chunk-YU7T5WOQ.js.map} +2 -2
  65. package/dist/chunks/{chunk-446RWIA3.js → chunk-ZMOMFU2B.js} +1 -1
  66. package/dist/chunks/{chunk-446RWIA3.js.map → chunk-ZMOMFU2B.js.map} +1 -1
  67. package/dist/chunks/renderSvg-KSQI5DH6.js +2 -0
  68. package/dist/chunks/renderSvg-KSQI5DH6.js.map +7 -0
  69. package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +4 -4
  70. package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +4 -4
  71. package/package.json +8 -9
  72. package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.test.ts +12 -10
  73. package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.ts +31 -39
  74. package/src/GbzBaseSyntenyAdapter/configSchema.ts +5 -29
  75. package/src/GetGraphHaplotypes.ts +6 -15
  76. package/src/GetGraphReads.ts +7 -14
  77. package/src/GetSubgraph.ts +11 -20
  78. package/src/GraphAddTrackWorkflow/AddTrackWorkflow.test.tsx +73 -0
  79. package/src/GraphAddTrackWorkflow/AddTrackWorkflow.tsx +1 -0
  80. package/src/GraphAddTrackWorkflow/buildTrackConfig.test.ts +3 -2
  81. package/src/GraphAddTrackWorkflow/buildTrackConfig.ts +2 -11
  82. package/src/GraphAddTrackWorkflow/graphManifest.ts +15 -3
  83. package/src/GraphGenomeView/components/BubbleHalos.tsx +5 -24
  84. package/src/GraphGenomeView/components/ElTree.tsx +6 -1
  85. package/src/GraphGenomeView/components/FacetPanels.test.tsx +65 -0
  86. package/src/GraphGenomeView/components/FacetPanels.tsx +17 -12
  87. package/src/GraphGenomeView/components/GenePins.tsx +5 -22
  88. package/src/GraphGenomeView/components/GraphCanvas.tsx +40 -234
  89. package/src/GraphGenomeView/components/GraphSettingsDialog.tsx +102 -108
  90. package/src/GraphGenomeView/components/GraphToolbar.tsx +5 -6
  91. package/src/GraphGenomeView/components/HoverLayer.tsx +3 -7
  92. package/src/GraphGenomeView/components/HoverTooltip.test.tsx +39 -0
  93. package/src/GraphGenomeView/components/HoverTooltip.tsx +122 -0
  94. package/src/GraphGenomeView/components/LabelChip.tsx +3 -5
  95. package/src/GraphGenomeView/components/LabelLayer.tsx +4 -17
  96. package/src/GraphGenomeView/components/LabelledSelect.tsx +1 -1
  97. package/src/GraphGenomeView/components/Legend.tsx +14 -23
  98. package/src/GraphGenomeView/components/PaneContextMenu.test.tsx +48 -0
  99. package/src/GraphGenomeView/components/PaneContextMenu.tsx +144 -0
  100. package/src/GraphGenomeView/components/PaneLayer.tsx +91 -0
  101. package/src/GraphGenomeView/components/PaneSvg.tsx +32 -50
  102. package/src/GraphGenomeView/components/ReferenceStripOverlay.test.tsx +48 -0
  103. package/src/GraphGenomeView/components/ReferenceStripOverlay.tsx +13 -42
  104. package/src/GraphGenomeView/components/SettingsMenu.test.tsx +29 -0
  105. package/src/GraphGenomeView/components/SettingsMenu.tsx +56 -65
  106. package/src/GraphGenomeView/components/TubeMapOverlay.tsx +15 -46
  107. package/src/GraphGenomeView/components/WalkRowsOverlay.tsx +58 -132
  108. package/src/GraphGenomeView/components/WalkStrip.tsx +17 -20
  109. package/src/GraphGenomeView/components/WalkStripLocator.tsx +8 -15
  110. package/src/GraphGenomeView/components/usePaneGestures.test.tsx +35 -0
  111. package/src/GraphGenomeView/components/usePaneGestures.ts +88 -91
  112. package/src/GraphGenomeView/genes/geneFeatures.ts +27 -45
  113. package/src/GraphGenomeView/graphLayers.ts +4 -4
  114. package/src/GraphGenomeView/host.ts +1 -1
  115. package/src/GraphGenomeView/legendSections.test.ts +23 -1
  116. package/src/GraphGenomeView/legendSections.ts +68 -74
  117. package/src/GraphGenomeView/model.test.ts +373 -39
  118. package/src/GraphGenomeView/model.ts +67 -11
  119. package/src/GraphGenomeView/pane/fitViews.ts +57 -514
  120. package/src/GraphGenomeView/pane/graphViews.ts +219 -160
  121. package/src/GraphGenomeView/pane/hostViews.ts +2 -10
  122. package/src/GraphGenomeView/pane/keepInView.ts +5 -4
  123. package/src/GraphGenomeView/pane/launchActions.ts +117 -139
  124. package/src/GraphGenomeView/pane/launchViews.ts +8 -27
  125. package/src/GraphGenomeView/pane/loadActions.ts +208 -187
  126. package/src/GraphGenomeView/pane/morph.ts +3 -9
  127. package/src/GraphGenomeView/pane/paneBase.ts +22 -11
  128. package/src/GraphGenomeView/pane/renderingActions.ts +65 -11
  129. package/src/GraphGenomeView/pane/settingActions.ts +17 -42
  130. package/src/GraphGenomeView/pane/tubeMapViews.ts +445 -0
  131. package/src/GraphGenomeView/pane/walkRowViews.ts +29 -37
  132. package/src/GraphGenomeView/renderPipeline.test.ts +1 -1
  133. package/src/GraphGenomeView/repeats/repeatFeatures.test.ts +23 -0
  134. package/src/GraphGenomeView/repeats/repeatFeatures.ts +16 -23
  135. package/src/GraphGenomeView/repeats/walkCalls.test.ts +18 -0
  136. package/src/GraphGenomeView/repeats/walkCalls.ts +46 -38
  137. package/src/GraphGenomeView/subgraphLoad.test.ts +67 -3
  138. package/src/GraphGenomeView/trackFeatures.ts +24 -0
  139. package/src/GraphGenomeView/tubeMapPanels.ts +28 -36
  140. package/src/GraphGenomeView/viewModel.ts +8 -56
  141. package/src/GraphGenomeView/walkRowGroups.ts +104 -30
  142. package/src/GraphGenomeView/walkRowSpans.test.ts +6 -0
  143. package/src/GraphGenomeView/walkRowSpans.ts +22 -31
  144. package/src/GraphGenomeView/walkRowsCut.ts +8 -17
  145. package/src/LinearGraphDisplay/LinearGraphDisplay.test.ts +173 -26
  146. package/src/LinearGraphDisplay/components/SubgraphContextSelect.test.tsx +1 -1
  147. package/src/LinearGraphDisplay/components/SubgraphContextSelect.tsx +3 -3
  148. package/src/LinearGraphDisplay/components/SubgraphHaplotypesField.test.tsx +3 -3
  149. package/src/LinearGraphDisplay/components/SubgraphHaplotypesField.tsx +7 -10
  150. package/src/LinearGraphDisplay/configSchema.ts +0 -3
  151. package/src/LinearGraphDisplay/denseWindow.ts +8 -11
  152. package/src/LinearGraphDisplay/model.ts +89 -82
  153. package/src/MinigraphBubbleAdapter/MinigraphBubbleAdapter.test.ts +21 -0
  154. package/src/MinigraphBubbleAdapter/MinigraphBubbleAdapter.ts +6 -14
  155. package/src/MinigraphBubbleAdapter/configSchema.ts +3 -9
  156. package/src/MinigraphBubbleAdapter/index.ts +1 -2
  157. package/src/RgfaTabixAdapter/RgfaTabixAdapter.test.ts +45 -1
  158. package/src/RgfaTabixAdapter/RgfaTabixAdapter.ts +111 -276
  159. package/src/RgfaTabixAdapter/configSchema.ts +15 -49
  160. package/src/RgfaTabixAdapter/index.ts +1 -2
  161. package/src/RgfaTabixAdapter/rgfaBed.ts +25 -15
  162. package/src/RgfaTabixAdapter/rgfaCut.ts +139 -0
  163. package/src/RgfaTabixAdapter/test_data/walks2_twopart.GRCh38.walks.bed.gz +0 -0
  164. package/src/RgfaTabixAdapter/test_data/walks2_twopart.GRCh38.walks.bed.gz.tbi +0 -0
  165. package/src/RgfaTabixAdapter/walkFiles.test.ts +33 -0
  166. package/src/RgfaTabixAdapter/walkReader.ts +103 -27
  167. package/src/RgfaTabixAdapter/walkRowRuns.test.ts +53 -0
  168. package/src/RgfaTabixAdapter/walkRowRuns.ts +42 -24
  169. package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.test.ts +37 -6
  170. package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.ts +23 -45
  171. package/src/WalkTabixSyntenyAdapter/configSchema.ts +11 -24
  172. package/src/WalkTabixSyntenyAdapter/index.ts +1 -2
  173. package/src/WalkTabixSyntenyAdapter/walkLanes.ts +35 -43
  174. package/src/adapterImplementing.ts +27 -0
  175. package/src/graphTrackDefaults/index.ts +14 -20
  176. package/src/hoverSync/lgvHover.ts +2 -4
  177. package/src/launchFromGraph/contributors.ts +1 -5
  178. package/src/launchFromGraph/graphMenuItems.ts +3 -4
  179. package/src/launchFromGraph/launchFromGraph.test.ts +0 -1
  180. package/src/launchFromGraph/launchFromGraph.ts +8 -13
  181. package/src/panSNTabix.test.ts +1 -26
  182. package/src/panSNTabix.ts +54 -51
  183. package/src/synteny/lanePairs.ts +8 -0
  184. package/src/synteny/matchFeature.ts +52 -0
  185. package/src/tabixRange.ts +13 -10
  186. package/src/version.ts +1 -1
  187. package/dist/chunks/AddTrackWorkflow-Q6RY23LF.js +0 -2
  188. package/dist/chunks/GbzBaseSyntenyAdapter-TIXR4Y3J.js +0 -2
  189. package/dist/chunks/GbzBaseSyntenyAdapter-TIXR4Y3J.js.map +0 -7
  190. package/dist/chunks/GraphTrackSettingsDialog-TAM6PMXD.js +0 -6
  191. package/dist/chunks/GraphTrackSettingsDialog-TAM6PMXD.js.map +0 -7
  192. package/dist/chunks/MinigraphBubbleAdapter-AGI2UYQR.js +0 -2
  193. package/dist/chunks/MinigraphBubbleAdapter-AGI2UYQR.js.map +0 -7
  194. package/dist/chunks/RgfaTabixAdapter-2OL5X3HF.js +0 -3
  195. package/dist/chunks/RgfaTabixAdapter-2OL5X3HF.js.map +0 -7
  196. package/dist/chunks/WalkTabixSyntenyAdapter-UKFHCFOF.js +0 -2
  197. package/dist/chunks/WalkTabixSyntenyAdapter-UKFHCFOF.js.map +0 -7
  198. package/dist/chunks/chunk-5SFGHDQA.js +0 -2
  199. package/dist/chunks/chunk-5SFGHDQA.js.map +0 -7
  200. package/dist/chunks/chunk-6OPB7FOJ.js +0 -2
  201. package/dist/chunks/chunk-AMFIBQVR.js +0 -2
  202. package/dist/chunks/chunk-AMFIBQVR.js.map +0 -7
  203. package/dist/chunks/chunk-BJMRBVG3.js +0 -2
  204. package/dist/chunks/chunk-BJMRBVG3.js.map +0 -7
  205. package/dist/chunks/chunk-E3WYW7Z6.js +0 -2
  206. package/dist/chunks/chunk-EHCF6AXH.js +0 -2
  207. package/dist/chunks/chunk-EHCF6AXH.js.map +0 -7
  208. package/dist/chunks/chunk-GOFS7BXK.js +0 -3
  209. package/dist/chunks/chunk-GOFS7BXK.js.map +0 -7
  210. package/dist/chunks/chunk-IJQTSJGT.js +0 -4
  211. package/dist/chunks/chunk-IJQTSJGT.js.map +0 -7
  212. package/dist/chunks/chunk-J6NZIAZF.js +0 -2
  213. package/dist/chunks/chunk-J6NZIAZF.js.map +0 -7
  214. package/dist/chunks/chunk-LUTMKRXY.js +0 -2
  215. package/dist/chunks/chunk-LUTMKRXY.js.map +0 -7
  216. package/dist/chunks/chunk-MHPJB22Z.js +0 -2
  217. package/dist/chunks/chunk-MHPJB22Z.js.map +0 -7
  218. package/dist/chunks/chunk-TXI43PEN.js +0 -2
  219. package/dist/chunks/chunk-TXI43PEN.js.map +0 -7
  220. package/dist/chunks/chunk-WRH2EJKX.js +0 -2
  221. package/dist/chunks/chunk-WRH2EJKX.js.map +0 -7
  222. package/dist/chunks/chunk-WX26KTZM.js +0 -2
  223. package/dist/chunks/chunk-WX26KTZM.js.map +0 -7
  224. package/dist/chunks/renderSvg-ST2GBBOC.js +0 -2
  225. package/dist/chunks/renderSvg-ST2GBBOC.js.map +0 -7
  226. package/src/GraphGenomeView/components/WalkRowContextMenu.tsx +0 -105
  227. /package/dist/chunks/{ChooseSamplesDialog-BNVYBGJQ.js.map → ChooseSamplesDialog-JRN4YLBY.js.map} +0 -0
  228. /package/dist/chunks/{ChooseWalksDialog-EN3C6AQA.js.map → ChooseWalksDialog-UXLFZTZJ.js.map} +0 -0
  229. /package/dist/chunks/{GraphGenomeView-Z2WZKEEO.js.map → GraphGenomeView-NJ5XCREB.js.map} +0 -0
  230. /package/dist/chunks/{HighlightColorDialog-EYBKFSJU.js.map → HighlightColorDialog-UK5VDDV6.js.map} +0 -0
  231. /package/dist/chunks/{LinearGraphDisplay-WIBVWRQE.js.map → LinearGraphDisplay-TXTKAACH.js.map} +0 -0
  232. /package/dist/chunks/{TrackWarningsDialog-QT4YEXGD.js.map → TrackWarningsDialog-TRYBOIHX.js.map} +0 -0
  233. /package/dist/chunks/{chunk-AHFQHYJI.js.map → chunk-IBWORBGY.js.map} +0 -0
@@ -1,6 +1,5 @@
1
- import { useState } from 'react'
2
-
3
1
  import { CascadingMenuButton } from '@jbrowse/core/ui'
2
+ import { getSession } from '@jbrowse/core/util'
4
3
  import CloseIcon from '@mui/icons-material/Close'
5
4
  import MoreVertIcon from '@mui/icons-material/MoreVert'
6
5
  import RouteIcon from '@mui/icons-material/Route'
@@ -17,78 +16,70 @@ const SettingsMenu = observer(function SettingsMenu({
17
16
  }: {
18
17
  model: GraphPaneModel
19
18
  }) {
20
- const [settingsOpen, setSettingsOpen] = useState(false)
21
19
  // the toolbar beside this menu picks the walks and the repeat
22
20
  const haplotypes = model.highlightMenuItems({ picks: false })
23
21
 
24
22
  return (
25
- <>
26
- <CascadingMenuButton
27
- size="small"
28
- tooltip="Graph options"
29
- menuItems={[
30
- ...(haplotypes.length > 0
31
- ? [{ label: 'Haplotypes', icon: RouteIcon, subMenu: haplotypes }]
32
- : []),
33
- ...model.layoutOptionMenuItems({ repeat: false }),
34
- {
35
- label: 'Show...',
36
- icon: VisibilityIcon,
37
- subMenu: [
38
- ...model.showMenuItems(),
39
- ...(model.modeDrawsNodes && model.walkChoices.length > 1
40
- ? [
41
- {
42
- type: 'checkbox' as const,
43
- label: 'Show walk rows under the graph',
44
- checked: model.walkStrip,
45
- onClick: () => {
46
- model.setWalkStrip(!model.walkStrip)
47
- },
23
+ <CascadingMenuButton
24
+ size="small"
25
+ tooltip="Graph options"
26
+ menuItems={[
27
+ ...(haplotypes.length > 0
28
+ ? [{ label: 'Haplotypes', icon: RouteIcon, subMenu: haplotypes }]
29
+ : []),
30
+ ...model.layoutOptionMenuItems({ repeat: false }),
31
+ {
32
+ label: 'Show...',
33
+ icon: VisibilityIcon,
34
+ subMenu: [
35
+ ...model.showMenuItems(),
36
+ ...(model.modeDrawsNodes && model.walkChoices.length > 1
37
+ ? [
38
+ {
39
+ type: 'checkbox' as const,
40
+ label: 'Show walk rows under the graph',
41
+ checked: model.walkStrip,
42
+ onClick: () => {
43
+ model.setWalkStrip(!model.walkStrip)
48
44
  },
49
- ]
50
- : []),
51
- {
52
- type: 'checkbox' as const,
53
- label: 'Show timings',
54
- checked: model.showPerf,
55
- onClick: () => {
56
- model.setShowPerf(!model.showPerf)
57
- },
45
+ },
46
+ ]
47
+ : []),
48
+ {
49
+ type: 'checkbox' as const,
50
+ label: 'Show timings',
51
+ checked: model.showPerf,
52
+ onClick: () => {
53
+ model.setShowPerf(!model.showPerf)
58
54
  },
59
- ],
60
- },
61
- { type: 'divider' as const },
62
- {
63
- label: 'Graph settings...',
64
- icon: SettingsIcon,
65
- helpText:
66
- 'Subgraph node limit; node width and path colors; the force-directed layout engine',
67
- onClick: () => {
68
- setSettingsOpen(true)
69
55
  },
56
+ ],
57
+ },
58
+ { type: 'divider' as const },
59
+ {
60
+ label: 'Graph settings...',
61
+ icon: SettingsIcon,
62
+ helpText:
63
+ 'Subgraph node limit; node width and path colors; the force-directed layout engine',
64
+ onClick: () => {
65
+ getSession(model).queueDialog(onClose => [
66
+ GraphSettingsDialog,
67
+ { model, open: true, onClose },
68
+ ])
70
69
  },
71
- { type: 'divider' as const },
72
- {
73
- label: 'Close graph',
74
- icon: CloseIcon,
75
- onClick: () => {
76
- model.clearGraph()
77
- },
70
+ },
71
+ { type: 'divider' as const },
72
+ {
73
+ label: 'Close graph',
74
+ icon: CloseIcon,
75
+ onClick: () => {
76
+ model.clearGraph()
78
77
  },
79
- ]}
80
- >
81
- <MoreVertIcon />
82
- </CascadingMenuButton>
83
-
84
- <GraphSettingsDialog
85
- model={model}
86
- open={settingsOpen}
87
- onClose={() => {
88
- setSettingsOpen(false)
89
- }}
90
- />
91
- </>
78
+ },
79
+ ]}
80
+ >
81
+ <MoreVertIcon />
82
+ </CascadingMenuButton>
92
83
  )
93
84
  })
94
85
 
@@ -1,14 +1,13 @@
1
- import { useEffect, useRef } from 'react'
1
+ import { useCallback } from 'react'
2
2
 
3
- import { getDpr } from '@jbrowse/bandage-core/renderer/canvas'
4
3
  import { drawTubeMapRuler } from '@jbrowse/bandage-core/tubeMap/axis'
5
4
  import { drawTubeMapConnectors } from '@jbrowse/bandage-core/tubeMap/connectors'
6
5
  import { drawDeviationMarks } from '@jbrowse/bandage-core/tubeMap/deviations'
7
6
  import { drawTubeMap } from '@jbrowse/bandage-core/tubeMap/draw'
8
7
  import { drawTubeMapGenes } from '@jbrowse/bandage-core/tubeMap/genes'
9
- import { autorun } from 'mobx'
10
8
  import { observer } from 'mobx-react'
11
9
 
10
+ import { PaneOverlayCanvas } from './PaneLayer'
12
11
  import {
13
12
  PANEL_TITLE_FONT,
14
13
  drawBundleCounts,
@@ -20,14 +19,6 @@ const PANEL_TICK_ALPHA = 0.45
20
19
 
21
20
  import type { GraphPaneModel } from '../model'
22
21
 
23
- const canvasStyle = {
24
- position: 'absolute' as const,
25
- left: 0,
26
- top: 0,
27
- pointerEvents: 'none' as const,
28
- zIndex: 1,
29
- }
30
-
31
22
  // The tubes, their connectors, genes and ruler, onto a canvas sized to the
32
23
  // pane or onto the linear view's SVG export
33
24
  export function paintTubeMap(
@@ -50,7 +41,6 @@ export function paintTubeMap(
50
41
  ...frame,
51
42
  width,
52
43
  highlightNode,
53
- darkMode: model.darkMode,
54
44
  tubeColors: model.tubeMapTubeColors,
55
45
  nodeColors: model.tubeMapNodeColors,
56
46
  }
@@ -90,7 +80,6 @@ function paintPanels(
90
80
  highlightNode: string | null,
91
81
  ) {
92
82
  const width = model.paneWidth
93
- const ink = model.darkMode ? '255,255,255' : '0,0,0'
94
83
  for (const p of panels) {
95
84
  if (p.bottom < 0 || p.titleTop > model.canvasHeight) {
96
85
  continue
@@ -99,7 +88,6 @@ function paintPanels(
99
88
  ...p.frame,
100
89
  width,
101
90
  highlightNode,
102
- darkMode: model.darkMode,
103
91
  tubeColors: p.tubeColors,
104
92
  nodeColors: p.nodeColors,
105
93
  }
@@ -109,7 +97,7 @@ function paintPanels(
109
97
  ctx.globalAlpha = PANEL_TICK_ALPHA
110
98
  drawDeviationMarks(ctx, p.deviations, tubeFrame)
111
99
  ctx.globalAlpha = 1
112
- ctx.strokeStyle = `rgba(${ink},0.15)`
100
+ ctx.strokeStyle = 'rgba(0,0,0,0.15)'
113
101
  ctx.lineWidth = 1
114
102
  ctx.beginPath()
115
103
  ctx.moveTo(0, Math.round(p.titleTop) + 0.5)
@@ -118,7 +106,7 @@ function paintPanels(
118
106
  ctx.font = PANEL_TITLE_FONT
119
107
  ctx.textAlign = 'left'
120
108
  ctx.textBaseline = 'top'
121
- ctx.fillStyle = `rgba(${ink},0.85)`
109
+ ctx.fillStyle = 'rgba(0,0,0,0.85)'
122
110
  ctx.fillText(p.label, 6, p.titleTop + 4)
123
111
  }
124
112
  const last = panels.at(-1)
@@ -127,7 +115,7 @@ function paintPanels(
127
115
  drawTubeMapRuler(
128
116
  ctx,
129
117
  boxes,
130
- { ...last.frame, width, darkMode: model.darkMode },
118
+ { ...last.frame, width },
131
119
  last.bottom + 4,
132
120
  true,
133
121
  )
@@ -145,38 +133,19 @@ const TubeMapOverlay = observer(function TubeMapOverlay({
145
133
  }: {
146
134
  model: GraphPaneModel
147
135
  }) {
148
- const ref = useRef<HTMLCanvasElement>(null)
149
- const { tubeMapPicture, paneWidth, canvasHeight } = model
150
- useEffect(
151
- () =>
152
- autorun(() => {
153
- const canvas = ref.current
154
- const ctx = canvas?.getContext('2d')
155
- if (canvas && ctx && model.tubeMapPicture && model.tubeMapFrame) {
156
- const dpr = getDpr()
157
- const width = model.paneWidth
158
- const height = model.canvasHeight
159
- canvas.width = Math.round(width * dpr)
160
- canvas.height = Math.round(height * dpr)
161
- ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
162
- ctx.clearRect(0, 0, width, height)
163
- paintTubeMap(ctx, model, { highlightNode: model.selectedNode })
164
- }
165
- }),
136
+ const paint = useCallback(
137
+ (ctx: CanvasRenderingContext2D) => {
138
+ paintTubeMap(ctx, model, { highlightNode: model.selectedNode })
139
+ },
166
140
  [model],
167
141
  )
168
- // Mounted whether or not there is a tube map, so the autorun above has its
169
- // canvas the moment a layout brings one.
170
142
  return (
171
- <canvas
172
- ref={ref}
173
- data-testid={tubeMapPicture ? 'graph-tube-map' : undefined}
174
- style={{
175
- ...canvasStyle,
176
- width: paneWidth,
177
- height: canvasHeight,
178
- display: tubeMapPicture ? 'block' : 'none',
179
- }}
143
+ <PaneOverlayCanvas
144
+ model={model}
145
+ zIndex={1}
146
+ shown={!!model.tubeMapPicture}
147
+ testId="graph-tube-map"
148
+ paint={paint}
180
149
  />
181
150
  )
182
151
  })
@@ -1,21 +1,14 @@
1
- import { useEffect, useId, useMemo, useRef } from 'react'
1
+ import { useCallback, useMemo } from 'react'
2
2
 
3
- import { walkRowsTree } from '@jbrowse/bandage-core/layout/walkRowDraw'
4
- import { getDpr } from '@jbrowse/bandage-core/renderer/canvas'
5
- import { autorun, computed } from 'mobx'
3
+ import { computed } from 'mobx'
6
4
  import { observer } from 'mobx-react'
7
5
 
8
- import ElTree from './ElTree'
9
- import { SECTION_HEADER_PX } from '../walkRowGroups'
6
+ import ElTree, { useSvgId } from './ElTree'
7
+ import { PaneOverlayCanvas, PaneSvgLayer } from './PaneLayer'
8
+ import { SECTION_HEADER_PX, walkRowTrees } from '../walkRowGroups'
10
9
  import { paintWalkRowSpans, walkRowSpans } from '../walkRowSpans'
11
10
 
12
11
  import type { GraphPaneModel } from '../model'
13
- import type { WalkRowSection } from '../walkRowGroups'
14
- import type { El } from '@jbrowse/bandage-core/el'
15
- import type {
16
- WalkRowsFrame,
17
- WalkRowsWithCalls,
18
- } from '@jbrowse/bandage-core/layout/walkRowDraw'
19
12
 
20
13
  // The walk-rows layout's bars: one per haplotype walk under the reference
21
14
  // row, each on its own bp axis from the window's left edge. The runs paint as
@@ -32,96 +25,31 @@ import type {
32
25
  // repeats/walkCalls.ts, which also holds the threshold a red readout is read
33
26
  // off. Colouring each copy by its unit is jbrowse-plugin-tandem-repeat's.
34
27
 
35
- const svgStyle = {
36
- position: 'absolute' as const,
37
- left: 0,
38
- top: 0,
39
- pointerEvents: 'none' as const,
40
- overflow: 'visible' as const,
41
- zIndex: 3,
42
- }
43
-
44
- // The rows' trees, a section at a time while grouped. walkRowsTree puts its
45
- // i-th row at i * rowPx below its reference row and draws that row too, so
46
- // each section is drawn shifted down to its place with its reference row
47
- // dropped.
48
- export function walkRowTrees(
49
- bars: WalkRowsWithCalls,
50
- sections: WalkRowSection[],
51
- rowY: (i: number) => number,
52
- frame: WalkRowsFrame & { rowPx: number },
53
- o: Parameters<typeof walkRowsTree>[2] & { idPrefix: string },
54
- ): El[] {
55
- if (sections.length === 0) {
56
- return [walkRowsTree(bars, frame, o)]
57
- }
58
- return [
59
- walkRowsTree({ ...bars, rows: [] }, frame, o),
60
- ...sections.flatMap((section, k) => {
61
- const tree = walkRowsTree(
62
- {
63
- ...bars,
64
- rows: bars.rows.slice(
65
- section.first - 1,
66
- section.first - 1 + section.count,
67
- ),
68
- },
69
- {
70
- ...frame,
71
- translateY:
72
- frame.translateY +
73
- (rowY(section.first) - frame.rowPx) * frame.scaleY,
74
- },
75
- { ...o, idPrefix: `${o.idPrefix}-s${k}` },
76
- )
77
- return tree.children.filter(
78
- (c): c is El =>
79
- typeof c !== 'string' &&
80
- c.attrs['data-testid'] !== 'graph-walk-reference',
81
- )
82
- }),
83
- ]
84
- }
85
-
86
- const canvasStyle = { ...svgStyle, overflow: undefined }
87
-
88
- // Repainted by an autorun, as the other overlay canvases are, so a pan moves
89
- // the bars in the same frame as the drawing. The spans are recut only when
90
- // the rows, the zoom or the ramp change.
91
- const WalkRowSpansCanvas = observer(function WalkRowSpansCanvas({
92
- model,
93
- }: {
94
- model: GraphPaneModel
95
- }) {
96
- const ref = useRef<HTMLCanvasElement>(null)
97
- useEffect(() => {
98
- const spans = computed(() => {
99
- const bars = model.walkRowBars
100
- return bars
101
- ? walkRowSpans(
102
- [bars.reference, ...bars.rows],
103
- model.scaleX,
104
- model.referenceRampDomain,
105
- )
106
- : undefined
107
- })
108
- return autorun(() => {
109
- const canvas = ref.current
110
- const ctx = canvas?.getContext('2d')
28
+ // The spans are recut only when the rows, the zoom or the ramp change
29
+ function WalkRowSpansCanvas({ model }: { model: GraphPaneModel }) {
30
+ const spans = useMemo(
31
+ () =>
32
+ computed(() => {
33
+ const bars = model.walkRowBars
34
+ return bars
35
+ ? walkRowSpans(
36
+ [bars.reference, ...bars.rows],
37
+ model.scaleX,
38
+ model.referenceRampDomain,
39
+ )
40
+ : undefined
41
+ }),
42
+ [model],
43
+ )
44
+ const paint = useCallback(
45
+ (ctx: CanvasRenderingContext2D) => {
111
46
  const bars = model.walkRowBars
112
47
  const place = model.walkRowPlacement
113
48
  const pitch = model.walkRowPitch
114
49
  const painted = spans.get()
115
- if (!canvas || !ctx || !bars || !place || !pitch || !painted) {
50
+ if (!bars || !place || !pitch || !painted) {
116
51
  return
117
52
  }
118
- const width = model.paneWidth
119
- const height = model.canvasHeight
120
- const dpr = getDpr()
121
- canvas.width = Math.round(width * dpr)
122
- canvas.height = Math.round(height * dpr)
123
- ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
124
- ctx.clearRect(0, 0, width, height)
125
53
  const sections = model.walkRowGroups?.sections
126
54
  const blocks = sections?.length
127
55
  ? [
@@ -134,31 +62,26 @@ const WalkRowSpansCanvas = observer(function WalkRowSpansCanvas({
134
62
  ]
135
63
  : [{ first: 0, count: bars.rows.length + 1, rowY: place.rowY(0) }]
136
64
  paintWalkRowSpans(ctx, painted, {
137
- scaleX: model.scaleX,
138
- scaleY: model.scaleY,
139
- translateX: model.translateX,
140
- translateY: model.translateY,
141
- width,
142
- height,
65
+ ...model.screenTransform,
66
+ width: model.paneWidth,
67
+ height: model.canvasHeight,
143
68
  rowPx: pitch.rowPx,
144
69
  barPx: pitch.barPx,
145
70
  origin: bars.origin,
146
71
  blocks,
147
72
  })
148
- })
149
- }, [model])
73
+ },
74
+ [model, spans],
75
+ )
150
76
  return (
151
- <canvas
152
- ref={ref}
153
- data-testid="graph-walk-rows-spans"
154
- style={{
155
- ...canvasStyle,
156
- width: model.paneWidth,
157
- height: model.canvasHeight,
158
- }}
77
+ <PaneOverlayCanvas
78
+ model={model}
79
+ zIndex={3}
80
+ testId="graph-walk-rows-spans"
81
+ paint={paint}
159
82
  />
160
83
  )
161
- })
84
+ }
162
85
 
163
86
  // `vector` for an SVG export, which draws the bars as walkRowsTree's rects
164
87
  const WalkRowsOverlay = observer(function WalkRowsOverlay({
@@ -168,7 +91,7 @@ const WalkRowsOverlay = observer(function WalkRowsOverlay({
168
91
  model: GraphPaneModel
169
92
  vector?: boolean
170
93
  }) {
171
- const idPrefix = useId().replace(/[^\w-]/g, '')
94
+ const idPrefix = useSvgId()
172
95
  const bars = model.walkRowBars
173
96
  const place = model.walkRowPlacement
174
97
  const pitch = model.walkRowPitch
@@ -185,19 +108,20 @@ const WalkRowsOverlay = observer(function WalkRowsOverlay({
185
108
  return null
186
109
  }
187
110
  const { paneWidth: width, canvasHeight } = model
188
- const Y = (y: number) => y * model.scaleY + model.translateY
189
111
  const hovered = model.hoveredWalkRowText
190
112
  ? [bars.reference, ...bars.rows].findIndex(
191
113
  r => r.name === model.hoveredWalkRow,
192
114
  )
193
115
  : -1
194
- const row =
195
- hovered >= 0 ? [bars.reference, ...bars.rows][hovered]! : undefined
116
+ const lit =
117
+ hovered >= 0
118
+ ? {
119
+ row: [bars.reference, ...bars.rows][hovered]!,
120
+ start: model.toScreen({ x: bars.origin, y: place.rowY(hovered) }),
121
+ }
122
+ : undefined
196
123
  const frame = {
197
- scaleX: model.scaleX,
198
- scaleY: model.scaleY,
199
- translateX: model.translateX,
200
- translateY: model.translateY,
124
+ ...model.screenTransform,
201
125
  width,
202
126
  height: canvasHeight,
203
127
  ...pitch,
@@ -205,11 +129,11 @@ const WalkRowsOverlay = observer(function WalkRowsOverlay({
205
129
  return (
206
130
  <>
207
131
  {vector ? null : <WalkRowSpansCanvas model={model} />}
208
- <svg
209
- style={svgStyle}
210
- width={width}
211
- height={canvasHeight}
212
- data-testid="graph-walk-rows"
132
+ <PaneSvgLayer
133
+ model={model}
134
+ zIndex={3}
135
+ overflow="visible"
136
+ testId="graph-walk-rows"
213
137
  >
214
138
  {walkRowTrees(
215
139
  vector ? bars : bare,
@@ -228,7 +152,9 @@ const WalkRowsOverlay = observer(function WalkRowsOverlay({
228
152
  <text
229
153
  key={header.key}
230
154
  x={10}
231
- y={Y(header.top) + SECTION_HEADER_PX - 4}
155
+ y={
156
+ model.toScreen({ x: 0, y: header.top }).y + SECTION_HEADER_PX - 4
157
+ }
232
158
  fontFamily="sans-serif"
233
159
  fontSize={11}
234
160
  fontWeight="bold"
@@ -238,19 +164,19 @@ const WalkRowsOverlay = observer(function WalkRowsOverlay({
238
164
  {header.title}
239
165
  </text>
240
166
  ))}
241
- {row ? (
167
+ {lit ? (
242
168
  <rect
243
169
  data-testid="graph-walk-row-hovered"
244
- x={bars.origin * model.scaleX + model.translateX - 2}
245
- y={Y(place.rowY(hovered)) - pitch.rowPx / 2 - 1}
246
- width={row.bp * model.scaleX + 4}
170
+ x={lit.start.x - 2}
171
+ y={lit.start.y - pitch.rowPx / 2 - 1}
172
+ width={lit.row.bp * model.scaleX + 4}
247
173
  height={pitch.rowPx + 2}
248
174
  fill="none"
249
175
  stroke="#111"
250
176
  strokeWidth={1}
251
177
  />
252
178
  ) : null}
253
- </svg>
179
+ </PaneSvgLayer>
254
180
  </>
255
181
  )
256
182
  })
@@ -1,4 +1,4 @@
1
- import { useId, useMemo, useState } from 'react'
1
+ import { useMemo, useState } from 'react'
2
2
 
3
3
  import {
4
4
  walkRowReadout,
@@ -15,9 +15,9 @@ import { RAMP_GRADIENT_CSS } from '@jbrowse/bandage-core/referenceRampCss'
15
15
  import { isAlive } from '@jbrowse/mobx-state-tree'
16
16
  import { observer } from 'mobx-react'
17
17
 
18
- import ElTree from './ElTree'
18
+ import ElTree, { useSvgId } from './ElTree'
19
19
  import { LegendSwatchView } from './Legend'
20
- import { WalkRowContextMenu } from './WalkRowContextMenu'
20
+ import PaneContextMenu from './PaneContextMenu'
21
21
  import { legendRowStyle } from './legendStyles'
22
22
  import { walkRowSwatch } from '../legendSections'
23
23
 
@@ -67,7 +67,7 @@ const StripBars = observer(function StripBars({
67
67
  ramp: { start: number; end: number } | undefined
68
68
  rowGenes: Map<string, RowGene[]> | undefined
69
69
  }) {
70
- const idPrefix = useId().replace(/[^\w-]/g, '')
70
+ const idPrefix = useSvgId()
71
71
  const tree = useMemo(
72
72
  () => walkRowsTree(bars, frame, { ramp, rowGenes, idPrefix }),
73
73
  [bars, frame, ramp, rowGenes, idPrefix],
@@ -115,9 +115,11 @@ const WalkStrip = observer(function WalkStrip({
115
115
  }) {
116
116
  const bars = model.walkStripRows
117
117
  const frame = model.walkStripFrame
118
- const [menu, setMenu] = useState<
119
- { row: number; top: number; left: number } | undefined
120
- >(undefined)
118
+ const [menu, setMenu] = useState<{
119
+ clientX: number
120
+ clientY: number
121
+ row: number
122
+ }>()
121
123
  if (!bars || !frame) {
122
124
  return null
123
125
  }
@@ -165,7 +167,7 @@ const WalkStrip = observer(function WalkStrip({
165
167
  const at = hit(e)
166
168
  if (at) {
167
169
  e.preventDefault()
168
- setMenu({ row: at.index, top: e.clientY, left: e.clientX })
170
+ setMenu({ clientX: e.clientX, clientY: e.clientY, row: at.index })
169
171
  }
170
172
  }}
171
173
  >
@@ -197,18 +199,13 @@ const WalkStrip = observer(function WalkStrip({
197
199
  </div>
198
200
  ))}
199
201
  </div>
200
- {menu ? (
201
- <WalkRowContextMenu
202
- model={model}
203
- row={menu.row}
204
- bars={bars}
205
- top={menu.top}
206
- left={menu.left}
207
- onClose={() => {
208
- setMenu(undefined)
209
- }}
210
- />
211
- ) : null}
202
+ <PaneContextMenu
203
+ model={model}
204
+ at={menu && { ...menu, bars }}
205
+ onClose={() => {
206
+ setMenu(undefined)
207
+ }}
208
+ />
212
209
  </div>
213
210
  )
214
211
  })
@@ -1,15 +1,8 @@
1
1
  import { observer } from 'mobx-react'
2
2
 
3
- import type { GraphPaneModel } from '../model'
3
+ import { PaneSvgLayer } from './PaneLayer'
4
4
 
5
- const svgStyle = {
6
- position: 'absolute' as const,
7
- left: 0,
8
- top: 0,
9
- pointerEvents: 'none' as const,
10
- overflow: 'visible' as const,
11
- zIndex: 4,
12
- }
5
+ import type { GraphPaneModel } from '../model'
13
6
 
14
7
  // A ring round the node a point on the walk strip lights, so a one-bp node
15
8
  // can be found in a hairball
@@ -20,11 +13,11 @@ const WalkStripLocator = observer(function WalkStripLocator({
20
13
  }) {
21
14
  const at = model.walkStripLocator
22
15
  return at ? (
23
- <svg
24
- style={svgStyle}
25
- width={model.paneWidth}
26
- height={model.canvasHeight}
27
- data-testid="graph-walk-strip-locator"
16
+ <PaneSvgLayer
17
+ model={model}
18
+ zIndex={4}
19
+ overflow="visible"
20
+ testId="graph-walk-strip-locator"
28
21
  >
29
22
  <circle
30
23
  cx={at.x}
@@ -42,7 +35,7 @@ const WalkStripLocator = observer(function WalkStripLocator({
42
35
  stroke="#111"
43
36
  strokeWidth={1.75}
44
37
  />
45
- </svg>
38
+ </PaneSvgLayer>
46
39
  ) : null
47
40
  })
48
41