Thank you for the suggestions and the example code.
One thing I’m not sure I fully understand is what d3.drag.subject() really is doing in this revised version of the example:
When I use d.x and d.y to set the position of the circle, I need to set the subject() as shown in the code. When I don’t set the subject(), the dragging causes the circle to jump to the d.x, d.y coordinates but in the pixel space. That is event.x = d.x, event.y = d.y and then dragging causes event.x and event.y to update starting from that data space location. When I add in the subject() then event.x and event.y are properly set to the pixel space location of the circle. I think I understand that, though I’m unclear on why it is a good default to set event.x = d.x, event.y = d.y when the subject isn’t specified.
Interestingly when I use d.xPos, d.yPos to set the position of the circle, I don’t need to set the subject and the drag operates as I would expect. So it seems like there is something special about the x,y fields of the datum (in fact the documentation of d3.drag().subject() seems to talk about this), but I couldn’t figure out from the documentation exactly what might be doing on.