Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Heart Disease Predictor</title> | |
| <style> | |
| body { font-family: Arial; background: #f3f4f6; margin: 0; padding: 20px; } | |
| .container { max-width: 700px; margin: auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); } | |
| h1, h2 { text-align: center; color: #d90429; } | |
| label { font-weight: bold; margin-top: 10px; display: block; } | |
| input, select, button { width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 5px; } | |
| button { margin-top: 15px; background: #d90429; color: white; font-size: 16px; border: none; border-radius: 5px; cursor: pointer; } | |
| button:hover { background: #a0031f; } | |
| .result { margin-top: 20px; padding: 15px; border-radius: 5px; font-size: 18px; text-align: center; font-weight: bold; } | |
| .success { background: #d4edda; color: #155724; } | |
| .danger { background: #f8d7da; color: #721c24; } | |
| .section { margin-top: 30px; } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>❤️ Heart Disease Predictor</h1> | |
| <div class="container"> | |
| <!-- Single Patient Prediction --> | |
| <div class="section"> | |
| <h2>Single Patient Prediction</h2> | |
| <form id="predictForm"> | |
| <!-- Age --> | |
| <label>Age</label> | |
| <select id="age" required> | |
| <option value="">-- Select Age --</option> | |
| {% for i in range(20, 81) %} | |
| <option value="{{ i }}">{{ i }}</option> | |
| {% endfor %} | |
| </select> | |
| <!-- Sex --> | |
| <label>Sex</label> | |
| <select id="sex" required> | |
| <option value="">-- Select Sex --</option> | |
| <option value="0">Female</option> | |
| <option value="1">Male</option> | |
| </select> | |
| <!-- Chest Pain Type --> | |
| <label>Chest Pain Type</label> | |
| <select id="cp" required> | |
| <option value="">-- Select Type --</option> | |
| <option value="0">Typical Angina</option> | |
| <option value="1">Atypical Angina</option> | |
| <option value="2">Non-anginal Pain</option> | |
| <option value="3">Asymptomatic</option> | |
| </select> | |
| <!-- Resting Blood Pressure --> | |
| <label>Resting BP</label> | |
| <input type="number" id="trestbps" required> | |
| <!-- Cholesterol --> | |
| <label>Cholesterol</label> | |
| <input type="number" id="chol" required> | |
| <!-- Fasting Blood Sugar --> | |
| <label>Fasting Blood Sugar</label> | |
| <select id="fbs" required> | |
| <option value="">-- Select --</option> | |
| <option value="0"><=120 mg/dl</option> | |
| <option value="1">>120 mg/dl</option> | |
| </select> | |
| <!-- Resting ECG --> | |
| <label>Resting ECG</label> | |
| <select id="restecg" required> | |
| <option value="">-- Select --</option> | |
| <option value="0">Normal</option> | |
| <option value="1">ST-T abnormality</option> | |
| <option value="2">Left ventricular hypertrophy</option> | |
| </select> | |
| <!-- Max Heart Rate --> | |
| <label>Max Heart Rate</label> | |
| <input type="number" id="thalach" required> | |
| <!-- Exercise Induced Angina --> | |
| <label>Exercise Angina</label> | |
| <select id="exang" required> | |
| <option value="">-- Select --</option> | |
| <option value="0">No</option> | |
| <option value="1">Yes</option> | |
| </select> | |
| <!-- Oldpeak --> | |
| <label>Oldpeak</label> | |
| <input type="number" step="0.1" id="oldpeak" required> | |
| <!-- Slope --> | |
| <label>Slope</label> | |
| <select id="slope" required> | |
| <option value="">-- Select --</option> | |
| <option value="0">Upsloping</option> | |
| <option value="1">Flat</option> | |
| <option value="2">Downsloping</option> | |
| </select> | |
| <!-- Number of Major Vessels --> | |
| <label>Number of Vessels</label> | |
| <select id="ca" required> | |
| <option value="">-- Select --</option> | |
| <option value="0">0</option> | |
| <option value="1">1</option> | |
| <option value="2">2</option> | |
| <option value="3">3</option> | |
| </select> | |
| <!-- Thal --> | |
| <label>Thal</label> | |
| <select id="thal" required> | |
| <option value="">-- Select --</option> | |
| <option value="1">Normal</option> | |
| <option value="2">Fixed Defect</option> | |
| <option value="3">Reversible Defect</option> | |
| </select> | |
| <button type="submit">Predict</button> | |
| </form> | |
| <div id="prediction_result" class="result"></div> | |
| </div> | |
| <!-- Batch CSV Upload --> | |
| <div class="section"> | |
| <h2>Batch Prediction (Upload CSV)</h2> | |
| <form id="batchForm" enctype="multipart/form-data" method="post" action="/batch_predict"> | |
| <input type="file" id="csvFile" name="file" accept=".csv" required> | |
| <button type="submit">Upload & Predict</button> | |
| </form> | |
| <div id="batchResult" class="result"></div> | |
| </div> | |
| </div> | |
| <script> | |
| // Single patient dynamic prediction | |
| document.getElementById("predictForm").addEventListener("submit", async function(e) { | |
| e.preventDefault(); | |
| const data = { | |
| age: parseInt(document.getElementById("age").value), | |
| sex: parseInt(document.getElementById("sex").value), | |
| cp: parseInt(document.getElementById("cp").value), | |
| trestbps: parseInt(document.getElementById("trestbps").value), | |
| chol: parseInt(document.getElementById("chol").value), | |
| fbs: parseInt(document.getElementById("fbs").value), | |
| restecg: parseInt(document.getElementById("restecg").value), | |
| thalach: parseInt(document.getElementById("thalach").value), | |
| exang: parseInt(document.getElementById("exang").value), | |
| oldpeak: parseFloat(document.getElementById("oldpeak").value), | |
| slope: parseInt(document.getElementById("slope").value), | |
| ca: parseInt(document.getElementById("ca").value), | |
| thal: parseInt(document.getElementById("thal").value) | |
| }; | |
| try { | |
| const res = await fetch("/predict_json", { | |
| method: "POST", | |
| headers: {"Content-Type": "application/json"}, | |
| body: JSON.stringify(data) | |
| }); | |
| const result = await res.json(); | |
| const div = document.getElementById("prediction_result"); | |
| if (result.prediction) { | |
| div.textContent = result.prediction; | |
| div.className = "result " + (result.prediction.includes("No") ? "success" : "danger"); | |
| } else { | |
| div.textContent = "Error: " + result.error; | |
| div.className = "result danger"; | |
| } | |
| } catch(err) { | |
| console.error(err); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |