@jbrowse/plugin-linear-comparative-view 2.6.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 (276) hide show
  1. package/LICENSE +201 -0
  2. package/dist/LGVSyntenyDisplay/configSchemaF.d.ts +52 -0
  3. package/dist/LGVSyntenyDisplay/configSchemaF.js +18 -0
  4. package/dist/LGVSyntenyDisplay/configSchemaF.js.map +1 -0
  5. package/dist/LGVSyntenyDisplay/index.d.ts +3 -0
  6. package/dist/LGVSyntenyDisplay/index.js +24 -0
  7. package/dist/LGVSyntenyDisplay/index.js.map +1 -0
  8. package/dist/LGVSyntenyDisplay/model.d.ts +380 -0
  9. package/dist/LGVSyntenyDisplay/model.js +154 -0
  10. package/dist/LGVSyntenyDisplay/model.js.map +1 -0
  11. package/dist/LaunchLinearSyntenyView.d.ts +2 -0
  12. package/dist/LaunchLinearSyntenyView.js +58 -0
  13. package/dist/LaunchLinearSyntenyView.js.map +1 -0
  14. package/dist/LinearComparativeDisplay/configSchemaF.d.ts +5 -0
  15. package/dist/LinearComparativeDisplay/configSchemaF.js +18 -0
  16. package/dist/LinearComparativeDisplay/configSchemaF.js.map +1 -0
  17. package/dist/LinearComparativeDisplay/index.d.ts +3 -0
  18. package/dist/LinearComparativeDisplay/index.js +24 -0
  19. package/dist/LinearComparativeDisplay/index.js.map +1 -0
  20. package/dist/LinearComparativeDisplay/stateModelFactory.d.ts +275 -0
  21. package/dist/LinearComparativeDisplay/stateModelFactory.js +172 -0
  22. package/dist/LinearComparativeDisplay/stateModelFactory.js.map +1 -0
  23. package/dist/LinearComparativeView/components/Header.d.ts +7 -0
  24. package/dist/LinearComparativeView/components/Header.js +89 -0
  25. package/dist/LinearComparativeView/components/Header.js.map +1 -0
  26. package/dist/LinearComparativeView/components/LinearComparativeView.d.ts +8 -0
  27. package/dist/LinearComparativeView/components/LinearComparativeView.js +99 -0
  28. package/dist/LinearComparativeView/components/LinearComparativeView.js.map +1 -0
  29. package/dist/LinearComparativeView/components/Rubberband.d.ts +9 -0
  30. package/dist/LinearComparativeView/components/Rubberband.js +225 -0
  31. package/dist/LinearComparativeView/components/Rubberband.js.map +1 -0
  32. package/dist/LinearComparativeView/index.d.ts +3 -0
  33. package/dist/LinearComparativeView/index.js +42 -0
  34. package/dist/LinearComparativeView/index.js.map +1 -0
  35. package/dist/LinearComparativeView/model.d.ts +326 -0
  36. package/dist/LinearComparativeView/model.js +346 -0
  37. package/dist/LinearComparativeView/model.js.map +1 -0
  38. package/dist/LinearReadVsRef/LinearReadVsRef.d.ts +7 -0
  39. package/dist/LinearReadVsRef/LinearReadVsRef.js +284 -0
  40. package/dist/LinearReadVsRef/LinearReadVsRef.js.map +1 -0
  41. package/dist/LinearReadVsRef/index.d.ts +2 -0
  42. package/dist/LinearReadVsRef/index.js +55 -0
  43. package/dist/LinearReadVsRef/index.js.map +1 -0
  44. package/dist/LinearSyntenyDisplay/afterAttach.d.ts +2 -0
  45. package/dist/LinearSyntenyDisplay/afterAttach.js +108 -0
  46. package/dist/LinearSyntenyDisplay/afterAttach.js.map +1 -0
  47. package/dist/LinearSyntenyDisplay/components/Component.d.ts +6 -0
  48. package/dist/LinearSyntenyDisplay/components/Component.js +87 -0
  49. package/dist/LinearSyntenyDisplay/components/Component.js.map +1 -0
  50. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.d.ts +6 -0
  51. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +160 -0
  52. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js.map +1 -0
  53. package/dist/LinearSyntenyDisplay/components/SyntenyTooltip.d.ts +7 -0
  54. package/dist/LinearSyntenyDisplay/components/SyntenyTooltip.js +83 -0
  55. package/dist/LinearSyntenyDisplay/components/SyntenyTooltip.js.map +1 -0
  56. package/dist/LinearSyntenyDisplay/components/util.d.ts +27 -0
  57. package/dist/LinearSyntenyDisplay/components/util.js +84 -0
  58. package/dist/LinearSyntenyDisplay/components/util.js.map +1 -0
  59. package/dist/LinearSyntenyDisplay/configSchemaF.d.ts +23 -0
  60. package/dist/LinearSyntenyDisplay/configSchemaF.js +36 -0
  61. package/dist/LinearSyntenyDisplay/configSchemaF.js.map +1 -0
  62. package/dist/LinearSyntenyDisplay/drawSynteny.d.ts +5 -0
  63. package/dist/LinearSyntenyDisplay/drawSynteny.js +235 -0
  64. package/dist/LinearSyntenyDisplay/drawSynteny.js.map +1 -0
  65. package/dist/LinearSyntenyDisplay/index.d.ts +3 -0
  66. package/dist/LinearSyntenyDisplay/index.js +47 -0
  67. package/dist/LinearSyntenyDisplay/index.js.map +1 -0
  68. package/dist/LinearSyntenyDisplay/model.d.ts +333 -0
  69. package/dist/LinearSyntenyDisplay/model.js +179 -0
  70. package/dist/LinearSyntenyDisplay/model.js.map +1 -0
  71. package/dist/LinearSyntenyView/components/ExportSvgDialog.d.ts +8 -0
  72. package/dist/LinearSyntenyView/components/ExportSvgDialog.js +86 -0
  73. package/dist/LinearSyntenyView/components/ExportSvgDialog.js.map +1 -0
  74. package/dist/LinearSyntenyView/components/Icons.d.ts +4 -0
  75. package/dist/LinearSyntenyView/components/Icons.js +19 -0
  76. package/dist/LinearSyntenyView/components/Icons.js.map +1 -0
  77. package/dist/LinearSyntenyView/components/ImportCustomTrack.d.ts +11 -0
  78. package/dist/LinearSyntenyView/components/ImportCustomTrack.js +180 -0
  79. package/dist/LinearSyntenyView/components/ImportCustomTrack.js.map +1 -0
  80. package/dist/LinearSyntenyView/components/ImportForm.d.ts +6 -0
  81. package/dist/LinearSyntenyView/components/ImportForm.js +127 -0
  82. package/dist/LinearSyntenyView/components/ImportForm.js.map +1 -0
  83. package/dist/LinearSyntenyView/components/ImportSyntenyTrackSelector.d.ts +9 -0
  84. package/dist/LinearSyntenyView/components/ImportSyntenyTrackSelector.js +63 -0
  85. package/dist/LinearSyntenyView/components/ImportSyntenyTrackSelector.js.map +1 -0
  86. package/dist/LinearSyntenyView/components/LinearSyntenyView.d.ts +7 -0
  87. package/dist/LinearSyntenyView/components/LinearSyntenyView.js +38 -0
  88. package/dist/LinearSyntenyView/components/LinearSyntenyView.js.map +1 -0
  89. package/dist/LinearSyntenyView/index.d.ts +3 -0
  90. package/dist/LinearSyntenyView/index.js +42 -0
  91. package/dist/LinearSyntenyView/index.js.map +1 -0
  92. package/dist/LinearSyntenyView/model.d.ts +754 -0
  93. package/dist/LinearSyntenyView/model.js +170 -0
  94. package/dist/LinearSyntenyView/model.js.map +1 -0
  95. package/dist/LinearSyntenyView/svgcomponents/SVGBackground.d.ts +6 -0
  96. package/dist/LinearSyntenyView/svgcomponents/SVGBackground.js +13 -0
  97. package/dist/LinearSyntenyView/svgcomponents/SVGBackground.js.map +1 -0
  98. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +4 -0
  99. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +85 -0
  100. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js.map +1 -0
  101. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +5 -0
  102. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js +66 -0
  103. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js.map +1 -0
  104. package/dist/SyntenyFeatureDetail/index.d.ts +3 -0
  105. package/dist/SyntenyFeatureDetail/index.js +58 -0
  106. package/dist/SyntenyFeatureDetail/index.js.map +1 -0
  107. package/dist/SyntenyTrack/configSchema.d.ts +75 -0
  108. package/dist/SyntenyTrack/configSchema.js +16 -0
  109. package/dist/SyntenyTrack/configSchema.js.map +1 -0
  110. package/dist/SyntenyTrack/index.d.ts +3 -0
  111. package/dist/SyntenyTrack/index.js +19 -0
  112. package/dist/SyntenyTrack/index.js.map +1 -0
  113. package/dist/index.d.ts +7 -0
  114. package/dist/index.js +47 -0
  115. package/dist/index.js.map +1 -0
  116. package/dist/util.d.ts +25 -0
  117. package/dist/util.js +77 -0
  118. package/dist/util.js.map +1 -0
  119. package/esm/LGVSyntenyDisplay/configSchemaF.d.ts +52 -0
  120. package/esm/LGVSyntenyDisplay/configSchemaF.js +16 -0
  121. package/esm/LGVSyntenyDisplay/configSchemaF.js.map +1 -0
  122. package/esm/LGVSyntenyDisplay/index.d.ts +3 -0
  123. package/esm/LGVSyntenyDisplay/index.js +19 -0
  124. package/esm/LGVSyntenyDisplay/index.js.map +1 -0
  125. package/esm/LGVSyntenyDisplay/model.d.ts +380 -0
  126. package/esm/LGVSyntenyDisplay/model.js +152 -0
  127. package/esm/LGVSyntenyDisplay/model.js.map +1 -0
  128. package/esm/LaunchLinearSyntenyView.d.ts +2 -0
  129. package/esm/LaunchLinearSyntenyView.js +55 -0
  130. package/esm/LaunchLinearSyntenyView.js.map +1 -0
  131. package/esm/LinearComparativeDisplay/configSchemaF.d.ts +5 -0
  132. package/esm/LinearComparativeDisplay/configSchemaF.js +16 -0
  133. package/esm/LinearComparativeDisplay/configSchemaF.js.map +1 -0
  134. package/esm/LinearComparativeDisplay/index.d.ts +3 -0
  135. package/esm/LinearComparativeDisplay/index.js +19 -0
  136. package/esm/LinearComparativeDisplay/index.js.map +1 -0
  137. package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +275 -0
  138. package/esm/LinearComparativeDisplay/stateModelFactory.js +170 -0
  139. package/esm/LinearComparativeDisplay/stateModelFactory.js.map +1 -0
  140. package/esm/LinearComparativeView/components/Header.d.ts +7 -0
  141. package/esm/LinearComparativeView/components/Header.js +61 -0
  142. package/esm/LinearComparativeView/components/Header.js.map +1 -0
  143. package/esm/LinearComparativeView/components/LinearComparativeView.d.ts +8 -0
  144. package/esm/LinearComparativeView/components/LinearComparativeView.js +94 -0
  145. package/esm/LinearComparativeView/components/LinearComparativeView.js.map +1 -0
  146. package/esm/LinearComparativeView/components/Rubberband.d.ts +9 -0
  147. package/esm/LinearComparativeView/components/Rubberband.js +200 -0
  148. package/esm/LinearComparativeView/components/Rubberband.js.map +1 -0
  149. package/esm/LinearComparativeView/index.d.ts +3 -0
  150. package/esm/LinearComparativeView/index.js +14 -0
  151. package/esm/LinearComparativeView/index.js.map +1 -0
  152. package/esm/LinearComparativeView/model.d.ts +326 -0
  153. package/esm/LinearComparativeView/model.js +318 -0
  154. package/esm/LinearComparativeView/model.js.map +1 -0
  155. package/esm/LinearReadVsRef/LinearReadVsRef.d.ts +7 -0
  156. package/esm/LinearReadVsRef/LinearReadVsRef.js +258 -0
  157. package/esm/LinearReadVsRef/LinearReadVsRef.js.map +1 -0
  158. package/esm/LinearReadVsRef/index.d.ts +2 -0
  159. package/esm/LinearReadVsRef/index.js +49 -0
  160. package/esm/LinearReadVsRef/index.js.map +1 -0
  161. package/esm/LinearSyntenyDisplay/afterAttach.d.ts +2 -0
  162. package/esm/LinearSyntenyDisplay/afterAttach.js +104 -0
  163. package/esm/LinearSyntenyDisplay/afterAttach.js.map +1 -0
  164. package/esm/LinearSyntenyDisplay/components/Component.d.ts +6 -0
  165. package/esm/LinearSyntenyDisplay/components/Component.js +59 -0
  166. package/esm/LinearSyntenyDisplay/components/Component.js.map +1 -0
  167. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.d.ts +6 -0
  168. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +132 -0
  169. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js.map +1 -0
  170. package/esm/LinearSyntenyDisplay/components/SyntenyTooltip.d.ts +7 -0
  171. package/esm/LinearSyntenyDisplay/components/SyntenyTooltip.js +58 -0
  172. package/esm/LinearSyntenyDisplay/components/SyntenyTooltip.js.map +1 -0
  173. package/esm/LinearSyntenyDisplay/components/util.d.ts +27 -0
  174. package/esm/LinearSyntenyDisplay/components/util.js +77 -0
  175. package/esm/LinearSyntenyDisplay/components/util.js.map +1 -0
  176. package/esm/LinearSyntenyDisplay/configSchemaF.d.ts +23 -0
  177. package/esm/LinearSyntenyDisplay/configSchemaF.js +31 -0
  178. package/esm/LinearSyntenyDisplay/configSchemaF.js.map +1 -0
  179. package/esm/LinearSyntenyDisplay/drawSynteny.d.ts +5 -0
  180. package/esm/LinearSyntenyDisplay/drawSynteny.js +229 -0
  181. package/esm/LinearSyntenyDisplay/drawSynteny.js.map +1 -0
  182. package/esm/LinearSyntenyDisplay/index.d.ts +3 -0
  183. package/esm/LinearSyntenyDisplay/index.js +19 -0
  184. package/esm/LinearSyntenyDisplay/index.js.map +1 -0
  185. package/esm/LinearSyntenyDisplay/model.d.ts +333 -0
  186. package/esm/LinearSyntenyDisplay/model.js +151 -0
  187. package/esm/LinearSyntenyDisplay/model.js.map +1 -0
  188. package/esm/LinearSyntenyView/components/ExportSvgDialog.d.ts +8 -0
  189. package/esm/LinearSyntenyView/components/ExportSvgDialog.js +60 -0
  190. package/esm/LinearSyntenyView/components/ExportSvgDialog.js.map +1 -0
  191. package/esm/LinearSyntenyView/components/Icons.d.ts +4 -0
  192. package/esm/LinearSyntenyView/components/Icons.js +11 -0
  193. package/esm/LinearSyntenyView/components/Icons.js.map +1 -0
  194. package/esm/LinearSyntenyView/components/ImportCustomTrack.d.ts +11 -0
  195. package/esm/LinearSyntenyView/components/ImportCustomTrack.js +152 -0
  196. package/esm/LinearSyntenyView/components/ImportCustomTrack.js.map +1 -0
  197. package/esm/LinearSyntenyView/components/ImportForm.d.ts +6 -0
  198. package/esm/LinearSyntenyView/components/ImportForm.js +99 -0
  199. package/esm/LinearSyntenyView/components/ImportForm.js.map +1 -0
  200. package/esm/LinearSyntenyView/components/ImportSyntenyTrackSelector.d.ts +9 -0
  201. package/esm/LinearSyntenyView/components/ImportSyntenyTrackSelector.js +38 -0
  202. package/esm/LinearSyntenyView/components/ImportSyntenyTrackSelector.js.map +1 -0
  203. package/esm/LinearSyntenyView/components/LinearSyntenyView.d.ts +7 -0
  204. package/esm/LinearSyntenyView/components/LinearSyntenyView.js +10 -0
  205. package/esm/LinearSyntenyView/components/LinearSyntenyView.js.map +1 -0
  206. package/esm/LinearSyntenyView/index.d.ts +3 -0
  207. package/esm/LinearSyntenyView/index.js +14 -0
  208. package/esm/LinearSyntenyView/index.js.map +1 -0
  209. package/esm/LinearSyntenyView/model.d.ts +754 -0
  210. package/esm/LinearSyntenyView/model.js +141 -0
  211. package/esm/LinearSyntenyView/model.js.map +1 -0
  212. package/esm/LinearSyntenyView/svgcomponents/SVGBackground.d.ts +6 -0
  213. package/esm/LinearSyntenyView/svgcomponents/SVGBackground.js +7 -0
  214. package/esm/LinearSyntenyView/svgcomponents/SVGBackground.js.map +1 -0
  215. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.d.ts +4 -0
  216. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +78 -0
  217. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js.map +1 -0
  218. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.d.ts +5 -0
  219. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js +38 -0
  220. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js.map +1 -0
  221. package/esm/SyntenyFeatureDetail/index.d.ts +3 -0
  222. package/esm/SyntenyFeatureDetail/index.js +30 -0
  223. package/esm/SyntenyFeatureDetail/index.js.map +1 -0
  224. package/esm/SyntenyTrack/configSchema.d.ts +75 -0
  225. package/esm/SyntenyTrack/configSchema.js +14 -0
  226. package/esm/SyntenyTrack/configSchema.js.map +1 -0
  227. package/esm/SyntenyTrack/index.d.ts +3 -0
  228. package/esm/SyntenyTrack/index.js +14 -0
  229. package/esm/SyntenyTrack/index.js.map +1 -0
  230. package/esm/index.d.ts +7 -0
  231. package/esm/index.js +41 -0
  232. package/esm/index.js.map +1 -0
  233. package/esm/util.d.ts +25 -0
  234. package/esm/util.js +69 -0
  235. package/esm/util.js.map +1 -0
  236. package/package.json +67 -0
  237. package/src/LGVSyntenyDisplay/configSchemaF.ts +22 -0
  238. package/src/LGVSyntenyDisplay/index.ts +20 -0
  239. package/src/LGVSyntenyDisplay/model.ts +177 -0
  240. package/src/LaunchLinearSyntenyView.ts +86 -0
  241. package/src/LinearComparativeDisplay/configSchemaF.ts +22 -0
  242. package/src/LinearComparativeDisplay/index.ts +21 -0
  243. package/src/LinearComparativeDisplay/stateModelFactory.ts +212 -0
  244. package/src/LinearComparativeView/components/Header.tsx +103 -0
  245. package/src/LinearComparativeView/components/LinearComparativeView.tsx +152 -0
  246. package/src/LinearComparativeView/components/Rubberband.tsx +329 -0
  247. package/src/LinearComparativeView/index.ts +15 -0
  248. package/src/LinearComparativeView/model.ts +395 -0
  249. package/src/LinearReadVsRef/LinearReadVsRef.tsx +360 -0
  250. package/src/LinearReadVsRef/index.ts +58 -0
  251. package/src/LinearSyntenyDisplay/afterAttach.ts +149 -0
  252. package/src/LinearSyntenyDisplay/components/Component.tsx +75 -0
  253. package/src/LinearSyntenyDisplay/components/LinearSyntenyRendering.tsx +200 -0
  254. package/src/LinearSyntenyDisplay/components/SyntenyTooltip.tsx +82 -0
  255. package/src/LinearSyntenyDisplay/components/util.ts +142 -0
  256. package/src/LinearSyntenyDisplay/configSchemaF.ts +38 -0
  257. package/src/LinearSyntenyDisplay/drawSynteny.ts +266 -0
  258. package/src/LinearSyntenyDisplay/index.ts +21 -0
  259. package/src/LinearSyntenyDisplay/model.ts +187 -0
  260. package/src/LinearSyntenyView/components/ExportSvgDialog.tsx +148 -0
  261. package/src/LinearSyntenyView/components/Icons.tsx +24 -0
  262. package/src/LinearSyntenyView/components/ImportCustomTrack.tsx +262 -0
  263. package/src/LinearSyntenyView/components/ImportForm.tsx +221 -0
  264. package/src/LinearSyntenyView/components/ImportSyntenyTrackSelector.tsx +82 -0
  265. package/src/LinearSyntenyView/components/LinearSyntenyView.tsx +20 -0
  266. package/src/LinearSyntenyView/index.ts +15 -0
  267. package/src/LinearSyntenyView/model.test.ts +1605 -0
  268. package/src/LinearSyntenyView/model.ts +169 -0
  269. package/src/LinearSyntenyView/svgcomponents/SVGBackground.tsx +21 -0
  270. package/src/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.tsx +176 -0
  271. package/src/SyntenyFeatureDetail/SyntenyFeatureDetail.tsx +64 -0
  272. package/src/SyntenyFeatureDetail/index.ts +36 -0
  273. package/src/SyntenyTrack/configSchema.ts +23 -0
  274. package/src/SyntenyTrack/index.tsx +15 -0
  275. package/src/index.tsx +42 -0
  276. package/src/util.ts +124 -0
@@ -0,0 +1,103 @@
1
+ import React, { useState } from 'react'
2
+ import { IconButton, Typography } from '@mui/material'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { SearchBox } from '@jbrowse/plugin-linear-genome-view'
5
+ import { observer } from 'mobx-react'
6
+ import { Menu } from '@jbrowse/core/ui'
7
+
8
+ // icons
9
+ import MoreVertIcon from '@mui/icons-material/MoreVert'
10
+
11
+ // locals
12
+ import { LinearComparativeViewModel } from '../model'
13
+ import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons'
14
+
15
+ type LCV = LinearComparativeViewModel
16
+
17
+ const useStyles = makeStyles()(() => ({
18
+ headerBar: {
19
+ gridArea: '1/1/auto/span 2',
20
+ display: 'flex',
21
+ },
22
+ spacer: {
23
+ flexGrow: 1,
24
+ },
25
+ iconButton: {
26
+ margin: 5,
27
+ },
28
+ bp: {
29
+ display: 'flex',
30
+ alignItems: 'center',
31
+ marginLeft: 10,
32
+ },
33
+ searchContainer: {
34
+ marginLeft: 5,
35
+ },
36
+ searchBox: {
37
+ display: 'flex',
38
+ },
39
+ }))
40
+
41
+ const TrackSelector = observer(({ model }: { model: LCV }) => {
42
+ return (
43
+ <IconButton
44
+ onClick={model.activateTrackSelector}
45
+ title="Open track selector"
46
+ >
47
+ <TrackSelectorIcon />
48
+ </IconButton>
49
+ )
50
+ })
51
+
52
+ const Header = observer(function ({ model }: { model: LCV }) {
53
+ const { classes } = useStyles()
54
+ const [menuAnchorEl, setMenuAnchorEl] = useState<HTMLElement>()
55
+ const anyShowHeaders = model.views.some(view => !view.hideHeader)
56
+ return (
57
+ <div className={classes.headerBar}>
58
+ <TrackSelector model={model} />
59
+
60
+ <IconButton
61
+ onClick={event => setMenuAnchorEl(event.currentTarget)}
62
+ className={classes.iconButton}
63
+ >
64
+ <MoreVertIcon />
65
+ </IconButton>
66
+ {!anyShowHeaders
67
+ ? model.views.map(view => (
68
+ <div key={view.id} className={classes.searchBox}>
69
+ <div className={classes.searchContainer}>
70
+ <SearchBox model={view} showHelp={false} />
71
+ </div>
72
+ <div className={classes.bp}>
73
+ <Typography
74
+ variant="body2"
75
+ color="textSecondary"
76
+ className={classes.bp}
77
+ >
78
+ {Math.round(view.coarseTotalBp).toLocaleString('en-US')} bp
79
+ </Typography>
80
+ </div>
81
+ </div>
82
+ ))
83
+ : null}
84
+
85
+ <div className={classes.spacer} />
86
+
87
+ {menuAnchorEl ? (
88
+ <Menu
89
+ anchorEl={menuAnchorEl}
90
+ open
91
+ onMenuItemClick={(_event, callback) => {
92
+ callback()
93
+ setMenuAnchorEl(undefined)
94
+ }}
95
+ menuItems={model.headerMenuItems()}
96
+ onClose={() => setMenuAnchorEl(undefined)}
97
+ />
98
+ ) : null}
99
+ </div>
100
+ )
101
+ })
102
+
103
+ export default Header
@@ -0,0 +1,152 @@
1
+ import React from 'react'
2
+ import { makeStyles } from 'tss-react/mui'
3
+ import { observer } from 'mobx-react'
4
+ import { getConf, AnyConfigurationModel } from '@jbrowse/core/configuration'
5
+ import { getEnv } from '@jbrowse/core/util'
6
+ import { ResizeHandle } from '@jbrowse/core/ui'
7
+
8
+ // locals
9
+ import { LinearComparativeViewModel } from '../model'
10
+ import Rubberband from './Rubberband'
11
+ import Header from './Header'
12
+
13
+ const useStyles = makeStyles()(theme => ({
14
+ container: {
15
+ display: 'grid',
16
+ },
17
+ overlay: {
18
+ zIndex: 100,
19
+ gridArea: '1/1',
20
+ },
21
+ content: {
22
+ gridArea: '1/1',
23
+ position: 'relative',
24
+ },
25
+ grid: {
26
+ display: 'grid',
27
+ },
28
+ relative: {
29
+ position: 'relative',
30
+ },
31
+
32
+ // this helps keep the vertical guide inside the parent view container,
33
+ // similar style exists in the single LGV's trackscontainer
34
+ rubberbandContainer: {
35
+ position: 'relative',
36
+ overflow: 'hidden',
37
+ },
38
+
39
+ rubberbandDiv: {
40
+ width: '100%',
41
+ background: theme.palette.action.disabledBackground,
42
+ height: 15,
43
+ '&:hover': {
44
+ background: theme.palette.action.selected,
45
+ },
46
+ },
47
+ }))
48
+
49
+ type LCV = LinearComparativeViewModel
50
+
51
+ const Overlays = observer(({ model }: { model: LCV }) => {
52
+ const { classes } = useStyles()
53
+ return (
54
+ <>
55
+ {model.tracks.map(track => {
56
+ const [display] = track.displays
57
+ const { RenderingComponent } = display
58
+ const trackId = getConf(track, 'trackId')
59
+ return RenderingComponent ? (
60
+ <div
61
+ className={classes.overlay}
62
+ key={trackId}
63
+ style={{
64
+ height: model.middleComparativeHeight,
65
+ overflow: 'hidden',
66
+ }}
67
+ >
68
+ <RenderingComponent model={display} />
69
+ </div>
70
+ ) : null
71
+ })}
72
+ </>
73
+ )
74
+ })
75
+
76
+ // The comparative is in the middle of the views
77
+ const MiddleComparativeView = observer(({ model }: { model: LCV }) => {
78
+ const { classes } = useStyles()
79
+ const { views } = model
80
+ const { pluginManager } = getEnv(model)
81
+ const { ReactComponent } = pluginManager.getViewType(views[0].type)
82
+
83
+ return (
84
+ <div className={classes.rubberbandContainer}>
85
+ <Header model={model} />
86
+ <Rubberband
87
+ model={model}
88
+ ControlComponent={<div className={classes.rubberbandDiv} />}
89
+ />
90
+ <div className={classes.container}>
91
+ <ReactComponent model={views[0]} />
92
+ <div className={classes.grid}>
93
+ <Overlays model={model} />
94
+ </div>
95
+ <ResizeHandle
96
+ onDrag={n =>
97
+ model.setMiddleComparativeHeight(model.middleComparativeHeight + n)
98
+ }
99
+ style={{
100
+ height: 4,
101
+ background: '#ccc',
102
+ }}
103
+ />
104
+ <ReactComponent model={views[1]} />
105
+ </div>
106
+ </div>
107
+ )
108
+ })
109
+ const OverlayComparativeView = observer(({ model }: { model: LCV }) => {
110
+ const { classes } = useStyles()
111
+ const { views } = model
112
+ const { pluginManager } = getEnv(model)
113
+ return (
114
+ <div className={classes.rubberbandContainer}>
115
+ <Header model={model} />
116
+ <Rubberband
117
+ model={model}
118
+ ControlComponent={<div className={classes.rubberbandDiv} />}
119
+ />
120
+
121
+ <div className={classes.container}>
122
+ <div className={classes.content}>
123
+ <div className={classes.relative}>
124
+ {views.map(view => {
125
+ const { ReactComponent } = pluginManager.getViewType(view.type)
126
+ return <ReactComponent key={view.id} model={view} />
127
+ })}
128
+ </div>
129
+ <Overlays model={model} />
130
+ </div>
131
+ </div>
132
+ </div>
133
+ )
134
+ })
135
+
136
+ export default observer(function (props: {
137
+ ExtraButtons?: React.ReactNode
138
+ model: LCV
139
+ }) {
140
+ const { model } = props
141
+
142
+ const middle = model.tracks.some(({ displays }) =>
143
+ displays.some((d: { configuration: AnyConfigurationModel }) =>
144
+ getConf(d, 'middle'),
145
+ ),
146
+ )
147
+ return middle ? (
148
+ <MiddleComparativeView {...props} />
149
+ ) : (
150
+ <OverlayComparativeView {...props} />
151
+ )
152
+ })
@@ -0,0 +1,329 @@
1
+ import React, { useRef, useEffect, useState } from 'react'
2
+ import { observer } from 'mobx-react'
3
+ import { Popover, Tooltip, Typography, alpha } from '@mui/material'
4
+ import { makeStyles } from 'tss-react/mui'
5
+ import { stringify } from '@jbrowse/core/util'
6
+ import { Menu } from '@jbrowse/core/ui'
7
+ import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
8
+ import { LinearComparativeViewModel } from '../model'
9
+
10
+ type LCV = LinearComparativeViewModel
11
+ type LGV = LinearGenomeViewModel
12
+
13
+ const useStyles = makeStyles()(theme => {
14
+ const { tertiary, primary } = theme.palette
15
+ const background = tertiary
16
+ ? alpha(tertiary.main, 0.7)
17
+ : alpha(primary.main, 0.7)
18
+ return {
19
+ rubberband: {
20
+ height: '100%',
21
+ background,
22
+ position: 'absolute',
23
+ zIndex: 10,
24
+ textAlign: 'center',
25
+ overflow: 'hidden',
26
+ },
27
+ rubberbandControl: {
28
+ cursor: 'crosshair',
29
+ width: '100%',
30
+ minHeight: 8,
31
+ },
32
+ rubberbandText: {
33
+ color: tertiary ? tertiary.contrastText : primary.contrastText,
34
+ },
35
+ popover: {
36
+ mouseEvents: 'none',
37
+ cursor: 'crosshair',
38
+ },
39
+ paper: {
40
+ paddingLeft: theme.spacing(1),
41
+ paddingRight: theme.spacing(1),
42
+ },
43
+ guide: {
44
+ pointerEvents: 'none',
45
+ height: '100%',
46
+ width: 1,
47
+ position: 'absolute',
48
+ zIndex: 10,
49
+ },
50
+ sm: {
51
+ fontSize: 10,
52
+ },
53
+ }
54
+ })
55
+
56
+ const VerticalGuide = observer(
57
+ ({ model, coordX }: { model: LCV; coordX: number }) => {
58
+ const { classes } = useStyles()
59
+ return (
60
+ <Tooltip
61
+ open
62
+ placement="top"
63
+ title={model.views
64
+ .map(view => view.pxToBp(coordX))
65
+ .map(elt => (
66
+ <Typography className={classes.sm} key={JSON.stringify(elt)}>
67
+ {stringify(elt)}
68
+ </Typography>
69
+ ))}
70
+ arrow
71
+ >
72
+ <div
73
+ className={classes.guide}
74
+ style={{
75
+ left: coordX,
76
+ background: 'red',
77
+ }}
78
+ />
79
+ </Tooltip>
80
+ )
81
+ },
82
+ )
83
+
84
+ function Rubberband({
85
+ model,
86
+ ControlComponent = <div />,
87
+ }: {
88
+ model: LCV
89
+ ControlComponent?: React.ReactElement
90
+ }) {
91
+ const [startX, setStartX] = useState<number>()
92
+ const [currentX, setCurrentX] = useState<number>()
93
+
94
+ // clientX and clientY used for anchorPosition for menu
95
+ // offsetX used for calculations about width of selection
96
+ const [anchorPosition, setAnchorPosition] = useState<{
97
+ offsetX: number
98
+ clientX: number
99
+ clientY: number
100
+ }>()
101
+ const [guideX, setGuideX] = useState<number>()
102
+ const controlsRef = useRef<HTMLDivElement>(null)
103
+ const rubberbandRef = useRef(null)
104
+ const { classes } = useStyles()
105
+ const mouseDragging = startX !== undefined && anchorPosition === undefined
106
+
107
+ useEffect(() => {
108
+ function computeOffsets(offsetX: number, view: LGV) {
109
+ if (startX === undefined) {
110
+ return
111
+ }
112
+ let leftPx = startX
113
+ let rightPx = offsetX
114
+ // handles clicking and dragging to the left
115
+ if (rightPx < leftPx) {
116
+ ;[leftPx, rightPx] = [rightPx, leftPx]
117
+ }
118
+ const leftOffset = view.pxToBp(leftPx)
119
+ const rightOffset = view.pxToBp(rightPx)
120
+
121
+ return { leftOffset, rightOffset }
122
+ }
123
+
124
+ function globalMouseMove(event: MouseEvent) {
125
+ if (controlsRef.current && mouseDragging) {
126
+ const relativeX =
127
+ event.clientX - controlsRef.current.getBoundingClientRect().left
128
+ setCurrentX(relativeX)
129
+ }
130
+ }
131
+
132
+ function globalMouseUp(event: MouseEvent) {
133
+ if (startX !== undefined && controlsRef.current) {
134
+ const { clientX, clientY } = event
135
+ const ref = controlsRef.current
136
+ const offsetX = clientX - ref.getBoundingClientRect().left
137
+ // as stated above, store both clientX/Y and offsetX for different
138
+ // purposes
139
+ setAnchorPosition({
140
+ offsetX,
141
+ clientX,
142
+ clientY,
143
+ })
144
+ model.views.forEach(view => {
145
+ const args = computeOffsets(offsetX, view)
146
+ if (args) {
147
+ const { leftOffset, rightOffset } = args
148
+ view.setOffsets(leftOffset, rightOffset)
149
+ }
150
+ })
151
+ setGuideX(undefined)
152
+ }
153
+ }
154
+ if (mouseDragging) {
155
+ window.addEventListener('mousemove', globalMouseMove)
156
+ window.addEventListener('mouseup', globalMouseUp)
157
+ return () => {
158
+ window.removeEventListener('mousemove', globalMouseMove)
159
+ window.removeEventListener('mouseup', globalMouseUp)
160
+ }
161
+ }
162
+ return () => {}
163
+ }, [startX, mouseDragging, anchorPosition, model])
164
+
165
+ useEffect(() => {
166
+ if (
167
+ !mouseDragging &&
168
+ currentX !== undefined &&
169
+ startX !== undefined &&
170
+ Math.abs(currentX - startX) <= 3
171
+ ) {
172
+ handleClose()
173
+ }
174
+ }, [mouseDragging, currentX, startX])
175
+
176
+ function mouseDown(event: React.MouseEvent<HTMLDivElement>) {
177
+ event.preventDefault()
178
+ event.stopPropagation()
179
+ const relativeX =
180
+ event.clientX -
181
+ (event.target as HTMLDivElement).getBoundingClientRect().left
182
+ setStartX(relativeX)
183
+ setCurrentX(relativeX)
184
+ }
185
+
186
+ function mouseMove(event: React.MouseEvent<HTMLDivElement>) {
187
+ const target = event.target as HTMLDivElement
188
+ setGuideX(event.clientX - target.getBoundingClientRect().left)
189
+ }
190
+
191
+ function mouseOut() {
192
+ setGuideX(undefined)
193
+ model.views.forEach(view => view.setOffsets(undefined, undefined))
194
+ }
195
+
196
+ function handleClose() {
197
+ setAnchorPosition(undefined)
198
+ setStartX(undefined)
199
+ setCurrentX(undefined)
200
+ }
201
+
202
+ const open = Boolean(anchorPosition)
203
+
204
+ function handleMenuItemClick(_: unknown, callback: Function) {
205
+ callback()
206
+ handleClose()
207
+ }
208
+
209
+ if (startX === undefined) {
210
+ return (
211
+ <>
212
+ {guideX !== undefined ? (
213
+ <VerticalGuide model={model} coordX={guideX} />
214
+ ) : null}
215
+ <div
216
+ data-testid="rubberband_controls"
217
+ className={classes.rubberbandControl}
218
+ role="presentation"
219
+ ref={controlsRef}
220
+ onMouseDown={mouseDown}
221
+ onMouseOut={mouseOut}
222
+ onMouseMove={mouseMove}
223
+ >
224
+ {ControlComponent}
225
+ </div>
226
+ </>
227
+ )
228
+ }
229
+
230
+ /* Calculating Pixels for Mouse Dragging */
231
+ const right = anchorPosition ? anchorPosition.offsetX : currentX || 0
232
+ const left = right < startX ? right : startX
233
+ const width = Math.abs(right - startX)
234
+ const { views } = model
235
+ const leftBpOffset = views.map(view => view.pxToBp(left))
236
+ const rightBpOffset = views.map(view => view.pxToBp(left + width))
237
+ const numOfBpSelected = views.map(view => Math.ceil(width * view.bpPerPx))
238
+ return (
239
+ <>
240
+ {rubberbandRef.current ? (
241
+ <>
242
+ <Popover
243
+ className={classes.popover}
244
+ classes={{
245
+ paper: classes.paper,
246
+ }}
247
+ open
248
+ anchorEl={rubberbandRef.current}
249
+ anchorOrigin={{
250
+ vertical: 'top',
251
+ horizontal: 'left',
252
+ }}
253
+ transformOrigin={{
254
+ vertical: 'bottom',
255
+ horizontal: 'right',
256
+ }}
257
+ keepMounted
258
+ disableRestoreFocus
259
+ >
260
+ {leftBpOffset.map(l => (
261
+ <Typography key={JSON.stringify(l)}>{stringify(l)}</Typography>
262
+ ))}
263
+ </Popover>
264
+ <Popover
265
+ className={classes.popover}
266
+ classes={{
267
+ paper: classes.paper,
268
+ }}
269
+ open
270
+ anchorEl={rubberbandRef.current}
271
+ anchorOrigin={{
272
+ vertical: 'top',
273
+ horizontal: 'right',
274
+ }}
275
+ transformOrigin={{
276
+ vertical: 'bottom',
277
+ horizontal: 'left',
278
+ }}
279
+ keepMounted
280
+ disableRestoreFocus
281
+ >
282
+ {rightBpOffset.map(l => (
283
+ <Typography key={JSON.stringify(l)}>{stringify(l)}</Typography>
284
+ ))}
285
+ </Popover>
286
+ </>
287
+ ) : null}
288
+ <div
289
+ ref={rubberbandRef}
290
+ className={classes.rubberband}
291
+ style={{ left, width }}
292
+ >
293
+ <Typography variant="h6" className={classes.rubberbandText}>
294
+ {numOfBpSelected.map((n, i) => (
295
+ <Typography key={`${n}_${i}`}>{`${n.toLocaleString(
296
+ 'en-US',
297
+ )}bp`}</Typography>
298
+ ))}
299
+ </Typography>
300
+ </div>
301
+ <div
302
+ data-testid="rubberband_controls"
303
+ className={classes.rubberbandControl}
304
+ role="presentation"
305
+ ref={controlsRef}
306
+ onMouseDown={mouseDown}
307
+ onMouseOut={mouseOut}
308
+ onMouseMove={mouseMove}
309
+ >
310
+ {ControlComponent}
311
+ </div>
312
+ {anchorPosition ? (
313
+ <Menu
314
+ anchorReference="anchorPosition"
315
+ anchorPosition={{
316
+ left: anchorPosition.clientX,
317
+ top: anchorPosition.clientY,
318
+ }}
319
+ onMenuItemClick={handleMenuItemClick}
320
+ open={open}
321
+ onClose={handleClose}
322
+ menuItems={model.rubberBandMenuItems()}
323
+ />
324
+ ) : null}
325
+ </>
326
+ )
327
+ }
328
+
329
+ export default observer(Rubberband)
@@ -0,0 +1,15 @@
1
+ import { lazy } from 'react'
2
+ import PluginManager from '@jbrowse/core/PluginManager'
3
+ import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'
4
+ import modelFactory from './model'
5
+
6
+ export default (pluginManager: PluginManager) => {
7
+ pluginManager.addViewType(() => {
8
+ return new ViewType({
9
+ name: 'LinearComparativeView',
10
+ displayName: 'Linear comparative view',
11
+ stateModel: modelFactory(pluginManager),
12
+ ReactComponent: lazy(() => import('./components/LinearComparativeView')),
13
+ })
14
+ })
15
+ }