A Pen by raffyjudy05 on CodePen.
Created
March 13, 2025 12:18
bNGYoYJ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Dionega Healthcare Analytics</title> | |
<link rel="stylesheet" href="styles.css"> | |
<!-- Chart.js CDN for data visualization --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script> | |
</head> | |
<body> | |
<header> | |
<div class="container header-content"> | |
<div class="logo"> | |
<h1>Dionega Healthcare Analytics</h1> | |
<p>Empowering Care Through Precise Vital Analysis</p> | |
</div> | |
<div class="date-time"> | |
<div id="current-date">Loading date...</div> | |
<div id="current-time">Loading time...</div> | |
</div> | |
</div> | |
</header> | |
<nav> | |
<div class="container"> | |
<ul class="nav-links"> | |
<li><a href="#welcome" class="nav-link active-nav" data-page="welcome">Welcome</a></li> | |
<li><a href="#dashboard" class="nav-link" data-page="dashboard">Live Dashboard</a></li> | |
<li><a href="#encode" class="nav-link" data-page="encode">Data Encoding</a></li> | |
</ul> | |
</div> | |
</nav> | |
<main class="container"> | |
<!-- Welcome Page --> | |
<section id="welcome" class="page active"> | |
<h2 class="page-title">Welcome to Dionega Healthcare Analytics</h2> | |
<div class="welcome-content"> | |
<img src="https://via.placeholder.com/800x400" alt="Healthcare Analytics" class="welcome-image"> | |
<div class="welcome-message"> | |
<p>Welcome to Dionega, your trusted resource for accurate and insightful vital sign interpretation and analytics. We're dedicated to empowering healthcare professionals with the knowledge they need to make informed decisions and provide optimal patient care.</p> | |
</div> | |
<div class="dashboard-grid"> | |
<div class="dashboard-card"> | |
<h3>Vital Sign Analysis</h3> | |
<p>Our platform provides real-time analysis of patient vital signs, helping you make informed clinical decisions quickly.</p> | |
</div> | |
<div class="dashboard-card"> | |
<h3>Data Visualization</h3> | |
<p>Interactive charts and graphs make it easy to identify trends and patterns in patient health data.</p> | |
</div> | |
<div class="dashboard-card"> | |
<h3>Clinical Decision Support</h3> | |
<p>Automated interpretation of vital signs based on established medical standards helps verify your clinical assessments.</p> | |
</div> | |
</div> | |
<button class="btn" id="get-started-btn">Get Started</button> | |
</div> | |
</section> | |
<!-- Dashboard Page --> | |
<section id="dashboard" class="page"> | |
<h2 class="page-title">Live Dashboard</h2> | |
<div id="dashboard-content"> | |
<div id="no-data-message" class="hidden"> | |
<h3>No patient data available</h3> | |
<p>Add patient data using the Data Encoding page to view analytics.</p> | |
<button class="btn" id="go-to-encode-btn">Go to Data Encoding</button> | |
</div> | |
<div id="dashboard-data" class="hidden"> | |
<div class="dashboard-grid"> | |
<div class="dashboard-card"> | |
<h3>Vital Signs Overview</h3> | |
<div class="chart-wrapper"> | |
<canvas id="vitals-overview-chart"></canvas> | |
</div> | |
</div> | |
<div class="dashboard-card"> | |
<h3>Blood Pressure Distribution</h3> | |
<div class="chart-wrapper"> | |
<canvas id="bp-distribution-chart"></canvas> | |
</div> | |
</div> | |
<div class="dashboard-card"> | |
<h3>Cardiac Rate Analysis</h3> | |
<div class="chart-wrapper"> | |
<canvas id="cardiac-rate-chart"></canvas> | |
</div> | |
</div> | |
<div class="dashboard-card"> | |
<h3>Temperature Readings</h3> | |
<div class="chart-wrapper"> | |
<canvas id="temperature-chart"></canvas> | |
</div> | |
</div> | |
</div> | |
<h3>Patient Vital Signs</h3> | |
<div class="table-container"> | |
<table id="patient-table"> | |
<thead> | |
<tr> | |
<th>Name</th> | |
<th>Blood Pressure</th> | |
<th>Cardiac Rate</th> | |
<th>Pulse Rate</th> | |
<th>Respiratory Rate</th> | |
<th>Temperature</th> | |
<th>Status</th> | |
<th>Actions</th> | |
</tr> | |
</thead> | |
<tbody id="patient-table-body"> | |
<!-- Patient data will be populated here --> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
</section> | |
<!-- Data Encoding Page --> | |
<section id="encode" class="page"> | |
<h2 class="page-title">Data Encoding</h2> | |
<div id="alert-container"></div> | |
<form id="patient-form"> | |
<div class="form-group"> | |
<label for="patient-name">Patient Name*</label> | |
<input type="text" id="patient-name" required> | |
</div> | |
<div class="form-group"> | |
<label for="blood-pressure-systolic">Blood Pressure - Systolic (mmHg)*</label> | |
<div class="input-with-icon"> | |
<input type="number" id="blood-pressure-systolic" placeholder="Systolic" required> | |
<span class="input-icon">mmHg</span> | |
</div> | |
<small class="info-text">Normal: Less than 120 mmHg</small> | |
</div> | |
<div class="form-group"> | |
<label for="blood-pressure-diastolic">Blood Pressure - Diastolic (mmHg)*</label> | |
<div class="input-with-icon"> | |
<input type="number" id="blood-pressure-diastolic" placeholder="Diastolic" required> | |
<span class="input-icon">mmHg</span> | |
</div> | |
<small class="info-text">Normal: Less than 80 mmHg</small> | |
</div> | |
<div class="form-group"> | |
<label for="cardiac-rate">Cardiac Rate (bpm)*</label> | |
<div class="input-with-icon"> | |
<input type="number" id="cardiac-rate" required> | |
<span class="input-icon">bpm</span> | |
</div> | |
<small class="info-text">Normal: 60-100 bpm</small> | |
</div> | |
<div class="form-group"> | |
<label for="pulse-rate">Pulse Rate (bpm)*</label> | |
<div class="input-with-icon"> | |
<input type="number" id="pulse-rate" required> | |
<span class="input-icon">bpm</span> | |
</div> | |
<small class="info-text">Normal: 60-100 bpm</small> | |
</div> | |
<div class="form-group"> | |
<label for="respiratory-rate">Respiratory Rate (breaths/min)*</label> | |
<div class="input-with-icon"> | |
<input type="number" id="respiratory-rate" required> | |
<span class="input-icon">bpm</span> | |
</div> | |
<small class="info-text">Normal: 12-20 breaths/min</small> | |
</div> | |
<div class="form-group"> | |
<label for="temperature">Temperature (°C)*</label> | |
<div class="input-with-icon"> | |
<input type="number" id="temperature" step="0.1" required> | |
<span class="input-icon">°C</span> | |
</div> | |
<small class="info-text">Normal: 36.5-37.5 °C</small> | |
</div> | |
<button type="submit" class="btn">Save Patient Data</button> | |
</form> | |
<div class="interpretation-result hidden" id="interpretation-result"> | |
<h3>Vital Signs Interpretation</h3> | |
<div id="interpretation-content"></div> | |
</div> | |
</section> | |
</main> | |
<footer> | |
<div class="container"> | |
<p>© 2025 Dionega Healthcare Analytics | Developed for Nursing Informatics Course</p> | |
</div> | |
</footer> | |
<script src="script.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// DOM Elements | |
const navLinks = document.querySelectorAll('.nav-link'); | |
const pages = document.querySelectorAll('.page'); | |
const currentDateElement = document.getElementById('current-date'); | |
const currentTimeElement = document.getElementById('current-time'); | |
const patientForm = document.getElementById('patient-form'); | |
const patientTableBody = document.getElementById('patient-table-body'); | |
const noDataMessage = document.getElementById('no-data-message'); | |
const dashboardData = document.getElementById('dashboard-data'); | |
const alertContainer = document.getElementById('alert-container'); | |
const getStartedBtn = document.getElementById('get-started-btn'); | |
const goToEncodeBtn = document.getElementById('go-to-encode-btn'); | |
const interpretationResult = document.getElementById('interpretation-result'); | |
const interpretationContent = document.getElementById('interpretation-content'); | |
// Charts | |
let vitalsOverviewChart; | |
let bpDistributionChart; | |
let cardiacRateChart; | |
let temperatureChart; | |
// Vital signs reference values | |
const vitalSigns = { | |
bloodPressure: { | |
systolic: { | |
min: 90, | |
normal: 120, | |
high: 140, | |
crisis: 180 | |
}, | |
diastolic: { | |
min: 60, | |
normal: 80, | |
high: 90, | |
crisis: 120 | |
} | |
}, | |
cardiacRate: { | |
min: 60, | |
max: 100 | |
}, | |
pulseRate: { | |
min: 60, | |
max: 100 | |
}, | |
respiratoryRate: { | |
min: 12, | |
max: 20 | |
}, | |
temperature: { | |
min: 36.5, | |
max: 37.5, | |
fever: 38.0, | |
hypothermia: 36.0 | |
} | |
}; | |
// Initialize the application | |
document.addEventListener('DOMContentLoaded', function() { | |
console.log('DOM loaded'); | |
updateDateTime(); | |
setInterval(updateDateTime, 1000); | |
loadPatientData(); | |
setupEventListeners(); | |
// Start with the home page active | |
changePage('home'); | |
}); | |
// Setup Event Listeners | |
function setupEventListeners() { | |
console.log('Setting up event listeners'); | |
console.log('Nav links found:', navLinks.length); | |
// Navigation | |
navLinks.forEach(link => { | |
link.addEventListener('click', function(e) { | |
e.preventDefault(); | |
const targetPage = this.getAttribute('data-page'); | |
console.log('Navigation clicked:', targetPage); | |
changePage(targetPage); | |
}); | |
}); | |
// Patient Form Submission | |
if (patientForm) { | |
patientForm.addEventListener('submit', function(e) { | |
e.preventDefault(); | |
savePatientData(); | |
}); | |
} else { | |
console.error('Patient form not found in the DOM'); | |
} | |
// Button Listeners | |
if (getStartedBtn) { | |
getStartedBtn.addEventListener('click', function(e) { | |
e.preventDefault(); | |
console.log('Get Started button clicked'); | |
changePage('encode'); | |
}); | |
} else { | |
console.error('Get Started button not found in the DOM'); | |
} | |
if (goToEncodeBtn) { | |
goToEncodeBtn.addEventListener('click', function(e) { | |
e.preventDefault(); | |
console.log('Go to Encode button clicked'); | |
changePage('encode'); | |
}); | |
} else { | |
console.error('Go to Encode button not found in the DOM'); | |
} | |
// Add export and clear data buttons event listeners | |
const exportDataBtn = document.getElementById('export-data-btn'); | |
if (exportDataBtn) { | |
exportDataBtn.addEventListener('click', exportPatientData); | |
} | |
const clearDataBtn = document.getElementById('clear-data-btn'); | |
if (clearDataBtn) { | |
clearDataBtn.addEventListener('click', clearAllData); | |
} | |
} | |
// Navigation Functions | |
function changePage(pageId) { | |
console.log('Changing page to:', pageId); | |
// Check if pages exist | |
if (!pages || pages.length === 0) { | |
console.error('No page elements found'); | |
return; | |
} | |
// Validate pageId exists | |
const targetPage = document.getElementById(pageId); | |
if (!targetPage) { | |
console.error('Target page not found:', pageId); | |
return; | |
} | |
// Update navigation active state | |
navLinks.forEach(link => { | |
if (link.getAttribute('data-page') === pageId) { | |
link.classList.add('active-nav'); | |
} else { | |
link.classList.remove('active-nav'); | |
} | |
}); | |
// Update page visibility | |
pages.forEach(page => { | |
if (page.id === pageId) { | |
page.classList.add('active'); | |
console.log('Made page active:', pageId); | |
} else { | |
page.classList.remove('active'); | |
} | |
}); | |
// Special handling for dashboard page | |
if (pageId === 'dashboard') { | |
updateDashboard(); | |
} | |
} | |
// Date and Time Functions | |
function updateDateTime() { | |
if (!currentDateElement || !currentTimeElement) { | |
console.error('Date/time elements not found'); | |
return; | |
} | |
const now = new Date(); | |
// Format date | |
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; | |
currentDateElement.textContent = now.toLocaleDateString('en-US', options); | |
// Format time | |
const timeOptions = { hour: '2-digit', minute: '2-digit', second: '2-digit' }; | |
currentTimeElement.textContent = now.toLocaleTimeString('en-US', timeOptions); | |
} | |
// Alert Functions | |
function showAlert(message, type) { | |
if (!alertContainer) { | |
console.error('Alert container not found'); | |
return; | |
} | |
const alertDiv = document.createElement('div'); | |
alertDiv.className = `alert alert-${type}`; | |
alertDiv.textContent = message; | |
alertContainer.innerHTML = ''; | |
alertContainer.appendChild(alertDiv); | |
// Auto dismiss after 3 seconds | |
setTimeout(() => { | |
alertDiv.remove(); | |
}, 3000); | |
} | |
// Patient Data Functions | |
function savePatientData() { | |
// Get form values | |
const nameInput = document.getElementById('patient-name'); | |
const systolicInput = document.getElementById('blood-pressure-systolic'); | |
const diastolicInput = document.getElementById('blood-pressure-diastolic'); | |
const cardiacRateInput = document.getElementById('cardiac-rate'); | |
const pulseRateInput = document.getElementById('pulse-rate'); | |
const respiratoryRateInput = document.getElementById('respiratory-rate'); | |
const temperatureInput = document.getElementById('temperature'); | |
// Check if all inputs exist | |
if (!nameInput || !systolicInput || !diastolicInput || !cardiacRateInput || | |
!pulseRateInput || !respiratoryRateInput || !temperatureInput) { | |
showAlert('Error: Form inputs not found', 'danger'); | |
return; | |
} | |
const name = nameInput.value; | |
const systolic = parseInt(systolicInput.value); | |
const diastolic = parseInt(diastolicInput.value); | |
const cardiacRate = parseInt(cardiacRateInput.value); | |
const pulseRate = parseInt(pulseRateInput.value); | |
const respiratoryRate = parseInt(respiratoryRateInput.value); | |
const temperature = parseFloat(temperatureInput.value); | |
// Validate inputs | |
if (!name || isNaN(systolic) || isNaN(diastolic) || isNaN(cardiacRate) || | |
isNaN(pulseRate) || isNaN(respiratoryRate) || isNaN(temperature)) { | |
showAlert('Please fill all fields with valid values', 'warning'); | |
return; | |
} | |
// Create patient object | |
const patient = { | |
id: Date.now(), // Use timestamp as unique ID | |
name, | |
bloodPressure: { | |
systolic, | |
diastolic | |
}, | |
cardiacRate, | |
pulseRate, | |
respiratoryRate, | |
temperature, | |
timestamp: new Date().toISOString(), | |
interpretation: interpretVitalSigns(systolic, diastolic, cardiacRate, pulseRate, respiratoryRate, temperature) | |
}; | |
// Get existing data from localStorage | |
let patients = JSON.parse(localStorage.getItem('patients')) || []; | |
// Add new patient | |
patients.push(patient); | |
// Save back to localStorage | |
localStorage.setItem('patients', JSON.stringify(patients)); | |
// Show success message | |
showAlert('Patient data saved successfully!', 'success'); | |
// Display interpretation | |
displayInterpretation(patient.interpretation); | |
// Reset form | |
patientForm.reset(); | |
} | |
function loadPatientData() { | |
// Get data from localStorage | |
const patients = JSON.parse(localStorage.getItem('patients')) || []; | |
// Check if there's data available | |
if (!noDataMessage || !dashboardData) { | |
console.error('Data message elements not found'); | |
return; | |
} | |
if (patients.length === 0) { | |
noDataMessage.classList.remove('hidden'); | |
dashboardData.classList.add('hidden'); | |
} else { | |
noDataMessage.classList.add('hidden'); | |
dashboardData.classList.remove('hidden'); | |
// Populate table | |
populatePatientTable(patients); | |
} | |
} | |
function populatePatientTable(patients) { | |
if (!patientTableBody) { | |
console.error('Patient table body not found'); | |
return; | |
} | |
// Clear existing table rows | |
patientTableBody.innerHTML = ''; | |
// Add each patient to table | |
patients.forEach(patient => { | |
const row = document.createElement('tr'); | |
// Determine overall status class | |
let statusClass = 'status-normal'; | |
let statusText = 'Normal'; | |
const interpretation = patient.interpretation; | |
if (interpretation.some(item => item.severity === 'danger')) { | |
statusClass = 'status-danger'; | |
statusText = 'Critical'; | |
} else if (interpretation.some(item => item.severity === 'warning')) { | |
statusClass = 'status-warning'; | |
statusText = 'Abnormal'; | |
} | |
// Build row content | |
row.innerHTML = ` | |
<td>${patient.name}</td> | |
<td>${patient.bloodPressure.systolic}/${patient.bloodPressure.diastolic} mmHg</td> | |
<td>${patient.cardiacRate} bpm</td> | |
<td>${patient.pulseRate} bpm</td> | |
<td>${patient.respiratoryRate} bpm</td> | |
<td>${patient.temperature.toFixed(1)}°C</td> | |
<td class="${statusClass}">${statusText}</td> | |
<td> | |
<button class="btn btn-danger btn-sm delete-btn" data-id="${patient.id}">Delete</button> | |
</td> | |
`; | |
patientTableBody.appendChild(row); | |
// Add event listener to delete button | |
const deleteBtn = row.querySelector('.delete-btn'); | |
deleteBtn.addEventListener('click', function() { | |
deletePatient(patient.id); | |
}); | |
}); | |
} | |
function deletePatient(patientId) { | |
// Get existing data | |
let patients = JSON.parse(localStorage.getItem('patients')) || []; | |
// Remove patient with matching ID | |
patients = patients.filter(patient => patient.id !== patientId); | |
// Save back to localStorage | |
localStorage.setItem('patients', JSON.stringify(patients)); | |
// Update UI | |
populatePatientTable(patients); | |
updateDashboard(); | |
// Show notification | |
showAlert('Patient record deleted', 'success'); | |
} | |
// Vital Signs Interpretation | |
function interpretVitalSigns(systolic, diastolic, cardiacRate, pulseRate, respiratoryRate, temperature) { | |
const interpretation = []; | |
// Blood Pressure Interpretation | |
if (systolic < vitalSigns.bloodPressure.systolic.min || diastolic < vitalSigns.bloodPressure.diastolic.min) { | |
interpretation.push({ | |
parameter: 'Blood Pressure', | |
status: 'Low Blood Pressure (Hypotension)', | |
message: 'Blood pressure is below normal range. Monitor for dizziness or fatigue.', | |
severity: 'warning' | |
}); | |
} else if (systolic >= vitalSigns.bloodPressure.systolic.crisis || diastolic >= vitalSigns.bloodPressure.diastolic.crisis) { | |
interpretation.push({ | |
parameter: 'Blood Pressure', | |
status: 'Hypertensive Crisis', | |
message: 'Blood pressure is critically high. Immediate medical attention required.', | |
severity: 'danger' | |
}); | |
} else if (systolic >= vitalSigns.bloodPressure.systolic.high || diastolic >= vitalSigns.bloodPressure.diastolic.high) { | |
interpretation.push({ | |
parameter: 'Blood Pressure', | |
status: 'High Blood Pressure (Hypertension)', | |
message: 'Blood pressure is elevated. Monitor and consider interventions.', | |
severity: 'warning' | |
}); | |
} else { | |
interpretation.push({ | |
parameter: 'Blood Pressure', | |
status: 'Normal Blood Pressure', | |
message: 'Blood pressure is within normal range.', | |
severity: 'normal' | |
}); | |
} | |
// Cardiac Rate Interpretation | |
if (cardiacRate < vitalSigns.cardiacRate.min) { | |
interpretation.push({ | |
parameter: 'Cardiac Rate', | |
status: 'Bradycardia', | |
message: 'Heart rate is slower than normal. Monitor for symptoms.', | |
severity: 'warning' | |
}); | |
} else if (cardiacRate > vitalSigns.cardiacRate.max) { | |
interpretation.push({ | |
parameter: 'Cardiac Rate', | |
status: 'Tachycardia', | |
message: 'Heart rate is faster than normal. Assess for causes.', | |
severity: 'warning' | |
}); | |
} else { | |
interpretation.push({ | |
parameter: 'Cardiac Rate', | |
status: 'Normal Heart Rate', | |
message: 'Heart rate is within normal range.', | |
severity: 'normal' | |
}); | |
} | |
// Pulse Rate Interpretation | |
if (pulseRate < vitalSigns.pulseRate.min) { | |
interpretation.push({ | |
parameter: 'Pulse Rate', | |
status: 'Low Pulse Rate', | |
message: 'Pulse rate is below normal range. Monitor cardiovascular status.', | |
severity: 'warning' | |
}); | |
} else if (pulseRate > vitalSigns.pulseRate.max) { | |
interpretation.push({ | |
parameter: 'Pulse Rate', | |
status: 'Elevated Pulse Rate', | |
message: 'Pulse rate is above normal range. Check for exertion, anxiety, or other causes.', | |
severity: 'warning' | |
}); | |
} else { | |
interpretation.push({ | |
parameter: 'Pulse Rate', | |
status: 'Normal Pulse Rate', | |
message: 'Pulse rate is within normal range.', | |
severity: 'normal' | |
}); | |
} | |
// Respiratory Rate Interpretation | |
if (respiratoryRate < vitalSigns.respiratoryRate.min) { | |
interpretation.push({ | |
parameter: 'Respiratory Rate', | |
status: 'Bradypnea', | |
message: 'Breathing rate is slower than normal. Monitor oxygen status.', | |
severity: 'warning' | |
}); | |
} else if (respiratoryRate > vitalSigns.respiratoryRate.max) { | |
interpretation.push({ | |
parameter: 'Respiratory Rate', | |
status: 'Tachypnea', | |
message: 'Breathing rate is faster than normal. Assess for respiratory distress.', | |
severity: 'warning' | |
}); | |
} else { | |
interpretation.push({ | |
parameter: 'Respiratory Rate', | |
status: 'Normal Respiratory Rate', | |
message: 'Breathing rate is within normal range.', | |
severity: 'normal' | |
}); | |
} | |
// Temperature Interpretation | |
if (temperature < vitalSigns.temperature.hypothermia) { | |
interpretation.push({ | |
parameter: 'Temperature', | |
status: 'Hypothermia', | |
message: 'Body temperature is dangerously low. Immediate warming measures required.', | |
severity: 'danger' | |
}); | |
} else if (temperature < vitalSigns.temperature.min) { | |
interpretation.push({ | |
parameter: 'Temperature', | |
status: 'Low Body Temperature', | |
message: 'Body temperature is below normal range. Monitor for signs of hypothermia.', | |
severity: 'warning' | |
}); | |
} else if (temperature >= vitalSigns.temperature.fever) { | |
interpretation.push({ | |
parameter: 'Temperature', | |
status: 'Fever', | |
message: 'Body temperature is elevated. Assess for infection or other causes.', | |
severity: 'warning' | |
}); | |
} else { | |
interpretation.push({ | |
parameter: 'Temperature', | |
status: 'Normal Temperature', | |
message: 'Body temperature is within normal range.', | |
severity: 'normal' | |
}); | |
} | |
return interpretation; | |
} | |
function displayInterpretation(interpretation) { | |
// Check if interpretation elements exist | |
if (!interpretationResult || !interpretationContent) { | |
console.error('Interpretation elements not found'); | |
return; | |
} | |
// Clear previous interpretation | |
interpretationContent.innerHTML = ''; | |
// Display overall status | |
let overallSeverity = 'normal'; | |
if (interpretation.some(item => item.severity === 'danger')) { | |
overallSeverity = 'danger'; | |
} else if (interpretation.some(item => item.severity === 'warning')) { | |
overallSeverity = 'warning'; | |
} | |
// Update result heading | |
interpretationResult.className = `interpretation-result status-${overallSeverity}`; | |
if (overallSeverity === 'danger') { | |
interpretationResult.textContent = 'Critical Condition - Immediate Attention Required'; | |
} else if (overallSeverity === 'warning') { | |
interpretationResult.textContent = 'Abnormal Vital Signs - Monitor Closely'; | |
} else { | |
interpretationResult.textContent = 'Normal Vital Signs'; | |
} | |
// Create interpretation details | |
interpretation.forEach(item => { | |
const interpretItem = document.createElement('div'); | |
interpretItem.className = `interpret-item ${item.severity}`; | |
interpretItem.innerHTML = ` | |
<h4>${item.parameter}: <span class="status-${item.severity}">${item.status}</span></h4> | |
<p>${item.message}</p> | |
`; | |
interpretationContent.appendChild(interpretItem); | |
}); | |
} | |
// Dashboard Functions | |
function updateDashboard() { | |
// Check if Chart.js is available | |
if (typeof Chart === 'undefined') { | |
console.error('Chart.js library is not loaded'); | |
return; | |
} | |
// Get data from localStorage | |
const patients = JSON.parse(localStorage.getItem('patients')) || []; | |
if (!noDataMessage || !dashboardData) { | |
console.error('Dashboard elements not found'); | |
return; | |
} | |
if (patients.length === 0) { | |
noDataMessage.classList.remove('hidden'); | |
dashboardData.classList.add('hidden'); | |
return; | |
} | |
noDataMessage.classList.add('hidden'); | |
dashboardData.classList.remove('hidden'); | |
// Update dashboard statistics | |
updateDashboardStats(patients); | |
// Update charts | |
try { | |
createVitalsOverviewChart(patients); | |
createBPDistributionChart(patients); | |
createCardiacRateChart(patients); | |
createTemperatureChart(patients); | |
} catch (error) { | |
console.error('Error creating charts:', error); | |
} | |
} | |
function updateDashboardStats(patients) { | |
const totalPatientsElement = document.getElementById('total-patients'); | |
const criticalCountElement = document.getElementById('critical-count'); | |
const abnormalCountElement = document.getElementById('abnormal-count'); | |
const normalCountElement = document.getElementById('normal-count'); | |
const criticalPercentElement = document.getElementById('critical-percent'); | |
const abnormalPercentElement = document.getElementById('abnormal-percent'); | |
const normalPercentElement = document.getElementById('normal-percent'); | |
if (!totalPatientsElement || !criticalCountElement || !abnormalCountElement || | |
!normalCountElement || !criticalPercentElement || !abnormalPercentElement || | |
!normalPercentElement) { | |
console.error('Dashboard statistics elements not found'); | |
return; | |
} | |
const totalPatients = patients.length; | |
const criticalCount = patients.filter(p => p.interpretation.some(i => i.severity === 'danger')).length; | |
const abnormalCount = patients.filter(p => | |
p.interpretation.some(i => i.severity === 'warning') && | |
!p.interpretation.some(i => i.severity === 'danger') | |
).length; | |
const normalCount = patients.filter(p => | |
!p.interpretation.some(i => i.severity === 'warning') && | |
!p.interpretation.some(i => i.severity === 'danger') | |
).length; | |
// Update statistics display | |
totalPatientsElement.textContent = totalPatients; | |
criticalCountElement.textContent = criticalCount; | |
abnormalCountElement.textContent = abnormalCount; | |
normalCountElement.textContent = normalCount; | |
// Calculate percentages | |
criticalPercentElement.textContent = | |
totalPatients > 0 ? Math.round((criticalCount / totalPatients) * 100) + '%' : '0%'; | |
abnormalPercentElement.textContent = | |
totalPatients > 0 ? Math.round((abnormalCount / totalPatients) * 100) + '%' : '0%'; | |
normalPercentElement.textContent = | |
totalPatients > 0 ? Math.round((normalCount / totalPatients) * 100) + '%' : '0%'; | |
} | |
function createVitalsOverviewChart(patients) { | |
const chartCanvas = document.getElementById('vitals-overview-chart'); | |
if (!chartCanvas) { | |
console.error('Vitals overview chart canvas not found'); | |
return; | |
} | |
// Calculate percentages for each vital sign | |
const vitalCategories = ['Blood Pressure', 'Cardiac Rate', 'Pulse Rate', 'Respiratory Rate', 'Temperature']; | |
const normalData = []; | |
const abnormalData = []; | |
vitalCategories.forEach((category) => { | |
// Count normal vs abnormal for each category | |
const totalForCategory = patients.length; | |
const abnormalForCategory = patients.filter(p => { | |
const relevantInterpretation = p.interpretation.find(i => i.parameter === category); | |
return relevantInterpretation && relevantInterpretation.severity !== 'normal'; | |
}).length; | |
const normalForCategory = totalForCategory - abnormalForCategory; | |
// Convert to percentages | |
normalData.push(Math.round((normalForCategory / totalForCategory) * 100)); | |
abnormalData.push(Math.round((abnormalForCategory / totalForCategory) * 100)); | |
}); | |
// Destroy previous chart if it exists | |
if (vitalsOverviewChart) { | |
vitalsOverviewChart.destroy(); | |
} | |
// Create new chart | |
const ctx = chartCanvas.getContext('2d'); | |
vitalsOverviewChart = new Chart(ctx, { | |
type: 'bar', | |
data: { | |
labels: vitalCategories, | |
datasets: [ | |
{ | |
label: 'Normal', | |
data: normalData, | |
backgroundColor: '#4CAF50', | |
borderColor: '#388E3C', | |
borderWidth: 1 | |
}, | |
{ | |
label: 'Abnormal', | |
data: abnormalData, | |
backgroundColor: '#FF5722', | |
borderColor: '#E64A19', | |
borderWidth: 1 | |
} | |
] | |
}, | |
options: { | |
responsive: true, | |
scales: { | |
y: { | |
beginAtZero: true, | |
max: 100, | |
title: { | |
display: true, | |
text: 'Percentage (%)' | |
} | |
}, | |
x: { | |
title: { | |
display: true, | |
text: 'Vital Signs' | |
} | |
} | |
}, | |
plugins: { | |
title: { | |
display: true, | |
text: 'Vital Signs Overview' | |
} | |
} | |
} | |
}); | |
} | |
function createBPDistributionChart(patients) { | |
const chartCanvas = document.getElementById('bp-distribution-chart'); | |
if (!chartCanvas) { | |
console.error('BP distribution chart canvas not found'); | |
return; | |
} | |
// Count patients in each BP category | |
const hypotensionCount = patients.filter(p => { | |
const bpInterpretation = p.interpretation.find(i => i.parameter === 'Blood Pressure'); | |
return bpInterpretation && bpInterpretation.status.includes('Low'); | |
}).length; | |
const normalCount = patients.filter(p => { | |
const bpInterpretation = p.interpretation.find(i => i.parameter === 'Blood Pressure'); | |
return bpInterpretation && bpInterpretation.status.includes('Normal'); | |
}).length; | |
const hypertensionCount = patients.filter(p => { | |
const bpInterpretation = p.interpretation.find(i => i.parameter === 'Blood Pressure'); | |
return bpInterpretation && bpInterpretation.status.includes('High') && !bpInterpretation.status.includes('Crisis'); | |
}).length; | |
const crisisCount = patients.filter(p => { | |
const bpInterpretation = p.interpretation.find(i => i.parameter === 'Blood Pressure'); | |
return bpInterpretation && bpInterpretation.status.includes('Crisis'); | |
}).length; | |
// Destroy previous chart if it exists | |
if (bpDistributionChart) { | |
bpDistributionChart.destroy(); | |
} | |
// Create new chart | |
const ctx = chartCanvas.getContext('2d'); | |
bpDistributionChart = new Chart(ctx, { | |
type: 'pie', | |
data: { | |
labels: ['Hypotension', 'Normal', 'Hypertension', 'Hypertensive Crisis'], | |
datasets: [{ | |
data: [hypotensionCount, normalCount, hypertensionCount, crisisCount], | |
backgroundColor: ['#2196F3', '#4CAF50', '#FFC107', '#F44336'], | |
borderWidth: 1 | |
}] | |
}, | |
options: { | |
responsive: true, | |
plugins: { | |
title: { | |
display: true, | |
text: 'Blood Pressure Distribution' | |
}, | |
legend: { | |
position: 'right' | |
} | |
} | |
} | |
}); | |
} | |
function createCardiacRateChart(patients) { | |
const chartCanvas = document.getElementById('cardiac-rate-chart'); | |
if (!chartCanvas) { | |
console.error('Cardiac rate chart canvas not found'); | |
return; | |
} | |
// Calculate distribution | |
const bradycardiaCount = patients.filter(p => p.cardiacRate < vitalSigns.cardiacRate.min).length; | |
const normalCount = patients.filter(p => p.cardiacRate >= vitalSigns.cardiacRate.min && p.cardiacRate <= vitalSigns.cardiacRate.max).length; | |
const tachycardiaCount = patients.filter(p => p.cardiacRate > vitalSigns.cardiacRate.max).length; | |
// Destroy previous chart if it exists | |
if (cardiacRateChart) { | |
cardiacRateChart.destroy(); | |
} | |
// Create new chart | |
const ctx = chartCanvas.getContext('2d'); | |
cardiacRateChart = new Chart(ctx, { | |
type: 'doughnut', | |
data: { | |
labels: ['Bradycardia', 'Normal', 'Tachycardia'], | |
datasets: [{ | |
data: [bradycardiaCount, normalCount, tachycardiaCount], | |
backgroundColor: ['#2196F3', '#4CAF50', '#F44336'], | |
borderWidth: 1 | |
}] | |
}, | |
options: { | |
responsive: true, | |
plugins: { | |
title: { | |
display: true, | |
text: 'Cardiac Rate Distribution' | |
}, | |
legend: { | |
position: 'right' | |
} | |
} | |
} | |
}); | |
} | |
function createTemperatureChart(patients) { | |
const chartCanvas = document.getElementById('temperature-chart'); | |
if (!chartCanvas) { | |
console.error('Temperature chart canvas not found'); | |
return; | |
} | |
// Sort patients by timestamp for chronological display | |
const sortedPatients = [...patients].sort((a, b) => | |
new Date(a.timestamp) - new Date(b.timestamp) | |
); | |
// Only use the last 10 patients for better visualization | |
const recentPatients = sortedPatients.slice(-10); | |
// Prepare data | |
const labels = recentPatients.map(p => p.name); | |
const temperatureData = recentPatients.map(p => p.temperature); | |
// Destroy previous chart if it exists | |
if (temperatureChart) { | |
temperatureChart.destroy(); | |
} | |
// Create new chart | |
const ctx = chartCanvas.getContext('2d'); | |
temperatureChart = new Chart(ctx, { | |
type: 'line', | |
data: { | |
labels: labels, | |
datasets: [{ | |
label: 'Temperature (°C)', | |
data: temperatureData, | |
backgroundColor: 'rgba(255, 152, 0, 0.2)', | |
borderColor: 'rgba(255, 152, 0, 1)', | |
borderWidth: 2, | |
tension: 0.3, | |
fill: true, | |
pointRadius: 4 | |
}] | |
}, | |
options: { | |
responsive: true, | |
scales: { | |
y: { | |
min: 35, | |
max: 40, | |
title: { | |
display: true, | |
text: 'Temperature (°C)' | |
} | |
}, | |
x: { | |
title: { | |
display: true, | |
text: 'Patient' | |
} | |
} | |
}, | |
plugins: { | |
title: { | |
display: true, | |
text: 'Patient Temperature Trends' | |
} | |
} | |
} | |
}); | |
// Add annotation plugin if available | |
if (Chart.annotation) { | |
temperatureChart.options.plugins.annotation = { | |
annotations: { | |
feverLine: { | |
type: 'line', | |
yMin: vitalSigns.temperature.fever, | |
yMax: vitalSigns.temperature.fever, | |
borderColor: '#F44336', | |
borderWidth: 2, | |
borderDash: [5, 5], | |
label: { | |
content: 'Fever', | |
enabled: true, | |
position: 'end' | |
} | |
}, | |
normalLow: { | |
type: 'line', | |
yMin: vitalSigns.temperature.min, | |
yMax: vitalSigns.temperature.min, | |
borderColor: '#2196F3', | |
borderWidth: 2, | |
borderDash: [5, 5], | |
label: { | |
content: 'Normal Low', | |
enabled: true, | |
position: 'start' | |
} | |
}, | |
normalHigh: { | |
type: 'line', | |
yMin: vitalSigns.temperature.max, | |
yMax: vitalSigns.temperature.max, | |
borderColor: '#FFC107', | |
borderWidth: 2, | |
borderDash: [5, 5], | |
label: { | |
content: 'Normal High', | |
enabled: true, | |
position: 'end' | |
} | |
} | |
} | |
}; | |
} | |
} | |
// Export and Data Management Functions | |
function exportPatientData() { | |
const patients = JSON.parse(localStorage.getItem('patients')) || []; | |
if (patients.length === 0) { | |
showAlert('No data to export', 'warning'); | |
return; | |
} | |
// Convert patient data to CSV | |
let csvContent = 'data:text/csv;charset=utf-8,'; | |
// Add headers | |
csvContent += 'Name,Systolic BP,Diastolic BP,Cardiac Rate,Pulse Rate,Respiratory Rate,Temperature,Status,Date\n'; | |
// Add data rows | |
patients.forEach(patient => { | |
// Determine overall status | |
let status = 'Normal'; | |
if (patient.interpretation.some(item => item.severity === 'danger')) { | |
status = 'Critical'; | |
} else if (patient.interpretation.some(item => item.severity === 'warning')) { | |
status = 'Abnormal'; | |
} | |
// Format date from timestamp | |
const date = new Date(patient.timestamp).toLocaleString(); | |
// Add row | |
csvContent += `${patient.name},${patient.bloodPressure.systolic},${patient.bloodPressure.diastolic},`; | |
csvContent += `${patient.cardiacRate},${patient.pulseRate},${patient.respiratoryRate},${patient.temperature.toFixed(1)},`; | |
csvContent += `${status},${date}\n`; | |
}); | |
// Create download link | |
const encodedUri = encodeURI(csvContent); | |
const link = document.createElement('a'); | |
link.setAttribute('href', encodedUri); | |
link.setAttribute('download', 'patient_data.csv'); | |
document.body.appendChild(link); | |
// Trigger download and remove link | |
link.click(); | |
document.body.removeChild(link); | |
showAlert('Data exported successfully', 'success'); | |
} | |
function clearAllData() { | |
// Show confirmation | |
if (confirm('Are you sure you want to delete all patient data? This action cannot be undone.')) { | |
// Clear localStorage | |
localStorage.removeItem('patients'); | |
// Update UI | |
if (patientTableBody) { | |
patientTableBody.innerHTML = ''; | |
} | |
if (noDataMessage && dashboardData) { | |
noDataMessage.classList.remove('hidden'); | |
dashboardData.classList.add('hidden'); | |
} | |
// Reset any existing charts | |
if (vitalsOverviewChart) vitalsOverviewChart.destroy(); | |
if (bpDistributionChart) bpDistributionChart.destroy(); | |
if (cardiacRateChart) cardiacRateChart.destroy(); | |
if (temperatureChart) temperatureChart.destroy(); | |
showAlert('All patient data has been cleared', 'success'); | |
} | |
} | |
// Fix for page navigation issues | |
function checkPageVisibility() { | |
console.log('Checking page visibility'); | |
// Ensure at least one page is visible | |
let anyPageVisible = false; | |
pages.forEach(page => { | |
if (page.classList.contains('active')) { | |
anyPageVisible = true; | |
console.log('Found visible page:', page.id); | |
} | |
}); | |
// If no page is visible, make the home page visible | |
if (!anyPageVisible) { | |
console.log('No pages visible, activating home page'); | |
const homePage = document.getElementById('home'); | |
if (homePage) { | |
homePage.classList.add('active'); | |
// Also update navigation active state | |
navLinks.forEach(link => { | |
if (link.getAttribute('data-page') === 'home') { | |
link.classList.add('active-nav'); | |
} else { | |
link.classList.remove('active-nav'); | |
} | |
}); | |
} else { | |
console.error('Home page not found'); | |
} | |
} | |
} | |
// Add page visibility check to initialization | |
document.addEventListener('DOMContentLoaded', function() { | |
console.log('DOM loaded'); | |
updateDateTime(); | |
setInterval(updateDateTime, 1000); | |
loadPatientData(); | |
setupEventListeners(); | |
// Check and fix page visibility | |
checkPageVisibility(); | |
// Additional check after a short delay to handle any race conditions | |
setTimeout(checkPageVisibility, 500); | |
}); | |
// Add a window resize handler to ensure page visibility persists | |
window.addEventListener('resize', function() { | |
checkPageVisibility(); | |
}); | |
// Additional enhancement for navigation debugging | |
function debugNavigationState() { | |
console.log('Navigation state:'); | |
console.log('Active pages:', Array.from(pages).filter(page => page.classList.contains('active')).map(page => page.id)); | |
console.log('Active nav links:', Array.from(navLinks).filter(link => link.classList.contains('active-nav')).map(link => link.getAttribute('data-page'))); | |
} | |
// Call debug function when changing pages | |
const originalChangePage = changePage; | |
changePage = function(pageId) { | |
console.log('ChangePage called with:', pageId); | |
originalChangePage(pageId); | |
debugNavigationState(); | |
// Force check visibility after page change | |
setTimeout(checkPageVisibility, 100); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:root { | |
--primary-color: #0078d7; | |
--secondary-color: #83c3f7; | |
--accent-color: #005a9e; | |
--light-color: #e6f2ff; | |
--white-color: #ffffff; | |
--text-color: #333333; | |
--success-color: #28a745; | |
--warning-color: #ffc107; | |
--danger-color: #dc3545; | |
--gray-color: #f8f9fa; | |
--border-color: #dee2e6; | |
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
} | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
} | |
body { | |
background-color: var(--light-color); | |
color: var(--text-color); | |
line-height: 1.6; | |
min-height: 100vh; | |
display: flex; | |
flex-direction: column; | |
} | |
.container { | |
width: 100%; | |
max-width: 1200px; | |
margin: 0 auto; | |
padding: 0 15px; | |
} | |
/* Header Styles */ | |
header { | |
background-color: var(--primary-color); | |
color: var(--white-color); | |
padding: 1rem 0; | |
box-shadow: var(--shadow); | |
} | |
.header-content { | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
} | |
.logo h1 { | |
font-size: 1.8rem; | |
margin-bottom: 0.5rem; | |
} | |
.logo p { | |
font-size: 0.9rem; | |
font-style: italic; | |
} | |
.date-time { | |
text-align: right; | |
font-size: 0.9rem; | |
} | |
/* Navigation Styles */ | |
nav { | |
background-color: var(--white-color); | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
} | |
.nav-links { | |
display: flex; | |
list-style: none; | |
} | |
.nav-links li { | |
padding: 1rem; | |
} | |
.nav-links a { | |
text-decoration: none; | |
color: var(--text-color); | |
font-weight: 500; | |
padding: 0.5rem; | |
border-radius: 4px; | |
transition: all 0.3s ease; | |
} | |
.nav-links a:hover, | |
.nav-links a.active { | |
background-color: var(--secondary-color); | |
color: var(--white-color); | |
} | |
/* Main Content Styles */ | |
main { | |
flex-grow: 1; | |
padding: 2rem 0; | |
} | |
.page { | |
display: none; | |
background-color: var(--white-color); | |
border-radius: 8px; | |
box-shadow: var(--shadow); | |
padding: 2rem; | |
margin-bottom: 1rem; | |
} | |
.page.active { | |
display: block; | |
} | |
.page-title { | |
color: var(--primary-color); | |
margin-bottom: 1.5rem; | |
padding-bottom: 0.5rem; | |
border-bottom: 2px solid var(--secondary-color); | |
} | |
/* Welcome Page Styles */ | |
.welcome-content { | |
text-align: center; | |
max-width: 800px; | |
margin: 0 auto; | |
} | |
.welcome-image { | |
max-width: 100%; | |
height: auto; | |
margin: 2rem 0; | |
border-radius: 8px; | |
box-shadow: var(--shadow); | |
} | |
.welcome-message { | |
font-size: 1.1rem; | |
line-height: 1.8; | |
margin-bottom: 2rem; | |
} | |
/* Form Styles */ | |
.form-group { | |
margin-bottom: 1.5rem; | |
} | |
label { | |
display: block; | |
margin-bottom: 0.5rem; | |
font-weight: 500; | |
} | |
input, select { | |
width: 100%; | |
padding: 0.75rem; | |
border: 1px solid var(--border-color); | |
border-radius: 4px; | |
font-size: 1rem; | |
} | |
.info-text { | |
display: block; | |
color: var(--accent-color); | |
margin-top: 0.25rem; | |
font-size: 0.85rem; | |
} | |
.btn { | |
display: inline-block; | |
background-color: var(--primary-color); | |
color: var(--white-color); | |
padding: 0.75rem 1.5rem; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
font-size: 1rem; | |
transition: background-color 0.3s ease; | |
} | |
.btn:hover { | |
background-color: var(--accent-color); | |
} | |
.btn-danger { | |
background-color: var(--danger-color); | |
} | |
.btn-danger:hover { | |
background-color: #bd2130; | |
} | |
.btn-sm { | |
padding: 0.25rem 0.5rem; | |
font-size: 0.875rem; | |
} | |
/* Dashboard Styles */ | |
.dashboard-grid { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); | |
gap: 1.5rem; | |
margin-bottom: 2rem; | |
} | |
.dashboard-card { | |
background-color: var(--white-color); | |
border-radius: 8px; | |
box-shadow: var(--shadow); | |
padding: 1.5rem; | |
} | |
.dashboard-card h3 { | |
color: var(--primary-color); | |
margin-bottom: 1rem; | |
padding-bottom: 0.5rem; | |
border-bottom: 1px solid var(--border-color); | |
} | |
.chart-container { | |
height: 250px; | |
margin-bottom: 1.5rem; | |
} | |
/* Table Styles */ | |
.table-container { | |
overflow-x: auto; | |
} | |
table { | |
width: 100%; | |
border-collapse: collapse; | |
margin-bottom: 1.5rem; | |
} | |
th, td { | |
padding: 0.75rem; | |
text-align: left; | |
border-bottom: 1px solid var(--border-color); | |
} | |
th { | |
background-color: var(--gray-color); | |
font-weight: 600; | |
} | |
tr:hover { | |
background-color: var(--light-color); | |
} | |
.status-normal { | |
color: var(--success-color); | |
font-weight: 500; | |
} | |
.status-warning { | |
color: var(--warning-color); | |
font-weight: 500; | |
} | |
.status-danger { | |
color: var(--danger-color); | |
font-weight: 500; | |
} | |
/* Footer Styles */ | |
footer { | |
background-color: var(--primary-color); | |
color: var(--white-color); | |
text-align: center; | |
padding: 1rem 0; | |
margin-top: auto; | |
} | |
/* Responsive Styles */ | |
@media (max-width: 768px) { | |
.header-content { | |
flex-direction: column; | |
text-align: center; | |
} | |
.date-time { | |
text-align: center; | |
margin-top: 1rem; | |
} | |
.nav-links { | |
flex-direction: column; | |
align-items: center; | |
} | |
.nav-links li { | |
padding: 0.5rem; | |
} | |
.dashboard-grid { | |
grid-template-columns: 1fr; | |
} | |
} | |
#no-data-message { | |
text-align: center; | |
padding: 2rem; | |
color: var(--accent-color); | |
} | |
.interpretation { | |
margin-top: 0.5rem; | |
padding: 0.5rem; | |
border-radius: 4px; | |
font-size: 0.9rem; | |
} | |
.input-with-icon { | |
position: relative; | |
} | |
.input-with-icon input { | |
padding-right: 2.5rem; | |
} | |
.input-icon { | |
position: absolute; | |
right: 0.75rem; | |
top: 50%; | |
transform: translateY(-50%); | |
color: var(--text-color); | |
font-size: 0.9rem; | |
} | |
.alert { | |
padding: 1rem; | |
margin-bottom: 1rem; | |
border-radius: 4px; | |
color: var(--white-color); | |
} | |
.alert-success { | |
background-color: var(--success-color); | |
} | |
.alert-danger { | |
background-color: var(--danger-color); | |
} | |
.hidden { | |
display: none; | |
} | |
/* Canvas styling */ | |
canvas { | |
width: 100%; | |
max-height: 250px; | |
} | |
/* Settings for Chart.js responsive design */ | |
.chart-wrapper { | |
position: relative; | |
height: 250px; | |
width: 100%; | |
} | |
/* Active page indicator */ | |
.nav-links .active-nav { | |
background-color: var(--secondary-color); | |
color: var(--white-color); | |
} | |
/* Medical icons in dashboard */ | |
.medical-icon { | |
font-size: 1.2rem; | |
margin-right: 0.5rem; | |
vertical-align: middle; | |
} | |
.interpretation-result { | |
margin-top: 2rem; | |
background-color: var(--light-color); | |
border-radius: 8px; | |
padding: 1.5rem; | |
} | |
.interpretation { | |
margin-bottom: 1rem; | |
padding: 1rem; | |
border-radius: 4px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment