extract calculator dosing helpers

This commit is contained in:
Daniel 2026-05-08 04:32:09 +02:00
parent c2eb550048
commit ae0ca83ccb
3 changed files with 44 additions and 6 deletions

View file

@ -2,6 +2,7 @@ import { parseAgeMonths, formatParsedAge } from './calculators/age.js';
import { calculateAapBilirubinAssessment, classifyBhutaniRisk, loadAapBilirubinThresholds, loadBhutaniZones } from './calculators/bilirubin.js';
import { calculateBMIAssessment, loadBmiLmsData } from './calculators/bmi.js';
import { calculateBPAssessment, computeBPPercentile, loadBpReferenceData } from './calculators/bp.js';
import { calculateBsa, calculateWeightBasedDose } from './calculators/dosing.js';
import { loadEquipmentData, renderEquipmentResult } from './calculators/equipment.js';
import { loadGrowthLmsData } from './calculators/growth.js';
import { initImageLightbox } from './calculators/lightbox.js';
@ -497,7 +498,7 @@ initImageLightbox();
var height = parseFloat(document.getElementById('bsa-height').value);
if (!weight || !height) { showToast('Enter weight and height', 'error'); return; }
var bsa = Math.sqrt(height * weight / 3600);
var bsa = calculateBsa(weight, height);
var resultDiv = document.getElementById('bsa-result');
resultDiv.classList.remove('hidden');
resultDiv.innerHTML =
@ -527,10 +528,10 @@ initImageLightbox();
if (!weight || !dosePerKg) { showToast('Enter weight and dose', 'error'); return; }
var singleDose = weight * dosePerKg;
var capped = false;
if (maxDose > 0 && singleDose > maxDose) { singleDose = maxDose; capped = true; }
var dailyDose = singleDose * freq;
var dose = calculateWeightBasedDose(weight, dosePerKg, freq, maxDose, conc);
var singleDose = dose.singleDose;
var dailyDose = dose.dailyDose;
var capped = dose.capped;
var rows = '<div class="calc-result-item"><div class="calc-result-label">Single Dose</div><div class="calc-result-value">' + singleDose.toFixed(1) + ' <span style="font-size:12px;">mg</span></div>'
+ (capped ? '<div class="calc-result-sub" style="color:var(--red);">Capped at max ' + maxDose + ' mg</div>' : '') + '</div>'
@ -538,7 +539,7 @@ initImageLightbox();
+ '<div class="calc-result-sub">' + singleDose.toFixed(1) + ' mg x ' + freq + '/day</div></div>';
if (conc > 0) {
var vol = singleDose / conc;
var vol = dose.volumeMl;
rows += '<div class="calc-result-item"><div class="calc-result-label">Volume per Dose</div><div class="calc-result-value">' + vol.toFixed(1) + ' <span style="font-size:12px;">mL</span></div>'
+ '<div class="calc-result-sub">at ' + conc + ' mg/mL</div></div>';
}

View file

@ -0,0 +1,20 @@
export function calculateBsa(weightKg, heightCm) {
return Math.sqrt(heightCm * weightKg / 3600);
}
export function calculateWeightBasedDose(weightKg, dosePerKg, frequencyPerDay, maxDoseMg, concentrationMgPerMl) {
var singleDose = weightKg * dosePerKg;
var capped = false;
if (maxDoseMg > 0 && singleDose > maxDoseMg) {
singleDose = maxDoseMg;
capped = true;
}
var dailyDose = singleDose * frequencyPerDay;
var volumeMl = concentrationMgPerMl > 0 ? singleDose / concentrationMgPerMl : null;
return {
singleDose: singleDose,
dailyDose: dailyDose,
volumeMl: volumeMl,
capped: capped
};
}

View file

@ -402,3 +402,20 @@ test('BP calculator preserves legacy outputs across sex/age/height/BP combinatio
assert.equal(actual.classification.classification, expected.classification, expected.name + ' classification');
});
});
test('dosing helpers preserve BSA and weight-based dose outputs', async () => {
const dosing = await import('../public/js/calculators/dosing.js');
assert.equal(Number(dosing.calculateBsa(20, 110).toFixed(3)), 0.782);
const uncapped = dosing.calculateWeightBasedDose(12, 15, 3, 0, 40);
assert.equal(uncapped.singleDose, 180);
assert.equal(uncapped.dailyDose, 540);
assert.equal(uncapped.volumeMl, 4.5);
assert.equal(uncapped.capped, false);
const capped = dosing.calculateWeightBasedDose(40, 15, 4, 500, 50);
assert.equal(capped.singleDose, 500);
assert.equal(capped.dailyDose, 2000);
assert.equal(capped.volumeMl, 10);
assert.equal(capped.capped, true);
});