I'd probably place one label, then place the next, check if it overlaps the first, and if so flip it, if that doesn't work, nudge it upwards until it doesn't overlap anymore... as a starting point anyway. Maybe add a cost function as a distance from the ideal or default placement (if there were no other labels to get in the way), which is to be minimized. Then find the lowest-cost arrangement of labels. Can give flipping, and movement, and rotation, abbreviation, and dropping each a different cost.
Here's my take:
- Mark the points where you want to put labels
- Split them into groups with the distance of at least
2*size
between them - For each group, go from the right an try to put a label.
- Try to put label to the right or to the left. See which results in lower length of the vertical line
- If doesn't matter, try to put to the right
- Unless it's the end of the group, then try to put it to the left
Now go again over the labels and see if any can be flipped from one side to another while shortening the length of vertical lines.
Should result in a decent output, in my opinion.
This question reminds me of a graphics project I did not too long ago. It was to draw a mathematical graph (as in nodes and edges) in the most pleasing way possible. There are several approaches but my favorite by far was the physics approach. You treat each node as a charged particle that repels all others and each edge as a classical spring with some ideal length. You run a few hundred time steps and eventually get to a stable state with an appropriate damping effect.
I see many parallels with your problem. The text boxes are the nodes and the leader lines are the edges.
It will have to be modified. For example there should be a positive force upward so they don't go below the graph. You'd also have to incorporate the idea of flipping the text to the left or right. But it should give a reasonable result on most inputs.
The article I referenced for my project was here.