Custom view types
TL;DR: View types are top-level "panels" the session can contain alongside
built-ins like LinearGenomeView, DotplotView, and CircularView. A view
defines its own state model and React component; displaying genomic tracks is
optional.
When to add a custom view type
Add a view type when you need a panel with its own layout, state, and toolbar that does not fit inside an existing view. Examples:
jbrowse-plugin-msaviewadds a multiple sequence alignment view that has no underlying tracks at allDotplotViewandLinearSyntenyViewhost synteny tracks but with their own axis and layout logic
To render features differently inside the linear genome view, use a custom display type.
Minimal walkthrough
The plugin templates scaffold the build
setup to register a view via pluginManager.addViewType(...). Every built-in
view is registered the same way — this is the dotplot's, in full:
import { lazy } from 'react'
import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'
import { dotplotLaunchKeys } from './launchKeys.ts'
import type PluginManager from '@jbrowse/core/PluginManager'
import type { ViewTypeRegistry } from '@jbrowse/core/PluginManager'
export default function DotplotViewF(pluginManager: PluginManager) {
pluginManager.addViewType(() => {
// annotated against the registry rather than inferred, which is what
// makes a hand-written augmentation earn what `getViewType` promises
// its callers — see `ViewTypeRegistry`
const stateModel = (): Promise<ViewTypeRegistry['DotplotView']> =>
import('./model.ts').then(f => f.default(pluginManager))
return new ViewType({
name: 'DotplotView',
displayName: 'Dotplot view',
stateModel,
launchKeys: dotplotLaunchKeys,
ReactComponent: lazy(() => import('./components/DotplotView.tsx')),
})
})
}
ViewType takes four core options:
name— what a session snapshot and a URL spec store.displayName— what the view launcher's dropdown shows.stateModel— a mobx-state-tree model, see MST patterns.ReactComponent— receives{ model }as a prop. Wrap it inReact.lazyas every built-in view does, so the view's whole component tree stays out of the initial bundle until a session opens one.
ViewType takes two more options:
extendedNamenames another view type whose displays yours should also accept. Display types register against exactly one view type, so a subtype ofLinearGenomeViewneeds this to pick up the displays every track already has:addViewTypecollects the displays matching yournameor yourextendedName.viewMetadata: { hiddenFromGUI: true }keeps the type out of the view launcher's dropdown, for a view that only ever arrives from a spec, a connection, or another view's action.
The registry entry the snippet annotates against also types the call that opens
the view. session.addView('DotplotView', { ... }) checks the snapshot against
your state model, so a misspelled key is a compile error at the call site rather
than a key MST drops on attach; replaceView and addOrReplaceView read the
same type. A name the registry does not carry still takes anything, which is
what a view keeps until it augments
ViewTypeRegistry.
Making the view launchable from a session spec
Registering the view type is what lets a session snapshot restore one. Opening
one from a URL is separate: loadSessionSpec dispatches on the spec's type to
a LaunchView-<name> extension point, and a view type with no registered point
cannot be launched from a spec; the error names the view type.
Register one to make yours launchable, exporting the args interface and
augmenting ExtensionPointRegistry beside it. The spreadsheet view's launcher
is the worked example, under
TypeScript types for extension points;
the LaunchView points
covers what the launcher is handed and which spec keys never reach it.
Reference implementations in this repo
plugins/linear-genome-view/src/LinearGenomeView- the canonical genomic view, with displayed regions, blocks, and a track containerplugins/dotplot-view/src/DotplotView- independent X/Y axes hosting synteny tracksplugins/spreadsheet-view/src/SpreadsheetView- non-genomic tabular viewplugins/circular-view/src/CircularView- radial layout with chord tracks
See also
- Custom track and display types
- Extension points
- MST patterns
- Pluggable elements
- VIEW_INIT.md
— the launch state machine under the session spec above, and where
afterAttachsits in it - REGION_VIEW_LAUNCH.md — the convention for opening another view type on a locus, where the two existing launchers diverge, and what is still open