CircularView
Auto-generated @jbrowse/mobx-state-tree API for the current JBrowse release — see pluggable elements for concepts. Provided by the circular-view plugin. View source.
Example usage
Hand-authored under defaultSession.views, with every setting written
directly on the view object. assembly picks the genome, a tracks entry may
carry display config inline, and displayedRegionNames keeps an assembly's
alt/unplaced contigs off the circle:
{
type: 'CircularView',
assembly: 'hg38',
displayedRegionNames: ['chr1', 'chr2', 'chr3'],
tracks: [{ trackId: 'my-sv-vcf', strokeColor: 'red' }],
}assembly also takes a list, for a synteny ribbon plot: each
assembly lays its contigs out in turn, so the first genome takes one arc of
the circle and the second the next, and a SyntenyTrack covering both draws
a ribbon per alignment between them. displayedRegionNames keyed by assembly
restricts each genome separately, and autoDiagonalize reorders the second
to follow the first:
{
type: 'CircularView',
assembly: ['hg38', 'mm39'],
displayedRegionNames: { hg38: ['chr1', 'chr2'] },
tracks: ['hg38_vs_mm39'],
autoDiagonalize: true,
}Members a composed model contributes are listed here too, so these tables are the whole surface.
Properties
| Member | Description | Defined by |
|---|---|---|
typetype: types.literal('CircularView') as unknown as string | this is a string instead of the const literal 'CircularView' to reduce some typescripting strictness, but you should pass the string 'CircularView' to the model explicitly | CircularView |
| offsetRadians | similar to offsetPx in linear genome view | CircularView |
bpPerPxbpPerPx: types.stripDefault(types.number, defaultBpPerPx) | the zoom level, base-pairs per pixel. Capped by minimumRadiusPx, and refit over by the first resize unless autoFit is false. | CircularView |
autoFitautoFit: types.stripDefault(types.boolean, true) | whether the view keeps re-fitting to its container on resize. Cleared once the user manually zooms/pans so their view (persisted via bpPerPx/offsetRadians) is preserved across resizes and reloads. | CircularView |
| tracks | CircularView | |
| hideVerticalResizeHandle | chrome switch, for an embed that drives the view itself | CircularView |
| chrome switch, for an embed that drives the view itself | CircularView | |
disableImportFormdisableImportForm: types.stripDefault(types.boolean, false) | suppress the import form even on an error — what the SV inspector's circle wants, since its assembly comes from the sheet beside it and a form there would offer a control that cannot work | CircularView |
showLegendshowLegend: types.stripDefault(types.boolean, false) | a key naming each track's ring, chords or ribbons in the corner | CircularView |
heightheight: types.stripDefault(types.number, defaultHeight) | the height of the view in pixels. The circle auto-fits its container, so this is what sizes the drawing. | CircularView |
| displayedRegions | the regions the circle lays out, one arc each, in this order. displayedRegionNames names the same thing by refName and is the shorter form. | CircularView |
| minimumRadiusPx | how far in the circle may be zoomed, as a floor on the radius; it is what caps bpPerPx | CircularView |
spacingPxspacingPx: types.stripDefault(types.number, defaultSpacingPx) | the gap drawn between adjacent chromosome arcs | CircularView |
paddingPxpaddingPx: types.stripDefault(types.number, defaultPaddingPx) | blank margin between the circle and the edge of the figure | CircularView |
| minVisibleWidth | arcs thinner than this many pixels are elided instead of drawn, so a few thousand unplaced contigs do not become a ring of hairlines | CircularView |
| trackSelectorType | vestigial: the hierarchical selector is the only one that exists, so this value is ignored. Retained because saved sessions and configs persist it. | CircularView |
| launch | transient launch state: the settings written on the view object that need resolving before they can be view state — the assembly the circle is drawn from, the refNames to restrict it to, chord track recipes. preProcessSnapshot moves them here off the snapshot, the afterAttach autorun applies them and clears this, so a saved session never retains it. Not written by hand: author every setting directly on the view. | CircularView |
idid: ElementId | BaseViewModel | |
displayNamedisplayName: types.maybe(types.string) | displayName is displayed in the header of the view, or assembly names being used if none is specified | BaseViewModel |
minimizedminimized: types.stripDefault(types.boolean, false) | collapse the view to its header bar, keeping it in the session rather than closing it | BaseViewModel |
Volatiles
| Member | Description | Defined by |
|---|---|---|
volatileWidthvolatileWidth: undefined as number | undefined | CircularView | |
volatileErrorvolatileError: undefined as unknown | CircularView | |
panXpanX: 0 | CircularView | |
panYpanY: 0 | CircularView | |
ringHostringHost: RingHost.create({}) | the strip every linear display in this view lays out along, and the rings drawn from it — see regionHost | CircularView |
widthwidth: 800 | BaseViewModel | |
bodyMountedbodyMounted: true | Whether the container has this view's body in the DOM.ViewContainer mounts a view's body only while an IntersectionObserver says it is on screen, to hold the app under the WebGL2 context ceiling (reference/GPU_CONTEXT_BUDGET.md). A view below the fold therefore has no canvas, so nothing ever calls markCanvasDrawn and the pre-first-paint term of displayPhase pins every display in it at loading with nothing left to resolve it — which parks [data-app-phase="ready"] for the whole app on a view the user cannot see.Defaults true so the containers that always mount a body — embedded views, workspace panels, and any test rendering a display directly — are unaffected and need not set it. The raw flag, written by this view's own container. A display asks effectiveBodyMounted instead, because a nested view has no container of its own. | BaseViewModel |
awaitingAutoDiagonalizeawaitingAutoDiagonalize: false | True while the init autorun is waiting on the diagonalize RPC. Gates the canvas off — otherwise the user watches an undiagonalized hairball flash before the reorder kicks in. | DiagonalizeProgressMixin |
pendingAutoDiagonalizependingAutoDiagonalize: false | A reorder this init asked for that has not succeeded yet. Raised before any render can paint, and lowered only once the pass RESOLVES — a skipped or thrown reorder leaves it up, so the view's settled gate never reports done on an undiagonalized view and the capture fails loudly (times out) instead of committing a hairball.One flag rather than a requested/complete pair: the two only ever moved together, and every state a pair can drift into either wedges the gate shut or opens it on the wrong pass. | DiagonalizeProgressMixin |
diagonalizeStatusdiagonalizeStatus: createStatusChannel() | Live status from the auto-diagonalize RPC (download %, parse, algorithm phase) shown on the reordering spinner; blank outside that wait. A StatusChannel rather than a status field plus a setter: there is one operation to narrate here, and the channel is that pair with the message/fraction split already done, so the spinner reads { message, fraction } instead of calling statusMessageText / statusFraction at every render site. | DiagonalizeProgressMixin |
diagonalizeCanceldiagonalizeCancel: undefined as (() => void) | undefined | Aborts the in-flight auto-diagonalize, so the spinner's Cancel can reach it; undefined when none is running. | DiagonalizeProgressMixin |
diagonalizeErrordiagonalizeError: undefined as unknown | Why the last reorder failed, while its gate is still up; cleared by the next run, a finish or a cancel | DiagonalizeProgressMixin |
| importFormSyntenyTrackSelections | ImportFormSyntenyMixin |
Getters
| Member | Description | Defined by |
|---|---|---|
ownTracksany[] | The census entry for this view: the tracks it holds itself. Declared rather than derived — see BaseViewModel.ownTracks. | CircularView |
widthnumber | CircularView | |
effectivePaddingPxnumber | paddingPx, capped so it cannot eat a small box.The declared value is a fixed 80px sized for a circle with a window to itself, and it comes out of the radius twice. In the SV inspector, whose circle gets about a third of the width, that left the drawn disc covering 41% of the area it was given, and in a 316px-tall one — the height the SV tutorial's figure sets — the radius fell to 78px. Capped as a fraction of the half-box rather than at a pixel count, so the circle holds one shape at every size. The fraction is the one the declared 80px already is at the size it was tuned for, so a roomy circle is untouched and a cramped one is merely not made worse. The floor is what the ruler labels need to sit outside the arc at all. | CircularView |
effectiveSpacingPxnumber | spacingPx, capped so the inter-chromosome gaps cannot take the ring.Also a fixed pixel count, and it is charged once per slice, so what it costs depends entirely on how big the circle ended up: 27% of the circumference at the SV inspector's default and 49% of it at that 316px-tall one, where the chromosomes drew as ticks with holes between them. Capping the total rather than the gap keeps a roomy circle on the declared value and only closes up where the ring is genuinely short. Measured against the radius the box would fit rather than radiusPx, which is derived from this. | CircularView |
fitRadiusPxnumber | the radius the current box has room for — what fitToWindow aims at, and the scale effectiveSpacingPx measures itself against. A pure function of the box, so neither reads back a value derived from it | CircularView |
circumferencePxnumber | CircularView | |
radiusPxnumber | CircularView | |
bpPerRadiannumber | CircularView | |
centerXY[number, number] | CircularView | |
totalBpnumber | CircularView | |
maxBpPerPxnumber | CircularView | |
minBpPerPxnumber | CircularView | |
atMaxBpPerPxboolean | CircularView | |
atMinBpPerPxboolean | CircularView | |
figureSizenumber | figure is always square, so width === height | CircularView |
figureOriginXY[number, number] | top-left of the figure within the view's box, then shifted by the zoom-to-cursor pan. Centered horizontally: a view much wider than it is tall would otherwise leave the circle jammed in the corner under the controls. Vertically it hangs from the top of a box taller than it is wide — see figureMiddleY, which zoomToPoint reads for the same reason. | CircularView |
elidedRegionsSliceRegion[] | this is displayedRegions, post-processed to elide regions that are too small to see reasonably | CircularView |
| pendingLaunch | the launch state that still has something to apply — the gate the loading and import-form paths below read. | CircularView |
assemblyNamesstring[] | CircularView | |
chordSyntenyDisplaysChordSyntenyDisplaySelf[] | Every ribbon display under this view's tracks; a chromosome reorder reads its alignments from these. Filtered by type rather than taken as tracks[i].displays[0], for the reason the dotplot's dotplotDisplays gives. | CircularView |
canDiagonalizeboolean | Whether a chromosome reorder has anything to do: a ribbon track to take alignments from, and exactly the two genomes a mirrored layout is defined for. One is a self-alignment, with no second arc to reorder; three or more have no layout in which every pair reads as a band. | CircularView |
launchAssemblyNamesstring[] | The assemblies a pending launch names, which the gates below wait on before displayedRegions exist. A blob carrying only tracks names none, and waiting on one nobody named never ends. | CircularView |
initializedboolean | CircularView | |
assemblyErrorsstring | undefined | CircularView | |
errorunknown | CircularView | |
hasSomethingToShowboolean | CircularView | |
showLoadingboolean | Whether to show a loading indicator instead of the import form or view | CircularView |
| loadingAssembly | The assembly whose load the spinner is waiting on. A pending launch names them before displayedRegions exist, so it is the source until then — the same order initialized above resolves in. | CircularView |
loadingViewLoading | undefined | What the loading screen says while showLoading, read off the assembly whose load is the wait; undefined otherwise. | CircularView |
showViewboolean | Whether the view is fully initialized and ready to display | CircularView |
showImportFormboolean | !hasSomethingToShow || !!error, the same predicate as every other view, with disableImportForm suppressing the whole thing rather than only its first half.The || used to bind the other way, so an error re-enabled a form the embedder had turned off. That is reachable, and the sv-inspector — disableImportForm's only setter — is where: its circle is driven by the spreadsheet's assembly, so a circle left sitting on regions whose assembly the config no longer has reports an error (the case the region-binding autorun's comment describes). The inspector then grew a circular-view import form inside its own panel, offering an assembly dropdown whose Open the inspector's autorun overwrites on the next pass — a control that cannot work, in a view that asked not to have it.The error still has to be reported, so the component renders a bare ErrorBanner in that case; the form is only the usual place a circular view puts one. | CircularView |
statusViewStatus | The view's lifecycle as one value — ready, error, loading or noRegions — for a host that draws its own chrome and has to render all four. Same shape and same precedence as the linear view's, through computeViewStatus. | CircularView |
| regionHost | The node a linear display's foundation reads as its view: the circumference unrolled into a strip. A display registered for the linear genome view draws on this view as a ring of that strip, so containingHost answers this rather than the view itself. | CircularView |
chordRadiusPxnumber | Where the chord displays start: inside the innermost ring, or at the ruler when the view holds none. | CircularView |
staticSlicesSlice[] | CircularView | |
legendSpecLegendSpec | one row per track: its name beside the color or ramp it paints with | CircularView |
rendersDisplaysboolean | Overridable hook (default true): whether this view's mounted body renders its own displays. A linear genome view collapsed to its ruler mounts the scalebar and none of its tracks, so a display in it can no more paint than one in a view scrolled off screen. Views nested in this one are unaffected: they paint wherever their own body is. | BaseViewModel |
effectiveBodyMountedboolean | Whether this view's displays have a canvas to paint into: its body is in the DOM, counting the views it is nested inside, and the body renders them (rendersDisplays). This is the question a display's phase asks.bodyMounted alone answers the DOM half only for a view a container renders directly. A view nested in another view (a synteny row, a breakpoint panel) has no container writing its flag, so it reads true forever while its whole subtree is out of the DOM, and every display in it waits for a first paint that nothing will make — the hang this flag exists to prevent, one level down.An ancestor that does not carry the flag at all leaves the answer alone rather than excusing the paint: only an explicit false unmounts, so a duck-typed stand-in that forgot it keeps waiting, which is the failure that shows up as a slow test rather than as a picture of an empty view. | BaseViewModel |
ownViewsAbstractViewModel[] | The views nested directly inside this one, which the census counts as views in their own right — a synteny stack's genome rows, a breakpoint split view's panels. Empty here for the same reason, and the dotplot is why it has to be a declaration rather than a walk of views: that prop name holds its two 1D axis models, which are view-shaped and are not views the user opened. No structural test separates the two — only the view knows. | BaseViewModel |
Methods
| Member | Description |
|---|---|
() => MenuItem[] | return the view menu items |
() => MenuItem | each track's own menu, which on a linear view hangs off its label and on the circle has nowhere else to go |
Actions
| Member | Description | Defined by |
|---|---|---|
fitToWindow() => void | size the figure so it exactly fills the smaller of the view's two dimensions | CircularView |
setWidth(newWidth: number) => number | CircularView | |
setHeight(newHeight: number) => number | CircularView | |
setShowLegend(flag: boolean) => void | CircularView | |
() => void | CircularView | |
() => void | CircularView | |
rotate(delta: number) => void | CircularView | |
resetView() => void | reset rotation, pan, and zoom back to the default fit-to-window view | CircularView |
() => void | CircularView | |
() => void | CircularView | |
setBpPerPx(newVal: number) => void | CircularView | |
zoomToPoint(newBpPerPx: number, cursorX: number, cursorY: number) => void | zoom toward/away from a point on the figure, keeping whatever is under it visually fixed. The point is its offset in screen px from the middle of the circle — what offsetFromCenter in the component hands back | CircularView |
setDisplayedRegions(regions: Region[]) => void | CircularView | |
activateTrackSelector() => Widget | undefined | CircularView | |
toggleTrack(trackId: string) => boolean | CircularView | |
setError(error: unknown) => void | CircularView | |
setLaunch(launch?: LaunchInput<CircularViewCommands> | undefined) => void | CircularView | |
| showTrack | CircularView | |
| addTrackConf | CircularView | |
hideTrack(trackId: string) => boolean | CircularView | |
openExportDialog() => void | CircularView | |
openReorderChromosomesDialog() => void | CircularView | |
autoDiagonalize() => Promise<void> | The init-time reorder, behind the "Reordering chromosomes" screen withDiagonalizeProgress drives. | CircularView |
exportSvg(opts?: ViewExportSvgOptions) => Promise<string> | renders the view to SVG markup, which it returns; saves it through FileSaver unless save: false | CircularView |
| launchTrack | showTrack for a track whose display state model may be lazily loaded: loads it, then shows | CircularView |
launchToggleTrack(trackId: string) => Promise<boolean> | toggleTrack with launchTrack's loading behavior | CircularView |
| launchTrackConf | addTrackConf with launchTrack's loading behavior, for a track handed over inline rather than from a session list | CircularView |
resizeHeight(distance: number) => number | CircularView | |
resizeWidth(distance: number) => number | CircularView | |
setDisplayName(name: string) => void | BaseViewModel | |
setBodyMounted(flag: boolean) => void | See bodyMounted. Written by the view's container, which is the only thing that knows whether it rendered the body. | BaseViewModel |
setMinimized(flag: boolean) => void | BaseViewModel | |
setAwaitingAutoDiagonalize(arg: boolean) => void | DiagonalizeProgressMixin | |
beginAutoDiagonalize(requested: boolean) => void | Declare the gate at the top of one init apply pass: a reorder is pending iff THIS init asked for one. Assigning rather than raising is what hands the gate over cleanly — a superseded init that asked for a reorder and then skipped it would otherwise leave the flag up with nothing coming, wedging settled forever. | DiagonalizeProgressMixin |
finishAutoDiagonalize() => void | A reorder resolved, the init's or a manual one, so the view on screen is the diagonalized one — open the gate. | DiagonalizeProgressMixin |
setDiagonalizeError(error: unknown) => void | DiagonalizeProgressMixin | |
setDiagonalizeCancel(arg?: (() => void) | undefined) => void | DiagonalizeProgressMixin | |
cancelAutoDiagonalize() => void | Abort an in-flight auto-diagonalize; withDiagonalizeProgress's finally clears the wait flag, revealing the (undiagonalized) view.Lowers the gate too. The abort reaches the caller as a throw, which skips its finishAutoDiagonalize() — right for a reorder that failed on its own (settled stays false and a capture times out loudly rather than committing a hairball), wrong for one the user stopped: cancelling IS the user settling for this view, and a gate nothing will lower again leaves settled false forever. | DiagonalizeProgressMixin |
setImportFormSyntenyTrack(idx: number, val: ImportFormSyntenyTrack) => void | ImportFormSyntenyMixin | |
clearImportFormSyntenyTracks() => void | Drop the pending selections once a launch has applied them. Left in place they outlive the form: "Return to import form" would reopen on a finished upload from the previous launch, and a pair whose assemblies no longer match it reads as an unfinished upload and disables Launch. | ImportFormSyntenyMixin |
Related links
- Guide: URL query parameter API