import React, { useState } from 'react'; import { RainLoadDiagrams } from '../diagrams/RainLoadDiagrams'; // --- DATA TABLES FROM SCREENSHOT --- const TABLES = { // value = dh (head in inches), keys = width/diameter rectClosed4: { widths: [6, 8, 12, 24], data: [ { dh: 0, 6: 0, 8: 0, 12: 0, 24: 0 }, { dh: 1, 6: 18, 8: 24, 12: 36, 24: 72 }, { dh: 2, 6: 50, 8: 66, 12: 100, 24: 200 }, { dh: 3, 6: 90, 8: 120, 12: 180, 24: 360 }, { dh: 4, 6: 140, 8: 186, 12: 280, 24: 560 }, { dh: 5, 6: 177, 8: 236, 12: 354, 24: 708 }, { dh: 6, 6: 206, 8: 274, 12: 412, 24: 824 }, { dh: 7, 6: 231, 8: 308, 12: 462, 24: 924 }, { dh: 8, 6: 253, 8: 338, 12: 506, 24: 1012 }, ] }, rectClosed6: { widths: [6, 8, 12, 24], data: [ { dh: 0, 6: 0, 8: 0, 12: 0, 24: 0 }, { dh: 1, 6: 18, 8: 24, 12: 36, 24: 72 }, { dh: 2, 6: 50, 8: 66, 12: 100, 24: 200 }, { dh: 3, 6: 90, 8: 120, 12: 180, 24: 360 }, { dh: 4, 6: 140, 8: 186, 12: 280, 24: 560 }, { dh: 5, 6: 194, 8: 258, 12: 388, 24: 776 }, { dh: 6, 6: 255, 8: 340, 12: 510, 24: 1020 }, { dh: 7, 6: 303, 8: 404, 12: 606, 24: 1212 }, { dh: 8, 6: 343, 8: 456, 12: 686, 24: 1372 }, ] }, channel: { // Channel Scupper widths: [6, 8, 12, 24], data: [ { dh: 0, 6: 0, 8: 0, 12: 0, 24: 0 }, { dh: 1, 6: 18, 8: 24, 12: 36, 24: 72 }, { dh: 2, 6: 50, 8: 66, 12: 100, 24: 200 }, { dh: 3, 6: 90, 8: 120, 12: 180, 24: 360 }, { dh: 4, 6: 140, 8: 186, 12: 280, 24: 560 }, { dh: 5, 6: 194, 8: 258, 12: 388, 24: 776 }, { dh: 6, 6: 255, 8: 340, 12: 510, 24: 1020 }, { dh: 7, 6: 321, 8: 428, 12: 642, 24: 1284 }, { dh: 8, 6: 393, 8: 522, 12: 786, 24: 1572 }, ] }, parapetCircular: { widths: [5, 6, 8, 10, 12, 14, 16], // Diameters data: [ { dh: 0, 5: 0, 6: 0, 8: 0, 10: 0, 12: 0, 14: 0, 16: 0 }, { dh: 1, 5: 6, 6: 7, 8: 8, 10: 8, 12: 10, 14: 10, 16: 10 }, { dh: 2, 5: 25, 6: 25, 8: 30, 10: 35, 12: 40, 14: 40, 16: 45 }, { dh: 3, 5: 50, 6: 55, 8: 65, 10: 75, 12: 75, 14: 90, 16: 95 }, { dh: 4, 5: 80, 6: 90, 8: 110, 10: 130, 12: 140, 14: 155, 16: 160 }, { dh: 5, 5: 115, 6: 135, 8: 165, 10: 190, 12: 220, 14: 240, 16: 260 }, { dh: 6, 5: 155, 6: 185, 8: 230, 10: 270, 12: 300, 14: 325, 16: 360 }, { dh: 7, 5: 190, 6: 230, 8: 300, 10: 350, 12: 410, 14: 440, 16: 480 }, { dh: 8, 5: 220, 6: 280, 8: 375, 10: 445, 12: 510, 14: 570, 16: 610 }, ] }, overflowDam8: { widths: [3, 4, 6], // Drain outlet size data: [ { dh: 0, 3: 0, 4: 0, 6: 0 }, { dh: 0.5, 3: 50, 4: 50, 6: 50 }, { dh: 1, 3: 75, 4: 100, 6: 100 }, { dh: 1.5, 3: 100, 4: 150, 6: 150 }, { dh: 2, 3: 125, 4: 200, 6: 200 }, { dh: 2.5, 3: 150, 4: 250, 6: 250 }, { dh: 3, 3: 175, 4: 300, 6: 300 }, { dh: 3.5, 3: 'NG', 4: 350, 6: 350 }, { dh: 4, 3: 'NG', 4: 362.5, 6: 450 }, { dh: 5, 3: 'NG', 4: 387.5, 6: 500 }, { dh: 5.5, 3: 'NG', 4: 400, 6: 550 }, { dh: 6, 3: 'NG', 4: 'NG', 6: 600 } ] }, overflowDam12_75: { widths: [6, 8], data: [ { dh: 0, 6: 0, 8: 0 }, { dh: 0.5, 6: 50, 8: 50 }, { dh: 1, 6: 100, 8: 100 }, { dh: 1.5, 6: 150, 8: 200 }, { dh: 2, 6: 200, 8: 300 }, { dh: 2.5, 6: 250, 8: 400 }, { dh: 3, 6: 350, 8: 500 }, { dh: 3.5, 6: 500, 8: 600 }, { dh: 4, 6: 550, 8: 700 }, // Interpolated { dh: 4.5, 6: 'NG', 8: 800 }, { dh: 5, 6: 500, 8: 900 }, { dh: 5.5, 6: 'NG', 8: 1000 }, { dh: 6, 6: 600, 8: 1100 } // Extrapolated ] }, overflowDam17: { widths: [10], data: [ { dh: 0, 10: 0 }, { dh: 1, 10: 100 }, { dh: 2, 10: 400 }, { dh: 3, 10: 700 }, { dh: 4, 10: 1100 }, // Interpolated { dh: 4.5, 10: 1200 } ] }, overflowStandpipe6: { widths: [4], data: [ { dh: 0, 4: 0 }, { dh: 1, 4: 50 }, { dh: 1.5, 4: 100 }, { dh: 2, 4: 150 }, { dh: 2.5, 4: 200 }, { dh: 3, 4: 300 }, { dh: 3.5, 4: 350 } ] } }; // Interpolation Logic // We need to find dh for a given Q. // The tables give Q for a given dh. // So we check the column corresponding to the width, and find where Q fits. const calculateDh = (table: any, size: number, Q: number): number | string => { if (!table || !table.data) return 'N/A'; // Find closest size if exact match not found? Or require exact match. // Screenshot has dropdown: "17'' dia Overflow Dam, 10'' drain outlet" // So distinct keys. const colKey = size.toString(); const rows = table.data; // Check if size exists // (Assuming correct table selected) // Iterate rows to bracket Q for (let i = 0; i < rows.length - 1; i++) { const rowLow = rows[i]; const rowHigh = rows[i + 1]; const qLow = rowLow[colKey]; const qHigh = rowHigh[colKey]; if (qLow === 'NG' || qHigh === 'NG') continue; if (Q >= qLow && Q <= qHigh) { // Interpolate if (qHigh === qLow) return rowLow.dh; const ratio = (Q - qLow) / (qHigh - qLow); const dh = rowLow.dh + ratio * (rowHigh.dh - rowLow.dh); return dh; } } // If Q is higher than max listed? const lastRow = rows[rows.length - 1]; if (Q > lastRow[colKey]) { return `> ${lastRow.dh}`; } return 0; // Q=0 or negative }; export const RainLoadsSheet: React.FC = () => { const [inputs, setInputs] = useState({ i: 7.23, ds: 2.00, A: 2500, dp: 2.00, }); // Device Selection const [deviceType, setDeviceType] = useState('rectClosed4'); const [deviceSize, setDeviceSize] = useState(6); // width or diameter // Calculate Q const Q = 0.0104 * inputs.A * inputs.i; // Calculate dh // Map selection to table and size let dh: number | string = 0; // Logic to select table based on type // In a real app we'd have a nicer selector structure. // For now simple switch or mapping. // Mock Table selection logic: let activeTable: any = TABLES.rectClosed4; if (deviceType === 'rectClosed4') activeTable = TABLES.rectClosed4; else if (deviceType === 'rectClosed6') activeTable = TABLES.rectClosed6; else if (deviceType === 'channel') activeTable = TABLES.channel; else if (deviceType === 'parapetCircular') activeTable = TABLES.parapetCircular; else if (deviceType === 'overflowDam8') activeTable = TABLES.overflowDam8; else if (deviceType === 'overflowDam12_75') activeTable = TABLES.overflowDam12_75; else if (deviceType === 'overflowDam17') activeTable = TABLES.overflowDam17; else if (deviceType === 'overflowStandpipe6') activeTable = TABLES.overflowStandpipe6; dh = calculateDh(activeTable, deviceSize, Q); const dhVal = typeof dh === 'number' ? dh : parseFloat(dh.toString().replace('>', '').trim()) || 0; // Fallback const R = 5.2 * (inputs.ds + dhVal + inputs.dp); return (