diff --git a/plugins/alignments/src/LinearPileupDisplay/SharedLinearPileupDisplayMixin.ts b/plugins/alignments/src/LinearPileupDisplay/SharedLinearPileupDisplayMixin.ts index 2b45d71c3c..b581890442 100644 --- a/plugins/alignments/src/LinearPileupDisplay/SharedLinearPileupDisplayMixin.ts +++ b/plugins/alignments/src/LinearPileupDisplay/SharedLinearPileupDisplayMixin.ts @@ -680,6 +680,7 @@ export function SharedLinearPileupDisplayMixin( }, })) .preProcessSnapshot(snap => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (snap) { // @ts-expect-error const { colorBy, filterBy, ...rest } = snap diff --git a/plugins/alignments/src/LinearPileupDisplay/components/GroupByDialog.tsx b/plugins/alignments/src/LinearPileupDisplay/components/GroupByDialog.tsx index 7cd0ffb236..b4e62a702b 100644 --- a/plugins/alignments/src/LinearPileupDisplay/components/GroupByDialog.tsx +++ b/plugins/alignments/src/LinearPileupDisplay/components/GroupByDialog.tsx @@ -23,8 +23,7 @@ import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view' // locals import { getUniqueTags } from '../../shared/getUniqueTags' -import { LinearAlignmentsDisplayModel } from '../../LinearAlignmentsDisplay/model' -import { defaultFilterFlags } from '../../shared/util' +import { defaultFilterFlags, negFlags, posFlags } from '../../shared/util' function clone(c: unknown) { return JSON.parse(JSON.stringify(c)) @@ -42,7 +41,6 @@ const GroupByTagDialog = observer(function (props: { const [tagSet, setGroupByTagSet] = useState() const [loading, setLoading] = useState(false) const [error, setError] = useState() - const [includeUndefined, setIncludeUndefined] = useState(true) const validTag = /^[A-Za-z][A-Za-z0-9]$/.exec(tag) const isInvalid = tag.length === 2 && !validTag @@ -75,10 +73,16 @@ const GroupByTagDialog = observer(function (props: { return ( + + NOTE: this will create new session tracks with the "filter by" set to + the values chosen here rather than affecting the current track state + setType(event.target.value)} + onChange={event => { + setType(event.target.value) + }} label="Group by..." select > @@ -87,25 +91,10 @@ const GroupByTagDialog = observer(function (props: { {type === 'tag' ? ( <> - - NOTE: this will create new session tracks with the "filter by" set - to the values chosen here rather than affecting the current track - state - Examples: HP for haplotype, RG for read group, etc. - { - setIncludeUndefined(!includeUndefined) - }} - /> - } - label="Make a new subtrack for undefined values of tag as well?" - /> + { @@ -150,10 +139,7 @@ const GroupByTagDialog = observer(function (props: { const view = getContainingView(model) as LinearGenomeViewModel if (type === 'tag') { if (tagSet) { - const ret = [...tagSet] as (string | undefined)[] - if (includeUndefined) { - ret.push(undefined) - } + const ret = [...tagSet, undefined] as (string | undefined)[] for (const tagValue of ret) { const t1 = `${trackConf.trackId}-${tag}:${tagValue}-${+Date.now()}-sessionTrack` // @ts-expect-error @@ -185,6 +171,7 @@ const GroupByTagDialog = observer(function (props: { } else if (type === 'strand') { const t1 = `${trackConf.trackId}-${tag}:(-)-${+Date.now()}-sessionTrack` const t2 = `${trackConf.trackId}-${tag}:(+)-${+Date.now()}-sessionTrack` + // @ts-expect-error session.addTrackConf({ ...trackConf, @@ -197,12 +184,14 @@ const GroupByTagDialog = observer(function (props: { pileupDisplay: { displayId: `${t1}-LinearAlignmentsDisplay-LinearPileupDisplay`, type: 'LinearPileupDisplay', - filterBy: { - flagInclude: 16, - flagExclude: 1540, - }, + filterBy: negFlags, }, }, + { + displayId: `${t1}-LinearSNPCoverageDisplay`, + type: 'LinearSNPCoverageDisplay', + filterBy: negFlags, + }, ], }) // @ts-expect-error @@ -217,12 +206,14 @@ const GroupByTagDialog = observer(function (props: { pileupDisplay: { displayId: `${t2}-LinearAlignmentsDisplay-LinearPileupDisplay`, type: 'LinearPileupDisplay', - filterBy: { - flagInclude: 0, - flagExclude: 1556, - }, + filterBy: posFlags, }, }, + { + displayId: `${t2}-LinearSNPCoverageDisplay`, + type: 'LinearSNPCoverageDisplay', + filterBy: posFlags, + }, ], }) view.showTrack(t1) diff --git a/plugins/alignments/src/LinearReadArcsDisplay/configSchema.ts b/plugins/alignments/src/LinearReadArcsDisplay/configSchema.ts index 3ba8e453a2..e5b3ff90cd 100644 --- a/plugins/alignments/src/LinearReadArcsDisplay/configSchema.ts +++ b/plugins/alignments/src/LinearReadArcsDisplay/configSchema.ts @@ -1,7 +1,6 @@ import PluginManager from '@jbrowse/core/PluginManager' import { ConfigurationSchema } from '@jbrowse/core/configuration' import { linearBasicDisplayConfigSchemaFactory } from '@jbrowse/plugin-linear-genome-view' -import { types } from 'mobx-state-tree' import { defaultFilterFlags } from '../shared/util' /** diff --git a/plugins/alignments/src/LinearReadCloudDisplay/model.ts b/plugins/alignments/src/LinearReadCloudDisplay/model.ts index 68895b6854..48625055bb 100644 --- a/plugins/alignments/src/LinearReadCloudDisplay/model.ts +++ b/plugins/alignments/src/LinearReadCloudDisplay/model.ts @@ -19,7 +19,6 @@ import FilterListIcon from '@mui/icons-material/ClearAll' // locals import { ColorBy, FilterBy } from '../shared/types' import { ChainData } from '../shared/fetchChains' -import { defaultFilterFlags } from '../shared/util' // async const FilterByTagDialog = lazy( diff --git a/plugins/alignments/src/LinearSNPCoverageDisplay/configSchema.ts b/plugins/alignments/src/LinearSNPCoverageDisplay/configSchema.ts index 17db5c43f0..d873416ef7 100644 --- a/plugins/alignments/src/LinearSNPCoverageDisplay/configSchema.ts +++ b/plugins/alignments/src/LinearSNPCoverageDisplay/configSchema.ts @@ -2,6 +2,7 @@ import { ConfigurationSchema } from '@jbrowse/core/configuration' import { baseLinearDisplayConfigSchema } from '@jbrowse/plugin-linear-genome-view' import { types } from 'mobx-state-tree' import PluginManager from '@jbrowse/core/PluginManager' +import { defaultFilterFlags } from '../shared/util' /** * #config LinearSNPCoverageDisplay @@ -52,7 +53,8 @@ export default function SNPCoverageConfigFactory(pluginManager: PluginManager) { }, /** * #slot - */ inverted: { + */ + inverted: { type: 'boolean', description: 'draw upside down', defaultValue: false, @@ -73,6 +75,25 @@ export default function SNPCoverageConfigFactory(pluginManager: PluginManager) { 'SNPCoverageRenderer', )!.configSchema, }), + /** + * #slot + */ + colorBy: { + type: 'frozen', + description: 'color scheme to use', + defaultValue: { + type: 'normal', + }, + }, + + /** + * #slot + */ + filterBy: { + type: 'frozen', + description: 'default filters to use', + defaultValue: defaultFilterFlags, + }, }, { /** diff --git a/plugins/alignments/src/LinearSNPCoverageDisplay/model.ts b/plugins/alignments/src/LinearSNPCoverageDisplay/model.ts index 3a987b8c9c..1cfeb9f0d7 100644 --- a/plugins/alignments/src/LinearSNPCoverageDisplay/model.ts +++ b/plugins/alignments/src/LinearSNPCoverageDisplay/model.ts @@ -62,14 +62,11 @@ function stateModelFactory( /** * #property */ - filterBy: types.optional(types.frozen(), { - flagInclude: 0, - flagExclude: 1540, - }), + filterBySetting: types.frozen(), /** * #property */ - colorBy: types.frozen(), + colorBySetting: types.frozen(), /** * #property */ @@ -88,6 +85,21 @@ function stateModelFactory( */ modificationsReady: false, })) + .views(self => ({ + /** + * #getter + */ + get colorBy() { + return self.colorBySetting ?? getConf(self, 'colorBy') + }, + + /** + * #getter + */ + get filterBy() { + return self.filterBySetting ?? getConf(self, 'filterBy') + }, + })) .actions(self => ({ /** * #action @@ -99,7 +111,7 @@ function stateModelFactory( * #action */ setFilterBy(filter: FilterBy) { - self.filterBy = { + self.filterBySetting = { ...filter, } }, @@ -107,7 +119,7 @@ function stateModelFactory( * #action */ setColorScheme(colorBy?: ColorBy) { - self.colorBy = colorBy + self.colorBySetting = colorBy ? { ...colorBy, } diff --git a/plugins/alignments/src/shared/util.ts b/plugins/alignments/src/shared/util.ts index ea5b257549..86e7a73dc9 100644 --- a/plugins/alignments/src/shared/util.ts +++ b/plugins/alignments/src/shared/util.ts @@ -22,6 +22,14 @@ export const defaultFilterFlags = { flagInclude: 0, flagExclude: 1540, } +export const negFlags = { + flagInclude: 16, + flagExclude: 1540, +} +export const posFlags = { + flagInclude: 0, + flagExclude: 1556, +} export function cacheGetter(ctor: { prototype: T }, prop: keyof T): void { const desc = Object.getOwnPropertyDescriptor(ctor.prototype, prop)! diff --git a/test_data/volvox/config.json b/test_data/volvox/config.json index f03e884036..db228fdb93 100644 --- a/test_data/volvox/config.json +++ b/test_data/volvox/config.json @@ -330,7 +330,7 @@ { "type": "AlignmentsTrack", "trackId": "volvox_cram_pileup", - "name": "volvox-sorted.cram (contigA, LinearPileupDisplay, large height)", + "name": "volvox-sorted.cram (contigA, LinearPileupDisplay, large height, colorBy mappingQual)", "category": ["Integration test"], "metadata": { "description": "this is a metadata description", @@ -490,7 +490,7 @@ { "type": "AlignmentsTrack", "trackId": "volvox_alignments", - "name": "volvox-sorted.bam (ctgA, larger default height)", + "name": "volvox-sorted.bam (ctgA, larger default height, colorBy mappingQual)", "category": ["Integration test"], "assemblyNames": ["volvox", "volvox2"], "adapter": {