Coloring and grouping by a field
Two menus set the color and the row facet from any attribute, with a Legend.
In grammar-of-graphics terms, Color by is a color scale and Group rows by is a
facet, each over a field. setColorScale and setFacet take the same
{ field, domain }. The color scale assigns the palette in domain order, and
the facet stacks the rows for those values first.
Grouping and lane order
covers the facet on every display.
View source — 123 lines
import {
EmbedProvider,
Legend,
Toolbar,
TrackStack,
} from '@jbrowse/display-ui/embed'
import { useCreateViewState } from '@jbrowse/react-linear-genome-view2'
import { observer } from 'mobx-react'
import type { LinearBasicDisplayModel } from '@jbrowse/plugin-canvas'
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
const fields = ['gene_biotype', 'strand', 'source']
const domains: Record<string, string[]> = {
gene_biotype: ['protein_coding', 'lncRNA', 'pseudogene'],
}
const FieldSelect = observer(function FieldSelect({
label,
value,
onChange,
}: {
label: string
value?: string
onChange: (field?: string) => void
}) {
return (
<label>
{label}{' '}
<select
value={value ?? ''}
onChange={event => {
onChange(event.target.value || undefined)
}}
>
<option value="">nothing</option>
{fields.map(field => (
<option key={field} value={field}>
{field}
</option>
))}
</select>
</label>
)
})
const Channels = observer(function Channels({
view,
}: {
view: LinearGenomeViewModel
}) {
const display = view.getTrack('genes')?.activeDisplay as
| LinearBasicDisplayModel
| undefined
if (!display) {
return null
}
return (
<Toolbar>
<FieldSelect
label="Color by"
value={display.colorField?.field}
onChange={field => {
display.setColorScale(
field ? { field, domain: domains[field] } : undefined,
)
}}
/>
<FieldSelect
label="Group rows by"
value={display.facet?.field}
onChange={field => {
display.setFacet(
field ? { field, domain: domains[field] } : undefined,
)
}}
/>
<Legend view={view} trackId="genes" />
</Toolbar>
)
})
const ColorAndGroupByAField = observer(function ColorAndGroupByAField() {
const state = useCreateViewState({
assembly: {
name: 'hg38',
uri: 'https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz',
refNameAliases: {
uri: 'https://jbrowse.org/genomes/GRCh38/hg38_aliases.txt',
},
},
tracks: [
{
trackId: 'genes',
name: 'NCBI RefSeq genes',
uri: 'https://jbrowse.org/genomes/GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz',
displayDefaults: {
height: 220,
geneGlyphMode: 'longestCoding',
color: { field: 'gene_biotype', domain: domains.gene_biotype },
showLegend: false,
},
},
],
view: {
loc: 'chr17:42,900,000..43,400,000',
tracks: ['genes'],
},
})
if (!state) {
return null
}
const { session } = state
return (
<EmbedProvider session={session}>
<Channels view={session.view} />
<TrackStack view={session.view} />
</EmbedProvider>
)
})
export default ColorAndGroupByAField