Unfortunately, I think it is going to be hard to find this solution readily available in Javascript or PHP. But, I do think your problem can be broken down into small sub-problems (based on your rules) to help you design your solution.
I would identify which of your rules are most important. From the looks of the graph you provided, I'd say that rule #1 and #2 would provide the greatest improvement in readability.
To determine placement according to those rules, I would calculate the boundary containers of the text and bubbles and test for intersection. Upon intersection, move to a location with no intersection. If one cannot be found, use a space with a minimum overlap.
This would allow you to also create a weighted placement heuristic for top-left, bottom-right, etc, to help place the labels in "preferred" locations.
I'd try writing out a small piece of the placement algorithm using two bubbles with two labels that are generally close and would potentially overlap. If you can generalize your placement algorithm to work for this small subset, you should be good moving forward with more bubbles.
Also, perhaps you could use something on the order of a kd-tree or another space partitioning datastructure to locate nearest neighbors to avoid.