Skip to content

Conversation

@jayhesselberth
Copy link
Member

Summary

Adds x-axis position windowing to aggregate plots to support visualization of long nanopore reads (1000-2000 nt) without cramming all data into view. Users can interactively select a position range using a dual-handle slider, with automatic bounds detection from BAM alignments.

Changes

UI Components

  • ✨ Dual-handle range slider (rc-slider) for position selection
  • 🎯 Auto-populates min/max from selected reference's alignment data
  • 🔄 "Reset to Full Range" button to restore default view
  • 🎨 Yellow/orange slider styling matching native VSCode controls

API Updates

  • Added x_axis_min/x_axis_max parameters to plot_aggregate()
  • Added get_reference_range(bam_path, reference) function
  • Updated SquiggyRuntimeAPI.generatePlot() signature
  • Added requestReferenceRange and updateReferenceRange messages

Python Implementation

  • Data windowing: filters positions before plotting (more performant than view windowing)
  • Explicit x-axis range setting with Bokeh Range1d
  • Smart filtering: handles position-keyed dicts (pileup, signal) separately from non-position dicts (modifications)
  • Implemented for aggregate.py strategy

Bug Fixes

  • 🐛 Fixed horizontal scrollbar in Plot Options panel
  • 🐛 Fixed control cutoff issues on right side
  • 🐛 Added box-sizing: border-box globally for proper width calculations
  • 🐛 Prevented horizontal overflow in webview base HTML
  • 🐛 Fixed ValueError when filtering modification dicts

Testing

Tested with:

  • ✅ Short reads (~100 nt) - slider disabled, shows full range
  • ✅ Long reads (1000-2000 nt) - slider enables interactive windowing
  • ✅ Position filtering with modifications enabled
  • ✅ Reset to full range functionality
  • ✅ Multiple references with different alignment ranges

Screenshots

[User to add screenshots showing slider in action]

Future Work

The following plot strategies still need windowing implementation:

  • single_read.py
  • eventalign.py
  • overlay.py
  • stacked.py

Additional enhancements:

  • Validation and edge case handling
  • Unit tests for windowing logic
  • Performance testing with very long reads (>10kb)

🤖 Generated with Claude Code

jayhesselberth and others added 4 commits November 21, 2025 09:01
Adds x-axis position windowing to aggregate plots to support visualization
of long nanopore reads (1000-2000 nt) without cramming all data into view.

## UI Changes
- Added dual-handle range slider (rc-slider) for position range selection
- Slider auto-populates min/max from selected reference's BAM alignment data
- "Reset to Full Range" button to restore default view
- Fixed horizontal scrollbar and control cutoff issues in Plot Options panel

## API Changes
- Added x_axis_min/x_axis_max parameters to plotting functions
- Added get_reference_range() function to query BAM alignment ranges
- Updated SquiggyRuntimeAPI.generatePlot() signature
- Added requestReferenceRange message for webview communication

## Implementation
- Data windowing approach: filters positions before plotting
- Explicit x-axis range setting with Bokeh Range1d
- Handles position-keyed dicts (pileup, signal) vs non-position dicts (mods)
- Implemented for aggregate.py strategy

## Styling Fixes
- Fixed Plot Options panel overflow issues
- Added box-sizing: border-box globally
- Prevented horizontal scrolling in webview base HTML
- Uniform padding matching other panels (Samples)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Implements windowing for remaining plot strategies and fixes lints.

## Implementation
- **single_read.py**: Data filtering based on x-axis type (time, position, genomic)
  - Filters signal arrays and seq_to_sig_map
  - Handles base positions and modification annotations
- **eventalign.py**: View windowing with Range1d
  - Takes precedence over clip_x_to_alignment
  - Works with both position and time modes
- **overlay.py**: View windowing for multi-read overlays
- **stacked.py**: View windowing for stacked reads

## Lint Fixes
- Added get_reference_range to __all__ in __init__.py
- Fixed raise statement to include 'from e' in io.py

All plot strategies now support x_axis_min/x_axis_max parameters.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…owing

Remove archived rc-slider dependency in favor of two native HTML number inputs.
This eliminates an unmaintained dependency, reduces bundle size by ~36 KiB,
and provides better UX for precise position entry.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Update PlotOptionsViewProvider test to include new x-axis windowing
fields in aggregate plot event expectations. Also apply code formatting
fixes from ruff and prettier.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@codecov-commenter
Copy link

codecov-commenter commented Nov 22, 2025

Codecov Report

❌ Patch coverage is 16.17647% with 114 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.74%. Comparing base (4e552d2) to head (e83a6b2).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
squiggy/plot_strategies/aggregate.py 12.06% 51 Missing ⚠️
squiggy/io.py 3.57% 27 Missing ⚠️
squiggy/plot_strategies/single_read.py 14.28% 24 Missing ⚠️
squiggy/plot_strategies/eventalign.py 50.00% 4 Missing ⚠️
squiggy/plot_strategies/overlay.py 42.85% 4 Missing ⚠️
squiggy/plot_strategies/stacked.py 42.85% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #160      +/-   ##
==========================================
- Coverage   73.47%   71.74%   -1.73%     
==========================================
  Files          27       27              
  Lines        4404     4538     +134     
  Branches      883      917      +34     
==========================================
+ Hits         3236     3256      +20     
- Misses       1168     1282     +114     
Components Coverage Δ
Core Logic ∅ <ø> (∅)
Plotting ∅ <ø> (∅)
GUI ∅ <ø> (∅)
Files with missing lines Coverage Δ
squiggy/__init__.py 80.00% <ø> (ø)
squiggy/plotting.py 38.94% <ø> (ø)
squiggy/plot_strategies/eventalign.py 83.53% <50.00%> (-1.82%) ⬇️
squiggy/plot_strategies/overlay.py 54.61% <42.85%> (-0.67%) ⬇️
squiggy/plot_strategies/stacked.py 55.20% <42.85%> (-0.74%) ⬇️
squiggy/plot_strategies/single_read.py 66.01% <14.28%> (-8.14%) ⬇️
squiggy/io.py 71.00% <3.57%> (-3.49%) ⬇️
squiggy/plot_strategies/aggregate.py 81.35% <12.06%> (-15.90%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

3 participants