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
@@ -35,6 +35,7 @@ import { HOVER_HIGHLIGHT_VALUES } from '../hoverHighlight'
35
35
  import { TUBE_MAP_PANELS, tubeMapPanelGroups } from '../tubeMapPanels'
36
36
 
37
37
  import type { GraphLocation } from '../../launchFromGraph/contributors'
38
+ import type { GraphLayer } from '../graphLayers'
38
39
  import type { TubeMapPanelSplit } from '../tubeMapPanels'
39
40
  import type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'
40
41
  import type { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'
@@ -48,6 +49,22 @@ const ENGINE_NAMES: readonly (readonly [LayoutEngineKind, string])[] = [
48
49
  const layoutMenuLabel = (mode: { label: string }) =>
49
50
  mode.label.replace(/ layout$/, '')
50
51
 
52
+ function radioItems<T>(
53
+ options: readonly { value: T; label: string; disabled?: boolean }[],
54
+ current: T | undefined,
55
+ onPick: (value: T) => void,
56
+ ): MenuItem[] {
57
+ return options.map(({ value, label, disabled }) => ({
58
+ type: 'radio',
59
+ label,
60
+ disabled,
61
+ checked: value === current,
62
+ onClick: () => {
63
+ onPick(value)
64
+ },
65
+ }))
66
+ }
67
+
51
68
  export const withLaunchActions = withRenderingActions
52
69
  .actions(self => ({
53
70
  // Move the linear view already on screen, or open one if there is none,
@@ -156,24 +173,16 @@ export const withLaunchActions = withRenderingActions
156
173
  // Which sample table column walk rows stack into sections by
157
174
  walkRowGroupMenuItems(): MenuItem[] {
158
175
  const field = self.walkRowGroups ? self.walkRowGroupBy?.field : undefined
159
- return [
160
- {
161
- type: 'radio',
162
- label: 'None',
163
- checked: field === undefined,
164
- onClick: () => {
165
- self.setWalkRowGroupBy(undefined)
166
- },
176
+ return radioItems(
177
+ [
178
+ { value: undefined, label: 'None' },
179
+ ...self.walkRowGroupFields.map(c => ({ value: c, label: c })),
180
+ ],
181
+ field,
182
+ c => {
183
+ self.setWalkRowGroupBy(c === undefined ? undefined : { field: c })
167
184
  },
168
- ...self.walkRowGroupFields.map(column => ({
169
- type: 'radio' as const,
170
- label: column,
171
- checked: field === column,
172
- onClick: () => {
173
- self.setWalkRowGroupBy({ field: column })
174
- },
175
- })),
176
- ]
185
+ )
177
186
  },
178
187
  // A tube map's panels: none, a sample's or a walk's each, or a group of
179
188
  // samples' each by a column of the source track's sample table
@@ -184,28 +193,32 @@ export const withLaunchActions = withRenderingActions
184
193
  const splits = (split: TubeMapPanelSplit) =>
185
194
  !!graph && tubeMapPanelGroups(graph, split).length > 1
186
195
  return [
187
- ...TUBE_MAP_PANELS.map(item => ({
188
- type: 'radio' as const,
189
- label: item.label,
190
- checked: item.field === field && (field !== '' || !column),
191
- disabled: item.field !== '' && !splits({ by: item.field }),
192
- onClick: () => {
193
- self.setFacet(item.field)
194
- if (item.field === '') {
196
+ ...radioItems(
197
+ TUBE_MAP_PANELS.map(item => ({
198
+ value: item.field,
199
+ label: item.label,
200
+ disabled: item.field !== '' && !splits({ by: item.field }),
201
+ })),
202
+ column ? undefined : field,
203
+ by => {
204
+ self.setFacet(by)
205
+ if (by === '') {
195
206
  self.setWalkRowGroupBy(undefined)
196
207
  }
197
208
  },
198
- })),
199
- ...self.walkRowGroupFields.map(c => ({
200
- type: 'radio' as const,
201
- label: `By ${c}`,
202
- checked: column === c,
203
- disabled: !table || !splits({ by: 'column', field: c, table }),
204
- onClick: () => {
209
+ ),
210
+ ...radioItems(
211
+ self.walkRowGroupFields.map(c => ({
212
+ value: c,
213
+ label: `By ${c}`,
214
+ disabled: !table || !splits({ by: 'column', field: c, table }),
215
+ })),
216
+ column,
217
+ c => {
205
218
  self.setFacet('')
206
219
  self.setWalkRowGroupBy({ field: c })
207
220
  },
208
- })),
221
+ ),
209
222
  ]
210
223
  },
211
224
  // `repeat` false where a toolbar already picks the repeat
@@ -215,16 +228,16 @@ export const withLaunchActions = withRenderingActions
215
228
  ? [
216
229
  {
217
230
  label: 'Fold variants',
218
- subMenu: TUBE_MAP_FOLDS.map(({ bp, label }) => ({
219
- type: 'radio' as const,
220
- label,
221
- // reads are placed by the cut's names, which a fold renames
222
- checked: (self.graph?.reads ? 0 : self.tubeMapFold) === bp,
223
- disabled: bp > 0 && self.graph?.reads !== undefined,
224
- onClick: () => {
225
- self.setTubeMapFold(bp)
226
- },
227
- })),
231
+ // reads are placed by the cut's names, which a fold renames
232
+ subMenu: radioItems(
233
+ TUBE_MAP_FOLDS.map(({ bp, label }) => ({
234
+ value: bp,
235
+ label,
236
+ disabled: bp > 0 && self.graph?.reads !== undefined,
237
+ })),
238
+ self.graph?.reads ? 0 : self.tubeMapFold,
239
+ self.setTubeMapFold,
240
+ ),
228
241
  },
229
242
  {
230
243
  label: 'Panels',
@@ -232,27 +245,24 @@ export const withLaunchActions = withRenderingActions
232
245
  },
233
246
  {
234
247
  label: 'Routes',
235
- subMenu: TUBE_MAP_ROUTES.map(({ value, label }) => ({
236
- type: 'radio' as const,
237
- label,
238
- checked: self.tubeMapRoutes === value,
239
- onClick: () => {
240
- self.setTubeMapRoutes(value)
241
- },
242
- })),
248
+ subMenu: radioItems(
249
+ TUBE_MAP_ROUTES,
250
+ self.tubeMapRoutes,
251
+ self.setTubeMapRoutes,
252
+ ),
243
253
  },
244
254
  ...(self.walkRowGroupFields.length > 0
245
255
  ? [
246
256
  {
247
257
  label: 'Tube color',
248
- subMenu: ['', ...self.walkRowGroupFields].map(field => ({
249
- type: 'radio' as const,
250
- label: field ? `By ${field}` : 'By role',
251
- checked: self.tubeMapColorBy === field,
252
- onClick: () => {
253
- self.setTubeMapColorBy(field)
254
- },
255
- })),
258
+ subMenu: radioItems(
259
+ ['', ...self.walkRowGroupFields].map(field => ({
260
+ value: field,
261
+ label: field ? `By ${field}` : 'By role',
262
+ })),
263
+ self.tubeMapColorBy,
264
+ self.setTubeMapColorBy,
265
+ ),
256
266
  },
257
267
  ]
258
268
  : []),
@@ -264,24 +274,17 @@ export const withLaunchActions = withRenderingActions
264
274
  ? [
265
275
  {
266
276
  label: 'Repeat',
267
- subMenu: [
268
- {
269
- type: 'radio' as const,
270
- label: 'Whole window',
271
- checked: !self.selectedRepeat,
272
- onClick: () => {
273
- self.setRepeatKey('')
274
- },
275
- },
276
- ...self.repeatChoices.map(({ key, name, unit }) => ({
277
- type: 'radio' as const,
278
- label: `${name} · ${unit.toLocaleString()} bp unit`,
279
- checked: self.repeatKey === key,
280
- onClick: () => {
281
- self.setRepeatKey(key)
282
- },
283
- })),
284
- ],
277
+ subMenu: radioItems(
278
+ [
279
+ { value: '', label: 'Whole window' },
280
+ ...self.repeatChoices.map(({ key, name, unit }) => ({
281
+ value: key,
282
+ label: `${name} · ${unit.toLocaleString()} bp unit`,
283
+ })),
284
+ ],
285
+ self.selectedRepeat?.key ?? '',
286
+ self.setRepeatKey,
287
+ ),
285
288
  },
286
289
  ]
287
290
  : []),
@@ -296,53 +299,31 @@ export const withLaunchActions = withRenderingActions
296
299
  ]
297
300
  },
298
301
  showMenuItems(): MenuItem[] {
299
- return [
300
- {
301
- type: 'checkbox',
302
- label: 'Show bubble halos',
303
- checked: self.showBubbles,
304
- onClick: () => {
305
- self.setShowBubbles(!self.showBubbles)
306
- },
307
- },
308
- {
309
- type: 'checkbox',
310
- label: 'Show deletion edges',
311
- checked: self.showDeletionEdges,
312
- onClick: () => {
313
- void self.toggleDeletionEdges()
314
- },
302
+ const layerItem = (label: string, layer: GraphLayer) => ({
303
+ type: 'checkbox' as const,
304
+ label,
305
+ checked: self.layerSet.has(layer),
306
+ onClick: () => {
307
+ self.setLayer(layer, !self.layerSet.has(layer))
315
308
  },
309
+ })
310
+ return [
311
+ layerItem('Show bubble halos', 'bubbles'),
312
+ layerItem('Show deletion edges', 'deletions'),
316
313
  {
317
314
  label: 'Hover highlight',
318
- subMenu: HOVER_HIGHLIGHT_VALUES.map(value => ({
319
- type: 'radio' as const,
320
- label: value[0]!.toUpperCase() + value.slice(1),
321
- checked: self.chosenHover === value,
322
- onClick: () => {
323
- self.setHover(value)
324
- },
325
- })),
326
- },
327
- {
328
- type: 'checkbox',
329
- label: 'Show genes on the backbone',
330
- checked: self.showGenes,
331
- onClick: () => {
332
- self.setShowGenes(!self.showGenes)
333
- },
315
+ subMenu: radioItems(
316
+ HOVER_HIGHLIGHT_VALUES.map(value => ({
317
+ value,
318
+ label: value[0]!.toUpperCase() + value.slice(1),
319
+ })),
320
+ self.chosenHover,
321
+ self.setHover,
322
+ ),
334
323
  },
324
+ layerItem('Show genes on the backbone', 'genes'),
335
325
  ...(self.referenceStripApplies
336
- ? [
337
- {
338
- type: 'checkbox' as const,
339
- label: 'Show reference strip',
340
- checked: self.showReferenceStrip,
341
- onClick: () => {
342
- self.setShowReferenceStrip(!self.showReferenceStrip)
343
- },
344
- },
345
- ]
326
+ ? [layerItem('Show reference strip', 'referenceStrip')]
346
327
  : []),
347
328
  ]
348
329
  },
@@ -448,14 +429,14 @@ export const withLaunchActions = withRenderingActions
448
429
  ...(self.walkLayers.length > 1 && self.modeDrawsNodes
449
430
  ? [
450
431
  { type: 'subHeader' as const, label: 'Arrange' },
451
- ...FACET_FIELDS.map(({ value, label }) => ({
452
- type: 'radio' as const,
453
- label: value === 'walk' ? 'A panel per haplotype' : label,
454
- checked: self.facetSetting.field === value,
455
- onClick: () => {
456
- self.setFacet(value)
457
- },
458
- })),
432
+ ...radioItems(
433
+ FACET_FIELDS.map(({ value, label }) => ({
434
+ value,
435
+ label: value === 'walk' ? 'A panel per haplotype' : label,
436
+ })),
437
+ self.facetSetting.field,
438
+ self.setFacet,
439
+ ),
459
440
  ]
460
441
  : []),
461
442
  ]
@@ -489,10 +470,7 @@ export const withLaunchActions = withRenderingActions
489
470
  self.chosenLayoutMode === mode.value &&
490
471
  self.layoutEngine === engine,
491
472
  onClick: () => {
492
- self.setLayoutEngine(engine)
493
- void (self.chosenLayoutMode === mode.value
494
- ? self.recomputeLayout()
495
- : self.switchLayout(mode.value))
473
+ void self.switchForceEngine(engine)
496
474
  },
497
475
  }))
498
476
  : [
@@ -527,14 +505,14 @@ export const withLaunchActions = withRenderingActions
527
505
  icon: PaletteIcon,
528
506
  disabled: self.colorSchemeLock !== undefined,
529
507
  disabledHelpText: self.colorSchemeLock?.why,
530
- subMenu: COLOR_SCHEMES.map(scheme => ({
531
- type: 'radio' as const,
532
- label: this.colorSchemeLabel(scheme.value),
533
- checked: self.chosenColorScheme === scheme.value,
534
- onClick: () => {
535
- self.setColorScheme(scheme.value)
536
- },
537
- })),
508
+ subMenu: radioItems(
509
+ COLOR_SCHEMES.map(({ value }) => ({
510
+ value,
511
+ label: this.colorSchemeLabel(value),
512
+ })),
513
+ self.chosenColorScheme,
514
+ self.setColorScheme,
515
+ ),
538
516
  },
539
517
  {
540
518
  label: 'Show...',
@@ -2,8 +2,7 @@ import {
2
2
  backboneNodes,
3
3
  backboneSpan,
4
4
  } from '@jbrowse/bandage-core/anchoredNodes'
5
- import { readConfObject } from '@jbrowse/core/configuration'
6
- import { getContainingView, getSession } from '@jbrowse/core/util'
5
+ import { getSession } from '@jbrowse/core/util'
7
6
 
8
7
  import { withGraphViews } from './graphViews'
9
8
  import {
@@ -13,7 +12,6 @@ import {
13
12
  resolveLocationAssembly,
14
13
  } from '../../launchFromGraph/contributors'
15
14
  import {
16
- canonicalAssemblyName,
17
15
  paddedLocation,
18
16
  withReferenceRegion,
19
17
  } from '../../launchFromGraph/launchFromGraph'
@@ -29,12 +27,7 @@ export const withLaunchViews = withGraphViews
29
27
  // that view's window and the cut is re-made when the window leaves it.
30
28
  // A pane that is a view of its own has none.
31
29
  get host(): LinearHost | undefined {
32
- let view: unknown
33
- try {
34
- view = getContainingView(self)
35
- } catch {
36
- return undefined
37
- }
30
+ const view = self.containingView
38
31
  return isLinearHost(view) ? view : undefined
39
32
  },
40
33
  }))
@@ -93,24 +86,12 @@ export const withLaunchViews = withGraphViews
93
86
  // backbone's is, so a walk row can read its haplotype's own annotation.
94
87
  // One pass over the tracks, not one per row.
95
88
  get geneTracksByAssembly() {
96
- const byAssembly = new Map<
97
- string,
98
- { trackId: string; name: string; adapterType: string }[]
99
- >()
100
- for (const t of getSession(self).tracks) {
101
- const adapterType = (readConfObject(t, 'adapter') as { type: string })
102
- .type
103
- if (!GENE_ADAPTER_TYPES.has(adapterType)) {
104
- continue
105
- }
106
- const track = {
107
- trackId: t.trackId as string,
108
- name: readConfObject(t, 'name') as string,
109
- adapterType,
110
- }
111
- for (const name of readConfObject(t, 'assemblyNames') as string[]) {
112
- const asm = canonicalAssemblyName(getSession(self), name)
113
- byAssembly.set(asm, [...(byAssembly.get(asm) ?? []), track])
89
+ const byAssembly = new Map<string, typeof self.sessionTracks>()
90
+ for (const track of self.sessionTracks) {
91
+ if (GENE_ADAPTER_TYPES.has(track.adapterType)) {
92
+ for (const asm of track.assemblies) {
93
+ byAssembly.set(asm, [...(byAssembly.get(asm) ?? []), track])
94
+ }
114
95
  }
115
96
  }
116
97
  return new Map(