# LinearVariantDisplay

Auto-generated @jbrowse/mobx-state-tree API for the current JBrowse release — see [pluggable elements](https://jbrowse.org/jb2/docs/developer_guide/) for concepts. Provided by the `variants` plugin. [View source](https://github.com/GMOD/jbrowse-components/blob/main/plugins/variants/src/LinearVariantDisplay/model.ts).

## Example usage

A complete `VariantTrack` config to paste into `tracks`:

```js
{
  type: 'VariantTrack',
  trackId: 'variants',
  name: 'Variants',
  assemblyNames: ['hg38'],
  adapter: {
    type: 'VcfTabixAdapter',
    uri: 'https://example.com/variants.vcf.gz',
  },
  displays: [
    {
      type: 'LinearVariantDisplay',
      displayId: 'variants-LinearVariantDisplay',
      height: 150,
    },
  ],
}
```

GPU-accelerated variant display with custom feature widget on click.

The configuration slots for this model are documented on its [config schema page](../../config/linearvariantdisplay).

Members a composed model contributes are listed here too, so these tables are the whole surface.

## Properties

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="property-type">**type**</span><br><code>type: types.literal('LinearVariantDisplay')</code> |  | LinearVariantDisplay |
| <span id="property-configuration">**configuration**</span><br><code>configuration: ConfigurationReference(configSchema)</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-configuration) |
| <span id="property-jexlfilterssetting">**jexlFiltersSetting**</span><br><code>jexlFiltersSetting: types.maybe(types.array(types.string))</code> | <span data-pagefind-ignore>Runtime "Filter by..." override.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-jexlfilterssetting) |
| <span id="property-pinnedfeatureids">**pinnedFeatureIds**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>pinnedFeatureIds: types.stripDefault(types.array(types.string),…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>pinnedFeatureIds: types.stripDefault(types.array(types.string), [])</code></pre></dialog></span> | <span data-pagefind-ignore>Feature ids the user pinned to the top of the layout via the feature right-click menu.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-pinnedfeatureids) |
| <span id="property-solofeatureids">**soloFeatureIds**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>soloFeatureIds: types.stripDefault(types.array(types.string), […</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>soloFeatureIds: types.stripDefault(types.array(types.string), [])</code></pre></dialog></span> | <span data-pagefind-ignore>"Show only these features": the collected set the user builds by ctrl+clicking features (or via the right-click menu).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-solofeatureids) |
| <span id="property-soloapplied">**soloApplied**</span><br><code>soloApplied: types.stripDefault(types.boolean, false)</code> | <span data-pagefind-ignore>Whether the collected soloFeatureIds set is actually isolating the view (worker drops non-members).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-soloapplied) |
| <span id="property-hiddenfeatureids">**hiddenFeatureIds**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>hiddenFeatureIds: types.stripDefault(types.array(types.string),…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>hiddenFeatureIds: types.stripDefault(types.array(types.string), [])</code></pre></dialog></span> | <span data-pagefind-ignore>"Hide this feature" exclusion set (inverse of solo): the worker drops these from layout/drawing.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-hiddenfeatureids) |
| <span id="property-expandedgeneids">**expandedGeneIds**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>expandedGeneIds: types.stripDefault(types.array(types.string),…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>expandedGeneIds: types.stripDefault(types.array(types.string), [])</code></pre></dialog></span> | <span data-pagefind-ignore>Genes the user opened from the isoform badge on their own label: these draw every isoform whatever `geneGlyphMode` or the fit ladder's isoform rung would otherwise collapse them to.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-expandedgeneids) |
| <span id="property-featurehighlights">**featureHighlights**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>featureHighlights: types.stripDefault( types.array(FeatureHighl…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>featureHighlights: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.array(FeatureHighlightModel),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;[],&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> | <span data-pagefind-ignore>Declarative feature highlights, typically seeded by a text search (highlight the gene you searched for).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#property-featurehighlights) |
| <span id="property-id">**id**</span><br><code>id: ElementId</code> |  | [BaseDisplay](../basedisplay#property-id) |

## Volatiles

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="volatile-featureidundermouse">**featureIdUnderMouse**</span><br><code>featureIdUnderMouse: undefined as string &#124; undefined</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-featureidundermouse) |
| <span id="volatile-subfeatureidundermouse">**subfeatureIdUnderMouse**</span><br><code>subfeatureIdUnderMouse: undefined as string &#124; undefined</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-subfeatureidundermouse) |
| <span id="volatile-mouseoverextrainformation">**mouseoverExtraInformation**</span><br><code>mouseoverExtraInformation: undefined as string[] &#124; undefined</code> | <span data-pagefind-ignore>the hover tooltip's rows, each rendered as its own element — see hoverTooltipRows for why this is a list and not one HTML string</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-mouseoverextrainformation) |
| <span id="volatile-sequencehoverposition">**sequenceHoverPosition**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>sequenceHoverPosition: undefined as SequenceHoverPosition &#124; und…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>sequenceHoverPosition: undefined as SequenceHoverPosition &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>genomic base currently hovered in a feature sequence dialog opened from this display, read by the LGV crosshair overlay</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-sequencehoverposition) |
| <span id="volatile-incrementallayout">**incrementalLayout**</span><br><code>incrementalLayout: createIncrementalLayout()</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-incrementallayout) |
| <span id="volatile-incrementallayoutlabelsonly">**incrementalLayoutLabelsOnly**</span><br><code>incrementalLayoutLabelsOnly: createIncrementalLayout()</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-incrementallayoutlabelsonly) |
| <span id="volatile-incrementallayoutbodiesonly">**incrementalLayoutBodiesOnly**</span><br><code>incrementalLayoutBodiesOnly: createIncrementalLayout()</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-incrementallayoutbodiesonly) |
| <span id="volatile-incrementallayoutdecimated">**incrementalLayoutDecimated**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>incrementalLayoutDecimated: createIncrementalLayout({ seedPrior…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>incrementalLayoutDecimated: createIncrementalLayout({&#10;&#160;&#160;&#160;&#160;&#160;&#160;seedPriorRows: false,&#10;&#160;&#160;&#160;&#160;})</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-incrementallayoutdecimated) |
| <span id="volatile-incrementallayoutisoforms">**incrementalLayoutIsoforms**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>incrementalLayoutIsoforms: createIncrementalLayout({ seedPriorR…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>incrementalLayoutIsoforms: createIncrementalLayout({&#10;&#160;&#160;&#160;&#160;&#160;&#160;seedPriorRows: false,&#10;&#160;&#160;&#160;&#160;})</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-incrementallayoutisoforms) |
| <span id="volatile-incrementallayoutbare">**incrementalLayoutBare**</span><br><code>incrementalLayoutBare: createIncrementalLayout()</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-incrementallayoutbare) |
| <span id="volatile-morphfromtops">**morphFromTops**</span><br><code>morphFromTops: undefined as Map&lt;string, number&gt; &#124; undefined</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-morphfromtops) |
| <span id="volatile-morphprogress">**morphProgress**</span><br><code>morphProgress: 1</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-morphprogress) |
| <span id="volatile-morphstartms">**morphStartMs**</span><br><code>morphStartMs: 0</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-morphstartms) |
| <span id="volatile-morphfrommaxy">**morphFromMaxY**</span><br><code>morphFromMaxY: 0</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#volatile-morphfrommaxy) |
| <span id="volatile-error">**error**</span><br><code>error: undefined as unknown</code> |  | [BaseDisplay](../basedisplay#volatile-error) |
| <span id="volatile-statusmessage">**statusMessage**</span><br><code>statusMessage: undefined as string &#124; undefined</code> |  | [BaseDisplay](../basedisplay#volatile-statusmessage) |
| <span id="volatile-statusprogress">**statusProgress**</span><br><code>statusProgress: undefined as number &#124; undefined</code> | <span data-pagefind-ignore>determinate progress fraction [0,1] for the current status, or undefined when the in-flight phase is indeterminate. Set alongside `statusMessage` by `setStatusMessage`; a display that never shows a bar simply leaves it undefined.</span> | [BaseDisplay](../basedisplay#volatile-statusprogress) |
| <span id="volatile-scrolltop">**scrollTop**</span><br><code>scrollTop: 0</code> |  | [TrackHeightMixin](../trackheightmixin#volatile-scrolltop) |
| <span id="volatile-loadedregions">**loadedRegions**</span><br><code>loadedRegions: regionDataMap&lt;LoadedRegion&gt;('loadedRegions')</code> | <span data-pagefind-ignore>The per-region store, keyed by `displayedRegionIndex`: what a fetch asked for (the span), what it was issued under (`fetchInputs`) and what it brought back (`payload`), written as one record by `ctx.commitRegion`.<br><br>A display's own `rpcDataMap` was the payload column of this map held separately, and every hook that existed to keep the two in step — `clearDisplaySpecificData`, a `regionHasData` that answered `rpcDataMap.has(idx)`, a hand-rolled prune — was that separation's cost. A display reads the payload back through `regionPayloads`.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#volatile-loadedregions) |
| <span id="volatile-forceloadtrack">**forceLoadTrack**</span><br><code>forceLoadTrack: false</code> | <span data-pagefind-ignore>The force-load button's track-wide approval. Volatile so it never reaches a saved session; the `forceLoad` config slot is the durable form.</span> | [RegionTooLargeMixin](../regiontoolargemixin#volatile-forceloadtrack) |
| <span id="volatile-byteestimate">**byteEstimate**</span><br><code>byteEstimate: undefined as ByteEstimate &#124; undefined</code> | <span data-pagefind-ignore>The last byte measurement: bytes, the span they were taken at, and whether zooming has been shown not to shrink them. Survives `clearAllRpcData`; dropped on chromosome navigation and on a tier swap.</span> | [RegionTooLargeMixin](../regiontoolargemixin#volatile-byteestimate) |
| <span id="volatile-gatemeasuredviewportkey">**gateMeasuredViewportKey**</span><br><code>gateMeasuredViewportKey: undefined as string &#124; undefined</code> | <span data-pagefind-ignore>The `gateViewport` key the gate last asked the adapter about, on either axis — the viewport AND the settings it asked under. Separate from `byteEstimate` because a density refusal measures no bytes.</span> | [RegionTooLargeMixin](../regiontoolargemixin#volatile-gatemeasuredviewportkey) |
| <span id="volatile-canvasdrawn">**canvasDrawn**</span><br><code>canvasDrawn: false</code> | <span data-pagefind-ignore>flips true on first paint; read by test selectors to detect render</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-canvasdrawn) |
| <span id="volatile-currentrenderingbackend">**currentRenderingBackend**</span><br><code>currentRenderingBackend: undefined</code> | <span data-pagefind-ignore>current backend reference, updated on context-loss recovery. Typed `unknown` (not generic `B`) on purpose: this mixin is composed by every display via a non-generic factory, so the per-display backend type `B` isn't known here — it's supplied at `attachRenderingBackend<B>` and narrowed with `as B` inside the autoruns. Don't "fix" the cast.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-currentrenderingbackend) |
| <span id="volatile-rendertick">**renderTick**</span><br><code>renderTick: 0</code> | <span data-pagefind-ignore>counter the render autorun observes; bumped to force a re-render</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-rendertick) |
| <span id="volatile-autorunsinstalled">**autorunsInstalled**</span><br><code>autorunsInstalled: false</code> | <span data-pagefind-ignore>guards attachRenderingBackend so the autorun pair spawns once per instance</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-autorunsinstalled) |
| <span id="volatile-rendererror">**renderError**</span><br><code>renderError: undefined</code> | <span data-pagefind-ignore>the render-backend (GPU/Canvas2D init or context-loss) error, or undefined. Single source of truth for the render-error terminal state: `useRenderingBackend` writes it from the canvas-init mechanism so the model — not React-local hook state — owns every terminal state. Read by `displayPhase` (whose `renderError` term outranks `loading`, suppressing the scrim) and by `DisplayChrome` (shows the retry overlay).</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-rendererror) |
| <span id="volatile-activestoptoken">**activeStopToken**</span><br><code>activeStopToken: undefined as StopToken &#124; undefined</code> | <span data-pagefind-ignore>stop token of the in-flight fetch, or undefined when idle</span> | [FetchMixin](../fetchmixin#volatile-activestoptoken) |
| <span id="volatile-fetchgeneration">**fetchGeneration**</span><br><code>fetchGeneration: 0</code> | <span data-pagefind-ignore>bumps at every fetch end; autoruns read it to re-evaluate, and it doubles as the staleness epoch inside runFetch</span> | [FetchMixin](../fetchmixin#volatile-fetchgeneration) |
| <span id="volatile-reloadcounter">**reloadCounter**</span><br><code>reloadCounter: 0</code> | <span data-pagefind-ignore>Bumped by `reload()` and read unconditionally by the fetch autoruns, so a user retry re-runs the body even where nothing else moved — after an error every other fetch input is unchanged. It is also the half that survives a `reload()` override that forgets to invalidate, which is the dead Retry button `makeRetryContractCheck` reports. Declared here because this is the one mixin every fetch foundation composes, the same argument that put `fetchInert` below; the comparative family carried its own until ADR-105.</span> | [FetchMixin](../fetchmixin#volatile-reloadcounter) |
| <span id="volatile-statuswindow">**statusWindow**</span><br><code>statusWindow: createStatusWindow(writeStatus(self))</code> | <span data-pagefind-ignore>This display's status field, and the only thing that writes it: one throttle window, one slot per concurrent operation, so N parallel per-region fetches thin to one stream between them rather than N and a second operation cannot end the first one's label (ADR-081). Lent whole to `createStopTokenRotation` by a display that also runs a bare-autorun fetch — see `StatusReporter`.</span> | [FetchMixin](../fetchmixin#volatile-statuswindow) |
| <span id="volatile-fetchcanceled">**fetchCanceled**</span><br><code>fetchCanceled: false</code> | <span data-pagefind-ignore>true after the user explicitly cancels a load (the loading overlay's cancel button → `cancelFetchByUser`). A durable, blocking state — unlike `cancelFetch`, it does not retrigger the fetch autoruns — so the load stays stopped until the user retries (`reload`) or the viewport changes. Any new fetch clears it (`runFetch` resets it at the start).</span> | [FetchMixin](../fetchmixin#volatile-fetchcanceled) |
| <span id="volatile-fetchrotation">**fetchRotation**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>fetchRotation: createStopTokenRotation(self, { statusWindow: se…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>fetchRotation: createStopTokenRotation(self, {&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;statusWindow: self.statusWindow,&#10;&#160;&#160;&#160;&#160;&#160;&#160;})</code></pre></dialog></span> | <span data-pagefind-ignore>**The latest-wins machine this mixin is a wrapper around**, and not a second one: `createStopTokenRotation` owns token rotation, the `isCurrent` guard, the status slot and the supersede-versus-end rule (ADR-080, ADR-081), for every fetch in the codebase that has one. `runFetch` adds the observable bookkeeping a display needs on top — `isLoading`, `error`, `fetchGeneration`, `fetchCanceled` — and nothing else.<br><br>It was two implementations of that machine until 2026-08-20, which is how they came to disagree about whether a completed fetch releases its token. A display's *primary* fetch is this wrapper; a second concurrent fetch on the same node holds a rotation of its own, which is why the primitive is the thing that exists and this is the thing built on it (ADR-054 §1, the one section ADR-105 keeps).<br><br>It is lent this display's `statusWindow`, so the fetch takes a slot on the one field rather than opening a second window over it — the whole point of `StatusReporter`.</span> | [FetchMixin](../fetchmixin#volatile-fetchrotation) |
| <span id="volatile-densitystatsperregion">**densityStatsPerRegion**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>densityStatsPerRegion: regionDataMap&lt;RegionDensityStats&gt;( 'dens…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>densityStatsPerRegion: regionDataMap&lt;RegionDensityStats&gt;(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;'densityStatsPerRegion',&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> | <span data-pagefind-ignore>Per-region feature counts, so the verdict is a live max at the current `bpPerPx`.</span> | [CanvasFeatureGateMixin](../canvasfeaturegatemixin#volatile-densitystatsperregion) |
| <span id="volatile-densityhoverpx">**densityHoverPx**</span><br><code>densityHoverPx: undefined as number &#124; undefined</code> | <span data-pagefind-ignore>The cursor's view px, not the bp under it: a wheel zoom under a stationary cursor fires no mousemove, and the px stays true through it.</span> | [DensityBandMixin](../densitybandmixin#volatile-densityhoverpx) |
| <span id="volatile-coarsetier">**coarseTier**</span><br><code>coarseTier: regionDataMap&lt;P&gt;('coarseTier')</code> | <span data-pagefind-ignore>The coarse payload by `displayedRegionIndex`, over the regions the last read was issued for. Cleared on chromosome navigation.</span> | [CoarseTierMixin](../coarsetiermixin#volatile-coarsetier) |
| <span id="volatile-coarsetierread">**coarseTierRead**</span><br><code>coarseTierRead: undefined as CoarseTierRead &#124; undefined</code> | <span data-pagefind-ignore>What the held payloads were read over — the buffered regions and the read key — so a pan or a zoom inside them re-reads nothing. Undefined until a read lands.</span> | [CoarseTierMixin](../coarsetiermixin#volatile-coarsetierread) |
| <span id="volatile-coarsetierloading">**coarseTierLoading**</span><br><code>coarseTierLoading: false</code> |  | [CoarseTierMixin](../coarsetiermixin#volatile-coarsetierloading) |
| <span id="volatile-contextmenuinfo">**contextMenuInfo**</span><br><code>contextMenuInfo: undefined as Info &#124; undefined</code> |  | [ContextMenuMixin](../contextmenumixin#volatile-contextmenuinfo) |

## Getters

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="getter-featurenoun">**featureNoun**</span><br><code>string</code> | Renames the shared canvas vocabulary for this display: every menu row, chip and indicator that names what the track holds reads this, so a variant track says "Variant height", "Hide this variant", "Showing 3 variants" instead of inheriting the gene-oriented "feature". The per-hit noun in the context menu still comes from the annotation's own type where it has one. | LinearVariantDisplay |
| <span id="getter-featurewidgettype">**featureWidgetType**</span><br><code>{ type: string; id: string; }</code> |  | LinearVariantDisplay |
| <span id="getter-colorsbyconsequenceimpact">**colorsByConsequenceImpact**</span><br><code>boolean</code> |  | LinearVariantDisplay |
| <span id="getter-colorsbysvtype">**colorsBySvType**</span><br><code>boolean</code> |  | LinearVariantDisplay |
| <span id="getter-colorlegend">**colorLegend**</span><br><code>LegendItem[]</code> | This display's answer to the base's `colorLegend` chrome hook: the rows for whichever preset color key is active (impact tiers or SV classes), or none. SV-type shows the fixed class key; copy-number and unrecognized tokens aren't listed (the pure jexl has no present-set). The shared canvas body draws the key, so this display needs no component of its own. | LinearVariantDisplay |
| <span id="getter-rpcdatamap">**rpcDataMap**</span><br><code>ReadonlyMap&lt;number, LoadedFeatureData&gt;</code> | <span data-pagefind-ignore>The fetched features, keyed by displayedRegionIndex — the foundation's per-region store, narrowed.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-rpcdatamap) |
| <span id="getter-conf">**conf**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>ModelInstanceTypeProps&lt;Record&lt;…&gt;&gt; &amp; { setSubschema(slotName: st…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>ModelInstanceTypeProps&lt;Record&lt;…&gt;&gt; &amp; { setSubschema(slotName: string, data: Record&lt;string, unknown&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;...&gt;</code></pre></dialog></span> | <span data-pagefind-ignore>the config typed off the concrete schema; `ConfigurationReference` erases `self.configuration` to `any`, so direct reads route through this to stay typed (same move as `BaseAdapter<CONF>`).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-conf) |
| <span id="getter-showoutline">**showOutline**</span><br><code>boolean</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-showoutline) |
| <span id="getter-featurecolor">**featureColor**</span><br><code>any</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-featurecolor) |
| <span id="getter-utrcolor">**utrColor**</span><br><code>string</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-utrcolor) |
| <span id="getter-colorbymode">**colorByMode**</span><br><code>"attribute" &#124; "default" &#124; "solid" &#124; "strand"</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-colorbymode) |
| <span id="getter-colorbyattribute">**colorByAttribute**</span><br><code>string</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-colorbyattribute) |
| <span id="getter-geneglyphnotice">**geneGlyphNotice**</span><br><code>GeneGlyphNotice &#124; undefined</code> | <span data-pagefind-ignore>Overridable hook (default absent): the isoform-collapse control the shared canvas body draws in its bottom-right chip stack, or nothing when the display has no gene glyphs.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-geneglyphnotice) |
| <span id="getter-layoutready">**layoutReady**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether features can be laid out: data is fetched, in-bounds, and the view is measured.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-layoutready) |
| <span id="getter-onscreenfeatureids">**onScreenFeatureIds**</span><br><code>ReadonlySet&lt;string&gt; &#124; undefined</code> | <span data-pagefind-ignore>The features whose bp span touches the viewport.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-onscreenfeatureids) |
| <span id="getter-labeldensityperpx">**labelDensityPerPx**</span><br><code>number</code> | <span data-pagefind-ignore>Features per pixel of what is actually ON SCREEN — the density the `auto` label modes gate on (ADR-093).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-labeldensityperpx) |
| <span id="getter-renderstate">**renderState**</span><br><code>{ scrollY: number; canvasWidth: number; canvasHeight: number; }</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-renderstate) |
| <span id="getter-labelscrollbucket">**labelScrollBucket**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-labelscrollbucket) |
| <span id="getter-displaymode">**displayMode**</span><br><code>"collapsed" &#124; "compact" &#124; "normal" &#124; "superCompact"</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-displaymode) |
| <span id="getter-effectivesubfeaturelabels">**effectiveSubfeatureLabels**</span><br><code>"below" &#124; "none" &#124; "overlay"</code> | <span data-pagefind-ignore>The subfeature-label mode the worker bakes.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-effectivesubfeaturelabels) |
| <span id="getter-labelfontsize">**labelFontSize**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-labelfontsize) |
| <span id="getter-showlabelsmode">**showLabelsMode**</span><br><code>"auto" &#124; "description" &#124; "name" &#124; "nameAndDescription" &#124; "none"</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-showlabelsmode) |
| <span id="getter-showlabels">**showLabels**</span><br><code>boolean</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-showlabels) |
| <span id="getter-showdescriptions">**showDescriptions**</span><br><code>boolean</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-showdescriptions) |
| <span id="getter-effectiveshowdescriptions">**effectiveShowDescriptions**</span><br><code>boolean</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-effectiveshowdescriptions) |
| <span id="getter-selectedfeatureid">**selectedFeatureId**</span><br><code>string &#124; undefined</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-selectedfeatureid) |
| <span id="getter-colorbycds">**colorByCDS**</span><br><code>boolean</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-colorbycds) |
| <span id="getter-showaminoacids">**showAminoAcids**</span><br><code>boolean</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-showaminoacids) |
| <span id="getter-reversedregions">**reversedRegions**</span><br><code>Set&lt;number&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-reversedregions) |
| <span id="getter-pinnedfeatureidset">**pinnedFeatureIdSet**</span><br><code>ReadonlySet&lt;string&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-pinnedfeatureidset) |
| <span id="getter-expandedgeneidset">**expandedGeneIdSet**</span><br><code>ReadonlySet&lt;string&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-expandedgeneidset) |
| <span id="getter-solofeatureidset">**soloFeatureIdSet**</span><br><code>ReadonlySet&lt;string&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-solofeatureidset) |
| <span id="getter-hiddenfeaturecount">**hiddenFeatureCount**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-hiddenfeaturecount) |
| <span id="getter-solofeaturecount">**soloFeatureCount**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-solofeaturecount) |
| <span id="getter-pinnedfeaturecount">**pinnedFeatureCount**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-pinnedfeaturecount) |
| <span id="getter-canonicalfeaturehighlights">**canonicalFeatureHighlights**</span><br><code>FeatureHighlight[]</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-canonicalfeaturehighlights) |
| <span id="getter-resolvedhighlights">**resolvedHighlights**</span><br><code>ResolvedHighlights</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-resolvedhighlights) |
| <span id="getter-highlightedfeatureidset">**highlightedFeatureIdSet**</span><br><code>ReadonlySet&lt;string&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-highlightedfeatureidset) |
| <span id="getter-layoutpinnedfeatureidset">**layoutPinnedFeatureIdSet**</span><br><code>ReadonlySet&lt;string&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-layoutpinnedfeatureidset) |
| <span id="getter-featurehighlightcount">**featureHighlightCount**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-featurehighlightcount) |
| <span id="getter-layoutinputs">**layoutInputs**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ bpPerPx: number; reversedRegions: Set&lt;…&gt;; displayMode: "colla…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ bpPerPx: number; reversedRegions: Set&lt;…&gt;; displayMode: "collapsed" &#124; "compact" &#124; "normal" &#124; "superCompact"; pinnedFeatureIds: ReadonlySet&lt;…&gt;; expandedGeneIds: ReadonlySet&lt;...&gt;; }</code></pre></dialog></span> | <span data-pagefind-ignore>Layout inputs shared by the base layout and every fit rung, `expandedGeneIds` included: a rung inheriting them without the exemption re-collapses the gene the user just opened.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-layoutinputs) |
| <span id="getter-fitmeasurefeatureids">**fitMeasureFeatureIds**</span><br><code>ReadonlySet&lt;string&gt; &#124; undefined</code> | <span data-pagefind-ignore>The features the ladder measures its rungs and its isoform solve against: the on-screen set in `fit` and `fixed`, undefined in `grow` (which measures the whole stack).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitmeasurefeatureids) |
| <span id="getter-showseveryisoform">**showsEveryIsoform**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false): the display's transcript setting names every isoform, so the fit ladder's `isoforms` rung may not trim — the surplus scrolls instead.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-showseveryisoform) |
| <span id="getter-effectivegeneglyphmode">**effectiveGeneGlyphMode**</span><br><code>"all" &#124; "auto" &#124; "longestCoding"</code> | <span data-pagefind-ignore>Overridable hook: the gene-glyph mode the worker collapses under.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-effectivegeneglyphmode) |
| <span id="getter-reservesbelowlabelrows">**reservesBelowLabelRows**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the settings reserve `below` subfeature-label rows, which is what earns the fit ladder its `bare` rung — with nothing reserved the rung would repack an identical stack.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-reservesbelowlabelrows) |
| <span id="getter-fullreservation">**fullReservation**</span><br><code>LabelReservation</code> | <span data-pagefind-ignore>What the `full` rung reserves: the names and descriptions the settings ask for.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fullreservation) |
| <span id="getter-labelsreservation">**labelsReservation**</span><br><code>LabelReservation</code> | <span data-pagefind-ignore>The `labels` and `decimated` rungs' reservation: names kept, descriptions dropped.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-labelsreservation) |
| <span id="getter-isoformsreservation">**isoformsReservation**</span><br><code>LabelReservation</code> | <span data-pagefind-ignore>The `isoforms` rung's reservation.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-isoformsreservation) |
| <span id="getter-decimatedbaseinputs">**decimatedBaseInputs**</span><br><code>LabelRoomFactorFreeInputs</code> | <span data-pagefind-ignore>The `decimated` rung's layout inputs minus the whitespace factor.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-decimatedbaseinputs) |
| <span id="getter-decimatedheightprobe">**decimatedHeightProbe**</span><br><code>(labelRoomFactor: number) =&gt; number</code> | <span data-pagefind-ignore>Measures the `decimated` rung's stack height at any whitespace factor, against the features the ladder measures its rungs with — so the factor the solve picks is judged on the same stack the rung is then kept or rejected on.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-decimatedheightprobe) |
| <span id="getter-isoformsbaseinputs">**isoformsBaseInputs**</span><br><code>IsoformCountFreeInputs</code> | <span data-pagefind-ignore>The `isoforms` rung's layout inputs minus the count itself, typed without it so the solve's shared preparation provably cannot depend on it.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-isoformsbaseinputs) |
| <span id="getter-isoformsheightprobe">**isoformsHeightProbe**</span><br><code>(maxIsoforms: number) =&gt; number</code> | <span data-pagefind-ignore>Measures the `isoforms` rung's stack height at any isoform count, against the features the ladder measures its rungs with.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-isoformsheightprobe) |
| <span id="getter-maxisoformsonscreen">**maxIsoformsOnScreen**</span><br><code>number</code> | <span data-pagefind-ignore>The most isoforms any trimmable gene ON SCREEN has — the top of the solve's bracket, and the count above which a trim can take nothing away.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-maxisoformsonscreen) |
| <span id="getter-fitisoformcount">**fitIsoformCount**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>The isoform count the `isoforms` rung commits at: the largest whose names-kept stack fits `fitTargetHeight`, so the most transcripts are kept without giving up a name.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitisoformcount) |
| <span id="getter-fitisoformssolved">**fitIsoformsSolved**</span><br><code>Map&lt;number, FeatureDataResult&gt;</code> | <span data-pagefind-ignore>The `isoforms` stack: every gene trimmed to `fitIsoformCount` transcripts, names intact.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitisoformssolved) |
| <span id="getter-baselaidoutdatamap">**baseLaidOutDataMap**</span><br><code>Map&lt;number, FeatureDataResult&gt;</code> | <span data-pagefind-ignore>Full reservation (names + descriptions): rendered at fit stage `full` and in non-fit modes, and the first stack `fitStage` probes.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-baselaidoutdatamap) |
| <span id="getter-fitlabelsonlylayout">**fitLabelsOnlyLayout**</span><br><code>Map&lt;number, FeatureDataResult&gt;</code> | <span data-pagefind-ignore>Names reserved, descriptions dropped — the `labels` stage's stack.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitlabelsonlylayout) |
| <span id="getter-fitdecimatedfactor">**fitDecimatedFactor**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>The whitespace factor the `decimated` rung commits at: the smallest one whose packed stack fits `fitTargetHeight`, so the most names are kept.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitdecimatedfactor) |
| <span id="getter-fitdecimatedsolved">**fitDecimatedSolved**</span><br><code>Map&lt;number, FeatureDataResult&gt;</code> | <span data-pagefind-ignore>The `decimated` stack: names kept only on features with at least `fitDecimatedFactor ×` their label width in neighbour whitespace (plus pinned/highlighted, always).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitdecimatedsolved) |
| <span id="getter-fitbodiesonlylayout">**fitBodiesOnlyLayout**</span><br><code>Map&lt;number, FeatureDataResult&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitbodiesonlylayout) |
| <span id="getter-fitbarelayout">**fitBareLayout**</span><br><code>Map&lt;number, FeatureDataResult&gt;</code> | <span data-pagefind-ignore>The `bare` stack: `bodies` with the `below` subfeature-label rows spent at zero height, so the last reduction before a squeeze gives back rows whose text the squeeze was about to hide anyway.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitbarelayout) |
| <span id="getter-fitsmallestboxpx">**fitSmallestBoxPx**</span><br><code>number</code> | <span data-pagefind-ignore>The shortest box the layout draws on screen, read off the layout rather than the `featureHeight` slot, a per-feature jexl callback that throws with no feature in scope.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitsmallestboxpx) |
| <span id="getter-fitminscale">**fitMinScale**</span><br><code>number</code> | <span data-pagefind-ignore>Floor on the fit squeeze: the smallest vertical scale that still leaves every drawn box at least `MIN_FIT_BOX_PX` tall.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitminscale) |
| <span id="getter-fitmaxscale">**fitMaxScale**</span><br><code>number</code> | <span data-pagefind-ignore>Ceiling on the fit grow: the largest vertical scale before a feature body exceeds the height it would have outside fit mode.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitmaxscale) |
| <span id="getter-fitstage">**fitStage**</span><br><code>FitStage</code> | <span data-pagefind-ignore>The resolved fit outcome — which reservation `level` survived, its unscaled `layout`, and the vertical `scale` to fill the track — bundled so the three can never disagree.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitstage) |
| <span id="getter-fitscale">**fitScale**</span><br><code>number</code> | <span data-pagefind-ignore>Uniform vertical scale for fit mode; 1 unless the resolved stack is being grown to fill the track (> 1) or the bodies stack squeezed to fit (< 1).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitscale) |
| <span id="getter-laidoutdatamap">**laidOutDataMap**</span><br><code>ReadonlyMap&lt;number, FeatureDataResult&gt;</code> | <span data-pagefind-ignore>What every consumer (hit test, GPU upload, React render) reads: the resolved fit layout, cloned and scaled only when grown or squeezed.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-laidoutdatamap) |
| <span id="getter-renderedshowdescriptions">**renderedShowDescriptions**</span><br><code>boolean</code> | <span data-pagefind-ignore>Descriptions are painted where the kept rung reserved room for them.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-renderedshowdescriptions) |
| <span id="getter-renderedshowlabels">**renderedShowLabels**</span><br><code>boolean</code> | <span data-pagefind-ignore>Names are painted where the kept rung reserved row height + overhang for them.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-renderedshowlabels) |
| <span id="getter-renderedshowsubfeaturelabels">**renderedShowSubfeatureLabels**</span><br><code>boolean</code> | <span data-pagefind-ignore>A subfeature label (a transcript name under its gene) is worker-baked and its row is reserved in the pack, so it survives every rung that kept those rows and goes only where the kept rung spent them at zero.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-renderedshowsubfeaturelabels) |
| <span id="getter-fitdrops">**fitDrops**</span><br><code>FitDrops</code> | <span data-pagefind-ignore>What the ladder took from the labels the settings reserved, and how far it squeezed — the one derivation both user-facing notes read.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitdrops) |
| <span id="getter-fitnote">**fitNote**</span><br><code>string &#124; undefined</code> | <span data-pagefind-ignore>The track-sizing control's account of what fit mode gave up, or undefined when nothing.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-fitnote) |
| <span id="getter-labelsfithint">**labelsFitHint**</span><br><code>string &#124; undefined</code> | <span data-pagefind-ignore>The note on the selected "Labels" radio while the ladder is not honouring it (see `inertLabelHint`).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-labelsfithint) |
| <span id="getter-morpheased">**morphEased**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-morpheased) |
| <span id="getter-renderdatamap">**renderDataMap**</span><br><code>ReadonlyMap&lt;number, FeatureDataResult&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-renderdatamap) |
| <span id="getter-settledmaxy">**settledMaxY**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-settledmaxy) |
| <span id="getter-maxy">**maxY**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-maxy) |
| <span id="getter-scrollextentmaxy">**scrollExtentMaxY**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-scrollextentmaxy) |
| <span id="getter-hasoverflow">**hasOverflow**</span><br><code>boolean</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-hasoverflow) |
| <span id="getter-truncatedfeaturecount">**truncatedFeatureCount**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-truncatedfeaturecount) |
| <span id="getter-contentheight">**contentHeight**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-contentheight) |
| <span id="getter-scrollcontentheight">**scrollContentHeight**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-scrollcontentheight) |
| <span id="getter-scrollableheight">**scrollableHeight**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-scrollableheight) |
| <span id="getter-growtargetheight">**growTargetHeight**</span><br><code>number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-growtargetheight) |
| <span id="getter-featureidindex">**featureIdIndex**</span><br><code>Map&lt;string, FlatbushItem&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-featureidindex) |
| <span id="getter-subfeatureidindex">**subfeatureIdIndex**</span><br><code>Map&lt;string, SubfeatureInfo&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-subfeatureidindex) |
| <span id="getter-hoveredfeature">**hoveredFeature**</span><br><code>FlatbushItem &#124; undefined</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-hoveredfeature) |
| <span id="getter-hoveredsubfeature">**hoveredSubfeature**</span><br><code>SubfeatureInfo &#124; undefined</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-hoveredsubfeature) |
| <span id="getter-hoverboxfeature">**hoverBoxFeature**</span><br><code>FlatbushItem &#124; undefined</code> | <span data-pagefind-ignore>The feature the hover box frames: the open context menu's target while one is open, so the box always agrees with what the menu acts on, else the feature under the cursor.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-hoverboxfeature) |
| <span id="getter-hoverboxsubfeature">**hoverBoxSubfeature**</span><br><code>SubfeatureInfo &#124; undefined</code> | <span data-pagefind-ignore>The transcript the hover box frames instead of its gene, by the rule of `hoverBoxFeature`.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-hoverboxsubfeature) |
| <span id="getter-featureitemmap">**featureItemMap**</span><br><code>Map&lt;string, FeatureItemEntry&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-featureitemmap) |
| <span id="getter-flatbushindexes">**flatbushIndexes**</span><br><code>Map&lt;number, FlatbushRegionIndexes&gt;</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-flatbushindexes) |
| <span id="getter-zoomfetchkey">**zoomFetchKey**</span><br><code>string</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#getter-zoomfetchkey) |
| <span id="getter-parenttrack">**parentTrack**</span><br><code>AbstractTrackModel</code> |  | [BaseDisplay](../basedisplay#getter-parenttrack) |
| <span id="getter-renderingcomponent">**RenderingComponent**</span><br><code>FC&lt;…&gt;</code> |  | [BaseDisplay](../basedisplay#getter-renderingcomponent) |
| <span id="getter-displayblurb">**DisplayBlurb**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>FC&lt;{ model: ModelInstanceTypeProps&lt;{ id: IOptionalIType&lt;ISimple…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>FC&lt;{ model: ModelInstanceTypeProps&lt;{ id: IOptionalIType&lt;ISimpleType&lt;string&gt;, [undefined]&gt;; type: ISimpleType&lt;string&gt;; }&gt; &amp; { ...; } &amp; { ...; } &amp; IStateTreeNode&lt;...&gt;; }&gt; &#124; null</code></pre></dialog></span> |  | [BaseDisplay](../basedisplay#getter-displayblurb) |
| <span id="getter-adapterconfig">**adapterConfig**</span><br><code>Record&lt;string, unknown&gt;</code> |  | [BaseDisplay](../basedisplay#getter-adapterconfig) |
| <span id="getter-isminimized">**isMinimized**</span><br><code>boolean</code> | <span data-pagefind-ignore>Returns true if the parent track is minimized. Used to skip expensive operations like autoruns when track is not visible.</span> | [BaseDisplay](../basedisplay#getter-isminimized) |
| <span id="getter-height">**height**</span><br><code>number</code> |  | [TrackHeightMixin](../trackheightmixin#getter-height) |
| <span id="getter-resizing">**resizing**</span><br><code>boolean</code> | <span data-pagefind-ignore>True for the duration of a height drag on this track, whichever handle is running it. A display whose row geometry is a function of the track height restretches every row per animation frame, and can use this to sit an expensive per-frame layer out of the drag (MAF's dense per-base letter overlay is a Canvas2D pass that scales with rows x columns).<br><br>The flag itself is the track's (`BaseTrackModel`), so the view brackets a drag without needing the active display to have opted into this mixin. Reading it here is what makes `self.resizing` available to a display that did.</span> | [TrackHeightMixin](../trackheightmixin#getter-resizing) |
| <span id="getter-heightmode">**heightMode**</span><br><code>"fit" &#124; "fixed" &#124; "grow"</code> | <span data-pagefind-ignore>The resolved track-height strategy (`fixed`/`grow`/`fit`). Promotable sentinel slot: resolveConf walks the customized-track -> session-default -> `fixed` cascade and never returns the `inherit` sentinel.</span> | [HeightModeMixin](../heightmodemixin#getter-heightmode) |
| <span id="getter-fittargetheight">**fitTargetHeight**</span><br><code>number</code> | <span data-pagefind-ignore>The drag-resizable track height as stored in the config slot — the fit target the fit/grow layout scales or packs content into. Read there instead of the reactive `height` getter to break the grow-mode cycle (`height`->grownHeight->layout->height). Equals `height` in fixed/fit.</span> | [HeightModeMixin](../heightmodemixin#getter-fittargetheight) |
| <span id="getter-growmaxheight">**growMaxHeight**</span><br><code>number</code> | <span data-pagefind-ignore>Ceiling `grow` mode sizes the track to, in px (content past it scrolls). Lives here rather than as a constant so a track whose whole point is a deep pileup can raise it; both displays that own a `grownHeight` read this, so the two can't diverge.</span> | [HeightModeMixin](../heightmodemixin#getter-growmaxheight) |
| <span id="getter-autoheight">**autoHeight**</span><br><code>boolean</code> | <span data-pagefind-ignore>`grow` mode as a boolean, derived from the unified `heightMode` slot.</span> | [HeightModeMixin](../heightmodemixin#getter-autoheight) |
| <span id="getter-fitheighttodisplay">**fitHeightToDisplay**</span><br><code>boolean</code> | <span data-pagefind-ignore>`fit` mode as a boolean, derived from the unified `heightMode` slot.</span> | [HeightModeMixin](../heightmodemixin#getter-fitheighttodisplay) |
| <span id="getter-grownheight">**grownHeight**</span><br><code>number</code> | <span data-pagefind-ignore>Target track height for `grow`: what the content wants, capped so a deep stack doesn't grow the track to thousands of px (the remainder scrolls). What `installGrowExitBake` bakes into the slot on exit.</span> | [HeightModeMixin](../heightmodemixin#getter-grownheight) |
| <span id="getter-showlegend">**showLegend**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the legend is drawn. Resolved through the promotable-slot tiers (`resolveConf`): an explicit track value customizes it either way, otherwise it follows the session-wide default for this display type, falling back to the slot's `promotedBase`.</span> | [LegendMixin](../legendmixin#getter-showlegend) |
| <span id="getter-showlegenddisplaytypedefault">**showLegendDisplayTypeDefault**</span><br><code>Pin</code> | <span data-pagefind-ignore>The legend checkbox over every open track of this type. `showLegendCheckboxItem` takes this as its `pin`.</span> | [LegendMixin](../legendmixin#getter-showlegenddisplaytypedefault) |
| <span id="getter-host">**host**</span><br><code>RegionHost</code> | <span data-pagefind-ignore>The containing LinearGenomeView, typed once for every display in this family — see `containingHost` for the cast it owns and why both foundations still declare the name.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-host) |
| <span id="getter-canvaswidthpx">**canvasWidthPx**</span><br><code>number</code> | <span data-pagefind-ignore>The CSS width of this display's on-screen canvas, in px — and the `canvasWidth` its `renderState` must carry, since the two have to agree or the bp→px mapping is scaled against a box it doesn't fill.<br><br>`trackWidthPx`, **not** `view.width`: `TrackRenderingContainer` insets the rendering component by the 2px track outline under `contain: strict`, so a `view.width`-wide canvas overhangs its own container and the browser clips the overhang away. It renders almost identically, which is why MAF drifted onto `view.width` uncaught.<br><br>A getter rather than a note on each display, because the choice was being made by copying a neighbour out of four plausible view getters — `width` (the viewport), this one, and `totalWidthPx` / `totalWidthPxWithoutBorders` (the *content* width, which the global family's heatmaps legitimately want: a different question, not a different answer). `no-restricted-syntax` bans the underlying read everywhere but this line, since a second spelling agrees until it doesn't.<br><br>SVG export is the one exception: the export shell has no outline, so `renderSvg` overrides `canvasWidth` with the shell's own width (see `LgvSvgBodyProps`).</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-canvaswidthpx) |
| <span id="getter-settledsubpixelbinbp">**settledSubPixelBinBp**</span><br><code>number</code> | <span data-pagefind-ignore>Genomic bp one cell of a per-base pass stands for at the settled zoom: `subPixelBinBp` off the host's debounced `coarseBpPerPx`, and 1 until the view initializes. A per-base encode or fetch reads this rather than the live zoom so a wheel tick does not redo every region.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-settledsubpixelbinbp) |
| <span id="getter-canrender">**canRender**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overrides `RenderLifecycleMixin`'s default-true hook with the LGV precondition both foundations share — see `foundationCanRender`.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-canrender) |
| <span id="getter-renderscanvas">**rendersCanvas**</span><br><code>boolean</code> | <span data-pagefind-ignore>Fills `RenderLifecycleMixin`'s hook off `fetchInert`, as `GlobalFetchMixin` does: a display that will never fetch here shows a placeholder where its canvas would be.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-renderscanvas) |
| <span id="getter-viewportwithinloadeddata">**viewportWithinLoadedData**</span><br><code>boolean</code> | <span data-pagefind-ignore>true when every visible block lies within an already-fetched region — i.e. the viewport shows data we actually loaded, not the stale fringe left after a zoom-out/pan. Drives the loading overlay through the pre-refetch debounce.<br><br>**Spatial only, and it stays that way.** Whether the data held for a block is still what a fetch would bring back is `isCacheValid`, which `dataCurrent` conjoins for the export gate. The scrim reads this getter and `dataSuperseded`, never `isCacheValid`: a phase that went `loading` on a moved `fetchInputs` would raise the overlay into every zoom.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-viewportwithinloadeddata) |
| <span id="getter-viewportempty">**viewportEmpty**</span><br><code>boolean</code> | <span data-pagefind-ignore>No content block is on screen, so this display has nothing to fetch and nothing to paint — see `viewportEmpty.ts` for the one viewport that reaches it, how narrow that is, and why the state still has to be terminal rather than a permanent scrim. Both foundations declare it over that one expression, the same way they each declare `host` and `paintInert`.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-viewportempty) |
| <span id="getter-fetchsuspended">**fetchSuspended**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false), read by the fetch plan: the display is drawing something in the features' place and wants no fetch while it does. `DensityTierMixin` says it while the band is up and the gate is not blocking, so a track forced to `density` never downloads the features it will not draw, while a refused viewport keeps its measurement pass and the gate can still release.<br><br>Not `fetchInert`: that one suppresses the scrim and ends the export wait, and a display saying this still has its stand-in to load. On this foundation alone, because only this family's plan reads it.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-fetchsuspended) |
| <span id="getter-datasuperseded">**dataSuperseded**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false): the held data is loaded and covers the viewport, but a fetch input has moved past it, so the data is about to be refetched. A display says so here rather than overriding `dataCurrent`, for the reason `FetchMixin.fetchInert` is a hook: an override has to restate the freshness terms and then misses the next one added.<br><br>Both answers a display gives about being finished read it — the export gate through `dataCurrent`, the loading scrim through `displayPhase`. The export gate is the sharper case: `awaitSvgReady` samples freshness once, and an export that samples it inside this window renders the data that is about to be replaced. GWAS's LD auto-index is that case: adopting the top hit as the index SNP is an `rpcProps` change, so the very load that produced the top hit is what it invalidates — and `SettingsInvalidate` lands a tick after the write, so until it does not even `staleSettingsDrawn` has seen it.<br><br>The window is NOT invisible on screen, which this used to say while `displayPhase` took a spatial-only argument: alignments' per-base wall spends the debounce plus the RPC painting a 1 px stripe every 8 px, with nothing in the key having moved yet.<br><br>**The input need not have settled yet.** Alignments counts the debounce window ahead of its per-base bin, where the bin the data was fetched under has not moved and the clear is inevitable rather than committed. That is the half of the window an export lands in, since a reader zooms and then reaches for the menu. What may NOT go in is a change that could still be taken back: this fails hung, not stale.<br><br>So state the live-vs-settled half as a **value** compare and leave key strings alone. The settled half — the stamp a fetch committed under against the key a fetch now would use — is the foundation's already, through the `isCacheValid` term in `dataCurrent`, and an override restating it buys nothing: a second derivation of the key's vocabulary reads `"16\|fine"` against a live `"16"` the day the key grows an axis, latches this true, and every export of the display then waits out `awaitSvgReady`'s backstop instead of failing.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-datasuperseded) |
| <span id="getter-renderblocks">**renderBlocks**</span><br><code>RenderBlock[]</code> | <span data-pagefind-ignore>Shared cached view for every LGV-based GPU display. A single displayedRegion may produce multiple render blocks (shared GPU buffer, different scissor clips on screen). Plugins that want to suppress rendering in certain states (e.g. no domain yet) can override this getter to return [] — the autorun lifecycle will then issue an empty-blocks render that clears the canvas.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-renderblocks) |
| <span id="getter-fetchinputs">**fetchInputs**</span><br><code>FetchInputs</code> | <span data-pagefind-ignore>What a fetch issued right now would stamp on a region: the settings tier (`rpcProps()` and the adapter config) and the zoom tier (the display's `zoomFetchArgs()` object, or its `zoomFetchKey` string where it has not been converted). `fetchRegions` captures it before the RPC goes out and stamps it beside the loaded region; `isCacheValid` compares against it.<br><br>A **value**, not a string. The inputs already exist as the object the display sends the worker, so a second serialized spelling of them is one more thing to keep in step — and `JSON.stringify`, which was that spelling, cannot tell an `undefined`-valued field from an absent one.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-fetchinputs) |
| <span id="getter-settingsfetchinputs">**settingsFetchInputs**</span><br><code>unknown</code> | <span data-pagefind-ignore>The settings tier alone, which `staleSettingsDrawn` compares: the scrim goes up on a settings or adapter change and stays down on a zoom.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-settingsfetchinputs) |
| <span id="getter-regionpayloads">**regionPayloads**</span><br><code>ReadonlyMap&lt;number, unknown&gt;</code> | <span data-pagefind-ignore>The store's payloads, keyed by `displayedRegionIndex`. A display narrows this once — `get rpcDataMap() { return self.regionPayloads as ReadonlyMap<number, MyResult> }` — and every reader it already had goes on reading a map.<br><br>MST makes a `.views()` getter a computed, so the Map is built once per store change and handed back by reference after that — which is what keeps `installUpload`'s diff a reference compare per key and a frame that changed no data free of it. **While something observes it**: MobX suspends an unobserved computed and rebuilds on every read, so a display whose only reader is a pointer handler needs the keep-alive canvas and Manhattan both install (display-kit/CLAUDE.md §"A hit test's index needs an observer"). The render lifecycle's upload autorun is that reader for every display that draws.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-regionpayloads) |
| <span id="getter-hasregiondata">**hasRegionData**</span><br><code>boolean</code> | <span data-pagefind-ignore>A fetch has landed: at least one region's payload is in the store. The render callback's first-paint gate reads this, so an empty frame before any data cannot flip `canvasDrawn`; an empty but loaded region counts, and paints its empty frame.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-hasregiondata) |
| <span id="getter-stalesettingsdrawn">**staleSettingsDrawn**</span><br><code>boolean</code> | <span data-pagefind-ignore>A visible block's held data was fetched under a settings or adapter key that has since moved: drawn, and wrong for the current settings, until the refetch `isCacheValid` already owes lands. The loading scrim's third staleness term, beside spatial coverage and `dataSuperseded` — the one that used to come from `SettingsInvalidate` emptying the coverage map, and the reason it no longer has to.<br><br>False on a zoom by construction: `LoadedRegion.settingsKey` is the key minus its zoom axis, so a moved `zoomFetchKey` raises no scrim. That is the whole distance from the fold REJECTED_IDEAS.md "Folding content staleness into `displayPhase`" declines, which compared the whole key and put the overlay 250 ms into every zoom.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-stalesettingsdrawn) |
| <span id="getter-datacurrent">**dataCurrent**</span><br><code>boolean</code> | <span data-pagefind-ignore>This family's answer to the shared freshness question every display foundation must answer (`dataCurrent`): the held data corresponds to what is on screen right now. Four terms — spatial coverage of every visible block, `loadedRegions.size` to rule out the vacuously-true empty viewport, `isCacheValid` per block, and the display's own `dataSuperseded`. Regions stream in one at a time, so this (not "the first datum arrived") is what keeps a multi-region/whole-genome export complete.<br><br>**`isCacheValid` belongs here and not in the scrim.** Coverage answers "is the data here", never "is it what a fetch now would bring back", so a zoom that moves `fetchInputs` leaves every held region covered and stale at once — and an export sampling `svgReady` across that window painted bins the worker computed for the previous zoom. `displayPhase` takes `dataSuperseded` but NOT this term: folding a moved `fetchInputs` into the phase raises the loading scrim into every zoom, which is the trade REJECTED_IDEAS.md "Folding content staleness into `displayPhase`" turned down and this does not take.<br><br>The term cannot latch, and the reason is structural rather than a case list: a block reaches `fetchNeeded` unless `planRegionFetch` finds it ungated, covered AND cache-valid, and it reads that last term tracked. The `&&` short-circuits ahead of it drop its observables only where the block is fetched anyway, so the key move that closes this gate is the same read, in the same dependency set, that wakes the refetch reopening it.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-datacurrent) |
| <span id="getter-loadedassembly">**loadedAssembly**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { error: unknown; loadingP: Promis…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { error: unknown; loadingP: Promise&lt;…&gt; &#124; undefined; ... 10 more ...; refNameMismatches: Map&lt;…&gt;; } &amp; ... 13 more ... &amp; IStateTreeNode&lt;...&gt;) &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>The assembly the data in hand came from, once it can answer about refNames — `undefined` before that.<br><br>Off the first LOADED region rather than the view's displayed ones, which is the distinction that makes it belong here: a display holding fetched data is asking about the assembly THAT data is on, and the view's regions can already have moved on.<br><br>The `initialized` gate is why this returns the assembly rather than its name. `getCanonicalRefName2` and `refNameToIndex` answer WRONGLY rather than throwing before the aliases land — identity, and a miss — so a caller that skips the gate gets a plausible answer and no signal. Handing back `undefined` until it can answer is what makes the caller write its fallback.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-loadedassembly) |
| <span id="getter-phaseviewportcurrent">**phaseViewportCurrent**</span><br><code>boolean</code> | <span data-pagefind-ignore>The loading scrim's staleness argument: what is drawn answers for what is on screen. Spatial coverage, `dataSuperseded` and `staleSettingsDrawn`; NOT `isCacheValid`, which is `dataCurrent`'s and would scrim every zoom (REJECTED_IDEAS.md "Folding content staleness into `displayPhase`"). `displayPhase` reads it, and so does a stand-in phase (`coarseTierDisplayPhase`) — one predicate, so a term added here reaches both.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-phaseviewportcurrent) |
| <span id="getter-svgready">**svgReady**</span><br><code>boolean</code> | <span data-pagefind-ignore>true once an off-screen (SVG) export can safely read this display's data. Policy single-sourced in `computeSvgReady`; this family supplies only the freshness half, which `foundationSvgReady` reads as `dataCurrent` or the vacuous currency of `viewportEmpty`. Off-screen renderers gate on it via `awaitSvgReady(model)` instead of inlining the condition.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-svgready) |
| <span id="getter-paintinert">**paintInert**</span><br><code>boolean</code> | <span data-pagefind-ignore>Fills `RenderLifecycleMixin`'s `paintInert` hook — see there for why a failed fetch has to read as finished to the consumers outside the display, and `foundationPaintInert` for the second such state and why both fetch families answer it through one function. Overridable, as the hook is: a display with a third inert state of its own says so here.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-paintinert) |
| <span id="getter-paintsuperseded">**paintSuperseded**</span><br><code>boolean</code> | <span data-pagefind-ignore>Fills `RenderLifecycleMixin`'s hook with `staleSettingsDrawn`, so `painted` — and `data-display-drawn` through it — reads pending over a canvas painted under the previous settings until the refetch lands. `clearAllRpcData` used to reset `canvasDrawn` for the same effect; the hook says it without blanking anything.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-paintsuperseded) |
| <span id="getter-displayphase">**displayPhase**</span><br><code>DisplayPhase</code> | <span data-pagefind-ignore>The display's mutually-exclusive visual state, mapped in `foundationDisplayPhase` — every foundation calls it and supplies only its staleness argument, so a term added to `computeLoadingTerm` reaches all three without being wired three times.<br><br>This family's argument is `phaseViewportCurrent`: spatial coverage AND `dataSuperseded` (data a settled fetch-input change is drawing wrong right now — alignments zooming perBaseLetter from 16 bp/px to 1 stays inside the loaded region and reported `ready` over a wall drawn as a 1 px stripe every 8 px) AND `staleSettingsDrawn`.<br><br>A thunk, so a suppressed or already-loading display doesn't subscribe to viewport churn.<br><br>A subclass customizes this through `fetchInert` (FetchMixin), never by overriding the getter — see that hook.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-displayphase) |
| <span id="getter-gateenabled">**gateEnabled**</span><br><code>boolean</code> | <span data-pagefind-ignore>The opt-in. Overridden with a literal `true` by gated displays, and `check-gated-adapter-budgets` insists on a literal: this mixin returns early on it in an autorun and in `commitFetchBytes`.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateenabled) |
| <span id="getter-bytegateadapterconfig">**byteGateAdapterConfig**</span><br><code>Record&lt;string, unknown&gt;</code> | <span data-pagefind-ignore>The adapter config the gate measures — the one at `byteGateAdapterPath`. Overridable for a display whose adapter config is synthesized rather than read off the track.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-bytegateadapterconfig) |
| <span id="getter-configuredfetchsizelimit">**configuredFetchSizeLimit**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>The display's `fetchSizeLimit` slot, from `regionTooLargeConfigSchemaFields`. `number \| undefined`, because `getConf` answers `undefined` for a slot a composing display's schema never declared and typing it `number` hid the whole failure — `resolveByteLimit` falls back closed, and says why.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-configuredfetchsizelimit) |
| <span id="getter-densitytoolarge">**densityTooLarge**</span><br><code>boolean</code> | <span data-pagefind-ignore>The density axis's verdict, and the whole of that axis's opt-in: `CanvasFeatureGateMixin` overrides it beside the measurement that fills it, and a byte-only display leaves it false.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-densitytoolarge) |
| <span id="getter-bytegateadapterpath">**byteGateAdapterPath**</span><br><code>string[]</code> | <span data-pagefind-ignore>Where on the track config the measured adapter sits. A tiered display overrides this one hook (MAF: `['adapter', 'summaryAdapter']` while `showSummary`), and both the measurement and the budget follow it.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-bytegateadapterpath) |
| <span id="getter-adapterfetchsizelimit">**adapterFetchSizeLimit**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>The measured adapter's own `fetchSizeLimit` slot, read off the live track config rather than the `adapterConfig` snapshot, which omits slots at their default.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-adapterfetchsizelimit) |
| <span id="getter-configforceload">**configForceLoad**</span><br><code>boolean</code> | <span data-pagefind-ignore>The declarative `forceLoad` slot.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-configforceload) |
| <span id="getter-gateviewport">**gateViewport**</span><br><code>GateViewport &#124; undefined</code> | <span data-pagefind-ignore>What a measurement taken now would be about: the span on screen, and a key for the stretch of genome it covers **and the settings it would be taken under**. Undefined until the view is measured, and the mixin's only read of the view. Captured before the fetch's round trip, never at commit, so the stamp names the settings the worker actually counted under.<br><br>The settings term is `rpcPropsCacheKey`, the axis both families already invalidate data on. It belongs in the measurement because the worker's density probe counts ADMITTED features (`densityGate`'s `admit`), so a filter admitting almost nothing is a different measurement of the same viewport — and while staleness was viewport-only, the main thread never went back to ask. The byte axis is an index read no `rpcProps` field can move; the rule is one rule rather than one per axis.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateviewport) |
| <span id="getter-bytegateadapterkey">**byteGateAdapterKey**</span><br><code>string</code> | <span data-pagefind-ignore>Which tier the estimate is about, as a comparable string.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-bytegateadapterkey) |
| <span id="getter-aboveforceloadfloor">**aboveForceLoadFloor**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the span on screen is at or above `AUTO_FORCE_LOAD_BP`, the one comparison against that constant. False on an unmeasured view.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-aboveforceloadfloor) |
| <span id="getter-gateexempt">**gateExempt**</span><br><code>boolean</code> | <span data-pagefind-ignore>Nothing may gate on either axis: the `forceLoad` slot or the button.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateexempt) |
| <span id="getter-estimatedfetchbytes">**estimatedFetchBytes**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>The stored estimate's bytes; undefined when nothing has been measured.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-estimatedfetchbytes) |
| <span id="getter-gatemeasurementstale">**gateMeasurementStale**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the last measurement still describes what a fetch issued now would ask: the viewport on screen, under the settings on screen. True before any measurement. The triple's third term, the adapter tier, is not here — a tier swap drops the measurement outright (`ClearByteEstimateOnNavOrTierSwap`) rather than marking it stale.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gatemeasurementstale) |
| <span id="getter-gatebytelimit">**gateByteLimit**</span><br><code>number</code> | <span data-pagefind-ignore>The byte budget: the adapter's limit, else the display's, doubled below `AUTO_FORCE_LOAD_BP`. Read only through `resolvedByteLimit()`.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gatebytelimit) |
| <span id="getter-gateactive">**gateActive**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the gate may act right now, on any axis: opted in, not exempt, view measured. The view is read last, so an ungated display never touches it.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateactive) |
| <span id="getter-densitygateactive">**densityGateActive**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the density axis may act: `gateActive`, and the span is above the floor — the one axis the floor applies to. Whether it has anything to say is `densityTooLarge`.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-densitygateactive) |
| <span id="getter-toolargestatus">**tooLargeStatus**</span><br><code>RegionTooLargeStatus</code> | <span data-pagefind-ignore>The verdict and its banner text, from the stored estimate against `resolvedByteLimit()` and the density axis when it may act.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-toolargestatus) |
| <span id="getter-regiontoolarge">**regionTooLarge**</span><br><code>boolean</code> |  | [RegionTooLargeMixin](../regiontoolargemixin#getter-regiontoolarge) |
| <span id="getter-regiontoolargereason">**regionTooLargeReason**</span><br><code>string</code> | <span data-pagefind-ignore>Banner text for the axis that tripped; empty when not too large.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-regiontoolargereason) |
| <span id="getter-zoomcanreleasegate">**zoomCanReleaseGate**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether "zoom in to see features" is honest advice. Density always releases on zoom; bytes only if the last zoom-in moved the estimate.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-zoomcanreleasegate) |
| <span id="getter-gateskipsmeasuredviewport">**gateSkipsMeasuredViewport**</span><br><code>boolean</code> | <span data-pagefind-ignore>The skip both fetch skeletons apply: the banner is up and its measurement already describes the viewport on screen.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateskipsmeasuredviewport) |
| <span id="getter-painted">**painted**</span><br><code>boolean</code> | <span data-pagefind-ignore>**The first-paint answer every consumer outside the display should read**, `canvasDrawn` being only the raw flag: a display that is deliberately not painting a canvas has finished, and saying otherwise is a lie that never resolves.<br><br>The two `rendersCanvas: false` states each had three of their four consumers wired by hand — the loading scrim (`rendersCanvas` / `fetchInert`) and the SVG export (`fetchInert`) — while the fourth, `data-display-drawn`, went on publishing `"false"` forever off the raw flag. That attribute is what `PENDING_DISPLAYS` (`@jbrowse/browser-test-utils`) selects on, so a zoomed-out reference sequence track made every `waitForDisplaysDone` on the page burn its full timeout — silently, since that wait swallows its own. Same shape as `fetchInert` on the comparative side: the reader you forget is the one outside the display, so the display has to publish one name for it.<br><br>`paintInert` is the third term and the same argument once more, for the state where a display *would* paint a canvas and never gets to — a fetch that failed before first paint. `paintSuperseded` is the fourth, and the one that subtracts: a canvas painted from data a settings change has made wrong is drawn and not finished. See both hooks.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#getter-painted) |
| <span id="getter-isloading">**isLoading**</span><br><code>boolean</code> | <span data-pagefind-ignore>true while a fetch is active</span> | [FetchMixin](../fetchmixin#getter-isloading) |
| <span id="getter-isloadingorcanceled">**isLoadingOrCanceled**</span><br><code>boolean</code> | <span data-pagefind-ignore>`isLoading` widened to cover a user-canceled load. **This, not `isLoading`, is what a `displayPhase` loading term wants.** `cancelFetchByUser` clears the stop token synchronously, so `isLoading` goes false the instant the user clicks Cancel — and the loading overlay that unmounts on it is carrying the Retry button, which is the only way back: the state is deliberately durable, so no autorun restarts the fetch on its own. A bare `isLoading` therefore reads as `ready` over a display that is stopped, empty and offering nothing.<br><br>Arc read `isLoading` directly and had exactly that hole. It is a getter here so no family has to remember the second term.</span> | [FetchMixin](../fetchmixin#getter-isloadingorcanceled) |
| <span id="getter-fetchinert">**fetchInert**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false): the states where this display deliberately never fetches, so it holds no data and none is coming. Sequence sets it past base resolution ("Zoom in to see sequence"); LD sets it with the triangle toggled off.<br><br>**One hook, three readers**, and that is the whole point — a display that grows such a state has one thing to say rather than three, and the reader it would have forgotten is always the one outside itself:<br><br>- the loading scrim (`computeLoadingTerm`), which otherwise parks over the placeholder, permanently once a cancel has been clicked; - the SVG export (`computeSvgReady`'s `extraTerminal`), whose `awaitSvgReady` is an unbounded `when`, so one such display hangs the whole view's export; - the retry contract check (`makeRetryContractCheck`), which would otherwise report a dead Retry on a display correctly declining to load anything.<br><br>It was three hooks — `loadingSuppressed`, `svgReadyExtraTerminal` on each of the two foundations, and `fetchInert` on the comparative family, which had already collapsed them. Both LGV displays that override it returned one expression for all three, and one of the three was hard-coded `false` on the global family for a while, which is how LD came to be able to express only half its own state. One declaration for all three fetch families since the comparative one composed this mixin (ADR-105), so the retry check reads one field everywhere. ADR-082.<br><br>A hook rather than a `displayPhase` override, because overriding the getter means restating the whole loading condition — which is how sequence came to hold a verbatim copy of the other terms, one `git blame` away from silently missing the next one added.<br><br>It lives **here** because this is the one mixin all three display foundations compose. Same argument, one level down, that put `rendersCanvas` on `RenderLifecycleMixin` beside `canvasDrawn`.</span> | [FetchMixin](../fetchmixin#getter-fetchinert) |
| <span id="getter-awaitingprerequisite">**awaitingPrerequisite**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false), read only by the retry contract check (`makeRetryContractCheck`): "this run declined because a prerequisite fetch in another autorun has not landed, and its arrival wakes this one again". It **defers** the retry verdict to that later run rather than waiving it, so a display cannot spend its retry on a decline it called preliminary.<br><br>Two displays say it, one per fetch foundation, which is why it lives beside `fetchInert` rather than on either: HiC's contacts fetch declines until `CoreGetInfo` lands, and `MultiSampleVariantBaseModel`'s `fetchNeeded` declines until `sourcesBase` does. Both have a `reload()` that wakes the prerequisite's autorun as well as their own.<br><br>**It has to be strictly narrower than the gate it explains.** One that restates the gate's negation makes every decline a deferred one, so no run is ever judged and the display has silently opted out — an exemption by another name. HiC is in that shape deliberately, because its gate and its prerequisite are one condition; what covers its retry instead is `LinearHicDisplay/infoFetchFailure.test.ts`.<br><br>Not for a display deliberately not fetching at all — that is `fetchInert` above, which the loading scrim and the export read too.</span> | [FetchMixin](../fetchmixin#getter-awaitingprerequisite) |
| <span id="getter-awaitingdependentdata">**awaitingDependentData**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false), read by `computeLoadingTerm`: a load this display depends on beyond its primary fetch has not landed for the first time, so the frame the primary fetch calls current is still missing something. Multi-way synteny says it until its lane genes and lane links first arrive, so an export or a capture never lands between the ortholog fetch and the gene models that fill the lanes.<br><br>A hook rather than a `displayPhase` override, for the reason `fetchInert` is one: that display carried the override, restating the foundation's two arguments verbatim to append one term, which is the shape that silently misses the next term added.<br><br>Not `dataSuperseded`, which holds the export through every later refetch too: a display saying this wants the scrim on the first landing only, since later lane fetches redraw over lanes already on screen.</span> | [FetchMixin](../fetchmixin#getter-awaitingdependentdata) |
| <span id="getter-rpcpropscachekey">**rpcPropsCacheKey**</span><br><code>string</code> | <span data-pagefind-ignore>The RPC cache key both fetch foundations invalidate on: this display's `rpcProps()` payload serialized to a string. `serializeRpcProps` owns the why, including the silently-dead-axis corollary.<br><br>Here, beside the two hooks above, for the same reason they are: it describes the display, and every foundation composes this mixin. The per-region family watches it from `SettingsInvalidate` and the global one from its fetch autorun's trigger list — one getter and one name, so the two cannot come to invalidate on different axes. The global side built its own local `computed` over the same function until 2026-08, which was the same value under a second spelling.</span> | [FetchMixin](../fetchmixin#getter-rpcpropscachekey) |
| <span id="getter-adapterconfigkey">**adapterConfigKey**</span><br><code>string</code> | <span data-pagefind-ignore>The adapter axis of the same key, watched by the same two readers as `rpcPropsCacheKey`: `SettingsInvalidate` per-region and the global family's `currentFetchKey`. A track re-pointed in the config editor is a different fetch, and until 2026-09 only the comparative family said so.</span> | [FetchMixin](../fetchmixin#getter-adapterconfigkey) |
| <span id="getter-visiblefeaturedensityperpx">**visibleFeatureDensityPerPx**</span><br><code>number</code> | <span data-pagefind-ignore>Density at the debounced `coarseBpPerPx`, so the verdict shares the layout cadence.</span> | [CanvasFeatureGateMixin](../canvasfeaturegatemixin#getter-visiblefeaturedensityperpx) |
| <span id="getter-maxfeaturedensity">**maxFeatureDensity**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>Undefined when the axis may not act.</span> | [CanvasFeatureGateMixin](../canvasfeaturegatemixin#getter-maxfeaturedensity) |
| <span id="getter-coarsetierstandsin">**coarseTierStandsIn**</span><br><code>boolean</code> |  | [DensityBandMixin](../densitybandmixin#getter-coarsetierstandsin) |
| <span id="getter-densitybandlayer">**densityBandLayer**</span><br><code>DensityBandLayer</code> |  | [DensityBandMixin](../densitybandmixin#getter-densitybandlayer) |
| <span id="getter-densityhover">**densityHover**</span><br><code>DensityHover &#124; undefined</code> |  | [DensityBandMixin](../densitybandmixin#getter-densityhover) |
| <span id="getter-densitypeakreadout">**densityPeakReadout**</span><br><code>string</code> | <span data-pagefind-ignore>The band's line of text with no cursor over it, which is what the SVG export writes.</span> | [DensityBandMixin](../densitybandmixin#getter-densitypeakreadout) |
| <span id="getter-densityreadout">**densityReadout**</span><br><code>string</code> | <span data-pagefind-ignore>Blank until the first read lands, so the scrim is not captioned "no density data" for a read still in flight.</span> | [DensityBandMixin](../densitybandmixin#getter-densityreadout) |
| <span id="getter-coarseadapterslot">**coarseAdapterSlot**</span><br><code>string</code> |  | [DensityTierMixin](../densitytiermixin#getter-coarseadapterslot) |
| <span id="getter-densitytiermode">**densityTierMode**</span><br><code>"auto" &#124; "density" &#124; "features"</code> | <span data-pagefind-ignore>The `densityTier` slot's value.</span> | [DensityTierMixin](../densitytiermixin#getter-densitytiermode) |
| <span id="getter-densitytierthresholdbpperpx">**densityTierThresholdBpPerPx**</span><br><code>number</code> |  | [DensityTierMixin](../densitytiermixin#getter-densitytierthresholdbpperpx) |
| <span id="getter-coarsetiermode">**coarseTierMode**</span><br><code>CoarseTierMode</code> |  | [DensityTierMixin](../densitytiermixin#getter-coarsetiermode) |
| <span id="getter-coarsetierpastthreshold">**coarseTierPastThreshold**</span><br><code>boolean</code> | <span data-pagefind-ignore>`auto` also swaps from the `densityTierBpPerPx` slot outward, where a track asks for the band before the region is too large to fetch.</span> | [DensityTierMixin](../densitytiermixin#getter-coarsetierpastthreshold) |
| <span id="getter-coarsereadkey">**coarseReadKey**</span><br><code>string</code> | <span data-pagefind-ignore>The bins are read at the view's bp/px, so a real zoom re-reads at the level the sidecar keeps for it and a small one reuses what is held.</span> | [DensityTierMixin](../densitytiermixin#getter-coarsereadkey) |
| <span id="getter-coarsetiergated">**coarseTierGated**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false): the coarse read is a feature download the byte gate has to measure. The gate then measures the coarse adapter while the tier is up, its refusal is the banner, the detail fetch stands down outright since the coarse read is the measurement pass, and the swap is by threshold alone — the verdict is about whichever tier is up, so it cannot also pick the tier. A read bounded by construction (bins per screen pixel) leaves this off.</span> | [CoarseTierMixin](../coarsetiermixin#getter-coarsetiergated) |
| <span id="getter-coarsesourceconfig">**coarseSourceConfig**</span><br><code>unknown</code> | <span data-pagefind-ignore>The coarse source's config, read off the live track config so a re-pointed adapter follows.</span> | [CoarseTierMixin](../coarsetiermixin#getter-coarsesourceconfig) |
| <span id="getter-hascoarsesource">**hasCoarseSource**</span><br><code>boolean</code> |  | [CoarseTierMixin](../coarsetiermixin#getter-hascoarsesource) |
| <span id="getter-coarsetieractive">**coarseTierActive**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the coarse tier stands in for the detail right now.</span> | [CoarseTierMixin](../coarsetiermixin#getter-coarsetieractive) |
| <span id="getter-gatemeasurescoarse">**gateMeasuresCoarse**</span><br><code>boolean</code> | <span data-pagefind-ignore>The byte gate is measuring the coarse read rather than the detail fetch, so its verdict is about the tier on screen.</span> | [CoarseTierMixin](../coarsetiermixin#getter-gatemeasurescoarse) |
| <span id="getter-gaterefusesdetail">**gateRefusesDetail**</span><br><code>boolean</code> | <span data-pagefind-ignore>The gate's refusal is about the detail fetch, so that fetch owes the re-measure the gate releases through.</span> | [CoarseTierMixin](../coarsetiermixin#getter-gaterefusesdetail) |
| <span id="getter-coarsetierissuekey">**coarseTierIssueKey**</span><br><code>string</code> | <span data-pagefind-ignore>The whole key a read is held under: the coarse adapter and the display's own term.</span> | [CoarseTierMixin](../coarsetiermixin#getter-coarsetierissuekey) |
| <span id="getter-drawswhentoolarge">**drawsWhenTooLarge**</span><br><code>boolean</code> | <span data-pagefind-ignore>`renderDisplaySvg`'s hook: the export paints the tier in place of the too-large note, the same swap the chrome makes on screen — unless the note is about the coarse read itself.</span> | [CoarseTierMixin](../coarsetiermixin#getter-drawswhentoolarge) |

## Methods

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="method-contextmenuitems">**contextMenuItems**</span><br><code>() =&gt; MenuItem[]</code> | The shared feature menu plus, on a breakend record, the row that opens the split view for it. Super-captured rather than replaced, so every generic row (details, zoom to, highlight, show/hide, copy) stays where a reader already learned it. | LinearVariantDisplay |
| <span id="method-colorbysubmenuitems">**colorBySubMenuItems**</span><br><code>() =&gt; MenuItem[]</code> |  | LinearVariantDisplay |
| <span id="method-configuredfilters">**configuredFilters**</span><br><code>() =&gt; string[]</code> | <span data-pagefind-ignore>What the `jexlFilters` config slot alone declares, `jexl:`-prefixed; in its own block so `featureFilterCount`, which subclasses super-capture and call unbound, reaches it through `self`.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-configuredfilters) |
| <span id="method-activefilters">**activeFilters**</span><br><code>() =&gt; string[]</code> | <span data-pagefind-ignore>The filters actually applied, as `jexl:`-prefixed expressions — see `activeJexlFilters`, which is the shared two-tier resolution.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-activefilters) |
| <span id="method-rpcprops">**rpcProps**</span><br><code>() =&gt; {…}</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-rpcprops) |
| <span id="method-gpuprops">**gpuProps**</span><br><code>() =&gt; { colorTable: Uint32Array&lt;ArrayBuffer&gt;; }</code> | <span data-pagefind-ignore>What the main-thread encode needs beyond a region's own data: the packed color for every theme class the worker emitted, off `session.palette` so a theme toggle re-encodes what is loaded instead of refetching it.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-gpuprops) |
| <span id="method-fitlayoutat">**fitLayoutAt**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(memo: (rpcDataMap: ReadonlyMap&lt;number, LayoutRegionData&gt;, inpu…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(memo: (rpcDataMap: ReadonlyMap&lt;number, LayoutRegionData&gt;, inputs: LayoutInputs) =&gt; Map&lt;number, FeatureDataResult&gt;, reserved: LabelReservation) =&gt; Map&lt;...&gt;</code></pre></dialog></span> | <span data-pagefind-ignore>One fit-escalation candidate: the stack packed with the given label reservation, via that config's own memo instance so each keeps stable references across renders.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-fitlayoutat) |
| <span id="method-decimatedlayoutinputs">**decimatedLayoutInputs**</span><br><code>(labelRoomFactor: number) =&gt; LayoutInputs</code> | <span data-pagefind-ignore>Layout inputs for the `decimated` rung at one whitespace factor.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-decimatedlayoutinputs) |
| <span id="method-solvelabelroomfactor">**solveLabelRoomFactor**</span><br><code>(trackHeight: number) =&gt; number &#124; undefined</code> | <span data-pagefind-ignore>The whitespace factor the `decimated` rung commits at: the smallest one whose packed stack fits `trackHeight` (smallest = most names kept), or undefined when even the most aggressive decimation overflows.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-solvelabelroomfactor) |
| <span id="method-morphoffsetfor">**morphOffsetFor**</span><br><code>(featureId: string) =&gt; number</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-morphoffsetfor) |
| <span id="method-searchfeaturebyid">**searchFeatureByID**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(id: string) =&gt; readonly [number, number, number, number] &#124; und…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(id: string) =&gt; readonly [number, number, number, number] &#124; undefined</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-searchfeaturebyid) |
| <span id="method-rendersvg">**renderSvg**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(opts?: ExportSvgDisplayOptions &#124; undefined) =&gt; Promise&lt;ReactEl…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(opts?: ExportSvgDisplayOptions &#124; undefined) =&gt; Promise&lt;ReactElement&lt;unknown, string &#124; JSXElementConstructor&lt;any&gt;&gt; &#124; Iterable&lt;...&gt; &#124; AwaitedReactNode&gt;</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-rendersvg) |
| <span id="method-featurenarrowings">**featureNarrowings**</span><br><code>() =&gt; Reversibles</code> | <span data-pagefind-ignore>Everything this display is doing to narrow what the user sees, each declared once, so the "Filter by... (n)" count, its undo rows and "Clear all filters" cannot disagree; a method, not a getter, because a getter cannot be super-captured.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-featurenarrowings) |
| <span id="method-featuremarks">**featureMarks**</span><br><code>() =&gt; Reversibles</code> | <span data-pagefind-ignore>Reversible state that MARKS features rather than hiding them — the highlight boxes and the pins holding features at the top of the layout.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-featuremarks) |
| <span id="method-featurefiltercount">**featureFilterCount**</span><br><code>() =&gt; number</code> | <span data-pagefind-ignore>How many independent things are narrowing what the display shows, derived so it cannot drift from the list it counts.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-featurefiltercount) |
| <span id="method-showsubmenucheckboxitems">**showSubmenuCheckboxItems**</span><br><code>() =&gt; MenuItem[]</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-showsubmenucheckboxitems) |
| <span id="method-showsubmenuradiogroups">**showSubmenuRadioGroups**</span><br><code>() =&gt; MenuItem[]</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-showsubmenuradiogroups) |
| <span id="method-showsubmenumenuitems">**showSubmenuMenuItems**</span><br><code>() =&gt; MenuItem[]</code> | <span data-pagefind-ignore>Flattened "Show..." submenu: all checkbox toggles first, then the radio groups (each under its own subHeader).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-showsubmenumenuitems) |
| <span id="method-colormenuitems">**colorMenuItems**</span><br><code>() =&gt; MenuItem[]</code> | <span data-pagefind-ignore>Color-related track menu entries: a single "Color by..." entry whose "Solid color..." choice opens the solid+UTR color picker.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-colormenuitems) |
| <span id="method-featureheightmenuitems">**featureHeightMenuItems**</span><br><code>() =&gt; MenuItem[]</code> | <span data-pagefind-ignore>One "Feature height" menu with two independent radio groups: the size presets and, under a "Track sizing" subheader, how the track responds when there are more features than fit.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-featureheightmenuitems) |
| <span id="method-trackmenuitems">**trackMenuItems**</span><br><code>() =&gt; MenuItem[]</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#method-trackmenuitems) |
| <span id="method-renderingprops">**renderingProps**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>() =&gt; { displayModel: ModelInstanceTypeProps&lt;{ id: IOptionalITy…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>() =&gt; { displayModel: ModelInstanceTypeProps&lt;{ id: IOptionalIType&lt;…&gt;; type: ISimpleType&lt;string&gt;; }&gt; &amp; { ...; } &amp; { ...; } &amp; { ...; } &amp; IStateTreeNode&lt;...&gt;; }</code></pre></dialog></span> | <span data-pagefind-ignore>props passed to the renderer's React "Rendering" component. these are client-side only and never sent to the worker. includes displayModel and callbacks</span> | [BaseDisplay](../basedisplay#method-renderingprops) |
| <span id="method-regionhasdata">**regionHasData**</span><br><code>(displayedRegionIndex: number) =&gt; boolean</code> | <span data-pagefind-ignore>Overridable hook, and the converted form of `zoomFetchKey` above: the zoom-derived worker arguments as an **object**, which the display spreads into its own RPC call and the foundation stamps beside every region the call loads. A display that fills this leaves `zoomFetchKey` alone; the foundation prefers this when it exists.<br><br>One declaration instead of two is the whole of it. The key and the argument are the same fact, and writing them apart is what lets them disagree — a `zoomFetchKey` that reads no observable is memoized for the display's life while the call goes on sending a live value, and a key naming a threshold while the call sends the mode behind it says stale on a crossing the worker never sees.<br><br>Looked up dynamically rather than declared, so a display keeps its narrow return type through MST's `.views()` chain — the same reason `rpcProps` is not declared here. Overridable hook: whether the display can actually draw what this region is marked loaded over.<br><br>The default answers off the store — an entry a fetch committed carries what it stored — so "marked loaded with nothing behind it" is a state only a hand-written `setLoadedRegion` reaches. It used to be `true`, and the base canvas display overrode it with `rpcDataMap.has(idx)` to get this answer back.<br><br>What survives an override is the question the store cannot answer: **which of several held payloads answers**. MAF caches a summary tier and a detail tier side by side under one `displayedRegionIndex`, so crossing the threshold inside an already-loaded region changes which map has to answer — something neither the coverage bounds nor one payload slot can see. A key would refetch the summary on every zoom back out, since both tiers are still held. The multi-row display's override survives for its second half, the auto-partition reconciliation (`regionHasPinnedData`).<br><br>**What the old fail-open default was protecting is now explicit.** A byte-gate refusal never commits at all, so it is unreachable either way. The case that mattered is sequence's legitimately-empty region, which stamped without storing and which a store-derived default would have refetched forever — and a commit is a payload now, the empty record, so it stays terminal.<br><br>A view, not an action, for the reason `zoomFetchKey` is a getter.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#method-regionhasdata) |
| <span id="method-iscachevalid">**isCacheValid**</span><br><code>(displayedRegionIndex: number) =&gt; boolean</code> | <span data-pagefind-ignore>Whether the data held for a region still answers the current view. Not a hook a display fills: a display states its rule as `zoomFetchArgs` (the zoom-derived arguments a fetch now would send) and `regionHasData` (did the last one store anything), and this compares the whole input set against the one the region was fetched under.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#method-iscachevalid) |
| <span id="method-resolvedbytelimit">**resolvedByteLimit**</span><br><code>() =&gt; number &#124; undefined</code> | <span data-pagefind-ignore>The budget the worker enforces and the banner compares against — the one spelling of that pair. Undefined when the gate may not act.</span> | [RegionTooLargeMixin](../regiontoolargemixin#method-resolvedbytelimit) |
| <span id="method-gatefetchstate">**gateFetchState**</span><br><code>() =&gt; GateFetchState</code> | <span data-pagefind-ignore>The gate as it stands for a fetch about to be issued. Calling it is the capture, which is why it is a method.</span> | [RegionTooLargeMixin](../regiontoolargemixin#method-gatefetchstate) |
| <span id="method-observedmaxdensity">**observedMaxDensity**</span><br><code>(bpPerPx: number) =&gt; number</code> |  | [CanvasFeatureGateMixin](../canvasfeaturegatemixin#method-observedmaxdensity) |

## Actions

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="action-openfilterdialog">**openFilterDialog**</span><br><code>() =&gt; void</code> |  | LinearVariantDisplay |
| <span id="action-beginymorph">**beginYMorph**</span><br><code>(fromTops: Map&lt;string, number&gt;, fromMaxY: number) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-beginymorph) |
| <span id="action-setmorphprogress">**setMorphProgress**</span><br><code>(t: number) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setmorphprogress) |
| <span id="action-endymorph">**endYMorph**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-endymorph) |
| <span id="action-setrpcdata">**setRpcData**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(displayedRegionIndex: number, data: FeatureDataResult, region:…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(displayedRegionIndex: number, data: FeatureDataResult, region: Region) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Stage a region as fetched — the store's raw write with this display's payload shape, so a test stands up a loaded display in one call.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setrpcdata) |
| <span id="action-prunedensitystatstovisible">**pruneDensityStatsToVisible**</span><br><code>(visibleDisplayedRegionIndices: Set&lt;number&gt;) =&gt; void</code> | <span data-pagefind-ignore>The gate's own measurements, which are keyed by region and are not fetch payloads, so the store's bound does not reach them.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-prunedensitystatstovisible) |
| <span id="action-startrenderingbackend">**startRenderingBackend**</span><br><code>(backend: CanvasFeatureRenderingBackend) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-startrenderingbackend) |
| <span id="action-togglepinnedfeature">**togglePinnedFeature**</span><br><code>(featureId: string) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-togglepinnedfeature) |
| <span id="action-clearpinnedfeatures">**clearPinnedFeatures**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearpinnedfeatures) |
| <span id="action-toggleexpandedgene">**toggleExpandedGene**</span><br><code>(featureId: string) =&gt; void</code> | <span data-pagefind-ignore>Open or re-collapse one gene's isoforms, from the badge on its own label.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-toggleexpandedgene) |
| <span id="action-clearexpandedgenes">**clearExpandedGenes**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Re-collapse every gene opened from a badge.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearexpandedgenes) |
| <span id="action-togglesolofeature">**toggleSoloFeature**</span><br><code>(featureId: string) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-togglesolofeature) |
| <span id="action-applysolo">**applySolo**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-applysolo) |
| <span id="action-solofeature">**soloFeature**</span><br><code>(featureId: string) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-solofeature) |
| <span id="action-clearsolo">**clearSolo**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearsolo) |
| <span id="action-hidefeature">**hideFeature**</span><br><code>(featureId: string) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-hidefeature) |
| <span id="action-showallhidden">**showAllHidden**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-showallhidden) |
| <span id="action-sethover">**setHover**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(featureId: string &#124; undefined, subfeatureId: string &#124; undefine…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(featureId: string &#124; undefined, subfeatureId: string &#124; undefined, tooltip: string[] &#124; undefined) =&gt; void</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-sethover) |
| <span id="action-clearhover">**clearHover**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearhover) |
| <span id="action-setfeaturehighlights">**setFeatureHighlights**</span><br><code>(highlights: FeatureHighlight[]) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setfeaturehighlights) |
| <span id="action-addfeaturehighlightforitem">**addFeatureHighlightForItem**</span><br><code>(target: HighlightTarget, refName: string) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-addfeaturehighlightforitem) |
| <span id="action-removefeaturehighlightsforid">**removeFeatureHighlightsForId**</span><br><code>(featureId: string) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-removefeaturehighlightsforid) |
| <span id="action-clearfeaturehighlights">**clearFeatureHighlights**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearfeaturehighlights) |
| <span id="action-opencontextmenu">**openContextMenu**</span><br><code>(info: FeatureContextMenuInfo) =&gt; void</code> | <span data-pagefind-ignore>Drops the hover first, so its tooltip does not sit under the menu; the highlight box stays on the target through `hoverBoxFeature`.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-opencontextmenu) |
| <span id="action-openfeaturedetails">**openFeatureDetails**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(fetch: () =&gt; Promise&lt;Feature &#124; undefined&gt;, parentFeature?: Par…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(fetch: () =&gt; Promise&lt;Feature &#124; undefined&gt;, parentFeature?: ParentFeatureSummary &#124; undefined) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Open the feature-details widget on what `fetch` resolves to, with the adapter's header metadata beside it; a lookup that resolves to nothing is reported as a miss.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-openfeaturedetails) |
| <span id="action-selectfeature">**selectFeature**</span><br><code>(feature: Feature) =&gt; void</code> | <span data-pagefind-ignore>Open the feature-details widget on a feature already in hand.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-selectfeature) |
| <span id="action-clearselection">**clearSelection**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearselection) |
| <span id="action-setshowlabels">**setShowLabels**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(value: "auto" &#124; "description" &#124; "name" &#124; "nameAndDescription"…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(value: "auto" &#124; "description" &#124; "name" &#124; "nameAndDescription" &#124; "none") =&gt; void</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setshowlabels) |
| <span id="action-setjexlfilters">**setJexlFilters**</span><br><code>(filters?: string[] &#124; undefined) =&gt; void</code> | <span data-pagefind-ignore>Sets the runtime filter override (already-`jexl:`-prefixed expressions).</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setjexlfilters) |
| <span id="action-setshowoutline">**setShowOutline**</span><br><code>(value: boolean) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setshowoutline) |
| <span id="action-setfeaturecolor">**setFeatureColor**</span><br><code>(color?: string &#124; undefined) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setfeaturecolor) |
| <span id="action-setutrcolor">**setUtrColor**</span><br><code>(color?: string &#124; undefined) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setutrcolor) |
| <span id="action-setsequencehoverposition">**setSequenceHoverPosition**</span><br><code>(pos: SequenceHoverPosition &#124; undefined) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setsequencehoverposition) |
| <span id="action-setdisplaymode">**setDisplayMode**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(value: "collapsed" &#124; "compact" &#124; "normal" &#124; "superCompact") =&gt;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(value: "collapsed" &#124; "compact" &#124; "normal" &#124; "superCompact") =&gt; void</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-setdisplaymode) |
| <span id="action-opensetcolordialog">**openSetColorDialog**</span><br><code>(showUtrColor?: any) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-opensetcolordialog) |
| <span id="action-opencolorbyattributedialog">**openColorByAttributeDialog**</span><br><code>() =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-opencolorbyattributedialog) |
| <span id="action-fetchfullfeature">**fetchFullFeature**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(featureId: string, displayedRegionIndex: number, opts?: { stop…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(featureId: string, displayedRegionIndex: number, opts?: { stopToken?: StopToken &#124; undefined; statusCallback?: StatusCallback &#124; undefined; }) =&gt; Promise&lt;SimpleFeature &#124; undefined&gt;</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-fetchfullfeature) |
| <span id="action-clearallfeaturefilters">**clearAllFeatureFilters**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Reverse every narrowing.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearallfeaturefilters) |
| <span id="action-selectfeaturebyid">**selectFeatureById**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(featureId: string, subfeatureInfo: SubfeatureInfo &#124; undefined,…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(featureId: string, subfeatureInfo: SubfeatureInfo &#124; undefined, displayedRegionIndex: number) =&gt; void</code></pre></dialog></span> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-selectfeaturebyid) |
| <span id="action-reload">**reload**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Clears the loaded regions and fetches straight away, rather than waiting out `FetchVisibleRegions`' 600ms debounce as the rest of the family does — Retry and Force load are both clicks, and this is the display the user is most often clicking on.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-reload) |
| <span id="action-fetchneeded">**fetchNeeded**</span><br><code>(needed: IndexedRegion[]) =&gt; void</code> |  | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-fetchneeded) |
| <span id="action-clearhoveredfeature">**clearHoveredFeature**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Fills `BaseDisplay`'s hover-clear hook, which the fetch foundation's reaction calls on every viewport change.</span> | [LinearCanvasBaseDisplay](../linearcanvasbasedisplay#action-clearhoveredfeature) |
| <span id="action-setstatusmessage">**setStatusMessage**</span><br><code>(status?: RpcStatus &#124; undefined) =&gt; void</code> |  | [BaseDisplay](../basedisplay#action-setstatusmessage) |
| <span id="action-seterror">**setError**</span><br><code>(error?: unknown) =&gt; void</code> |  | [BaseDisplay](../basedisplay#action-seterror) |
| <span id="action-applydisplaysettings">**applyDisplaySettings**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(settings: Record&lt;…&gt;, options?: { allowSetters?: boolean &#124; unde…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(settings: Record&lt;…&gt;, options?: { allowSetters?: boolean &#124; undefined; } &#124; undefined) =&gt; { applied: string[]; unapplied: string[]; failed: { key: string; error: string; }[]; }</code></pre></dialog></span> | <span data-pagefind-ignore>Apply a bag of display settings to the LIVE display, and report what landed. Each key runs through the display config schema's `preProcessSnapshot` (shorthand expansions, legacy-key migrations — the same lowering a session spec's inline track keys get in `showTrackGeneric`), then writes the matching config slot. Keys that are not slots come back in `unapplied` rather than vanishing: the settings vocabulary's historical failure mode is the silently dropped key.<br><br>`allowSetters` additionally routes a non-slot key to a conventionally named single-argument `set<Key>` action. Opt-in, never the default: the declarative surfaces (session specs, share links, embeds) feed this whole bags of untyped JSON, and a blanket fallback would let them reach internal setters (`setError`, `setScrollTop`, ...) and call multi-argument setters with one argument. A caller that wants a specific action can also simply call it.<br><br>A key whose write THREW is reported separately, in `failed` — it is the only one of the three that means the caller got something wrong, and the only one worth a notification. `unapplied` is not: at the `showTrackGeneric` call site it also collects keys that surface consumed itself (`type`) and MST display props the display snapshot already applied (`resolution`), so treating it as "dropped" would report a correct call as broken.<br><br>Per-key errors do not abort the rest of the bag — a caller mid-`showTrack` has already pushed the track, and one rejected value must not strand a half-configured track.</span> | [BaseDisplay](../basedisplay#action-applydisplaysettings) |
| <span id="action-setscrolltop">**setScrollTop**</span><br><code>(scrollTop: number) =&gt; void</code> | <span data-pagefind-ignore>Clamped into `[0, scrollableHeight]`, so no caller has to remember the bound. Unbounded for a display that leaves `scrollableHeight` at its `Infinity` default.</span> | [TrackHeightMixin](../trackheightmixin#action-setscrolltop) |
| <span id="action-setheight">**setHeight**</span><br><code>(displayHeight: number) =&gt; number</code> |  | [TrackHeightMixin](../trackheightmixin#action-setheight) |
| <span id="action-resizeheight">**resizeHeight**</span><br><code>(distance: number) =&gt; number</code> |  | [TrackHeightMixin](../trackheightmixin#action-resizeheight) |
| <span id="action-expandtocontentheight">**expandToContentHeight**</span><br><code>() =&gt; number</code> | <span data-pagefind-ignore>Grow the track by exactly the content it is currently hiding, so a display scrolled over a taller stack ends up showing all of it. The track's resize handle runs this on a double click.<br><br>`scrollableHeight` is the whole measurement — it is already every scrolling display's answer to "how much is off the bottom", so no display has to supply a second one. A display that doesn't scroll internally leaves it at `Infinity` and gets a no-op, as does one already showing everything (0).<br><br>Routed through `resizeHeight` rather than `setHeight` so grow mode's override still gets to leave grow first; going straight to the slot would let the reactive height re-derive `grownHeight` and the double click would appear to do nothing.</span> | [TrackHeightMixin](../trackheightmixin#action-expandtocontentheight) |
| <span id="action-setheightmode">**setHeightMode**</span><br><code>(mode: "fit" &#124; "fixed" &#124; "grow") =&gt; void</code> | <span data-pagefind-ignore>Set the track-height strategy by writing the unified `heightMode` slot; the modes are mutually exclusive by construction. Leaving grow bakes the grown height into the `height` slot in the same action, so the switch is atomic: `installGrowExitBake` also covers this exit, but it is a reaction, and an observer scheduled ahead of it would catch the new mode against the stale slot — a track grown to 800px fitting one frame into the 100px the slot still held. The reaction sees the slot move with the mode and skips, the same guard that protects a drag-resize exit. Entering a non-`fixed` mode drops a leftover scroll offset that the reconfigured height contradicts — neither fit nor grow generally scrolls, and a sticky canvas left at an out-of-range offset paints clipped or blank with no DOM scroll event to resync it. Displays with more transient state to reset super-capture this.</span> | [HeightModeMixin](../heightmodemixin#action-setheightmode) |
| <span id="action-setshowlegend">**setShowLegend**</span><br><code>(arg: boolean) =&gt; void</code> |  | [LegendMixin](../legendmixin#action-setshowlegend) |
| <span id="action-setloadedregion">**setLoadedRegion**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(displayedRegionIndex: number, region: Region, payload: {} &#124; un…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(displayedRegionIndex: number, region: Region, payload: {} &#124; undefined, fetchInputs?: FetchInputs) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>The raw write behind `ctx.commitRegion`, and **not what a fetch should call**: a display naming its own span is the bug this family spent a release on, and going through the context is what makes that inexpressible — see RegionFetchContext. Direct callers are tests staging an already-loaded display.<br><br>The payload is named on every call, `undefined` included: this write replaces the whole record, so a re-stamp that left it off dropped the data a test had staged one line earlier, and the failure surfaced as a reader throwing three layers away. A test stages a claim with nothing behind it by saying so.<br><br>An action so callers after an async boundary stay in MST strict mode. Stamps the region with the fetch key its data came back under. `fetchRegions` passes the key it captured before issuing the RPC; the default reads it *now*, which is right for a caller holding the region already and wrong for anything resuming after an await, where the viewport may have moved under the fetch.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-setloadedregion) |
| <span id="action-evictregionstore">**evictRegionStore**</span><br><code>(keep: ReadonlySet&lt;number&gt;) =&gt; void</code> | <span data-pagefind-ignore>The store's bound. Drops the entries a fetch can no longer be about: an index outside the view's buffered viewport, once the store is over `MAX_STORED_REGIONS`, oldest first.<br><br>One rule for every display, where canvas hand-rolled `pruneRpcDataMapToVisible` (prune to the buffer on every fetch) and every other display had no bound at all beyond `displayedRegions.length` — which is the contig count, so a fragmented assembly had none worth the name. The cap is what lets a pan back onto a recently-visited region draw immediately, which the prune-to-buffer rule gave up.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-evictregionstore) |
| <span id="action-droploadedregion">**dropLoadedRegion**</span><br><code>(displayedRegionIndex: number) =&gt; void</code> | <span data-pagefind-ignore>Forget one region — for a display pruning what has scrolled off screen.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-droploadedregion) |
| <span id="action-cleardisplayspecificdata">**clearDisplaySpecificData**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Overridable hook (no-op base): drop what this display holds beside the store — a second store of its own, a verdict about the viewport that was just dropped. Called by `clearAllRpcData`, which runs on a displayed-regions change, on a viewport move past an error or a cancel, and on `reload()`.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-cleardisplayspecificdata) |
| <span id="action-clearsettingsbakeddata">**clearSettingsBakedData**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Overridable hook (no-op base): drop what this display holds that is wrong under a changed setting rather than merely stale — a payload whose shape the setting decides. Called by `invalidateSettings`, where `clearDisplaySpecificData` is deliberately not: bins, reads and features fetched under the previous setting draw honestly under the scrim `staleSettingsDrawn` raises until the refetch lands, the way canvas has kept its features since ADR-006 and every display does since 2026-09.<br><br>The variant matrix overrides it, for a structural reason: it holds one payload for every visible region and the row set is a setting, so there is no per-region replacement to wait for.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-clearsettingsbakeddata) |
| <span id="action-clearallrpcdata">**clearAllRpcData**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>full reset: cancels fetch, clears error, loadedRegions, display-specific data, and the canvas-drawn flag. The too-large gate is derived (a pure function of the cached estimate × viewport), so it needs no explicit clear here — the fetch autorun re-measures at the new viewport and the verdict follows.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-clearallrpcdata) |
| <span id="action-invalidatesettings">**invalidateSettings**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>`SettingsInvalidate`'s reset: the half of `clearAllRpcData` a settings change still needs now that the settings and adapter axes are in `fetchInputs`. The in-flight fetch is superseded now rather than when its payload lands stamped stale, a blocking error or cancel is cleared so the plan is not `blocked`, and the display drops its settings-baked data. `loadedRegions` and the canvas-drawn flag stay: every held region already reads `!isCacheValid`, so the plan refetches it, and until that lands the data stays on screen under the scrim `staleSettingsDrawn` raises.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-invalidatesettings) |
| <span id="action-fetchregions">**fetchRegions**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(needed: IndexedRegion[], work: (ctx: RegionFetchContext) =&gt; Pr…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(needed: IndexedRegion[], work: (ctx: RegionFetchContext) =&gt; Promise&lt;void&gt;) =&gt; Promise&lt;void&gt;</code></pre></dialog></span> | <span data-pagefind-ignore>Run a per-region fetch. The work callback calls `ctx.commitRegion` as it stores each region's payload, which is what marks it loaded — see RegionFetchContext for why this function no longer does that itself. Its only callers are the three helpers in `fetchEachRegion.ts`, which make that call for every display in the family; a display reaching past them owns both `ctx.isStale()` guards and the commit by hand, and none does.<br><br>The fetch key is captured here, at issue, and carried into every commit — never re-read after the await. `ctx.isStale()` trips on a newer fetch or a cancel, not on a viewport that moved under a fetch that is still current, so a key read at commit time would stamp this data with a zoom it was not fetched at.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-fetchregions) |
| <span id="action-afterattach">**afterAttach**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>installs the fetch-lifecycle autoruns (DisplayedRegionsChange, FetchVisibleRegions, SettingsInvalidate, ClearBlockingStateOnViewportChange)</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-afterattach) |
| <span id="action-clearbyteestimate">**clearByteEstimate**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Drops the estimate and the viewport stamp. `forceLoadTrack` survives: it is a track-wide approval.</span> | [RegionTooLargeMixin](../regiontoolargemixin#action-clearbyteestimate) |
| <span id="action-setforceloadtrack">**setForceLoadTrack**</span><br><code>(flag: boolean) =&gt; void</code> |  | [RegionTooLargeMixin](../regiontoolargemixin#action-setforceloadtrack) |
| <span id="action-commitfetchbytes">**commitFetchBytes**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(perRegionBytes: (number &#124; undefined)[], issued: GateFetchState…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(perRegionBytes: (number &#124; undefined)[], issued: GateFetchState, partial?: boolean) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>The byte axis of a finished fetch, called by the fetch runners with the `gateFetchState()` they captured at issue. Commits the per-region max; an empty batch, or an ungated display, commits nothing.</span> | [RegionTooLargeMixin](../regiontoolargemixin#action-commitfetchbytes) |
| <span id="action-forceload">**forceLoad**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>The banner's button: exempt the track on both axes and refetch.</span> | [RegionTooLargeMixin](../regiontoolargemixin#action-forceload) |
| <span id="action-markcanvasdrawn">**markCanvasDrawn**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-markcanvasdrawn) |
| <span id="action-resetcanvasdrawn">**resetCanvasDrawn**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-resetcanvasdrawn) |
| <span id="action-stoprenderingbackend">**stopRenderingBackend**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-stoprenderingbackend) |
| <span id="action-rendernow">**renderNow**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-rendernow) |
| <span id="action-setrendererror">**setRenderError**</span><br><code>(error: unknown) =&gt; void</code> | <span data-pagefind-ignore>set/clear the render-backend error. Called by `useRenderingBackend`: with the error when the canvas factory rejects (or context-loss re-init fails), and with `undefined` on successful (re)init and on retry.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#action-setrendererror) |
| <span id="action-attachrenderingbackend">**attachRenderingBackend**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>&lt;B&gt;(backend: B, setup: () =&gt; RenderingBackendCallbacks&lt;B&gt;) =&gt; v…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>&lt;B&gt;(backend: B, setup: () =&gt; RenderingBackendCallbacks&lt;B&gt;) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>attach a GPU/Canvas2D backend and install the upload + render autorun pair. Idempotent: re-calling swaps the backend and does not run `setup` again, so the callbacks and everything they close over are the first call's.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#action-attachrenderingbackend) |
| <span id="action-stopactivefetch">**stopActiveFetch**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Abort the in-flight fetch (if any) and retire its slot. The shared preamble of both cancel paths; the difference between them is only what they do to `fetchCanceled` / `fetchGeneration` afterward.</span> | [FetchMixin](../fetchmixin#action-stopactivefetch) |
| <span id="action-openstatusstream">**openStatusStream**</span><br><code>(isCurrent: () =&gt; boolean) =&gt; StatusStream</code> | <span data-pagefind-ignore>Open one operation's slot on the display's status field: an RPC `statusCallback` throttled through the display-wide window and guarded so a callback that fires after the node is torn down (RPCs resolve their status stream asynchronously) is a safe no-op, plus the `clear` that retires the slot when the operation ends.<br><br>**Every operation on the display opens one**, and the two come back together because an operation that never retires goes on voting for a phase that is over. The viewport fetch (`runFetch`), the clustering run and a lent `createStopTokenRotation` are three of them on one field; before ADR-081 each blanked the field outright and the last one to finish decided what the other two were still saying.<br><br>`isCurrent` is required and has no "node is alive" default, because alive is not the interesting question: a *superseded* fetch is on a live node, and its late status repainting the overlay of the fetch that replaced it is the failure this guards. `runFetch` passes `!isStale()`, which is what every display gets for free through `ctx.statusCallback`; a caller outside a fetch (the clustering autorun) passes its own run's flag. Defaulting to `isAlive` made the loose answer the easy one and five displays took it.<br><br>`runFetch`'s own slot is opened by the rotation; this is for an operation outside any fetch, the tree sidebar's clustering run.</span> | [FetchMixin](../fetchmixin#action-openstatusstream) |
| <span id="action-cancelfetch">**cancelFetch**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>cancel any in-flight fetch and bump fetchGeneration (always bumps, so callers can retrigger fetch autoruns even when nothing was in flight). This is the *internal* reset `clearAllRpcData` runs — it clears any user-cancel flag so the retrigger actually re-fetches.</span> | [FetchMixin](../fetchmixin#action-cancelfetch) |
| <span id="action-cancelfetchbyuser">**cancelFetchByUser**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>User-initiated cancel from the loading overlay. Stops the in-flight fetch and lands in a durable `fetchCanceled` state. Unlike `cancelFetch`, it does NOT bump fetchGeneration — so the fetch autoruns don't immediately restart the load. The user retries via `reload` (the overlay's retry button), or it clears on the next viewport change.</span> | [FetchMixin](../fetchmixin#action-cancelfetchbyuser) |
| <span id="action-beforedestroy">**beforeDestroy**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Release an in-flight fetch's stop token on teardown. Without this, a display destroyed mid-fetch (track/view closed while loading) never signals the worker to abort the now-useless work, and its in-flight HTTP reads keep downloading. MST auto-chains lifecycle hooks, so a composing display can still define its own beforeDestroy.</span> | [FetchMixin](../fetchmixin#action-beforedestroy) |
| <span id="action-beginfetch">**beginFetch**</span><br><code>(stopToken: StopToken) =&gt; void</code> | <span data-pagefind-ignore>The `onBegin` half of a fetch's bookkeeping: publish the in-flight token (`isLoading`) and clear the durable user-cancel — a load starting is the single clear point that covers every retrigger path (reload, viewport change, settings invalidate). An action of its own for the same reason `endFetch` is: `installFetch`'s lifecycle callbacks run outside any MST flow this mixin owns.</span> | [FetchMixin](../fetchmixin#action-beginfetch) |
| <span id="action-endfetch">**endFetch**</span><br><code>(current: boolean) =&gt; void</code> | <span data-pagefind-ignore>The `finally` half of `runFetch`'s bookkeeping, an action of its own because `runFetchOnce`'s `finally` resumes on a microtask the flow does not own — a direct volatile write there is outside the action context, which is the one thing hoisting the sequence into a shared function costs. The stale branch is a superseded fetch, which must not clear the loading flag the run that replaced it just set. The stop token itself is released by the rotation's own `end()`, one layer down.</span> | [FetchMixin](../fetchmixin#action-endfetch) |
| <span id="action-runfetch">**runFetch**</span><br><code>(work: (ctx: FetchContext) =&gt; Promise&lt;void&gt;) =&gt; Promise&lt;void&gt;</code> | <span data-pagefind-ignore>Run a cancel-safe fetch (cancels any prior). The work callback gets a FetchContext with a stopToken to forward to the RPC and an isStale() check to short-circuit commits once the user has moved on.<br><br>**The MST-flow wrapper over the shared `runFetchOnce` sequence**, and only the wrapper: the begin/clear/run/commit/error/end order, and the rules that keep a superseded run from writing back, are the same function every other fetch in the tree runs. What this adds is the observable bookkeeping a display needs — `isLoading` through `activeStopToken`, `fetchGeneration`, the user-cancel clear — and the flow itself, which is an action, so `work`'s synchronous prefix runs untracked wherever a fetch autorun calls this.</span> | [FetchMixin](../fetchmixin#action-runfetch) |
| <span id="action-setdensitystats">**setDensityStats**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(displayedRegionIndex: number, stats: RegionDensityStats) =&gt; vo…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(displayedRegionIndex: number, stats: RegionDensityStats) =&gt; void</code></pre></dialog></span> |  | [CanvasFeatureGateMixin](../canvasfeaturegatemixin#action-setdensitystats) |
| <span id="action-cleargatemeasurements">**clearGateMeasurements**</span><br><code>() =&gt; void</code> |  | [CanvasFeatureGateMixin](../canvasfeaturegatemixin#action-cleargatemeasurements) |
| <span id="action-commitgatemeasurements">**commitGateMeasurements**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(measurements: RegionGateMeasurement[], issued: GateFetchState)…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(measurements: RegionGateMeasurement[], issued: GateFetchState) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Judged by the tier captured at issue.</span> | [CanvasFeatureGateMixin](../canvasfeaturegatemixin#action-commitgatemeasurements) |
| <span id="action-setdensityhoverpx">**setDensityHoverPx**</span><br><code>(px?: number &#124; undefined) =&gt; void</code> | <span data-pagefind-ignore>Kept only while the band is up, so a pointer over features writes nothing here.</span> | [DensityBandMixin](../densitybandmixin#action-setdensityhoverpx) |
| <span id="action-fetchcoarsetier">**fetchCoarseTier**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(read: CoarseTierRead, ctx: FetchContext) =&gt; Promise&lt;CoarseTier…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(read: CoarseTierRead, ctx: FetchContext) =&gt; Promise&lt;CoarseTierResult&lt;FeatureDensity&gt;&gt;</code></pre></dialog></span> |  | [DensityTierMixin](../densitytiermixin#action-fetchcoarsetier) |
| <span id="action-setcoarsetier">**setCoarseTier**</span><br><code>(entries: CoarseTierEntry&lt;P&gt;[], read: CoarseTierRead) =&gt; void</code> |  | [CoarseTierMixin](../coarsetiermixin#action-setcoarsetier) |
| <span id="action-clearcoarsetier">**clearCoarseTier**</span><br><code>() =&gt; void</code> |  | [CoarseTierMixin](../coarsetiermixin#action-clearcoarsetier) |
| <span id="action-setcoarsetierloading">**setCoarseTierLoading**</span><br><code>(loading: boolean) =&gt; void</code> |  | [CoarseTierMixin](../coarsetiermixin#action-setcoarsetierloading) |
| <span id="action-closecontextmenu">**closeContextMenu**</span><br><code>() =&gt; void</code> |  | [ContextMenuMixin](../contextmenumixin#action-closecontextmenu) |

