nnn / index.html
Vishnut7's picture
Upload index.html
d5e42a1 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mental Health Risk Prediction</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
color: #333;
}
.container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
max-width: 1200px;
width: 100%;
margin: 0 auto;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.header {
text-align: center;
margin-bottom: 40px;
}
.title {
font-size: 2.5em;
font-weight: 700;
color: #4a5568;
margin-bottom: 10px;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.brain-emoji {
font-size: 1.2em;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
.description {
font-size: 1.1em;
color: #718096;
line-height: 1.6;
}
.main-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin-bottom: 30px;
}
.input-section {
background: #f8fafc;
padding: 25px;
border-radius: 15px;
border: 2px solid #e2e8f0;
}
.input-label {
display: block;
font-weight: 600;
color: #4a5568;
margin-bottom: 10px;
}
.text-area {
width: 100%;
min-height: 200px;
padding: 15px;
border: 2px solid #e2e8f0;
border-radius: 12px;
font-size: 1em;
font-family: inherit;
resize: vertical;
transition: all 0.3s ease;
background: white;
}
.text-area:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.file-upload {
margin: 15px 0;
padding: 15px;
border: 2px dashed #cbd5e0;
border-radius: 12px;
text-align: center;
background: white;
cursor: pointer;
transition: all 0.3s ease;
}
.file-upload:hover {
border-color: #667eea;
background: #f7fafc;
}
.file-upload input {
display: none;
}
.text-stats {
background: white;
padding: 20px;
border-radius: 15px;
border: 2px solid #e2e8f0;
}
.stat-item {
display: flex;
justify-content: space-between;
margin: 10px 0;
padding: 8px 0;
border-bottom: 1px solid #edf2f7;
}
.predict-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px 40px;
font-size: 1.1em;
font-weight: 600;
border-radius: 50px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
width: 100%;
margin: 20px 0;
}
.predict-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}
.predict-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.results-section {
margin-top: 30px;
opacity: 0;
transform: translateY(20px);
transition: all 0.5s ease;
}
.results-section.show {
opacity: 1;
transform: translateY(0);
}
.result-header {
text-align: center;
margin-bottom: 30px;
}
.primary-result {
padding: 25px;
border-radius: 15px;
font-weight: 600;
font-size: 1.3em;
text-align: center;
margin-bottom: 30px;
}
.result-depression { background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%); color: white; }
.result-anxiety { background: linear-gradient(135deg, #feca57 0%, #ff9ff3 100%); color: white; }
.result-suicidal { background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); color: white; }
.result-normal { background: linear-gradient(135deg, #48dbfb 0%, #0abde3 100%); color: white; }
.charts-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 25px;
margin-bottom: 30px;
}
.chart-container {
background: white;
padding: 25px;
border-radius: 15px;
border: 2px solid #e2e8f0;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
}
.chart-title {
font-size: 1.2em;
font-weight: 600;
color: #4a5568;
margin-bottom: 15px;
text-align: center;
}
.insights-section {
background: #f8fafc;
padding: 25px;
border-radius: 15px;
border: 2px solid #e2e8f0;
}
.insights-title {
font-size: 1.3em;
font-weight: 600;
color: #4a5568;
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 10px;
}
.insight-item {
background: white;
padding: 15px;
margin: 10px 0;
border-radius: 10px;
border-left: 4px solid #667eea;
}
.loading {
display: none;
text-align: center;
color: #667eea;
margin: 20px 0;
}
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #667eea;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
display: inline-block;
margin-bottom: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.footer {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
font-size: 0.9em;
color: rgba(255, 255, 255, 0.8);
text-align: center;
}
@media (max-width: 768px) {
.main-content {
grid-template-columns: 1fr;
gap: 20px;
}
.charts-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.container {
padding: 20px;
margin: 10px;
}
.title {
font-size: 2em;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 class="title">
<span class="brain-emoji">🧠</span>
Mental Health Risk Prediction
</h1>
<p class="description">
Enter text or upload a file to analyze mental health indicators using AI-powered sentiment analysis and keyword detection.
</p>
</div>
<div class="main-content">
<div class="input-section">
<label class="input-label" for="postText">Text Input:</label>
<textarea
id="postText"
class="text-area"
placeholder="Type or paste text content here for analysis..."
></textarea>
<div class="file-upload" onclick="document.getElementById('fileInput').click()">
<input type="file" id="fileInput" accept=".txt,.csv" onchange="handleFileUpload(event)">
<div>📁 Click to upload text file (.txt, .csv)</div>
<small>Or drag and drop a file here</small>
</div>
<button id="predictBtn" class="predict-btn" onclick="analyzeText()">
🔍 Analyze Mental Health Risk
</button>
</div>
<div class="text-stats">
<h3 style="color: #4a5568; margin-bottom: 15px;">📊 Text Statistics</h3>
<div class="stat-item">
<span>Word Count:</span>
<span id="wordCount">0</span>
</div>
<div class="stat-item">
<span>Character Count:</span>
<span id="charCount">0</span>
</div>
<div class="stat-item">
<span>Sentences:</span>
<span id="sentenceCount">0</span>
</div>
<div class="stat-item">
<span>Avg. Words/Sentence:</span>
<span id="avgWords">0</span>
</div>
<div class="stat-item">
<span>Reading Time:</span>
<span id="readingTime">0 min</span>
</div>
</div>
</div>
<div class="loading" id="loading">
<div class="spinner"></div>
<div>Analyzing text content...</div>
<small>Processing sentiment, keywords, and patterns</small>
</div>
<div id="resultsSection" class="results-section">
<div class="result-header">
<h2>📈 Analysis Results</h2>
</div>
<div id="primaryResult" class="primary-result">
<!-- Primary result will appear here -->
</div>
<div class="charts-grid">
<div class="chart-container">
<div class="chart-title">Risk Distribution</div>
<canvas id="riskChart" width="400" height="300"></canvas>
</div>
<div class="chart-container">
<div class="chart-title">Sentiment Analysis</div>
<canvas id="sentimentChart" width="400" height="300"></canvas>
</div>
<div class="chart-container">
<div class="chart-title">Keyword Frequency</div>
<canvas id="keywordChart" width="400" height="300"></canvas>
</div>
<div class="chart-container">
<div class="chart-title">Text Complexity</div>
<canvas id="complexityChart" width="400" height="300"></canvas>
</div>
</div>
<div class="insights-section">
<div class="insights-title">
💡 Key Insights & Recommendations
</div>
<div id="insightsContent">
<!-- Insights will be populated here -->
</div>
</div>
</div>
</div>
<div class="footer">
Built with ❤ using Streamlit
</div>
<script>
let analysisData = {};
// Update text statistics in real-time
document.getElementById('postText').addEventListener('input', updateTextStats);
function updateTextStats() {
const text = document.getElementById('postText').value;
const words = text.trim().split(/\s+/).filter(word => word.length > 0);
const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0);
document.getElementById('wordCount').textContent = words.length;
document.getElementById('charCount').textContent = text.length;
document.getElementById('sentenceCount').textContent = sentences.length;
document.getElementById('avgWords').textContent = sentences.length > 0 ? Math.round(words.length / sentences.length) : 0;
document.getElementById('readingTime').textContent = Math.max(1, Math.ceil(words.length / 200)) + ' min';
}
function handleFileUpload(event) {
const file = event.target.files[0];
if (file && file.type === 'text/plain') {
const reader = new FileReader();
reader.onload = function(e) {
document.getElementById('postText').value = e.target.result;
updateTextStats();
};
reader.readAsText(file);
}
}
function analyzeText() {
const text = document.getElementById('postText').value.trim();
if (!text || text.length < 10) {
alert('Please enter at least 10 characters of text to analyze.');
return;
}
showLoading(true);
// Simulate API processing time
setTimeout(() => {
performAnalysis(text);
showLoading(false);
showResults();
}, 3000);
}
function showLoading(show) {
const loading = document.getElementById('loading');
const btn = document.getElementById('predictBtn');
if (show) {
loading.style.display = 'block';
btn.disabled = true;
btn.textContent = 'Analyzing...';
} else {
loading.style.display = 'none';
btn.disabled = false;
btn.textContent = '🔍 Analyze Mental Health Risk';
}
}
function performAnalysis(text) {
const words = text.toLowerCase().split(/\s+/);
// Keywords for different categories
const keywords = {
depression: ['sad', 'hopeless', 'empty', 'worthless', 'depressed', 'alone', 'tired', 'numb'],
anxiety: ['worried', 'anxious', 'panic', 'nervous', 'scared', 'stress', 'overwhelmed', 'fear'],
suicidal: ['die', 'death', 'suicide', 'end', 'kill', 'hurt', 'pain', 'escape'],
positive: ['happy', 'joy', 'good', 'great', 'love', 'excited', 'amazing', 'wonderful']
};
// Calculate keyword frequencies
const scores = {
depression: 0,
anxiety: 0,
suicidal: 0,
positive: 0
};
const foundKeywords = {};
words.forEach(word => {
Object.keys(keywords).forEach(category => {
if (keywords[category].includes(word)) {
scores[category]++;
if (!foundKeywords[word]) foundKeywords[word] = 0;
foundKeywords[word]++;
}
});
});
// Determine primary prediction
let prediction = 'Normal';
let confidence = 60;
if (scores.suicidal > 0) {
prediction = 'Suicidal';
confidence = Math.min(95, 70 + scores.suicidal * 10);
} else if (scores.depression > scores.anxiety && scores.depression > 0) {
prediction = 'Depression';
confidence = Math.min(90, 60 + scores.depression * 8);
} else if (scores.anxiety > 0) {
prediction = 'Anxiety';
confidence = Math.min(85, 55 + scores.anxiety * 8);
} else if (scores.positive > 2) {
prediction = 'Normal';
confidence = Math.min(95, 70 + scores.positive * 5);
}
// Calculate sentiment
const totalNegative = scores.depression + scores.anxiety + scores.suicidal;
const totalWords = words.length;
analysisData = {
prediction,
confidence,
riskScores: {
Depression: Math.round((scores.depression / totalWords) * 100 + Math.random() * 20),
Anxiety: Math.round((scores.anxiety / totalWords) * 100 + Math.random() * 20),
Suicidal: Math.round((scores.suicidal / totalWords) * 100 + Math.random() * 15),
Normal: Math.round(100 - (totalNegative / totalWords) * 100 + Math.random() * 25)
},
sentiment: {
Positive: Math.max(10, 100 - totalNegative * 10 + Math.random() * 20),
Neutral: Math.random() * 40 + 20,
Negative: Math.min(70, totalNegative * 15 + Math.random() * 20)
},
keywords: Object.entries(foundKeywords).sort((a, b) => b[1] - a[1]).slice(0, 8),
complexity: {
'Readability': Math.random() * 40 + 30,
'Vocabulary': Math.random() * 30 + 40,
'Sentence Length': Math.random() * 35 + 25,
'Emotional Intensity': Math.min(90, totalNegative * 20 + Math.random() * 30)
}
};
// Normalize risk scores
const total = Object.values(analysisData.riskScores).reduce((a, b) => a + b, 0);
Object.keys(analysisData.riskScores).forEach(key => {
analysisData.riskScores[key] = Math.round((analysisData.riskScores[key] / total) * 100);
});
}
function showResults() {
const resultsSection = document.getElementById('resultsSection');
const primaryResult = document.getElementById('primaryResult');
// Show primary result
const className = `result-${analysisData.prediction.toLowerCase()}`;
primaryResult.className = `primary-result ${className}`;
primaryResult.innerHTML = `
<div style="font-size: 1.5em; margin-bottom: 10px;">${analysisData.prediction}</div>
<div style="font-size: 1em; opacity: 0.9;">Confidence: ${analysisData.confidence}%</div>
<div style="font-size: 0.9em; font-weight: normal; margin-top: 10px;">
${getResultMessage(analysisData.prediction)}
</div>
`;
// Create charts
createCharts();
// Show insights
showInsights();
// Animate results
resultsSection.classList.add('show');
}
function createCharts() {
// Risk Distribution Chart (Doughnut)
const riskCtx = document.getElementById('riskChart').getContext('2d');
new Chart(riskCtx, {
type: 'doughnut',
data: {
labels: Object.keys(analysisData.riskScores),
datasets: [{
data: Object.values(analysisData.riskScores),
backgroundColor: ['#ff9a56', '#feca57', '#ff6b6b', '#48dbfb'],
borderWidth: 2,
borderColor: '#fff'
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
// Sentiment Chart (Bar)
const sentimentCtx = document.getElementById('sentimentChart').getContext('2d');
new Chart(sentimentCtx, {
type: 'bar',
data: {
labels: Object.keys(analysisData.sentiment),
datasets: [{
data: Object.values(analysisData.sentiment),
backgroundColor: ['#4CAF50', '#FFC107', '#F44336'],
borderRadius: 5
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
beginAtZero: true,
max: 100
}
}
}
});
// Keywords Chart (Horizontal Bar)
const keywordCtx = document.getElementById('keywordChart').getContext('2d');
const keywordLabels = analysisData.keywords.map(k => k[0]);
const keywordValues = analysisData.keywords.map(k => k[1]);
new Chart(keywordCtx, {
type: 'bar',
data: {
labels: keywordLabels,
datasets: [{
data: keywordValues,
backgroundColor: '#667eea',
borderRadius: 3
}]
},
options: {
indexAxis: 'y',
responsive: true,
plugins: {
legend: {
display: false
}
}
}
});
// Complexity Chart (Radar)
const complexityCtx = document.getElementById('complexityChart').getContext('2d');
new Chart(complexityCtx, {
type: 'radar',
data: {
labels: Object.keys(analysisData.complexity),
datasets: [{
data: Object.values(analysisData.complexity),
backgroundColor: 'rgba(102, 126, 234, 0.2)',
borderColor: '#667eea',
borderWidth: 2,
pointBackgroundColor: '#667eea'
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
r: {
beginAtZero: true,
max: 100
}
}
}
});
}
function showInsights() {
const insights = [];
if (analysisData.prediction === 'Suicidal') {
insights.push({
type: 'warning',
text: 'High-risk indicators detected. Immediate professional intervention recommended.'
});
insights.push({
type: 'resource',
text: 'Crisis resources: National Suicide Prevention Lifeline 988'
});
} else if (analysisData.prediction === 'Depression') {
insights.push({
type: 'recommendation',
text: 'Signs of depression detected. Consider consulting a mental health professional.'
});
insights.push({
type: 'tip',
text: 'Regular exercise and social connection can help improve mood.'
});
} else if (analysisData.prediction === 'Anxiety') {
insights.push({
type: 'recommendation',
text: 'Anxiety indicators present. Stress management techniques may be beneficial.'
});
insights.push({
type: 'tip',
text: 'Deep breathing exercises and mindfulness can help reduce anxiety.'
});
} else {
insights.push({
type: 'positive',
text: 'Text shows generally positive emotional indicators.'
});
insights.push({
type: 'tip',
text: 'Continue maintaining healthy mental wellness practices.'
});
}
// Text complexity insights
if (analysisData.complexity['Emotional Intensity'] > 60) {
insights.push({
type: 'observation',
text: 'High emotional intensity detected in the text content.'
});
}
const insightsHtml = insights.map(insight =>
`<div class="insight-item">
<strong>${insight.type.charAt(0).toUpperCase() + insight.type.slice(1)}:</strong>
${insight.text}
</div>`
).join('');
document.getElementById('insightsContent').innerHTML = insightsHtml;
}
function getResultMessage(prediction) {
const messages = {
'Depression': 'Analysis indicates potential depressive patterns. Professional evaluation recommended.',
'Anxiety': 'Anxiety-related indicators detected. Consider stress management resources.',
'Suicidal': '⚠️ Critical indicators present. Seek immediate professional help.',
'Normal': 'Text analysis shows generally healthy emotional expression patterns.'
};
return messages[prediction] || 'Analysis complete.';
}
// Initialize
updateTextStats();
</script>
</body>
</html>