@jbrowse/plugin-linear-genome-view 2.3.4 → 2.4.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 (271) hide show
  1. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +2 -3
  2. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +4 -4
  3. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js.map +1 -1
  4. package/dist/BaseLinearDisplay/components/Block.js +1 -1
  5. package/dist/BaseLinearDisplay/components/Block.js.map +1 -1
  6. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +11 -11
  7. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  8. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +82 -7
  9. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +43 -28
  10. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  11. package/dist/BaseLinearDisplay/models/configSchema.js +8 -0
  12. package/dist/BaseLinearDisplay/models/configSchema.js.map +1 -1
  13. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +1 -1
  14. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +9 -5
  15. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  16. package/dist/BaseLinearDisplay/models/util.js +2 -2
  17. package/dist/BaseLinearDisplay/models/util.js.map +1 -1
  18. package/dist/LaunchLinearGenomeView/index.js +1 -1
  19. package/dist/LaunchLinearGenomeView/index.js.map +1 -1
  20. package/dist/LinearBareDisplay/index.d.ts +2 -3
  21. package/dist/LinearBareDisplay/index.js +4 -2
  22. package/dist/LinearBareDisplay/index.js.map +1 -1
  23. package/dist/LinearBareDisplay/model.d.ts +61 -3
  24. package/dist/LinearBasicDisplay/index.d.ts +2 -3
  25. package/dist/LinearBasicDisplay/index.js +4 -2
  26. package/dist/LinearBasicDisplay/index.js.map +1 -1
  27. package/dist/LinearBasicDisplay/model.d.ts +82 -14
  28. package/dist/LinearGenomeView/components/CenterLine.js +2 -2
  29. package/dist/LinearGenomeView/components/CenterLine.js.map +1 -1
  30. package/dist/LinearGenomeView/components/Cytobands.d.ts +118 -0
  31. package/dist/LinearGenomeView/components/Cytobands.js +92 -0
  32. package/dist/LinearGenomeView/components/Cytobands.js.map +1 -0
  33. package/dist/LinearGenomeView/components/ExportSvgDialog.d.ts +1 -1
  34. package/dist/LinearGenomeView/components/ExportSvgDialog.js +24 -3
  35. package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
  36. package/dist/LinearGenomeView/components/Gridlines.js +1 -1
  37. package/dist/LinearGenomeView/components/Gridlines.js.map +1 -1
  38. package/dist/LinearGenomeView/components/Header.js +3 -4
  39. package/dist/LinearGenomeView/components/Header.js.map +1 -1
  40. package/dist/LinearGenomeView/components/ImportForm.d.ts +2 -2
  41. package/dist/LinearGenomeView/components/ImportForm.js +15 -19
  42. package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
  43. package/dist/LinearGenomeView/components/LinearGenomeView.js +1 -1
  44. package/dist/LinearGenomeView/components/MiniControls.js +5 -4
  45. package/dist/LinearGenomeView/components/MiniControls.js.map +1 -1
  46. package/dist/LinearGenomeView/components/OverviewRubberband.d.ts +3 -4
  47. package/dist/LinearGenomeView/components/OverviewRubberband.js +8 -11
  48. package/dist/LinearGenomeView/components/OverviewRubberband.js.map +1 -1
  49. package/dist/LinearGenomeView/components/OverviewScalebar.d.ts +4 -119
  50. package/dist/LinearGenomeView/components/OverviewScalebar.js +19 -103
  51. package/dist/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
  52. package/dist/LinearGenomeView/components/RefNameAutocomplete.d.ts +2 -1
  53. package/dist/LinearGenomeView/components/RefNameAutocomplete.js +35 -31
  54. package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  55. package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +2 -2
  56. package/dist/LinearGenomeView/components/RubberbandSpan.js +4 -18
  57. package/dist/LinearGenomeView/components/RubberbandSpan.js.map +1 -1
  58. package/dist/LinearGenomeView/components/SearchBox.js +3 -3
  59. package/dist/LinearGenomeView/components/SearchBox.js.map +1 -1
  60. package/dist/LinearGenomeView/components/TrackLabel.js +6 -7
  61. package/dist/LinearGenomeView/components/TrackLabel.js.map +1 -1
  62. package/dist/LinearGenomeView/components/TracksContainer.d.ts +2 -3
  63. package/dist/LinearGenomeView/components/TracksContainer.js +9 -8
  64. package/dist/LinearGenomeView/components/TracksContainer.js.map +1 -1
  65. package/dist/LinearGenomeView/components/ZoomControls.js +5 -4
  66. package/dist/LinearGenomeView/components/ZoomControls.js.map +1 -1
  67. package/dist/LinearGenomeView/components/hooks.d.ts +6 -1
  68. package/dist/LinearGenomeView/components/hooks.js +1 -1
  69. package/dist/LinearGenomeView/components/hooks.js.map +1 -1
  70. package/dist/LinearGenomeView/components/util.d.ts +6 -0
  71. package/dist/LinearGenomeView/components/util.js +11 -1
  72. package/dist/LinearGenomeView/components/util.js.map +1 -1
  73. package/dist/LinearGenomeView/index.js +8 -6
  74. package/dist/LinearGenomeView/index.js.map +1 -1
  75. package/dist/LinearGenomeView/model.d.ts +18 -12
  76. package/dist/LinearGenomeView/model.js +31 -34
  77. package/dist/LinearGenomeView/model.js.map +1 -1
  78. package/dist/LinearGenomeView/svgcomponents/SVGBackground.d.ts +6 -0
  79. package/dist/LinearGenomeView/svgcomponents/SVGBackground.js +13 -0
  80. package/dist/LinearGenomeView/svgcomponents/SVGBackground.js.map +1 -0
  81. package/dist/LinearGenomeView/svgcomponents/SVGHeader.d.ts +10 -0
  82. package/dist/LinearGenomeView/svgcomponents/SVGHeader.js +55 -0
  83. package/dist/LinearGenomeView/svgcomponents/SVGHeader.js.map +1 -0
  84. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
  85. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +57 -0
  86. package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +1 -0
  87. package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +8 -0
  88. package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +13 -0
  89. package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.js.map +1 -0
  90. package/dist/LinearGenomeView/svgcomponents/SVGRuler.d.ts +8 -0
  91. package/dist/LinearGenomeView/svgcomponents/SVGRuler.js +51 -0
  92. package/dist/LinearGenomeView/svgcomponents/SVGRuler.js.map +1 -0
  93. package/dist/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +8 -0
  94. package/dist/LinearGenomeView/svgcomponents/SVGScalebar.js +22 -0
  95. package/dist/LinearGenomeView/svgcomponents/SVGScalebar.js.map +1 -0
  96. package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +8 -0
  97. package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js +16 -0
  98. package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +1 -0
  99. package/dist/LinearGenomeView/svgcomponents/SVGTracks.d.ts +23 -0
  100. package/dist/LinearGenomeView/svgcomponents/SVGTracks.js +30 -0
  101. package/dist/LinearGenomeView/svgcomponents/SVGTracks.js.map +1 -0
  102. package/dist/LinearGenomeView/util.js +2 -2
  103. package/dist/LinearGenomeView/util.js.map +1 -1
  104. package/dist/index.d.ts +157 -44
  105. package/dist/index.js +21 -13
  106. package/dist/index.js.map +1 -1
  107. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +2 -3
  108. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +2 -3
  109. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js.map +1 -1
  110. package/esm/BaseLinearDisplay/components/Block.js +1 -1
  111. package/esm/BaseLinearDisplay/components/Block.js.map +1 -1
  112. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +11 -11
  113. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  114. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +82 -7
  115. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +44 -29
  116. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  117. package/esm/BaseLinearDisplay/models/configSchema.js +8 -0
  118. package/esm/BaseLinearDisplay/models/configSchema.js.map +1 -1
  119. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +1 -1
  120. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +9 -5
  121. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  122. package/esm/BaseLinearDisplay/models/util.js +2 -2
  123. package/esm/BaseLinearDisplay/models/util.js.map +1 -1
  124. package/esm/LaunchLinearGenomeView/index.js +1 -1
  125. package/esm/LaunchLinearGenomeView/index.js.map +1 -1
  126. package/esm/LinearBareDisplay/index.d.ts +2 -3
  127. package/esm/LinearBareDisplay/index.js +2 -1
  128. package/esm/LinearBareDisplay/index.js.map +1 -1
  129. package/esm/LinearBareDisplay/model.d.ts +61 -3
  130. package/esm/LinearBasicDisplay/index.d.ts +2 -3
  131. package/esm/LinearBasicDisplay/index.js +2 -1
  132. package/esm/LinearBasicDisplay/index.js.map +1 -1
  133. package/esm/LinearBasicDisplay/model.d.ts +82 -14
  134. package/esm/LinearGenomeView/components/CenterLine.js +2 -2
  135. package/esm/LinearGenomeView/components/CenterLine.js.map +1 -1
  136. package/esm/LinearGenomeView/components/Cytobands.d.ts +118 -0
  137. package/esm/LinearGenomeView/components/Cytobands.js +87 -0
  138. package/esm/LinearGenomeView/components/Cytobands.js.map +1 -0
  139. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +1 -1
  140. package/esm/LinearGenomeView/components/ExportSvgDialog.js +25 -4
  141. package/esm/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
  142. package/esm/LinearGenomeView/components/Gridlines.js +1 -1
  143. package/esm/LinearGenomeView/components/Gridlines.js.map +1 -1
  144. package/esm/LinearGenomeView/components/Header.js +5 -6
  145. package/esm/LinearGenomeView/components/Header.js.map +1 -1
  146. package/esm/LinearGenomeView/components/ImportForm.d.ts +2 -2
  147. package/esm/LinearGenomeView/components/ImportForm.js +16 -20
  148. package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
  149. package/esm/LinearGenomeView/components/LinearGenomeView.js +1 -1
  150. package/esm/LinearGenomeView/components/MiniControls.js +5 -4
  151. package/esm/LinearGenomeView/components/MiniControls.js.map +1 -1
  152. package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +3 -4
  153. package/esm/LinearGenomeView/components/OverviewRubberband.js +8 -11
  154. package/esm/LinearGenomeView/components/OverviewRubberband.js.map +1 -1
  155. package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +4 -119
  156. package/esm/LinearGenomeView/components/OverviewScalebar.js +16 -100
  157. package/esm/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
  158. package/esm/LinearGenomeView/components/RefNameAutocomplete.d.ts +2 -1
  159. package/esm/LinearGenomeView/components/RefNameAutocomplete.js +36 -32
  160. package/esm/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  161. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +2 -2
  162. package/esm/LinearGenomeView/components/RubberbandSpan.js +5 -20
  163. package/esm/LinearGenomeView/components/RubberbandSpan.js.map +1 -1
  164. package/esm/LinearGenomeView/components/SearchBox.js +3 -3
  165. package/esm/LinearGenomeView/components/SearchBox.js.map +1 -1
  166. package/esm/LinearGenomeView/components/TrackLabel.js +6 -7
  167. package/esm/LinearGenomeView/components/TrackLabel.js.map +1 -1
  168. package/esm/LinearGenomeView/components/TracksContainer.d.ts +2 -3
  169. package/esm/LinearGenomeView/components/TracksContainer.js +9 -8
  170. package/esm/LinearGenomeView/components/TracksContainer.js.map +1 -1
  171. package/esm/LinearGenomeView/components/ZoomControls.js +5 -4
  172. package/esm/LinearGenomeView/components/ZoomControls.js.map +1 -1
  173. package/esm/LinearGenomeView/components/hooks.d.ts +6 -1
  174. package/esm/LinearGenomeView/components/hooks.js +1 -1
  175. package/esm/LinearGenomeView/components/hooks.js.map +1 -1
  176. package/esm/LinearGenomeView/components/util.d.ts +6 -0
  177. package/esm/LinearGenomeView/components/util.js +9 -0
  178. package/esm/LinearGenomeView/components/util.js.map +1 -1
  179. package/esm/LinearGenomeView/index.js +8 -6
  180. package/esm/LinearGenomeView/index.js.map +1 -1
  181. package/esm/LinearGenomeView/model.d.ts +18 -12
  182. package/esm/LinearGenomeView/model.js +24 -28
  183. package/esm/LinearGenomeView/model.js.map +1 -1
  184. package/esm/LinearGenomeView/svgcomponents/SVGBackground.d.ts +6 -0
  185. package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +7 -0
  186. package/esm/LinearGenomeView/svgcomponents/SVGBackground.js.map +1 -0
  187. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +10 -0
  188. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +49 -0
  189. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js.map +1 -0
  190. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +12 -0
  191. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +47 -0
  192. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +1 -0
  193. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +8 -0
  194. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +7 -0
  195. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js.map +1 -0
  196. package/esm/LinearGenomeView/svgcomponents/SVGRuler.d.ts +8 -0
  197. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +45 -0
  198. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js.map +1 -0
  199. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +8 -0
  200. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +16 -0
  201. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js.map +1 -0
  202. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +8 -0
  203. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +10 -0
  204. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +1 -0
  205. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +23 -0
  206. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +24 -0
  207. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js.map +1 -0
  208. package/esm/LinearGenomeView/util.js +2 -2
  209. package/esm/LinearGenomeView/util.js.map +1 -1
  210. package/esm/index.d.ts +157 -44
  211. package/esm/index.js +9 -5
  212. package/esm/index.js.map +1 -1
  213. package/package.json +3 -3
  214. package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +4 -3
  215. package/src/BaseLinearDisplay/components/Block.tsx +1 -1
  216. package/src/BaseLinearDisplay/components/ServerSideRenderedBlockContent.tsx +11 -12
  217. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +55 -40
  218. package/src/BaseLinearDisplay/models/configSchema.ts +8 -0
  219. package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +15 -22
  220. package/src/BaseLinearDisplay/models/util.ts +2 -2
  221. package/src/LaunchLinearGenomeView/index.ts +1 -1
  222. package/src/LinearBareDisplay/index.ts +2 -1
  223. package/src/LinearBasicDisplay/index.ts +2 -1
  224. package/src/LinearGenomeView/components/CenterLine.tsx +2 -2
  225. package/src/LinearGenomeView/components/Cytobands.tsx +154 -0
  226. package/src/LinearGenomeView/components/ExportSvgDialog.tsx +56 -4
  227. package/src/LinearGenomeView/components/Gridlines.tsx +1 -1
  228. package/src/LinearGenomeView/components/Header.tsx +6 -13
  229. package/src/LinearGenomeView/components/ImportForm.tsx +17 -26
  230. package/src/LinearGenomeView/components/LinearGenomeView.test.tsx +8 -11
  231. package/src/LinearGenomeView/components/LinearGenomeView.tsx +1 -1
  232. package/src/LinearGenomeView/components/MiniControls.tsx +6 -7
  233. package/src/LinearGenomeView/components/OverviewRubberband.tsx +40 -49
  234. package/src/LinearGenomeView/components/OverviewScalebar.tsx +222 -385
  235. package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +50 -48
  236. package/src/LinearGenomeView/components/RubberbandSpan.tsx +8 -25
  237. package/src/LinearGenomeView/components/SearchBox.tsx +3 -2
  238. package/src/LinearGenomeView/components/TrackLabel.tsx +76 -76
  239. package/src/LinearGenomeView/components/TracksContainer.tsx +8 -8
  240. package/src/LinearGenomeView/components/ZoomControls.tsx +3 -4
  241. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +1230 -1200
  242. package/src/LinearGenomeView/components/hooks.ts +7 -1
  243. package/src/LinearGenomeView/components/util.ts +13 -0
  244. package/src/LinearGenomeView/index.test.ts +12 -13
  245. package/src/LinearGenomeView/index.ts +8 -9
  246. package/src/LinearGenomeView/model.ts +41 -36
  247. package/src/LinearGenomeView/svgcomponents/SVGBackground.tsx +21 -0
  248. package/src/LinearGenomeView/svgcomponents/SVGHeader.tsx +93 -0
  249. package/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx +114 -0
  250. package/src/LinearGenomeView/svgcomponents/SVGRegionSeparators.tsx +31 -0
  251. package/src/LinearGenomeView/svgcomponents/SVGRuler.tsx +125 -0
  252. package/src/LinearGenomeView/svgcomponents/SVGScalebar.tsx +57 -0
  253. package/src/LinearGenomeView/svgcomponents/SVGTrackLabel.tsx +47 -0
  254. package/src/LinearGenomeView/svgcomponents/SVGTracks.tsx +67 -0
  255. package/src/LinearGenomeView/util.test.ts +7 -4
  256. package/src/LinearGenomeView/util.ts +3 -3
  257. package/src/index.ts +22 -23
  258. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.d.ts +0 -4
  259. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +0 -141
  260. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js.map +0 -1
  261. package/dist/LinearGenomeView/components/Ruler.d.ts +0 -11
  262. package/dist/LinearGenomeView/components/Ruler.js +0 -39
  263. package/dist/LinearGenomeView/components/Ruler.js.map +0 -1
  264. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.d.ts +0 -4
  265. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js +0 -134
  266. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js.map +0 -1
  267. package/esm/LinearGenomeView/components/Ruler.d.ts +0 -11
  268. package/esm/LinearGenomeView/components/Ruler.js +0 -34
  269. package/esm/LinearGenomeView/components/Ruler.js.map +0 -1
  270. package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +0 -307
  271. package/src/LinearGenomeView/components/Ruler.tsx +0 -78
@@ -239,7 +239,12 @@ export function useRangeSelect(
239
239
 
240
240
  export function useWheelScroll(
241
241
  ref: React.RefObject<HTMLDivElement>,
242
- model: LGV,
242
+ model: {
243
+ bpPerPx: number
244
+ zoomTo: (arg: number, arg2?: number) => void
245
+ setScaleFactor: (arg: number) => void
246
+ horizontalScroll: (arg: number) => void
247
+ },
243
248
  ) {
244
249
  const delta = useRef(0)
245
250
  const timeout = useRef<Timer>()
@@ -266,6 +271,7 @@ export function useWheelScroll(
266
271
  delta.current > 0
267
272
  ? model.bpPerPx * (1 + delta.current)
268
273
  : model.bpPerPx / (1 - delta.current),
274
+ origEvent.clientX - (curr?.getBoundingClientRect().left || 0),
269
275
  )
270
276
  delta.current = 0
271
277
  }, 300)
@@ -60,3 +60,16 @@ export function getRelativeX<
60
60
  >(event: T, element: HTMLElement | null) {
61
61
  return event.clientX - (element?.getBoundingClientRect().left || 0)
62
62
  }
63
+
64
+ export function getCytobands(assembly: Assembly | undefined, refName: string) {
65
+ return (
66
+ assembly?.cytobands
67
+ ?.map(f => ({
68
+ refName: assembly.getCanonicalRefName(f.get('refName')),
69
+ start: f.get('start'),
70
+ end: f.get('end'),
71
+ type: f.get('type'),
72
+ }))
73
+ .filter(f => f.refName === refName) || []
74
+ )
75
+ }
@@ -7,13 +7,17 @@ import {
7
7
  } from '@jbrowse/core/pluggableElementTypes/models'
8
8
  import TrackType from '@jbrowse/core/pluggableElementTypes/TrackType'
9
9
  import PluginManager from '@jbrowse/core/PluginManager'
10
- import { Instance, types } from 'mobx-state-tree'
11
- import { LinearGenomeViewStateModel, stateModelFactory } from '.'
10
+ import { types } from 'mobx-state-tree'
11
+
12
+ // locals
13
+ import { LinearGenomeViewModel, stateModelFactory } from '.'
12
14
  import { BaseLinearDisplayComponent } from '..'
13
15
  import { stateModelFactory as LinearBasicDisplayStateModelFactory } from '../LinearBareDisplay'
14
16
  import hg38Regions from './hg38DisplayedRegions.json'
15
17
  import volvoxDisplayedRegions from './volvoxDisplayedRegions.json'
16
18
 
19
+ type LGV = LinearGenomeViewModel
20
+
17
21
  // use initializer function to avoid having console.warn jest.fn in a global
18
22
  function initialize() {
19
23
  console.warn = jest.fn()
@@ -92,14 +96,14 @@ function initialize() {
92
96
  assemblyManager: types.optional(AssemblyManager, {
93
97
  assemblies: {
94
98
  volvox: {
95
- // @ts-ignore
99
+ // @ts-expect-error
96
100
  regions: volvoxDisplayedRegions,
97
101
  },
98
102
  },
99
103
  }),
100
104
  })
101
105
  .actions(self => ({
102
- setView(view: Instance<LinearGenomeViewStateModel>) {
106
+ setView(view: LGV) {
103
107
  self.view = view
104
108
  return view
105
109
  },
@@ -306,8 +310,7 @@ test('can navToMultiple', () => {
306
310
 
307
311
  describe('Zoom to selected displayed regions', () => {
308
312
  const { Session, LinearGenomeModel } = initialize()
309
- let model: Instance<ReturnType<typeof stateModelFactory>>
310
- let largestBpPerPx: number
313
+ let model: LGV
311
314
  beforeEach(() => {
312
315
  const session = Session.create({
313
316
  configuration: {},
@@ -353,7 +356,6 @@ describe('Zoom to selected displayed regions', () => {
353
356
  },
354
357
  )
355
358
 
356
- largestBpPerPx = model.bpPerPx
357
359
  expect(model.offsetPx).toEqual(0)
358
360
  expect(model.bpPerPx).toBeCloseTo(31.408)
359
361
  })
@@ -380,7 +382,6 @@ describe('Zoom to selected displayed regions', () => {
380
382
  expect(model.offsetPx).toEqual(0)
381
383
  // 10000 - 5000 = 5000 / 800 = 6.25
382
384
  expect(model.bpPerPx).toEqual(6.25)
383
- expect(model.bpPerPx).toBeLessThan(largestBpPerPx)
384
385
  })
385
386
 
386
387
  it('can select one region with start or end outside of displayed region', () => {
@@ -407,7 +408,6 @@ describe('Zoom to selected displayed regions', () => {
407
408
  expect(Math.abs(model.offsetPx)).toEqual(0)
408
409
  // endOffset 19000 - (-1) = 19001 / 800 = zoomTo(23.75)
409
410
  expect(model.bpPerPx).toBeCloseTo(23.75)
410
- expect(model.bpPerPx).toBeLessThan(largestBpPerPx)
411
411
  })
412
412
 
413
413
  it('can select over two regions in the same reference sequence', () => {
@@ -435,7 +435,6 @@ describe('Zoom to selected displayed regions', () => {
435
435
  expect(model.bpPerPx).toBeCloseTo(27.78, 0)
436
436
  // offset 5000 / bpPerPx (because that is the starting) = 180.5
437
437
  expect(model.offsetPx).toBe(181)
438
- expect(model.bpPerPx).toBeLessThan(largestBpPerPx)
439
438
  })
440
439
 
441
440
  it('can navigate to overlapping regions with a region between', () => {
@@ -581,7 +580,7 @@ test('can perform bpToPx in a way that makes sense on things that happen outside
581
580
  model.toggleHeaderOverview()
582
581
  expect(model.hideHeaderOverview).toEqual(true)
583
582
  model.toggleHeaderOverview()
584
- model.setError(Error('pxToBp failed to map to a region'))
583
+ model.setError(new Error('pxToBp failed to map to a region'))
585
584
  expect(`${model.error}`).toEqual('Error: pxToBp failed to map to a region')
586
585
  })
587
586
  // determined objectively by looking at
@@ -674,7 +673,7 @@ describe('get sequence for selected displayed regions', () => {
674
673
  /* the start of all the results should be +1
675
674
  the sequence dialog then handles converting from 1-based closed to interbase
676
675
  */
677
- let model: Instance<ReturnType<typeof stateModelFactory>>
676
+ let model: LGV
678
677
  beforeEach(() => {
679
678
  const session = Session.create({
680
679
  configuration: {},
@@ -932,7 +931,7 @@ test('navToLocString with human assembly', async () => {
932
931
  assemblyManager: {
933
932
  assemblies: {
934
933
  hg38: {
935
- // @ts-ignore
934
+ // @ts-expect-error
936
935
  regions: hg38Regions,
937
936
  },
938
937
  },
@@ -4,15 +4,14 @@ import { ViewType } from '@jbrowse/core/pluggableElementTypes'
4
4
  import { stateModelFactory } from './model'
5
5
 
6
6
  export default (pluginManager: PluginManager) => {
7
- pluginManager.addViewType(
8
- () =>
9
- new ViewType({
10
- name: 'LinearGenomeView',
11
- displayName: 'Linear genome view',
12
- stateModel: stateModelFactory(pluginManager),
13
- ReactComponent: lazy(() => import('./components/LinearGenomeView')),
14
- }),
15
- )
7
+ pluginManager.addViewType(() => {
8
+ return new ViewType({
9
+ name: 'LinearGenomeView',
10
+ displayName: 'Linear genome view',
11
+ stateModel: stateModelFactory(pluginManager),
12
+ ReactComponent: lazy(() => import('./components/LinearGenomeView')),
13
+ })
14
+ })
16
15
  }
17
16
 
18
17
  export * from './model'
@@ -17,6 +17,7 @@ import {
17
17
  measureText,
18
18
  parseLocString,
19
19
  springAnimate,
20
+ sum,
20
21
  } from '@jbrowse/core/util'
21
22
  import BaseResult from '@jbrowse/core/TextSearch/BaseResults'
22
23
  import { BlockSet, BaseBlock } from '@jbrowse/core/util/blockTypes'
@@ -51,14 +52,11 @@ import ZoomInIcon from '@mui/icons-material/ZoomIn'
51
52
  import MenuOpenIcon from '@mui/icons-material/MenuOpen'
52
53
 
53
54
  // locals
54
- import { renderToSvg } from './components/LinearGenomeViewSvg'
55
- import RefNameAutocomplete from './components/RefNameAutocomplete'
56
- import SearchBox from './components/SearchBox'
55
+ import { renderToSvg } from './svgcomponents/SVGLinearGenomeView'
56
+
57
57
  import ExportSvgDlg from './components/ExportSvgDialog'
58
58
  import MiniControls from './components/MiniControls'
59
59
  import Header from './components/Header'
60
- import ZoomControls from './components/ZoomControls'
61
- import LinearGenomeView from './components/LinearGenomeView'
62
60
 
63
61
  // lazies
64
62
  const SequenceSearchDialog = lazy(
@@ -76,12 +74,19 @@ export interface BpOffset {
76
74
  assemblyName?: string
77
75
  oob?: boolean
78
76
  }
79
-
80
77
  export interface ExportSvgOptions {
81
78
  rasterizeLayers?: boolean
82
79
  filename?: string
83
80
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
81
  Wrapper?: React.FC<any>
82
+ fontSize?: number
83
+ rulerHeight?: number
84
+ textHeight?: number
85
+ paddingHeight?: number
86
+ headerHeight?: number
87
+ cytobandHeight?: number
88
+ trackLabels?: string
89
+ themeName?: string
85
90
  }
86
91
 
87
92
  function calculateVisibleLocStrings(contentBlocks: BaseBlock[]) {
@@ -358,9 +363,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
358
363
  * #getter
359
364
  */
360
365
  get trackHeights() {
361
- return self.tracks
362
- .map(t => t.displays[0].height)
363
- .reduce((a, b) => a + b, 0)
366
+ return sum(self.tracks.map(t => t.displays[0].height))
364
367
  },
365
368
 
366
369
  /**
@@ -471,14 +474,14 @@ export function stateModelFactory(pluginManager: PluginManager) {
471
474
  */
472
475
  rankSearchResults(results: BaseResult[]) {
473
476
  // order of rank
474
- const openTrackIds = self.tracks.map(
475
- track => track.configuration.trackId,
477
+ const openTrackIds = new Set(
478
+ self.tracks.map(track => track.configuration.trackId),
476
479
  )
477
- results.forEach(result => {
478
- if (openTrackIds.includes(result.trackId)) {
480
+ for (const result of results) {
481
+ if (openTrackIds.has(result.trackId)) {
479
482
  result.updateScore(result.getScore() + 1)
480
483
  }
481
- })
484
+ }
482
485
  return results
483
486
  },
484
487
 
@@ -576,25 +579,25 @@ export function stateModelFactory(pluginManager: PluginManager) {
576
579
  /**
577
580
  * #action
578
581
  */
579
- zoomTo(bpPerPx: number) {
582
+ zoomTo(bpPerPx: number, offset = self.width / 2, centerAtOffset = false) {
580
583
  const newBpPerPx = clamp(bpPerPx, self.minBpPerPx, self.maxBpPerPx)
581
584
  if (newBpPerPx === self.bpPerPx) {
582
585
  return newBpPerPx
583
586
  }
584
587
  const oldBpPerPx = self.bpPerPx
585
- self.bpPerPx = newBpPerPx
586
588
 
587
589
  if (Math.abs(oldBpPerPx - newBpPerPx) < 0.000001) {
588
590
  console.warn('zoomTo bpPerPx rounding error')
589
591
  return oldBpPerPx
590
592
  }
593
+ self.bpPerPx = newBpPerPx
591
594
 
592
- // tweak the offset so that the center of the view remains at the same coordinate
593
- const viewWidth = self.width
595
+ // tweak the offset so that the center of the view remains at the same
596
+ // coordinate
594
597
  this.scrollTo(
595
598
  Math.round(
596
- ((self.offsetPx + viewWidth / 2) * oldBpPerPx) / newBpPerPx -
597
- viewWidth / 2,
599
+ ((self.offsetPx + offset) * oldBpPerPx) / newBpPerPx -
600
+ (centerAtOffset ? self.width / 2 : offset),
598
601
  ),
599
602
  )
600
603
  return newBpPerPx
@@ -637,8 +640,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
637
640
  */
638
641
  horizontallyFlip() {
639
642
  self.displayedRegions = cast(
640
- self.displayedRegions
641
- .slice()
643
+ [...self.displayedRegions]
642
644
  .reverse()
643
645
  .map(region => ({ ...region, reversed: !region.reversed })),
644
646
  )
@@ -663,9 +665,11 @@ export function stateModelFactory(pluginManager: PluginManager) {
663
665
  throw new Error(`Unknown track type ${conf.type}`)
664
666
  }
665
667
  const viewType = pluginManager.getViewType(self.type)
666
- const supportedDisplays = viewType.displayTypes.map(d => d.name)
668
+ const supportedDisplays = new Set(
669
+ viewType.displayTypes.map(d => d.name),
670
+ )
667
671
  const displayConf = conf.displays.find((d: AnyConfigurationModel) =>
668
- supportedDisplays.includes(d.type),
672
+ supportedDisplays.has(d.type),
669
673
  )
670
674
  if (!displayConf) {
671
675
  throw new Error(
@@ -907,7 +911,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
907
911
  },
908
912
 
909
913
  /**
910
- * #action
914
+ * #method
911
915
  * creates an svg export and save using FileSaver
912
916
  */
913
917
  async exportSvg(opts: ExportSvgOptions = {}) {
@@ -1359,7 +1363,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
1359
1363
  })
1360
1364
  } else {
1361
1365
  self.setDisplayedRegions(
1362
- // @ts-ignore
1366
+ // @ts-expect-error
1363
1367
  locations.map(r => (r.start === undefined ? r.parentRegion : r)),
1364
1368
  )
1365
1369
  self.showAllRegions()
@@ -1579,22 +1583,23 @@ export function stateModelFactory(pluginManager: PluginManager) {
1579
1583
  * #getter
1580
1584
  */
1581
1585
  get centerLineInfo() {
1582
- return self.displayedRegions.length
1586
+ return self.displayedRegions.length > 0
1583
1587
  ? this.pxToBp(self.width / 2)
1584
1588
  : undefined
1585
1589
  },
1586
1590
  }))
1587
1591
  }
1588
1592
 
1589
- export {
1590
- renderToSvg,
1591
- RefNameAutocomplete,
1592
- SearchBox,
1593
- ZoomControls,
1594
- LinearGenomeView,
1595
- }
1596
-
1597
1593
  export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>
1598
1594
  export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>
1599
1595
 
1600
- export { default as ReactComponent } from './components/LinearGenomeView'
1596
+ export {
1597
+ default as ReactComponent,
1598
+ default as LinearGenomeView,
1599
+ } from './components/LinearGenomeView'
1600
+
1601
+ export { default as RefNameAutocomplete } from './components/RefNameAutocomplete'
1602
+ export { default as SearchBox } from './components/SearchBox'
1603
+ export { default as ZoomControls } from './components/ZoomControls'
1604
+
1605
+ export { renderToSvg } from './svgcomponents/SVGLinearGenomeView'
@@ -0,0 +1,21 @@
1
+ import React from 'react'
2
+ import { useTheme } from '@mui/material'
3
+
4
+ export default function SVGBackground({
5
+ width,
6
+ height,
7
+ shift,
8
+ }: {
9
+ width: number
10
+ height: number
11
+ shift: number
12
+ }) {
13
+ const theme = useTheme()
14
+ return (
15
+ <rect
16
+ width={width + shift * 2}
17
+ height={height}
18
+ fill={theme.palette.background.default}
19
+ />
20
+ )
21
+ }
@@ -0,0 +1,93 @@
1
+ import React from 'react'
2
+ import { getSession } from '@jbrowse/core/util'
3
+ import Base1DView from '@jbrowse/core/util/Base1DViewModel'
4
+ import { useTheme } from '@mui/material'
5
+
6
+ // locals
7
+ import { LinearGenomeViewModel, HEADER_OVERVIEW_HEIGHT } from '..'
8
+ import Cytobands from '../components/Cytobands'
9
+ import { Polygon } from '../components/OverviewScalebar'
10
+ import SVGRuler from './SVGRuler'
11
+ import SVGScalebar from './SVGScalebar'
12
+
13
+ type LGV = LinearGenomeViewModel
14
+
15
+ export default function SVGHeader({
16
+ model,
17
+ fontSize,
18
+ cytobandHeight,
19
+ rulerHeight,
20
+ }: {
21
+ model: LGV
22
+ rulerHeight: number
23
+ fontSize: number
24
+ cytobandHeight: number
25
+ }) {
26
+ const { width, assemblyNames, showCytobands, displayedRegions } = model
27
+ const { assemblyManager } = getSession(model)
28
+ const assemblyName = assemblyNames.length > 1 ? '' : assemblyNames[0]
29
+ const assembly = assemblyManager.get(assemblyName)
30
+ const theme = useTheme()
31
+
32
+ const overview = Base1DView.create({
33
+ displayedRegions: JSON.parse(JSON.stringify(displayedRegions)),
34
+ interRegionPaddingWidth: 0,
35
+ minimumBlockWidth: model.minimumBlockWidth,
36
+ })
37
+ const visibleRegions = model.dynamicBlocks.contentBlocks
38
+
39
+ overview.setVolatileWidth(width)
40
+ overview.showAllRegions()
41
+ const block = overview.dynamicBlocks.contentBlocks[0]
42
+
43
+ const first = visibleRegions[0]
44
+ const firstOverviewPx =
45
+ overview.bpToPx({
46
+ ...first,
47
+ coord: first.reversed ? first.end : first.start,
48
+ }) || 0
49
+
50
+ const last = visibleRegions[visibleRegions.length - 1]
51
+ const lastOverviewPx =
52
+ overview.bpToPx({
53
+ ...last,
54
+ coord: last.reversed ? last.start : last.end,
55
+ }) || 0
56
+ const c = +showCytobands * cytobandHeight
57
+ return (
58
+ <g id="header">
59
+ <text
60
+ x={0}
61
+ y={fontSize}
62
+ fontSize={fontSize}
63
+ fill={theme.palette.text.primary}
64
+ >
65
+ {assemblyName}
66
+ </text>
67
+
68
+ {showCytobands ? (
69
+ <g transform={`translate(0 ${rulerHeight})`}>
70
+ <Cytobands overview={overview} assembly={assembly} block={block} />
71
+ <rect
72
+ stroke="red"
73
+ fill="rgb(255,0,0,0.1)"
74
+ width={Math.max(lastOverviewPx - firstOverviewPx, 0.5)}
75
+ height={HEADER_OVERVIEW_HEIGHT - 1}
76
+ x={firstOverviewPx}
77
+ y={0.5}
78
+ />
79
+ <g transform={`translate(0,${HEADER_OVERVIEW_HEIGHT})`}>
80
+ <Polygon overview={overview} model={model} useOffset={false} />
81
+ </g>
82
+ </g>
83
+ ) : null}
84
+
85
+ <g transform={`translate(0 ${fontSize + c})`}>
86
+ <SVGScalebar model={model} fontSize={fontSize} />
87
+ </g>
88
+ <g transform={`translate(0 ${rulerHeight + c})`}>
89
+ <SVGRuler model={model} fontSize={fontSize} />
90
+ </g>
91
+ </g>
92
+ )
93
+ }
@@ -0,0 +1,114 @@
1
+ import React from 'react'
2
+ import { renderToStaticMarkup } from 'react-dom/server'
3
+ import { when } from 'mobx'
4
+ import { getSession, max, measureText, sum } from '@jbrowse/core/util'
5
+ import { ThemeProvider } from '@mui/material'
6
+ import { createJBrowseTheme } from '@jbrowse/core/ui'
7
+
8
+ // locals
9
+ import { LinearGenomeViewModel, ExportSvgOptions } from '..'
10
+ import SVGBackground from './SVGBackground'
11
+ import SVGTracks from './SVGTracks'
12
+ import SVGHeader from './SVGHeader'
13
+
14
+ import { getTrackName } from '@jbrowse/core/util/tracks'
15
+
16
+ type LGV = LinearGenomeViewModel
17
+
18
+ interface Display {
19
+ height: number
20
+ }
21
+ interface Track {
22
+ displays: Display[]
23
+ }
24
+
25
+ export function totalHeight(
26
+ tracks: Track[],
27
+ textHeight: number,
28
+ trackLabels: string,
29
+ ) {
30
+ return sum(
31
+ tracks.map(
32
+ t =>
33
+ t.displays[0].height +
34
+ (['none', 'left'].includes(trackLabels) ? 0 : textHeight),
35
+ ),
36
+ )
37
+ }
38
+
39
+ // render LGV to SVG
40
+ export async function renderToSvg(model: LGV, opts: ExportSvgOptions) {
41
+ await when(() => model.initialized)
42
+ const {
43
+ textHeight = 18,
44
+ headerHeight = 40,
45
+ rulerHeight = 50,
46
+ fontSize = 13,
47
+ cytobandHeight = 100,
48
+ trackLabels = 'offset',
49
+ themeName = 'default',
50
+ Wrapper = ({ children }) => <>{children}</>,
51
+ } = opts
52
+ const session = getSession(model)
53
+ const theme = session.allThemes?.()[themeName]
54
+ const { width, tracks, showCytobands } = model
55
+ const shift = 50
56
+ const c = +showCytobands * cytobandHeight
57
+ const offset = headerHeight + rulerHeight + c + 10
58
+ const height = totalHeight(tracks, textHeight, trackLabels) + offset + 100
59
+ const displayResults = await Promise.all(
60
+ tracks.map(async track => {
61
+ const display = track.displays[0]
62
+ await when(() => (display.ready !== undefined ? display.ready : true))
63
+ return { track, result: await display.renderSvg({ ...opts, theme }) }
64
+ }),
65
+ )
66
+ const trackLabelMaxLen =
67
+ max(
68
+ tracks.map(t =>
69
+ measureText(getTrackName(t.configuration, session), fontSize),
70
+ ),
71
+ 0,
72
+ ) + 40
73
+ const trackLabelOffset = trackLabels === 'left' ? trackLabelMaxLen : 0
74
+ const w = width + trackLabelOffset
75
+
76
+ // the xlink namespace is used for rendering <image> tag
77
+ return renderToStaticMarkup(
78
+ <ThemeProvider theme={createJBrowseTheme(theme)}>
79
+ <Wrapper>
80
+ <svg
81
+ width={w}
82
+ height={height}
83
+ xmlns="http://www.w3.org/2000/svg"
84
+ xmlnsXlink="http://www.w3.org/1999/xlink"
85
+ viewBox={[0, 0, w + shift * 2, height].toString()}
86
+ >
87
+ <SVGBackground width={w} height={height} shift={shift} />
88
+ <g transform={`translate(${shift} 0)`}>
89
+ <g transform={`translate(${trackLabelOffset})`}>
90
+ <SVGHeader
91
+ model={model}
92
+ fontSize={fontSize}
93
+ rulerHeight={rulerHeight}
94
+ cytobandHeight={cytobandHeight}
95
+ />
96
+ </g>
97
+ <SVGTracks
98
+ textHeight={textHeight}
99
+ fontSize={fontSize}
100
+ model={model}
101
+ displayResults={displayResults}
102
+ offset={offset}
103
+ trackLabels={trackLabels}
104
+ trackLabelOffset={trackLabelOffset}
105
+ />
106
+ </g>
107
+ </svg>
108
+ </Wrapper>
109
+ </ThemeProvider>,
110
+ )
111
+ }
112
+
113
+ export { default as SVGRuler } from './SVGRuler'
114
+ export { default as SVGTracks } from './SVGTracks'
@@ -0,0 +1,31 @@
1
+ import React from 'react'
2
+
3
+ // locals
4
+ import { LinearGenomeViewModel } from '..'
5
+
6
+ type LGV = LinearGenomeViewModel
7
+
8
+ // SVG component, region separator
9
+ export default function SVGRegionSeparators({
10
+ model,
11
+ height,
12
+ }: {
13
+ height: number
14
+ model: LGV
15
+ }) {
16
+ const { dynamicBlocks, offsetPx, interRegionPaddingWidth } = model
17
+ return (
18
+ <>
19
+ {dynamicBlocks.contentBlocks.slice(1).map(block => (
20
+ <rect
21
+ key={block.key}
22
+ x={block.offsetPx - offsetPx - interRegionPaddingWidth}
23
+ width={interRegionPaddingWidth}
24
+ y={0}
25
+ height={height}
26
+ fill="grey"
27
+ />
28
+ ))}
29
+ </>
30
+ )
31
+ }