From 1a176f082a97fec7652e0f1be6aaede576db78da Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 14 Apr 2026 07:02:46 +0200 Subject: [PATCH] Growth charts: restore full 9-percentile Epic/CDC line set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverted from the 7-line reduced set back to the full clinical set: 3rd, 5th, 10th, 25th, 50th, 75th, 90th, 95th, 97th — matching what Epic and the printed AAP/CDC/WHO charts display. Kept the mobile-readability improvements from the prior pass: - Each percentile is a distinct hue (red / deep-orange / orange / amber / green / blue / violet / purple / pink) - Outer 3rd + 97th are dashed (abnormal-threshold convention); 5th and 95th use a tighter dash; rest solid - 50th remains bold green to anchor the center - Label plugin's white halo + vertical nudge keeps 3/5/10 and 90/95/97 label stacks legible - Patient dot still on top, white-ringed Fill bands updated for 9 indexes (3↔97, 5↔95, 10↔90, 25↔75). --- public/js/calculators.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/public/js/calculators.js b/public/js/calculators.js index 99de526..64cb584 100644 --- a/public/js/calculators.js +++ b/public/js/calculators.js @@ -758,18 +758,20 @@ return M * Math.pow(1 + L * S * z, 1 / L); } - // Seven reference lines — classic WHO/CDC set minus the near-duplicate - // 5th/95th, which crowd the 3rd/10th and 90th/97th labels on mobile. - // Each percentile gets a distinct solid color; dashed only for the - // outermost bands (3rd / 97th) so they read as "abnormal thresholds". + // Full Epic / CDC / WHO reference set: 3, 5, 10, 25, 50, 75, 90, 95, 97. + // Each percentile has its own hue so clinicians can match the patient + // dot to a band at a glance. Outer pairs (3/97) dashed — they're the + // abnormal-threshold lines on AAP-published charts. var PERCENTILE_LINES = [ - { p: 3, z: -1.88079, color: 'rgba(220,38,38,0.85)', dash: [5,4], width: 1.4 }, // red - { p: 10, z: -1.28155, color: 'rgba(234,88,12,0.85)', dash: [], width: 1.2 }, // orange - { p: 25, z: -0.67449, color: 'rgba(202,138,4,0.85)', dash: [], width: 1.1 }, // amber + { p: 3, z: -1.88079, color: 'rgba(220,38,38,0.85)', dash: [6,4], width: 1.4 }, // red + { p: 5, z: -1.64485, color: 'rgba(234,88,12,0.8)', dash: [3,3], width: 1.1 }, // deep orange + { p: 10, z: -1.28155, color: 'rgba(245,158,11,0.85)', dash: [], width: 1.1 }, // orange + { p: 25, z: -0.67449, color: 'rgba(202,138,4,0.8)', dash: [], width: 1.0 }, // amber { p: 50, z: 0, color: 'rgba(22,163,74,0.95)', dash: [], width: 2.4 }, // green (center) - { p: 75, z: 0.67449, color: 'rgba(37,99,235,0.85)', dash: [], width: 1.1 }, // blue - { p: 90, z: 1.28155, color: 'rgba(124,58,237,0.85)', dash: [], width: 1.2 }, // violet - { p: 97, z: 1.88079, color: 'rgba(219,39,119,0.9)', dash: [5,4], width: 1.4 } // pink + { p: 75, z: 0.67449, color: 'rgba(37,99,235,0.8)', dash: [], width: 1.0 }, // blue + { p: 90, z: 1.28155, color: 'rgba(124,58,237,0.85)', dash: [], width: 1.1 }, // violet + { p: 95, z: 1.64485, color: 'rgba(168,85,247,0.8)', dash: [3,3], width: 1.1 }, // purple + { p: 97, z: 1.88079, color: 'rgba(219,39,119,0.9)', dash: [6,4], width: 1.4 } // pink ]; function generatePercentileCurves(lmsTable, percentileLines) { @@ -795,12 +797,13 @@ order: 10 }); }); - // Fill bands between symmetric percentile pairs. Indexes match the - // 7-line PERCENTILE_LINES array above: 3=0, 10=1, 25=2, 50=3, 75=4, 90=5, 97=6 + // Fill bands between symmetric percentile pairs. + // Indexes: 3=0, 5=1, 10=2, 25=3, 50=4, 75=5, 90=6, 95=7, 97=8 var fills = [ - { outer: 0, inner: 6, color: 'rgba(220,38,38,0.05)' }, // 3rd-97th band (widest) - { outer: 1, inner: 5, color: 'rgba(234,88,12,0.05)' }, // 10th-90th band - { outer: 2, inner: 4, color: 'rgba(163,163,163,0.05)' } // 25th-75th band (IQR) + { outer: 0, inner: 8, color: 'rgba(220,38,38,0.04)' }, // 3rd-97th (widest) + { outer: 1, inner: 7, color: 'rgba(234,88,12,0.04)' }, // 5th-95th + { outer: 2, inner: 6, color: 'rgba(245,158,11,0.04)' }, // 10th-90th + { outer: 3, inner: 5, color: 'rgba(163,163,163,0.05)' } // 25th-75th (IQR) ]; fills.forEach(function(f) { if (datasets[f.outer] && datasets[f.inner]) {