New files for stdev calculation for v0.2
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* 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');
|
||||
Reference in New Issue
Block a user