@jbrowse/plugin-alignments 1.6.7 → 1.7.0

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 (94) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +216 -0
  2. package/dist/AlignmentsFeatureDetail/index.js +63 -0
  3. package/dist/AlignmentsFeatureDetail/index.test.js +60 -0
  4. package/dist/AlignmentsTrack/index.js +37 -0
  5. package/dist/BamAdapter/BamAdapter.js +598 -0
  6. package/dist/BamAdapter/BamAdapter.test.js +177 -0
  7. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +1 -10
  8. package/dist/BamAdapter/BamSlightlyLazyFeature.js +176 -0
  9. package/dist/BamAdapter/MismatchParser.d.ts +3 -5
  10. package/dist/BamAdapter/MismatchParser.js +384 -0
  11. package/dist/BamAdapter/MismatchParser.test.js +259 -0
  12. package/dist/BamAdapter/configSchema.js +48 -0
  13. package/dist/BamAdapter/index.js +36 -0
  14. package/dist/CramAdapter/CramAdapter.js +660 -0
  15. package/dist/CramAdapter/CramAdapter.test.js +138 -0
  16. package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -2
  17. package/dist/CramAdapter/CramSlightlyLazyFeature.js +447 -0
  18. package/dist/CramAdapter/CramTestAdapters.js +234 -0
  19. package/dist/CramAdapter/configSchema.js +40 -0
  20. package/dist/CramAdapter/index.js +36 -0
  21. package/dist/HtsgetBamAdapter/HtsgetBamAdapter.js +97 -0
  22. package/dist/HtsgetBamAdapter/configSchema.js +31 -0
  23. package/dist/HtsgetBamAdapter/index.js +42 -0
  24. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +69 -0
  25. package/dist/LinearAlignmentsDisplay/index.js +31 -0
  26. package/dist/LinearAlignmentsDisplay/models/configSchema.js +25 -0
  27. package/dist/LinearAlignmentsDisplay/models/configSchema.test.js +83 -0
  28. package/dist/LinearAlignmentsDisplay/models/model.js +250 -0
  29. package/dist/LinearPileupDisplay/components/ColorByModifications.js +123 -0
  30. package/dist/LinearPileupDisplay/components/ColorByTag.js +98 -0
  31. package/dist/LinearPileupDisplay/components/FilterByTag.js +203 -0
  32. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +32 -0
  33. package/dist/LinearPileupDisplay/components/SetFeatureHeight.js +99 -0
  34. package/dist/LinearPileupDisplay/components/SetMaxHeight.js +90 -0
  35. package/dist/LinearPileupDisplay/components/SortByTag.js +95 -0
  36. package/dist/LinearPileupDisplay/configSchema.js +47 -0
  37. package/dist/LinearPileupDisplay/configSchema.test.js +92 -0
  38. package/dist/LinearPileupDisplay/index.js +30 -0
  39. package/dist/LinearPileupDisplay/model.js +602 -0
  40. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +63 -0
  41. package/dist/LinearSNPCoverageDisplay/index.js +30 -0
  42. package/dist/LinearSNPCoverageDisplay/models/configSchema.js +57 -0
  43. package/dist/LinearSNPCoverageDisplay/models/configSchema.test.js +62 -0
  44. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +2 -2
  45. package/dist/LinearSNPCoverageDisplay/models/model.js +237 -0
  46. package/dist/NestedFrequencyTable.js +152 -0
  47. package/dist/PileupRPC/rpcMethods.js +285 -0
  48. package/dist/PileupRenderer/PileupLayoutSession.js +79 -0
  49. package/dist/PileupRenderer/PileupRenderer.d.ts +20 -6
  50. package/dist/PileupRenderer/PileupRenderer.js +1220 -0
  51. package/dist/PileupRenderer/components/PileupRendering.js +270 -0
  52. package/dist/PileupRenderer/components/PileupRendering.test.js +36 -0
  53. package/dist/PileupRenderer/configSchema.js +72 -0
  54. package/dist/PileupRenderer/index.js +25 -0
  55. package/dist/PileupRenderer/sortUtil.js +112 -0
  56. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +3 -11
  57. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +606 -0
  58. package/dist/SNPCoverageAdapter/configSchema.js +22 -0
  59. package/dist/SNPCoverageAdapter/index.js +45 -0
  60. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +296 -0
  61. package/dist/SNPCoverageRenderer/configSchema.js +40 -0
  62. package/dist/SNPCoverageRenderer/index.js +34 -0
  63. package/dist/declare.d.js +1 -0
  64. package/dist/index.js +154 -6
  65. package/dist/index.test.js +26 -0
  66. package/dist/plugin-alignments.cjs.development.js +591 -552
  67. package/dist/plugin-alignments.cjs.development.js.map +1 -1
  68. package/dist/plugin-alignments.cjs.production.min.js +1 -1
  69. package/dist/plugin-alignments.cjs.production.min.js.map +1 -1
  70. package/dist/plugin-alignments.esm.js +594 -555
  71. package/dist/plugin-alignments.esm.js.map +1 -1
  72. package/dist/shared.js +96 -0
  73. package/dist/util.d.ts +4 -0
  74. package/dist/util.js +135 -0
  75. package/package.json +5 -9
  76. package/src/BamAdapter/BamAdapter.ts +45 -15
  77. package/src/BamAdapter/BamSlightlyLazyFeature.ts +11 -79
  78. package/src/BamAdapter/MismatchParser.test.ts +53 -297
  79. package/src/BamAdapter/MismatchParser.ts +54 -116
  80. package/src/BamAdapter/configSchema.ts +0 -4
  81. package/src/CramAdapter/CramAdapter.ts +42 -15
  82. package/src/CramAdapter/CramSlightlyLazyFeature.ts +3 -10
  83. package/src/LinearPileupDisplay/components/ColorByModifications.tsx +76 -80
  84. package/src/LinearPileupDisplay/components/ColorByTag.tsx +24 -23
  85. package/src/LinearPileupDisplay/components/FilterByTag.tsx +73 -68
  86. package/src/LinearPileupDisplay/components/SetFeatureHeight.tsx +28 -26
  87. package/src/LinearPileupDisplay/components/SetMaxHeight.tsx +24 -13
  88. package/src/LinearPileupDisplay/components/SortByTag.tsx +29 -21
  89. package/src/LinearPileupDisplay/model.ts +8 -22
  90. package/src/LinearSNPCoverageDisplay/models/model.ts +6 -36
  91. package/src/PileupRenderer/PileupRenderer.tsx +178 -60
  92. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +189 -244
  93. package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +12 -11
  94. 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 &quot;Max height reached&quot;
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
  )
@@ -27,7 +27,6 @@ import FilterListIcon from '@material-ui/icons/ClearAll'
27
27
 
28
28
  import { autorun, observable } from 'mobx'
29
29
  import { AnyConfigurationModel } from '@jbrowse/core/configuration/configurationSchema'
30
- import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain'
31
30
  import { LinearPileupDisplayConfigModel } from './configSchema'
32
31
  import LinearPileupDisplayBlurb from './components/LinearPileupDisplayBlurb'
33
32
 
@@ -377,26 +376,6 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
377
376
  return LinearPileupDisplayBlurb
378
377
  },
379
378
 
380
- get filters() {
381
- let filters: string[] = []
382
- const { flagInclude, flagExclude, tagFilter, readName } =
383
- self.filterBy
384
-
385
- filters = [
386
- `jexl:((get(feature,'flags')&${flagInclude})==${flagInclude}) && !(get(feature,'flags')&${flagExclude})`,
387
- ]
388
- if (tagFilter) {
389
- const { tag, value } = tagFilter
390
- filters.push(
391
- `jexl:"${value}" =='*' ? getTag(feature,"${tag}") != undefined : getTag(feature,"${tag}") == "${value}"`,
392
- )
393
- }
394
- if (readName) {
395
- filters.push(`jexl:get(feature,'name') == "${readName}"`)
396
- }
397
- return new SerializableFilterChain({ filters })
398
- },
399
-
400
379
  renderProps() {
401
380
  const view = getContainingView(self) as LGV
402
381
  const {
@@ -404,6 +383,7 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
404
383
  modificationTagMap,
405
384
  sortedBy,
406
385
  colorBy,
386
+ filterBy,
407
387
  rpcDriverName,
408
388
  } = self
409
389
 
@@ -419,9 +399,9 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
419
399
  displayModel: self,
420
400
  sortedBy,
421
401
  colorBy,
402
+ filterBy,
422
403
  colorTagMap: JSON.parse(JSON.stringify(colorTagMap)),
423
404
  modificationTagMap: JSON.parse(JSON.stringify(modificationTagMap)),
424
- filters: this.filters,
425
405
  showSoftClip: self.showSoftClipping,
426
406
  config: self.rendererConfig,
427
407
  }
@@ -506,6 +486,12 @@ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
506
486
  self.setColorScheme({ type: 'perBaseQuality' })
507
487
  },
508
488
  },
489
+ {
490
+ label: 'Per-base lettering',
491
+ onClick: () => {
492
+ self.setColorScheme({ type: 'perBaseLettering' })
493
+ },
494
+ },
509
495
  {
510
496
  label: 'Modifications or methylation',
511
497
  onClick: () => {
@@ -1,13 +1,14 @@
1
1
  import { addDisposer, types, cast, getEnv, getSnapshot } from 'mobx-state-tree'
2
2
  import { observable, autorun } from 'mobx'
3
- import { getConf, readConfObject } from '@jbrowse/core/configuration'
4
- import { linearWiggleDisplayModelFactory } from '@jbrowse/plugin-wiggle'
5
3
  import {
4
+ getConf,
5
+ readConfObject,
6
6
  AnyConfigurationSchemaType,
7
7
  AnyConfigurationModel,
8
- } from '@jbrowse/core/configuration/configurationSchema'
8
+ } from '@jbrowse/core/configuration'
9
+ import { linearWiggleDisplayModelFactory } from '@jbrowse/plugin-wiggle'
10
+
9
11
  import PluginManager from '@jbrowse/core/PluginManager'
10
- import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain'
11
12
  import { getContainingView } from '@jbrowse/core/util'
12
13
  import Tooltip from '../components/Tooltip'
13
14
  import { getUniqueModificationValues } from '../../shared'
@@ -135,7 +136,6 @@ const stateModelFactory = (
135
136
  return {
136
137
  ...superProps,
137
138
  notReady: superProps.notReady || !this.modificationsReady,
138
- filters: self.filters,
139
139
  modificationTagMap: JSON.parse(
140
140
  JSON.stringify(self.modificationTagMap),
141
141
  ),
@@ -143,6 +143,7 @@ const stateModelFactory = (
143
143
  // must use getSnapshot because otherwise changes to e.g. just the
144
144
  // colorBy.type are not read
145
145
  colorBy: self.colorBy ? getSnapshot(self.colorBy) : undefined,
146
+ filterBy: self.filterBy,
146
147
  }
147
148
  },
148
149
  }
@@ -241,37 +242,6 @@ const stateModelFactory = (
241
242
  },
242
243
  ]
243
244
  },
244
- // The SNPCoverage filters are called twice because the BAM/CRAM
245
- // features pass filters and then the SNPCoverage score features pass
246
- // through here, and are already have 'snpinfo' are passed through
247
- get filters() {
248
- let filters: string[] = []
249
- if (self.filterBy) {
250
- const { flagInclude, flagExclude, tagFilter, readName } =
251
- self.filterBy
252
- filters = [
253
- `jexl:get(feature,'snpinfo') != undefined ? true : ` +
254
- `((get(feature,'flags')&${flagInclude})==${flagInclude}) && ` +
255
- `!((get(feature,'flags')&${flagExclude}))`,
256
- ]
257
-
258
- if (tagFilter) {
259
- const { tag, value } = tagFilter
260
- filters.push(
261
- `jexl:get(feature,'snpinfo') != undefined ? true : ` +
262
- `"${value}" =='*' ? getTag(feature,"${tag}") != undefined : ` +
263
- `getTag(feature,"${tag}") == "${value}"`,
264
- )
265
- }
266
- if (readName) {
267
- filters.push(
268
- `jexl:get(feature,'snpinfo') != undefined ? true : ` +
269
- `get(feature,'name') == "${readName}"`,
270
- )
271
- }
272
- }
273
- return new SerializableFilterChain({ filters })
274
- },
275
245
  }
276
246
  })
277
247