Improve on the following code:

```<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Linear Programming Graphical Solver</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        #controls {
            margin-bottom: 20px;
        }
        #constraints {
            margin-bottom: 10px;
        }
        .constraint {
            margin-bottom: 5px;
        }
        #graph {
            border: 1px solid #ccc;
            position: relative;
            width: 600px;
            height: 600px;
        }
        #tooltip {
            position: absolute;
            background-color: rgba(0,0,0,0.7);
            color: #fff;
            padding: 5px;
            border-radius: 3px;
            pointer-events: none;
            display: none;
            font-size: 12px;
        }
        button {
            margin-left: 5px;
        }
        label {
            margin-right: 5px;
        }
        input[type="number"] {
            width: 60px;
        }
    </style>
</head>
<body>
    <h1>Linear Programming Graphical Solver</h1>
    <div id="controls">
        <h2>Constraints</h2>
        <div id="constraints">
            <!-- Constraint inputs will be added here -->
        </div>
        <button id="addConstraint">Add Constraint</button>
        <h2>Objective Function</h2>
        <div>
            <label for="objective">Maximize / Minimize:</label>
            <select id="objective">
                <option value="maximize">Maximize</option>
                <option value="minimize">Minimize</option>
            </select>
        </div>
        <div>
            <label for="objA">Objective Function:</label>
            <input type="number" id="objA" value="1"> x +
            <input type="number" id="objB" value="1"> y
        </div>
    </div>
    <h2>Graph</h2>
    <div id="graph">
        <canvas id="canvas" width="600" height="600"></canvas>
        <div id="tooltip"></div>
    </div>
    <h2>Solution</h2>
    <div id="solution">
        <!-- Optimal solution will be displayed here -->
    </div>

    <script>
        // Linear Programming Graphical Solver

        // Initial setup
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        const constraintsDiv = document.getElementById('constraints');
        const addConstraintBtn = document.getElementById('addConstraint');
        const objectiveSelect = document.getElementById('objective');
        const objAInput = document.getElementById('objA');
        const objBInput = document.getElementById('objB');
        const solutionDiv = document.getElementById('solution');
        const tooltip = document.getElementById('tooltip');

        // Define constraints array
        let constraints = [];

        // Add initial constraint
        addConstraint();

        // Event listeners
        addConstraintBtn.addEventListener('click', addConstraint);
        objectiveSelect.addEventListener('change', drawGraph);
        objAInput.addEventListener('input', drawGraph);
        objBInput.addEventListener('input', drawGraph);

        // Function to add a new constraint input
        function addConstraint() {
            const id = Date.now();
            const constraintDiv = document.createElement('div');
            constraintDiv.className = 'constraint';
            constraintDiv.dataset.id = id;
            constraintDiv.innerHTML = `
                <label>A:</label>
                <input type="number" step="any" class="a" value="1">
                <label>x +</label>
                <label>B:</label>
                <input type="number" step="any" class="b" value="1">
                <label>y ≤</label>
                <input type="number" step="any" class="c" value="10">
                <button class="remove">Remove</button>
            `;
            constraintsDiv.appendChild(constraintDiv);

            // Add to constraints array
            constraints.push({ a: 1, b: 1, c: 10, id: id });

            // Add event listeners
            const aInput = constraintDiv.querySelector('.a');
            const bInput = constraintDiv.querySelector('.b');
            const cInput = constraintDiv.querySelector('.c');
            const removeBtn = constraintDiv.querySelector('.remove');

            aInput.addEventListener('input', () => updateConstraint(id, 'a', parseFloat(aInput.value)));
            bInput.addEventListener('input', () => updateConstraint(id, 'b', parseFloat(bInput.value)));
            cInput.addEventListener('input', () => updateConstraint(id, 'c', parseFloat(cInput.value)));
            removeBtn.addEventListener('click', () => removeConstraint(id));

            drawGraph();
        }

        // Function to update a constraint
        function updateConstraint(id, field, value) {
            const constraint = constraints.find(con => con.id === id);
            if (constraint) {
                constraint[field] = value;
                drawGraph();
            }
        }

        // Function to remove a constraint
        function removeConstraint(id) {
            constraints = constraints.filter(con => con.id !== id);
            const constraintDiv = constraintsDiv.querySelector(`[data-id="${id}"]`);
            if (constraintDiv) {
                constraintsDiv.removeChild(constraintDiv);
            }
            drawGraph();
        }

        // Function to draw the graph
        function drawGraph() {
            // Clear canvas
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // Draw axes
            drawAxes();

            // Draw constraints
            constraints.forEach(con => drawConstraint(con));

            // Calculate and draw feasible region
            const feasiblePoints = calculateFeasibleRegion();
            if (feasiblePoints.length > 0) {
                drawFeasibleRegion(feasiblePoints);
                // Find and draw optimal solution
                const optimal = findOptimalSolution(feasiblePoints);
                if (optimal) {
                    drawOptimalPoint(optimal);
                    displaySolution(optimal);
                } else {
                    solutionDiv.innerHTML = 'No optimal solution found.';
                }
            } else {
                solutionDiv.innerHTML = 'No feasible region.';
            }

            // Draw objective function
            drawObjectiveFunction();
        }

        // Function to draw axes
        function drawAxes() {
            ctx.beginPath();
            ctx.strokeStyle = '#000';
            ctx.lineWidth = 2;
            // X axis
            ctx.moveTo(50, canvas.height - 50);
            ctx.lineTo(canvas.width - 50, canvas.height - 50);
            // Y axis
            ctx.moveTo(50, canvas.height - 50);
            ctx.lineTo(50, 50);
            ctx.stroke();

            // Labels
            ctx.fillStyle = '#000';
            ctx.font = '12px Arial';
            ctx.fillText('0', 45, canvas.height - 45);
            ctx.fillText('X', canvas.width - 55, canvas.height - 55);
            ctx.fillText('Y', 55, 55);
        }

        // Function to draw a single constraint
        function drawConstraint(con) {
            // y = (c - a x) / b
            if (con.b === 0) return; // Avoid division by zero
            const x1 = 0;
            const y1 = (con.c - con.a * x1) / con.b;
            const x2 = con.c / con.a;
            const y2 = 0;

            // Convert to canvas coordinates
            const p1 = toCanvasCoords(x1, y1);
            const p2 = toCanvasCoords(x2, y2);

            ctx.beginPath();
            ctx.strokeStyle = 'blue';
            ctx.lineWidth = 1;
            ctx.moveTo(p1.x, p1.y);
            ctx.lineTo(p2.x, p2.y);
            ctx.stroke();

            // Shade the appropriate side based on inequality
            // For simplicity, we will not implement shading individual constraints
        }

        // Function to convert mathematical coordinates to canvas coordinates
        function toCanvasCoords(x, y) {
            const scale = 50; // pixels per unit
            const canvasX = 50 + x * scale;
            const canvasY = canvas.height - 50 - y * scale;
            return { x: canvasX, y: canvasY };
        }

        // Function to calculate the feasible region
        function calculateFeasibleRegion() {
            // Find intersection points of all constraints
            let points = [];

            // Generate all pairs of constraints
            for (let i = 0; i < constraints.length; i++) {
                for (let j = i + 1; j < constraints.length; j++) {
                    const inter = intersect(constraints[i], constraints[j]);
                    if (inter) {
                        points.push(inter);
                    }
                }
            }

            // Also include intercepts of each constraint
            constraints.forEach(con => {
                points.push({ x: 0, y: con.c / con.b });
                points.push({ x: con.c / con.a, y: 0 });
            });

            // Remove duplicate points
            points = uniquePoints(points);

            // Filter points that satisfy all constraints and x,y >=0
            const feasiblePoints = points.filter(p => {
                if (p.x < 0 || p.y < 0) return false;
                return constraints.every(con => (con.a * p.x + con.b * p.y <= con.c + 1e-6));
            });

            // Find convex hull of feasible points
            return convexHull(feasiblePoints);
        }

        // Function to find intersection of two constraints
        function intersect(con1, con2) {
            const a1 = con1.a, b1 = con1.b, c1 = con1.c;
            const a2 = con2.a, b2 = con2.b, c2 = con2.c;
            const det = a1 * b2 - a2 * b1;
            if (det === 0) return null; // Parallel lines
            const x = (c1 * b2 - c2 * b1) / det;
            const y = (a1 * c2 - a2 * c1) / det;
            return { x: x, y: y };
        }

        // Function to remove duplicate points
        function uniquePoints(points) {
            const unique = [];
            points.forEach(p => {
                if (!unique.some(q => Math.abs(q.x - p.x) < 1e-6 && Math.abs(q.y - p.y) < 1e-6)) {
                    unique.push(p);
                }
            });
            return unique;
        }

        // Function to compute convex hull using Graham's scan
        function convexHull(points) {
            if (points.length < 3) return points;

            // Sort the points
            points.sort((a, b) => a.x === b.x ? a.y - b.y : a.x - b.x);

            // Create upper and lower hulls
            const upper = [];
            for (let p of points) {
                while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {
                    upper.pop();
                }
                upper.push(p);
            }

            const lower = [];
            for (let i = points.length - 1; i >= 0; i--) {
                const p = points[i];
                while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {
                    lower.pop();
                }
                lower.push(p);
            }

            // Concatenate upper and lower to get full hull
            upper.pop();
            lower.pop();
            return upper.concat(lower);
        }

        // Helper function for convex hull
        function cross(o, a, b) {
            return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
        }

        // Function to draw feasible region
        function drawFeasibleRegion(points) {
            ctx.beginPath();
            ctx.fillStyle = 'rgba(0, 255, 0, 0.3)';
            points.forEach((p, index) => {
                const coord = toCanvasCoords(p.x, p.y);
                if (index === 0) ctx.moveTo(coord.x, coord.y);
                else ctx.lineTo(coord.x, coord.y);
            });
            ctx.closePath();
            ctx.fill();
        }

        // Function to find the optimal solution
        function findOptimalSolution(points) {
            if (points.length === 0) return null;
            const objective = objectiveSelect.value;
            const a = parseFloat(objAInput.value);
            const b = parseFloat(objBInput.value);

            let optimalPoint = points[0];
            let optimalValue = a * points[0].x + b * points[0].y;

            points.forEach(p => {
                const value = a * p.x + b * p.y;
                if (objective === 'maximize') {
                    if (value > optimalValue) {
                        optimalValue = value;
                        optimalPoint = p;
                    }
                } else {
                    if (value < optimalValue) {
                        optimalValue = value;
                        optimalPoint = p;
                    }
                }
            });

            return optimalPoint;
        }

        // Function to draw the optimal point
        function drawOptimalPoint(p) {
            const coord = toCanvasCoords(p.x, p.y);
            ctx.beginPath();
            ctx.fillStyle = 'red';
            ctx.arc(coord.x, coord.y, 5, 0, 2 * Math.PI);
            ctx.fill();
            ctx.font = '12px Arial';
            ctx.fillText('Optimal', coord.x + 7, coord.y - 7);
        }

        // Function to display the solution
        function displaySolution(p) {
            const a = parseFloat(objAInput.value);
            const b = parseFloat(objBInput.value);
            const value = a * p.x + b * p.y;
            solutionDiv.innerHTML = `
                Optimal Solution: x = ${p.x.toFixed(2)}, y = ${p.y.toFixed(2)} <br>
                ${objectiveSelect.value.charAt(0).toUpperCase() + objectiveSelect.value.slice(1)} Value = ${value.toFixed(2)}
            `;
        }

        // Function to draw the objective function
        function drawObjectiveFunction() {
            const a = parseFloat(objAInput.value);
            const b = parseFloat(objBInput.value);

            if (a === 0 && b === 0) return; // Invalid objective function

            // To plot the line ax + by = k, choose k as needed
            // We'll plot it near the optimal point direction
            const k = 0; // Base value

            // Find two points on the objective function line
            let x1 = 0;
            let y1 = k / b;
            let x2 = k / a;
            let y2 = 0;

            // Adjust k to visualize the line within the graph
            // For simplicity, we plot a arbitrary line
            x1 = -10;
            y1 = (k - a * x1) / b;
            x2 = 10;
            y2 = (k - a * x2) / b;

            const p1 = toCanvasCoords(x1, y1);
            const p2 = toCanvasCoords(x2, y2);

            ctx.beginPath();
            ctx.strokeStyle = 'purple';
            ctx.lineWidth = 2;
            ctx.moveTo(p1.x, p1.y);
            ctx.lineTo(p2.x, p2.y);
            ctx.stroke();

            // Add event listeners for tooltip
            canvas.addEventListener('mousemove', onMouseMove);
            canvas.addEventListener('mouseleave', () => {
                tooltip.style.display = 'none';
            });
        }

        // Function to handle mouse move for tooltip
        function onMouseMove(event) {
            const rect = canvas.getBoundingClientRect();
            const mouseX = event.clientX - rect.left;
            const mouseY = event.clientY - rect.top;

            // Check if mouse is near any constraint line
            // For simplicity, this is not implemented here
            // You can implement proximity checks and show relevant tooltips

            // Example tooltip
            tooltip.style.left = event.clientX + 10 + 'px';
            tooltip.style.top = event.clientY + 10 + 'px';
            tooltip.innerHTML = 'Tooltips can be implemented here.';
            tooltip.style.display = 'block';
        }

        // Initial draw
        drawGraph();
    </script>
</body>
</html>```