How do I make the data points follow the cursor in this interactive scatter plot graph?

I want to create an interactive scatter plot graph with the x-axis ranging from 24 to 48 and the y-axis ranging from 10,000 to 100,000. The points should be able to be moved by the user by dragging them, following the cursor.

Currently, when I try to drag a point, it snaps to the bottom of the graph and can only move on the x-axis. I have tried searching for solutions and using chatgpt but they did not work.

This is my code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Interactive D3 Chart</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <style>
        .axis path,
        .axis line {
            fill: none;
            shape-rendering: crispEdges;
        }
        .axis text {
            font-size: 12px;
        }
        .dot {
            fill: steelblue;
            stroke: #000;
            stroke-width: 1.5px;
        }
        .dragging {
            fill: orange;
        }
    </style>
</head>
<body>
    <script>
        // Set dimensions and margins of the graph
        const margin = { top: 20, right: 30, bottom: 40, left: 50 },
              width = 800 - margin.left - margin.right,
              height = 600 - margin.top - margin.bottom;

        // Append the svg object to the body of the page
        const svg = d3.select("body").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
          .append("g")
            .attr("transform", `translate(${margin.left},${margin.top})`);

        // X scale and axis
        const x = d3.scaleLinear()
            .domain([24, 48])
            .range([0, width]);

        svg.append("g")
            .attr("transform", `translate(0,${height})`)
            .call(d3.axisBottom(x));

        // Y scale and axis
        const y = d3.scaleLinear()
            .domain([10000, 100000])
            .range([height, 0]);

        svg.append("g")
            .call(d3.axisLeft(y));

        // Initial data points
        const data = [
            {x: 30, y: 20000},
            {x: 35, y: 50000},
            {x: 40, y: 75000},
        ];

        // Create and place the "dots"
        const dots = svg.selectAll(".dot")
            .data(data)
          .enter().append("circle")
            .attr("class", "dot")
            .attr("cx", d => x(d.x))
            .attr("cy", d => y(d.y))
            .attr("r", 5)
            .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended)
            );

        function dragstarted(event, d) {
            d3.select(this).raise().classed("dragging", true);
        }

        function dragged(event, d) {
            const newX = x.invert(event.x);
            const newY = y.invert(event.y);
            d.x = Math.max(24, Math.min(48, newX));
            d.y = Math.max(10000, Math.min(100000, newY));
            d3.select(this)
                .attr("cx", x(d.x))
                .attr("cy", y(d.y));
        }

        function dragended(event, d) {
            d3.select(this).classed("dragging", false);
        }
    </script>
</body>
</html>