How do I create a bubble chat based on sale price in D3?

I’m trying to create an interactive bubble chart in D3. The size of the cirlces and the shade of color (green) is supposed to be based on how much a hotel sold for. When the user hovers over the cirlce with their mouse a tooltip should display additional information from the other columns.

A list of columns and data are below. I keep getting the following error:
Error: <circle> attribute cx: Expected length, "NaN"

I’m reading the data in from a csv file with the following columns:

PropertyName,
PropertyAddress,
City,
SalePrice,
Square_Footage,
Units,
Price_SF,
Price_Unit,
SaleDate,
Buyer,
Seller,
Link

And my code is below:

(function () {

    // Margin convention
    const margin = { top: 30, right: 50, bottom: 50, left: 50 }
    const width = 600 - margin.left - margin.right
    const height = 425 - margin.top - margin.bottom
  
    const svg = d3.select("#chart").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 + ")")
  
    // Define colour scale
    const colorScale = d3.scaleOrdinal()
      .domain(['SalePrice'])
      .range(["#228C22"])
  
    // Set radius scale
    const radiusScale = d3.scaleSqrt()
      .domain([0, 300001])
      .range([0, 40])
  
    // Define years
    const years = [2021]
  
    // Define x axis position
    const xPositionScale = d3.scalePoint()
      .domain(years)
      .range([140, width - 110])
  
    // Create currency formatted
    var formatter = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
      minimumFractionDigits: 0
    });
  
    // Create tooltip
    const tooltip = d3
      .select("body")
      .append("div")
      .attr("class", "svg-tooltip")
      .style("position", "absolute")
      .style("visibility", "hidden");
    
    // Force simulation and prevent overlap
    const forceX = d3.forceX(d => xPositionScale(d.year)).strength(1)
    const forceY = d3.forceY(200).strength(1)
    const forceCollide = d3.forceCollide((d => radiusScale(d.amount) + 4))
    const simulation = d3.forceSimulation()
      .force("overlap", forceCollide)
      .force("y", forceY)
      .force("x", forceX)
      .force('charge', d3.forceManyBody().strength(-50))
  
    // Read in csv
    d3.csv("2021_hotel_sales_for_graphic.csv")
      .then(ready)
    function ready (datapoints) {
      datapoints.forEach(d => {
        d.x = 0;
        d.y = 0;
      })
  
      // Show text labels
      svg.selectAll('text')
        .data(years)
        .join('text')
        .attr('text-anchor', 'end')
        .attr('x', d => xPositionScale(d))
        .attr('dx', 20)
        .attr('dy', 0)
        .text(d => d)
  
      // Set position of circles
      svg.selectAll('circle')
        .data(datapoints)
        .join('circle')
        .attr("id", "circleBasicTooltip")
        .attr('r', d => radiusScale(d.SalePrice))
        .attr('cx', 200)
        .attr('fill', d => colorScale(d.colorScale))
        .attr('cy', 200)
        .attr('stroke', 3)
  
      // Trigger tooltip
      d3.selectAll("circle")
        .on("mouseover", function(e, d) {
          d3.select(this)
            .attr('stroke-width', '2')
            .attr("stroke", "black");
          tooltip
            .style("visibility", "visible")
            .attr('class','tooltipdiv')
            .html(`<h4>${d.PropertyName}</h4>` + 
                  `<p><strong>Address</strong>: ${d.PropertyAddress}<br />` +
                  `<p><strong>City</strong>: ${d.City}<br />` +
                  `<p><strong>Sale Price</strong>: ${d.SalePrice}<br />` +
                  `<p><strong>Square Footage</strong>: ${d.Square_Footage}<br />` +
                  `<p><strong>Units</strong>: ${d.Units}<br />` +
                  `<p><strong>Price per Sq Ft</strong>: ${d.Price_SF}<br />` +
                  `<p><strong>Price per Unit</strong>: ${d.Price_Unit}<br />` +
                  `<p><strong>Sale Date</strong>: ${d.SaleDate}<br />` +
                  `<p><strong>Buyer</strong>: ${d.Buyer}<br />` +
                  `<p><strong>Seller</strong>: ${d.Seller}<br />`);
        })
        .on("mousemove", function(e) {
          tooltip
            .style("top", e.pageY - 10 + "px")
            .style("left", e.pageX + 10 + "px");
        })
        .on("mouseout", function() {
          d3.select(this).attr('stroke-width', '0');
            tooltip.style("visibility", "hidden");
      });
  
      simulation.nodes(datapoints)
        .on('tick', ticked)
      function ticked() {
        svg.selectAll('circle')
          .attr("cx", d => d.x)
          .attr("cy", d => d.y)
        
      }
    }
  })();