JBrowse 2 · Linear Genome View examples

Export & errors

Render the whole view to a vector SVG (or rasterized PNG), and catch and render view errors with your own UI.

Export the view (SVG/PNG)

exportSvg renders the whole view to a publication-ready vector image, reached through a ref (or state.session.view under createViewState):

await ref.current.session.view.exportSvg({ filename: 'volvox.svg' })

It resolves once every visible track has re-rendered through the SVG code path, then hands the result to the browser’s download flow. format: 'png' rasterizes the same markup; trackLabels, themeName and fontSize tune the output. Options: ExportSvgOptions.

View source — 80 lines
import { useRef, useState } from 'react'

import { ErrorBanner } from '@jbrowse/core/ui'
import { LinearGenomeView } from '@jbrowse/react-linear-genome-view2'

import type { ViewModel } 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 ExportSvg() {
  const ref = useRef<ViewModel>(null)
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<unknown>()

  // exportSvg is an async action on the view model — it renders every track
  // through the SVG code path and hands the result to FileSaver. format 'png'
  // rasterizes the same markup. See #action-exportsvg in the docs below.
  async function download(format: 'svg' | 'png') {
    setBusy(true)
    setError(undefined)
    try {
      await ref.current?.session.view.exportSvg({
        filename: `volvox.${format}`,
        format,
      })
    } catch (e) {
      setError(e)
    } finally {
      setBusy(false)
    }
  }

  return (
    <div>
      <div style={{ marginBottom: 8 }}>
        <button
          disabled={busy}
          style={{ marginRight: 8 }}
          onClick={() => {
            void download('svg')
          }}
        >
          Export SVG
        </button>
        <button
          disabled={busy}
          onClick={() => {
            void download('png')
          }}
        >
          Export PNG
        </button>
        {busy ? ' Rendering…' : null}
      </div>
      {error ? <ErrorBanner error={error} /> : null}
      <LinearGenomeView
        ref={ref}
        assembly={assembly}
        tracks={tracks}
        init={{ loc: 'ctgA:1..50,000', tracks: ['volvox_gff3'] }}
      />
    </div>
  )
}

Custom error handling

The embedded view ships no error boundary, so catching errors is the host app’s job. There are two kinds:

  • constructioncreateViewState validates the config and can throw a (verbose) @jbrowse/mobx-state-tree error. Wrap the call in try/catch.
  • runtime — observable at viewState.session.view.error. An observer can render your own UI when it becomes truthy.

For both, ErrorBanner from @jbrowse/core/ui is an error display (not a React error boundary): it formats JBrowse errors with a stack-trace button and, for validation failures, the offending config snapshot. ErrorMessage is the plain-text sibling.

This demo configures a BadTrack track type that fails validation, so the banner has something real to render.

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

import { ErrorBanner } from '@jbrowse/core/ui'
import {
  JBrowseLinearGenomeView,
  createViewState,
} from '@jbrowse/react-linear-genome-view2'

import type { ViewModel } from '@jbrowse/react-linear-genome-view2'

export default function WithErrorHandler() {
  // createViewState builds the whole model synchronously, so it either hands
  // back an engine or throws — there is no third, still-loading state
  const [result] = useState<{ viewState: ViewModel } | { error: unknown }>(
    () => {
      try {
        return {
          viewState: createViewState({
            assembly: {
              name: 'volvox',
              uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit',
            },
            tracks: [
              {
                type: 'BadTrack',
                notProperTrack: 'error',
                shouldHaveTrackIdAndStuff: 'test',
              },
            ],
            location: 'ctgA:1105..1221',
          }),
        }
      } catch (error) {
        return { error }
      }
    },
  )
  return 'error' in result ? (
    <ErrorBanner error={result.error} />
  ) : (
    <JBrowseLinearGenomeView viewState={result.viewState} />
  )
}