JBrowse 2 · React App examples

Sessions

Read the open views, share them as a link, open several.

Observe the session

Anything marked #getter or #property on the session model or a view model is reactive. There is no change callback: to save the session, take getSnapshot(viewState.session) and pass it back as the session option.

View source — 60 lines
import { JBrowseApp, useCreateViewState } from '@jbrowse/react-app2'
import { observer } from 'mobx-react'

const base = 'https://jbrowse.org/code/jb2/main/test_data/volvox'

const config = {
  assemblies: [
    { name: 'volvox', uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit' },
  ],
  tracks: [
    {
      trackId: 'volvox_cram',
      name: 'volvox-sorted.cram',
      uri: `${base}/volvox-sorted.cram`,
    },
  ],
  defaultSession: {
    name: 'observe',
    views: [
      {
        id: 'view-0',
        type: 'LinearGenomeView',
        assembly: 'volvox',
        loc: 'ctgA:1..50000',
        tracks: ['volvox_cram'],
      },
    ],
  },
}

const SessionSummary = observer(function SessionSummary({
  viewState,
}: {
  viewState: NonNullable<ReturnType<typeof useCreateViewState>>
}) {
  const { views } = viewState.session
  return (
    <div style={{ padding: 8, fontFamily: 'monospace', fontSize: 12 }}>
      <div>{views.length} view(s) open</div>
      <ul style={{ margin: 0 }}>
        {views.map(view => (
          <li key={view.id}>
            {view.type} — {view.coarseVisibleLocStrings || 'no region'}
          </li>
        ))}
      </ul>
    </div>
  )
})

export default function ObserveSession() {
  const viewState = useCreateViewState({ config })

  return viewState ? (
    <div>
      <SessionSummary viewState={viewState} />
      <JBrowseApp viewState={viewState} />
    </div>
  ) : null
}

Put the session in the URL

The hash fragment never reaches the server, so a long session cannot fail with HTTP 414. Only the session travels: the receiving page supplies its own assemblies and tracks, and File → New session still returns to defaultSession.

View source — 96 lines
import { useState } from 'react'

import {
  JBrowseApp,
  createViewStateAsync,
  decodeSession,
  encodeSession,
  useCreateViewState,
} from '@jbrowse/react-app2'

const base = 'https://jbrowse.org/code/jb2/main/test_data/volvox'

const config = {
  assemblies: [
    { name: 'volvox', uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit' },
  ],
  tracks: [
    {
      trackId: 'volvox_gff3',
      name: 'Volvox genes',
      uri: `${base}/volvox.sort.gff3.gz`,
    },
  ],
  defaultSession: {
    name: 'Session in URL',
    views: [
      {
        id: 'view-0',
        type: 'LinearGenomeView',
        assembly: 'volvox',
        loc: 'ctgA:1..50000',
        tracks: ['volvox_gff3'],
      },
    ],
  },
}

function writeSessionParam(value: string) {
  const params = new URLSearchParams(window.location.hash.slice(1))
  params.set('session', value)
  window.history.replaceState(null, '', `#${params.toString()}`)
}

async function build(report: (status: string) => void) {
  const param = new URLSearchParams(window.location.hash.slice(1)).get(
    'session',
  )
  if (param) {
    try {
      const session = await decodeSession(param)
      const engine = await createViewStateAsync({ config, session })
      report(`restored "${session.name}" from the URL`)
      return engine
    } catch (e) {
      console.error(e)
      report(`could not restore the session in the URL: ${e}`)
    }
  }
  return createViewStateAsync({ config })
}

export default function SessionInUrl() {
  const [status, setStatus] = useState('')
  const viewState = useCreateViewState(() => build(setStatus))

  return viewState ? (
    <div>
      <div style={{ padding: 8, fontSize: 13, background: '#8881' }}>
        {status || 'navigate or open a track, then save from the app toolbar'}
      </div>
      <JBrowseApp
        viewState={viewState}
        headerButtons={
          <button
            type="button"
            onClick={() => {
              void encodeSession(viewState)
                .then(encoded => {
                  writeSessionParam(encoded)
                  setStatus(
                    `saved to the URL (${encoded.length} chars) — copy the address bar, or reload to restore it`,
                  )
                })
                .catch((e: unknown) => {
                  console.error(e)
                  setStatus(`could not save the session to the URL: ${e}`)
                })
            }}
          >
            Save to URL
          </button>
        }
      />
    </div>
  ) : null
}

Multiple views in one session

View source — 44 lines
import { JBrowse } from '@jbrowse/react-app2'

const base = 'https://jbrowse.org/code/jb2/main/test_data/volvox'

const assemblies = [
  { name: 'volvox', uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit' },
]

const tracks = [
  {
    trackId: 'volvox_sv',
    name: 'volvox structural variants',
    uri: `${base}/volvox.dup.vcf.gz`,
    category: ['Variants'],
  },
  {
    trackId: 'volvox_cram',
    name: 'volvox-sorted.cram',
    uri: `${base}/volvox-sorted.cram`,
    category: ['Alignments'],
  },
]

export default function MultiViewSession() {
  return (
    <JBrowse
      assemblies={assemblies}
      tracks={tracks}
      views={[
        {
          type: 'CircularView',
          assembly: 'volvox',
          tracks: ['volvox_sv'],
        },
        {
          type: 'LinearGenomeView',
          assembly: 'volvox',
          loc: 'ctgA:1..50000',
          tracks: ['volvox_cram'],
        },
      ]}
    />
  )
}