Skip to content

feat(visualization): add gene and transcript visualization - #29

Merged
dsk-dev-ai merged 3 commits into
mainfrom
feat/visualization-gene-transcript
Aug 10, 2026
Merged

feat(visualization): add gene and transcript visualization#29
dsk-dev-ai merged 3 commits into
mainfrom
feat/visualization-gene-transcript

Conversation

@dsk-dev-ai

@dsk-dev-ai dsk-dev-ai commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Summary

Implements Phase 6.3 — Gene / Transcript Visualization for GenomeAI.

This builds on the Phase 6.1 Visualization Foundation and Phase 6.2
Genome Browser, adding a reusable biological annotation layer for
visualizing genes, transcripts, and exon structures using the existing
genomic coordinate system.

Features

Gene Visualization

  • Gene genomic span
  • Gene label/name
  • Chromosome position
  • Strand/direction representation
  • Coordinate-aligned rendering

Transcript Visualization

  • Multiple transcripts per gene
  • Transcript genomic boundaries
  • Transcript labels
  • Transcript strand
  • Independent transcript lanes

Exon Visualization

  • Exon blocks
  • Intron connections
  • Exon ordering
  • Coordinate-based exon positioning
  • Support for multiple transcript structures

Genome Browser Integration

  • Reuses the existing Genome Browser coordinate system
  • Reuses existing viewport/region utilities
  • Reuses existing visualization architecture
  • Avoids a second independent coordinate implementation
  • Designed for future biological annotation tracks

Accessibility

  • Accessible visualization labels
  • Keyboard/focus support where applicable
  • Meaningful SVG semantics
  • Accessible interactive elements

Testing

Added coverage for:

  • Gene data handling
  • Transcript data handling
  • Exon data handling
  • Strand handling
  • Coordinate-to-screen geometry
  • Transcript lane layout
  • Rendering
  • Multiple transcripts
  • Empty/loading/error states
  • Accessibility
  • Integration with the existing genome coordinate system
  • API adapter behavior where applicable

Architecture

The visualization follows the existing architecture:

Genome Browser

Shared genomic coordinate system

Gene / Transcript visualization layer

Gene + Transcript + Exon tracks

The implementation uses React + TypeScript and existing browser/SVG
rendering primitives.

No C++, WebGPU, WebAssembly, Three.js, D3, or Cytoscape dependencies
were introduced.

API

The implementation uses the existing GenomeAI API/data contracts where
available.

No new backend infrastructure was introduced unless required by an
existing supported contract.

Documentation

Updated:

  • docs/visualization/README.md
  • docs/visualization/roadmap.md

Added Gene / Transcript visualization documentation covering:

  • Data model
  • Coordinate system
  • Gene rendering
  • Transcript rendering
  • Exon rendering
  • Strand handling
  • Architecture
  • API integration
  • Accessibility
  • Testing
  • Future extension points

Verification

  • make setup
  • make lint
  • make typecheck
  • make test
  • pnpm turbo build
  • Web application verified
  • Visualization route verified
  • Gene/transcript visualization tested
  • No unrelated backend changes
  • Documentation updated

Roadmap

Completed:

  • Phase 6.1 — Visualization Foundation
  • Phase 6.2 — Genome Browser
  • Phase 6.3 — Gene / Transcript Visualization

Next:

  • Phase 6.4 — Variant Visualization

Future visualization milestones remain unchanged.

Scope

This PR intentionally does not implement:

  • Variant visualization
  • Protein structure visualization
  • Network visualization
  • Scientific charts
  • WebGPU
  • WebAssembly
  • C++
  • AI functionality
  • Workflow functionality
  • Backend search infrastructure

Summary by Sourcery

Add a Phase 6.3 gene/transcript visualization layer to the GenomeAI web app, integrating a new SVG viewer and demo with the existing genome browser and coordinate system.

New Features:

  • Introduce a typed gene/transcript/exon domain model and pure geometry utilities for coordinate-aligned isoform visualization.
  • Add a GeneTranscriptViewer SVG component and GeneTranscriptDemo page section that render gene spans, transcript lanes, intron connectors, and exon blocks with accessible interaction.
  • Provide a thin gene/transcript data adapter over the existing coordinate-search API, with an injectable exon source and dev-only fixtures for sample exon structures.

Enhancements:

  • Export shared API utilities so gene/transcript adapters can reuse the existing paginated coordinate-search request pipeline.
  • Update visualization docs and roadmap to document Phase 6.3, its scope, data flow, API usage, accessibility, and testing, and mark the milestone as implemented.

Documentation:

  • Add a dedicated Gene / Transcript visualization document describing the model, geometry, adapter, exon data boundary, accessibility, and tests.
  • Update the visualization README and roadmap to reflect Phase 6.3 completion, describe what it provides, and adjust future milestone aggregation.

Tests:

  • Add unit tests for the gene/transcript domain model, geometry, API adapter, and SVG viewer, covering normalization, grouping, layout, pagination, accessibility, and selection behavior.

Summary by CodeRabbit

  • New Features
    • Added an interactive gene and transcript visualization with genomic coordinates, exons, introns, strand indicators, tooltips, keyboard support, and transcript selection.
    • Added TP53 and reverse-strand gene examples to the visualization page.
    • Added data loading, validation, grouping, pagination, and retry handling for gene/transcript records.
  • Documentation
    • Documented the completed gene/transcript visualization milestone and capabilities.
  • Tests
    • Added extensive coverage for rendering, selection, geometry, normalization, grouping, and data fetching.

@sourcery-ai

sourcery-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a reusable Gene / Transcript visualization layer on top of the existing Genome Browser, including a typed domain model, pure geometry utilities, a coordinate-search-based data adapter, a React SVG viewer component, demo wiring, dev exon fixtures, and accompanying docs/tests, all reusing the shared genomic coordinate system without backend changes.

File-Level Changes

Change Details Files
Introduce typed gene/transcript/exon domain model plus grouping, normalization, and validation utilities for coordinate-search results.
  • Defined Gene, GeneTranscript, and GeneExon interfaces with one-based inclusive coordinates and strand typing.
  • Implemented normalization helpers (toGene, toTranscript, toExon) to adapt Phase 5 coordinate-search responses into the typed model, including safe defaults and strand handling.
  • Added validators and utilities (isValidExon/isValidTranscript/isValidGene, sortTranscripts, groupTranscriptsByGene) to filter bad spans and deterministically assign transcripts to genes.
apps/web/src/lib/genome/geneTranscript.ts
apps/web/src/lib/genome/geneTranscript.test.ts
Add pure layout geometry helpers for mapping genomic spans to pixel coordinates and laying out gene/transcript lanes.
  • Implemented intervalToPixels, exonToPixels, and transcriptToPixels using the shared Genome Browser scale with viewport clipping.
  • Defined layoutTranscriptLanes and geneTranscriptHeight to compute lane positions and total SVG height from transcript count.
  • Introduced visual constants (lane heights, exon height, intron stroke, label offsets) and covered them with unit tests.
apps/web/src/lib/genome/geneTranscriptGeometry.ts
apps/web/src/lib/genome/geneTranscriptGeometry.test.ts
Create a gene/transcript data adapter over the existing coordinate-search API, including optional exon enrichment.
  • Exported RawSearchItem and requestCoordinateSearch from the shared genome API module so they can be reused by Phase 6.3 adapters.
  • Implemented fetchGeneTranscripts to request gene and transcript coordinate searches in parallel, normalize items, group transcripts under genes, and plug in an ExonSource.
  • Added tests verifying pagination, grouping semantics, exonSource behavior, and request wiring against the mock fetch pipeline.
apps/web/src/lib/genome/api.ts
apps/web/src/lib/genome/geneTranscriptApi.ts
apps/web/src/lib/genome/geneTranscriptApi.test.ts
Implement the GeneTranscriptViewer React SVG component and a TP53-based visualization demo integrated into the Visualization page.
  • Implemented GeneTranscriptViewer to render a gene lane and one lane per transcript with strand-aware arrows, intron connectors, exon blocks, shared label gutter, and keyboard/ARIA-based selection.
  • Added TP53 and BRCA1-like exon fixtures and a GeneTranscriptDemo that uses the shared VisualizationContainer and viewport conventions to showcase the viewer at /visualization.
  • Extended the visualization route to include the new demo, updated metadata copy, and ensured alignment with the Genome Browser coordinate system.
apps/web/src/components/genome/GeneTranscriptViewer.tsx
apps/web/src/components/genome/GeneTranscriptViewer.test.tsx
apps/web/src/app/visualization/GeneTranscriptDemo.tsx
apps/web/src/app/visualization/page.tsx
apps/web/src/lib/genome/geneTranscript.fixtures.ts
Document the Gene / Transcript visualization milestone and integrate it into the Phase 6 visualization docs and roadmap.
  • Updated visualization README and roadmap to mark Phase 6.3 Gene / Transcript Visualization as implemented, describe its scope, constraints, and integration, and adjust future milestone descriptions.
  • Added a dedicated gene-transcript.md describing architecture, data model, geometry, API usage, exon boundary, accessibility, tests, and file map.
  • Ensured docs consistently reference the lack of backend exon support and the dev-only nature of fixtures.
docs/visualization/README.md
docs/visualization/roadmap.md
docs/visualization/gene-transcript.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 37716485-b7f8-4954-8e75-188cbac067fd

📥 Commits

Reviewing files that changed from the base of the PR and between 4041790 and fbcdf5e.

📒 Files selected for processing (8)
  • apps/web/src/app/visualization/GeneTranscriptDemo.tsx
  • apps/web/src/app/visualization/GenomeBrowserDemo.tsx
  • apps/web/src/components/genome/GeneTranscriptViewer.test.tsx
  • apps/web/src/components/genome/GeneTranscriptViewer.tsx
  • apps/web/src/lib/genome/geneTranscript.fixtures.ts
  • apps/web/src/lib/genome/geneTranscript.test.ts
  • apps/web/src/lib/genome/geneTranscript.ts
  • docs/visualization/gene-transcript.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/web/src/components/genome/GeneTranscriptViewer.test.tsx
  • docs/visualization/gene-transcript.md
  • apps/web/src/lib/genome/geneTranscript.test.ts
  • apps/web/src/app/visualization/GeneTranscriptDemo.tsx
  • apps/web/src/lib/genome/geneTranscript.ts

📝 Walkthrough

Walkthrough

The pull request adds a typed gene/transcript model, coordinate-search adapter, viewport geometry, strand-aware SVG rendering, transcript selection, fixtures, tests, and visualization-page integration.

Changes

Gene Transcript Visualization

Layer / File(s) Summary
Gene/transcript domain model
apps/web/src/lib/genome/geneTranscript.ts, apps/web/src/lib/genome/geneTranscript.test.ts, apps/web/src/lib/genome/geneTranscript.fixtures.ts
Adds typed gene, transcript, and exon models with normalization, validation, grouping, sorting, fixtures, and tests.
Coordinate-search adapter
apps/web/src/lib/genome/api.ts, apps/web/src/lib/genome/geneTranscriptApi.ts, apps/web/src/lib/genome/geneTranscriptApi.test.ts
Adds concurrent gene/transcript retrieval, optional exon enrichment, exported search utilities, and pagination tests.
Geometry and SVG viewer
apps/web/src/lib/genome/geneTranscriptGeometry.ts, apps/web/src/lib/genome/geneTranscriptGeometry.test.ts, apps/web/src/components/genome/GeneTranscriptViewer.tsx, apps/web/src/components/genome/GeneTranscriptViewer.test.tsx
Adds viewport clipping, transcript lane layout, strand-aware SVG rendering, accessible selection, and tests.
Visualization-page integration and documentation
apps/web/src/app/visualization/GeneTranscriptDemo.tsx, apps/web/src/app/visualization/GenomeBrowserDemo.tsx, apps/web/src/app/visualization/page.tsx, docs/visualization/*
Adds the TP53 demo, shares the TP53 viewport fixture with the Genome Browser, and documents the Phase 6.3 implementation and roadmap status.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant VisualizationPage
  participant GeneTranscriptDemo
  participant useVisualizationData
  participant GeneTranscriptViewer
  VisualizationPage->>GeneTranscriptDemo: render gene/transcript demo
  GeneTranscriptDemo->>useVisualizationData: load TP53 fixture data
  useVisualizationData-->>GeneTranscriptDemo: return loading, error, or gene data
  GeneTranscriptDemo->>GeneTranscriptViewer: render loaded gene and chr17 viewport
  GeneTranscriptViewer-->>GeneTranscriptDemo: report transcript selection
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 68.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding gene and transcript visualization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/visualization-gene-transcript

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In geneTranscript.ts you re-declare RawSearchItem instead of reusing the exported RawSearchItem from lib/genome/api.ts; consider importing it to avoid type drift if the raw search shape changes.
  • The ExonSource in fetchGeneTranscripts always overwrites transcript.exons, which could discard real API-provided exons in the future; you may want to only enrich when exons is empty or explicitly merge the two sources.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `geneTranscript.ts` you re-declare `RawSearchItem` instead of reusing the exported `RawSearchItem` from `lib/genome/api.ts`; consider importing it to avoid type drift if the raw search shape changes.
- The `ExonSource` in `fetchGeneTranscripts` always overwrites `transcript.exons`, which could discard real API-provided exons in the future; you may want to only enrich when `exons` is empty or explicitly merge the two sources.

## Individual Comments

### Comment 1
<location path="apps/web/src/lib/genome/geneTranscript.ts" line_range="75" />
<code_context>
   pagination?: PaginationPayload
 }

-type RawSearchItem = Record<string, unknown>
+/** A raw, untyped item from a search response. */
+export type RawSearchItem = Record<string, unknown>
</code_context>
<issue_to_address>
**suggestion:** Reuse the shared RawSearchItem type from the genome API instead of redefining it here.

This module now defines and exports its own `RawSearchItem`, separate from the one in `lib/genome/api.ts`. Please import and reuse the shared type instead to avoid duplication and keep the contracts in sync as the raw search item shape changes.
</issue_to_address>

### Comment 2
<location path="apps/web/src/lib/genome/geneTranscript.ts" line_range="226-227" />
<code_context>
+    const owned: GeneTranscript[] = []
+    for (const transcript of transcripts) {
+      if (!isValidTranscript(transcript)) continue
+      const explicit = transcript.geneId !== undefined && transcript.geneId === gene.id
+      const contained =
+        transcript.chromosome === gene.chromosome &&
+        transcript.start >= gene.start &&
</code_context>
<issue_to_address>
**issue:** Explicit transcript→gene linking may fail when `gene.id` differs from `gene.geneId`.

In `groupTranscriptsByGene`, explicit linking uses `transcript.geneId === gene.id`, but `toGene` sets `id` to `idOf(item.id) || gene_id`. When `item.id` is a search-record id and `gene_id` is an accession, `transcript.geneId` will match `gene.geneId`, not `gene.id`, so valid transcript–gene pairs may be treated as unlinked and dropped. To make explicit linking robust, compare against `gene.geneId ?? gene.id` or check both fields.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread apps/web/src/lib/genome/geneTranscript.ts Outdated
Comment thread apps/web/src/lib/genome/geneTranscript.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/app/visualization/GeneTranscriptDemo.tsx`:
- Line 25: Align the viewport in GeneTranscriptDemo by changing the chromosome
17 start coordinate from 7_660_000 to 7_650_000, matching GenomeBrowserDemo
while preserving the existing end coordinate and memoization.

In `@apps/web/src/components/genome/GeneTranscriptViewer.test.tsx`:
- Around line 124-145: Update the reverseGene fixture in the
GeneTranscriptViewer test to set its start and end bounds to the BRCA1 interval,
instead of inheriting TP53_FIXTURE values. Keep the existing transcript and
viewport values unchanged so GeneGlyph renders and the test exercises the
intended reverse-strand gene.

In `@apps/web/src/components/genome/GeneTranscriptViewer.tsx`:
- Around line 106-111: Replace the role="img" assignment on the interactive SVG
in GeneTranscriptViewer with a non-leaf role such as group, preserving the
accessible geneAriaLabel name so the transcript controls remain exposed to
screen readers.
- Around line 242-252: Keep strand markers within each clipped span by capping
the arrowhead length used in the GeneGlyph rendering at span.width, and ensure
the body width does not exceed the remaining span after that arrowhead. Also
update the width-based rendering path at
apps/web/src/components/genome/GeneTranscriptViewer.tsx lines 269-275 to cap the
arrowhead base offset at width.

In `@apps/web/src/lib/genome/geneTranscript.fixtures.ts`:
- Around line 108-110: Update the negative-strand exon fixture entries so
transcription order is represented correctly: change exon-3’s rank to 1 and
exon-1’s rank to 3, while leaving exon-2 and the genomic coordinates unchanged.

In `@apps/web/src/lib/genome/geneTranscript.ts`:
- Around line 226-232: Update the transcript ownership condition in the
gene-matching logic so coordinate containment is considered only when
transcript.geneId is undefined; when an explicit geneId is present, assign the
transcript only if it matches gene.id or gene.geneId. Add a regression test
covering a contained transcript whose geneId references a different gene.

In `@docs/visualization/gene-transcript.md`:
- Around line 40-49: Add language identifiers to the fenced code blocks in the
GeneTranscriptViewer documentation: mark the architecture diagram block as text
and the validation-command block as shell, including the additional block near
the validation commands.
- Around line 80-85: Update the JSON request example in the gene-transcript
documentation to use valid integer literals for interval.start and interval.end:
replace the underscore-separated values with 7650000 and 7700000, leaving the
remaining fields unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5525443a-48af-42e1-8108-f556deb4a5a9

📥 Commits

Reviewing files that changed from the base of the PR and between 6615d05 and 4041790.

📒 Files selected for processing (15)
  • apps/web/src/app/visualization/GeneTranscriptDemo.tsx
  • apps/web/src/app/visualization/page.tsx
  • apps/web/src/components/genome/GeneTranscriptViewer.test.tsx
  • apps/web/src/components/genome/GeneTranscriptViewer.tsx
  • apps/web/src/lib/genome/api.ts
  • apps/web/src/lib/genome/geneTranscript.fixtures.ts
  • apps/web/src/lib/genome/geneTranscript.test.ts
  • apps/web/src/lib/genome/geneTranscript.ts
  • apps/web/src/lib/genome/geneTranscriptApi.test.ts
  • apps/web/src/lib/genome/geneTranscriptApi.ts
  • apps/web/src/lib/genome/geneTranscriptGeometry.test.ts
  • apps/web/src/lib/genome/geneTranscriptGeometry.ts
  • docs/visualization/README.md
  • docs/visualization/gene-transcript.md
  • docs/visualization/roadmap.md

Comment thread apps/web/src/app/visualization/GeneTranscriptDemo.tsx Outdated
Comment thread apps/web/src/components/genome/GeneTranscriptViewer.test.tsx
Comment thread apps/web/src/components/genome/GeneTranscriptViewer.tsx
Comment thread apps/web/src/components/genome/GeneTranscriptViewer.tsx
Comment thread apps/web/src/lib/genome/geneTranscript.fixtures.ts Outdated
Comment thread apps/web/src/lib/genome/geneTranscript.ts
Comment thread docs/visualization/gene-transcript.md Outdated
Comment thread docs/visualization/gene-transcript.md
@dsk-dev-ai
dsk-dev-ai merged commit b9bfcda into main Aug 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant