Channel Manager v1.0.60¶
Every TranscriptBrowserRenderer instance ships with its own channelManager, responsible for adding, removing, updating, and querying channels, as well as sorting, deduplication, and data export:
When you need a "standalone channel manager", you can also create one manually via new ChannelManager(delegate), but this is very rarely needed (see IChannelManagerDelegate for the shape of delegate).
Method¶
add¶
method
Appends a channel after showing a confirmation dialog.
addDirect¶
method
Appends directly, skipping the dialog. Recommended for programmatic use.
addMany¶
method
Adds multiple channels at once after showing a batch confirmation dialog. Note: addMany does not emit the "add" event itself directly (it fires only after the confirmation dialog flow completes).
cm.addDirect({
name: "My BigWig",
plot: "bar",
data: { method: "remote", format: "bigwig", url: "https://.../signal.bw" },
});
get / findByName / indexOfName¶
method
cm.findByName(name: string): IChannel | undefined
cm.indexOfName(name: string): number
indexOfName returns -1 when not found.
findDuplicates¶
method
Deduplication: returns the subset of configs that already exists in the current channel list. addChannel / addManyChannels call this method before showing the regular confirmation dialog; if duplicates are found, a "Channels already loaded — Force Load / Cancel" warning dialog is shown first.
Equality rule: two channels are considered duplicates when they share the same name and an identical data source (data.method + data.format + data.url all matching). Display fields such as style / group / plot / order do not participate in the comparison — re-importing the same source data with a different skin still counts as a duplicate.
Special case for local files (blob: URLs)
Local imports and drag-and-drop use URL.createObjectURL(file) to generate a new blob: URL — the URL string differs on every import of the same file. So equality has a special case: when both sides are blob: URLs, the URL comparison is skipped and equality is decided by name + format + method (the local import flow already encodes the file name into channel.name). If one side is a blob: URL and the other is a remote URL, they are refused as duplicates (the content cannot be proven equal).
| Parameter | Type | Required | Description |
|---|---|---|---|
configs |
IChannel[] |
✓ | Candidate channel list (the ones about to be added) |
Returns: IChannel[] — the duplicate subset of configs, preserving input order; returns [] when there are no duplicates.
Automatic within the add / addMany flow
You usually don't need to call findDuplicates manually — add() / addMany() already invoke it automatically before each addition and show the dialog as needed. This method is exposed for advanced integrations that "want to drive the UI themselves" (e.g. custom dialogs, batch background deduplication flows).
getAll / getConfig¶
method
cm.getConfig(): IChannel[]
The two methods are equivalent (getConfig is an alias for getAll), returning a shallow copy of all current channel configs (in display order).
getDataByIndex / getDataByName / getDataList¶
method
cm.getDataByName(channelName: string): unknown[] | undefined
cm.getDataList(): Array<{ channelIndex: number; channelName: string; channelData: unknown[] }>
Returns a channel's loaded runtime data (for export / downstream analysis). Note the parameter names are channelIndex / channelName.
update¶
method
Merges partial into the config of the specified channel and triggers a redraw.
remove¶
method
silent = true skips the confirmation dialog (defaults to false, i.e. shows the confirmation dialog by default). Returns whether a deletion actually occurred.
removeByName¶
method
Removes channels in bulk by name, returning the number deleted. silent defaults to true.
clear¶
method
Clears all channels. silent defaults to true.
reorder / moveUp / moveDown¶
method
cm.moveUp(index: number): boolean
cm.moveDown(index: number): boolean
replaceAll¶
method
Destroys all ChannelViews and rebuilds them from the new configs.
reload¶
method
Makes all channels re-fetch data for the current visible region.
exportConfigs¶
method
A snapshot of channel configs in the current display order (re-stamps order based on the display index).
count¶
getter
The current number of channels (a getter, not a method).
on¶
method
Subscribes to channel events, returning an unsubscribe function.
Event¶
event
| Event name | Trigger |
|---|---|
"add" |
After calling add() / addDirect() (addMany goes through the dialog and fires later) |
"remove" |
After calling remove() / removeByName() (when ≥1 channel is actually deleted) |
"update" |
After calling update() |
"reorder" |
After calling reorder() / moveUp() / moveDown() |
"clear" |
After calling clear() |
"replace" |
After calling replaceAll() |
"reload" |
After calling reload() |
The detail of every event is { index?: number; channel?: IChannel; channels?: IChannel[] }. In particular, detail.channels is always populated with the full current channel list, making it easy to re-render directly.
ChannelManagerEvent / ChannelManagerListener¶
type
type ChannelManagerEvent =
| "add"
| "remove"
| "update"
| "reorder"
| "clear"
| "replace"
| "reload";
type ChannelManagerListener = (
event: ChannelManagerEvent,
detail?: { index?: number; channel?: IChannel; channels?: IChannel[] },
) => void;
Types¶
IChannel¶
type
The complete configuration of a single channel (track).
interface IChannel {
name: string;
plot: string;
level?: string;
style?: IChannelStyle;
group?: IChannelGroup;
data?: IChannelData;
filter?: string;
pin?: boolean;
/** Annotation config: field expansion, tooltip keys, separator, color mapping. */
annotation?: IChannelAnnotation;
/**
* Display order. Sorting rules:
* 1. Defaults to the config.channels array order
* 2. Channels with an order come after those without
* 3. Among channels with order, smaller values come first
*/
order?: number;
sortable?: boolean; // Whether sortable, defaults to true
// ── Context-menu item visibility (each defaults to true; set to false to hide the item) ──
isDeleteEnabled?: boolean;
isSortEnabled?: boolean;
isGroupEnabled?: boolean;
isRenameEnabled?: boolean;
isBackgroundColorEnabled?: boolean;
isForegroundColorEnabled?: boolean;
isChannelHeightEnabled?: boolean;
isPinEnabled?: boolean;
isImageDownloadEnabled?: boolean;
isDataDownloadEnabled?: boolean;
/**
* When true (default), the channel obeys the style.detailZoom threshold: when the visible
* region exceeds the threshold it shows a "Zoom in to view details" hint and **skips fetching
* data**, reducing network requests. Set to false to ignore detailZoom and always fetch. Only
* meaningful when style.detailZoom is set. Defaults to true.
*/
isDetailLimitedByZoom?: boolean;
}
IChannelData¶
type
interface IChannelData {
method: string;
format: string;
url?: string;
index?: string;
/** Secondary index file (e.g. the .gzi for a bgzip FASTA). */
index2?: string;
/**
* Explicitly specify the BAM index variant ("bai" / "csi"). Only needed when the index URL has
* no recognizable suffix (e.g. a drag-and-drop blob URL); otherwise it is inferred from the
* index file-name suffix.
*/
indexFormat?: "bai" | "csi";
/**
* Data source for method:"buildin" channels.
* - "annotation": derive structure from the active reference's GFF3 annotation (transcript
* exon/CDS/UTR, gene exons, splice junctions), used for the auto-injected Transcript Structure /
* Exon / Junction.
* - unset / other: use the legacy expression API of the defaultConfig.buildin template (e.g.
* GTEx exon / junction expression).
*/
source?: "annotation" | string;
/**
* Inline raw content for method:"local". Pairs with format "tsv" (BED6/BED12) or "json" (a single
* record or an array). When set, the URL is no longer fetched.
*/
content?: string;
retain?: boolean;
/**
* Aggregation function for multiple features within the same pixel bin in a BigWig/BigBed bar chart.
* - 'mean': average within the bin (IGV default)
* - 'max' / 'min': maximum / minimum within the bin
* Only affects the score range label and normalization, not single-feature rendering. Defaults to 'mean'.
*/
windowingFunction?: "mean" | "max" | "min";
}
IChannelStyle¶
type
All of a channel's display styling. Most fields are optional, with different defaults per plot type.
interface IChannelStyle {
height?: number;
/** Whether to pin (sticky) at the top of the viewport. axis is pinned by default. */
pinned?: boolean;
/** Maximum number of sub-channels visible when expanded (a multiple of the parent channel height), defaults to 5; a scrollbar appears beyond this. */
maxHeight?: number;
label?: IChannelLabelStyle;
color?: string;
paddingTop?: number;
paddingBottom?: number;
paddingLeft?: number;
paddingRight?: number;
cellWidth?: number;
// ── Channel content styling ──
expand?: string | string[];
keys?: string[];
/** Display order of key-value pairs in the tooltip. */
order?: string[];
sep?: string;
foreground?:
| string // Single color: "yellow", "#ff0000"
| string[] // Color array: ["sky", "yellow", "green"]
| {
// Colormap config for continuous data
colormap?: string; // 'viridis', 'plasma', 'coolwarm', etc.
range?: [number, number];
reversed?: boolean;
custom?: { [key: string]: string };
// ── Data-driven mapping specific to the diamond plot ──
colorBy?: string;
sizeBy?: string;
sizeRange?: [number, number]; // Defaults to [0.1, 1]
alpha?: number; // Defaults to 1
alphaBy?: string;
alphaRange?: [number, number]; // Defaults to [0.1, 1]
/** Filter diamond data by gene: the field name in record.rest that must match the current gene_id (version-stripped). */
filterGene?: string;
/** Filter by transcript: the field name in record.rest that must match the current trans_id (version-stripped). */
filterTranscript?: string;
};
background?: string; // Channel background color, defaults to #ffffff
padding?: string; // e.g. '0.2 0.1' (top bottom) or '0.2' (both)
size?: number; // Diamond plot size ratio: diamondPx = channelHeight * size, defaults to 0.3
/**
* Domain span threshold (bp); beyond it, details are hidden and a "Zoom in" hint is shown. Set 0
* to disable (always show details). Per-plot defaults: bam 50000; transcript 500000; sequence
* 10000; others 0.
*/
detailZoom?: number;
/** BAM coverage display config: a boolean toggle, or an object for fine-grained control. */
coverage?:
| boolean
| {
enabled?: boolean; // Defaults to true
color?: string | { colormap?: string; range?: [number, number] };
alpha?: number; // Defaults to 0.7
height?: number; // Fraction of channel height, defaults to 0.2
plot?: "bar" | "line" | "heatmap" | "point"; // Defaults to "bar"
detailZoom?: number; // Defaults to 5000000
scoreLabel?: { enabled?: boolean; fontSize?: number; color?: string; background?: string };
};
/** BAM read strand colors: plus (+) / minus (−) / other (unknown). */
readsColor?: { plus?: string; minus?: string; other?: string };
/** Per-row height of lane stacking plots (variant / transcript), as a fraction of the content area, defaults to 0.31. */
rowHeight?: number;
/** In-row padding for variant lanes (a fraction of lane height, added top and bottom), defaults to 0.01. */
rowPadding?: number;
/** Variant base colors: A/T/C/G/N → hex. */
baseColors?: { [base: string]: string };
refColor?: string;
baseTextColor?: string;
/** Rendering config for RNA modification marks (m6A, m5C, etc.) on the transcript plot. */
modification?: {
enabled?: boolean; // Defaults to true
color?: string | { colormap?: string; range?: [number, number] }; // Defaults to { colormap: "coolwarm" }
alpha?: number; // Defaults to 1
height?: number; // Fraction of channel height, defaults to 0.05
plot?: "triangle"; // Defaults to a downward triangle ▼
};
/** Whether junction arcs (score_curve) fill the area under the arc, defaults to false (stroke only). */
areaShow?: boolean;
/** Whether to auto-expand sub-channels when data first arrives, defaults to false. */
isExpand?: boolean;
/** Whether the rect plot (bigbed/bed) shows feature names as text labels, defaults to false. */
showName?: boolean;
}
IChannelAnnotation¶
type
interface IChannelAnnotation {
/** Field name used to expand (split) a feature into sub-channels. */
expand?: string;
/** Field keys to display in the tooltip / annotation. */
keys?: string[];
/** Separator used to split compound field values. */
sep?: string;
/**
* Sub-channel color mapping:
* - string: a single color name / hex
* - string[]: a color array cycled across sub-channels
* - { custom: Record<string, string> }: an explicit key → color mapping
*/
colors?: string | string[] | { custom?: Record<string, string> };
/** Filter expression applied to annotation records. */
filter?: string;
}
IChannelLabelStyle¶
type
IChannelGroup¶
type
The shape of IChannel.group — used for grouping, stacked rendering, and group autoscale.
interface IChannelGroup {
name: string;
number?: number;
/** Whether channels within the same number group are stacked (overlaid with alpha blending). If any channel in the group has stacked=true, the whole group is stacked. */
stacked?: boolean;
/** Per-channel alpha for stacked rendering (0.0–1.0, defaults to 0.8). */
alpha?: number;
/** Whether it belongs to a multi-select "Group Autoscale" group: members share the same value domain, kept in sync across pan/zoom/reorder. */
autoscale?: boolean;
/** The [min, max] value domain shared by the autoscale group, persisted to survive data reloads / config import-export. */
autoscaleRange?: [number, number];
style?: { color: string };
}
IChannelManagerDelegate¶
type
Needed only when manually constructing new ChannelManager(delegate) — it delegates channel CRUD back to the host renderer. No need to worry about it for regular use of renderer.channelManager.
interface IChannelManagerDelegate {
addChannel(config: IChannel): void;
addChannelDirect(config: IChannel): void;
addManyChannels(configs: IChannel[]): void;
removeChannelByIndex(index: number, silent?: boolean): Promise<boolean>;
reorderChannels(fromIndex: number, toIndex: number): void;
getChannelConfigs(): IChannel[];
getChannelCount(): number;
getChannelData(index: number): unknown[] | undefined;
reloadAll(): void;
replaceAllChannels(channels: IChannel[]): void;
updateChannel(index: number): void;
}