react-msaview 3.0.0 → 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 (84) hide show
  1. package/bundle/index.js +31 -31
  2. package/dist/components/Header.js +4 -9
  3. package/dist/components/Header.js.map +1 -1
  4. package/dist/components/HeaderInfoArea.d.ts +6 -0
  5. package/dist/components/HeaderInfoArea.js +12 -0
  6. package/dist/components/HeaderInfoArea.js.map +1 -0
  7. package/dist/components/MSAPanel/Loading.d.ts +2 -0
  8. package/dist/components/MSAPanel/Loading.js +12 -0
  9. package/dist/components/MSAPanel/Loading.js.map +1 -0
  10. package/dist/components/MSAPanel/MSACanvas.js +1 -10
  11. package/dist/components/MSAPanel/MSACanvas.js.map +1 -1
  12. package/dist/components/MSAPanel/MSAMouseoverCanvas.js +1 -22
  13. package/dist/components/MSAPanel/MSAMouseoverCanvas.js.map +1 -1
  14. package/dist/components/MSAPanel/renderMSABlock.js +0 -1
  15. package/dist/components/MSAPanel/renderMSABlock.js.map +1 -1
  16. package/dist/components/MSAPanel/renderMSAMouseover.d.ts +5 -0
  17. package/dist/components/MSAPanel/renderMSAMouseover.js +24 -0
  18. package/dist/components/MSAPanel/renderMSAMouseover.js.map +1 -0
  19. package/dist/components/Minimap.js +13 -13
  20. package/dist/components/Minimap.js.map +1 -1
  21. package/dist/components/TreePanel/TreeCanvasBlock.js +8 -4
  22. package/dist/components/TreePanel/TreeCanvasBlock.js.map +1 -1
  23. package/dist/components/TreePanel/{TreeMenu.d.ts → TreeNodeMenu.d.ts} +1 -0
  24. package/dist/components/TreePanel/{TreeMenu.js → TreeNodeMenu.js} +8 -4
  25. package/dist/components/TreePanel/TreeNodeMenu.js.map +1 -0
  26. package/dist/components/TreePanel/dialogs/{TreeNodeInfoDlg.js → TreeNodeInfoDialog.js} +2 -2
  27. package/dist/components/TreePanel/dialogs/TreeNodeInfoDialog.js.map +1 -0
  28. package/dist/components/TreePanel/renderTreeCanvas.d.ts +8 -3
  29. package/dist/components/TreePanel/renderTreeCanvas.js +8 -7
  30. package/dist/components/TreePanel/renderTreeCanvas.js.map +1 -1
  31. package/dist/components/dialogs/SettingsDialog.js +31 -22
  32. package/dist/components/dialogs/SettingsDialog.js.map +1 -1
  33. package/dist/model.d.ts +120 -62
  34. package/dist/model.js +176 -124
  35. package/dist/model.js.map +1 -1
  36. package/dist/parsers/ClustalMSA.d.ts +1 -1
  37. package/dist/parsers/ClustalMSA.js +1 -1
  38. package/dist/parsers/ClustalMSA.js.map +1 -1
  39. package/dist/parsers/FastaMSA.d.ts +1 -1
  40. package/dist/parsers/FastaMSA.js +2 -2
  41. package/dist/parsers/FastaMSA.js.map +1 -1
  42. package/dist/parsers/StockholmMSA.d.ts +1 -1
  43. package/dist/parsers/StockholmMSA.js +2 -2
  44. package/dist/parsers/StockholmMSA.js.map +1 -1
  45. package/dist/util.d.ts +1 -0
  46. package/dist/util.js +15 -7
  47. package/dist/util.js.map +1 -1
  48. package/dist/version.d.ts +1 -1
  49. package/dist/version.js +1 -1
  50. package/package.json +1 -1
  51. package/src/components/Header.tsx +5 -11
  52. package/src/components/HeaderInfoArea.tsx +21 -0
  53. package/src/components/MSAPanel/Loading.tsx +16 -0
  54. package/src/components/MSAPanel/MSACanvas.tsx +1 -16
  55. package/src/components/MSAPanel/MSAMouseoverCanvas.tsx +2 -50
  56. package/src/components/MSAPanel/renderMSABlock.ts +0 -2
  57. package/src/components/MSAPanel/renderMSAMouseover.ts +51 -0
  58. package/src/components/Minimap.tsx +15 -15
  59. package/src/components/TreePanel/TreeCanvasBlock.tsx +8 -3
  60. package/src/components/TreePanel/{TreeMenu.tsx → TreeNodeMenu.tsx} +12 -3
  61. package/src/components/TreePanel/dialogs/{TreeNodeInfoDlg.tsx → TreeNodeInfoDialog.tsx} +1 -1
  62. package/src/components/TreePanel/renderTreeCanvas.ts +13 -4
  63. package/src/components/dialogs/SettingsDialog.tsx +61 -44
  64. package/src/model.ts +279 -154
  65. package/src/parsers/ClustalMSA.ts +1 -1
  66. package/src/parsers/FastaMSA.ts +1 -1
  67. package/src/parsers/StockholmMSA.ts +1 -1
  68. package/src/util.ts +19 -6
  69. package/src/version.ts +1 -1
  70. package/dist/components/OverviewRubberband.d.ts +0 -8
  71. package/dist/components/OverviewRubberband.js +0 -185
  72. package/dist/components/OverviewRubberband.js.map +0 -1
  73. package/dist/components/Rubberband.d.ts +0 -8
  74. package/dist/components/Rubberband.js +0 -185
  75. package/dist/components/Rubberband.js.map +0 -1
  76. package/dist/components/TreePanel/TreeMenu.js.map +0 -1
  77. package/dist/components/TreePanel/dialogs/TreeNodeInfoDlg.js.map +0 -1
  78. package/dist/components/dialogs/AnnotationDialog.d.ts +0 -11
  79. package/dist/components/dialogs/AnnotationDialog.js +0 -65
  80. package/dist/components/dialogs/AnnotationDialog.js.map +0 -1
  81. package/src/components/OverviewRubberband.tsx +0 -283
  82. package/src/components/Rubberband.tsx +0 -283
  83. package/src/components/dialogs/AnnotationDialog.tsx +0 -144
  84. /package/dist/components/TreePanel/dialogs/{TreeNodeInfoDlg.d.ts → TreeNodeInfoDialog.d.ts} +0 -0
@@ -1,11 +1,12 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react'
2
2
  import { autorun } from 'mobx'
3
3
  import { observer } from 'mobx-react'
4
+ import { useTheme } from '@mui/material'
4
5
  import RBush from 'rbush'
5
6
 
6
7
  // locals
7
8
  import { MsaViewModel } from '../../model'
8
- import TreeMenu from './TreeMenu'
9
+ import TreeNodeMenu from './TreeNodeMenu'
9
10
  import TreeBranchMenu from './TreeBranchMenu'
10
11
  import { padding, renderTreeCanvas } from './renderTreeCanvas'
11
12
 
@@ -33,6 +34,7 @@ const TreeCanvasBlock = observer(function ({
33
34
  model: MsaViewModel
34
35
  offsetY: number
35
36
  }) {
37
+ const theme = useTheme()
36
38
  const ref = useRef<HTMLCanvasElement>()
37
39
  const clickMap = useRef(new RBush<ClickEntry>())
38
40
  const mouseoverRef = useRef<HTMLCanvasElement>(null)
@@ -68,9 +70,10 @@ const TreeCanvasBlock = observer(function ({
68
70
  model,
69
71
  offsetY,
70
72
  clickMap: clickMap.current,
73
+ theme,
71
74
  })
72
75
  })
73
- }, [model, offsetY])
76
+ }, [model, offsetY, theme])
74
77
 
75
78
  useEffect(() => {
76
79
  const ctx = mouseoverRef.current?.getContext('2d')
@@ -138,7 +141,7 @@ const TreeCanvasBlock = observer(function ({
138
141
  ) : null}
139
142
 
140
143
  {toggleNodeMenu?.id ? (
141
- <TreeMenu
144
+ <TreeNodeMenu
142
145
  node={toggleNodeMenu}
143
146
  model={model}
144
147
  onClose={() => setToggleNodeMenu(undefined)}
@@ -155,6 +158,7 @@ const TreeCanvasBlock = observer(function ({
155
158
  }
156
159
 
157
160
  const ret = hoverNameClickMap(event) || hoverBranchClickMap(event)
161
+ console.log({ ret })
158
162
  ref.current.style.cursor = ret ? 'pointer' : 'default'
159
163
  setHoverElt(hoverNameClickMap(event))
160
164
  }}
@@ -171,6 +175,7 @@ const TreeCanvasBlock = observer(function ({
171
175
  setToggleNodeMenu({ ...data2, x, y })
172
176
  }
173
177
  }}
178
+ onMouseLeave={() => setHoverElt(undefined)}
174
179
  ref={vref}
175
180
  />
176
181
  <canvas
@@ -5,14 +5,14 @@ import { observer } from 'mobx-react'
5
5
  // locals
6
6
  import { MsaViewModel } from '../../model'
7
7
 
8
- const TreeNodeInfoDlg = lazy(() => import('./dialogs/TreeNodeInfoDlg'))
8
+ const TreeNodeInfoDialog = lazy(() => import('./dialogs/TreeNodeInfoDialog'))
9
9
 
10
10
  const TreeMenu = observer(function ({
11
11
  node,
12
12
  onClose,
13
13
  model,
14
14
  }: {
15
- node: { x: number; y: number; name: string }
15
+ node: { x: number; y: number; name: string; id: string }
16
16
  model: MsaViewModel
17
17
  onClose: () => void
18
18
  }) {
@@ -40,7 +40,7 @@ const TreeMenu = observer(function ({
40
40
  dense
41
41
  onClick={() => {
42
42
  model.queueDialog(onClose => [
43
- TreeNodeInfoDlg,
43
+ TreeNodeInfoDialog,
44
44
  {
45
45
  info: model.getRowData(node.name),
46
46
  model,
@@ -53,6 +53,15 @@ const TreeMenu = observer(function ({
53
53
  >
54
54
  More info...
55
55
  </MenuItem>
56
+ <MenuItem
57
+ dense
58
+ onClick={() => {
59
+ model.hideNode(node.id)
60
+ onClose()
61
+ }}
62
+ >
63
+ Hide node
64
+ </MenuItem>
56
65
 
57
66
  {structures[node.name]?.map(entry => {
58
67
  return !model.selectedStructures.some(n => n.id === node.name) ? (
@@ -25,7 +25,7 @@ export default observer(function ({
25
25
  <Dialog onClose={() => onClose()} open title="Tree node info">
26
26
  <DialogContent>
27
27
  <BaseCard title="Attributes">
28
- <Attributes attributes={info} />
28
+ <Attributes attributes={{ nodeName, ...info }} />
29
29
  </BaseCard>
30
30
  {metadata ? (
31
31
  <BaseCard title="Extra metadata">
@@ -2,6 +2,7 @@ import RBush from 'rbush'
2
2
 
3
3
  // locals
4
4
  import { MsaViewModel } from '../../model'
5
+ import { Theme } from '@mui/material'
5
6
 
6
7
  export const padding = 600
7
8
  const extendBounds = 5
@@ -22,12 +23,15 @@ export function renderTree({
22
23
  offsetY,
23
24
  ctx,
24
25
  model,
26
+ theme,
25
27
  }: {
26
28
  offsetY: number
27
29
  ctx: CanvasRenderingContext2D
28
30
  model: MsaViewModel
31
+ theme: Theme
29
32
  }) {
30
33
  const { hierarchy, showBranchLen, blockSize } = model
34
+ ctx.strokeStyle = theme.palette.text.primary
31
35
  for (const { source, target } of hierarchy.links()) {
32
36
  const y = showBranchLen ? 'len' : 'y'
33
37
  // @ts-expect-error
@@ -60,6 +64,7 @@ export function renderNodeBubbles({
60
64
  clickMap: RBush<ClickEntry>
61
65
  offsetY: number
62
66
  model: MsaViewModel
67
+ theme: Theme
63
68
  }) {
64
69
  const { hierarchy, showBranchLen, collapsed, blockSize } = model
65
70
  for (const node of hierarchy.descendants()) {
@@ -98,6 +103,7 @@ export function renderNodeBubbles({
98
103
  }
99
104
 
100
105
  export function renderTreeLabels({
106
+ theme,
101
107
  model,
102
108
  offsetY,
103
109
  ctx,
@@ -107,6 +113,7 @@ export function renderTreeLabels({
107
113
  offsetY: number
108
114
  ctx: CanvasRenderingContext2D
109
115
  clickMap: RBush<ClickEntry>
116
+ theme: Theme
110
117
  }) {
111
118
  const {
112
119
  rowHeight,
@@ -149,7 +156,7 @@ export function renderTreeLabels({
149
156
  const height = ctx.measureText('M').width // use an 'em' for height
150
157
 
151
158
  const hasStructure = structures[name]
152
- ctx.fillStyle = hasStructure ? 'blue' : 'black'
159
+ ctx.fillStyle = hasStructure ? 'blue' : theme.palette.text.primary
153
160
 
154
161
  if (!drawTree && !labelsAlignRight) {
155
162
  ctx.fillText(displayName, 0, yp)
@@ -200,11 +207,13 @@ export function renderTreeCanvas({
200
207
  clickMap,
201
208
  ctx,
202
209
  offsetY,
210
+ theme,
203
211
  }: {
204
212
  model: MsaViewModel
205
213
  offsetY: number
206
214
  ctx: CanvasRenderingContext2D
207
215
  clickMap: RBush<ClickEntry>
216
+ theme: Theme
208
217
  }) {
209
218
  clickMap.clear()
210
219
  const {
@@ -232,14 +241,14 @@ export function renderTreeCanvas({
232
241
  ctx.font = font.replace(/\d+px/, `${fontSize}px`)
233
242
 
234
243
  if (!noTree && drawTree) {
235
- renderTree({ ctx, offsetY, model })
244
+ renderTree({ ctx, offsetY, model, theme })
236
245
 
237
246
  if (drawNodeBubbles) {
238
- renderNodeBubbles({ ctx, offsetY, clickMap, model })
247
+ renderNodeBubbles({ ctx, offsetY, clickMap, model, theme })
239
248
  }
240
249
  }
241
250
 
242
251
  if (rowHeight >= 5) {
243
- renderTreeLabels({ ctx, offsetY, model, clickMap })
252
+ renderTreeLabels({ ctx, offsetY, model, clickMap, theme })
244
253
  }
245
254
  }
@@ -8,6 +8,7 @@ import {
8
8
  DialogActions,
9
9
  DialogContent,
10
10
  FormControlLabel,
11
+ FormControlLabelProps,
11
12
  MenuItem,
12
13
  Slider,
13
14
  TextField,
@@ -21,15 +22,20 @@ const useStyles = makeStyles()(theme => ({
21
22
  field: {
22
23
  margin: theme.spacing(4),
23
24
  },
25
+ flex: {
26
+ display: 'flex',
27
+ },
24
28
  }))
25
29
 
26
- const SettingsDialog = observer(function ({
27
- model,
28
- onClose,
29
- }: {
30
- model: MsaViewModel
31
- onClose: () => void
32
- }) {
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 }) {
33
39
  const { classes } = useStyles()
34
40
  const {
35
41
  bgColor,
@@ -44,59 +50,52 @@ const SettingsDialog = observer(function ({
44
50
  treeWidthMatchesArea,
45
51
  treeWidth,
46
52
  } = model
47
-
48
53
  return (
49
- <Dialog open onClose={() => onClose()} title="Settings">
50
- <DialogContent>
51
- <FormControlLabel
54
+ <>
55
+ <div>
56
+ <Button onClick={() => model.clearHidden()}>Clear hidden</Button>
57
+ <h1>Tree options</h1>
58
+ <FormControlLabel2
52
59
  control={
53
60
  <Checkbox
54
61
  checked={showBranchLen}
55
62
  onChange={() => model.setShowBranchLen(!showBranchLen)}
56
63
  />
57
64
  }
58
- label="Show branch length"
65
+ label="Show branch length?"
59
66
  />
60
- <FormControlLabel
61
- control={
62
- <Checkbox
63
- checked={bgColor}
64
- onChange={() => model.setBgColor(!bgColor)}
65
- />
66
- }
67
- label="Color background"
68
- />
69
- <FormControlLabel
67
+
68
+ <FormControlLabel2
70
69
  control={
71
70
  <Checkbox
72
71
  checked={drawNodeBubbles}
73
72
  onChange={() => model.setDrawNodeBubbles(!drawNodeBubbles)}
74
73
  />
75
74
  }
76
- label="Draw node bubbles"
75
+ label="Draw clickable bubbles on tree branches?"
77
76
  />
78
- <FormControlLabel
77
+ <FormControlLabel2
79
78
  control={
80
79
  <Checkbox
81
80
  checked={drawTree}
82
81
  onChange={() => model.setDrawTree(!drawTree)}
83
82
  />
84
83
  }
85
- label="Draw tree (if available)"
84
+ label="Show tree?"
86
85
  />
87
- <FormControlLabel
86
+
87
+ <FormControlLabel2
88
88
  control={
89
89
  <Checkbox
90
90
  checked={labelsAlignRight}
91
91
  onChange={() => model.setLabelsAlignRight(!labelsAlignRight)}
92
92
  />
93
93
  }
94
- label="Labels align right"
94
+ label="Tree labels align right?"
95
95
  />
96
-
97
96
  {!noTree ? (
98
97
  <div>
99
- <FormControlLabel
98
+ <FormControlLabel2
100
99
  control={
101
100
  <Checkbox
102
101
  checked={treeWidthMatchesArea}
@@ -108,7 +107,7 @@ const SettingsDialog = observer(function ({
108
107
  label="Make tree width fit to tree area?"
109
108
  />
110
109
  {!treeWidthMatchesArea ? (
111
- <div style={{ display: 'flex' }}>
110
+ <div className={classes.flex}>
112
111
  <Typography>Tree width ({treeWidth}px)</Typography>
113
112
  <Slider
114
113
  className={classes.field}
@@ -121,8 +120,21 @@ const SettingsDialog = observer(function ({
121
120
  ) : null}
122
121
  </div>
123
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
+ />
124
136
 
125
- <div style={{ display: 'flex' }}>
137
+ <div className={classes.flex}>
126
138
  <Typography>Column width ({colWidth}px)</Typography>
127
139
  <Slider
128
140
  className={classes.field}
@@ -132,7 +144,7 @@ const SettingsDialog = observer(function ({
132
144
  onChange={(_, val) => model.setColWidth(val as number)}
133
145
  />
134
146
  </div>
135
- <div style={{ display: 'flex' }}>
147
+ <div className={classes.flex}>
136
148
  <Typography>Row height ({rowHeight}px)</Typography>
137
149
  <Slider
138
150
  className={classes.field}
@@ -155,19 +167,24 @@ const SettingsDialog = observer(function ({
155
167
  </MenuItem>
156
168
  ))}
157
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} />
158
186
  <DialogActions>
159
- <Button
160
- onClick={() => {
161
- model.setRowHeight(+rowHeight)
162
- model.setColWidth(+colWidth)
163
- if (!noTree) {
164
- model.setTreeWidth(+treeWidth)
165
- }
166
- onClose()
167
- }}
168
- variant="contained"
169
- color="primary"
170
- >
187
+ <Button onClick={() => onClose()} variant="contained" color="primary">
171
188
  Submit
172
189
  </Button>
173
190
  </DialogActions>