API Reference
RFviewJS is a self-contained JavaScript module for RNA secondary structure visualization and editing. It requires no build step and no external dependencies: a single <script> tag is enough.
Installation
To install RFviewJS on your webpage, just obtain RFview.js from the Git repository (under scripts/RFview.js), upload it to your webserver and include it with a plain <script> tag:
<script src="path/to/RFview.js"></script>
Alternatively, you can directly import it from the official RFviewJS website:
<script src="https://rfview.incarnatolab.com/scripts/RFview.js"></script>
The module exports a single global class, RFviewJS.
Quick start
<!DOCTYPE html>
<html>
<head>
<script src="RFview.js"></script>
<style>
html, body { height: 100%; margin: 0; }
#viewer { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="viewer"></div>
<script>
const viewer = new RFviewJS(document.getElementById('viewer'));
viewer.load({
sequence: 'GGGUCUAUCUAUUGGAGAGAACCAUGGAGAAACCC',
structure: '((((...(((((.((......)))))))...))))',
});
</script>
</body>
</html>
Several usage examples are available from the Git repository (under examples/).
Constructor
const viewer = new RFviewJS(container, options);
container is any DOM element. The viewer fills it completely, so give the element explicit dimensions (usually via CSS).
Viewer options
| Option | Type | Default | Description |
|---|---|---|---|
toolbarPosition |
'left' | 'right' | 'top' | 'bottom' |
'left' |
Toolbar's positioning in the canvas |
statusBar |
boolean |
true |
Shows the bottom status bar containing general information about the structure (sequence length, base-pair count, etc.) |
canvasDrop |
boolean |
true |
Enables loading of structure/reactivity/annotation files via direct drag-and-drop onto the canvas |
layout |
'auto' | 'radiate' | 'naview' |
'auto' |
RNA secondary structure rendering algorithm. 'auto' computes both NAView and Radiate layouts, counts the number of helix crossings in each, and picks the one with fewer crossings. NAView wins when its count is < Radiate's (within tolerance, see autoLayoutTolerance below) |
autoLayoutTolerance |
numeric |
0 |
Maximum number of helix crossings that can be allowed to still prefer Radiate layout over NAView |
showIndices |
boolean |
true |
Shows position index labels |
showColors |
boolean |
true |
Shows reactivity colors to bases on load (see colorMap below) |
showPairAnnotations |
boolean |
true |
Shows base-pair/helix-level annotation boxes on load |
showInsets |
boolean |
true |
Shows inset panels of non-nested interactions for Stockholm structures on load |
showLabels |
boolean |
true |
Shows labels of SS_cons annotations for Stockholm structures on load |
showSsEnds |
boolean |
false |
Shows single-stranded (unstructured) nucleotides at either ends of a structure (off by default) |
showPercCanonical |
boolean |
false |
Activates % canonical pairs coloring on load for Stockholm alignments (colors every base-pair by the percentage of sequences in the alignment that form a canonical pair [AU, GC or GU] at that position). It has no effect on non-Stockholm structures. |
autoRefit |
boolean |
true |
Automatically refits structure to the canvas upon helix rotation |
transitionDuration |
numeric |
600 |
Duration (in ms) of the transition when switching between alternative structures that share the same sequence |
buttons |
object | false |
all on | Fine-grained toolbar control (see Toolbar buttonw below) |
width |
numeric | string |
— | Width of the container (e.g. 800 or '100%') |
height |
numeric | string |
— | Height of the container |
id |
string |
— | Used as the basename when saving the structure as SVG |
colorMap |
object |
— | A colorMap object used as the default for the initial load() call triggered by the constructor (Note: it has no effect on subsequent load() calls) |
relaxedSequence |
boolean |
false |
Disables sequence character validation, allowing any character (custom alphabets) to be used. When enabled, all base pairs are rendered as single lines regardless of the base identity |
The constructor always calls load(options) at the end, so any key accepted by load() can be passed directly to the constructor.
Toolbar buttons
The module allows full toolbar customization. Toggling of individual buttons can be controlled as it follows:
const viewer = new RFviewJS(container, {
buttons: {
upload: true, // Structure/Reactivity/Annotation file upload
rfam: true, // Fetch alignment from Rfam
manualInput: true, // Manual input of sequence & structure
cleanOne: true, // Clear current structure
cleanAll: true, // Clear all structures
zoomIn: true, // Zoom in
zoomOut: true, // Zoom out
fit: true, // Fit structure to canvas
autoRefit: true, // Automatically refits structure to canvas upon helix rotation
reset: true, // Layout reset
save: true, // SVG export
indices: true, // Toggle display position indices
colorMap: true, // Toggle display reactivities
pairAnnotations: true, // Toggle display base-pair/helix-level annotations
pseudoknots: true, // Toggle display pseudoknots
insets: true, // Toggle display of inset panels (Stockholm structures)
labels: true, // Toggle display of labels from SS_cons annotation lines (Stockholm structures)
ssEnds: true, // Toggle display single-stranded bases at either ends of a structure (when present)
percCanonical: true, // Toggle display % canonical pairs coloring (Stockholm structures)
layout: true, // Structure rendering layout switching
toolbarPos: true, // Toolbar repositioning
}
});
Omitted keys default to true. Setting buttons: false is equivalent to setting every key to false. Please note, the Settings and About buttons cannot be hidden.
Public methods
| Method | Argument(s) | Description |
|---|---|---|
fit() |
Fits the current structure to the canvas, with a small padding. Called automatically after every load() |
|
reset() |
Redraws the current structure from scratch (discards any manual helix rotations) | |
clear() |
Removes all structures and annotations and resets the viewer to a blank state | |
| `toggleLayout() | Switches the rendering layout between NAView and Radiate, preserving all annotations and canon state | |
clearCurrent() |
Removes only the currently active structure. The remaining structures stay loaded and the viewer switches to the next one. Falls back to clear() if only one structure is loaded |
|
switchToStructure() |
index | label |
Switches to another structure. Structures can be specified via their 0-based index (which follows the order of loading) or by label string. If sequences match, therefore structures represent alternative conformations of the same RNA, a smooth animated transition is triggered |
setShowIndices() |
bool |
Shows or hides position index labels |
setShowColors() |
bool |
Toggles reactivity coloring |
setShowPairAnnotations() |
bool |
Toggles base-pair/helix-level annotation boxes |
setShowInsets() |
bool |
Toggles inset panels for non-nested interactions (Stockholm structures) |
setShowLabels() |
bool |
Toggles labels for SS_cons annotation lines (Stockholm structures) |
setShowSsEnds() |
bool |
Toggles rendering of single-stranded nucleotides at either ends of a structure |
setLayoutAlgorithm() |
algorithm |
Switches the RNA structure rendering algorithm ('auto', 'radiate', or 'naview') and re-renders |
fetchRfam() |
id |
Fetches a Stockholm alignment from Rfam by family ID (e.g., 'RF00162') and loads it |
exportSVGString() |
Renders the current structure and returns it as an SVG string. Useful for programmatic export without triggering a file-save dialog |
load()
load(config) is the main method. Every key is optional unless stated otherwise.
Loading single structures
viewer.load({
sequence: 'GGGGAUUCCCC', // Required (Ts are auto-converted to Us)
structure: '((((...))))', // Required
label: 'RNA#1', // Structure ID/label
values: [...], // Array of per-base reactivities
showColors: true, // Whether to apply reactivity coloring on load()
colorMap: { ... }, // see "Color maps" section below (can be omitted for default reactivity coloring)
nanColor: '#999999', // Color of bases with NaN values
pairAnnotations: [...], // see "Base-pair annotations" section below
pairAnnotColorMap: { ... }, // Color map for base-pair annotation boxes
helixAnnotations: [...], // see "Helix-level annotations"
});
structure accepts standard dot-bracket notation. Square brackets [], curly braces {}, and angle brackets <>, as well as upper-case/lower-case pairs (e.g., Aa) are also accepted.
values must have the same length as sequence. NaN can be used for positions with no data, which will be colored by nanColor.
Multiple structures in one canvas
Multiple structures can be simultaneously loaded by passing a structures array. Each entry is a structure-level config object. Keys declared at the top level act as shared defaults, and each structure entry can override them individually.
viewer.load({
sequence: 'GGGAAAUUUCCC', // Shared sequence
showColors: true, // Shared color map display flag
structures: [
{
label: 'Structure 1 — Default reactivity colorMap',
structure: '(((......)))',
values: [ ... ],
// no colorMap defined, falls back to built-in default
},
{
label: 'Structure 2 — Custom colorMap',
structure: '(((...)))...',
values: [ ... ],
colorMap: { ... },
nanColor: '#999999',
},
],
});
The viewer will automatically display a structure switcher when more than one structure is loaded. Switching between structures with the same sequence triggers a smooth animated transition.
Each entry in structures can contain: label, sequence, structure, values, colorMap, pairAnnotations, pairAnnotColorMap and helixAnnotations.
Loading from text: dot-bracket, CT and Stockholm
Raw dot-bracket, CT and Stockholm file contents can be directly passed as fileText (or the Stockholm-specific alias stockholmText) to the constructor, or to the load() method. The format is auto-detected.
// Stockholm alignment
viewer.load({ stockholmText: stockholmFileText, label: 'RF00162' });
// Dot-bracket / CT
viewer.load({ fileText: structureFileText });
When label is provided, it overrides the name extracted from the file (e.g., #=GF AC or #=GF ID for Stockholm files). If the file contains multiple records, the label is suffixed with (1), (2), and so on.
Stockholm files are parsed into a consensus structure. The alignment view (conservation colors, alignment track) is shown alongside the structure diagram. Gap-only columns are filtered out. Position labels are remapped so that covariation data loaded afterwards aligns correctly. For additional details, please see Visualization of structures from Stockholm alignments.
Furthermore, any additional #=GC SS_cons_* entry in the file is processed and labeled on the consensus structure. Non-nested interactions (such as pseudoknots, cross-covariations, etc.) are displayed as separate insets and labeled. Hovering on the inset causes the corresponding bases in the consensus structure to glow up.
Fetching from Rfam
Alignments can also be directly fetched from Rfam, by passing an Rfam ID to rfamId directly to the constructor, or to the load() method:
viewer.load({ rfamId: 'RF00162' });
Alternatively, alignments can be fetched via the fetchRfam() method after construction:
viewer.fetchRfam('RF00162');
Multiple Stockholm alignments in one canvas
To load multiple Stockholm files into the same canvas as switchable structures, use RFviewJS.parseStockholmFile() to pre-parse each file into the structures array format, then spread them into a single structures array:
viewer.load({
structures: [
...RFviewJS.parseStockholmFile(stockholmText1, 'RF00162'),
...RFviewJS.parseStockholmFile(stockholmText2, 'RF00504'),
],
});
After loading, covariation data for each alignment must be applied while that structure is active (see switchToStructure() and loadCov()):
viewer.switchToStructure(1); // Switches to structure RF00504
viewer.loadCov(covFileText); // Loads base-pair covariation data from R-scape's .cov file text
viewer.loadCov(helixCovFileText); // Loads helix-level covariation data from R-scape's .helixcov file text
Color maps
A color map controls how values are mapped to base colors. If no colorMap is provided, coloring falls back to the built-in reactivity discrete color map:
| Value range | Color |
|---|---|
| 0-0.3 | #1f2328 (black) |
| 0.3-0.7 | #f5c518 (yellow) |
| 0.7+ | #cc0000 (red) |
| NaN | #808080 (grey) |
Shorthand gradient
As a quick shortcut, a two-stop gradient can be created without writing a full colorMap object:
viewer.load({
sequence: '...',
structure: '...',
values: [ ... ],
colorMapMin: 0, // Minimum value (default: 0)
colorMapMax: 1, // Maximum value (default: 1)
colorMapMinColor: '#4870c8', // colorMapMin color
colorMapMaxColor: '#bd0530', // colorMapMax color
colorMapNaN: '#808080', // Color for NaN positions
});
Full colormap object
For complete control, a full colorMap object can be created:
const COLOR_MAP = {
type: 'discrete', // 'discrete' or 'gradient'
min: 0, // Lower bound for the first stop (gradient only)
nanColor: '#999999', // Color for NaN / missing values
stops: [
{ value: 0.3, color: '#1e3a55' }, // Upper bound of the first stop
{ value: 0.7, color: '#60a5fa' },
{ value: 1.0, color: '#9353ea' },
],
};
viewer.load({
sequence: '...',
structure: '...',
values: [ ... ],
showColors: true,
colorMap: COLOR_MAP,
});
With type: 'discrete', each stop defines the upper bound of a color band. Any value ≤ stops[0].value will get stops[0].color, while values beyond the last stop get the last stop's color.
With type: 'gradient', colors are interpolated linearly between stops. Values below the first stop or above the last stop are clamped.
Stops are sorted by value automatically.
Base-pair annotations
pairAnnotations are drawn as colored boxes surrounding specific base-pairs, and they are useful for highlighting, for example, significantly covarying pairs.
Each annotation is an object:
viewer.load({
sequence, structure,
pairAnnotations: [
{ i: 5, color: '#e74c3c' }, // Annotates pair at position 5
{ i: 12, j: 40, color: '#3498db', opacity: 0.5 },
{ i: 20, value: 0.8 }, // Colored via pairAnnotColorMap
],
pairAnnotColorMap: {
type: 'gradient',
stops: [
{ value: 0.0, color: '#ffffff' },
{ value: 1.0, color: '#e74c3c' },
],
},
});
where:
| Key | Type | Default | Description |
|---|---|---|---|
i |
numeric |
0-indexed position of the first base of the pair (required) | |
j |
numeric |
pairs[i] |
0-indexed position of the second base of the pair (optional). Defaults to the pair partner of i in the current structure |
color |
string |
Hex color (Note:color and value are mutually exclusive) |
|
value |
numeric |
Mapped to a color through pairAnnotColorMap (Note:color and value are mutually exclusive) |
|
opacity |
numeric |
0.5 |
Fill opacity |
strokeWidth |
numeric |
1.5 |
Border thickness |
padding |
numeric |
5 |
Extra padding around the base-pair in scene units |
i and j must refer to an actual base pair in the structure. The viewer validates annotations at load time and reports any that reference unpaired or out-of-range positions.
Note: when annotating structures loaded from Stockholm alignments, i and j refer to the original alignment column (0-based), not the rendered position. The viewer remaps it automatically.
Helix-level annotations
helixAnnotations are drawn as colored bounding boxes around entire helices, and they are useful for highlighting, for example, significantly covarying helices.
Each annotation is an object with i specifying any paired position within the target helix. The viewer automatically walks outward to find the outermost pair of the helix, then inward to collect all stacked pairs, so the box encompasses the full helix regardless of which position i points to.
viewer.load({
sequence, structure,
helixAnnotations: [
{ i: 5, color: '#e74c3c' },
{ i: 20, color: '#3498db', opacity: 0.12, strokeWidth: 2 },
{ i: 40, padding: 30 },
],
});
where:
| Key | Type | Default | Description |
|---|---|---|---|
i |
numeric |
0-indexed position of any base within the target helix (required). Must be a paired position | |
color |
string |
--rv-helix-annot-color |
Hex color of the annotation box. Falls back to the CSS custom property --rv-helix-annot-color |
opacity |
numeric |
0.5 |
Fill opacity |
strokeWidth |
numeric |
1.5 |
Border thickness |
padding |
numeric |
--rv-helix-annot-padding |
Extra padding around the helix in scene units. Falls back to the CSS custom property --rv-helix-annot-padding |
Note #1: helixAnnotations does not support value/helixAnnotColorMap. Use color directly for per-annotation coloring.
Note #2: when annotating structures loaded from Stockholm alignments, i refers to the original alignment column (0-based), not the rendered position. The viewer remaps it automatically.
Post-load annotation methods
loadCov()
Loads R-scape's covariation files (.cov or .helixcov format), or TSV files (please see File formats for more information) onto the currently displayed structure. The method auto-detects the format.
try {
viewer.loadCov(covFileText);
} catch (e) {
console.warn('Covariation error:', e.message);
}
Base-pair annotations from a .cov file are color-coded by E-value, while TSV annotations are colored by group ID (third field). A .helixcov file draws a bounding box around each significantly covarying helix.
loadCov() throws an exception if the file contains pairs that cannot be mapped onto the current structure (e.g. if the structure was not yet loaded, or if the file belongs to a different alignment). Exceptions can be caught via wrapping in try/catch.
When working with multiple structures, switchToStructure() can be called first to select the correct target structure before calling loadCov():
viewer.switchToStructure(0);
viewer.loadCov(cov1);
viewer.switchToStructure(1);
viewer.loadCov(cov2);
viewer.switchToStructure(0); // Goes back to the first structure
loadHelixCov()
Loads a .helixcov file directly (bypassing the auto-detect in loadCov()). Only significant helices are drawn. Behaviour and error handling are identical to those of loadCov().
viewer.loadHelixCov(helixCovText);
Static methods
| Method | Description |
|---|---|
RFviewJS.parseStockholmFile(text, labelFallback) |
Parses a Stockholm alignment and returns an array of structure-record objects suitable for spreading into a structures array (the label is taken from #=GF ID or #=GF AC, falling back to labelFallback) |
RFviewJS.parseDbFile(text, label) |
Parses a dot-bracket or CT file and returns an array of structure records |
RFviewJS.parseCTFile(text) |
Parses a CT file and returns structure records |
RFviewJS.parseXmlReactivity(text) |
Parses an RNA Framework XML reactivity file |
RFviewJS.parsePairAnnotFile(text) |
Parses a TSV pair-annotation file |
RFviewJS.parseCovFile(text) |
Parses an R-scape .cov file |
RFviewJS.parseHelixCovFile(text) |
Parses an R-scape .helixcov file |
RFviewJS.buildAnnotColorMap(pairs) |
Builds a color map for a set of pair annotations |
CSS custom properties
All visual properties are exposed as CSS custom properties set on the .rv root element, so any theme can be applied from a stylesheet without touching the JS.
Color palette
| Property | Default | Description |
|---|---|---|
--rv-bg |
#ffffff |
Canvas and toolbar background |
--rv-surface |
#f6f8fa |
Panel and dialog background |
--rv-border |
#d0d7de |
Border color for panels and controls |
--rv-text |
#1f2328 |
Primary text color |
--rv-muted |
#656d76 |
Secondary / label text color |
--rv-accent |
#0969da |
Buttons, links, and highlights |
--rv-accent2 |
#2da44e |
Secondary accent (green), used for pair formation highlights |
--rv-accent3 |
#8250df |
Tertiary accent (purple) |
--rv-error-border |
— | Border color for error states |
--rv-error |
#cf222e |
Error messages |
Structure drawing
| Property | Default | Description |
|---|---|---|
--rv-backbone |
#1f2328 |
Backbone line color |
--rv-backbone-width |
2 |
Backbone stroke width |
--rv-basepair |
#1f2328 |
Base-pair line color |
--rv-basepair-width |
2.2 |
Base-pair stroke width |
--rv-pseudopair |
#0969da |
Pseudoknot color |
--rv-pseudopair-width |
2 |
Pseudoknot stroke width |
--rv-base-fill |
#eaeef2 |
Default (no-data) base circle fill |
--rv-base-stroke |
#1f2328 |
Base circle border color |
--rv-base-stroke-width |
2 |
Base circle border width |
--rv-base-hover |
#bbd4f0 |
Base fill on hover |
--rv-base-radius |
11 |
Base circle radius in SVG units |
--rv-base-label-color |
#1f2328 |
Nucleotide letter color |
--rv-base-label-font |
monospace |
Nucleotide letter font |
--rv-base-label-font-size |
13 |
Nucleotide letter size in px |
--rv-base-index-color |
#656d76 |
Position index label color |
--rv-base-index-font |
monospace |
Font family for position index labels |
--rv-base-index-font-size |
12 |
Position index label size in px |
--rv-base-index-offset |
26 |
Distance from base centre to index label |
--rv-noncanon-dot-r |
4.5 |
Radius of the dot drawn for non-canonical base pairs |
--rv-pair-break |
#ef4444 |
Color of base-pairs lost between start and end structure (sharing same sequence) during the animated structure transition |
--rv-pair-form |
#22c55e |
Color of base-pairs gained between start and end structure (sharing same sequence) during the animated structure transition |
--rv-rot-line |
#0969da80 |
Color of the rotation axis line shown during helix rotation |
--rv-rot-ring |
#0969da20 |
Color of the rotation handle ring shown during helix rotation |
Insets for non-nested interactions
| Property | Default | Description |
|---|---|---|
--rv-inset-max-width |
120px |
Maximum width of inset panels (automatically set to 1/20th of the canvas width at render time, overriding this default) |
--rv-inset-min-width |
80px |
Minimum width of inset panels |
--rv-inset-hover-glow |
8px |
Glow radius of bases in the main structure when hovering over an inset panel |
Base-pair annotations
| Property | Default | Description |
|---|---|---|
--rv-pair-annot-opacity |
0.5 |
Default fill opacity for annotation boxes |
--rv-pair-annot-stroke-width |
1.5 |
Default border width for annotation boxes |
--rv-pair-annot-padding |
16 |
Default padding around pairs in scene units |
--rv-helix-annot-opacity |
0.5 |
Default fill opacity for helix-level annotation boxes |
--rv-helix-annot-padding |
25 |
Padding for helix-level annotation boxes |
--rv-helix-annot-color |
#aff0a8 |
Helix-level annotation box color |
Several CSS stylesheet examples are available from the Git repository (under css/).
Examples
Single structure with reactivity
const viewer = new RFviewJS(document.getElementById('viewer'), {
showIndices: true,
toolbarPosition: 'left',
statusBar: true,
canvasDrop: false,
buttons: {
upload: false, cleanOne: false, cleanAll: false,
zoomIn: true, zoomOut: true, fit: true, reset: true, save: true,
indices: false, colorMap: false, toolbarPos: false,
},
});
viewer.load({
sequence: 'GGGUCUAACCC',
structure: '((((...))))',
values: [0.05, 0.82, 0.77, ...],
showColors: true,
// colorMap omitted → uses built-in SHAPE default
});
Two alternative folds, same sequence, different colormaps
viewer.load({
sequence: SEQ,
showColors: true,
structures: [
{
label: 'MFE structure',
structure: STR1,
values: VALUES,
// SHAPE default colormap
},
{
label: 'Alternative fold',
structure: STR2,
values: VALUES,
colorMap: {
type: 'discrete', min: 0, nanColor: '#999',
stops: [
{ value: 0.3, color: '#1e3a55' },
{ value: 0.7, color: '#60a5fa' },
{ value: 1.0, color: '#9353ea' },
],
},
},
],
});
Stockholm alignment with covariation
const viewer = new RFviewJS(el, { statusBar: true });
// Load alignment — label overrides #=GF ID if provided
viewer.load({ stockholmText: stoText, label: 'RF00162' });
// Add R-scape covariation (pair-level)
try { viewer.loadCov(covText); } catch (e) { console.warn(e.message); }
// Add R-scape helix covariation (helix-level boxes)
try { viewer.loadCov(helixCovText); } catch (e) { console.warn(e.message); }
Two Stockholm alignments with covariation each
viewer.load({
structures: [
...RFviewJS.parseStockholmFile(sto1, 'RF00162'),
...RFviewJS.parseStockholmFile(sto2, 'RF00504'),
],
});
// Apply covariation to the first alignment
viewer.switchToStructure(0);
try { viewer.loadCov(cov1); } catch (e) { console.warn(e.message); }
try { viewer.loadCov(helixCov1); } catch (e) { console.warn(e.message); }
// Apply covariation to the second alignment
viewer.switchToStructure(1);
try { viewer.loadCov(cov2); } catch (e) { console.warn(e.message); }
try { viewer.loadCov(helixCov2); } catch (e) { console.warn(e.message); }
// Start on the first
viewer.switchToStructure(0);
Programmatic control
// Toggle features
viewer.setShowColors(false);
viewer.setShowIndices(false);
viewer.setShowPairAnnotations(true);
// Switch layout algorithm
viewer.setLayoutAlgorithm('naview');
// Navigate structures
viewer.switchToStructure(0);
viewer.switchToStructure('Alternative fold');
// Zoom / reset
viewer.fit();
viewer.reset();
// Tear down
viewer.clear();