Skip to content

feat(core): add ECGViewport for DICOM waveform rendering#2621

Open
TFRadicalImaging wants to merge 1 commit intocornerstonejs:mainfrom
TFRadicalImaging:feat/ecg-viewport
Open

feat(core): add ECGViewport for DICOM waveform rendering#2621
TFRadicalImaging wants to merge 1 commit intocornerstonejs:mainfrom
TFRadicalImaging:feat/ecg-viewport

Conversation

@TFRadicalImaging
Copy link
Contributor

Add a new ECG viewport type that renders 12-lead ECG traces from DICOM Waveform data using a canvas-based custom rendering pipeline (same pattern as VideoViewport and WSIViewport).

  • ECGViewport class with grid, trace, and label rendering
  • Pan (left-drag) and Zoom (right-drag) tool support
  • Per-channel trace visibility toggle
  • Supports InlineBinary, BulkDataURI, and retrieveBulkData data sources
  • Typed WaveformSequenceInput interface for the setEcg() API
  • Interactive example with 12-lead ECG demo data

Context

Adds a new ECG viewport type to Cornerstone3D for rendering 12-lead ECG traces from DICOM Waveform data (SOP Class 1.2.840.10008.5.1.4.1.1.9.1.1). This follows the same custom rendering pipeline pattern used by VideoViewport and WSIViewport — canvas 2D rendering, no VTK.js dependency.

The viewport accepts parsed DICOM WaveformSequence metadata via setEcg() and handles data loading from InlineBinary, BulkDataURI, or retrieveBulkData sources.

Changes & Results

New files:

  • packages/core/src/RenderingEngine/ECGViewport.ts — Main viewport class (~940 lines) with grid, trace, and label rendering
  • packages/core/src/types/ECGViewportTypes.ts — Type definitions (ECGChannel, ECGWaveformData, WaveformSequenceInput, WaveformDataSource)
  • packages/core/src/types/ECGViewportProperties.ts — Viewport properties extending ViewportProperties
  • packages/core/src/types/IECGViewport.ts — Type alias for the viewport
  • packages/core/examples/ecg/index.ts — Interactive example with 12-lead ECG demo data

Modified files:

  • packages/core/src/enums/ViewportType.ts — Added ECG = 'ecg'
  • packages/core/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts — Registered ECGViewport
  • packages/core/src/index.ts — Exported ECGViewport
  • packages/core/src/types/index.ts — Exported new ECG types

Features:

  • ECG paper grid rendering (major/minor lines, adaptive spacing at different zoom levels)
  • White trace polylines on black background with yellow channel labels
  • Pan (left-drag) and Zoom (right-drag) via standard Cornerstone tools
  • Per-channel trace visibility toggle
  • Dynamic channel scaling to fit canvas aspect ratio
  • Viewport auto-resizes to match ECG content dimensions
  • Channel min/max cached at data load time for efficient rendering

Testing

  1. Run yarn example ecg
  2. Verify 12-lead ECG traces render with grid background
  3. Left-drag to pan, right-drag to zoom
  4. Click "Reset View" to reset camera
  5. Toggle individual lead checkboxes to show/hide traces
  6. Verify traces rescale when toggling channels on/off

Checklist

PR

  • My Pull Request title is descriptive, accurate and follows the
    semantic-release format and guidelines.

Code

  • My code has been well-documented (function documentation, inline comments,
    etc.)

Tested Environment

  • OS: macOS 25.1.0
  • Node version: >=20
  • Browser: Versão 144.0.7559.134 (Oficial Version) (arm64)

Add a new ECG viewport type that renders 12-lead ECG traces from DICOM
Waveform data using a canvas-based custom rendering pipeline (same pattern
as VideoViewport and WSIViewport).

- ECGViewport class with grid, trace, and label rendering
- Pan (left-drag) and Zoom (right-drag) tool support
- Per-channel trace visibility toggle
- Supports InlineBinary, BulkDataURI, and retrieveBulkData data sources
- Typed WaveformSequenceInput interface for the setEcg() API
- Interactive example with 12-lead ECG demo data
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

Comments