Multiple views
Companion panels that follow the view, and two views on one page.
Observe the visible view
Key a fetch off coarseDynamicBlocks, the debounced twin of dynamicBlocks, or
a drag fires one per frame. Two fetches can resolve out of order; the generation
counter keeps the older one from landing last.
View source — 126 lines
import { useEffect, useState } from 'react'
import { getConf } from '@jbrowse/core/configuration'
import { getRpcSessionId } from '@jbrowse/core/util/tracks'
import {
JBrowseLinearGenomeView,
useCreateViewState,
} from '@jbrowse/react-linear-genome-view2'
import { autorun } from 'mobx'
import { observer } from 'mobx-react'
import type { Feature } from '@jbrowse/core/util'
import type { ViewModel } from '@jbrowse/react-linear-genome-view2'
const VisibleRegions = observer(function VisibleRegions({
viewState,
}: {
viewState: ViewModel
}) {
const view = viewState.session.view
return view.initialized ? (
<p>Visible region {view.coarseVisibleLocStrings}</p>
) : null
})
const VisibleFeatures = observer(function VisibleFeatures({
viewState,
}: {
viewState: ViewModel
}) {
const [features, setFeatures] = useState<Feature[]>()
const [error, setError] = useState<unknown>()
const { rpcManager, view } = viewState.session
useEffect(() => {
let latest = 0
return autorun(() => {
if (view.initialized) {
const track = view.tracks[0]
if (track) {
const adapterConfig = getConf(track, 'adapter')
const sessionId = getRpcSessionId(track)
const generation = ++latest
void rpcManager
// eslint-disable-next-line no-restricted-syntax
.call(sessionId, 'CoreGetFeatures', {
adapterConfig,
regions: view.coarseDynamicBlocks,
})
.then(feats => {
if (generation === latest) {
setFeatures(feats)
}
})
.catch((e: unknown) => {
if (generation === latest) {
setError(e)
}
})
}
}
})
}, [rpcManager, view])
return error ? (
<div>Error: {String(error)}</div>
) : !features ? (
<div>Loading...</div>
) : (
<table>
<thead>
<tr>
<th>Name</th>
<th>Location</th>
</tr>
</thead>
<tbody>
{features.map(f => (
<tr key={f.id()}>
<td>{f.get('name')}</td>
<td>
{f.get('refName')}:{f.get('start')}-{f.get('end')}
</td>
</tr>
))}
</tbody>
</table>
)
})
export default function ObserveVisible() {
const state = useCreateViewState({
assembly: {
name: 'volvox',
uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit',
},
tracks: [
{
type: 'FeatureTrack',
trackId: 'volvox_gff3',
name: 'Volvox genes',
assemblyNames: ['volvox'],
adapter: {
type: 'Gff3TabixAdapter',
uri: 'https://jbrowse.org/code/jb2/main/test_data/volvox/volvox.sort.gff3.gz',
},
},
],
defaultSession: {
name: 'Observe visible',
view: {
type: 'LinearGenomeView',
assembly: 'volvox',
loc: 'ctgA:1105..1221',
tracks: ['volvox_gff3'],
},
},
})
return state ? (
<div>
<JBrowseLinearGenomeView viewState={state} />
<VisibleRegions viewState={state} />
<VisibleFeatures viewState={state} />
</div>
) : null
}Observe the selected feature
View source — 60 lines
import { isFeature } from '@jbrowse/core/util'
import {
JBrowseLinearGenomeView,
useCreateViewState,
} from '@jbrowse/react-linear-genome-view2'
import { observer } from 'mobx-react'
import type { ViewModel } from '@jbrowse/react-linear-genome-view2'
const SelectedFeature = observer(function SelectedFeature({
viewState,
}: {
viewState: ViewModel
}) {
const { selection } = viewState.session
return isFeature(selection) ? (
<p>
Selected <b>{selection.get('name') || selection.id()}</b> at{' '}
{selection.get('refName')}:{selection.get('start')}-{selection.get('end')}
</p>
) : (
<p>Click a feature to select it.</p>
)
})
export default function ObserveSelection() {
const state = useCreateViewState({
assembly: {
name: 'volvox',
uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit',
},
tracks: [
{
type: 'FeatureTrack',
trackId: 'volvox_gff3',
name: 'Volvox genes',
assemblyNames: ['volvox'],
adapter: {
type: 'Gff3TabixAdapter',
uri: 'https://jbrowse.org/code/jb2/main/test_data/volvox/volvox.sort.gff3.gz',
},
},
],
defaultSession: {
name: 'Observe selection',
view: {
type: 'LinearGenomeView',
assembly: 'volvox',
loc: 'ctgA:1..50,000',
tracks: ['volvox_gff3'],
},
},
})
return state ? (
<div>
<JBrowseLinearGenomeView viewState={state} />
<SelectedFeature viewState={state} />
</div>
) : null
}Two linear genome views
View source — 41 lines
import {
JBrowseLinearGenomeView,
useCreateViewState,
} from '@jbrowse/react-linear-genome-view2'
const assembly = {
name: 'volvox',
uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit',
}
const tracks = [
{
type: 'FeatureTrack',
trackId: 'volvox_gff3',
name: 'Volvox genes',
assemblyNames: ['volvox'],
adapter: {
type: 'Gff3TabixAdapter',
uri: 'https://jbrowse.org/code/jb2/main/test_data/volvox/volvox.sort.gff3.gz',
},
},
]
export default function WithTwoLinearGenomeViews() {
const state1 = useCreateViewState({
assembly,
tracks,
location: 'ctgA:1105..1221',
})
const state2 = useCreateViewState({
assembly,
tracks,
location: 'ctgA:5560..30589',
})
return (
<div>
{state1 ? <JBrowseLinearGenomeView viewState={state1} /> : null}
{state2 ? <JBrowseLinearGenomeView viewState={state2} /> : null}
</div>
)
}