Skip to content

Commit e2ccaa9

Browse files
feat: add interactive decay chain visualization (#13) (#67)
## Summary Implements issue #13 - Interactive Radioactive Decay Chain Visualization This PR adds a comprehensive interactive decay chain visualization system that shows multi-generation radioactive decay pathways. Key features: - **Multi-generation decay tree building** - Recursive depth-first traversal of RadioNuclides table (46,797 decay records) - **Interactive zoom/pan/pinch controls** - Using react-zoom-pan-pinch library (25KB) with both UI controls and mouse/touch gestures - **Horizontal left-to-right layout** - Reingold-Tilford-inspired tree layout algorithm optimized for wide decay chains - **Mutually exclusive row expansion** - Only one decay chain visible at a time for cleaner UX - **Responsive table height** - Auto-adjusts when filter panels expand/collapse using transitionend events ## Implementation Details **New Files:** - `src/services/decayChainService.ts` - Core service for building decay chains from database - `src/components/DecayChainDiagram.tsx` - Interactive SVG visualization with zoom controls - `src/constants/decaySeries.ts` - Famous natural decay series metadata (U-238, Th-232, U-235, Np-237) **Modified Files:** - `src/pages/ShowElementData.tsx` - Replaced expanded decay rows with DecayChainDiagram - `src/components/NuclideDetailsCard.tsx` - Added decay chain section for radioactive nuclides - `src/components/SortableTable.tsx` - Added expandedContentNoPadding prop and fixed table height recalculation - `src/types/index.ts` - Added DecayChainNode and DecayChainResult interfaces **Critical Bug Fix:** - Fixed `isNuclideStable()` to check RadioNuclides table FIRST before logHalfLife threshold - Previously, U-238 (logHalfLife=9.65) was incorrectly marked stable despite having decay data ## UI Changes **Decays Tab (ShowElementData):** - Clicking a decay row now expands an interactive decay chain diagram - Zoom controls: Auto-fit, zoom in/out, reset - Mouse wheel to zoom, click-and-drag to pan, double-click to zoom in - Mobile: pinch-to-zoom and drag to pan - Only one row expands at a time for focused viewing **Integrated Tab (NuclideDetailsCard):** - Added "Radioactive Decay Chain" section for radioactive nuclides - Interactive controls for adjusting max depth (1-10 generations) and minimum branching ratio (1-100%) - Collapsible section to save space for stable nuclides ## Technical Details **Layout Algorithm:** - Horizontal tree layout with configurable spacing - Left-to-right progression through decay generations - SVG-based rendering with curved edges - Color-coded nodes: radioactive (red), stable (green), unknown stability (gray) **Performance:** - Configurable max depth prevents infinite loops in decay cycles - Branching ratio threshold filters minor decay paths - Virtualized table rendering handles large datasets **Dependencies:** - Added: react-zoom-pan-pinch (25KB gzipped) for zoom/pan functionality ## Test Plan - [x] View decay chain for U-238 (14 generations, 18 branches) - [x] Verify horizontal left-to-right layout - [x] Test zoom controls (auto-fit, zoom in/out, reset) - [x] Test mouse wheel zoom and click-and-drag pan - [x] Test double-click to zoom in - [x] Test mobile pinch-to-zoom (Safari/Chrome on iOS/Android) - [x] Verify mutually exclusive row expansion in Decays tab - [x] Verify table height adjusts when filter panel expands/collapses - [x] Verify no page scrolling with expanded decay chains - [x] Test with various nuclides (Th-232, U-235, Np-237) - [ ] E2E tests for decay chain rendering - [ ] E2E tests for zoom/pan interactions - [ ] Cross-browser testing (Chrome, Firefox, Safari) ## Screenshots ### Decays Tab - Expanded Row <img width="1280" height="1024" alt="image" src="https://github.com/user-attachments/assets/a42779d9-b63a-47c7-8f0a-1d7203bd4cd9" /> >Interactive decay chain replaces simple parent→daughter→granddaughter display ### Integrated Tab - Nuclide Details <img width="1280" height="1024" alt="image" src="https://github.com/user-attachments/assets/ac572b15-cec7-416d-a75e-413dc974967c" /> >Full decay chain with controls for depth and branching ratio --- Closes #13
1 parent 4db68c3 commit e2ccaa9

10 files changed

Lines changed: 1189 additions & 183 deletions

File tree

CLAUDE.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ The application uses **sql.js** (SQLite compiled to WebAssembly) to run queries
7171
**Key tables**:
7272
- `NuclidesPlus` - Nuclide properties (Z, A, binding energy, half-life, boson/fermion flags)
7373
- `ElementPropertiesPlus` - Element properties (melting point, density, electronegativity, etc.)
74+
- `RadioNuclides` - Radioactive decay data (46,797 records) with decay modes, radiation types, energies, intensities, and half-lives
7475
- `FusionAll` - A + B → C reactions (includes neutrino-involved reactions)
7576
- `FissionAll` - A → B + C reactions (includes neutrino-involved reactions)
7677
- `TwoToTwoAll` - A + B → C + D reactions (includes neutrino-involved reactions)
@@ -135,6 +136,54 @@ const result = queryFusionReactions(db, {
135136
- **Context up**: Components access global state via `useDatabase()` and `useTheme()` hooks
136137
- **URL state**: ShowElementData uses `useSearchParams` for shareable state
137138

139+
### Radioactive Decay Chain Visualization
140+
141+
The application includes interactive multi-generation decay chain visualization for radioactive nuclides:
142+
143+
**Architecture** (`src/services/decayChainService.ts`):
144+
- `traceDecayChain()` - Recursively builds decay trees from `RadioNuclides` table
145+
- Parameters: `db`, `Z`, `A`, `maxDepth` (default: 10), `minBranchingRatio` (default: 1%)
146+
- Returns: Tree structure with nodes containing nuclide, decay mode, branching ratio, children[]
147+
- Handles branching decay paths and circular references (e.g., isomeric transitions)
148+
- Stop conditions: stable nuclide (LHL > 9), max depth reached, or already visited
149+
- `getDaughterNuclide()` - Calculates daughter Z/A from decay modes (A, B-, B+, EC, IT)
150+
- `getLinearDecayChain()` - Simplified linear chain following primary decay mode only
151+
152+
**UI Components**:
153+
- `DecayChainDiagram.tsx` - SVG tree visualization with:
154+
- Reingold-Tilford tree layout algorithm for balanced node spacing
155+
- Color-coded decay modes (alpha=red, beta-=blue, beta+=green, EC=purple, IT=yellow)
156+
- Interactive nodes (click to navigate to nuclide details page)
157+
- Hover tooltips with full decay information
158+
- Responsive sizing with automatic viewBox calculation
159+
- `NuclideDetailsCard.tsx` - Integrates decay chain with:
160+
- Collapsible "Decay Chain Visualization" section
161+
- Interactive depth slider (1-15 generations)
162+
- Branching ratio filter (1-100%)
163+
- Chain metadata display (total generations, branch count, terminal nuclides)
164+
165+
**Famous Decay Series** (`src/constants/decaySeries.ts`):
166+
- Uranium-238 series (4n+2) - 14 steps → Pb-206
167+
- Thorium-232 series (4n) - 10 steps → Pb-208
168+
- Uranium-235 actinium series (4n+3) - 11 steps → Pb-207
169+
- Neptunium-237 series (4n+1) - 11 steps → Bi-209 (synthetic)
170+
171+
**Usage Example**:
172+
```typescript
173+
import { traceDecayChain } from '../services/decayChainService'
174+
175+
// Trace U-238 decay chain
176+
const chain = traceDecayChain(db, 92, 238, {
177+
maxDepth: 10,
178+
minBranchingRatio: 5 // Only show branches ≥5%
179+
})
180+
181+
// chain.root contains full tree
182+
// chain.totalGenerations = maximum depth
183+
// chain.branchCount = number of decay branches
184+
// chain.terminalNuclides = array of leaf nodes
185+
```
186+
138187
## Data Types
139188

140189
All type definitions are in `src/types/index.ts`:
@@ -146,6 +195,9 @@ All type definitions are in `src/types/index.ts`:
146195
- `TwoToTwoReaction` - Two inputs → two outputs
147196
- `QueryFilter` - Filter parameters for reaction queries
148197
- `QueryResult` - Standardized query response with timing
198+
- `DecayChainNode` - Tree node for multi-generation decay sequences (nuclide, decay mode, branching ratio, children)
199+
- `DecayChainResult` - Complete decay chain result (root node, total generations, branch count, terminal nuclides)
200+
- `DecayData` - Individual decay record from RadioNuclides table (decay mode, radiation type, energy, intensity, half-life)
149201

150202
## Database Column Mapping
151203

package-lock.json

Lines changed: 17 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"react-markdown": "^9.0.3",
5050
"react-router-dom": "^6.20.0",
5151
"react-virtualized": "^9.22.6",
52+
"react-zoom-pan-pinch": "^3.7.0",
5253
"recharts": "^2.10.3",
5354
"remark-gfm": "^4.0.0",
5455
"remark-github": "^12.0.0",

0 commit comments

Comments
 (0)