DotplotView
Auto-generated from the @jbrowse/mobx-state-tree model in the source — see the developer guide for concepts. Provided by the dotplot-view plugin. View source.
Example usage
Hand-authored under defaultSession.views, with every setting written
directly on the view object. views lists the two assemblies on the axes and
tracks the synteny track(s) to plot (self-vs-self is allowed):
{
type: 'DotplotView',
views: [{ assembly: 'hg38' }, { assembly: 'mm10' }],
tracks: ['hg38_vs_mm10.paf'],
color: { field: 'query' },
}autoDiagonalize and a per-axis loc on each views entry are the other
launch keys; everything else is a property below.
Plots the alignments between two assemblies, one on each axis, as a dot plot.
Each section ends with the members a composed model contributes, linked to the page that documents them.
Properties
| Member | Description |
|---|---|
idid: ElementId | |
typetype: types.literal('DotplotView') | |
heightheight: types.stripDefault(types.number, defaultHeight) | the height of the plot in pixels |
| trackSelectorType | vestigial: the hierarchical selector is the only one that exists, so this value is ignored. Retained because saved sessions and share links persist it. |
assemblyNamesassemblyNames: types.stripDefault(types.array(types.string), []) | the two assemblies being compared, horizontal axis first. A spec normally names these per axis instead, as views[0].assembly and views[1].assembly. |
drawCigardrawCigar: types.stripDefault(types.boolean, true) | resolve each alignment's CIGAR into the drawn shape rather than plotting it as a single straight segment |
showGridlinesshowGridlines: types.stripDefault(types.boolean, true) | carry each axis' ruler ticks across the plot as faint lines, the way LinearGenomeView's gridlines carry its own down over the tracks |
showTickLabelsshowTickLabels: types.stripDefault(types.boolean, true) | number each axis' major ticks; off keeps the tick marks and the chromosome names |
lockAspectRatiolockAspectRatio: types.stripDefault(types.boolean, false) | When true, hview and vview are kept at the same bpPerPx so the dotplot stays square. Wheel zoom already preserves the ratio; box-zoom and other independent ops trigger an autorun resync. |
lineWidthlineWidth: types.stripDefault(types.number, DEFAULT_LINE_WIDTH) | Line width in CSS pixels of every alignment in the plot |
| minIdentity | Hide alignments whose sequence identity is below this fraction (0-1), enforced per feature in buildLineSegments beside minAlignmentLength. A feature carrying no identity at all is kept at every threshold — the alternative blanks a plot whose adapter simply never reported one. |
hviewhview: types.optional(DotplotHView, {}) | the horizontal axis, as a full 1D view state. A spec writes views[0] instead, which the launcher resolves into this. |
vviewvview: types.optional(DotplotVView, {}) | the vertical axis, the counterpart to hview. A spec writes views[1]. |
trackstracks: types.array(pm.pluggableMstType('track', 'stateModel')) | |
| launch | transient launch state: the settings written on the view object that need resolving before they can be view state — the two axis assemblies, track recipes, highlights. 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. |
8 inherited properties from 4 models
From BaseViewModel: displayName, minimized
From SyntenyViewMixin: lodMode
Volatiles
| Member | Description |
|---|---|
volatileWidthnumber | undefined | |
volatileErrorunknown | |
cursorModestring | these are 'personal preferences', stored in volatile and loaded/written to localStorage |
17 inherited volatiles from 6 models
From BaseViewModel: width, bodyMounted
From RenderLifecycleMixin: canvasDrawn, paintCount, currentRenderingBackend, renderTick, autorunsInstalled, renderError, offScreen
From DiagonalizeProgressMixin: awaitingAutoDiagonalize, pendingAutoDiagonalize, diagonalizeStatus, diagonalizeCancel, diagonalizeError
From ImportFormSyntenyMixin: importFormSyntenyTrackSelections
Getters
| Member | Description |
|---|---|
ownTracksany[] | The census entry for this view: the tracks it holds itself. Declared rather than derived — see BaseViewModel.ownTracks. |
widthnumber | |
borderXnumber | Left margin: fits the vertical (vview) axis labels. Derived purely from that axis's regions + zoom — never from viewWidth — so it can't feed back through viewWidth = width - borderX into a render loop. |
borderYnumber | Bottom margin: fits the horizontal (hview) axis labels. See borderX. |
| pendingLaunch | the launch state that still has something to apply — the gate every loading and import-form path below reads. |
assemblyErrorsstring | undefined | |
highlightsHighlightType[] | the session's highlights on either axis' assembly |
assembliesInitializedboolean | |
axisAssemblyErrorError | undefined | A dotplot plots one assembly against another, so anything but two names here cannot lay out. initializeDisplayedRegions walks the two axes in step with this array, so one name leaves the other axis with no regions and initialized never comes true — the view sat on its spinner saying "Loading" forever, with the assembly it was supposedly waiting for already loaded. Extra names fail the other way: nothing reads past the second, so a third assembly is not plotted and nothing says so.Only reachable from a hand-authored snapshot — setAssemblyNames writes both, and applyInit already rejects an init naming one — and that snapshot is the case this error reports. Zero names is not an error: it is the import form. |
errorunknown | The view's terminal state: whatever the import form's submit threw, else a pair of axes that cannot lay out, else whatever the assemblies did. Declared here rather than beside menuItems so every reader below is the same expression — showImportForm and showLoading each used to re-spell it, and showLoading spelled it as a two-term && that a third source of error would have to be added to in three places. |
initializedboolean | |
hasSomethingToShowboolean | |
initPendingboolean | An init blob that has not been applied yet — installInitAutorun clears it as the last thing an apply pass does. The plot is assembling itself: the axes can already exist, and be initialized, while the tracks or the region restriction are still to come, which is why the settled gate reads this.Read by settled, deliberately not by showLoading — a plot whose axes are up is worth showing while the rest lands. LGV's equivalent is awaitingInitNavigation, a narrower thing (init set and nothing on screen at all) that it does fold into showLoading; it used to share this name, and the two disagree exactly where a reader would assume they agree. |
showImportFormboolean | Whether to show the import form |
showLoadingboolean | Whether to show a loading indicator instead of the import form or view |
| loadingAssembly | The assembly whose load the spinner is waiting on. init names them before assemblyNames is materialized, so it is the source until then. |
loadingViewLoading | undefined | What the loading screen says while showLoading, read off the assembly whose load is the wait; undefined otherwise. |
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. |
viewWidthnumber | Plot area width. Floored at 0: the axis borders have their own MIN_BORDER floor, so a container narrower than that would otherwise yield a negative canvas dimension and a negative maxBpPerPx. |
viewHeightnumber | Plot area height. Floored at 0, see viewWidth. |
gridlinesEmptyboolean | The setting is on and neither axis has a ruler to cast — a ticked checkbox doing nothing observable, which the menu says out loud rather than looking broken. The whole-genome view is this. |
hasVisibleRegionsboolean | Both axes have a region on screen, so the plot has a grid to draw and a first block to anchor its backdrop rect on. The grid reads the two block lists' heads, which only this makes safe. |
| views | |
number | The zoom-out limit both axes share under lockAspectRatio: one bpPerPx has to fit the LONGER genome, so it is the larger of the two axes' own fits. Read back by each axis as its maxBpPerPx (see axisMaxBpPerPx), so every route to a zoom — the buttons, the wheel, box-zoom, showAllRegions — clamps against the same ceiling. |
dotplotDisplaysDotplotDisplayModel[] | Every DotplotDisplay under this view's tracks. Filtered by type rather than taken as tracks[i].displays[0]: showTrack only ever builds one view-compatible display, but a hand-written or legacy session snapshot is hydrated verbatim, and an empty or foreign displays array put an undefined into this list that every consumer below dereferences — settled and geometryByDisplayKey both crash the view on it. Same spelling as the synteny level's linearSyntenyDisplays.Not index-aligned with tracks, so a consumer that wants a display's track reads display.parentTrack rather than tracks[i]. |
trackWarningsTrackWarning[] | Every loaded track's render warnings, under the name to report them by. Shared with the synteny view's own report (see collectTrackWarnings for why the name has to come off the display's parentTrack), and a cached computed rather than a render-time flatMap: the header that reads it re-renders on every pointermove of a selection drag, and resolving a name is a getConf per track. |
surfaceReadinessComparativeSurface | The plot rect as the displays drawing onto it see it: first paint, plus the two flags that mean what is on screen is not the answer yet. Published here so a display reads one field, and so settled below and every display's displayPhase are computed from the same three values. |
displayPhaseDisplayStatusPhase | What the shared canvas publishes as data-display-phase: the ranking over the plots drawing onto it. Its twin settled below is the stricter question — see comparativeReadiness. |
settledboolean | Canvas has painted and no display is still fetching, so what's on screen is the final settled content. Drives the data-display-drawn on dotplot_webgl_canvas that screenshot capture and the browser-test suites wait on — so it must mean "done", not just "first paint".Not the same question as "is every display finished" — see comparativeReadiness, which holds both and says why an error answers them differently. |
hoveredDisplayDotplotDisplayModel | undefined | The one track that owns the plot's hover, or undefined. At most one can: setHoveredFeature points a single display at the hit and clears every other in the same batch.Resolved here so the two readers below — and the components — take the view they already have rather than looping the tracks themselves. |
hoveredTooltipLinesstring[] | undefined | The hovered alignment's tooltip lines, or undefined when nothing is hovered. |
hoveredHighlightDotplotHoverHighlight | undefined | The hovered alignment's restroke geometry — see DotplotDisplay.hoveredFeatureHighlight. |
geometryByDisplayKeyMap<number, DotplotGeometryData> | Per-display GPU geometry keyed by displayKey. The upload autorun diffs this map: new entries upload, vanished entries evict. Drawn in insertion order, so tracks paint bottom-of-the-list last. |
| plotTransform | The cumBp -> plot px reconstruction, as the numbers everything that draws or hit-tests this plot runs on: the viewport-start cumBp per axis, the inverse bpPerPx per axis, and the plot height the v axis is flipped through (it lays out bottom-up). Its own getter because three readers want exactly these and nothing else — the render state below, the pick's exact test, and DotplotDisplay.hoveredFeatureHighlight. Taking them off dotplotRenderState also subscribes to alpha, lineWidth and the display-key list, so an opacity drag rebuilt the hover path.viewHeight belongs in here and not beside it: this is also what setupClearHoverOnPlotMove watches to decide the plot has moved under a stationary cursor, and a height change slides every alignment down the canvas exactly as a pan does. Left out, it was the one way to move the plot that kept the hover pinned to the alignment it no longer pointed at. |
dotplotBlocksRenderBlock[] | One canvas-wide block per loaded display, in the map's insertion order, so tracks paint bottom-of-the-list last. An empty list is a real frame, not a skip: the backend clears before drawing, so painting zero displays is what wipes the plot when the last track is hidden. |
dotplotRenderStateDotplotRenderState | Aggregated per-frame render state — a resolved value, never undefined; "the view isn't measured yet" is the canRender precondition below. |
canRenderboolean | Render-lifecycle precondition (overrides RenderLifecycleMixin's default-true hook): before the axes have regions and a measured width there is nothing to paint against. Gating the autorun pair here lets dotplotRenderState stay a resolved getter. |
paintInertboolean | Overrides RenderLifecycleMixin's hook: a measured plot with no tracks on it paints nothing this tick and nothing is coming, so it has finished rather than being pending. The backend answers "did content reach the canvas" off the blocks it drew, which is the right answer for a track still fetching and the wrong one for a canvas with nothing to draw on it.initialized is the other half and is not redundant with canRender: an import form has no tracks either, and it is not finished — AppReadyMarkerComparative pins that its settled stays false, and the marker asks its displays rather than this. |
27 inherited getters from 5 models
From BaseViewModel: rendersDisplays, effectiveBodyMounted, ownViews
From RenderLifecycleMixin: rendersCanvas, paintSuperseded, painted
From SyntenyViewMixin: hasLodCapableAdapter, showLegend, legendSpec
From SyntenyColorsMixin: defaultOpacity, opacitySetting, opacityFade, opacityLevel, opacityField
From TrackColorsMixin: colorSetting, colorPaint, colorValue, colorDomain, colorRange, colorableAttributes, attributeRanges, colorableTracks, trackColorAssignments, colorField, hasLegendKey, colorLegendChips, colorScales
Methods
| Member | Description |
|---|---|
syntenyTracks() => ComparativeTrackModel[] | Annotated for the reason ComparativeTrackModel documents: the array is any. |
loadedAttributeRanges() => Record<string, AttributeRange>[] | Each loaded display's observed attribute spans, which the mixin unions into the domain the legend labels its ramp with. |
colorSurface() => "points" | Flat points, never a CIGAR op. |
svgLegendWidth() => number | The export parks the key beside the plot rather than over it: a diagonalized plot's alignments run into the top-right corner the key would otherwise cover. |
| getCoords | Both corners of a drag rect, in bp on each axis. Undefined for a drag too small to be a selection — the same threshold the interaction hook uses to tell a drag from a click. |
pickFeatureAt(x: number, y: number) => DotplotPlotPickHit | undefined | The alignment under a pointer position (plot px, y downward), across every track on the shared canvas, or undefined. Resolved on the model rather than through the rendering backend, which is where this departs from synteny's backend.pick(...): dotplot geometry is already here in absolute cumBp (display.instanceData), so this answers with NO backend attached at all — before the first paint, through a context loss that has not recovered, and in a test with no canvas. (Both of synteny's backends implement pick, so its hover is not GPU-only either despite gpuRenderingBackend's name; what it cannot do is answer while nothing is attached. It lives in the backend because the projected geometry it indexes does, which also means each backend builds its own index.)Nearest wins ACROSS tracks too, ties going to the later track (the one drawn on top) — see pickDotplotFeature for why a dotplot answers nearest where a ribbon answers topmost. |
| getHHighlightCoords | Map a highlight region to {left, width} px on the horizontal axis. left is already screen-offset. Returns undefined when the region isn't on hview's assembly/displayed regions. |
| getVHighlightCoords | Map a highlight region to {top, height} px on the vertical axis. Returns undefined when the region isn't on vview's assembly/displayed regions. |
7 inherited methods from 2 models
From SyntenyColorsMixin: colorableTrackConfigs, colorableAttributeNames, legendAlpha
From TrackColorsMixin: legendCigarOps, offersReferenceColor, shapeShowsStrand, trackColorFor
Actions
| Member | Description |
|---|---|
startRenderingBackend(backend: DotplotRenderingBackend) => void | |
setHoveredFeature(hit: DotplotPlotPickHit | undefined) => void | Point the whole plot's hover state at one pick hit: the track whose geometry was hit takes the segment index, every other track clears, so undefined (a miss) clears the plot. An action rather than a loop in the pointer handler so the N writes land in one MobX batch — and so nothing outside the model has to resolve a displayKey to a display. Same shape as the synteny level's setHoveredFeature. |
setCursorMode(mode: CursorMode) => void | |
setDrawCigar(flag: boolean) => void | |
setShowGridlines(flag: boolean) => void | |
setShowTickLabels(flag: boolean) => void | |
setLockAspectRatio(flag: boolean) => void | |
setLineWidth(value: number) => void | |
setMinIdentity(value: number) => void | |
clearView() => void | returns to the import form |
setWidth(newWidth: number) => number | |
setHeight(newHeight: number) => number | |
setError(e: unknown) => void | |
setLaunch(launch?: LaunchInput<DotplotViewCommands> | undefined) => void | |
zoomOut() => void | |
zoomIn() => void | |
scrollXY(dx: number, dy: number) => void | Pan both axes one gesture step. Each delta is in its own axis' scroll direction, not screen px — the vertical axis lays out bottom-up, and both callers (wheel, drag) already hold the flipped value for their own reasons. One action rather than two scroll calls, because an MST action is a MobX action: unbatched, the render autorun ran twice per pointermove and drew a whole frame against a moved h axis and a stale v one. |
zoomAt(factor: number, [x, y]: Coord) => void | Zoom both axes by factor, holding the locus under a plot-area point still. The anchor is the same component-px Coord the drag handlers pass around, so each axis takes it through its own fromScreenPx, as getCoords does.Multiplying both axes by one factor keeps wheel zoom ratio-preserving, so the aspect lock never has to correct it. One action, for the reason scrollXY documents. |
activateTrackSelector() => Widget | |
| showTrack | initialSnapshot is annotated rather than inferred from its default. A bare {} accepts a number, so this signature satisfied applySyntenyTrackSelections' (trackId, level) => void callback — passing model.showTrack there typechecked and handed the pair index over as the new track's snapshot. |
hideTrack(trackId: string) => boolean | |
toggleTrack(trackId: string) => boolean | |
setAssemblyNames(x: string, y: string) => void | |
zoomInToMouseCoords(mousedown: Coord, mouseup: Coord) => void | zooms into clicked and dragged region. Under lockAspectRatio both axes take the larger of the two fits, so the whole box stays in view on the axis whose plot dimension is shorter. |
addHighlightFromMouseCoords(mousedown: Coord, mouseup: Coord) => void | highlights the clicked and dragged region: the x-span becomes a band on the horizontal axis and the y-span a band on the vertical axis, so the drag rect is their intersection |
showAllRegions() => void | |
initializeDisplayedRegions() => void | |
openInCircularSyntenyView() => void | a circular view of the two axes' genomes with this view's tracks as ribbons, the second genome reordered to follow the first, and this view's color and length filter |
launchLinearSyntenyView(mousedown: Coord, mouseup: Coord) => void | opens a linear synteny view on the clicked and dragged region: the horizontal axis' span on the top row, the vertical axis' below, each fitted to this view's width, with every track that has a linear synteny display, painted and filtered by the settings the two views share |
| launchTrack | showTrack for a track whose display state model may be lazily loaded: loads it, then shows |
launchToggleTrack(trackId: string) => Promise<boolean> | toggleTrack with launchTrack's loading behavior |
exportSvg(opts?: ViewExportSvgOptions) => Promise<string> | renders the view to SVG markup, which it returns; saves it through FileSaver unless save: false |
applySquare(ratio: number) => void | Set both axes to the average bpPerPx (hview divided by ratio), re-anchoring each on the locus that was at its center. setBpPerPx alone would leave offsetPx untouched while bpPerPx changed under it, scrolling the plot; the centerAt calls are what hold it still. |
squareView() => void | Equalize both axes' bpPerPx. Also what the aspect-ratio lock applies to absorb divergence from box-zoom and other per-axis operations — deliberately not clamped to either axis's own maxBpPerPx, since a shared bpPerPx that fits the larger genome necessarily exceeds the smaller axis's limit, and it converges in one step where a clamped one would ping-pong between the two maxima. |
squareViewProportional() => void |
31 inherited actions from 7 models
From BaseViewModel: setDisplayName, setBodyMounted, setMinimized
From RenderLifecycleMixin: markCanvasDrawn, resetCanvasDrawn, stopRenderingBackend, renderNow, setOffScreen, setRenderError, attachRenderingBackend
From DiagonalizeProgressMixin: setAwaitingAutoDiagonalize, beginAutoDiagonalize, finishAutoDiagonalize, setDiagonalizeError, setDiagonalizeCancel, cancelAutoDiagonalize
From ImportFormSyntenyMixin: setImportFormSyntenyTrack, clearImportFormSyntenyTracks
From SyntenyViewMixin: setLodMode, setShowLegend, dismissLegendSection
From SyntenyColorsMixin: setOpacity, setOpacityField, setMinAlignmentLength
From TrackColorsMixin: observeAttributeRanges, resetAttributeRanges, setHideUnlabelled, setColorField, setColorDomain, setTrackColor, clearTrackColors
Related links
- Docs: URL query parameter API