LinearSyntenyView
Auto-generated @jbrowse/mobx-state-tree API for the current JBrowse release —
see pluggable elements for concepts. Provided by the
linear-comparative-view plugin.
View source.
Example usage
Hand-authored under defaultSession.views. init.views declares the two member
assemblies (stacked as linear views) and tracks the synteny feature track
connecting them with a ribbon:
{
type: 'LinearSyntenyView',
init: {
views: [{ assembly: 'hg38' }, { assembly: 'mm10' }],
tracks: ['hg38_vs_mm10.paf'],
drawCurves: true,
},
}
init also takes the launch commands (levelHeights, autoDiagonalize,
sameScale, collapseEmptyRows) and ANY property below — colorBy, alpha,
minAlignmentLength, drawLocationMarkers, … . There is no list to join:
applyInitSettings matches an init key against this model's own properties, and
LinearSyntenyViewInit is derived from its snapshot type.
Members a composed model contributes are listed here too, so these tables are the whole surface.
Properties
| Member | Description | Defined by |
|---|---|---|
typetype: types.literal('LinearSyntenyView') | LinearSyntenyView | |
| cigarMode | How per-base insertions and deletions inside each alignment are shown: 'full' paints indel wedges, 'matches' leaves them see-through, 'off' draws blocks only. | LinearSyntenyView |
drawCurvesdrawCurves: types.stripDefault(types.boolean, false) | Render ribbons as bezier curves rather than straight chords. Reads much better at whole-genome scale, where straight crossings stack into noise. | LinearSyntenyView |
drawLocationMarkersdrawLocationMarkers: types.stripDefault(types.boolean, false) | Continue the query view's scalebar grid down through the ribbons: a tick at each round query coordinate, joined to the coordinate the alignment pairs it with. | LinearSyntenyView |
showOffscreenMatesshowOffscreenMates: types.stripDefault(types.boolean, true) | Mark, on the query axis, the alignments whose mate is on a contig the facing row is not displaying — real synteny a ribbon has nowhere to land, which the view otherwise draws nothing for. | LinearSyntenyView |
bidirectionalFetchbidirectionalFetch: types.stripDefault(types.boolean, false) | Ask each level's adapter for the alignments anchored on its LOWER row as well as its upper one. A synteny band queries its query axis — the upper row of the pair — so an alignment anchored on a lower-row contig whose other end is somewhere the upper row is not showing is never requested, and nothing downstream can recover it. Which genome a user stacked on top therefore decided what the view was able to report. A FETCH INPUT, unlike showOffscreenMates above, and off by default because it is a second query per level. | LinearSyntenyView |
| overdrawPx | pixels beyond the visible viewport edge that synteny lines are still drawn. Effective up to the pan buffer (syntenyPanBufferPx: 2000px, or half the viewport when that is wider) — the worker emits CIGAR detail and location markers only that far, so a larger value draws ribbons whose detail stops partway along them. | LinearSyntenyView |
alphaalpha: types.stripDefault(types.number, DEFAULT_ALPHA) | Per-feature opacity in [0,1]. The default is tuned for dense unfiltered hairballs; a whole-genome view with minAlignmentLength set can use a higher value (~0.4) for stronger color. | LinearSyntenyView |
| minAlignmentLength | Hide alignment blocks shorter than this many bp. Enforced per-feature by its own span in buildSyntenyGeometry, then culled in the shader (isCulled) and pick engine. Cuts whole-genome hairball noise. | LinearSyntenyView |
| lodMode | Level-of-detail tier selection for PIF adapters. 'auto' uses the adapter's bpPerPx threshold; 'fine' forces the per-row CIGAR tier (t/q); 'coarse' forces the no-CIGAR tier (T/Q) when present. | LinearSyntenyView |
opacityByIdentityopacityByIdentity: types.stripDefault(types.boolean, false) | Fade alignment blocks by per-feature identity (lower identity = more transparent). Orthogonal to colorBy — surfaces identity-dropoff zones without consuming the color channel. | LinearSyntenyView |
| fadeThinAlignmentsMode | Whether to fade a sub-pixel-thin ribbon's opacity by its on-screen width (see WIDTH_FADE_FLOOR in syntenyTypes.slang), so an unfiltered whole-genome view doesn't read as a hard full-opacity hairball. 'auto' enables the fade once a display is dominated by sub-pixel ribbons (see autoFadeWidthPx); a genuinely sparse comparison (only a handful of ribbons) keeps full alpha so the fade doesn't wash it out. 'on'/'off' pin it. Resolved view-wide by the fadeThinAlignments getter, so all levels fade together. | LinearSyntenyView |
initinit: types.frozen<LinearSyntenyViewCommands | undefined>() | used for initializing the view from a session snapshot. tracks is 2D — outer index is the level (the gap between views[i] and views[i+1]), so a 3-way view has two entries. example: json { views: [ { loc: "chr1:1-100", assembly: "hg38", tracks: ["genes"] }, { loc: "chr1:1-100", assembly: "mm39" }, { loc: "chr1:1-100", assembly: "rn7" } ], tracks: [["hg38_vs_mm39_synteny"], ["mm39_vs_rn7_synteny"]] } | LinearSyntenyView |
idid: ElementId | LinearComparativeView | |
| trackSelectorType | vestigial: the hierarchical selector is the only one that exists, so this value is ignored. Retained because saved sessions and configs persist it. | LinearComparativeView |
linkViewslinkViews: types.stripDefault(types.boolean, false) | sync scroll and zoom across the genome rows, so panning one pans them all | LinearComparativeView |
followSyntenyfollowSynteny: types.stripDefault(types.boolean, false) | Move the non-anchor genome rows to whatever region aligns to the anchor row, re-resolved through the synteny data each time the anchor settles. The synteny-aware alternative to linkViews, which locks the rows in PIXELS and so drifts apart as soon as an indel accumulates — the two are mutually exclusive (see setRowSyncMode). | LinearComparativeView |
sameScalesameScale: types.stripDefault(types.boolean, false) | Hold every genome row on one bp/px — the coarsest row's fit — so the rows compare by drawn length instead of all filling their pane. A mode rather than a one-shot zoom because it is the rows' zoom-out LIMIT it moves (sharedFit), and a limit has to still be there on the next wheel tick. | LinearComparativeView |
followAnchorIndexfollowAnchorIndex: types.stripDefault(types.number, 0) | Which genome row drives the others while followSynteny is on. Every other row is placed by mapping this one's window outward one level at a time. Clamped to the views array by reconcileLevels. | LinearComparativeView |
followMatchOrientationfollowMatchOrientation: types.stripDefault(types.boolean, false) | While following, flip a row whose placing alignment runs the other way from the anchor's, so the two pan in the same direction. Off by default: the crossing ribbons are the picture of an inversion, and a row turning round under the reader is the loudest thing one can do. | LinearComparativeView |
levelslevels: types.array(LinearSyntenyLevel) | One synteny band per adjacent pair of views. Each holds its own track list, which is why the track-selector and add-track widgets address them through trackContainerFor — a level is not a view and cannot be the target of their view reference. | LinearComparativeView |
| views | N genome rows, with N-1 synteny levels between adjacent pairs. The views/levels invariant is maintained by reconcileLevels(). | LinearComparativeView |
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 |
colorBycolorBy: types.stripDefault(types.string, 'default') | The color-by mode the whole view renders with, unless a track overrides it in trackColorBy. | TrackColorsMixin |
trackColorBytrackColorBy: types.map(types.string) | trackId -> color-by mode for that track alone. Absent means the track follows the view-wide colorBy. | TrackColorsMixin |
trackColorstrackColors: types.map(types.string) | trackId -> explicit color under colorBy: 'track'. Absent means the track takes an automatic slot from the palette. | TrackColorsMixin |
showColorLegendshowColorLegend: types.stripDefault(types.boolean, false) | Show the floating color-by legend. Dismissible via the legend's close button; re-enable from the color-by (palette) menu. | TrackColorsMixin |
Volatiles
| Member | Description | Defined by |
|---|---|---|
| importFormSyntenyTrackSelections | LinearSyntenyView | |
fadeThinLatchfadeThinLatch: false | Whether the 'auto' thin-fade is latched on. State rather than a derived value because the decision has hysteresis, and hysteresis is a memory — see fadeThinAlignments. | LinearSyntenyView |
widthwidth: undefined as number | undefined | LinearComparativeView | |
volatileErrorvolatileError: undefined as unknown | View-level failure (e.g. an init block that couldn't be applied). Volatile on purpose: a reload re-runs the init autorun from a clean slate, so a transient failure stays recoverable. | LinearComparativeView |
followUnalignedfollowUnaligned: false | The follow found no alignment over the anchor row's window on its last pass, so the other rows are holding position. What the header's follow button reports; without it the rows simply stop tracking, which is the same picture as a broken follow. Volatile because it describes the current window, not the session. | LinearComparativeView |
followApproximatefollowApproximate: false | The follow placed a row by mapping the anchor window proportionally rather than by walking a CIGAR, so its position is close but not base-exact — a window wider than one alignment, or a tier carrying no CIGAR. What the header's follow tooltip reports; nothing else in the view distinguishes the two. | LinearComparativeView |
followPartialfollowPartial: undefined as FollowPartialReport | undefined | The follow had a multi-contig answer and refused it: placing a row on two regions that are not neighbours in its layout puts every contig between them on screen too, and past a point that is nearly all of what the reader is looking at. The rows are on one of the anchor's regions instead, and this names it and the ones whose answers are therefore off screen — enough for the header to say which region to scroll onto to see those instead. Read only by the header's follow tooltip. | LinearComparativeView |
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 |
diagonalizeStopTokendiagonalizeStopToken: undefined as StopToken | undefined | Stop token for the in-flight auto-diagonalize, so the spinner's Cancel can abort it; undefined when none is running. | DiagonalizeProgressMixin |
seenAttributeRangesseenAttributeRanges: {} as Record<string, AttributeRange> | The widest span each numeric channel has been seen to cover, over every fetch this view has taken — what keeps an attribute:<column> ramp from re-scaling under a pan. Widened by observeAttributeRanges, dropped by resetAttributeRanges, read through attributeRanges, which is where the reasoning is. | TrackColorsMixin |
Getters
| Member | Description | Defined by |
|---|---|---|
hasSomethingToShowboolean | LinearSyntenyView | |
initPendingboolean | An init blob that has not been applied yet — installInitAutorun clears it as the last thing an apply pass does. The view is assembling itself: the rows can already exist, and be initialized, while the synteny tracks are still several awaits away, which is why the levels' settled gate reads this.Same predicate as dotplot's, and read the same way — by settled, not by showLoading. LGV's awaitingInitNavigation is the narrower "init set and nothing on screen at all", which it does fold into showLoading; it used to share this name. | LinearSyntenyView |
showAssemblyNameInSubviewScalebarboolean | Opt each sub-view's scalebar into prefixing its refName labels with the assembly name (e.g. "hg38:chr1"), so stacked genome rows of different assemblies stay distinguishable. Read duck-typed by the child LinearGenomeView (scalebarDisplayPrefix) to avoid an upward plugin dependency. | LinearSyntenyView |
drawCIGARboolean | LinearSyntenyView | |
drawCIGARMatchesOnlyboolean | LinearSyntenyView | |
hasLodCapableAdapterboolean | True if any track on any level has an adapter with tiered storage. Used to gate the "Level of detail" row — PAFAdapter, BlastTabularAdapter and friends have nothing to switch between. | LinearSyntenyView |
hasCigarDataboolean | True if any synteny display could show CIGAR detail — used to gate the CIGAR settings row, which a CIGAR-less PAF has nothing to put in. Optimistic while no display has finished a fetch yet, so the row is there from the first render rather than popping in once data lands (the common case: most synteny files carry CIGARs). A view with no synteny tracks at all has nothing to gate, so it reports false. | LinearSyntenyView |
offscreenMateMode"both" | "off" | "query" | Which of the three steps the two properties are in. both implies marking, so a hand-written snapshot that fetches the lower row without drawing it reads as the mode it behaves like — the fetch is happening, and the marks are the half of it that shows. | LinearSyntenyView |
offscreenMateTally{ refName: string; count: number; }[] | The contigs this view has alignments to and cannot draw, largest first. A locus can be syntenic to a contig you did not stack, and a view showing no ribbon for it looks exactly like one where it is syntenic to nothing; the marks along the axis are what says so, and a mark's tooltip is where this contig's own number appears. Summed across levels rather than reported per level, because the answer a reader wants is about the view: a contig missing from two levels is one contig to go add. The case for the whole feature, with the numbers, is agent-docs/ideas/offscreen-synteny-mates.md. | LinearSyntenyView |
presentCigarKindsnumber | Union across every loaded synteny display of which CIGAR indel ops are actually drawn on screen. The floating legend lists an indel chip only when a visible-width op of that kind is painted somewhere in the view. | LinearSyntenyView |
fadeThinAlignmentsboolean | Resolved fade-thin flag that every display's renderParams reads. In 'auto' mode the fade turns on once ANY loaded synteny display is dominated by sub-pixel ribbons (a thin hairball that benefits from decluttering); a sparse view keeps its few ribbons at full alpha. 'on'/'off' pin it. LATCHED, with a deadband ( fadesThinAt): a fade that is off engages at 1px and one that is on holds until the ribbons come back above 1.25px. The signal underneath is a mean over the features the current fetch window holds, and that window rolls over once per syntenyPanBufferPx of panning, stepping the mean with the slice it swapped; on a single threshold a view sitting near it flipped every ribbon in the stack between full alpha and WIDTH_FADE_FLOOR while the reader was merely scrolling. installAutoFadeLatch moves the latch, and an un-moved latch reads as the plain un-hysteretic answer, so a first frame or an SVG export taken before it runs is not a different picture.Deliberately view-wide rather than per display: stacked levels are read as one picture, so levels resolving the fade independently would paint the same ribbon density differently from row to row. | LinearSyntenyView |
autoFadeWidthPxnumber | The width 'auto' compares against its thresholds: the narrowest capped mean block width any loaded display reports, or Infinity when none of them has enough blocks to judge by. Each display measures its own ribbons (cappedMeanAlignmentPx) and this takes the thinnest, so the densest level in a stack carries the view-wide decision.Skips a display holding fewer than FADE_AUTO_MIN_FEATURES blocks, and one still at 0 (no fetch landed yet), so neither can fade the view on its own. | LinearSyntenyView |
anchorAssemblyNamestring | undefined | The "anchor" assembly for colorBy:'reference': the assembly bordering the most synteny levels. In a stacked ref-vs-A / ref-vs-B layout each interior assembly touches two levels and the ends touch one, so the max-adjacency assembly is the shared reference. Ties resolve to the topmost. Every level then colors by this assembly's chromosome names, so a region keeps its color as it's traced across levels. | LinearSyntenyView |
colorableTrackConfigs() => { trackId: string; name: string; }[] | Every synteny track across every level, in order, paired with whatever color the user pinned on it. View-wide rather than per level: the floating legend is one box for the whole stack, so two levels handing out the same color would make that one legend lie. | LinearSyntenyView |
showLoadingboolean | Whether to show a loading indicator instead of the import form or view | LinearSyntenyView |
| loadingAssembly | The assembly whose load the spinner is waiting on. init names them before the rows are built, so it is the source until then. | LinearSyntenyView |
loadingMessagestring | undefined | Label for the generic loading spinner, naming the assembly file being downloaded when the assembly load is what the wait is. The auto-diagonalize wait is a separate render branch (DiagonalizeLoadingScreen), so this only covers the plain "view not ready" case. | LinearSyntenyView |
loadingProgressnumber | undefined | Determinate fraction for the spinner's bar, when the assembly load reports one | LinearSyntenyView |
loadingSourcestring | undefined | The URL the assembly load is currently fetching, when the phase named one. Only the stalled-load notice reads it — see ViewLoadingScreen. | LinearSyntenyView |
showImportFormboolean | Whether to show the import form. A failed init counts: init is kept so a reload can retry it, but in this session there is nothing to show and no second attempt coming, so the form (with the error banner) is the only way forward — matching LGV/dotplot/circular, which also fall back to the form on error rather than spinning. | LinearSyntenyView |
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.A host gating on initialized alone gets the trap this closes: it waits on every row, so a failure in either assembly leaves it false for good, and the empty box that follows says nothing about which of the two happened. | LinearSyntenyView |
scrollZoomboolean | scroll-to-zoom is a global, personal preference resolved from the session; toggling it in any view applies everywhere | LinearComparativeView |
initializedboolean | LinearComparativeView | |
errorunknown | LinearComparativeView | |
assemblyNamesstring[] | LinearComparativeView | |
SharedFit | The zoom-out limit every row shares while sameScale is on, and whether it can be answered at all. Each row PULLS this back through its own maxBpPerPx (sharedScaleContainerOf finds this view by the presence of this getter), so nothing here is copied onto the rows and nothing can go stale between a resize and the next layout. The dotplot's lockAspectRatio derives the same quantity the same way.The rule, and why the unanswered state is not a zero, are in sharedFit.ts. | LinearComparativeView |
allSyntenyDisplaysany[] | Every synteny display across every level, flattened. One memoized getter for the view-wide aggregates that would otherwise each re-flatten the levels. | LinearComparativeView |
followPairs{…}[] | Each synteny level resolved into the pair of rows a follow would move it between: which row stays, which row moves, which axis the anchor window is read off, and the assembly naming the level's lane of an all-vs-all track. Levels whose rows are not both initialized are dropped, since there is nothing to place yet. A getter rather than a loop in each caller because the follow reads it from TWO autoruns — the exact one and the per-frame one — which had each resolved the direction, looked the two rows up and repeated the initialized guard. Those are the same question, and the answer changes only when the rows or the anchor do. ORDERED OUTWARD FROM THE ANCHOR rather than by level index, which is what makes a stack of three or more settle in one pass: a level's staying row is either the anchor or a row some nearer level places, so visiting them nearest-first means every level reads an input the same pass has already written. In level order that only holds when the anchor is the top row. | LinearComparativeView |
syntenyWarningsComparativeWarning[] | Data-quality warnings raised by every synteny display, e.g. a reversed assembly row order. What the header's warning button counts. | LinearComparativeView |
trackWarningsTrackWarning[] | The same warnings grouped under the track that raised each, which is what the dialog reports. A stacked view's levels raise swappedAssembliesWarning verbatim, and so does every overlaid track that hits it, so the flat list above was N identical rows with nothing to tell the user which file to go fix. Shared with the dotplot's table so the two reports say the same thing. | LinearComparativeView |
trackContainersTrackContainer[] | The same track lists, for a reader with no id to ask with. This view has no tracks of its own, so anything walking a session for displays — AppReadyMarker, the capture harness's busy probe — sees an empty view and reports a still-fetching synteny stack as idle unless it asks here too. | LinearComparativeView |
effectiveBodyMountedboolean | Whether this view's body is in the DOM, counting the views it is nested inside — which is the question a display's phase actually asks.bodyMounted alone answers it 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 |
colorableAttributesstring[] | Distinct numeric columns across the overlaid tracks, in first-seen order — two tracks declaring dn offer one dn mode, not two. | TrackColorsMixin |
attributeRangesRecord<string, AttributeRange> | The span each numeric channel covers: unioned over the loaded displays, and over every fetch this view has already taken (seenAttributeRanges). An attribute:<column> mode has no declared domain, so this is what its ramp scales to, what the legend labels it with, and — since it is the one domain — what the two cannot disagree about.MONOTONIC, which is the point. A fetch's payload reports the span of the slice it holds, and that slice is the snapped window: painting straight off it re-maps every feature onto the ramp each time a pan rolls the window over, so a ribbon in the middle of the ramp turns into one at the bottom while the reader is scrolling and its value has not changed. A domain that only ever widens still says what the reader is looking at — the legend prints the actual numbers — and settles instead of oscillating. Monotonic UNTIL A MODE IS PICKED, which is the way back: one window holding an outlier would otherwise compress the ramp for the rest of the session, and the union above is over the LOADED spans, so resetAttributeRanges rescales to what is on screen there and then.View-wide rather than per display because the floating legend is one box for the whole view: two displays scaling the same ramp from different spans would make that one legend lie about one of them. | TrackColorsMixin |
colorableTracksColorableTrack[] | colorableTrackConfigs paired with whatever color the user pinned. This is the single definition of "the tracks that get colors" — the palette, the legend and the palette menu all read it, so they cannot disagree about which tracks are in play. | TrackColorsMixin |
trackColorAssignmentsMap<string, string> | trackId -> the color it draws in under colorBy: 'track'. Assigned across the whole view rather than per display, so an automatic slot can't duplicate a color pinned on a sibling. | TrackColorsMixin |
uniformColorBySyntenyColorBy | undefined | The mode to report as "the view's mode" — undefined when tracks disagree, so the menu shows nothing checked and the legend says so instead of picking one track's answer for everyone. | TrackColorsMixin |
colorLegendChipsColorChip[] | Legend rows naming the overlaid tracks — non-empty only when they are colored by track, or by different modes. | TrackColorsMixin |
Methods
| Member | Description | Defined by |
|---|---|---|
colorableAttributeNames() => string[] | The numeric columns the overlaid tracks declare, so the palette menu can offer one mode per measurement without any of them being a named mode. attributeColumns is the ortholog-table adapter's slot; a track whose adapter has no such slot contributes nothing. | LinearSyntenyView |
loadedAttributeRanges() => Record<string, AttributeRange>[] | Each loaded display's observed attribute spans, which the mixin unions into the domain the legend labels its ramp with. | LinearSyntenyView |
() => MenuItem[] | The header hamburger, which is NOT a subset of menuItems() — the two share only Export SVG. This one is the synteny surface; the app menubar's is the generic view one.SIX ROWS WHATEVER THE STACK HOLDS — seven on screen, where ViewOptionsMenuButton appends the "Show..." row carrying the search box prefs, whose state is React's rather than the model's. The menu answers what the view IS — where the rows point, which genomes it stacks, what leaves it — and nothing about how the ribbons are drawn: every render setting is in the header's settings menu, and SyntenySettingsMenu states that division from the other side.A group in THIS menu names a CHOICE ("Link views") or what varies with row count ("Rows"), never a topic: the "Navigation" group that used to hold the zoom commands was named after what the whole menu is about, and charged a popup for it. LGV's menu had one too, and it went the same way. | LinearSyntenyView |
() => MenuItem[] | LinearSyntenyView | |
isViewCompact(idx: number) => boolean | LinearComparativeView | |
trackContainerFor(id: string) => TrackContainer | undefined | The level that owns a given track list. This view holds one track list per synteny band rather than one of its own, so the track-selector and add-track widgets target a level through here instead of referencing this view directly. By id, not index: reconcileLevels pops levels when a genome row is removed, and an index would silently retarget a different pair. | LinearComparativeView |
() => MenuItem[] | items for the "Show..." submenu in the header. overridden by subclasses to add view-specific toggle options | LinearComparativeView |
() => { label: string; onClick: () => void; }[] | LinearComparativeView | |
colorableTrackConfigs() => { trackId: string; name: string; }[] | The tracks that can take a palette slot, in paint order. Overridden by the composing view; a method rather than a getter because that is the form MST overrides cleanly. | TrackColorsMixin |
resolveColorBy(trackId: string) => SyntenyColorBy | The mode one track renders with: its own override, else the view-wide mode. | TrackColorsMixin |
trackColorFor(trackId: string) => string | TrackColorsMixin |
Actions
| Member | Description | Defined by |
|---|---|---|
clearImportFormSyntenyTracks() => void | Drop every pending pair-selection. The import form rewrites the whole list through this whenever its assembly rows change (a selection is about a pair of assemblies, not a row index — see remapSelectionsToPairs), and again once they have been applied. | LinearSyntenyView |
setImportFormSyntenyTrack(arg: number, val: ImportFormSyntenyTrack) => void | LinearSyntenyView | |
setDrawCurves(arg: boolean) => void | LinearSyntenyView | |
setCigarMode(arg: "full" | "matches" | "off") => void | LinearSyntenyView | |
setDrawLocationMarkers(arg: boolean) => void | LinearSyntenyView | |
setShowOffscreenMates(arg: boolean) => void | LinearSyntenyView | |
setBidirectionalFetch(arg: boolean) => void | LinearSyntenyView | |
setOffscreenMateMode(mode: "both" | "off" | "query") => void | The two properties above as the one question a reader is actually answering — how much of what this view cannot draw to go and find. They stay two properties because they are two KINDS: marking is a repaint of what the worker already counted, and the second query is a fetch input. One control over both is what keeps the free half from costing a round trip, and it closes the combination nothing wanted — fetching the lower row and then not drawing what came back. | LinearSyntenyView |
setOverdrawPx(arg: number) => void | LinearSyntenyView | |
setAlpha(arg: number) => void | LinearSyntenyView | |
setMinAlignmentLength(arg: number) => void | LinearSyntenyView | |
setLodMode(arg: LodMode) => void | LinearSyntenyView | |
setOpacityByIdentity(arg: boolean) => void | LinearSyntenyView | |
setFadeThinAlignmentsMode(arg: FadeThinMode) => void | LinearSyntenyView | |
setFadeThinLatch(arg: boolean) => void | Move the latched 'auto' thin-fade decision — installAutoFadeLatch is the only caller. | LinearSyntenyView |
showAllRegions() => void | Every row back to its own whole assembly, fit to its own width — and so also the way off sameScale, whose raised ceiling would otherwise make "show all regions" mean the shared scale on every row. The fit-to-width half of showAllRegionsAcrossRows, under the name the rest of the app reaches it by. | LinearSyntenyView |
setInit(init?: LinearSyntenyViewCommands | undefined) => void | LinearSyntenyView | |
clearView() => void | Also drops init, which hasSomethingToShow keys off while views is empty — leaving it set would bounce "return to import form" straight back to the loading spinner. | LinearSyntenyView |
exportSvg(opts: ExportSvgOptions) => Promise<void> | LinearSyntenyView | |
setFollowUnaligned(arg: boolean) => void | Written by the follow's autorun and read only by the header, which is what keeps it from being a dependency of the very pass that writes it. In THIS block, ahead of afterAttach, rather than with the other follow actions below: a later block's actions are not on the self an earlier one sees, so anything afterAttach calls has to be declared before it — the same reason reconcileLevels is here. | LinearComparativeView |
setFollowApproximate(arg: boolean) => void | Same terms as setFollowUnaligned above: written by the autorun, read only by the header. | LinearComparativeView |
setFollowPartial(arg: FollowPartialReport | undefined) => void | Same terms again: written by the autorun, read only by the header. | LinearComparativeView |
reconcileLevels() => void | Reconcile the levels array to the views array: exactly one synteny level per gap between adjacent views (N views -> N-1 levels). Grows or shrinks from the end, preserving existing levels and their tracks. The single source of truth for the views/levels invariant. | LinearComparativeView |
setWidth(newWidth: number) => void | LinearComparativeView | |
setError(e: unknown) => void | LinearComparativeView | |
| setViews | LinearComparativeView | |
| addView | Push a new genome row. The new trailing level starts with no synteny tracks. | LinearComparativeView |
removeLastRow() => void | Drop the bottom genome row and its synteny level. Only terminal removal is supported: a level's level index addresses views[level]/[level+1], so removing a middle row would require reindexing every level below it. Growth and shrinkage both happen at the end of the chain. | LinearComparativeView |
setLinkViews(arg: boolean) => void | Kept for the plugin ABI; setRowSyncMode is what the UI calls. It still has to drop the follow, since the exclusion below is a property of the two flags rather than of the action that happens to set them. | LinearComparativeView |
setRowSyncMode(mode: "follow" | "independent" | "link") => void | The one way the UI changes how the rows track each other, so the two flags can't both be on. They fight if they are: linkViews replays the anchor's own scroll/zoom onto every row, which is precisely the pixel lock the follow then has to undo on the next settle, and the moving row visibly jumps twice. | LinearComparativeView |
setFollowAnchorIndex(idx: number) => void | LinearComparativeView | |
setFollowMatchOrientation(arg: boolean) => void | LinearComparativeView | |
setScrollZoom(arg: boolean) => void | LinearComparativeView | |
activateTrackSelector(level: number) => Widget | LinearComparativeView | |
toggleTrack(trackId: string, level?: any) => any | LinearComparativeView | |
| showTrack | No-op for a level that doesn't exist, matching hideTrack/toggleTrack. reconcileLevels already materializes exactly one level per adjacent view pair, so a missing level means the caller named a gap that has no views (e.g. an init.tracks with more levels than init.views has gaps); creating one here would append a level whose views[level+1] is absent, which renders nothing and silently breaks the views/levels invariant. | LinearComparativeView |
hideTrack(trackId: string, level?: any) => void | LinearComparativeView | |
squareView() => void | LinearComparativeView | |
showAllRegionsAcrossRows(sameScale: boolean) => void | Every row onto its whole assembly, and the one choice about it: leave them all on ONE bp/px — the coarsest row's fit, so the largest genome fills its pane and every other row is drawn shorter in proportion to its size — or hand each row its own fit, so each fills its own pane. That difference is the point of offering the choice: rows fit individually to width all end up the same length, which silently stretches a small genome to look like a large one and misaligns every ribbon between them by the ratio. Distinct from squareView, which averages the rows' current scales (the average fits nobody, and each row's own zoom clamp pulls the small ones back to fit-to-width anyway). ONE ACTION FOR BOTH, because the menu offers them as one radio and a reader reads them as one sentence with one word changed. Written as two bodies they drifted: the same-scale half took its scale off whatever region subset a row happened to be displaying while the other half reset the rows first, so the pair was not a pair — switching between them did not land back where it started. sameScale LATCHES rather than firing once, because the shared scale is coarser than a small row's own fit: without the raised ceiling the first wheel tick or setDisplayedRegions clamps that row straight back to fit-to-width and the comparison is gone. | LinearComparativeView |
setSameScale(sameScale: boolean) => void | LinearComparativeView | |
() => void | Latch the mode and zoom every row onto the scale it implies, without touching any row's regions or its centre — init names a loc per row, and both a region reset and a re-centre would throw that away. zoomTo anchors at the centre, which is the difference. | LinearComparativeView |
toggleCompactView(idx: number) => void | LinearComparativeView | |
compactAllViews() => void | LinearComparativeView | |
expandAllViews() => void | LinearComparativeView | |
autoScaleLevelHeights() => void | LinearComparativeView | |
| appendRow | Append an assembly to the bottom of the stack and optionally show a synteny track on the new level connecting it to the previous bottom row. A synteny dataset is an edge between two adjacent assemblies, so rows are only ever added at the chain's end. The new row is created with a LinearGenomeView init — its own afterAttach autorun loads the assembly regions and navigates (whole genome, or loc when given), so we don't reimplement that imperatively here. | LinearComparativeView |
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 | The init-time reorder resolved, so the view on screen is the diagonalized one — open the gate. | DiagonalizeProgressMixin |
setDiagonalizeStopToken(arg?: StopToken | 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 |
observeAttributeRanges(ranges: Record<string, AttributeRange>) => void | Fold one fetch's observed attribute spans into the domain this view paints and labels its ramps with. Called by each display as its fetch lands, because the accumulation has to outlive the payload it came from: the previous window's span is gone from loadedAttributeRanges the moment the next one commits. | TrackColorsMixin |
resetAttributeRanges() => void | Forget the accumulated domain, leaving attributeRanges reporting what the LOADED fetches cover and nothing else.The way back from a monotonic domain, and the only one: a single window holding an outlier widens the ramp for the rest of the session, and attributeRanges unions the loaded spans over this, so a reset rescales to what is on screen without waiting for a refetch. Picking a mode is what calls it — the gesture a reader makes when the ramp is telling them nothing is to choose it again. | TrackColorsMixin |
setColorBy(value: SyntenyColorBy) => void | Set the view-wide mode. Clears every per-track override, so picking a mode from the top level of the palette menu really does mean "all tracks" — and rescales the ramp, which is the only way back from a domain one outlying window widened. | TrackColorsMixin |
setTrackColorBy(trackId: string, value: SyntenyColorBy | undefined) => void | Point one track at its own mode, or back at the view-wide one. | TrackColorsMixin |
setTrackColor(trackId: string, value: string | undefined) => void | Pin one track's color under colorBy: 'track', or release it back to an automatic palette slot. | TrackColorsMixin |
clearTrackColorSettings() => void | TrackColorsMixin | |
setShowColorLegend(value: boolean) => void | TrackColorsMixin |
Related links
- Guide: URL query parameter API