Three clinical modules were added to the OHIF Viewer as standalone extensions, plus a runtime bug fix for the i18n library. Subsequently, several enhancements were made to all three modules based on user feedback.
File: platform/i18n/src/index.js
Problem: App crashed on load with:
TypeError: _this.services.languageUtils.isWhitelisted is not a function
Root Cause: Version mismatch — i18next (newer) removed isWhitelisted(), but i18next-browser-languagedetector (older) still calls it during language detection.
Fix: Monkey-patched LanguageDetector.prototype.detect at module-load time so the missing method is injected right before it is called.
extensions/ecg-tools/
├── package.json ← @custom/extension-ecg-tools
└── src/
├── index.tsx ← OHIF extension entry point
├── utils/
│ └── ecgCalculations.ts ← Clinical math
└── panels/
└── PanelEcgViewer.tsx ← Main UI
Clinical Calculations (ecgCalculations.ts):
| Function | Formula | Description |
|---|---|---|
bazettQTc(qtMs, rrMs) |
QTc = QT / √RR (seconds) |
QT interval corrected for heart rate |
heartRate(rrMs) |
HR = 60000 / RR |
Beats per minute from RR interval |
qrsAxis(leadI, aVF) |
atan2(aVF, leadI) × 180/π |
Electrical axis in degrees |
rrVariance(intervals[]) |
std deviation formula | RR interval variability |
standardCalibration(px/mm) |
25 mm/s, 10 mm/mV | Convert pixels to clinical units |
QRS Axis Interpretation:
-30° to +90°→ Normal-30° to -90°→ Left Axis Deviation (LAD)+90° to +180°→ Right Axis Deviation (RAD)> ±180°→ Extreme Axis Deviation
Tools available in the UI:
CURSOR— Pan/inspectCALIBRATE_H/CALIBRATE_V— Set pixel-to-mm scaleTIME— Measure time intervals (ms)AMPLITUDE— Measure voltage (mV)RR_INTERVAL— Measure R-to-R distance → HRQT_INTERVAL— Measure QT → compute QTcQRS_AXIS— Enter Lead I & aVF amplitudesCOMPARE— Side-by-side study comparison
ECG Improvements (post-initial):
- Measurement annotation font size reduced to ~12px for cleaner readout
- Image rendering quality improved (
imageSmoothingQuality = 'high') for sharper ECG waveforms - Canvas max size raised (1800×1200) to support higher-resolution ECG images
extensions/smart-paint/
├── package.json ← @custom/extension-smart-paint
└── src/
├── index.tsx ← OHIF extension entry point
├── tools/
│ └── SmartPaintTool.ts ← Paint engine
└── panels/
└── PanelSmartPaint.tsx ← Interactive UI
Paint Engine (SmartPaintTool.ts):
| Function | Description |
|---|---|
paintBrush(state, cx, cy, radius, sensitivity, pixelData, erase) |
Paint or erase pixels in a circle; optional intensity-based region grow |
commitHistory(state) |
Save current mask to undo stack (max 50 steps) |
undo(state) |
Restore previous mask |
redo(state) |
Re-apply undone mask |
clearMask(key) |
Reset all painted pixels |
maskToContour(state) |
Marching-squares algorithm → array of [x,y] boundary points |
renderMaskOverlay(ctx, state, color) |
Draw mask as semi-transparent color on canvas |
countPaintedPixels(state) |
Count total painted pixels → used for area display |
UI Features:
- Upload any image file
- Brush tool with adjustable radius and sensitivity
- Custom SVG cursor that scales with brush size
- Erase mode toggle
- 2D / 3D mode toggle
- Undo / Redo buttons
- "Extract Contour" button → traces mask boundary
- Painted area display — shown as
px²below the canvas and in status bar (live, updates on every stroke) - Panel icon changed to segmentation icon (
tab-segmentation)
extensions/flatfoot/
├── package.json ← @custom/extension-flatfoot
└── src/
├── index.tsx ← OHIF extension entry point
├── utils/
│ └── flatfootCalculations.ts ← Clinical foot math
└── panels/
└── PanelFlatfoot.tsx ← Measurement UI
Measurement Tools:
DISTANCE— Ruler between two pointsCALCANEAL_PITCH— 2-point angle from horizontalCLARKE_ANGLE— 3-point angle at arch apexARCH_INDEX— 2-point span (total foot length + mid-foot)MEARYS_ANGLE— 4 points defining talus and first metatarsal axesTRIANGLE— 3 corner points → all 3 angles + side midpoints + areaTRIANGLE_SPLIT— Baseline (2 pts) + apex → perpendicular creates 2 sub-triangles with all 6 angles
Flatfoot Improvements (post-initial):
- All measurement points are now draggable — click and drag any placed dot to reposition it; values recalculate live
- Triangle tool added — 3-corner measurement with law-of-cosines angles, midpoints, area
- Split Triangle tool added — Arch-Index-style baseline + apex, perpendicular drop creates 2 triangles; D point (foot of perpendicular) is also independently draggable
| URL | Component | Description |
|---|---|---|
/ecg-viewer |
EcgViewer |
Full ECG analysis page |
/smart-paint |
SmartPaint |
Smart Paint ROI page |
/flatfoot |
Flatfoot |
Flatfoot measurement page |
Files changed:
platform/app/src/routes/index.tsx— Added 3 route entriesplatform/app/src/routes/EcgViewer/EcgViewer.tsx— Lazy-loads extension panelplatform/app/src/routes/SmartPaint/SmartPaintRoute.tsx— New fileplatform/app/src/routes/Flatfoot/FlatfootRoute.tsx— New file
File: platform/app/src/routes/WorkList/WorkList.tsx
Three buttons added to the toolbar area above the study list:
| Button | Color | Navigates To |
|---|---|---|
| ECG Viewer | Green | /ecg-viewer |
| Smart Paint ROI | Cyan | /smart-paint |
| Flatfoot Analysis | Amber | /flatfoot |
File: platform/app/src/pluginImports.js
Added dynamic imports for all new extensions and mode:
extensions.push("@custom/extension-ecg-tools");
extensions.push("@custom/extension-smart-paint");
extensions.push("@custom/extension-flatfoot");
modes.push("@custom/mode-ecg");Files: modes/ecg/src/index.tsx, modes/ecg/src/id.ts
- Mode ID:
@custom/mode-ecg - Route:
viewer/ecg - Panels: ECG Tools, Smart Paint, Flatfoot in right-side panel layout
□ cd /home/artem/Desktop/project/frontend/Viewers
□ yarn install (install any new deps)
□ yarn dev (start dev server)
□ Open http://localhost:3000
□ Check browser console — no red errors
□ See 3 buttons on WorkList page
□ Test each clinical tool with a sample image
| File | Type | What Changed |
|---|---|---|
platform/i18n/src/index.js |
Fix | Monkey-patch for isWhitelisted crash |
platform/app/src/pluginImports.js |
Feature | Register 3 extensions + 1 mode |
platform/app/src/routes/index.tsx |
Feature | Add 3 new routes |
platform/app/src/routes/WorkList/WorkList.tsx |
Feature | Add 3 toolbar nav buttons |
extensions/ecg-tools/src/panels/PanelEcgViewer.tsx |
Update | Smaller font, better image quality, larger canvas |
extensions/smart-paint/src/index.tsx |
Update | Icon changed to tab-segmentation |
extensions/smart-paint/src/tools/SmartPaintTool.ts |
Update | Added countPaintedPixels() |
extensions/smart-paint/src/panels/PanelSmartPaint.tsx |
Update | Painted area display below canvas |
extensions/flatfoot/src/panels/PanelFlatfoot.tsx |
Update | Triangle tool, Split Triangle tool, drag for all points |
extensions/ecg-tools/** |
New | Full ECG Tools extension |
extensions/smart-paint/** |
New | Full Smart Paint extension |
extensions/flatfoot/** |
New | Full Flatfoot extension |
modes/ecg/** |
New | OHIF ECG mode |