Skip to content

3.2 Visualization Components

coding man edited this page Nov 4, 2026 · 1 revision

Visualization Components

Relevant source files

The following files were used as context for generating this wiki page:

Purpose and Scope

This page documents the user interface visualization components of VariantScope, located in src/ui. These modules render biological data into interactive visual elements, including three-dimensional molecular structures via 3Dmol.js (src/ui/viewer3d.js), lollipop mutation distribution plots via Chart.js (src/ui/lollipop.js), tabular variant grids (src/ui/table.js), and contextual metadata cards (src/ui/cards.js). It also details cross-component synchronization (src/ui/selection.js) and shared visual token definitions (src/ui/palette.js).

Sources: src/ui/viewer3d.js, src/ui/lollipop.js, src/ui/table.js, src/ui/cards.js, src/ui/selection.js, src/ui/palette.js


1. Selection Synchronization (src/ui/selection.js)

The selection object maintains a centralized application state for the currently active variant ID (selectedId), enabling cross-component coordination. When a user selects a variant in the 3D viewer, the lollipop plot, or the tabular grid, all subscribed panels update to reflect the new selection.

---
title: Selection Synchronization Flow
---
graph TD
  UserAction["User Interaction"] -->|Click| Comp["Viewer / Plot / Table"]
  Comp -->|Calls| Sel["selection.select clinvarId, source"]
  Sel -->|Updates| State["selectedId State"]
  Sel -->|Notifies| Listeners["Registered Listeners Set"]
  Listeners -->|Callback| V3D["viewer3d.js Update"]
  Listeners -->|Callback| Lolly["lollipop.js Update"]
  Listeners -->|Callback| Tab["table.js Update"]

  classDef code fill:#f9f,stroke:#333,stroke-width:2px;
  class Sel,V3D,Lolly,Tab code;
Loading

Sources: src/ui/selection.js

The selection API provides three primary members defined in src/ui/selection.js:

  • id: A getter returning the active selectedId src/ui/selection.js:5-9.
  • select(clinvarId, source): Updates selectedId and iterates through listeners, executing each listener callback with the new ID and source context src/ui/selection.js:11-14.
  • subscribe(listener): Adds a listener function to the listeners Set and returns a cleanup function to unsubscribe src/ui/selection.js:16-19.

Sources: src/ui/selection.js:1-20


2. Color Palette and Visual Tokens (src/ui/palette.js)

The src/ui/palette.js module standardizes colors across the application, mapping functional states (such as AlphaFold pLDDT confidence scores, ClinVar clinical significance, and variant density) to visual styles.

pLDDT Confidence Bands

AlphaFold confidence scores (pLDDT) are classified into four standard bands using plddtBand(score) src/ui/palette.js:4-19:

Classification Styles

CLASS_STYLE maps ClinVar classification strings to visual groupings, colors, glyphs, and Chart.js point styles to ensure that color is never the sole visual indicator src/ui/palette.js:27-39:

Density and CSS Variables

The module computes sequential interpolation stops for variant density via densityColor(t) src/ui/palette.js:45-50 and extracts computed CSS variables through cssVar(name) to synchronize canvases with the active theme src/ui/palette.js:60-62.

Sources: src/ui/palette.js:1-62


3. Three-Dimensional Structure Viewer (src/ui/viewer3d.js)

The src/ui/viewer3d.js component wraps 3Dmol.js to render AlphaFold protein structures, displaying residues colored by pLDDT, density, or plain mode, with variant positions rendered as C-alpha spheres src/ui/viewer3d.js:1-62.

Lazy Loading

To optimize initial bundle size, 3Dmol.js is loaded asynchronously on first use via loadLibrary() src/ui/viewer3d.js:17-22:

let libraryPromise;
function loadLibrary() {
  libraryPromise ??= import('3dmol/build/3Dmol.es6.js');
  return libraryPromise;
}

src/ui/viewer3d.js:17-22

Structure Viewer Architecture

---
title: Structure Viewer Data Flow
---
graph TD
  Init["createStructureViewer container, onSelect"] -->|Awaits| LoadLib["loadLibrary 3dmol.es6.js"]
  LoadLib -->|Creates| Viewer["$3Dmol.createViewer"]
  Viewer -->|Registers| Pick["registerPicking setClickable / setHoverable"]
  LoadData["viewer.load pdbText, variants"] -->|Clears & Adds Model| Viewer
  Viewer -->|Applies Styles| Restyle["restyle function"]
  Restyle -->|ColorFunc| pLDDT["plddtColor / densityColor"]
  Restyle -->|Spheres| Spheres["addStyle sphere on C-alpha"]

  classDef code fill:#f9f,stroke:#333,stroke-width:2px;
  class LoadLib,Viewer,RegisterPicking,Restyle code;
Loading

Sources: src/ui/viewer3d.js:17-178

Interaction and Picking

registerPicking() configures C-alpha (CA) atoms to support interactive picking and tooltips src/ui/viewer3d.js:134-161:

  • Click: Triggers onSelect(variant.clinvarId) using the most severe representative variant at the clicked residue position src/ui/viewer3d.js:135-139.
  • Hover: Displays a floating DOM element (viewer-tooltip) containing residue metadata, pLDDT score, and overlapping variants src/ui/viewer3d.js:140-160.

Sources: src/ui/viewer3d.js:1-297


4. Lollipop Mutation Plot (src/ui/lollipop.js)

The src/ui/lollipop.js module implements a Chart.js scatter plot where the X-axis represents amino acid residue positions, pathogenic variants extend upward, benign variants extend downward, and stem heights correspond to $-\log_{10}(\text{gnomAD AF})$ src/ui/lollipop.js:1-20.

Chart.js Integration and Custom Plugins

The chart registers ScatterController, LinearScale, PointElement, and Tooltip src/ui/lollipop.js:7, and incorporates three custom plugins:

  1. stems plugin: Draws vertical lines (ctx.strokeStyle) from the baseline ($y = 0$) to each variant coordinate src/ui/lollipop.js:46-65.
  2. plddtStrip plugin: Renders a 12-pixel confidence heat strip directly beneath the X-axis, color-coded by residue pLDDT src/ui/lollipop.js:68-89.
  3. overlay plugin: Highlights the selected variant with a yellow ring and manages drag-to-zoom rubber-band rendering src/ui/lollipop.js:92-124.

Height Calculation

lollipopHeight(variant) computes vertical offsets with a maximum height cap of 7 src/ui/lollipop.js:16-20 src/ui/lollipop.js:10:

export function lollipopHeight(variant) {
  if (variant.rarity === 'unknown') return UNKNOWN_HEIGHT;
  if (variant.rarity === 'absent' || !variant.gnomad.af) return HEIGHT_CAP;
  return Math.min(HEIGHT_CAP, -Math.log10(variant.gnomad.af));
}

src/ui/lollipop.js:16-20

Sources: src/ui/lollipop.js:1-297


5. Variant Data Table (src/ui/table.js)

src/ui/table.js constructs an interactive, sortable tabular view of variants with text filtering, classification/rarity chips, and pagination src/ui/table.js:1-43.

Core Controls and Filtering

  • Text Search: Real-time input filtering matching protein changes, classifications, or review descriptors src/ui/table.js:46-56.
  • Numbering Toggle: A checkbox controlling onlyNumberingOk state constraints src/ui/table.js:57-65.
  • Filter Chips: Toggle buttons for ClinVar classifications and gnomAD rarity categories, paired with aria-pressed accessibility attributes src/ui/table.js:78-96.
  • Pagination: Displays rows in blocks of 50 with previous/next page handlers src/ui/table.js:112-170.

Row Interaction

Rows support mouse clicks and keyboard navigation (Enter or Space), updating selection state and applying CSS classes (selected, mismatch) src/ui/table.js:180-198.

Sources: src/ui/table.js:1-256


6. Informational Cards and Headers (src/ui/cards.js)

The src/ui/cards.js module renders summary stat cards, gene header metadata, and genetic constraint summaries src/ui/cards.js:1-193.

Key Functions

  • renderGeneHeader(root, { gene, freshness, onRefresh }): Populates gene names, UniProt/AlphaFold/ClinVar/gnomAD external links, alias notices, data freshness timestamps, and refresh controls src/ui/cards.js:18-89.
  • renderStatCards(root, { summary, skipped, capped }): Generates the five primary summary stat cards (analyzed variants, pathogenic share, confident-region share, ultra-rare/absent share, and skipped records breakdown) src/ui/cards.js:104-156.
  • renderConstraint(root, constraint): Displays pLI, LOEUF, and missense Z-score metrics with plain-English interpretations src/ui/cards.js:174-193.

Sources: src/ui/cards.js:1-366


Clone this wiki locally