score:2

Figured it out! Using getBoundingClientRect() on this gets the absolute position of the SVG element

function onMouseOverCircle(d) {
  const {
    x, y, width,
  } = this.getBoundingClientRect();

  tooltip.transition()
    .duration(100)
    .style('opacity', 0.9);

  tooltip.html(d.id)
    .style('left', `${x + width / 2}px`)
    .style('top', `${y - 10}px`);
}

const node = g.append('g')
  .attr('stroke', '#fff')
  .attr('stroke-width', 1.5)
  .selectAll('circle')
  .data(nodes)
  .enter()
  .append('circle')
  .attr('r', radius)
  .attr('fill', d => (colors[d.type]))
  .on('mouseover', onMouseOverCircle)
  .on('mouseout', () => {
    tooltip.transition()
      .duration(100)
      .style('opacity', 0);
  })

Related Query