Pluggable elements
TL;DR: the ten element types a plugin can register — adapters, text search adapters, displays, tracks, connections, views, widgets, RPC methods, internet accounts and add-track workflows — plus extension points, and which guide covers each. Drawing is implemented by the display types.
A plugin's install method adds these elements to the host application, while
configure typically sets up
mobx autoruns that react to
application state (Writing a plugin covers the class
itself). A plugin is loaded at runtime as an ESM module, or a UMD bundle for
legacy compatibility, and only one version of a given plugin can be loaded on
a page, even if multiple products use it.
Pluggable elements
Pluggable elements are pieces of functionality a plugin can add to JBrowse, in the order the plugin manager creates them:
| Phase | Element type | Registered with |
|---|---|---|
| 1 | Adapter types | pluginManager.addAdapterType() |
| 2 | Text search adapter types | pluginManager.addTextSearchAdapterType() |
| 3 | Display types | pluginManager.addDisplayType() |
| 4 | Track types | pluginManager.addTrackType() |
| 5 | Connection types | pluginManager.addConnectionType() |
| 6 | View types | pluginManager.addViewType() |
| 7 | Widget types | pluginManager.addWidgetType() |
| 8 | RPC method types | pluginManager.addRpcMethod() |
| 9 | Internet account types | pluginManager.addInternetAccountType() |
| 10 | Add track workflow types | pluginManager.addAddTrackWorkflowType() |
The order is a real dependency: your install runs before any of them are
built, and the plugin manager then creates each group in turn, so a track type
registered in the fourth phase can look up a display type registered in the
third by name. Look up only what an earlier phase has already built.
Extension points are the eleventh way a plugin extends the app: named callbacks the host fires. See Extension points.
Elements are composable: adapters can wrap other adapters (MultiWiggleAdapter
takes a subadapters array), and views can contain sub-views (SvInspectorView
holds a SpreadsheetView and a CircularView).
The three you will meet first relate like this:
- A view is a container that typically has tracks
- A track controls what data (adapter) and how it's shown (display)
- A display owns the drawing of a track's data; a track may have multiple displays for different view types
View types
View types allow entirely different visualizations alongside the linear genome view. The seven in-tree types:
LinearGenomeView- the classic linear view of a genomeCircularView- a Circos-like circular whole genome viewDotplotView- a comparative 2-D genome viewLinearSyntenyView- two or more linear views stacked, with synteny drawn between themBreakpointSplitView- two linear views showing the two sides of a structural variantSpreadsheetView- a tabular view of a feature fileSvInspectorView- super-view containingCircularViewandSpreadsheetViewsub-views
Each has a generated state-model page under State models, and Custom view types covers writing your own.
Adapters
Adapters parse a data format. To write your own, see
creating adapters. The
@jbrowse/plugin-alignments plugin creates:
BamAdapter- wraps the@gmod/bamNPM module for the browserCramAdapter- wraps the@gmod/cramNPM module; the sequence adapter is injected at runtime from the enclosing assembly
Supported file types maps every supported format to the adapter that reads it.
Track types
A track combines an adapter with one or more displays, and can also:
- Add extra menu items to the track menu. The track's own menu is assembled from
its displays'
trackMenuItems()plus a "Display types" submenu, so most items come from the display rather than the track - Add its own file formats to "Save track data"
Example tracks:
AlignmentsTrack(from@jbrowse/plugin-alignments) - reads and their coverage, drawn by a singleLinearAlignmentsDisplayVariantTrack(from@jbrowse/plugin-variants) - displays variant featuresFeatureTrack(from@jbrowse/plugin-linear-genome-view) - displays generic features including gene glyphs
Displays
A display is a method for showing a track in a particular view, letting one track entry work across view types; a track may own several, one per view type it supports. A display also decides:
- What the track draws, and on which rendering path (see below)
- Which widget opens on a feature click, via a
featureWidgetTypegetter - Which regions to fetch — the view's
staticBlocks(stable while scrolling) ordynamicBlocks(recomputed as the view moves)
See Custom track and display types for how tracks and displays relate and when to add a new one, and Tracks for the generated table of which displays attach to which track type.
Rendering
Drawing is implemented by the display types:
- The worker fetches feature data via RPC and returns compact typed arrays (absolute genomic uint32 coordinates). Its job ends there; drawing begins on the main thread.
- The main thread draws that data with WebGPU, falling back to WebGL2, then Canvas2D. This covers alignments, features, variants, wiggle, synteny, MAF, Hi-C, GWAS and dotplot. Every one of them supplies a Canvas2D draw function, which SVG export runs too, so on-screen and exported pixels stay identical; the shader path is an accelerator layered over it.
- The arc displays take a third route: their components emit JSX
<path>elements, on screen and in SVG export alike.
DisplayChrome is the wrapper every canvas-backed display renders, and it owns
the loading scrim, the error banner, the "region too large" message and the
render-error retry. It picks between them from a single getter,
displayPhase,
which each display answers with one of loading / error / tooLarge /
renderError / ready. So a new display gets every terminal state by composing
the foundation mixins and answering that getter, and the arc displays get the
same chrome through DisplayStatusChrome, the backend-free half.
See display foundations for the mixins this is built from, and GPU displays to build one.
Widgets
Widgets are custom info panels shown in side panels, modals, or elsewhere. Most of the app's own chrome is built from them — the plugin store, the session manager and the track selector are all widgets. The ones a plugin author meets first:
BaseFeatureWidget- the feature detail panelConfigurationEditorWidget- the per-track settings editorAddTrackWidgetandAddConnectionWidget- the two add flows
Plugins can extend widgets. For example, @jbrowse/plugin-alignments extends
BaseFeatureWidget:
AlignmentsFeatureWidget- customizes the basic feature detail widget for alignments features
A display names the one it opens with a featureWidgetType getter; to replace a
widget you do not own, use
Core-replaceWidget.
RPC methods
Plugins can register RPC methods to offload custom behavior to a web worker or server-side process. The wiggle plugin registers, for example:
MultiWiggleGetScoreMatrixMultiWiggleClusterScoreMatrix
These run in the web worker when available.
Add track workflows
Add track workflows let a plugin supply a custom React component for loading tracks into a session. See the add-track workflow guide.
Connection types
A connection fetches a set of track configs from somewhere else and adds them to
the session — UCSCTrackHubConnection, JB2TrackHubConnection and
JBrowse1Connection are the in-tree ones. See
Custom connections.
Text search adapter types
A text search adapter answers the search box's name lookups. See Text search adapters.
Internet account types
An internet account supplies credentials for a data source that needs them, so a
track can read from Dropbox, Google Drive, or a host behind HTTP basic auth or a
bearer token. @jbrowse/plugin-authentication registers all five; their config
slots are documented under BaseInternetAccount.
Extension points
Extension points are named callback chains: a producer fires one, and any plugin can register a callback against the same name to transform what it carries, add to a list, or just react.
See the full extension point API or the menus guide for an example of adding context menu items.