| <!DOCTYPE html> |
| <html lang="en"> |
|
|
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width,initial-scale=1" /> |
| <title>Your Health Report | HeartCare</title> |
|
|
| |
| <link rel="preconnect" href="https://fonts.googleapis.com"> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
| <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap" |
| rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
| |
| <link rel="stylesheet" href="/static/style.css"> |
|
|
| |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script> |
| <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> |
| <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> |
|
|
| <style> |
| |
| .recommendation-page { |
| padding: 2rem 0; |
| } |
| |
| .page-header { |
| text-align: center; |
| margin-bottom: 3rem; |
| animation: fadeInDown 0.8s ease-out; |
| } |
| |
| .page-header h1 { |
| font-size: 2.5rem; |
| font-weight: 800; |
| color: var(--text-main); |
| margin-bottom: 0.5rem; |
| } |
| |
| .page-header p { |
| color: var(--text-muted); |
| font-size: 1.125rem; |
| } |
| |
| .report-grid { |
| display: grid; |
| grid-template-columns: 1fr 420px; |
| gap: 2rem; |
| margin-bottom: 2rem; |
| } |
| |
| @media (max-width: 980px) { |
| .report-grid { |
| grid-template-columns: 1fr; |
| } |
| |
| .sidebar { |
| order: -1; |
| } |
| } |
| |
| |
| .risk-selector { |
| background: white; |
| padding: 2rem; |
| border-radius: var(--radius-xl); |
| box-shadow: var(--shadow-md); |
| margin-bottom: 2rem; |
| } |
| |
| .risk-selector h3 { |
| font-size: 1.25rem; |
| font-weight: 700; |
| margin-bottom: 1rem; |
| color: var(--text-main); |
| } |
| |
| .risk-pills { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); |
| gap: 0.75rem; |
| } |
| |
| .risk-pill { |
| padding: 1rem; |
| border-radius: var(--radius-lg); |
| color: white; |
| text-align: center; |
| cursor: pointer; |
| font-weight: 600; |
| transition: all 0.3s ease; |
| border: 2px solid transparent; |
| } |
| |
| .risk-pill:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); |
| } |
| |
| .risk-pill.active { |
| border-color: var(--text-main); |
| box-shadow: 0 0 0 4px rgba(79, 70, 229, 0.1); |
| } |
| |
| .risk-pill.vlow { |
| background: linear-gradient(135deg, #10B981, #059669); |
| } |
| |
| .risk-pill.low { |
| background: linear-gradient(135deg, #34D399, #10B981); |
| } |
| |
| .risk-pill.mod { |
| background: linear-gradient(135deg, #FBBF24, #F59E0B); |
| } |
| |
| .risk-pill.high { |
| background: linear-gradient(135deg, #FB923C, #F97316); |
| } |
| |
| .risk-pill.vh { |
| background: linear-gradient(135deg, #EF4444, #DC2626); |
| } |
| |
| .risk-pill small { |
| display: block; |
| font-size: 0.75rem; |
| opacity: 0.9; |
| margin-top: 0.25rem; |
| } |
| |
| |
| .report-card { |
| background: white; |
| padding: 2.5rem; |
| border-radius: var(--radius-xl); |
| box-shadow: var(--shadow-lg); |
| border-left: 6px solid var(--primary-color); |
| animation: fadeInUp 0.8s ease-out; |
| } |
| |
| .report-card.highlight { |
| box-shadow: 0 0 0 4px rgba(79, 70, 229, 0.1), var(--shadow-lg); |
| } |
| |
| .report-title { |
| font-size: 1.75rem; |
| font-weight: 800; |
| margin-bottom: 0.5rem; |
| color: var(--text-main); |
| } |
| |
| .report-subtitle { |
| color: var(--text-muted); |
| margin-bottom: 2rem; |
| font-size: 1rem; |
| } |
| |
| .recommendations-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); |
| gap: 1.5rem; |
| margin-top: 2rem; |
| } |
| |
| .recommendation-card { |
| background: linear-gradient(135deg, #F8FAFC 0%, #F1F5F9 100%); |
| padding: 1.5rem; |
| border-radius: var(--radius-lg); |
| border: 1px solid var(--border-color); |
| transition: all 0.3s ease; |
| } |
| |
| .recommendation-card:hover { |
| transform: translateY(-4px); |
| box-shadow: var(--shadow-md); |
| } |
| |
| .recommendation-card h4 { |
| font-size: 1.125rem; |
| font-weight: 700; |
| margin-bottom: 1rem; |
| color: var(--primary-color); |
| display: flex; |
| align-items: center; |
| gap: 0.5rem; |
| } |
| |
| .recommendation-card ul { |
| list-style: none; |
| padding: 0; |
| margin: 0; |
| } |
| |
| .recommendation-card li { |
| padding: 0.5rem 0; |
| color: var(--text-main); |
| display: flex; |
| align-items: flex-start; |
| gap: 0.5rem; |
| } |
| |
| .recommendation-card li::before { |
| content: "✓"; |
| color: var(--primary-color); |
| font-weight: 700; |
| flex-shrink: 0; |
| } |
| |
| |
| .sidebar .card { |
| background: white; |
| padding: 1.5rem; |
| border-radius: var(--radius-xl); |
| box-shadow: var(--shadow-md); |
| margin-bottom: 1.5rem; |
| } |
| |
| .sidebar h3 { |
| font-size: 1.125rem; |
| font-weight: 700; |
| margin-bottom: 1rem; |
| color: var(--text-main); |
| } |
| |
| |
| .meter-container { |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| padding: 1.5rem 0; |
| } |
| |
| .meter { |
| width: 160px; |
| height: 160px; |
| position: relative; |
| } |
| |
| .meter svg { |
| transform: rotate(-90deg); |
| } |
| |
| .meter .center { |
| position: absolute; |
| inset: 0; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| flex-direction: column; |
| } |
| |
| .meter .percent { |
| font-size: 2rem; |
| font-weight: 800; |
| color: var(--primary-color); |
| } |
| |
| .meter .label { |
| font-size: 0.875rem; |
| color: var(--text-muted); |
| margin-top: 0.25rem; |
| } |
| |
| |
| .chart-container { |
| height: 240px; |
| margin-top: 1rem; |
| } |
| |
| |
| .doctor-list { |
| display: flex; |
| flex-direction: column; |
| gap: 1rem; |
| } |
| |
| .doctor-card { |
| padding: 1.25rem; |
| border-radius: var(--radius-lg); |
| background: linear-gradient(135deg, #F8FAFC 0%, #F1F5F9 100%); |
| border: 1px solid var(--border-color); |
| transition: all 0.3s ease; |
| } |
| |
| .doctor-card:hover { |
| transform: translateX(4px); |
| box-shadow: var(--shadow-sm); |
| } |
| |
| .doctor-name { |
| font-weight: 700; |
| color: var(--text-main); |
| margin-bottom: 0.5rem; |
| } |
| |
| .doctor-info { |
| font-size: 0.875rem; |
| color: var(--text-muted); |
| margin-bottom: 0.75rem; |
| } |
| |
| .doctor-actions { |
| display: flex; |
| gap: 0.5rem; |
| margin-top: 0.75rem; |
| } |
| |
| .btn-small { |
| padding: 0.5rem 1rem; |
| border-radius: 0.5rem; |
| font-size: 0.875rem; |
| font-weight: 500; |
| border: none; |
| cursor: pointer; |
| transition: all 0.2s ease; |
| } |
| |
| .btn-outline { |
| background: white; |
| border: 1px solid var(--border-color); |
| color: var(--text-main); |
| } |
| |
| .btn-outline:hover { |
| background: var(--bg-body); |
| } |
| |
| .btn-primary-small { |
| background: var(--primary-color); |
| color: white; |
| } |
| |
| .btn-primary-small:hover { |
| background: var(--primary-hover); |
| } |
| |
| |
| #map { |
| height: 280px; |
| border-radius: var(--radius-lg); |
| overflow: hidden; |
| margin: 1rem 0; |
| } |
| |
| |
| .action-section { |
| background: white; |
| padding: 2rem; |
| border-radius: var(--radius-xl); |
| box-shadow: var(--shadow-md); |
| margin-top: 2rem; |
| } |
| |
| .action-section h3 { |
| font-size: 1.25rem; |
| font-weight: 700; |
| margin-bottom: 1.5rem; |
| color: var(--text-main); |
| } |
| |
| .action-buttons { |
| display: flex; |
| flex-wrap: wrap; |
| gap: 1rem; |
| } |
| |
| .action-btn { |
| padding: 0.875rem 1.75rem; |
| border-radius: 100px; |
| font-weight: 600; |
| border: none; |
| cursor: pointer; |
| transition: all 0.3s ease; |
| display: inline-flex; |
| align-items: center; |
| gap: 0.5rem; |
| } |
| |
| .action-btn-primary { |
| background: var(--primary-color); |
| color: white; |
| box-shadow: 0 4px 6px rgba(79, 70, 229, 0.2); |
| } |
| |
| .action-btn-primary:hover { |
| background: var(--primary-hover); |
| transform: translateY(-2px); |
| box-shadow: 0 8px 12px rgba(79, 70, 229, 0.3); |
| } |
| |
| |
| .priority-section { |
| margin-bottom: 2rem; |
| animation: fadeInUp 0.9s ease-out; |
| } |
| |
| .priority-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); |
| gap: 1rem; |
| } |
| |
| .priority-card { |
| background: #FEF2F2; |
| border: 1px solid #FCA5A5; |
| padding: 1.25rem; |
| border-radius: var(--radius-lg); |
| position: relative; |
| } |
| |
| .priority-card.warning { |
| background: #FFFBEB; |
| border-color: #FCD34D; |
| } |
| |
| .priority-header { |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| margin-bottom: 0.5rem; |
| } |
| |
| .priority-title { |
| font-weight: 700; |
| color: #991B1B; |
| display: flex; |
| align-items: center; |
| gap: 0.5rem; |
| } |
| |
| .priority-card.warning .priority-title { |
| color: #92400E; |
| } |
| |
| .priority-value { |
| font-weight: 800; |
| font-size: 1.1rem; |
| } |
| |
| .priority-desc { |
| font-size: 0.9rem; |
| color: var(--text-main); |
| margin-bottom: 0.5rem; |
| } |
| |
| .info-tooltip { |
| display: inline-block; |
| cursor: pointer; |
| color: var(--primary-color); |
| margin-left: 0.5rem; |
| } |
| |
| .explanation-box { |
| background: white; |
| padding: 0.75rem; |
| border-radius: var(--radius-md); |
| font-size: 0.85rem; |
| margin-top: 0.5rem; |
| border-left: 3px solid var(--primary-color); |
| display: none; |
| } |
| |
| .explanation-box.visible { |
| display: block; |
| animation: fadeInDown 0.3s ease-out; |
| } |
| |
| .action-btn-secondary { |
| background: white; |
| color: var(--text-main); |
| border: 1px solid var(--border-color); |
| } |
| |
| .action-btn-secondary:hover { |
| background: var(--bg-body); |
| } |
| |
| |
| @keyframes fadeInDown { |
| from { |
| opacity: 0; |
| transform: translateY(-20px); |
| } |
| |
| to { |
| opacity: 1; |
| transform: translateY(0); |
| } |
| } |
| |
| @keyframes fadeInUp { |
| from { |
| opacity: 0; |
| transform: translateY(20px); |
| } |
| |
| to { |
| opacity: 1; |
| transform: translateY(0); |
| } |
| } |
| </style> |
| </head> |
|
|
| <body> |
| |
| <div class="background-glow"></div> |
|
|
| |
| <header class="site-header"> |
| <div class="header-container"> |
| <div class="brand"> |
| <span class="heart-icon">❤️</span> |
| <span class="brand-name">HeartCare</span> |
| </div> |
| <nav class="nav-links"> |
| <a href="/">Home</a> |
| <a href="/#about">About</a> |
| <a href="/#contact">Contact</a> |
| <a href="/calculate" class="btn-start">Start Assessment</a> |
| </nav> |
| </div> |
| </header> |
|
|
| <main class="container recommendation-page"> |
| |
| <div class="page-header"> |
| <h1>Your Personalized Health Report</h1> |
| <p>Comprehensive cardiovascular risk assessment with tailored recommendations</p> |
| </div> |
|
|
| |
| <div class="risk-selector"> |
| <h3>Select Risk Level to View Details</h3> |
| <p class="small" style="margin-bottom: 1rem;">Click on a risk level below or the system will auto-select based on |
| your assessment</p> |
| <div class="risk-pills"> |
| <div class="risk-pill vlow" onclick="show(1)"> |
| Very Low<br><small>0–20%</small> |
| </div> |
| <div class="risk-pill low" onclick="show(2)"> |
| Low<br><small>21–40%</small> |
| </div> |
| <div class="risk-pill mod" onclick="show(3)"> |
| Moderate<br><small>41–60%</small> |
| </div> |
| <div class="risk-pill high" onclick="show(4)"> |
| High<br><small>61–80%</small> |
| </div> |
| <div class="risk-pill vh" onclick="show(5)"> |
| Very High<br><small>81–100%</small> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="report-grid"> |
| |
| <div class="main-content"> |
| <div id="detailsArea"></div> |
|
|
| |
| <div class="action-section"> |
| <h3><i class="fa-solid fa-download"></i> Export & Download</h3> |
| <div class="action-buttons"> |
| <button class="action-btn action-btn-primary" onclick="downloadDietPDF()"> |
| <i class="fa-solid fa-file-pdf"></i> Download Diet Plan (PDF) |
| </button> |
| <button class="action-btn action-btn-secondary" onclick="downloadDietCSV()"> |
| <i class="fa-solid fa-file-csv"></i> Download Diet Plan (CSV) |
| </button> |
| <button class="action-btn action-btn-primary" onclick="generatePDF()"> |
| <i class="fa-solid fa-file-medical"></i> Download Full Report (PDF) |
| </button> |
| <button class="action-btn action-btn-secondary" onclick="printFriendly()"> |
| <i class="fa-solid fa-print"></i> Print Report |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="sidebar"> |
| |
| <div class="card"> |
| <h3><i class="fa-solid fa-gauge-high"></i> Risk Severity</h3> |
| <div class="meter-container"> |
| <div class="meter"> |
| <svg width="160" height="160" viewBox="0 0 100 100"> |
| <defs> |
| <linearGradient id="meterGradient" x1="0" x2="1"> |
| <stop offset="0%" stop-color="#10B981" /> |
| <stop offset="50%" stop-color="#FBBF24" /> |
| <stop offset="100%" stop-color="#EF4444" /> |
| </linearGradient> |
| </defs> |
| <circle cx="50" cy="50" r="40" stroke="#E5E7EB" stroke-width="12" fill="none"></circle> |
| <circle id="meterArc" cx="50" cy="50" r="40" stroke="url(#meterGradient)" stroke-width="12" |
| stroke-linecap="round" fill="none" stroke-dasharray="0 251.2"></circle> |
| </svg> |
| <div class="center"> |
| <div class="percent" id="meterPercent">0%</div> |
| <div class="label" id="meterLabel">Risk Level</div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="card"> |
| <h3><i class="fa-solid fa-chart-column"></i> Risk Factor Analysis</h3> |
| <div class="chart-container"> |
| <canvas id="factorChart"></canvas> |
| </div> |
| </div> |
|
|
| |
| <div class="card"> |
| <h3><i class="fa-solid fa-user-doctor"></i> Nearby Cardiologists</h3> |
| <p class="small" style="margin-bottom: 1rem;">Recommended specialists in Nanded, Maharashtra</p> |
| <div id="map"></div> |
| <div class="doctor-list" id="doctorList"></div> |
| </div> |
| </div> |
| </div> |
| </main> |
|
|
| |
| <footer class="footer"> |
| <div class="footer-container"> |
| <div class="footer-about"> |
| <h3>HeartCare</h3> |
| <p>HeartCare is a heart disease risk prediction platform created to promote early detection, awareness, and |
| prevention of cardiovascular diseases.</p> |
| </div> |
| <div class="footer-links"> |
| <h4>Quick Links</h4> |
| <a href="/">Home</a> |
| <a href="/#about">About</a> |
| <a href="/#contact">Contact</a> |
| <a href="/calculate">Start Calculation</a> |
| </div> |
| <div class="footer-contact"> |
| <h4>Contact Info</h4> |
| <p><strong>Email:</strong> support@heartcare.com</p> |
| <p><strong>Phone:</strong> +91 9876543210</p> |
| <p><strong>Location:</strong> Nanded, Maharashtra, India</p> |
| </div> |
| </div> |
| <div class="footer-bottom"> |
| <p>© 2025 HeartCare | AI Heart Disease Risk Prediction System | All Rights Reserved</p> |
| </div> |
| </footer> |
|
|
| <script> |
| |
| const doctors = [ |
| { name: "Dr. Shrikant Bhoskar", address: "Sunrise Global Hospital, Nanded", phone: "+91 70454 45363", email: "shrikant@example.com", lat: 19.1683962, lon: 77.3063096 }, |
| { name: "Dr. Sunil Kamble", address: "Rhythm Heart Care Clinic, Nanded", phone: "+91 92267 30273", email: "sunil@example.com", lat: 19.1574799, lon: 77.3081876 }, |
| { name: "Dattakrupa Heart Care", address: "Doctor Lane, Khadakpura, Nanded", phone: "+91 93071 27289", email: "dattakrupa@example.com", lat: 19.159009, lon: 77.307444 } |
| ]; |
| |
| const NANDED_LAT = 19.1601; |
| const NANDED_LON = 77.3040; |
| |
| |
| const PLANS = { |
| 1: { |
| title: "✅ Very Low Risk (0–20%)", |
| desc: "Excellent health status! Continue your healthy lifestyle with routine checkups once per year.", |
| factors: [2, 2, 1, 2, 2], |
| diet: ["Daily fruits & vegetables", "Whole grains", "Limit processed sugar", "Stay hydrated"], |
| exercise: ["30 min walk daily", "Yoga/Stretching 3× week", "Light cardio activities"] |
| }, |
| 2: { |
| title: "🟢 Low Risk (21–40%)", |
| desc: "Good health with room for improvement. Small lifestyle changes recommended.", |
| factors: [3, 3, 2, 3, 3], |
| diet: ["Reduce salt intake", "Increase fiber", "Include omega-3 foods", "Limit saturated fats"], |
| exercise: ["Brisk walk 30–40 mins daily", "Light resistance training 2× week", "Swimming or cycling"] |
| }, |
| 3: { |
| title: "🟡 Moderate Risk (41–60%)", |
| desc: "Preventive action advised. Please consult your doctor for personalized guidance.", |
| factors: [5, 6, 5, 5, 4], |
| diet: ["Mediterranean diet", "Avoid fried foods", "Limit red meat", "Increase vegetables"], |
| exercise: ["Brisk walking 30–45 mins", "Swimming or cycling", "Yoga for stress management"] |
| }, |
| 4: { |
| title: "🟠 High Risk (61–80%)", |
| desc: "Cardiologist consultation strongly recommended. Take immediate preventive measures.", |
| factors: [7, 8, 7, 6, 5], |
| diet: ["Low sodium & low saturated fat", "Small frequent meals", "Consult dietician", "Avoid processed foods"], |
| exercise: ["Doctor-approved light exercise only", "Avoid heavy exertion", "Gentle walking"] |
| }, |
| 5: { |
| title: "🔴 Very High Risk (81–100%)", |
| desc: "URGENT: Immediate medical attention required. Please visit ER or cardiology specialist now.", |
| factors: [9, 10, 9, 8, 7], |
| diet: ["Strict medical diet", "Monitor blood sugar", "Avoid processed foods", "Follow doctor's plan"], |
| exercise: ["Only doctor-approved minimal activity", "Complete rest if advised"] |
| } |
| }; |
| |
| |
| let currentRiskLevel = {{ risk_level }}; |
| const params = new URLSearchParams(location.search); |
| const riskPercentParam = parseFloat(params.get("risk")) || (currentRiskLevel * 20 - 10); |
| |
| let factorChartInstance = null; |
| |
| |
| let map = L.map('map', { scrollWheelZoom: false }).setView([NANDED_LAT, NANDED_LON], 13); |
| L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }).addTo(map); |
| |
| doctors.forEach((d) => { |
| const marker = L.marker([d.lat, d.lon]).addTo(map); |
| marker.bindPopup(`<strong>${d.name}</strong><br>${d.address}<br>Phone: ${d.phone}`); |
| }); |
| |
| |
| function refreshDoctorList() { |
| const div = document.getElementById('doctorList'); |
| div.innerHTML = ''; |
| doctors.forEach(d => { |
| const el = document.createElement('div'); |
| el.className = 'doctor-card'; |
| el.innerHTML = ` |
| <div class="doctor-name">${d.name}</div> |
| <div class="doctor-info">${d.address}</div> |
| <div class="doctor-info">📞 ${d.phone}</div> |
| <div class="doctor-actions"> |
| <button class="btn-small btn-outline" onclick="emailDoctor('${d.email}','${d.name}')"> |
| <i class="fa-solid fa-envelope"></i> Email |
| </button> |
| <button class="btn-small btn-primary-small" onclick="alertDoctor('${d.email}','${d.name}')"> |
| <i class="fa-solid fa-bell"></i> Send Alert |
| </button> |
| </div> |
| `; |
| div.appendChild(el); |
| }); |
| } |
| refreshDoctorList(); |
| |
| |
| function show(level) { |
| currentRiskLevel = level; |
| const data = PLANS[level]; |
| const details = document.getElementById('detailsArea'); |
| |
| |
| document.querySelectorAll('.risk-pill').forEach(pill => pill.classList.remove('active')); |
| document.querySelectorAll('.risk-pill')[level - 1].classList.add('active'); |
| |
| const priorityHTML = getPriorityFactorsHTML(); |
| |
| details.innerHTML = ` |
| <div class="report-card highlight" id="detailSection"> |
| <div class="report-title">${data.title}</div> |
| <div class="report-subtitle">${data.desc}</div> |
| |
| <div style="background: linear-gradient(135deg, #EEF2FF 0%, #E0E7FF 100%); padding: 1.5rem; border-radius: var(--radius-lg); margin-bottom: 2rem;"> |
| <h4 style="margin: 0 0 0.5rem 0; color: var(--primary-color);"><i class="fa-solid fa-chart-line"></i> Your Risk Score</h4> |
| <p style="margin: 0; font-size: 2rem; font-weight: 800; color: var(--text-main);" id="predRiskText">--</p> |
| </div> |
| |
| ${priorityHTML} |
| |
| <h3 style="margin-bottom: 1.5rem; font-size: 1.5rem;"><i class="fa-solid fa-clipboard-list"></i> Personalized Recommendations</h3> |
| <div class="recommendations-grid"> |
| <div class="recommendation-card"> |
| <h4><i class="fa-solid fa-utensils"></i> Diet Plan</h4> |
| <ul>${data.diet.map(i => `<li>${i}</li>`).join('')}</ul> |
| </div> |
| <div class="recommendation-card"> |
| <h4><i class="fa-solid fa-dumbbell"></i> Exercise</h4> |
| <ul>${data.exercise.map(i => `<li>${i}</li>`).join('')}</ul> |
| </div> |
| <div class="recommendation-card"> |
| <h4><i class="fa-solid fa-stethoscope"></i> Medical Care</h4> |
| <ul> |
| <li>${data.desc}</li> |
| <li>Recommended tests: BP, Lipid profile, ECG</li> |
| ${level >= 4 ? '<li style="color: #EF4444; font-weight: 600;">Consult cardiologist immediately</li>' : ''} |
| </ul> |
| </div> |
| </div> |
| </div> |
| `; |
| |
| const risk = (typeof riskPercentParam === 'number' && !Number.isNaN(riskPercentParam)) ? riskPercentParam : Math.min(100, Math.max(5, level * 20 - 5)); |
| animateMeter(risk); |
| document.getElementById('predRiskText').innerText = risk + '%'; |
| renderChart(data.factors); |
| |
| setTimeout(() => document.getElementById('detailSection').scrollIntoView({ behavior: 'smooth' }), 150); |
| } |
| |
| function getPriorityFactorsHTML() { |
| const factors = []; |
| |
| |
| const bmi = parseFloat(params.get('BMI')); |
| if (bmi >= 30) { |
| factors.push({ |
| title: 'High BMI (Obesity)', |
| value: bmi, |
| desc: 'A BMI above 30 significantly increases heart disease risk.', |
| critical: true, |
| tip: 'Aim for a BMI between 18.5 and 24.9 through calorie deficit and regular exercise.' |
| }); |
| } else if (bmi >= 25) { |
| factors.push({ |
| title: 'Overweight', |
| value: bmi, |
| desc: 'Being overweight is a modifiable risk factor.', |
| critical: false, |
| tip: 'Slight weight loss (5-10%) can produce significant health benefits.' |
| }); |
| } |
| |
| |
| if (params.get('Smoking') === '1') { |
| factors.push({ |
| title: 'Smoking History', |
| value: 'Yes', |
| desc: 'Smoking damages blood vessels and reduces oxygen delivery.', |
| critical: true, |
| tip: 'Quitting smoking is the most impactful step for heart health. Ask a doctor about cessation aids.' |
| }); |
| } |
| |
| |
| const diabetes = params.get('Diabetes'); |
| if (diabetes === 'Yes' || diabetes === 'During Pregnancy') { |
| factors.push({ |
| title: 'Diabetes Indicator', |
| value: diabetes, |
| desc: 'High blood sugar damages nerves and blood vessels controlling the heart.', |
| critical: true, |
| tip: 'Monitor blood sugar daily and adhere to a low-glycemic diet.' |
| }); |
| } |
| |
| |
| const alcohol = parseInt(params.get('Alcohol')); |
| if (alcohol > 14) { |
| factors.push({ |
| title: 'High Alcohol Intake', |
| value: `${alcohol} days/mo`, |
| desc: 'Excessive alcohol can lead to high blood pressure and heart failure.', |
| critical: false, |
| tip: 'Limit alcohol to max 1-2 drinks per occasion or consider abstinence.' |
| }); |
| } |
| |
| |
| const age = parseInt(params.get('Age')); |
| if (age > 65) { |
| factors.push({ |
| title: 'Age Factor', |
| value: `${age} yrs`, |
| desc: 'Cardiovascular risk naturally increases with age.', |
| critical: false, |
| tip: 'More frequent checkups (every 6 months) are recommended for your age group.' |
| }); |
| } |
| |
| |
| const genHealth = params.get('General_Health'); |
| if (genHealth === 'Poor' || genHealth === 'Fair') { |
| factors.push({ |
| title: 'Self-Reported Health', |
| value: genHealth, |
| desc: 'Your self-perception often correlates with underlying issues.', |
| critical: true, |
| tip: 'Discuss your specific symptoms (fatigue, pain) with a GP.' |
| }); |
| } |
| |
| |
| if (params.get('Depression') === '1') { |
| factors.push({ |
| title: 'Emotional Well-being', |
| value: 'Depression Indicator', |
| desc: 'Mental health significantly impacts physical heart health.', |
| critical: false, |
| tip: 'Regular exercise and therapy can improve both mood and heart health.' |
| }); |
| } |
| |
| |
| if (params.get('Arthritis') === '1') { |
| factors.push({ |
| title: 'Chronic Condition', |
| value: 'Arthritis', |
| desc: 'Inflammation from arthritis can affect cardiovascular health.', |
| critical: false, |
| tip: 'Focus on low-impact activities like swimming to keep the heart healthy without straining joints.' |
| }); |
| } |
| |
| |
| if (params.get('Skin_Cancer') === '1' || params.get('Other_Cancer') === '1') { |
| factors.push({ |
| title: 'Medical History', |
| value: 'Cancer Survivor', |
| desc: 'Prior health challenges require more careful cardiovascular monitoring.', |
| critical: false, |
| tip: 'Maintain regular follow-ups with your oncology and cardiology team.' |
| }); |
| } |
| |
| if (factors.length === 0) return ''; |
| |
| return ` |
| <div class="priority-section"> |
| <h3 style="color: #991B1B; margin-bottom: 1rem;"><i class="fa-solid fa-triangle-exclamation"></i> Priority Risk Factors</h3> |
| <div class="priority-grid"> |
| ${factors.map((f, i) => ` |
| <div class="priority-card ${f.critical ? '' : 'warning'}"> |
| <div class="priority-header"> |
| <div class="priority-title"> |
| ${f.critical ? '<i class="fa-solid fa-circle-exclamation"></i>' : '<i class="fa-solid fa-circle-info"></i>'} |
| ${f.title} |
| </div> |
| <div class="priority-value">${f.value}</div> |
| </div> |
| <div class="priority-desc">${f.desc}</div> |
| <div style="font-size: 0.85rem; color: var(--primary-color); font-weight: 600; cursor: pointer;" onclick="toggleExp(${i})"> |
| <i class="fa-regular fa-lightbulb"></i> View Advice |
| </div> |
| <div id="exp-${i}" class="explanation-box"> |
| <strong><i class="fa-solid fa-user-doctor"></i> Recommendation:</strong> ${f.tip} |
| </div> |
| </div> |
| `).join('')} |
| </div> |
| </div> |
| `; |
| } |
| |
| function toggleExp(i) { |
| const el = document.getElementById(`exp-${i}`); |
| el.classList.toggle('visible'); |
| } |
| |
| |
| function animateMeter(percent) { |
| const arc = document.getElementById('meterArc'); |
| const meterPercent = document.getElementById('meterPercent'); |
| const circumference = 2 * Math.PI * 40; |
| const target = Math.max(0, Math.min(100, percent)); |
| const length = (target / 100) * circumference; |
| |
| let current = 0; |
| const steps = 50; |
| const stepVal = length / steps; |
| |
| if (window.meterAnim) clearInterval(window.meterAnim); |
| arc.style.strokeDasharray = `0 ${circumference}`; |
| |
| window.meterAnim = setInterval(() => { |
| current += stepVal; |
| const filled = current; |
| const remain = Math.max(0, circumference - filled); |
| arc.style.strokeDasharray = `${filled} ${remain}`; |
| meterPercent.innerText = Math.round((filled / circumference) * 100) + '%'; |
| if (filled >= length - 0.1) { |
| clearInterval(window.meterAnim); |
| meterPercent.innerText = Math.round(target) + '%'; |
| } |
| }, 10); |
| } |
| |
| |
| function renderChart(values) { |
| const ctx = document.getElementById('factorChart').getContext('2d'); |
| if (factorChartInstance) factorChartInstance.destroy(); |
| factorChartInstance = new Chart(ctx, { |
| type: 'bar', |
| data: { |
| labels: ['BMI', 'BP', 'Cholesterol', 'Lifestyle', 'Diet'], |
| datasets: [{ |
| label: 'Factor Level', |
| data: values, |
| backgroundColor: ['#10B981', '#34D399', '#FBBF24', '#FB923C', '#EF4444'] |
| }] |
| }, |
| options: { |
| responsive: true, |
| maintainAspectRatio: false, |
| plugins: { legend: { display: false } }, |
| scales: { y: { beginAtZero: true, max: 10 } } |
| } |
| }); |
| } |
| |
| |
| function downloadDietCSV() { |
| const lev = currentRiskLevel; |
| const plan = PLANS[lev]; |
| const rows = [['Type', 'Item'], ...plan.diet.map(i => ['Diet', i]), ...plan.exercise.map(i => ['Exercise', i])]; |
| const csv = rows.map(r => r.map(c => `"${String(c).replace(/"/g, '""')}"`).join(',')).join('\n'); |
| const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = `heartcare_diet_plan_level_${lev}.csv`; |
| document.body.appendChild(a); |
| a.click(); |
| a.remove(); |
| URL.revokeObjectURL(url); |
| } |
| |
| async function downloadDietPDF() { |
| const { jsPDF } = window.jspdf; |
| const doc = new jsPDF(); |
| const lev = currentRiskLevel; |
| const plan = PLANS[lev]; |
| doc.setFontSize(16); |
| doc.text(`HeartCare - Diet & Exercise Plan`, 14, 20); |
| doc.setFontSize(14); |
| doc.text(`${plan.title}`, 14, 30); |
| doc.setFontSize(12); |
| let y = 44; |
| doc.text('Diet Recommendations:', 14, y); |
| y += 6; |
| plan.diet.forEach(i => { doc.text(`• ${i}`, 18, y); y += 6; }); |
| y += 4; |
| doc.text('Exercise Recommendations:', 14, y); |
| y += 6; |
| plan.exercise.forEach(i => { doc.text(`• ${i}`, 18, y); y += 6; }); |
| doc.save(`heartcare_diet_plan_level_${lev}.pdf`); |
| } |
| |
| function printFriendly() { |
| window.print(); |
| } |
| |
| async function generatePDF() { |
| const { jsPDF } = window.jspdf; |
| const doc = new jsPDF({ unit: 'px', format: 'a4' }); |
| const lev = currentRiskLevel; |
| const plan = PLANS[lev]; |
| const risk = riskPercentParam || (lev * 20 - 10); |
| |
| doc.setFontSize(20); |
| doc.text('HeartCare — Health Report', 20, 30); |
| doc.setFontSize(12); |
| doc.text(`${plan.title} — Risk: ${risk}%`, 20, 52); |
| doc.text(`Generated: ${new Date().toLocaleString()}`, 20, 68); |
| |
| const chartCanvas = document.getElementById('factorChart'); |
| const chartDataUrl = chartCanvas.toDataURL('image/png', 1.0); |
| doc.addImage(chartDataUrl, 'PNG', 20, 90, 320, 160); |
| |
| let y = 260; |
| doc.setFontSize(13); |
| doc.text('Diet Recommendations:', 20, y); |
| y += 16; |
| plan.diet.forEach(i => { doc.setFontSize(11); doc.text('• ' + i, 24, y); y += 12; }); |
| y += 8; |
| doc.setFontSize(13); |
| doc.text('Exercise Recommendations:', 20, y); |
| y += 16; |
| plan.exercise.forEach(i => { doc.setFontSize(11); doc.text('• ' + i, 24, y); y += 12; }); |
| y += 14; |
| doc.setFontSize(13); |
| doc.text('Nearby Doctors:', 20, y); |
| y += 16; |
| doctors.forEach(d => { |
| doc.setFontSize(11); |
| doc.text(`${d.name} — ${d.address} — ${d.phone}`, 24, y); |
| y += 12; |
| }); |
| doc.save(`heartcare_report_level_${lev}.pdf`); |
| } |
| |
| function emailDoctor(email, name) { |
| const lev = currentRiskLevel; |
| const risk = riskPercentParam || (lev * 20 - 10); |
| const subject = encodeURIComponent(`HeartCare: Consultation Request — Risk ${risk}%`); |
| const body = encodeURIComponent(`Dear ${name},\n\nI am contacting you regarding a cardiovascular risk assessment showing ${risk}% risk. Please let me know your available consultation slots.\n\nRegards,\nHeartCare User`); |
| window.location.href = `mailto:${email}?subject=${subject}&body=${body}`; |
| } |
| |
| function alertDoctor(email, name) { |
| emailDoctor(email, name); |
| } |
| |
| /* Initialize */ |
| window.addEventListener('load', () => { |
| show(currentRiskLevel); |
| }); |
| </script> |
| </body> |
|
|
| </html> |