IS-335-Demo / interactive_decision_tree.html
Ric
Add UNLV study location space app
23a9ae4
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Decision Tree - UNLV Edition</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #CE1126 0%, #990000 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.header p {
font-size: 1.2em;
opacity: 0.9;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
padding: 30px;
}
.input-panel {
background: #f8f9fa;
padding: 25px;
border-radius: 15px;
}
.input-group {
margin-bottom: 25px;
}
.input-group label {
display: block;
font-weight: 600;
margin-bottom: 8px;
color: #333;
font-size: 1.1em;
}
.input-group input[type="range"] {
width: 100%;
height: 8px;
border-radius: 5px;
background: #ddd;
outline: none;
-webkit-appearance: none;
}
.input-group input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #CE1126;
cursor: pointer;
}
.input-group input[type="range"]::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background: #CE1126;
cursor: pointer;
border: none;
}
.value-display {
display: inline-block;
background: #CE1126;
color: white;
padding: 5px 15px;
border-radius: 20px;
font-weight: bold;
margin-left: 10px;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 10px;
}
.checkbox-group input[type="checkbox"] {
width: 20px;
height: 20px;
cursor: pointer;
}
.predict-button {
width: 100%;
padding: 15px;
background: linear-gradient(135deg, #CE1126 0%, #990000 100%);
color: white;
border: none;
border-radius: 10px;
font-size: 1.2em;
font-weight: bold;
cursor: pointer;
transition: transform 0.2s;
}
.predict-button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(206, 17, 38, 0.4);
}
.result-panel {
padding: 25px;
}
.prediction-result {
text-align: center;
padding: 30px;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
border-radius: 15px;
margin-bottom: 20px;
}
.prediction-icon {
font-size: 5em;
margin-bottom: 15px;
}
.prediction-text {
font-size: 2em;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.confidence {
font-size: 1.2em;
color: #666;
}
.decision-path {
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
}
.decision-path h3 {
color: #CE1126;
margin-bottom: 15px;
}
.path-step {
padding: 10px;
margin: 8px 0;
background: white;
border-left: 4px solid #CE1126;
border-radius: 5px;
}
.explanation {
background: #fff3cd;
border: 2px solid #ffc107;
padding: 20px;
border-radius: 10px;
}
.explanation h3 {
color: #856404;
margin-bottom: 10px;
}
@media (max-width: 768px) {
.content {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🌳 Interactive Decision Tree</h1>
<p>UNLV Study Location Predictor</p>
</div>
<div class="content">
<div class="input-panel">
<h2 style="margin-bottom: 20px; color: #CE1126;">Enter Current Conditions</h2>
<div class="input-group">
<label>
🌡️ Temperature
<span class="value-display" id="tempValue">85°F</span>
</label>
<input type="range" id="temperature" min="60" max="115" value="85" step="1">
<small style="color: #666;">Las Vegas range: 60-115°F</small>
</div>
<div class="input-group">
<label>
💧 Humidity
<span class="value-display" id="humidityValue">20%</span>
</label>
<input type="range" id="humidity" min="5" max="40" value="20" step="1">
<small style="color: #666;">Las Vegas is typically dry</small>
</div>
<div class="input-group">
<label>
💨 Wind Speed
<span class="value-display" id="windValue">10 mph</span>
</label>
<input type="range" id="wind" min="0" max="25" value="10" step="1">
</div>
<div class="input-group">
<label>
🕐 Time of Day
<span class="value-display" id="hourValue">14:00</span>
</label>
<input type="range" id="hour" min="8" max="22" value="14" step="1">
<small style="color: #666;">8:00 AM - 10:00 PM</small>
</div>
<div class="input-group">
<div class="checkbox-group">
<input type="checkbox" id="weekend">
<label for="weekend" style="margin: 0;">📅 Weekend</label>
</div>
</div>
<button class="predict-button" onclick="makePrediction()">
🔮 Predict Best Study Location
</button>
</div>
<div class="result-panel">
<div class="prediction-result">
<div class="prediction-icon" id="predictionIcon">🤔</div>
<div class="prediction-text" id="predictionText">Adjust the sliders and click Predict!</div>
<div class="confidence" id="confidence"></div>
</div>
<div class="decision-path">
<h3>🔍 Decision Path</h3>
<div id="decisionPath">
<p style="color: #666; font-style: italic;">The decision tree's reasoning will appear here...</p>
</div>
</div>
<div class="explanation">
<h3>💡 How It Works</h3>
<p>This decision tree uses a series of if-then rules to make predictions:</p>
<ul style="margin-top: 10px; margin-left: 20px;">
<li>It checks temperature, wind, and time first</li>
<li>Each decision narrows down the options</li>
<li>Finally, it reaches a leaf node with the prediction</li>
</ul>
</div>
</div>
</div>
</div>
<script>
// Update value displays
function updateValues() {
document.getElementById('tempValue').textContent =
document.getElementById('temperature').value + '°F';
document.getElementById('humidityValue').textContent =
document.getElementById('humidity').value + '%';
document.getElementById('windValue').textContent =
document.getElementById('wind').value + ' mph';
const hour = document.getElementById('hour').value;
document.getElementById('hourValue').textContent =
hour.padStart(2, '0') + ':00';
}
// Add event listeners
document.getElementById('temperature').addEventListener('input', updateValues);
document.getElementById('humidity').addEventListener('input', updateValues);
document.getElementById('wind').addEventListener('input', updateValues);
document.getElementById('hour').addEventListener('input', updateValues);
// Simple decision tree logic
function makePrediction() {
const temp = parseInt(document.getElementById('temperature').value);
const humidity = parseInt(document.getElementById('humidity').value);
const wind = parseInt(document.getElementById('wind').value);
const hour = parseInt(document.getElementById('hour').value);
const isWeekend = document.getElementById('weekend').checked;
let prediction = '';
let icon = '';
let path = [];
let confidence = '';
// Decision tree logic
path.push('📍 Starting at root node...');
if (temp > 105) {
path.push(`🌡️ Temperature ${temp}°F > 105°F → Too hot!`);
prediction = 'Library';
icon = '🏛️';
confidence = 'High confidence (95%)';
path.push('✅ Decision: Stay indoors where it\'s cool!');
} else if (temp < 75) {
path.push(`🌡️ Temperature ${temp}°F < 75°F → Checking wind...`);
if (wind > 15) {
path.push(`💨 Wind ${wind} mph > 15 mph → Too windy!`);
prediction = 'Library';
icon = '🏛️';
confidence = 'High confidence (92%)';
path.push('✅ Decision: Too windy for outdoor study');
} else {
path.push(`💨 Wind ${wind} mph ≤ 15 mph → Checking time...`);
if (hour <= 18 && hour >= 9) {
path.push(`🕐 Hour ${hour} is daytime → Perfect!`);
prediction = 'Outdoors';
icon = '🌳';
confidence = 'High confidence (88%)';
path.push('✅ Decision: Great conditions for outdoor study!');
} else {
path.push(`🕐 Hour ${hour} is evening/early → Better lighting needed`);
prediction = 'Library';
icon = '🏛️';
confidence = 'Medium confidence (78%)';
path.push('✅ Decision: Library has better lighting');
}
}
} else {
path.push(`🌡️ Temperature ${temp}°F between 75-105°F → Moderate range`);
if (wind > 20) {
path.push(`💨 Wind ${wind} mph > 20 mph → Very windy!`);
prediction = 'Library';
icon = '🏛️';
confidence = 'High confidence (90%)';
path.push('✅ Decision: Strong winds make outdoor study difficult');
} else if (temp < 85 && wind < 15 && hour <= 18 && hour >= 9) {
path.push(`✓ Temperature comfortable (${temp}°F)`);
path.push(`✓ Wind calm (${wind} mph)`);
path.push(`✓ Good daylight hours`);
prediction = 'Outdoors';
icon = '🌳';
confidence = 'Medium-High confidence (82%)';
path.push('✅ Decision: Nice conditions for outdoor study!');
} else if (hour > 19) {
path.push(`🕐 Hour ${hour} is late evening → Poor natural light`);
prediction = 'Library';
icon = '🏛️';
confidence = 'High confidence (87%)';
path.push('✅ Decision: Evening study best indoors');
} else {
path.push('🤔 Conditions are marginal...');
if (temp > 95) {
path.push(`🌡️ Temperature ${temp}°F getting hot`);
prediction = 'Library';
icon = '🏛️';
confidence = 'Medium confidence (75%)';
path.push('✅ Decision: Stay cool indoors');
} else {
prediction = 'Library';
icon = '🏛️';
confidence = 'Low-Medium confidence (68%)';
path.push('✅ Decision: Library is the safer choice');
}
}
}
// Update display
document.getElementById('predictionIcon').textContent = icon;
document.getElementById('predictionText').textContent =
`Study at the ${prediction}!`;
document.getElementById('confidence').textContent = confidence;
// Update decision path
const pathHTML = path.map(step =>
`<div class="path-step">${step}</div>`
).join('');
document.getElementById('decisionPath').innerHTML = pathHTML;
}
// Initialize
updateValues();
</script>
</body>
</html>