function renderDetectionChart() { const canvas = document.getElementById('detectionChart'); const ctx = canvas.getContext('2d'); const w = canvas.width, h = canvas.height; ctx.clearRect(0, 0, w, h); const dpo = [7,8,9,10,11,12,13,14,15,16,17,18]; const prob = [5,10,25,45,65,80,90,95,98,99,99.5,99.9]; const padding = 40; const chartW = w - padding * 2; const chartH = h - padding * 2; ctx.strokeStyle = '#e8e4df'; ctx.lineWidth = 1; for (let i = 0; i <= 5; i++) { const y = padding + (chartH / 5) * i; ctx.beginPath(); ctx.moveTo(padding, y); ctx.lineTo(w - padding, y); ctx.stroke(); } ctx.strokeStyle = '#7dd3c0'; ctx.lineWidth = 3; ctx.beginPath(); dpo.forEach((d, i) => { const x = padding + (chartW / (dpo.length - 1)) * i; const y = padding + chartH - (prob[i] / 100) * chartH; if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); }); ctx.stroke(); ctx.fillStyle = '#7dd3c0'; dpo.forEach((d, i) => { const x = padding + (chartW / (dpo.length - 1)) * i; const y = padding + chartH - (prob[i] / 100) * chartH; ctx.beginPath(); ctx.arc(x, y, 5, 0, Math.PI * 2); ctx.fill(); }); ctx.fillStyle = '#8a8a8a'; ctx.font = '12px Segoe UI'; ctx.textAlign = 'center'; dpo.forEach((d, i) => { const x = padding + (chartW / (dpo.length - 1)) * i; ctx.fillText(d + 'd', x, h - 15); }); } renderDetectionChart(); function renderDetectionChart() { const canvas = document.getElementById('detectionChart'); const ctx = canvas.getContext('2d'); const w = canvas.width, h = canvas.height; ctx.clearRect(0, 0, w, h); const dpo = [7,8,9,10,11,12,13,14,15,16,17,18]; const prob = [5,10,25,45,65,80,90,95,98,99,99.5,99.9]; const padding = 40; const chartW = w - padding * 2; const chartH = h - padding * 2; ctx.strokeStyle = '#e8e4df'; ctx.lineWidth = 1; for (let i = 0; i <= 5; i++) { const y = padding + (chartH / 5) * i; ctx.beginPath(); ctx.moveTo(padding, y); ctx.lineTo(w - padding, y); ctx.stroke(); } ctx.strokeStyle = '#7dd3c0'; ctx.lineWidth = 3; ctx.beginPath(); dpo.forEach((d, i) => { const x = padding + (chartW / (dpo.length - 1)) * i; const y = padding + chartH - (prob[i] / 100) * chartH; if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); }); ctx.stroke(); ctx.fillStyle = '#7dd3c0'; dpo.forEach((d, i) => { const x = padding + (chartW / (dpo.length - 1)) * i; const y = padding + chartH - (prob[i] / 100) * chartH; ctx.beginPath(); ctx.arc(x, y, 5, 0, Math.PI * 2); ctx.fill(); }); ctx.fillStyle = '#8a8a8a'; ctx.font = '12px Segoe UI'; ctx.textAlign = 'center'; dpo.forEach((d, i) => { const x = padding + (chartW / (dpo.length - 1)) * i; ctx.fillText(d + 'd', x, h - 15); }); } renderDetectionChart();
Quick Calculator: Open Ovulation Calculator

Pregnancy Test Timeline

Enter your ovulation date to see the earliest day you can test, the best day to test, and when a negative result is truly reliable.

Advertisement

Saved Timelines

No saved timelines yet.

Test Detection Probability

Advertisement

All calculations are performed locally. Your data never leaves your browser.

Advertisement