react-msaview 2.1.5 → 3.0.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 (199) hide show
  1. package/bundle/index.js +37 -255
  2. package/dist/DialogQueue.d.ts +25 -0
  3. package/dist/DialogQueue.js +46 -0
  4. package/dist/DialogQueue.js.map +1 -0
  5. package/dist/UniprotTrack.js.map +1 -1
  6. package/dist/colorSchemes.js.map +1 -1
  7. package/dist/components/BoxTrackBlock.js +3 -2
  8. package/dist/components/BoxTrackBlock.js.map +1 -1
  9. package/dist/components/Header.js +12 -20
  10. package/dist/components/Header.js.map +1 -1
  11. package/dist/components/HeaderInfoArea.d.ts +6 -0
  12. package/dist/components/HeaderInfoArea.js +12 -0
  13. package/dist/components/HeaderInfoArea.js.map +1 -0
  14. package/dist/components/ImportForm/ImportFormExamples.d.ts +6 -0
  15. package/dist/components/ImportForm/ImportFormExamples.js +50 -0
  16. package/dist/components/ImportForm/ImportFormExamples.js.map +1 -0
  17. package/dist/components/ImportForm/data/seq2.js.map +1 -0
  18. package/dist/components/{ImportForm.d.ts → ImportForm/index.d.ts} +1 -1
  19. package/dist/components/ImportForm/index.js +31 -0
  20. package/dist/components/ImportForm/index.js.map +1 -0
  21. package/dist/components/ImportForm/util.d.ts +3 -0
  22. package/dist/components/ImportForm/util.js +15 -0
  23. package/dist/components/ImportForm/util.js.map +1 -0
  24. package/dist/components/MSAPanel/Loading.d.ts +2 -0
  25. package/dist/components/MSAPanel/Loading.js +12 -0
  26. package/dist/components/MSAPanel/Loading.js.map +1 -0
  27. package/dist/components/{MSABlock.d.ts → MSAPanel/MSABlock.d.ts} +1 -1
  28. package/dist/components/MSAPanel/MSABlock.js +46 -0
  29. package/dist/components/MSAPanel/MSABlock.js.map +1 -0
  30. package/dist/components/{MSACanvas.d.ts → MSAPanel/MSACanvas.d.ts} +1 -1
  31. package/dist/components/{MSACanvas.js → MSAPanel/MSACanvas.js} +2 -4
  32. package/dist/components/MSAPanel/MSACanvas.js.map +1 -0
  33. package/dist/components/{MSAMouseoverCanvas.d.ts → MSAPanel/MSAMouseoverCanvas.d.ts} +1 -1
  34. package/dist/components/MSAPanel/MSAMouseoverCanvas.js +29 -0
  35. package/dist/components/MSAPanel/MSAMouseoverCanvas.js.map +1 -0
  36. package/dist/components/MSAPanel/index.d.ts +5 -0
  37. package/dist/components/MSAPanel/index.js +9 -0
  38. package/dist/components/MSAPanel/index.js.map +1 -0
  39. package/dist/components/MSAPanel/renderMSABlock.d.ts +8 -0
  40. package/dist/components/MSAPanel/renderMSABlock.js +80 -0
  41. package/dist/components/MSAPanel/renderMSABlock.js.map +1 -0
  42. package/dist/components/MSAPanel/renderMSAMouseover.d.ts +5 -0
  43. package/dist/components/MSAPanel/renderMSAMouseover.js +24 -0
  44. package/dist/components/MSAPanel/renderMSAMouseover.js.map +1 -0
  45. package/dist/components/MSAView.d.ts +2 -2
  46. package/dist/components/MSAView.js +26 -31
  47. package/dist/components/MSAView.js.map +1 -1
  48. package/dist/components/Minimap.d.ts +6 -0
  49. package/dist/components/Minimap.js +72 -0
  50. package/dist/components/Minimap.js.map +1 -0
  51. package/dist/components/ResizeHandles.js.map +1 -1
  52. package/dist/components/TextTrack.js +3 -2
  53. package/dist/components/TextTrack.js.map +1 -1
  54. package/dist/components/Track.js +5 -5
  55. package/dist/components/Track.js.map +1 -1
  56. package/dist/components/{TreeBranchMenu.d.ts → TreePanel/TreeBranchMenu.d.ts} +1 -1
  57. package/dist/components/TreePanel/TreeBranchMenu.js.map +1 -0
  58. package/dist/components/{TreeCanvas.d.ts → TreePanel/TreeCanvas.d.ts} +1 -1
  59. package/dist/components/{TreeCanvas.js → TreePanel/TreeCanvas.js} +1 -1
  60. package/dist/components/TreePanel/TreeCanvas.js.map +1 -0
  61. package/dist/components/{TreeCanvasBlock.d.ts → TreePanel/TreeCanvasBlock.d.ts} +1 -1
  62. package/dist/components/TreePanel/TreeCanvasBlock.js +121 -0
  63. package/dist/components/TreePanel/TreeCanvasBlock.js.map +1 -0
  64. package/dist/components/{TreeMenu.d.ts → TreePanel/TreeNodeMenu.d.ts} +2 -1
  65. package/dist/components/{TreeMenu.js → TreePanel/TreeNodeMenu.js} +16 -8
  66. package/dist/components/TreePanel/TreeNodeMenu.js.map +1 -0
  67. package/dist/components/{TreeRuler.d.ts → TreePanel/TreeRuler.d.ts} +1 -1
  68. package/dist/components/TreePanel/TreeRuler.js +8 -0
  69. package/dist/components/TreePanel/TreeRuler.js.map +1 -0
  70. package/dist/components/{dialogs/TreeNodeInfoDlg.d.ts → TreePanel/dialogs/TreeNodeInfoDialog.d.ts} +1 -1
  71. package/dist/components/{dialogs/TreeNodeInfoDlg.js → TreePanel/dialogs/TreeNodeInfoDialog.js} +2 -2
  72. package/dist/components/TreePanel/dialogs/TreeNodeInfoDialog.js.map +1 -0
  73. package/dist/components/TreePanel/index.d.ts +6 -0
  74. package/dist/components/TreePanel/index.js +10 -0
  75. package/dist/components/TreePanel/index.js.map +1 -0
  76. package/dist/components/TreePanel/renderTreeCanvas.d.ts +41 -0
  77. package/dist/components/TreePanel/renderTreeCanvas.js +154 -0
  78. package/dist/components/TreePanel/renderTreeCanvas.js.map +1 -0
  79. package/dist/components/dialogs/{AboutDlg.js → AboutDialog.js} +1 -1
  80. package/dist/components/dialogs/AboutDialog.js.map +1 -0
  81. package/dist/components/dialogs/{AddTrackDlg.js → AddTrackDialog.js} +1 -1
  82. package/dist/components/dialogs/AddTrackDialog.js.map +1 -0
  83. package/dist/components/dialogs/{MetadataDlg.js → MetadataDialog.js} +1 -1
  84. package/dist/components/dialogs/MetadataDialog.js.map +1 -0
  85. package/dist/components/dialogs/SettingsDialog.js +63 -0
  86. package/dist/components/dialogs/SettingsDialog.js.map +1 -0
  87. package/dist/components/dialogs/{TrackInfoDlg.js → TrackInfoDialog.js} +1 -1
  88. package/dist/components/dialogs/TrackInfoDialog.js.map +1 -0
  89. package/dist/components/dialogs/{TracklistDlg.js → TracklistDialog.js} +1 -1
  90. package/dist/components/dialogs/TracklistDialog.js.map +1 -0
  91. package/dist/components/util.js.map +1 -1
  92. package/dist/layout.js.map +1 -1
  93. package/dist/model.d.ts +179 -88
  94. package/dist/model.js +287 -175
  95. package/dist/model.js.map +1 -1
  96. package/dist/parseNewick.js.map +1 -1
  97. package/dist/parsers/ClustalMSA.d.ts +1 -1
  98. package/dist/parsers/ClustalMSA.js +1 -1
  99. package/dist/parsers/ClustalMSA.js.map +1 -1
  100. package/dist/parsers/FastaMSA.d.ts +1 -1
  101. package/dist/parsers/FastaMSA.js +2 -2
  102. package/dist/parsers/FastaMSA.js.map +1 -1
  103. package/dist/parsers/StockholmMSA.d.ts +1 -1
  104. package/dist/parsers/StockholmMSA.js +2 -2
  105. package/dist/parsers/StockholmMSA.js.map +1 -1
  106. package/dist/util.d.ts +1 -0
  107. package/dist/util.js +15 -7
  108. package/dist/util.js.map +1 -1
  109. package/dist/version.d.ts +1 -1
  110. package/dist/version.js +1 -1
  111. package/package.json +6 -4
  112. package/src/DialogQueue.ts +47 -0
  113. package/src/components/BoxTrackBlock.tsx +3 -1
  114. package/src/components/Header.tsx +13 -20
  115. package/src/components/HeaderInfoArea.tsx +21 -0
  116. package/src/components/ImportForm/ImportFormExamples.tsx +133 -0
  117. package/src/components/ImportForm/index.tsx +63 -0
  118. package/src/components/ImportForm/util.ts +20 -0
  119. package/src/components/MSAPanel/Loading.tsx +16 -0
  120. package/src/components/MSAPanel/MSABlock.tsx +81 -0
  121. package/src/components/{MSACanvas.tsx → MSAPanel/MSACanvas.tsx} +3 -6
  122. package/src/components/MSAPanel/MSAMouseoverCanvas.tsx +44 -0
  123. package/src/components/MSAPanel/index.tsx +13 -0
  124. package/src/components/MSAPanel/renderMSABlock.ts +158 -0
  125. package/src/components/MSAPanel/renderMSAMouseover.ts +51 -0
  126. package/src/components/MSAView.tsx +36 -56
  127. package/src/components/Minimap.tsx +102 -0
  128. package/src/components/TextTrack.tsx +3 -1
  129. package/src/components/Track.tsx +5 -5
  130. package/src/components/{TreeBranchMenu.tsx → TreePanel/TreeBranchMenu.tsx} +1 -1
  131. package/src/components/{TreeCanvas.tsx → TreePanel/TreeCanvas.tsx} +2 -3
  132. package/src/components/TreePanel/TreeCanvasBlock.tsx +195 -0
  133. package/src/components/{TreeMenu.tsx → TreePanel/TreeNodeMenu.tsx} +21 -8
  134. package/src/components/{TreeRuler.tsx → TreePanel/TreeRuler.tsx} +3 -3
  135. package/src/components/{dialogs/TreeNodeInfoDlg.tsx → TreePanel/dialogs/TreeNodeInfoDialog.tsx} +2 -2
  136. package/src/components/TreePanel/index.tsx +16 -0
  137. package/src/components/TreePanel/renderTreeCanvas.ts +254 -0
  138. package/src/components/dialogs/SettingsDialog.tsx +196 -0
  139. package/src/model.ts +414 -211
  140. package/src/parsers/ClustalMSA.ts +1 -1
  141. package/src/parsers/FastaMSA.ts +1 -1
  142. package/src/parsers/StockholmMSA.ts +1 -1
  143. package/src/util.ts +19 -6
  144. package/src/version.ts +1 -1
  145. package/dist/components/ImportForm.js +0 -84
  146. package/dist/components/ImportForm.js.map +0 -1
  147. package/dist/components/MSABlock.js +0 -103
  148. package/dist/components/MSABlock.js.map +0 -1
  149. package/dist/components/MSACanvas.js.map +0 -1
  150. package/dist/components/MSAMouseoverCanvas.js +0 -61
  151. package/dist/components/MSAMouseoverCanvas.js.map +0 -1
  152. package/dist/components/Rubberband.d.ts +0 -8
  153. package/dist/components/Rubberband.js +0 -173
  154. package/dist/components/Rubberband.js.map +0 -1
  155. package/dist/components/Ruler.d.ts +0 -6
  156. package/dist/components/Ruler.js +0 -52
  157. package/dist/components/Ruler.js.map +0 -1
  158. package/dist/components/TreeBranchMenu.js.map +0 -1
  159. package/dist/components/TreeCanvas.js.map +0 -1
  160. package/dist/components/TreeCanvasBlock.js +0 -255
  161. package/dist/components/TreeCanvasBlock.js.map +0 -1
  162. package/dist/components/TreeMenu.js.map +0 -1
  163. package/dist/components/TreeRuler.js +0 -8
  164. package/dist/components/TreeRuler.js.map +0 -1
  165. package/dist/components/data/seq2.js.map +0 -1
  166. package/dist/components/dialogs/AboutDlg.js.map +0 -1
  167. package/dist/components/dialogs/AddTrackDlg.js.map +0 -1
  168. package/dist/components/dialogs/AnnotationDlg.d.ts +0 -11
  169. package/dist/components/dialogs/AnnotationDlg.js +0 -65
  170. package/dist/components/dialogs/AnnotationDlg.js.map +0 -1
  171. package/dist/components/dialogs/MetadataDlg.js.map +0 -1
  172. package/dist/components/dialogs/SettingsDlg.js +0 -48
  173. package/dist/components/dialogs/SettingsDlg.js.map +0 -1
  174. package/dist/components/dialogs/TrackInfoDlg.js.map +0 -1
  175. package/dist/components/dialogs/TracklistDlg.js.map +0 -1
  176. package/dist/components/dialogs/TreeNodeInfoDlg.js.map +0 -1
  177. package/src/components/ImportForm.tsx +0 -192
  178. package/src/components/MSABlock.tsx +0 -164
  179. package/src/components/MSAMouseoverCanvas.tsx +0 -99
  180. package/src/components/Rubberband.tsx +0 -270
  181. package/src/components/Ruler.tsx +0 -123
  182. package/src/components/TreeCanvasBlock.tsx +0 -363
  183. package/src/components/dialogs/AnnotationDlg.tsx +0 -144
  184. package/src/components/dialogs/SettingsDlg.tsx +0 -154
  185. /package/dist/components/{data → ImportForm/data}/seq2.d.ts +0 -0
  186. /package/dist/components/{data → ImportForm/data}/seq2.js +0 -0
  187. /package/dist/components/{TreeBranchMenu.js → TreePanel/TreeBranchMenu.js} +0 -0
  188. /package/dist/components/dialogs/{AboutDlg.d.ts → AboutDialog.d.ts} +0 -0
  189. /package/dist/components/dialogs/{AddTrackDlg.d.ts → AddTrackDialog.d.ts} +0 -0
  190. /package/dist/components/dialogs/{MetadataDlg.d.ts → MetadataDialog.d.ts} +0 -0
  191. /package/dist/components/dialogs/{SettingsDlg.d.ts → SettingsDialog.d.ts} +0 -0
  192. /package/dist/components/dialogs/{TrackInfoDlg.d.ts → TrackInfoDialog.d.ts} +0 -0
  193. /package/dist/components/dialogs/{TracklistDlg.d.ts → TracklistDialog.d.ts} +0 -0
  194. /package/src/components/{data → ImportForm/data}/seq2.ts +0 -0
  195. /package/src/components/dialogs/{AboutDlg.tsx → AboutDialog.tsx} +0 -0
  196. /package/src/components/dialogs/{AddTrackDlg.tsx → AddTrackDialog.tsx} +0 -0
  197. /package/src/components/dialogs/{MetadataDlg.tsx → MetadataDialog.tsx} +0 -0
  198. /package/src/components/dialogs/{TrackInfoDlg.tsx → TrackInfoDialog.tsx} +0 -0
  199. /package/src/components/dialogs/{TracklistDlg.tsx → TracklistDialog.tsx} +0 -0
@@ -1,363 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react'
2
- import { observer } from 'mobx-react'
3
- import RBush from 'rbush'
4
-
5
- // locals
6
- import { MsaViewModel } from '../model'
7
- import TreeMenu from './TreeMenu'
8
- import TreeBranchMenu from './TreeBranchMenu'
9
-
10
- const extendBounds = 5
11
- const radius = 3.5
12
- const d = radius * 2
13
-
14
- const padding = 600
15
-
16
- interface TooltipData {
17
- name: string
18
- id: string
19
- x: number
20
- y: number
21
- }
22
-
23
- interface ClickEntry {
24
- name: string
25
- id: string
26
- branch?: boolean
27
- minX: number
28
- maxX: number
29
- minY: number
30
- maxY: number
31
- }
32
-
33
- const TreeCanvasBlock = observer(function ({
34
- model,
35
- offsetY,
36
- }: {
37
- model: MsaViewModel
38
- offsetY: number
39
- }) {
40
- const ref = useRef<HTMLCanvasElement>(null)
41
- const clickMap = useRef(new RBush<ClickEntry>())
42
- const mouseoverRef = useRef<HTMLCanvasElement>(null)
43
- const [branchMenu, setBranchMenu] = useState<TooltipData>()
44
- const [toggleNodeMenu, setToggleNodeMenu] = useState<TooltipData>()
45
- const [hoverElt, setHoverElt] = useState<ClickEntry>()
46
-
47
- const {
48
- hierarchy,
49
- rowHeight,
50
- scrollY,
51
- treeWidth,
52
- treeMetadata,
53
- showBranchLen,
54
- collapsed,
55
- margin,
56
- labelsAlignRight,
57
- noTree,
58
- blockSize,
59
- drawNodeBubbles,
60
- drawTree,
61
- treeAreaWidth,
62
- structures,
63
- highResScaleFactor,
64
- } = model
65
-
66
- useEffect(() => {
67
- clickMap.current.clear()
68
-
69
- if (!ref.current) {
70
- return
71
- }
72
- const ctx = ref.current.getContext('2d')
73
- if (!ctx) {
74
- return
75
- }
76
-
77
- ctx.resetTransform()
78
- ctx.scale(highResScaleFactor, highResScaleFactor)
79
- ctx.clearRect(0, 0, treeWidth + padding, blockSize)
80
- ctx.translate(margin.left, -offsetY)
81
-
82
- const font = ctx.font
83
- ctx.font = font.replace(/\d+px/, `${Math.max(8, rowHeight - 8)}px`)
84
-
85
- if (!noTree && drawTree) {
86
- for (const { source, target } of hierarchy.links()) {
87
- const y = showBranchLen ? 'len' : 'y'
88
- // @ts-expect-error
89
- const { x: sy, [y]: sx } = source
90
- // @ts-expect-error
91
- const { x: ty, [y]: tx } = target
92
-
93
- const y1 = Math.min(sy, ty)
94
- const y2 = Math.max(sy, ty)
95
- // 1d line intersection to check if line crosses block at all, this is
96
- // an optimization that allows us to skip drawing most tree links
97
- // outside the block
98
- if (offsetY + blockSize >= y1 && y2 >= offsetY) {
99
- ctx.beginPath()
100
- ctx.moveTo(sx, sy)
101
- ctx.lineTo(sx, ty)
102
- ctx.lineTo(tx, ty)
103
- ctx.stroke()
104
- }
105
- }
106
-
107
- if (drawNodeBubbles) {
108
- for (const node of hierarchy.descendants()) {
109
- const val = showBranchLen ? 'len' : 'y'
110
- const {
111
- // @ts-expect-error
112
- x: y,
113
- // @ts-expect-error
114
- [val]: x,
115
- data,
116
- } = node
117
- const { id = '', name = '' } = data
118
-
119
- if (
120
- y > offsetY - extendBounds &&
121
- y < offsetY + blockSize + extendBounds
122
- ) {
123
- ctx.strokeStyle = 'black'
124
- ctx.fillStyle = collapsed.includes(id) ? 'black' : 'white'
125
- ctx.beginPath()
126
- ctx.arc(x, y, radius, 0, 2 * Math.PI)
127
- ctx.fill()
128
- ctx.stroke()
129
-
130
- clickMap.current.insert({
131
- minX: x - radius,
132
- maxX: x - radius + d,
133
- minY: y - radius,
134
- maxY: y - radius + d,
135
- branch: true,
136
- id,
137
- name,
138
- })
139
- }
140
- }
141
- }
142
- }
143
-
144
- if (rowHeight >= 5) {
145
- if (labelsAlignRight) {
146
- ctx.textAlign = 'right'
147
- ctx.setLineDash([1, 3])
148
- } else {
149
- ctx.textAlign = 'start'
150
- }
151
- for (const node of hierarchy.leaves()) {
152
- const {
153
- // @ts-expect-error
154
- x: y,
155
- // @ts-expect-error
156
- y: x,
157
- data: { name, id },
158
- // @ts-expect-error
159
- len,
160
- } = node
161
-
162
- const displayName = treeMetadata[name]?.genome || name
163
-
164
- if (
165
- y > offsetY - extendBounds &&
166
- y < offsetY + blockSize + extendBounds
167
- ) {
168
- // note: +rowHeight/4 matches with -rowHeight/4 in msa
169
- const yp = y + rowHeight / 4
170
- const xp = showBranchLen ? len : x
171
-
172
- const { width } = ctx.measureText(displayName)
173
- const height = ctx.measureText('M').width // use an 'em' for height
174
-
175
- const hasStructure = structures[name]
176
- ctx.fillStyle = hasStructure ? 'blue' : 'black'
177
-
178
- if (!drawTree && !labelsAlignRight) {
179
- ctx.fillText(displayName, 0, yp)
180
- clickMap.current.insert({
181
- minX: 0,
182
- maxX: width,
183
- minY: yp - height,
184
- maxY: yp,
185
- name,
186
- id,
187
- })
188
- } else if (labelsAlignRight) {
189
- const smallPadding = 2
190
- const offset = treeAreaWidth - smallPadding - margin.left
191
- if (drawTree && !noTree) {
192
- const { width } = ctx.measureText(displayName)
193
- ctx.moveTo(xp + radius + 2, y)
194
- ctx.lineTo(offset - smallPadding - width, y)
195
- ctx.stroke()
196
- }
197
- ctx.fillText(displayName, offset, yp)
198
- clickMap.current.insert({
199
- minX: treeAreaWidth - margin.left - width,
200
- maxX: treeAreaWidth - margin.left,
201
- minY: yp - height,
202
- maxY: yp,
203
- name,
204
- id,
205
- })
206
- } else {
207
- ctx.fillText(displayName, xp + d, yp)
208
- clickMap.current.insert({
209
- minX: xp + d,
210
- maxX: xp + d + width,
211
- minY: yp - height,
212
- maxY: yp,
213
- name,
214
- id,
215
- })
216
- }
217
- }
218
- }
219
- ctx.setLineDash([])
220
- }
221
- }, [
222
- collapsed,
223
- rowHeight,
224
- margin.left,
225
- hierarchy,
226
- offsetY,
227
- treeWidth,
228
- showBranchLen,
229
- noTree,
230
- blockSize,
231
- drawNodeBubbles,
232
- drawTree,
233
- labelsAlignRight,
234
- treeAreaWidth,
235
- structures,
236
- highResScaleFactor,
237
- treeMetadata,
238
- ])
239
-
240
- useEffect(() => {
241
- const canvas = mouseoverRef.current
242
- if (!canvas) {
243
- return
244
- }
245
- const ctx = canvas.getContext('2d')
246
- if (!ctx) {
247
- return
248
- }
249
-
250
- ctx.resetTransform()
251
- ctx.clearRect(0, 0, treeWidth + padding, blockSize)
252
- ctx.translate(margin.left, -offsetY)
253
-
254
- if (hoverElt) {
255
- const { minX, maxX, minY, maxY } = hoverElt
256
-
257
- ctx.fillStyle = 'rgba(0,0,0,0.1)'
258
- ctx.fillRect(minX, minY, maxX - minX, maxY - minY)
259
- }
260
- }, [hoverElt, margin.left, offsetY, blockSize, treeWidth])
261
-
262
- function hoverBranchClickMap(event: React.MouseEvent) {
263
- const x = event.nativeEvent.offsetX - margin.left
264
- const y = event.nativeEvent.offsetY
265
-
266
- const [entry] = clickMap.current.search({
267
- minX: x,
268
- maxX: x + 1,
269
- minY: y + offsetY,
270
- maxY: y + 1 + offsetY,
271
- })
272
-
273
- return entry && entry.branch
274
- ? { ...entry, x: event.clientX, y: event.clientY }
275
- : undefined
276
- }
277
-
278
- function hoverNameClickMap(event: React.MouseEvent) {
279
- const x = event.nativeEvent.offsetX - margin.left
280
- const y = event.nativeEvent.offsetY
281
- const [entry] = clickMap.current.search({
282
- minX: x,
283
- maxX: x + 1,
284
- minY: y + offsetY,
285
- maxY: y + 1 + offsetY,
286
- })
287
-
288
- return entry && !entry.branch
289
- ? { ...entry, x: event.clientX, y: event.clientY }
290
- : undefined
291
- }
292
-
293
- return (
294
- <>
295
- {branchMenu?.id ? (
296
- <TreeBranchMenu
297
- node={branchMenu}
298
- model={model}
299
- onClose={() => setBranchMenu(undefined)}
300
- />
301
- ) : null}
302
-
303
- {toggleNodeMenu?.id ? (
304
- <TreeMenu
305
- node={toggleNodeMenu}
306
- model={model}
307
- onClose={() => setToggleNodeMenu(undefined)}
308
- />
309
- ) : null}
310
-
311
- <canvas
312
- width={(treeWidth + padding) * highResScaleFactor}
313
- height={blockSize * highResScaleFactor}
314
- style={{
315
- width: treeWidth + padding,
316
- height: blockSize,
317
- top: scrollY + offsetY,
318
- left: 0,
319
- position: 'absolute',
320
- }}
321
- onMouseMove={event => {
322
- if (!ref.current) {
323
- return
324
- }
325
-
326
- const ret = hoverNameClickMap(event) || hoverBranchClickMap(event)
327
- ref.current.style.cursor = ret ? 'pointer' : 'default'
328
- setHoverElt(hoverNameClickMap(event))
329
- }}
330
- onClick={event => {
331
- const { clientX: x, clientY: y } = event
332
-
333
- const data = hoverBranchClickMap(event)
334
- if (data?.id) {
335
- setBranchMenu({ ...data, x, y })
336
- }
337
-
338
- const data2 = hoverNameClickMap(event)
339
- if (data2?.id) {
340
- setToggleNodeMenu({ ...data2, x, y })
341
- }
342
- }}
343
- ref={ref}
344
- />
345
- <canvas
346
- style={{
347
- width: treeWidth + padding,
348
- height: blockSize,
349
- top: scrollY + offsetY,
350
- left: 0,
351
- position: 'absolute',
352
- pointerEvents: 'none',
353
- zIndex: 100,
354
- }}
355
- width={treeWidth + padding}
356
- height={blockSize}
357
- ref={mouseoverRef}
358
- />
359
- </>
360
- )
361
- })
362
-
363
- export default TreeCanvasBlock
@@ -1,144 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { observer } from 'mobx-react'
3
- import {
4
- Button,
5
- DialogActions,
6
- DialogContent,
7
- IconButton,
8
- TextField,
9
- Typography,
10
- } from '@mui/material'
11
- import { Dialog } from '@jbrowse/core/ui'
12
-
13
- // icons
14
- import DeleteIcon from '@mui/icons-material/Delete'
15
-
16
- // locals
17
- import { MsaViewModel } from '../../model'
18
-
19
- const specialFromEntries = (val: string[][]) => {
20
- const ret = {} as Record<string, string[]>
21
- val.forEach(([key, val]) => {
22
- if (!ret[key]) {
23
- ret[key] = [] as string[]
24
- }
25
- ret[key].push(val)
26
- })
27
- return ret
28
- }
29
-
30
- const Row = observer(function ({
31
- name,
32
- value,
33
- setValue,
34
- setName,
35
- onDelete,
36
- }: {
37
- name: string
38
- value: string
39
- setValue: (arg: string) => void
40
- setName: (arg: string) => void
41
- onDelete: () => void
42
- }) {
43
- return (
44
- <div>
45
- <IconButton onClick={onDelete} style={{ margin: 10 }}>
46
- <DeleteIcon />
47
- </IconButton>
48
- <TextField
49
- value={name}
50
- onChange={event => setName(event.target.value)}
51
- label="Key"
52
- />
53
- <TextField
54
- value={value}
55
- onChange={event => setValue(event.target.value)}
56
- label="Value"
57
- />
58
- </div>
59
- )
60
- })
61
-
62
- export default observer(
63
- ({
64
- onClose,
65
- data,
66
- model,
67
- }: {
68
- model: MsaViewModel
69
- onClose: () => void
70
- data: { left: number; right: number }
71
- }) => {
72
- const { blanks } = model
73
- const { left: l, right: r } = data
74
- const [rows, setRows] = useState([
75
- ['Name', ''],
76
- ['ID', ''],
77
- ['Note', ''],
78
- ])
79
- return (
80
- <Dialog
81
- onClose={() => onClose()}
82
- open
83
- title="Create new region annotation"
84
- >
85
- <DialogContent>
86
- <Typography>
87
- Do you want to add an annotation to the MSA at {l}..{r}{' '}
88
- {blanks.length
89
- ? ` (gapped ${model.getPos(l)}..${model.getPos(r)}`
90
- : ''}
91
- </Typography>
92
- {rows.map(([key, val], index) => (
93
- <Row
94
- key={index}
95
- name={key}
96
- value={val}
97
- setValue={newValue => {
98
- const newRows = [...rows]
99
- newRows[index][1] = newValue
100
- setRows(newRows)
101
- }}
102
- setName={newName => {
103
- const newRows = [...rows]
104
- newRows[index][0] = newName
105
- setRows(newRows)
106
- }}
107
- onDelete={() => {
108
- rows.splice(index, 1)
109
- setRows([...rows])
110
- }}
111
- />
112
- ))}
113
- <Button
114
- onClick={() => {
115
- setRows([...rows, ['', '']])
116
- }}
117
- >
118
- Add row
119
- </Button>
120
-
121
- <DialogActions>
122
- <Button
123
- onClick={() => {
124
- model.addAnnotation(l, r, specialFromEntries(rows))
125
- onClose()
126
- }}
127
- variant="contained"
128
- color="primary"
129
- >
130
- Submit
131
- </Button>
132
- <Button
133
- variant="contained"
134
- color="secondary"
135
- onClick={() => onClose()}
136
- >
137
- Cancel
138
- </Button>
139
- </DialogActions>
140
- </DialogContent>
141
- </Dialog>
142
- )
143
- },
144
- )
@@ -1,154 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { observer } from 'mobx-react'
3
- import { makeStyles } from 'tss-react/mui'
4
- import { Dialog } from '@jbrowse/core/ui'
5
- import {
6
- Button,
7
- Checkbox,
8
- DialogActions,
9
- DialogContent,
10
- FormControlLabel,
11
- MenuItem,
12
- TextField,
13
- } from '@mui/material'
14
-
15
- import { MsaViewModel } from '../../model'
16
- import colorSchemes from '../../colorSchemes'
17
-
18
- const useStyles = makeStyles()(theme => ({
19
- field: {
20
- margin: theme.spacing(4),
21
- },
22
- }))
23
-
24
- const SettingsDialog = observer(function ({
25
- model,
26
- onClose,
27
- }: {
28
- model: MsaViewModel
29
- onClose: () => void
30
- }) {
31
- const { classes } = useStyles()
32
- const { colorSchemeName, noTree } = model
33
- const [rowHeight, setRowHeight] = useState(`${model.rowHeight}`)
34
- const [colWidth, setColWidth] = useState(`${model.colWidth}`)
35
- const [treeWidth, setTreeWidth] = useState(`${model.treeWidth}`)
36
-
37
- function error(n: string) {
38
- return Number.isNaN(+n) || +n < 0
39
- }
40
- const rowHeightError = error(rowHeight)
41
- const colWidthError = error(colWidth)
42
- const treeWidthError = error(treeWidth)
43
-
44
- return (
45
- <Dialog open onClose={() => onClose()} title="Settings">
46
- <DialogContent>
47
- <FormControlLabel
48
- control={
49
- <Checkbox
50
- checked={model.showBranchLen}
51
- onChange={() => model.toggleBranchLen()}
52
- />
53
- }
54
- label="Show branch length"
55
- />
56
- <FormControlLabel
57
- control={
58
- <Checkbox
59
- checked={model.bgColor}
60
- onChange={() => model.toggleBgColor()}
61
- />
62
- }
63
- label="Color background"
64
- />
65
- <FormControlLabel
66
- control={
67
- <Checkbox
68
- checked={model.drawNodeBubbles}
69
- onChange={() => model.toggleNodeBubbles()}
70
- />
71
- }
72
- label="Draw node bubbles"
73
- />
74
- <FormControlLabel
75
- control={
76
- <Checkbox
77
- checked={model.drawTree}
78
- onChange={() => model.toggleDrawTree()}
79
- />
80
- }
81
- label="Draw tree (if available)"
82
- />
83
- <FormControlLabel
84
- control={
85
- <Checkbox
86
- checked={model.labelsAlignRight}
87
- onChange={() => model.toggleLabelsAlignRight()}
88
- />
89
- }
90
- label="Labels align right (note: labels may draw over tree, but can adjust tree width or tree area width in UI)"
91
- />
92
-
93
- <TextField
94
- className={classes.field}
95
- label="Row height (px)"
96
- value={rowHeight}
97
- error={rowHeightError}
98
- onChange={event => setRowHeight(event.target.value)}
99
- />
100
- <TextField
101
- className={classes.field}
102
- label="Column width (px)"
103
- value={colWidth}
104
- error={colWidthError}
105
- onChange={event => setColWidth(event.target.value)}
106
- />
107
- <br />
108
- {!noTree ? (
109
- <TextField
110
- className={classes.field}
111
- label="Tree width (px)"
112
- value={treeWidth}
113
- error={treeWidthError}
114
- onChange={event => setTreeWidth(event.target.value)}
115
- />
116
- ) : null}
117
-
118
- <br />
119
-
120
- <TextField
121
- select
122
- label="Color scheme"
123
- value={colorSchemeName}
124
- onChange={event => model.setColorSchemeName(event.target.value)}
125
- >
126
- {Object.keys(colorSchemes).map(option => (
127
- <MenuItem key={option} value={option}>
128
- {option}
129
- </MenuItem>
130
- ))}
131
- </TextField>
132
- <DialogActions>
133
- <Button
134
- disabled={rowHeightError || colWidthError || treeWidthError}
135
- onClick={() => {
136
- model.setRowHeight(+rowHeight)
137
- model.setColWidth(+colWidth)
138
- if (!noTree) {
139
- model.setTreeWidth(+treeWidth)
140
- }
141
- onClose()
142
- }}
143
- variant="contained"
144
- color="primary"
145
- >
146
- Submit
147
- </Button>
148
- </DialogActions>
149
- </DialogContent>
150
- </Dialog>
151
- )
152
- })
153
-
154
- export default SettingsDialog