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
@@ -0,0 +1,254 @@
1
+ import RBush from 'rbush'
2
+
3
+ // locals
4
+ import { MsaViewModel } from '../../model'
5
+ import { Theme } from '@mui/material'
6
+
7
+ export const padding = 600
8
+ const extendBounds = 5
9
+ const radius = 2.5
10
+ const d = radius * 2
11
+
12
+ interface ClickEntry {
13
+ name: string
14
+ id: string
15
+ branch?: boolean
16
+ minX: number
17
+ maxX: number
18
+ minY: number
19
+ maxY: number
20
+ }
21
+
22
+ export function renderTree({
23
+ offsetY,
24
+ ctx,
25
+ model,
26
+ theme,
27
+ }: {
28
+ offsetY: number
29
+ ctx: CanvasRenderingContext2D
30
+ model: MsaViewModel
31
+ theme: Theme
32
+ }) {
33
+ const { hierarchy, showBranchLen, blockSize } = model
34
+ ctx.strokeStyle = theme.palette.text.primary
35
+ for (const { source, target } of hierarchy.links()) {
36
+ const y = showBranchLen ? 'len' : 'y'
37
+ // @ts-expect-error
38
+ const { x: sy, [y]: sx } = source
39
+ // @ts-expect-error
40
+ const { x: ty, [y]: tx } = target
41
+
42
+ const y1 = Math.min(sy, ty)
43
+ const y2 = Math.max(sy, ty)
44
+ // 1d line intersection to check if line crosses block at all, this is
45
+ // an optimization that allows us to skip drawing most tree links
46
+ // outside the block
47
+ if (offsetY + blockSize >= y1 && y2 >= offsetY) {
48
+ ctx.beginPath()
49
+ ctx.moveTo(sx, sy)
50
+ ctx.lineTo(sx, ty)
51
+ ctx.lineTo(tx, ty)
52
+ ctx.stroke()
53
+ }
54
+ }
55
+ }
56
+
57
+ export function renderNodeBubbles({
58
+ ctx,
59
+ clickMap,
60
+ offsetY,
61
+ model,
62
+ }: {
63
+ ctx: CanvasRenderingContext2D
64
+ clickMap: RBush<ClickEntry>
65
+ offsetY: number
66
+ model: MsaViewModel
67
+ theme: Theme
68
+ }) {
69
+ const { hierarchy, showBranchLen, collapsed, blockSize } = model
70
+ for (const node of hierarchy.descendants()) {
71
+ const val = showBranchLen ? 'len' : 'y'
72
+ const {
73
+ // @ts-expect-error
74
+ x: y,
75
+ // @ts-expect-error
76
+ [val]: x,
77
+ data,
78
+ } = node
79
+ const { branchset, id = '', name = '' } = data
80
+ if (
81
+ branchset.length &&
82
+ y > offsetY - extendBounds &&
83
+ y < offsetY + blockSize + extendBounds
84
+ ) {
85
+ ctx.strokeStyle = 'black'
86
+ ctx.fillStyle = collapsed.includes(id) ? 'black' : 'white'
87
+ ctx.beginPath()
88
+ ctx.arc(x, y, radius, 0, 2 * Math.PI)
89
+ ctx.fill()
90
+ ctx.stroke()
91
+
92
+ clickMap.insert({
93
+ minX: x - radius,
94
+ maxX: x - radius + d,
95
+ minY: y - radius,
96
+ maxY: y - radius + d,
97
+ branch: true,
98
+ id,
99
+ name,
100
+ })
101
+ }
102
+ }
103
+ }
104
+
105
+ export function renderTreeLabels({
106
+ theme,
107
+ model,
108
+ offsetY,
109
+ ctx,
110
+ clickMap,
111
+ }: {
112
+ model: MsaViewModel
113
+ offsetY: number
114
+ ctx: CanvasRenderingContext2D
115
+ clickMap: RBush<ClickEntry>
116
+ theme: Theme
117
+ }) {
118
+ const {
119
+ rowHeight,
120
+ showBranchLen,
121
+ treeMetadata,
122
+ hierarchy,
123
+ blockSize,
124
+ labelsAlignRight,
125
+ drawTree,
126
+ structures,
127
+ treeAreaWidth,
128
+ margin,
129
+ noTree,
130
+ } = model
131
+ if (labelsAlignRight) {
132
+ ctx.textAlign = 'right'
133
+ ctx.setLineDash([1, 3])
134
+ } else {
135
+ ctx.textAlign = 'start'
136
+ }
137
+ for (const node of hierarchy.leaves()) {
138
+ const {
139
+ // @ts-expect-error
140
+ x: y,
141
+ // @ts-expect-error
142
+ y: x,
143
+ data: { name, id },
144
+ // @ts-expect-error
145
+ len,
146
+ } = node
147
+
148
+ const displayName = treeMetadata[name]?.genome || name
149
+
150
+ if (y > offsetY - extendBounds && y < offsetY + blockSize + extendBounds) {
151
+ // note: +rowHeight/4 matches with -rowHeight/4 in msa
152
+ const yp = y + rowHeight / 4
153
+ const xp = showBranchLen ? len : x
154
+
155
+ const { width } = ctx.measureText(displayName)
156
+ const height = ctx.measureText('M').width // use an 'em' for height
157
+
158
+ const hasStructure = structures[name]
159
+ ctx.fillStyle = hasStructure ? 'blue' : theme.palette.text.primary
160
+
161
+ if (!drawTree && !labelsAlignRight) {
162
+ ctx.fillText(displayName, 0, yp)
163
+ clickMap.insert({
164
+ minX: 0,
165
+ maxX: width,
166
+ minY: yp - height,
167
+ maxY: yp,
168
+ name,
169
+ id,
170
+ })
171
+ } else if (labelsAlignRight) {
172
+ const smallPadding = 2
173
+ const offset = treeAreaWidth - smallPadding - margin.left
174
+ if (drawTree && !noTree) {
175
+ const { width } = ctx.measureText(displayName)
176
+ ctx.moveTo(xp + radius + 2, y)
177
+ ctx.lineTo(offset - smallPadding - width, y)
178
+ ctx.stroke()
179
+ }
180
+ ctx.fillText(displayName, offset, yp)
181
+ clickMap.insert({
182
+ minX: treeAreaWidth - margin.left - width,
183
+ maxX: treeAreaWidth - margin.left,
184
+ minY: yp - height,
185
+ maxY: yp,
186
+ name,
187
+ id,
188
+ })
189
+ } else {
190
+ ctx.fillText(displayName, xp + d, yp)
191
+ clickMap.insert({
192
+ minX: xp + d,
193
+ maxX: xp + d + width,
194
+ minY: yp - height,
195
+ maxY: yp,
196
+ name,
197
+ id,
198
+ })
199
+ }
200
+ }
201
+ }
202
+ ctx.setLineDash([])
203
+ }
204
+
205
+ export function renderTreeCanvas({
206
+ model,
207
+ clickMap,
208
+ ctx,
209
+ offsetY,
210
+ theme,
211
+ }: {
212
+ model: MsaViewModel
213
+ offsetY: number
214
+ ctx: CanvasRenderingContext2D
215
+ clickMap: RBush<ClickEntry>
216
+ theme: Theme
217
+ }) {
218
+ clickMap.clear()
219
+ const {
220
+ noTree,
221
+ drawTree,
222
+ drawNodeBubbles,
223
+ treeWidth,
224
+ highResScaleFactor,
225
+ margin,
226
+ blockSize,
227
+ fontSize,
228
+ rowHeight,
229
+ // nref has to be kept as a unused var or at least reference to force
230
+ // redraw after canvas ref change
231
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
232
+ nref,
233
+ } = model
234
+
235
+ ctx.resetTransform()
236
+ ctx.scale(highResScaleFactor, highResScaleFactor)
237
+ ctx.clearRect(0, 0, treeWidth + padding, blockSize)
238
+ ctx.translate(margin.left, -offsetY)
239
+
240
+ const font = ctx.font
241
+ ctx.font = font.replace(/\d+px/, `${fontSize}px`)
242
+
243
+ if (!noTree && drawTree) {
244
+ renderTree({ ctx, offsetY, model, theme })
245
+
246
+ if (drawNodeBubbles) {
247
+ renderNodeBubbles({ ctx, offsetY, clickMap, model, theme })
248
+ }
249
+ }
250
+
251
+ if (rowHeight >= 5) {
252
+ renderTreeLabels({ ctx, offsetY, model, clickMap, theme })
253
+ }
254
+ }
@@ -0,0 +1,196 @@
1
+ import React 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
+ FormControlLabelProps,
12
+ MenuItem,
13
+ Slider,
14
+ TextField,
15
+ Typography,
16
+ } from '@mui/material'
17
+
18
+ import { MsaViewModel } from '../../model'
19
+ import colorSchemes from '../../colorSchemes'
20
+
21
+ const useStyles = makeStyles()(theme => ({
22
+ field: {
23
+ margin: theme.spacing(4),
24
+ },
25
+ flex: {
26
+ display: 'flex',
27
+ },
28
+ }))
29
+
30
+ function FormControlLabel2(rest: FormControlLabelProps) {
31
+ return (
32
+ <div>
33
+ <FormControlLabel {...rest} />
34
+ </div>
35
+ )
36
+ }
37
+
38
+ const SettingsContent = observer(function ({ model }: { model: MsaViewModel }) {
39
+ const { classes } = useStyles()
40
+ const {
41
+ bgColor,
42
+ colWidth,
43
+ colorSchemeName,
44
+ drawTree,
45
+ drawNodeBubbles,
46
+ labelsAlignRight,
47
+ noTree,
48
+ rowHeight,
49
+ showBranchLen,
50
+ treeWidthMatchesArea,
51
+ treeWidth,
52
+ } = model
53
+ return (
54
+ <>
55
+ <div>
56
+ <Button onClick={() => model.clearHidden()}>Clear hidden</Button>
57
+ <h1>Tree options</h1>
58
+ <FormControlLabel2
59
+ control={
60
+ <Checkbox
61
+ checked={showBranchLen}
62
+ onChange={() => model.setShowBranchLen(!showBranchLen)}
63
+ />
64
+ }
65
+ label="Show branch length?"
66
+ />
67
+
68
+ <FormControlLabel2
69
+ control={
70
+ <Checkbox
71
+ checked={drawNodeBubbles}
72
+ onChange={() => model.setDrawNodeBubbles(!drawNodeBubbles)}
73
+ />
74
+ }
75
+ label="Draw clickable bubbles on tree branches?"
76
+ />
77
+ <FormControlLabel2
78
+ control={
79
+ <Checkbox
80
+ checked={drawTree}
81
+ onChange={() => model.setDrawTree(!drawTree)}
82
+ />
83
+ }
84
+ label="Show tree?"
85
+ />
86
+
87
+ <FormControlLabel2
88
+ control={
89
+ <Checkbox
90
+ checked={labelsAlignRight}
91
+ onChange={() => model.setLabelsAlignRight(!labelsAlignRight)}
92
+ />
93
+ }
94
+ label="Tree labels align right?"
95
+ />
96
+ {!noTree ? (
97
+ <div>
98
+ <FormControlLabel2
99
+ control={
100
+ <Checkbox
101
+ checked={treeWidthMatchesArea}
102
+ onChange={() =>
103
+ model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
104
+ }
105
+ />
106
+ }
107
+ label="Make tree width fit to tree area?"
108
+ />
109
+ {!treeWidthMatchesArea ? (
110
+ <div className={classes.flex}>
111
+ <Typography>Tree width ({treeWidth}px)</Typography>
112
+ <Slider
113
+ className={classes.field}
114
+ min={50}
115
+ max={600}
116
+ value={treeWidth}
117
+ onChange={(_, val) => model.setTreeWidth(val as number)}
118
+ />
119
+ </div>
120
+ ) : null}
121
+ </div>
122
+ ) : null}
123
+ </div>
124
+ <div>
125
+ <h1>MSA options</h1>
126
+
127
+ <FormControlLabel2
128
+ control={
129
+ <Checkbox
130
+ checked={bgColor}
131
+ onChange={() => model.setBgColor(!bgColor)}
132
+ />
133
+ }
134
+ label="Color background tiles of MSA?"
135
+ />
136
+
137
+ <div className={classes.flex}>
138
+ <Typography>Column width ({colWidth}px)</Typography>
139
+ <Slider
140
+ className={classes.field}
141
+ min={1}
142
+ max={50}
143
+ value={colWidth}
144
+ onChange={(_, val) => model.setColWidth(val as number)}
145
+ />
146
+ </div>
147
+ <div className={classes.flex}>
148
+ <Typography>Row height ({rowHeight}px)</Typography>
149
+ <Slider
150
+ className={classes.field}
151
+ min={1}
152
+ max={50}
153
+ value={rowHeight}
154
+ onChange={(_, val) => model.setRowHeight(val as number)}
155
+ />
156
+ </div>
157
+
158
+ <TextField
159
+ select
160
+ label="Color scheme"
161
+ value={colorSchemeName}
162
+ onChange={event => model.setColorSchemeName(event.target.value)}
163
+ >
164
+ {Object.keys(colorSchemes).map(option => (
165
+ <MenuItem key={option} value={option}>
166
+ {option}
167
+ </MenuItem>
168
+ ))}
169
+ </TextField>
170
+ </div>
171
+ </>
172
+ )
173
+ })
174
+
175
+ const SettingsDialog = observer(function ({
176
+ model,
177
+ onClose,
178
+ }: {
179
+ model: MsaViewModel
180
+ onClose: () => void
181
+ }) {
182
+ return (
183
+ <Dialog open onClose={() => onClose()} title="Settings">
184
+ <DialogContent>
185
+ <SettingsContent model={model} />
186
+ <DialogActions>
187
+ <Button onClick={() => onClose()} variant="contained" color="primary">
188
+ Submit
189
+ </Button>
190
+ </DialogActions>
191
+ </DialogContent>
192
+ </Dialog>
193
+ )
194
+ })
195
+
196
+ export default SettingsDialog