This demonstrates relaxing constraints on label placement. Reload the example to get a different scatterplot. Click "relax" do show the labels reorganizing themselves to prevent stacking.
The relax routine checks collisions between each member of the data and every subsequent member of the data array. If there is a collision, the labels get nudged a bit in opposite directions, and the entire array is walked again. The walking continues until no collisions are found. The routine was inspired by /syntagmatic/4054247, but I've made some changes to allow more than one label to occupying the same vertical space. I've also removed the setTimeout() method, choosing a loop instead -- this blocks display while computing, but executes much faster.
This is a relatively naïve example intended to demonstrate the basic approach, not serve as a one-size-fits-all, robust solution. Other things to take into consideration: Things I've ignored: changing height or width of labels, boundaries of the charts, etc. The circumstances of your implementation may not require anything fancy here, but there are ways to augment the example to handle all of those edge cases. It becomes computationally expensive with many labels, but in that case you have more problems than processing time with your visualization.
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js