import { usePileCapStore } from '../../store/pileCapStore'; import { DraggableLabel } from './DraggableLabel'; export const PileCapDiagram = () => { const geometry = usePileCapStore(state => state.geometry); const results = usePileCapStore(state => state.results); // Global Diagram State const isLocked = usePileCapStore(state => state.diagramState.isLocked); const labelPositions = usePileCapStore(state => state.diagramState.labelPositions); const setDiagramLocked = usePileCapStore(state => state.setDiagramLocked); const updateLabelPosition = usePileCapStore(state => state.updateLabelPosition); const getLabelPos = (id: string, defaultX: number, defaultY: number) => { return labelPositions[id] || { x: defaultX, y: defaultY }; }; const scale = 40; const svgWidth = geometry.length * scale + 150; // Increased width for legend const svgHeight = geometry.width * scale + 120; const offsetX = 50; const offsetY = 70; // Increased top margin for title const startX = (geometry.length - (geometry.pileColumns - 1) * geometry.pileSpacingX) / 2; const startY = (geometry.width - (geometry.pileRows - 1) * geometry.pileSpacingY) / 2; // Helper to get pile color based on reaction const getPileColor = (reaction: number, maxReaction: number) => { if (reaction < 0) return '#ffcccc'; // Uplift (Red tint) // Compression scaling (White to Dark Blue) // Normalize reaction between 0 and maxReaction const ratio = maxReaction > 0 ? reaction / maxReaction : 0; // Interpolate between White (#ffffff) and Blue (#2b5797) // Simple opacity approach on blue base const opacity = 0.1 + (ratio * 0.9); return `rgba(43, 87, 151, ${opacity})`; }; return (
Pile Cap Layout & Reactions
{results && (
Governing: {results.governingCombination}
)}
{/* Controls */}
{/* Definitions for markers/gradients if needed */} {/* Main Pile Cap Rect */} {/* Dimensions */} {/* Column */} {/* Piles */} {Array.from({ length: geometry.pileRows }).map((_, row) => Array.from({ length: geometry.pileColumns }).map((_, col) => { const x = startX + col * geometry.pileSpacingX; const y = startY + row * geometry.pileSpacingY; const pileNumber = row * geometry.pileColumns + col + 1; const pile = results?.pileReactions.find(p => p.pileNumber === pileNumber); const reaction = pile?.reaction || 0; const isUplift = reaction < 0; const isMax = results && Math.abs(reaction - results.maxPileReaction) < 0.01; const pileColor = results ? getPileColor(reaction, results.maxPileReaction) : '#f0f0f0'; return ( results.maxPileReaction * 0.5) ? "white" : "black"} fontWeight="bold" pointerEvents="none" > {pileNumber} {results && ( )} ); }) )} {/* Legend */} {results && ( Legend Max Comp. Min Comp. Uplift Critical Pile )}
); };