|
|
const canvas = document.getElementById("polyCanvas");
|
|
|
const ctx = canvas.getContext("2d");
|
|
|
|
|
|
const X_data = [1, 2, 3, 4, 5];
|
|
|
const y_data = [3, 8, 15, 24, 35];
|
|
|
|
|
|
function toCanvasX(x, xScale, padding) {
|
|
|
return padding + x * xScale;
|
|
|
}
|
|
|
|
|
|
function toCanvasY(y, yScale, padding, canvasHeight) {
|
|
|
return canvasHeight - padding - y * yScale;
|
|
|
}
|
|
|
|
|
|
function setupAndDraw(predX = null, predY = null) {
|
|
|
const padding = 50;
|
|
|
const canvasWidth = canvas.width = canvas.clientWidth;
|
|
|
const canvasHeight = canvas.height = canvas.clientHeight;
|
|
|
|
|
|
const xMax = 6;
|
|
|
const yMax = 40;
|
|
|
|
|
|
const xScale = (canvasWidth - 2 * padding) / xMax;
|
|
|
const yScale = (canvasHeight - 2 * padding) / yMax;
|
|
|
|
|
|
|
|
|
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
|
ctx.moveTo(padding, toCanvasY(0, yScale, padding, canvasHeight));
|
|
|
ctx.lineTo(canvasWidth - padding, toCanvasY(0, yScale, padding, canvasHeight));
|
|
|
ctx.moveTo(toCanvasX(0, xScale, padding), padding);
|
|
|
ctx.lineTo(toCanvasX(0, xScale, padding), canvasHeight - padding);
|
|
|
ctx.strokeStyle = "#475569";
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
|
ctx.fillStyle = "#3b82f6";
|
|
|
X_data.forEach((x, i) => {
|
|
|
ctx.beginPath();
|
|
|
ctx.arc(toCanvasX(x, xScale, padding), toCanvasY(y_data[i], yScale, padding, canvasHeight), 5, 0, 2 * Math.PI);
|
|
|
ctx.fill();
|
|
|
});
|
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
|
ctx.moveTo(toCanvasX(0, xScale, padding), toCanvasY(0, yScale, padding, canvasHeight));
|
|
|
for (let x = 0; x <= xMax; x += 0.1) {
|
|
|
const y = x * x + 2 * x;
|
|
|
ctx.lineTo(toCanvasX(x, xScale, padding), toCanvasY(y, yScale, padding, canvasHeight));
|
|
|
}
|
|
|
ctx.strokeStyle = "#ef4444";
|
|
|
ctx.lineWidth = 2;
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
|
if (predX !== null && predY !== null) {
|
|
|
ctx.fillStyle = "#22c55e";
|
|
|
ctx.beginPath();
|
|
|
ctx.arc(toCanvasX(predX, xScale, padding), toCanvasY(predY, yScale, padding, canvasHeight), 6, 0, 2 * Math.PI);
|
|
|
ctx.fill();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
function predict() {
|
|
|
const hours = parseFloat(document.getElementById("hoursInput").value);
|
|
|
fetch("/predict_poly", {
|
|
|
method: "POST",
|
|
|
body: JSON.stringify({ hours }),
|
|
|
headers: {
|
|
|
"Content-Type": "application/json"
|
|
|
}
|
|
|
})
|
|
|
.then(res => res.json())
|
|
|
.then(data => {
|
|
|
const score = data.prediction;
|
|
|
document.getElementById("predictedScore").textContent = score;
|
|
|
document.getElementById("predictionOutput").classList.remove("hidden");
|
|
|
setupAndDraw(hours, score);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
window.onload = () => setupAndDraw();
|
|
|
|