/* Neonatal jaundice treatment threshold calculator Copyright (C) 2024 Lee Yingtong Li This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ // -------------- // Graph plotting function plotGraphData() { let gestation = document.getElementById('gestation').valueAsNumber; if (isNaN(gestation) || gestation < 23) { chart.data.datasets[0].data = []; chart.data.datasets[1].data = []; } else { chart.data.datasets[0].data = [...Array(14*24).keys()].map((i) => i / 24).map((d) => ({x: d, y: phototherapy_thresh(d, gestation)})); chart.data.datasets[1].data = [...Array(14*24).keys()].map((i) => i / 24).map((d) => ({x: d, y: exchange_thresh(d, gestation)})); } chart.update(); } Chart.defaults.color = '#111827'; // gray-900 Chart.defaults.font.family = 'Manrope, Helvetica, Arial, sans-serif'; const chart = new Chart(document.getElementById('bilirubinChart'), { type: 'scatter', data: { datasets: [ { label: 'Phototherapy', data: [], showLine: true, pointStyle: false }, { label: 'Exchange transfusion', data: [], showLine: true, pointStyle: false }, { label: 'Measurement', data: [] } ] }, options: { scales: { x: { title: { display: true, text: 'Chronological age (days)' }, min: 0, max: 14, ticks: { stepSize: 0.25, callback: (value) => value % 1 == 0 ? value : '', autoSkip: false, maxRotation: 0 }, grid: { color: (context) => context.tick.value % 1 == 0 ? '#9ca3af' : '#e5e7eb' // gray-400 / gray-200 } }, y: { title: { display: true, text: 'Total bilirubin (μmol/L)' }, min: 0, max: 550, ticks: { stepSize: 10, callback: (value) => value % 50 == 0 ? value : '', autoSkip: false }, grid: { color: (context) => context.tick.value % 50 == 0 ? '#9ca3af' : '#e5e7eb' // gray-400 / gray-200 } } }, interaction: { mode: 'x', intersect: false }, plugins: { tooltip: { callbacks: { title: (context) => prettyPrintDays(context[0].parsed.x), label: (context) => context.dataset.label + ': ' + Math.round(context.parsed.y) }, filter: (context, idx, items) => Math.abs(context.parsed.x - items[0].parsed.x) < 0.5/24 } }, maintainAspectRatio: false } }); plotGraphData(); // ------------ // Prefill form let dateNow = dateToISOStringLocal(new Date()); if (document.getElementById('time_birth').value === '') { document.getElementById('time_birth').value = dateNow; } if (document.getElementById('time_measurement').value === '') { document.getElementById('time_measurement').value = dateNow; } // -------------------------- // Plot bilirubin measurement function updateBilirubin() { let resultDiv = document.getElementById('result'); let resultP = resultDiv.querySelector('p'); let bilirubin = document.getElementById('bilirubin').valueAsNumber; let gestation = document.getElementById('gestation').valueAsNumber; if (document.getElementById('time_birth').value === '') { resultDiv.className = 'hidden'; return; } if (document.getElementById('time_measurement').value === '') { resultDiv.className = 'hidden'; return; } if (isNaN(bilirubin)) { resultDiv.className = 'hidden'; return; } if (isNaN(gestation) || gestation < 23) { resultDiv.className = 'hidden'; return; } let [d, result_text, text_colour, background_colour, accent_colour] = describeBilirubin(gestation, new Date(document.getElementById('time_birth').value), new Date(document.getElementById('time_measurement').value), bilirubin); chart.data.datasets[2].data = [{x: d, y: bilirubin}]; chart.update(); resultDiv.className = 'border-l-4 ' + accent_colour + ' ' + background_colour + ' py-2 px-4 mt-4'; resultP.className = 'text-sm ' + text_colour; resultP.innerHTML = result_text; } updateBilirubin();