Files
RollCalcPython/static/rollcalc_stddev_integration.js
T

275 lines
9.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* INTEGRATION PATCH FOR STDDEV RANGES
* ====================================
*
* This shows how to integrate the StdDev calculator into the existing
* Direct Calculation button handler in roll_calculator.html
*
* CHANGES:
* 1. Load stddev data from article-data.json when article is selected
* 2. Modify the d-calc button handler to use ranges
* 3. Update Forklift checker to use worst-case weight
* 4. Keep everything backward compatible
*/
// ===================================================================
// PATCH 1: STORE STDDEV IN HIDDEN FIELDS DURING ARTICLE SELECTION
// ===================================================================
// Add this to populateArticleDropdowns_v14() in rollcalc_improvements.js
// In the article selection handler for d-art:
/*
if (match) {
console.log('[Article Select] Found:', match.nr, '- Thickness:', match.thickness, 'Area Weight:', match.area_weight);
// 1. Auto-fill Thickness
document.getElementById('d-th').value = match.thickness;
// 2. Auto-fill Area Weight
if (match.area_weight && match.area_weight > 0) {
document.getElementById('d-aw').value = match.area_weight;
}
// 3. Auto-fill Roll Width
var widthMatch = match.name.match(/(\d+[,\.]\d+)\s*x\s*\d+/);
if (widthMatch) {
var width = widthMatch[1].replace(',', '.');
document.getElementById('de-wi').value = width;
}
// NEW: Store stddev values in hidden attributes
document.getElementById('d-th').dataset.stddev = match.thickness_stddev || 0;
document.getElementById('d-aw').dataset.stddev = match.area_weight_stddev || 0;
console.log('[StdDev] Stored:', {
thickness_stddev: match.thickness_stddev,
area_weight_stddev: match.area_weight_stddev
});
setTimeout(function() {
triggerAutoWeightCalculation();
}, 50);
}
*/
// ===================================================================
// PATCH 2: MODIFY d-calc BUTTON HANDLER FOR DIAMETER MODE
// ===================================================================
// Replace the diameter calculation section in the d-calc click handler:
/*
OLD CODE (diameter mode):
if (mode === 'diameter') {
if (!d_mm || !t_mm || !L_m) { alert('Please enter d, t and L.'); return; }
const D_nom = Math.sqrt(d_mm*d_mm + (4*L_m*1000*t_mm)/Math.PI);
resLabel.textContent = 'Roll Diameter (D)';
resVal.textContent = D_nom.toFixed(1) + ' mm';
if (tol) {
const D_min = Math.sqrt(d_mm*d_mm + (4*L_m*1000*(t_mm-tol))/Math.PI);
const D_max = Math.sqrt(d_mm*d_mm + (4*L_m*1000*(t_mm+tol))/Math.PI);
resRange.textContent = 'Min: ' + D_min.toFixed(1) + ' mm | Max: ' + D_max.toFixed(1) + ' mm';
} else { resRange.textContent = ''; }
document.getElementById('d-di').value = D_nom.toFixed(1);
calculatedLength = L_m;
}
NEW CODE (with stddev):
*/
// Example replacement for diameter mode:
function calculateDiameterWithStddev(d_mm, t_mm, t_stddev, L_m, tol) {
if (!d_mm || !t_mm || !L_m) {
alert('Please enter d, t and L.');
return false;
}
// Get stddev from data attribute (set during article selection)
const thField = document.getElementById('d-th');
const actualStddev = t_stddev || parseFloat(thField?.dataset.stddev || 0);
const resBox = document.getElementById('d-result');
const resLabel = document.getElementById('d-res-label');
const resVal = document.getElementById('d-res-val');
const resRange = document.getElementById('d-res-range');
const diField = document.getElementById('d-di');
// Use StdDev calculator
const diameterRanges = window.StdDevCalculator.calculateDiameterRanges(
d_mm, t_mm, actualStddev, L_m
);
resLabel.textContent = 'Roll Diameter (D)';
resVal.textContent = diameterRanges.nom.toFixed(1) + ' mm';
// Show ±2σ range
const d_low = Math.min(diameterRanges.min, diameterRanges.max);
const d_high = Math.max(diameterRanges.min, diameterRanges.max);
let rangeText = `Range (±2σ): ${d_low.toFixed(1)} – ${d_high.toFixed(1)} mm`;
if (tol && tol > 0) {
const d_tol_min = diameterRanges.nom - tol;
const d_tol_max = diameterRanges.nom + tol;
rangeText += ` | Tol: ${d_tol_min.toFixed(1)} – ${d_tol_max.toFixed(1)} mm`;
}
resRange.textContent = rangeText;
diField.value = diameterRanges.nom.toFixed(1);
resBox.style.display = 'block';
console.log('[StdDev-Calc] Diameter with ranges:', diameterRanges);
return {
calculatedLength: L_m,
diameterRanges: diameterRanges
};
}
// ===================================================================
// PATCH 3: MODIFY WEIGHT CALCULATION FOR STDDEV RANGES
// ===================================================================
// Replace the weight calculation in calcWeight():
/*
OLD:
function calcWeight(length) {
const wi = parseFloat(document.getElementById('de-wi').value) || 0;
const aw = parseFloat(document.getElementById('d-aw').value) || 0;
if (wi > 0 && aw > 0 && length > 0) {
const w = (aw * length * wi / 1000).toFixed(1);
document.getElementById('d-wo').value = w;
return parseFloat(w);
}
document.getElementById('d-wo').value = '';
return null;
}
NEW:
*/
function calcWeightWithStddev(length) {
const wi = parseFloat(document.getElementById('de-wi').value) || 0;
const aw = parseFloat(document.getElementById('d-aw').value) || 0;
const awField = document.getElementById('d-aw');
const awStddev = parseFloat(awField?.dataset.stddev || 0);
if (wi > 0 && aw > 0 && length > 0) {
// Calculate weight ranges
const weightRanges = window.StdDevCalculator.calculateWeightRanges(
aw, awStddev, length, wi
);
// Store in field and data attributes
const woField = document.getElementById('d-wo');
woField.value = weightRanges.nom.toFixed(1);
woField.dataset.weight_nom = weightRanges.nom.toFixed(1);
woField.dataset.weight_min = weightRanges.min.toFixed(1);
woField.dataset.weight_max = weightRanges.max.toFixed(1);
console.log('[StdDev-Weight] Calculated ranges:', {
nom: weightRanges.nom.toFixed(1),
min: weightRanges.min.toFixed(1),
max: weightRanges.max.toFixed(1)
});
return weightRanges;
}
document.getElementById('d-wo').value = '';
return null;
}
// ===================================================================
// PATCH 4: UPDATE FORKLIFT CHECKER TO USE WORST-CASE
// ===================================================================
// In ForkliftChecker.evaluate(), use worst-case weight:
/*
OLD:
evaluate(weightKg, coreMm, category) {
const box = document.getElementById('forkliftCheck');
// ... check if weightKg > limit
}
NEW:
*/
function evaluateForkliftWithWorstCase(coreMm, category) {
const woField = document.getElementById('d-wo');
if (!woField) return true;
// Get worst-case weight
const weight_nom = parseFloat(woField.value) || 0;
const weight_max = parseFloat(woField.dataset.weight_max) || weight_nom;
// Use maximum for safety
const weightToCheck = Math.max(weight_nom, weight_max);
console.log('[Forklift-StdDev] Using worst-case weight:', {
nominal: weight_nom.toFixed(1),
worst_case: weight_max.toFixed(1),
checking: weightToCheck.toFixed(1)
});
if (window.ForkliftChecker) {
return window.ForkliftChecker.evaluate(weightToCheck, coreMm, category);
}
return true;
}
// ===================================================================
// COMPLETE EXAMPLE: NEW d-calc HANDLER WITH STDDEV
// ===================================================================
/*
document.getElementById('d-calc').addEventListener('click', () => {
const mode = document.querySelector('.mode-btn.active')?.dataset.mode || 'diameter';
const d_mm = parseFloat(document.getElementById('d-co').value) || 0;
const t_mm = parseFloat(document.getElementById('d-th').value) || 0;
const tol = parseFloat(document.getElementById('d-tol').value) || 0;
const L_m = parseFloat(document.getElementById('d-le').value) || 0;
const D_mm = parseFloat(document.getElementById('d-di').value) || 0;
const category = (document.getElementById('d-cat')?.value || '').toLowerCase();
if (mode === 'diameter') {
// Use new function with stddev
const result = calculateDiameterWithStddev(d_mm, t_mm, null, L_m, tol);
if (!result) return;
const calculatedLength = result.calculatedLength;
const diameterRanges = result.diameterRanges;
// Calculate weight with stddev
const weightRanges = calcWeightWithStddev(calculatedLength);
// Evaluate forklift with worst-case weight
evaluateForkliftWithWorstCase(d_mm, category);
// Store for Load Optimizer (use nominal)
if (weightRanges) {
window.loadOptimizerUI.optimizer.setRollData({
rollDiameter: diameterRanges.nom,
coreDiameter: d_mm,
rollWidth: parseFloat(document.getElementById('de-wi').value) || 0,
rollWeight: weightRanges.nom, // Nominal for optimizer
m2PerRoll: calculatedLength * (parseFloat(document.getElementById('de-wi').value) || 0),
productLength: calculatedLength
});
}
}
// ... handle other modes ...
});
*/
// ===================================================================
// EXPORT FUNCTIONS
// ===================================================================
window.StdDevIntegration = {
calculateDiameterWithStddev: calculateDiameterWithStddev,
calcWeightWithStddev: calcWeightWithStddev,
evaluateForkliftWithWorstCase: evaluateForkliftWithWorstCase
};
console.log('[StdDevIntegration] Integration functions ready');