@jbrowse/plugin-alignments 1.6.5 → 1.6.8

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 (52) hide show
  1. package/dist/AlignmentsFeatureDetail/index.d.ts +1 -1
  2. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +2 -10
  3. package/dist/BamAdapter/MismatchParser.d.ts +3 -5
  4. package/dist/BamAdapter/configSchema.d.ts +1 -1
  5. package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -2
  6. package/dist/CramAdapter/configSchema.d.ts +1 -1
  7. package/dist/HtsgetBamAdapter/configSchema.d.ts +1 -1
  8. package/dist/LinearAlignmentsDisplay/models/configSchema.d.ts +1 -1
  9. package/dist/LinearAlignmentsDisplay/models/model.d.ts +1 -1
  10. package/dist/LinearPileupDisplay/configSchema.d.ts +1 -1
  11. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  12. package/dist/LinearSNPCoverageDisplay/models/configSchema.d.ts +1 -1
  13. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +2 -2
  14. package/dist/PileupRenderer/PileupRenderer.d.ts +20 -6
  15. package/dist/PileupRenderer/configSchema.d.ts +1 -1
  16. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +3 -11
  17. package/dist/SNPCoverageAdapter/configSchema.d.ts +1 -1
  18. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +1 -1
  19. package/dist/SNPCoverageRenderer/configSchema.d.ts +1 -1
  20. package/dist/SNPCoverageRenderer/index.d.ts +1 -1
  21. package/dist/plugin-alignments.cjs.development.js +795 -682
  22. package/dist/plugin-alignments.cjs.development.js.map +1 -1
  23. package/dist/plugin-alignments.cjs.production.min.js +1 -1
  24. package/dist/plugin-alignments.cjs.production.min.js.map +1 -1
  25. package/dist/plugin-alignments.esm.js +797 -684
  26. package/dist/plugin-alignments.esm.js.map +1 -1
  27. package/dist/util.d.ts +4 -0
  28. package/package.json +4 -4
  29. package/src/AlignmentsFeatureDetail/AlignmentsFeatureDetail.tsx +23 -14
  30. package/src/BamAdapter/BamAdapter.ts +10 -7
  31. package/src/BamAdapter/BamSlightlyLazyFeature.ts +11 -75
  32. package/src/BamAdapter/MismatchParser.test.ts +53 -297
  33. package/src/BamAdapter/MismatchParser.ts +54 -116
  34. package/src/BamAdapter/configSchema.ts +0 -4
  35. package/src/CramAdapter/CramSlightlyLazyFeature.ts +3 -10
  36. package/src/LinearAlignmentsDisplay/components/AlignmentsDisplay.tsx +38 -30
  37. package/src/LinearAlignmentsDisplay/models/model.tsx +10 -9
  38. package/src/LinearPileupDisplay/components/ColorByModifications.tsx +76 -80
  39. package/src/LinearPileupDisplay/components/ColorByTag.tsx +24 -23
  40. package/src/LinearPileupDisplay/components/FilterByTag.tsx +73 -68
  41. package/src/LinearPileupDisplay/components/SetFeatureHeight.tsx +28 -26
  42. package/src/LinearPileupDisplay/components/SetMaxHeight.tsx +24 -13
  43. package/src/LinearPileupDisplay/components/SortByTag.tsx +29 -21
  44. package/src/LinearPileupDisplay/model.ts +12 -6
  45. package/src/LinearSNPCoverageDisplay/components/Tooltip.tsx +5 -3
  46. package/src/LinearSNPCoverageDisplay/models/configSchema.ts +4 -5
  47. package/src/PileupRenderer/PileupRenderer.tsx +202 -70
  48. package/src/PileupRenderer/components/PileupRendering.tsx +5 -3
  49. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +192 -237
  50. package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +91 -60
  51. package/src/SNPCoverageRenderer/configSchema.js +1 -1
  52. package/src/util.ts +25 -0
@@ -4,6 +4,7 @@ import {
4
4
  Button,
5
5
  Dialog,
6
6
  DialogContent,
7
+ DialogActions,
7
8
  DialogTitle,
8
9
  IconButton,
9
10
  TextField,
@@ -46,32 +47,29 @@ function ColorByTagDlg(props: {
46
47
  </IconButton>
47
48
  </DialogTitle>
48
49
  <DialogContent style={{ overflowX: 'hidden' }}>
49
- <div className={classes.root}>
50
- <Typography>Enter tag to color by: </Typography>
51
- <Typography color="textSecondary">
52
- Examples: XS or TS for RNA-seq inferred read strand, ts (lower-case)
53
- for minimap2 read strand, HP for haplotype, RG for read group, etc.
54
- </Typography>
50
+ <Typography>Enter tag to color by: </Typography>
51
+ <Typography color="textSecondary">
52
+ Examples: XS or TS for RNA-seq inferred read strand, ts (lower-case)
53
+ for minimap2 read strand, HP for haplotype, RG for read group, etc.
54
+ </Typography>
55
55
 
56
- <TextField
57
- value={tag}
58
- onChange={event => {
59
- setTag(event.target.value)
60
- }}
61
- placeholder="Enter tag name"
62
- inputProps={{
63
- maxLength: 2,
64
- 'data-testid': 'color-tag-name-input',
65
- }}
66
- error={tag.length === 2 && !validTag}
67
- helperText={tag.length === 2 && !validTag ? 'Not a valid tag' : ''}
68
- autoComplete="off"
69
- data-testid="color-tag-name"
70
- />
56
+ <TextField
57
+ value={tag}
58
+ onChange={event => setTag(event.target.value)}
59
+ placeholder="Enter tag name"
60
+ inputProps={{
61
+ maxLength: 2,
62
+ 'data-testid': 'color-tag-name-input',
63
+ }}
64
+ error={tag.length === 2 && !validTag}
65
+ helperText={tag.length === 2 && !validTag ? 'Not a valid tag' : ''}
66
+ autoComplete="off"
67
+ data-testid="color-tag-name"
68
+ />
69
+ <DialogActions>
71
70
  <Button
72
71
  variant="contained"
73
72
  color="primary"
74
- style={{ marginLeft: 20 }}
75
73
  onClick={() => {
76
74
  model.setColorScheme({
77
75
  type: 'tag',
@@ -83,7 +81,10 @@ function ColorByTagDlg(props: {
83
81
  >
84
82
  Submit
85
83
  </Button>
86
- </div>
84
+ <Button variant="contained" color="secondary" onClick={handleClose}>
85
+ Cancel
86
+ </Button>
87
+ </DialogActions>
87
88
  </DialogContent>
88
89
  </Dialog>
89
90
  )
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
5
  Dialog,
6
+ DialogActions,
6
7
  DialogContent,
7
8
  DialogTitle,
8
9
  IconButton,
@@ -16,9 +17,6 @@ import {
16
17
  import CloseIcon from '@material-ui/icons/Close'
17
18
 
18
19
  const useStyles = makeStyles(theme => ({
19
- root: {
20
- width: 500,
21
- },
22
20
  paper: {
23
21
  padding: theme.spacing(2),
24
22
  margin: theme.spacing(2),
@@ -123,74 +121,74 @@ function FilterByTagDlg(props: {
123
121
  Set filter bitmask options. Refer to <Link href={site}>{site}</Link>{' '}
124
122
  for details
125
123
  </Typography>
126
- <div className={classes.root}>
127
- <Paper className={classes.paper} variant="outlined">
128
- <div style={{ display: 'flex' }}>
129
- <div>
130
- <Typography>Read must have ALL these flags</Typography>
131
- <Bitmask flag={flagInclude} setFlag={setFlagInclude} />
132
- </div>
133
- <div>
134
- <Typography>Read must have NONE of these flags</Typography>
135
- <Bitmask flag={flagExclude} setFlag={setFlagExclude} />
136
- </div>
124
+ <Paper className={classes.paper} variant="outlined">
125
+ <div style={{ display: 'flex' }}>
126
+ <div>
127
+ <Typography>Read must have ALL these flags</Typography>
128
+ <Bitmask flag={flagInclude} setFlag={setFlagInclude} />
137
129
  </div>
138
- </Paper>
139
- <Paper className={classes.paper} variant="outlined">
140
- <Typography>
141
- Filter by tag name and value. Use * in the value field to get all
142
- reads containing any value for that tag. Example: filter tag name
143
- SA with value * to get all split/supplementary reads. Other
144
- examples include HP for haplotype, or RG for read group
145
- </Typography>
146
- <TextField
147
- className={classes.field}
148
- value={tag}
149
- onChange={event => {
150
- setTag(event.target.value)
151
- }}
152
- placeholder="Enter tag name"
153
- inputProps={{
154
- maxLength: 2,
155
- 'data-testid': 'color-tag-name-input',
156
- }}
157
- error={tag.length === 2 && !validTag}
158
- helperText={
159
- tag.length === 2 && !validTag ? 'Not a valid tag' : ''
160
- }
161
- data-testid="color-tag-name"
162
- />
163
- <TextField
164
- className={classes.field}
165
- value={tagValue}
166
- onChange={event => {
167
- setTagValue(event.target.value)
168
- }}
169
- placeholder="Enter tag value"
170
- inputProps={{
171
- 'data-testid': 'color-tag-name-input',
172
- }}
173
- data-testid="color-tag-value"
174
- />
175
- </Paper>
176
- <Paper className={classes.paper} variant="outlined">
177
- <Typography>Filter by read name</Typography>
178
- <TextField
179
- className={classes.field}
180
- value={readName}
181
- onChange={event => {
182
- setReadName(event.target.value)
183
- }}
184
- placeholder="Enter read name"
185
- inputProps={{
186
- 'data-testid': 'color-tag-readname-input',
187
- }}
188
- data-testid="color-tag-readname"
189
- />
190
- </Paper>
130
+ <div>
131
+ <Typography>Read must have NONE of these flags</Typography>
132
+ <Bitmask flag={flagExclude} setFlag={setFlagExclude} />
133
+ </div>
134
+ </div>
135
+ </Paper>
136
+ <Paper className={classes.paper} variant="outlined">
137
+ <Typography>
138
+ Filter by tag name and value. Use * in the value field to get all
139
+ reads containing any value for that tag. Example: filter tag name SA
140
+ with value * to get all split/supplementary reads. Other examples
141
+ include HP for haplotype, or RG for read group
142
+ </Typography>
143
+ <TextField
144
+ className={classes.field}
145
+ value={tag}
146
+ onChange={event => {
147
+ setTag(event.target.value)
148
+ }}
149
+ placeholder="Enter tag name"
150
+ inputProps={{
151
+ maxLength: 2,
152
+ 'data-testid': 'color-tag-name-input',
153
+ }}
154
+ error={tag.length === 2 && !validTag}
155
+ helperText={tag.length === 2 && !validTag ? 'Not a valid tag' : ''}
156
+ data-testid="color-tag-name"
157
+ />
158
+ <TextField
159
+ className={classes.field}
160
+ value={tagValue}
161
+ onChange={event => {
162
+ setTagValue(event.target.value)
163
+ }}
164
+ placeholder="Enter tag value"
165
+ inputProps={{
166
+ 'data-testid': 'color-tag-name-input',
167
+ }}
168
+ data-testid="color-tag-value"
169
+ />
170
+ </Paper>
171
+ <Paper className={classes.paper} variant="outlined">
172
+ <Typography>Filter by read name</Typography>
173
+ <TextField
174
+ className={classes.field}
175
+ value={readName}
176
+ onChange={event => {
177
+ setReadName(event.target.value)
178
+ }}
179
+ placeholder="Enter read name"
180
+ inputProps={{
181
+ 'data-testid': 'color-tag-readname-input',
182
+ }}
183
+ data-testid="color-tag-readname"
184
+ />
185
+ </Paper>
186
+ <DialogActions>
191
187
  <Button
192
188
  variant="contained"
193
189
  color="primary"
190
+ autoFocus
191
+ type="submit"
194
192
  onClick={() => {
195
193
  model.setFilterBy({
196
194
  flagInclude,
@@ -209,7 +207,14 @@ function FilterByTagDlg(props: {
209
207
  >
210
208
  Submit
211
209
  </Button>
212
- </div>
210
+ <Button
211
+ variant="contained"
212
+ color="secondary"
213
+ onClick={() => handleClose()}
214
+ >
215
+ Cancel
216
+ </Button>
217
+ </DialogActions>
213
218
  </DialogContent>
214
219
  </Dialog>
215
220
  )
@@ -6,6 +6,7 @@ import {
6
6
  Typography,
7
7
  IconButton,
8
8
  Dialog,
9
+ DialogActions,
9
10
  DialogContent,
10
11
  DialogTitle,
11
12
  Checkbox,
@@ -15,9 +16,6 @@ import {
15
16
  import CloseIcon from '@material-ui/icons/Close'
16
17
 
17
18
  const useStyles = makeStyles(theme => ({
18
- root: {
19
- margin: theme.spacing(4),
20
- },
21
19
  closeButton: {
22
20
  position: 'absolute',
23
21
  right: theme.spacing(1),
@@ -42,7 +40,6 @@ function SetFeatureHeightDlg(props: {
42
40
  const classes = useStyles()
43
41
  const { model, handleClose } = props
44
42
  const { featureHeightSetting, noSpacing: noSpacingSetting } = model
45
-
46
43
  const [height, setHeight] = useState(`${featureHeightSetting}`)
47
44
  const [noSpacing, setNoSpacing] = useState(noSpacingSetting)
48
45
 
@@ -60,44 +57,49 @@ function SetFeatureHeightDlg(props: {
60
57
  <Typography>
61
58
  Adjust the feature height and whether there is any spacing between
62
59
  features. Setting feature height to 1 and removing spacing makes the
63
- display very compact
60
+ display very compact.
64
61
  </Typography>
65
- <div className={classes.root}>
66
- <Typography>Enter feature height: </Typography>
67
- <TextField
68
- value={height}
69
- onChange={event => {
70
- setHeight(event.target.value)
71
- }}
72
- />
73
- <FormControlLabel
74
- control={
75
- <Checkbox
76
- checked={!!noSpacing}
77
- onChange={() => setNoSpacing(val => !val)}
78
- />
79
- }
80
- label="Remove spacing between features in y-direction?"
81
- />
82
-
62
+ <TextField
63
+ value={height}
64
+ helperText="Feature height"
65
+ onChange={event => {
66
+ setHeight(event.target.value)
67
+ }}
68
+ />
69
+ <FormControlLabel
70
+ control={
71
+ <Checkbox
72
+ checked={!!noSpacing}
73
+ onChange={() => setNoSpacing(val => !val)}
74
+ />
75
+ }
76
+ label="Remove spacing between features in y-direction?"
77
+ />
78
+ <DialogActions>
83
79
  <Button
84
80
  variant="contained"
85
81
  color="primary"
86
82
  type="submit"
87
- style={{ marginLeft: 20 }}
83
+ autoFocus
88
84
  disabled={!ok}
89
85
  onClick={() => {
90
86
  model.setFeatureHeight(
91
87
  height !== '' && !Number.isNaN(+height) ? +height : undefined,
92
88
  )
93
89
  model.setNoSpacing(noSpacing)
94
-
95
90
  handleClose()
96
91
  }}
97
92
  >
98
93
  Submit
99
94
  </Button>
100
- </div>
95
+ <Button
96
+ variant="contained"
97
+ color="secondary"
98
+ onClick={() => handleClose()}
99
+ >
100
+ Cancel
101
+ </Button>
102
+ </DialogActions>
101
103
  </DialogContent>
102
104
  </Dialog>
103
105
  )
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
5
  Dialog,
6
+ DialogActions,
6
7
  DialogContent,
7
8
  DialogTitle,
8
9
  IconButton,
@@ -41,7 +42,7 @@ function SetMaxHeightDlg(props: {
41
42
 
42
43
  return (
43
44
  <Dialog open onClose={handleClose}>
44
- <DialogTitle id="alert-dialog-title">
45
+ <DialogTitle>
45
46
  Filter options
46
47
  <IconButton
47
48
  aria-label="close"
@@ -51,21 +52,24 @@ function SetMaxHeightDlg(props: {
51
52
  <CloseIcon />
52
53
  </IconButton>
53
54
  </DialogTitle>
54
- <DialogContent>
55
- <div className={classes.root}>
56
- <Typography>Set max height for the track</Typography>
57
- <TextField
58
- value={max}
59
- onChange={event => {
60
- setMax(event.target.value)
61
- }}
62
- placeholder="Enter max height for layout"
63
- />
55
+ <DialogContent className={classes.root}>
56
+ <Typography>
57
+ Set max height for the track. For example, you can increase this if
58
+ the layout says "Max height reached"
59
+ </Typography>
60
+ <TextField
61
+ value={max}
62
+ onChange={event => {
63
+ setMax(event.target.value)
64
+ }}
65
+ placeholder="Enter max height for layout"
66
+ />
67
+ <DialogActions>
64
68
  <Button
65
69
  variant="contained"
66
70
  color="primary"
67
71
  type="submit"
68
- style={{ marginLeft: 20 }}
72
+ autoFocus
69
73
  onClick={() => {
70
74
  model.setMaxHeight(
71
75
  max !== '' && !Number.isNaN(+max) ? +max : undefined,
@@ -75,7 +79,14 @@ function SetMaxHeightDlg(props: {
75
79
  >
76
80
  Submit
77
81
  </Button>
78
- </div>
82
+ <Button
83
+ variant="contained"
84
+ color="secondary"
85
+ onClick={() => handleClose()}
86
+ >
87
+ Cancel
88
+ </Button>
89
+ </DialogActions>
79
90
  </DialogContent>
80
91
  </Dialog>
81
92
  )
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
5
  Dialog,
6
+ DialogActions,
6
7
  DialogContent,
7
8
  DialogTitle,
8
9
  IconButton,
@@ -47,29 +48,29 @@ function SortByTagDlg(props: {
47
48
  </IconButton>
48
49
  </DialogTitle>
49
50
  <DialogContent>
50
- <div>
51
- <Typography>Set the tag to sort by</Typography>
52
- <Typography color="textSecondary">
53
- Examples: HP for haplotype, RG for read group, etc.
54
- </Typography>
55
- <TextField
56
- value={tag}
57
- onChange={event => {
58
- setTag(event.target.value)
59
- }}
60
- placeholder="Enter tag name"
61
- inputProps={{
62
- maxLength: 2,
63
- 'data-testid': 'sort-tag-name-input',
64
- }}
65
- error={tag.length === 2 && !validTag}
66
- helperText={tag.length === 2 && !validTag ? 'Not a valid tag' : ''}
67
- autoComplete="off"
68
- data-testid="sort-tag-name"
69
- />
51
+ <Typography>Set the tag to sort by</Typography>
52
+ <Typography color="textSecondary">
53
+ Examples: HP for haplotype, RG for read group, etc.
54
+ </Typography>
55
+ <TextField
56
+ value={tag}
57
+ onChange={event => setTag(event.target.value)}
58
+ placeholder="Enter tag name"
59
+ inputProps={{
60
+ maxLength: 2,
61
+ 'data-testid': 'sort-tag-name-input',
62
+ }}
63
+ error={tag.length === 2 && !validTag}
64
+ helperText={tag.length === 2 && !validTag ? 'Not a valid tag' : ''}
65
+ autoComplete="off"
66
+ data-testid="sort-tag-name"
67
+ />
68
+ <DialogActions>
70
69
  <Button
71
70
  variant="contained"
72
71
  color="primary"
72
+ type="submit"
73
+ autoFocus
73
74
  onClick={() => {
74
75
  model.setSortedBy('tag', tag)
75
76
  handleClose()
@@ -77,7 +78,14 @@ function SortByTagDlg(props: {
77
78
  >
78
79
  Submit
79
80
  </Button>
80
- </div>
81
+ <Button
82
+ variant="contained"
83
+ color="secondary"
84
+ onClick={() => handleClose()}
85
+ >
86
+ Cancel
87
+ </Button>
88
+ </DialogActions>
81
89
  </DialogContent>
82
90
  </Dialog>
83
91
  )
@@ -460,7 +460,7 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
460
460
  {
461
461
  label: 'Sort by tag...',
462
462
  onClick: () => {
463
- getSession(self).queueDialog((doneCallback: Function) => [
463
+ getSession(self).queueDialog(doneCallback => [
464
464
  SortByTagDlg,
465
465
  { model: self, handleClose: doneCallback },
466
466
  ])
@@ -506,10 +506,16 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
506
506
  self.setColorScheme({ type: 'perBaseQuality' })
507
507
  },
508
508
  },
509
+ {
510
+ label: 'Per-base lettering',
511
+ onClick: () => {
512
+ self.setColorScheme({ type: 'perBaseLettering' })
513
+ },
514
+ },
509
515
  {
510
516
  label: 'Modifications or methylation',
511
517
  onClick: () => {
512
- getSession(self).queueDialog((doneCallback: Function) => [
518
+ getSession(self).queueDialog(doneCallback => [
513
519
  ModificationsDlg,
514
520
  { model: self, handleClose: doneCallback },
515
521
  ])
@@ -530,7 +536,7 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
530
536
  {
531
537
  label: 'Color by tag...',
532
538
  onClick: () => {
533
- getSession(self).queueDialog((doneCallback: Function) => [
539
+ getSession(self).queueDialog(doneCallback => [
534
540
  ColorByTagDlg,
535
541
  { model: self, handleClose: doneCallback },
536
542
  ])
@@ -542,7 +548,7 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
542
548
  label: 'Filter by',
543
549
  icon: FilterListIcon,
544
550
  onClick: () => {
545
- getSession(self).queueDialog((doneCallback: Function) => [
551
+ getSession(self).queueDialog(doneCallback => [
546
552
  FilterByTagDlg,
547
553
  { model: self, handleClose: doneCallback },
548
554
  ])
@@ -551,7 +557,7 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
551
557
  {
552
558
  label: 'Set feature height',
553
559
  onClick: () => {
554
- getSession(self).queueDialog((doneCallback: Function) => [
560
+ getSession(self).queueDialog(doneCallback => [
555
561
  SetFeatureHeightDlg,
556
562
  { model: self, handleClose: doneCallback },
557
563
  ])
@@ -560,7 +566,7 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
560
566
  {
561
567
  label: 'Set max height',
562
568
  onClick: () => {
563
- getSession(self).queueDialog((doneCallback: Function) => [
569
+ getSession(self).queueDialog(doneCallback => [
564
570
  SetMaxHeightDlg,
565
571
  { model: self, handleClose: doneCallback },
566
572
  ])
@@ -27,11 +27,11 @@ const TooltipContents = React.forwardRef(
27
27
  const start = feature.get('start')
28
28
  const end = feature.get('end')
29
29
  const name = feature.get('refName')
30
+ const info = feature.get('snpinfo') as SNPInfo
30
31
  const loc = [name, start === end ? en(start) : `${en(start)}..${en(end)}`]
31
32
  .filter(f => !!f)
32
33
  .join(':')
33
34
 
34
- const info = feature.get('snpinfo') as SNPInfo
35
35
  const total = info?.total
36
36
 
37
37
  return (
@@ -64,7 +64,9 @@ const TooltipContents = React.forwardRef(
64
64
  <td>
65
65
  {base === 'total' || base === 'skip'
66
66
  ? '---'
67
- : `${Math.floor((score.total / total) * 100)}%`}
67
+ : `${Math.floor(
68
+ (score.total / (total || score.total || 1)) * 100,
69
+ )}%`}
68
70
  </td>
69
71
  <td>
70
72
  {strands['-1'] ? `${strands['-1']}(-)` : ''}
@@ -90,7 +92,7 @@ const SNPCoverageTooltip = observer(
90
92
  height: number
91
93
  offsetMouseCoord: Coord
92
94
  clientMouseCoord: Coord
93
- clientRect?: ClientRect
95
+ clientRect?: DOMRect
94
96
  }) => {
95
97
  const { model } = props
96
98
  const { featureUnderMouse: feat } = model
@@ -40,11 +40,10 @@ export default function SNPCoverageConfigFactory(pluginManager: PluginManager) {
40
40
  defaultValue: false,
41
41
  },
42
42
 
43
- headroom: {
44
- type: 'number',
45
- description:
46
- 'round the upper value of the domain scale to the nearest N',
47
- defaultValue: 0,
43
+ multiTicks: {
44
+ type: 'boolean',
45
+ description: 'Display multiple values for the ticks',
46
+ defaultValue: false,
48
47
  },
49
48
 
50
49
  renderers: ConfigurationSchema('RenderersConfiguration', {