JBrowse 2 · React App examples

Multi-way linear synteny view

Stack four E. coli strains in one synteny view, all backed by a single all-vs-all PAF.

A LinearSyntenyView is not limited to two genomes. Give init.views three or more assemblies and the view stacks them as rows, each adjacent pair joined by a connecting ribbon. This example stacks four E. coli strains (K-12, Sakai, CFT073, NCTC86) — the pangenome demo from the all-vs-all synteny tutorial.

With N rows there are N−1 bands, so tracks is an array per band: tracks[i] holds the track(s) connecting views[i] and views[i+1]. Because a single all-vs-all PAF aligns every strain to every other, one AllVsAllPAFAdapter track (whose assemblyNames lists all four strains) backs all three bands:

{
  type: 'LinearSyntenyView',
  init: {
    views: [
      { assembly: 'K12' },
      { assembly: 'Sakai' },
      { assembly: 'CFT073' },
      { assembly: 'NCTC86' },
    ],
    tracks: [['ecoli_ava'], ['ecoli_ava'], ['ecoli_ava']],
    drawCurves: true,
    minAlignmentLength: 10000,
  },
}

minAlignmentLength hides the short minimap2 alignments so the shared backbone reads as clean ribbons. The nested tracks shape matches JBrowse Web’s multi-way ?session=spec-… URL — see the multi-way section of the URL query parameter API. For separate pairwise files instead of one all-vs-all track, give each band its own PAF.

The full set of fields init accepts is in the LinearSyntenyView state model docs.

Live demo

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

// Four E. coli strains aligned all-vs-all (the E. coli pangenome demo from the
// all-vs-all synteny tutorial). Data hosted at jbrowse.org/demos/ecoli_pangenome.
const base = 'https://jbrowse.org/demos/ecoli_pangenome'

const strains = [
  { name: 'K12', displayName: 'E. coli K12' },
  { name: 'Sakai', displayName: 'E. coli Sakai' },
  { name: 'CFT073', displayName: 'E. coli CFT073' },
  { name: 'NCTC86', displayName: 'E. coli NCTC86' },
]

const assemblies = strains.map(({ name, displayName }) => ({
  name,
  displayName,
  sequence: {
    type: 'ReferenceSequenceTrack',
    trackId: `${name}-ref`,
    // bare `uri` shorthand: the .fai/.gzi siblings are derived automatically
    adapter: { type: 'BgzipFastaAdapter', uri: `${base}/${name}.fa.gz` },
  },
}))

// A single all-vs-all PAF whose assemblyNames list every strain, so one track
// can align any adjacent pair — this one SyntenyTrack backs all three bands.
const tracks = [
  {
    type: 'SyntenyTrack',
    trackId: 'ecoli_ava',
    name: 'E. coli pangenome (all-vs-all PAF)',
    assemblyNames: strains.map(s => s.name),
    category: ['Synteny'],
    adapter: {
      type: 'AllVsAllPAFAdapter',
      pafLocation: { uri: `${base}/all_vs_all.paf.gz` },
      assemblyNames: strains.map(s => s.name),
    },
  },
]

export default function MultiwaySyntenyExample() {
  return (
    <JBrowse
      assemblies={assemblies}
      tracks={tracks}
      views={[
        {
          type: 'LinearSyntenyView',
          init: {
            // four strain rows → three bands, all backed by ecoli_ava
            views: strains.map(s => ({ assembly: s.name })),
            tracks: [['ecoli_ava'], ['ecoli_ava'], ['ecoli_ava']],
            drawCurves: true,
            // hide the short minimap2 alignments so the shared backbone reads
            // as clean ribbons instead of a dense noise band
            minAlignmentLength: 10000,
          },
        },
      ]}
    />
  )
}