178 lines
5.4 KiB
JavaScript
178 lines
5.4 KiB
JavaScript
|
// Define handleAjaxComplete in the global scope first
|
||
|
window.handleAjaxComplete = function() {
|
||
|
if (typeof canvasManager !== 'undefined') {
|
||
|
canvasManager.initCanvas();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Canvas manager object
|
||
|
const canvasManager = {
|
||
|
canvas: null,
|
||
|
ctx: null,
|
||
|
CANVAS_WIDTH: 400,
|
||
|
CANVAS_HEIGHT: 400,
|
||
|
|
||
|
getElement: function(id) {
|
||
|
return document.getElementById('mainForm:' + id);
|
||
|
},
|
||
|
|
||
|
initCanvas: function() {
|
||
|
this.canvas = document.getElementById('graph');
|
||
|
if (this.canvas) {
|
||
|
this.ctx = this.canvas.getContext('2d');
|
||
|
this.canvas.addEventListener('click', this.handleCanvasClick.bind(this));
|
||
|
this.updateGraph();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
handleCanvasClick: function(event) {
|
||
|
if (!this.canvas || !this.ctx) return;
|
||
|
|
||
|
const rInput = this.getElement('rInput');
|
||
|
if (!rInput) return;
|
||
|
|
||
|
const r = parseFloat(rInput.value);
|
||
|
if (!r || r < 1 || r > 4) {
|
||
|
alert('Please set a valid R value (1-4) first');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const rect = this.canvas.getBoundingClientRect();
|
||
|
const x = event.clientX - rect.left;
|
||
|
const y = event.clientY - rect.top;
|
||
|
|
||
|
const center = this.CANVAS_WIDTH / 2;
|
||
|
const scale = this.CANVAS_WIDTH / 3 / r;
|
||
|
|
||
|
const graphX = ((x - center) / scale).toFixed(2);
|
||
|
const graphY = ((center - y) / scale).toFixed(2);
|
||
|
|
||
|
this.getElement('xHidden').value = graphX;
|
||
|
this.getElement('yHidden').value = graphY;
|
||
|
|
||
|
plotPoint();
|
||
|
},
|
||
|
|
||
|
updateGraph: function() {
|
||
|
if (!this.canvas || !this.ctx) return;
|
||
|
|
||
|
const rInput = this.getElement('rInput');
|
||
|
if (!rInput) return;
|
||
|
|
||
|
const r = parseFloat(rInput.value);
|
||
|
if (!r || r < 1 || r > 4) return;
|
||
|
|
||
|
this.ctx.clearRect(0, 0, this.CANVAS_WIDTH, this.CANVAS_HEIGHT);
|
||
|
this.drawGrid(r);
|
||
|
this.drawAreas(r);
|
||
|
this.drawPoints();
|
||
|
},
|
||
|
|
||
|
drawGrid: function(r) {
|
||
|
const center = this.CANVAS_WIDTH / 2;
|
||
|
const scale = this.CANVAS_WIDTH / 3 / r;
|
||
|
|
||
|
this.ctx.beginPath();
|
||
|
this.ctx.moveTo(0, center);
|
||
|
this.ctx.lineTo(this.CANVAS_WIDTH, center);
|
||
|
this.ctx.moveTo(center, 0);
|
||
|
this.ctx.lineTo(center, this.CANVAS_HEIGHT);
|
||
|
this.ctx.strokeStyle = 'black';
|
||
|
this.ctx.stroke();
|
||
|
|
||
|
this.ctx.font = '12px Arial';
|
||
|
this.ctx.textAlign = 'center';
|
||
|
this.ctx.textBaseline = 'middle';
|
||
|
|
||
|
[-r, -r/2, r/2, r].forEach(value => {
|
||
|
const x = center + value * scale;
|
||
|
const y = center - value * scale;
|
||
|
|
||
|
this.ctx.beginPath();
|
||
|
this.ctx.moveTo(x, center - 5);
|
||
|
this.ctx.lineTo(x, center + 5);
|
||
|
this.ctx.moveTo(center - 5, y);
|
||
|
this.ctx.lineTo(center + 5, y);
|
||
|
this.ctx.stroke();
|
||
|
|
||
|
this.ctx.fillText(value.toString(), x, center + 20);
|
||
|
this.ctx.fillText(value.toString(), center - 20, y);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
drawAreas: function(r) {
|
||
|
const center = this.CANVAS_WIDTH / 2;
|
||
|
const scale = this.CANVAS_WIDTH / 3 / r;
|
||
|
|
||
|
this.ctx.fillStyle = 'rgba(100, 149, 237, 0.5)';
|
||
|
|
||
|
// Triangle in -x, -y quadrant
|
||
|
this.ctx.beginPath();
|
||
|
this.ctx.moveTo(center, center);
|
||
|
this.ctx.lineTo(center - r/2 * scale, center);
|
||
|
this.ctx.lineTo(center, center + r * scale);
|
||
|
this.ctx.closePath();
|
||
|
this.ctx.fill();
|
||
|
|
||
|
// Square in -x, +y quadrant
|
||
|
this.ctx.fillRect(center - r/2 * scale, center - r * scale, r/2 * scale, r * scale);
|
||
|
|
||
|
// Quarter circle in +x, -y quadrant
|
||
|
this.ctx.beginPath();
|
||
|
this.ctx.moveTo(center, center);
|
||
|
this.ctx.arc(center, center, r * scale, 0, Math.PI/2, false);
|
||
|
this.ctx.closePath();
|
||
|
this.ctx.fill();
|
||
|
},
|
||
|
|
||
|
drawPoints: function() {
|
||
|
const rInput = this.getElement('rInput');
|
||
|
if (!rInput) return;
|
||
|
|
||
|
const r = parseFloat(rInput.value);
|
||
|
if (!r) return;
|
||
|
|
||
|
const center = this.CANVAS_WIDTH / 2;
|
||
|
const scale = this.CANVAS_WIDTH / 3 / r;
|
||
|
|
||
|
// Updated selector to match PrimeFaces table
|
||
|
const table = document.querySelector('[id$="resultsTable"]');
|
||
|
if (!table) return;
|
||
|
|
||
|
const rows = table.querySelectorAll('tbody tr');
|
||
|
|
||
|
rows.forEach(row => {
|
||
|
const cells = row.cells;
|
||
|
// Skip if we don't have enough cells
|
||
|
if (!cells || cells.length < 4) return;
|
||
|
|
||
|
try {
|
||
|
const x = parseFloat(cells[0].textContent.trim());
|
||
|
const y = parseFloat(cells[1].textContent.trim());
|
||
|
const hit = cells[3].textContent.trim() === 'Yes';
|
||
|
|
||
|
// Skip if we couldn't parse the coordinates
|
||
|
if (isNaN(x) || isNaN(y)) return;
|
||
|
|
||
|
// Convert graph coordinates to canvas coordinates
|
||
|
const canvasX = center + x * scale;
|
||
|
const canvasY = center - y * scale;
|
||
|
|
||
|
// Draw the point
|
||
|
this.ctx.beginPath();
|
||
|
this.ctx.arc(canvasX, canvasY, 4, 0, 2 * Math.PI);
|
||
|
this.ctx.fillStyle = hit ? 'green' : 'red';
|
||
|
this.ctx.fill();
|
||
|
this.ctx.strokeStyle = 'black';
|
||
|
this.ctx.stroke();
|
||
|
} catch (e) {
|
||
|
console.error('Error drawing point:', e);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Initialize when DOM is loaded
|
||
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
canvasManager.initCanvas();
|
||
|
});
|