function renderHCGChart() {
const canvas = document.getElementById('hcgChart');
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,19,20,21];
const hcgLow = [0,0,5,10,25,50,100,200,400,800,1500,3000,5000,8000,12000];
const hcgHigh = [5,10,50,100,200,400,800,1500,3000,5000,8000,15000,25000,40000,60000];
const padding = 40;
const chartW = w - padding * 2;
const chartH = h - padding * 2;
const maxHCG = 60000;
ctx.fillStyle = 'rgba(232,90,138,0.15)';
ctx.beginPath();
ctx.moveTo(padding, padding + chartH);
hcgHigh.forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * i;
const y = padding + chartH - (v / maxHCG) * chartH;
ctx.lineTo(x, y);
});
hcgLow.slice().reverse().forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * (dpo.length - 1 - i);
const y = padding + chartH - (v / maxHCG) * chartH;
ctx.lineTo(x, y);
});
ctx.closePath(); ctx.fill();
ctx.strokeStyle = '#e85a8a'; ctx.lineWidth = 2; ctx.beginPath();
hcgHigh.forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * i;
const y = padding + chartH - (v / maxHCG) * chartH;
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
});
ctx.stroke();
ctx.strokeStyle = '#7dd3c0'; ctx.lineWidth = 2; ctx.beginPath();
hcgLow.forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * i;
const y = padding + chartH - (v / maxHCG) * chartH;
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
});
ctx.stroke();
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);
});
}
renderHCGChart();
function renderHCGChart() {
const canvas = document.getElementById('hcgChart');
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,19,20,21];
const hcgLow = [0,0,5,10,25,50,100,200,400,800,1500,3000,5000,8000,12000];
const hcgHigh = [5,10,50,100,200,400,800,1500,3000,5000,8000,15000,25000,40000,60000];
const padding = 40;
const chartW = w - padding * 2;
const chartH = h - padding * 2;
const maxHCG = 60000;
ctx.fillStyle = 'rgba(232,90,138,0.15)';
ctx.beginPath();
ctx.moveTo(padding, padding + chartH);
hcgHigh.forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * i;
const y = padding + chartH - (v / maxHCG) * chartH;
ctx.lineTo(x, y);
});
hcgLow.slice().reverse().forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * (dpo.length - 1 - i);
const y = padding + chartH - (v / maxHCG) * chartH;
ctx.lineTo(x, y);
});
ctx.closePath(); ctx.fill();
ctx.strokeStyle = '#e85a8a'; ctx.lineWidth = 2; ctx.beginPath();
hcgHigh.forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * i;
const y = padding + chartH - (v / maxHCG) * chartH;
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
});
ctx.stroke();
ctx.strokeStyle = '#7dd3c0'; ctx.lineWidth = 2; ctx.beginPath();
hcgLow.forEach((v, i) => {
const x = padding + (chartW / (dpo.length - 1)) * i;
const y = padding + chartH - (v / maxHCG) * chartH;
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
});
ctx.stroke();
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);
});
}
renderHCGChart();
All calculations are performed locally. Your data never leaves your browser.