Loading configuration
Import or fetch a config.json, or add tracks and views later.
On this page: Import a config.json · Fetch a config.json · Add tracks programmatically · Launch a view imperatively
Import a config.json
Bundled at build time.
URIs in a config.json are relative to where it was served, so
addRelativeUris resolves them against that URL. The file’s shape is
JBrowseRootConfig.
View source — 13 lines
import { addRelativeUris } from '@jbrowse/core/util/addRelativeUris'
import { JBrowseApp, useCreateViewState } from '@jbrowse/react-app2'
import config from '../volvox-config.json' with { type: 'json' }
const configUrl =
'https://jbrowse.org/code/jb2/main/test_data/volvox/config.json'
addRelativeUris(config, new URL(configUrl))
export default function WithImportConfigJson() {
const state = useCreateViewState({ config })
return state ? <JBrowseApp viewState={state} /> : null
}Fetch a config.json
Fetched at runtime.
Unlike JBrowse Web, the embedded app does not load a config’s plugins: hand
them to loadPlugins, whose baseUri resolves a relative plugin URL against
the config rather than your page.
View source — 48 lines
import { useEffect, useState } from 'react'
import { addRelativeUris } from '@jbrowse/core/util/addRelativeUris'
import {
JBrowseApp,
createViewState,
destroyViewState,
loadPlugins,
} from '@jbrowse/react-app2'
type ViewState = ReturnType<typeof createViewState>
const configUrl =
'https://jbrowse.org/code/jb2/main/test_data/volvox/config.json'
export default function WithFetchConfigJson() {
const [state, setState] = useState<ViewState>()
useEffect(() => {
const mount = {
unmounted: false,
engine: undefined as ViewState | undefined,
}
void (async () => {
const response = await fetch(configUrl)
if (!response.ok) {
throw new Error(`HTTP ${response.status} fetching config ${configUrl}`)
}
const config = await response.json()
addRelativeUris(config, new URL(configUrl))
const plugins = await loadPlugins(config.plugins ?? [], {
baseUri: configUrl,
})
if (mount.unmounted) {
return
}
mount.engine = createViewState({ config, plugins })
setState(mount.engine)
})()
return () => {
mount.unmounted = true
if (mount.engine) {
destroyViewState(mount.engine)
}
}
}, [])
return state ? <JBrowseApp viewState={state} /> : null
}Add tracks programmatically
addTrackConf, then launchTrack.
View source — 57 lines
import { useRef, useState } from 'react'
import { JBrowse } from '@jbrowse/react-app2'
import type { ViewModel } from '@jbrowse/react-app2'
const base = 'https://jbrowse.org/code/jb2/main/test_data/volvox'
const assemblies = [{ name: 'volvox', uri: `${base}/volvox.2bit` }]
const genesTrackConf = {
type: 'FeatureTrack',
trackId: 'volvox_genes',
name: 'Volvox genes',
assemblyNames: ['volvox'],
adapter: { type: 'Gff3TabixAdapter', uri: `${base}/volvox.sort.gff3.gz` },
}
export default function AddTracksProgrammatically() {
const ref = useRef<ViewModel>(null)
const [added, setAdded] = useState(false)
async function addTrack() {
const state = ref.current
if (state) {
state.jbrowse.addTrackConf(genesTrackConf)
await state.session.views[0]?.launchTrack('volvox_genes')
setAdded(true)
}
}
return (
<div>
<button
disabled={added}
onClick={() => {
void addTrack()
}}
>
{added ? 'Genes track added' : 'Add genes track'}
</button>
<JBrowse
ref={ref}
assemblies={assemblies}
tracks={[]}
sessionName="Programmatic tracks"
views={[
{
type: 'LinearGenomeView',
assembly: 'volvox',
loc: 'ctgA:1..50000',
},
]}
/>
</div>
)
}Launch a view imperatively
The LaunchView extension point, after mount.
LaunchView-LinearSyntenyView and LaunchView-DotplotView work the same way.
Automating JBrowse describes the
init they share.
View source — 80 lines
import { useEffect, useState } from 'react'
import { ErrorMessage } from '@jbrowse/core/ui'
import { getEnv } from '@jbrowse/core/util'
import {
JBrowseApp,
createViewState,
destroyViewState,
} from '@jbrowse/react-app2'
type ViewState = ReturnType<typeof createViewState>
export default function WithLaunchLinearGenomeView() {
const [viewState, setViewState] = useState<ViewState>()
const [error, setError] = useState<unknown>()
useEffect(() => {
const mount = { engine: undefined as ViewState | undefined }
void (async () => {
try {
const state = createViewState({
config: {
assemblies: [
{
name: 'GRCh38',
aliases: ['hg38'],
uri: 'https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz',
refNameAliases: {
uri: 'https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt',
},
geneticCodes: { chrM: 2 },
},
],
tracks: [
{
type: 'QuantitativeTrack',
trackId: 'hg38.100way.phyloP100way',
name: 'hg38.100way.phyloP100way',
category: ['Conservation'],
assemblyNames: ['hg38'],
adapter: {
type: 'BigWigAdapter',
uri: 'https://hgdownload.soe.ucsc.edu/goldenpath/hg38/phyloP100way/hg38.phyloP100way.bw',
},
},
],
},
})
const { pluginManager } = getEnv(state)
mount.engine = state
setViewState(state)
await pluginManager.evaluateAsyncExtensionPointStrict(
'LaunchView-LinearGenomeView',
{
tracks: ['hg38.100way.phyloP100way'],
loc: 'chr10:1-100000',
assembly: 'hg38',
session: state.session,
},
)
} catch (e) {
console.error(e)
setError(e)
}
})()
return () => {
if (mount.engine) {
destroyViewState(mount.engine)
}
}
}, [])
return viewState ? (
<>
{error ? <ErrorMessage error={error} /> : null}
<JBrowseApp viewState={viewState} />
</>
) : null
}