const canvas = document.getElementById('drift-canvas'); const ctx = canvas.getContext('2d'); let accuracy = Array.from({ length: 44 }, (_, index) => 92 - Math.sin(index / 3) * 2); let status = 'Model is healthy.'; function draw() { const width = canvas.width; const height = canvas.height; const pad = 28; ctx.clearRect(0, 0, width, height); ctx.fillStyle = '#f8fafc'; ctx.fillRect(0, 0, width, height); ctx.strokeStyle = '#d9e2ec'; for (let i = 0; i < 5; i += 1) { const y = pad + ((height - pad * 2) / 4) * i; ctx.beginPath(); ctx.moveTo(pad, y); ctx.lineTo(width - pad, y); ctx.stroke(); } ctx.strokeStyle = '#805ad5'; ctx.lineWidth = 3; ctx.beginPath(); accuracy.forEach((value, index) => { const x = pad + (index / Math.max(1, accuracy.length - 1)) * (width - pad * 2); const y = height - pad - ((value - 40) / 60) * (height - pad * 2); if (index === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); }); ctx.stroke(); document.getElementById('drift-status').textContent = status; } document.getElementById('drift-spike').addEventListener('click', () => { accuracy = accuracy.map((value, index) => index > 20 ? Math.max(55, value - (index - 18) * 0.9) : value); status = 'Black Friday traffic spike: feature distribution shifted, accuracy is sliding.'; draw(); }); document.getElementById('drift-corrupt').addEventListener('click', () => { accuracy = accuracy.map((value, index) => index % 4 === 0 ? Math.max(45, value - 18) : value); status = 'Corrupted input data: model confidence is having a very bad afternoon.'; draw(); }); document.getElementById('drift-retrain').addEventListener('click', () => { accuracy = accuracy.map((_, index) => 91 + Math.sin(index / 4) * 3); status = 'Retrained model: accuracy recovered and everyone pretends this was planned.'; draw(); }); draw();