Seeking help to position d3 tooltip accurately

I am trying to understand how can I assign the tooltip div the exact same position as the element.

For example,
The full code is below and a notebook. The notebook does not render the tooltip at all, but the following code in the browser does.

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
         .svg-container {
         position: relative;
         }
         .xAxisLabel,
         .yAxisLabel {
         font-size: medium;
         }
         .chartTitle {
         font-size: medium;
         text-decoration: underline;
         }
         .vornoiBound,
         .vornoiOutline,
         path.cell {
         pointer-events: none;
         }
         #tooltip {
         position: absolute;
         width: auto;
         height: auto;
         padding: 10px;
         background-color: white;
         border-radius: 10px;
         box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
         pointer-events: none;
         font-size: 1.5vh;
         text-align: center;
         }
      </style>
   </head>
   <script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
   <body>
      <div id="container" class="svg-container"></div>
      </div>
      <script type="text/javascript">
const tbl = [{ "Month": 1, "Value": 14841, "MonthName": "Jan" }, { "Month": 2, "Value": 24467, "MonthName": "Feb" }, { "Month": 3, "Value": 78423, "MonthName": "Mar" }, { "Month": 4, "Value": 60213, "MonthName": "Apr" }, { "Month": 5, "Value": 87257, "MonthName": "May" }, { "Month": 6, "Value": 21543, "MonthName": "Jun" }, { "Month": 7, "Value": 21373, "MonthName": "Jul" }, { "Month": 8, "Value": 87363, "MonthName": "Aug" }, { "Month": 9, "Value": 50378, "MonthName": "Sep" }, { "Month": 10, "Value": 29714, "MonthName": "Oct" }, { "Month": 11, "Value": 20171, "MonthName": "Nov" }, { "Month": 12, "Value": 70059, "MonthName": "Dec" }]
         
         //the chart X Axis needs to start from 0
         tbl.filter(a => (a.Month == 0)).length == 0 ? tbl.unshift({ "Month": 0, "Value": 0 }) : tbl
         
                 
         //define dimension
         const width = 1280;
         const height = 720;
         
         //------------------------1.CREATE SVG------------------------//
         //namespace
         const svgns = 'http://www.w3.org/2000/svg'
         
         d3.select('#container')
             .append('svg')
             .attr('xmlns', svgns)
             .attr('viewBox', `0 0 ${width} ${height}`)
             .attr('id', 'svg')
         
         //---create a rect encompassing viewBox --- to be deleted later
         const svg = d3.select('svg')
         //------------------------2. CREATE BOUND------------------------//    
         const padding = {
             top: 70,
             bottom: 50,
             left: 70,
             right: 50
         }
                
         const boundHeight = height  - padding.top - padding.bottom;
         const boundWidth = width  - padding.right - padding.left;
         
         //create bound element
         const bound = svg.append('g')
             .attr('class', 'bound')
             //specify transform, must be .style and not .attr, px needs to be mentioned
             .style('transform', `translate(${padding.left}px,${padding.top}px)`)        
         
         
         //------------------------3. CREATE SCALE------------------------//
         //scale converts a domain (data) to range (pixel)
         const scaleX = d3.scaleLinear()
             .range([0, boundWidth])
             .domain(d3.extent(tbl, d => d.Month))
         
         const scaleY = d3.scaleLinear()
             .range([boundHeight, 0])
             .domain(d3.extent(tbl, d => d.Value))
         
         //create Y Axis    
         bound.append('g').attr('class', 'yAxis')
 
         .call(d3.axisLeft(scaleY).tickSizeOuter(0))
             .attr('class', 'yAxis')
             //select the first tick and change the opacity to 0
             .call(d => d3.select('.yAxis g:nth-of-type(1)')
                 .attr('opacity', '0')
             )
             //create Y axis label
             .append('text')
             .attr('class', 'yAxisLabel')
             .style("text-anchor", "middle")
             .text('Value')
             .attr("transform", `translate(${(padding.left-20)*-1},${boundHeight/2}),rotate(-90)`)
             //.attr('transfom', 'rotate(45deg)')
             .attr('fill', 'black')
         
         //------------------------4. CREATE AXIS------------------------//    
         
         //create X Axis Bottom
         bound.append('g')
             .attr('class', 'xAxis')
             .append('g')
             .attr('class', 'xAxisBottom')
             .call(d3.axisBottom(scaleX).tickSizeOuter(0))
             .style('transform', `translateY(${boundHeight}px)`)
             .call(d => d.select('.xAxisBottom g:nth-of-type(1)')
                 .attr('opacity', '0')
             )
             //change the class name of the tick
             .call(d => d.selectAll('.xAxisBottom>.tick')
                 .attr('class', (d, i) => { return `xAxisBottomTick${i}` })
             )
             .call(d => d.append('g').attr('class', 'rectContainer'))
             //create X axis label
             .append('text')
             .attr('class', 'xAxisLabel')
             .style("text-anchor", "middle")
             .text('Month')
             .attr("transform", `translate(${boundWidth/2},40)`)
             .attr('fill', 'black')
         
         
         //------------------------5. CREATE LINE------------------------//
         const line = d3.line()
             //.curve(eval(`${curves[3]}`))
             .x(d => scaleX(d.Month))
             .y(d => scaleY(d.Value))
         
         bound.append('g')
             .attr('class', 'valLine')
             //.append('path')
             .selectAll('path')
             .data([tbl])
             .join('path')
             .attr('d', (d, i) => {
                 return d3.line()            
                     .x(d => scaleX(d.Month))
                     .y(d => scaleY(d.Value))
                     (tbl)
             })
             .attr('class', (d, i) => `line${i}`)
             .attr('fill', 'none')
             .attr('stroke', 'white')
         
         //create tooltip div
         const tooltip = d3.select('body')
             .append('div')
             .attr('id', 'tooltip')
             .attr('style', 'opacity: 0;')	
         
         //add circle
         const circ =
             bound.append('g')
             .attr('class', 'valCirc')
             .selectAll('circle')
             .data(tbl)
             .join('circle')
             .attr('r', '5')
             .attr('cx', d => scaleX(d.Month))
             .attr('cy', d => scaleY(d.Value))
             .attr('opacity', (d, i) => {
                 return (i == 0 && d.Month == 0) ? '0' : '1'
             })
             .attr('pointer-events', 'all')
             .on('mouseenter', function(event, d) {
                 tooltip
                     .transition().duration(200).style('opacity', '1');                 
                 d3.select('#tooltip')
				     //assign circle's position to div
					 .style("left", d3.select(this).attr("cx") + "px")                     
					 .style("top", d3.select(this).attr("cy") + "px")
                     .text(d.Value.toLocaleString())

             })
             .on('mouseout', function(d) {
                 d3.select('#tooltip').style('opacity', 0)
             })
         
         //add inlineLabel
         const some = bound.append('g')
             .attr('class', 'inlineLabel')
             .selectAll('text')
             .data(tbl)
             .join('text')
             .attr('x', d => scaleX(d.Month))
             .attr('y', d => scaleY(d.Value) + 12)
             .attr('opacity', (d, i) => {
                 return (i == 0 && d.Month == 0) ? '0' : '1'
             })
             .text(d => { return d.Value.toLocaleString() })
             .attr('dominant-baseline', 'middle')
             .attr('text-anchor', 'middle')
         	
         
         
         
         // add a voronoi diagram on top of the existing elements
         // following the docs specify the x and y points through functions referencing the values included in the visualization
         const delaunay = d3.Delaunay.from(tbl, d => scaleX(d.Month), d => scaleY(d.Value));
         // create a Vonoroi diagram describing its boundaries
         const voronoi = delaunay.voronoi([0, 0, boundWidth, boundHeight]);
         
         bound
             .append('path')
             .attr('class', 'vornoiOutline')
             // hidden by default
             .attr('opacity', 1)
             .attr('d', voronoi.render())
             .attr('fill', 'none')
             .attr('stroke', 'currentColor');
         
         // add the boundaries as a substitute to the axes, 
         //and to encase the visualization on four sides    
         
         bound
             .append('path')
             .attr('class', 'vornoiBound')
             .attr('d', voronoi.renderBounds())
             .attr('fill', 'none')
             .attr('stroke', 'currentColor');
         
         // for each data point add a cell
         // ! make the cell fully transparent, since the path is included only for mouseover events
         bound
             .selectAll('path.cell')
             .data(tbl)
             .enter()
             .append('path')
             .attr('class', 'cell')
             .attr('opacity', 0)
             .attr('d', (d, i) => voronoi.renderCell(i))
      </script>
      <!--d3 script-->
   </body>
</html>

What I am struggling with is the following bit of the code. I thought I could simply assign the circle’s position to the tooltip div but the tooltip is not rendering at the exact same position as circles.

image

Can you please advise what am I doing wrong here or how to correct this?

@smpa01 Your notebook does not seem to be published?

@mootari I am currently experimenting with tooltip. I will update this soon with a better Q and reinstate the notebook.