alexdatamed's picture
Upload app.js
4ad38c8 verified
raw
history blame
15.9 kB
// Application data
const appData = {
"lifecycleStages": [
{
"id": 1,
"name": "Problem Formulation",
"icon": "πŸ’‘",
"description": "Transform real-world problems into data-driven questions",
"example": "Healthcare: Predicting patient recovery time based on medical history",
"keyPoints": ["Define business objectives", "Identify success metrics", "Translate to ML problem", "Set constraints and requirements"],
"status": "completed"
},
{
"id": 2,
"name": "Data Collection",
"icon": "πŸ“Š",
"description": "Gather relevant data from reliable sources",
"sources": ["Clinical databases", "IoT sensors", "Public datasets", "APIs"],
"compliance": {"HIPAA": true, "GDPR": true, "SOX": false},
"status": "completed"
},
{
"id": 3,
"name": "Data Preprocessing",
"icon": "πŸ”§",
"description": "Clean and standardize data for analysis",
"metrics": {"missingValues": 12, "normalization": "StandardScaler", "categoricalEncoding": "OneHot", "outliers": 8},
"status": "in-progress"
},
{
"id": 4,
"name": "Modeling",
"icon": "πŸ€–",
"description": "Select and apply appropriate algorithms",
"modelTypes": ["Classification", "Regression", "Clustering"],
"algorithms": ["Random Forest", "Logistic Regression", "SVM", "Neural Networks"],
"status": "pending"
},
{
"id": 5,
"name": "Evaluation",
"icon": "πŸ“ˆ",
"description": "Assess model performance and reliability",
"metrics": {"accuracy": 0.94, "precision": 0.91, "recall": 0.89, "f1Score": 0.90},
"status": "pending"
},
{
"id": 6,
"name": "Deployment",
"icon": "πŸš€",
"description": "Deploy model to production environment",
"pipeline": {"docker": true, "kubernetes": true, "cicd": "Jenkins", "api": "REST"},
"status": "pending"
},
{
"id": 7,
"name": "Monitoring & Maintenance",
"icon": "πŸ”",
"description": "Monitor performance and maintain model accuracy",
"alerts": {"dataDrift": false, "accuracyDecay": 2.1, "retrainingDue": "2025-07-15"},
"status": "pending"
}
],
"industries": [
{"name": "Healthcare", "examples": ["Patient recovery prediction", "Disease diagnosis", "Drug discovery"]},
{"name": "Retail", "examples": ["Customer segmentation", "Demand forecasting", "Price optimization"]},
{"name": "Finance", "examples": ["Fraud detection", "Credit scoring", "Algorithmic trading"]},
{"name": "Manufacturing", "examples": ["Predictive maintenance", "Quality control", "Supply chain optimization"]},
{"name": "Education", "examples": ["Student performance prediction", "Personalized learning", "Dropout prevention"]}
],
"modelTypes": [
{"name": "Logistic Regression", "type": "Classification", "accuracy": 0.85},
{"name": "Random Forest", "type": "Classification", "accuracy": 0.92},
{"name": "SVM", "type": "Classification", "accuracy": 0.88},
{"name": "Neural Networks", "type": "Classification", "accuracy": 0.94},
{"name": "Linear Regression", "type": "Regression", "rmse": 0.23},
{"name": "K-Means", "type": "Clustering", "silhouette": 0.67}
],
"complianceRequirements": {
"Healthcare": ["HIPAA", "FDA", "HITECH"],
"Finance": ["SOX", "GDPR", "PCI-DSS"],
"Retail": ["GDPR", "CCPA"],
"Manufacturing": ["ISO 27001", "GDPR"],
"Education": ["FERPA", "COPPA"]
}
};
// Global state
let currentStage = null;
let currentFilters = {
industry: '',
model: '',
version: ''
};
let evaluationChart = null;
// Initialize the application
document.addEventListener('DOMContentLoaded', function() {
initializeTimeline();
initializeFilters();
updateProgressSummary();
});
// Initialize timeline with stages
function initializeTimeline() {
const timelineStages = document.getElementById('timelineStages');
appData.lifecycleStages.forEach((stage, index) => {
const stageElement = createTimelineStage(stage, index);
timelineStages.appendChild(stageElement);
});
}
// Create timeline stage element
function createTimelineStage(stage, index) {
const stageDiv = document.createElement('div');
stageDiv.className = `timeline-stage timeline-stage--${index % 2 === 0 ? 'left' : 'right'} timeline-stage--${stage.status}`;
stageDiv.setAttribute('data-stage-id', stage.id);
stageDiv.innerHTML = `
<div class="timeline-stage__card">
<h3 class="timeline-stage__title">${stage.name}</h3>
<p class="timeline-stage__description">${stage.description}</p>
<span class="timeline-stage__status status--${stage.status}">${stage.status.replace('-', ' ')}</span>
</div>
<div class="timeline-stage__node">${stage.icon}</div>
`;
stageDiv.addEventListener('click', () => selectStage(stage.id));
return stageDiv;
}
// Initialize filters
function initializeFilters() {
const industryFilter = document.getElementById('industryFilter');
const modelFilter = document.getElementById('modelFilter');
const versionFilter = document.getElementById('versionFilter');
industryFilter.addEventListener('change', (e) => {
currentFilters.industry = e.target.value;
applyFilters();
});
modelFilter.addEventListener('change', (e) => {
currentFilters.model = e.target.value;
applyFilters();
});
versionFilter.addEventListener('change', (e) => {
currentFilters.version = e.target.value;
applyFilters();
});
}
// Apply filters (placeholder for future filtering logic)
function applyFilters() {
// This could filter content based on selected industry, model, etc.
console.log('Filters applied:', currentFilters);
}
// Select a stage and show its details
function selectStage(stageId) {
// Remove active class from all stages
document.querySelectorAll('.timeline-stage').forEach(stage => {
stage.classList.remove('timeline-stage--active');
});
// Add active class to selected stage
const selectedStage = document.querySelector(`[data-stage-id="${stageId}"]`);
if (selectedStage) {
selectedStage.classList.add('timeline-stage--active');
}
// Find stage data
const stage = appData.lifecycleStages.find(s => s.id === stageId);
if (stage) {
currentStage = stage;
showStageDetails(stage);
}
}
// Show detailed information for a stage
function showStageDetails(stage) {
const stageDetail = document.getElementById('stageDetail');
let content = `
<div class="stage-content">
<div class="stage-header">
<div class="stage-icon">${stage.icon}</div>
<div>
<h2 class="stage-title">${stage.name}</h2>
<p class="stage-description">${stage.description}</p>
</div>
</div>
<div class="stage-sections">
`;
// Generate content based on stage type
switch(stage.id) {
case 1: // Problem Formulation
content += `
<div class="stage-section">
<h4>Real-world Example</h4>
<p>${stage.example}</p>
</div>
<div class="stage-section">
<h4>Key Activities</h4>
<ul class="key-points">
${stage.keyPoints.map(point => `<li>${point}</li>`).join('')}
</ul>
</div>
`;
break;
case 2: // Data Collection
content += `
<div class="stage-section">
<h4>Data Sources</h4>
<ul class="key-points">
${stage.sources.map(source => `<li>${source}</li>`).join('')}
</ul>
</div>
<div class="stage-section">
<h4>Compliance Status</h4>
<div class="compliance-badges">
${Object.entries(stage.compliance).map(([key, value]) =>
`<span class="compliance-badge compliance-badge--${value ? 'active' : 'inactive'}">${key}</span>`
).join('')}
</div>
</div>
`;
break;
case 3: // Data Preprocessing
content += `
<div class="stage-section">
<h4>Data Quality Metrics</h4>
<div class="metrics-grid">
<div class="metric-item">
<span class="metric-label">Missing Values</span>
<span class="metric-value">${stage.metrics.missingValues}%</span>
</div>
<div class="metric-item">
<span class="metric-label">Normalization</span>
<span class="metric-value">${stage.metrics.normalization}</span>
</div>
<div class="metric-item">
<span class="metric-label">Categorical Encoding</span>
<span class="metric-value">${stage.metrics.categoricalEncoding}</span>
</div>
<div class="metric-item">
<span class="metric-label">Outliers Detected</span>
<span class="metric-value">${stage.metrics.outliers}</span>
</div>
</div>
</div>
`;
break;
case 4: // Modeling
content += `
<div class="stage-section">
<h4>Select Model Type</h4>
<div class="model-selector">
${stage.modelTypes.map(type =>
`<div class="model-option" data-model-type="${type}">${type}</div>`
).join('')}
</div>
<div id="modelOutput" class="mt-8"></div>
</div>
`;
break;
case 5: // Evaluation
content += `
<div class="stage-section">
<h4>Performance Metrics</h4>
<div class="metrics-grid">
<div class="metric-item">
<span class="metric-label">Accuracy</span>
<span class="metric-value">${(stage.metrics.accuracy * 100).toFixed(1)}%</span>
</div>
<div class="metric-item">
<span class="metric-label">Precision</span>
<span class="metric-value">${(stage.metrics.precision * 100).toFixed(1)}%</span>
</div>
<div class="metric-item">
<span class="metric-label">Recall</span>
<span class="metric-value">${(stage.metrics.recall * 100).toFixed(1)}%</span>
</div>
<div class="metric-item">
<span class="metric-label">F1-Score</span>
<span class="metric-value">${(stage.metrics.f1Score * 100).toFixed(1)}%</span>
</div>
</div>
<div class="chart-container">
<canvas id="evaluationChart"></canvas>
</div>
</div>
`;
break;
case 6: // Deployment
content += `
<div class="stage-section">
<h4>Infrastructure Status</h4>
<div class="metrics-grid">
<div class="metric-item">
<span class="metric-label">Docker</span>
<span class="metric-value">${stage.pipeline.docker ? 'βœ“ Ready' : 'βœ— Not Ready'}</span>
</div>
<div class="metric-item">
<span class="metric-label">Kubernetes</span>
<span class="metric-value">${stage.pipeline.kubernetes ? 'βœ“ Ready' : 'βœ— Not Ready'}</span>
</div>
<div class="metric-item">
<span class="metric-label">CI/CD</span>
<span class="metric-value">${stage.pipeline.cicd}</span>
</div>
<div class="metric-item">
<span class="metric-label">API Type</span>
<span class="metric-value">${stage.pipeline.api}</span>
</div>
</div>
</div>
`;
break;
case 7: // Monitoring & Maintenance
content += `
<div class="stage-section">
<h4>System Health</h4>
<div class="alert alert--${stage.alerts.dataDrift ? 'warning' : 'success'}">
<strong>Data Drift:</strong> ${stage.alerts.dataDrift ? 'Detected - Review required' : 'No drift detected'}
</div>
<div class="alert alert--warning">
<strong>Accuracy Decay:</strong> ${stage.alerts.accuracyDecay}% decline detected
</div>
<div class="alert alert--info">
<strong>Next Retraining:</strong> Scheduled for ${stage.alerts.retrainingDue}
</div>
</div>
`;
break;
}
content += `
</div>
</div>
`;
stageDetail.innerHTML = content;
// Add event listeners for interactive elements
if (stage.id === 4) {
setupModelSelector();
} else if (stage.id === 5) {
setTimeout(() => createEvaluationChart(stage.metrics), 100);
}
}
// Setup model selector for modeling stage
function setupModelSelector() {
document.querySelectorAll('.model-option').forEach(option => {
option.addEventListener('click', function() {
// Remove selected class from all options
document.querySelectorAll('.model-option').forEach(opt => {
opt.classList.remove('model-option--selected');
});
// Add selected class to clicked option
this.classList.add('model-option--selected');
// Show sample output
const modelType = this.getAttribute('data-model-type');
showModelOutput(modelType);
});
});
}
// Show model output based on selected type
function showModelOutput(modelType) {
const outputDiv = document.getElementById('modelOutput');
const relevantModels = appData.modelTypes.filter(model => model.type === modelType);
let output = `
<h5>Available ${modelType} Models:</h5>
<div class="model-selector">
`;
relevantModels.forEach(model => {
const metric = model.accuracy ? `Accuracy: ${(model.accuracy * 100).toFixed(1)}%` :
model.rmse ? `RMSE: ${model.rmse}` :
`Silhouette Score: ${model.silhouette}`;
output += `
<div class="model-option">
<strong>${model.name}</strong><br>
<small>${metric}</small>
</div>
`;
});
output += '</div>';
outputDiv.innerHTML = output;
}
// Create evaluation chart
function createEvaluationChart(metrics) {
const ctx = document.getElementById('evaluationChart');
if (!ctx) return;
// Destroy existing chart if it exists
if (evaluationChart) {
evaluationChart.destroy();
}
evaluationChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Accuracy', 'Precision', 'Recall', 'F1-Score'],
datasets: [{
label: 'Performance Metrics',
data: [metrics.accuracy, metrics.precision, metrics.recall, metrics.f1Score],
backgroundColor: ['#1FB8CD', '#FFC185', '#B4413C', '#5D878F'],
borderColor: ['#1FB8CD', '#FFC185', '#B4413C', '#5D878F'],
borderWidth: 2,
borderRadius: 8
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
callbacks: {
label: function(context) {
return `${context.label}: ${(context.parsed.y * 100).toFixed(1)}%`;
}
}
}
},
scales: {
y: {
beginAtZero: true,
max: 1,
ticks: {
callback: function(value) {
return (value * 100).toFixed(0) + '%';
}
}
}
}
}
});
}
// Update progress summary
function updateProgressSummary() {
const completed = appData.lifecycleStages.filter(stage => stage.status === 'completed').length;
const inProgress = appData.lifecycleStages.filter(stage => stage.status === 'in-progress').length;
const pending = appData.lifecycleStages.filter(stage => stage.status === 'pending').length;
document.getElementById('completedCount').textContent = completed;
document.getElementById('inProgressCount').textContent = inProgress;
document.getElementById('pendingCount').textContent = pending;
}