Strategies to avoid overlapping chart elements

4,337 views
Skip to first unread message

Ollie Boermans

unread,
Sep 30, 2011, 1:18:46 AM9/30/11
to d3-js
Hi all,

Jumping into D3 with a mission to dynamically build a slope graph:
http://charliepark.org/slopegraphs/

The vertical axis of my chart has a number of very similar values. I
am using these values to position the labels for each line. Naturally
the labels of lines representing similar values overlap.

My question is:
Does D3 offer any tools to help me apply some logic to shift the
labels to a nearest unoccupied position on the chart axis?

As long as the order of the values is retained a little inaccuracy
traded for clarity seems fair.

Snapping the labels to a nearest predefined increments looks straight
forward, but I need them to be effectively collision sensitive and
stack one beneath another vertically (y axis) rather than over one
another (‘z’ axis).

Either way I’m interested in any strategies you might suggest.
Cheers Ollie
--
@ollicle

Mike Bostock

unread,
Sep 30, 2011, 1:22:35 AM9/30/11
to d3...@googlegroups.com
> Does D3 offer any tools to help me apply some logic to shift the
> labels to a nearest unoccupied position on the chart axis?

Not really. You probably want to do the collision detection ("is there
already a label in this position?") and resolution yourself. If you
want to be clever you could try using the constraint relaxation used
by the force layout. See the Dorling cartogram for example, which
involves detecting and resolving collisions between circles; the same
technique could be adapted for label placement.

Mike

Oliver Boermans

unread,
Sep 30, 2011, 6:47:21 AM9/30/11
to d3...@googlegroups.com
Thanks for the quick reply Mike.
I’m looking forward to giving it a go.
Cheers Ollie
--
@ollicle

Lars Kotthoff

unread,
Sep 30, 2011, 1:57:35 PM9/30/11
to d3...@googlegroups.com, mbos...@cs.stanford.edu
I've played around with this and put something together using the force layout.
The secret sauce is basically in the .on("tick" function -- I reset the
coordinate that I don't want to change and check that the other coordinate is
within the bounds of the axis and such that the order of the labels is
preserved.

I added links between consecutive labels and set gravity to 0. Then I fiddled
with the friction parameter until it looked ok. I also added lines from the
axis position to the actual position to make it clear where each label belongs.

You can see it here -- http://www.larsko.org/v/igdp/

Getting the spacing between the labels approximately equal was the most
difficult bit. I guess there're better ways to do it, but I simply adjusted the
friction parameter until I got it.

Lars

Mike Bostock

unread,
Sep 30, 2011, 2:16:24 PM9/30/11
to d3...@googlegroups.com
> http://www.larsko.org/v/igdp/

Awesome, thanks for sharing! Great demonstration of the technique.

Your page will load faster (and GitHub will thank you) if you don't
serve files from raw.github.com. Instead say:

http://mbostock.github.com/d3/d3.min.js

Mike

Lars Kotthoff

unread,
Sep 30, 2011, 2:33:48 PM9/30/11
to d3...@googlegroups.com, mbos...@cs.stanford.edu
> Your page will load faster (and GitHub will thank you) if you don't
> serve files from raw.github.com. Instead say:
>
> http://mbostock.github.com/d3/d3.min.js

Thanks! I copied this from somewhere a while ago and never bothered to change it
:)

Lars

Oliver Boermans

unread,
Sep 30, 2011, 8:19:06 PM9/30/11
to d3...@googlegroups.com
On 1 October 2011 03:46, Mike Bostock <mbos...@cs.stanford.edu> wrote:
>> http://www.larsko.org/v/igdp/
>
> Awesome, thanks for sharing! Great demonstration of the technique.

Impressive work Lars!
I’ll be sure to have a closer look.
Ollie
--
@ollicle

dmitry b

unread,
Sep 26, 2012, 6:00:34 PM9/26/12
to d3...@googlegroups.com, mbos...@cs.stanford.edu
I'm trying to adapt the technique to a scatter plot (with at most 10 data points) in which I need to display a label next to each point and I don't want the labels to overlap when a number of points are close to each other).  I'm not having much luck figuring out how to do this.  Here's my strategy:

1. set the force layout's nodes to a combined set representing dots and labels
2. set dot nodes to 'fixed'
3. create a link between each dot and corresponding label
4. set the link distance at some small number (I figured, this would force the label to rotate around its dot, but otherwise not go anywhere else)

Does this sound reasonable?  If so, I would appreciate a few pointers on how to approach coding this in d3.


Thanks
Dmitry

Alexander Skaburskis

unread,
Sep 27, 2012, 1:54:13 PM9/27/12
to d3...@googlegroups.com, mbos...@cs.stanford.edu
Here are some examples that do something very similar:

http://bl.ocks.org/1691430

HTH
Alexander

sabahat iqbal

unread,
Jul 22, 2020, 12:59:45 PM7/22/20
to d3-js
Hi - I know I am several years late to the discussion but hope someone can help all the same!

Does it make sense to use force layout to prevent overlap of labels in a slope graph (see my code here: link)? Since the labels have to be either right or left of the data point, I can't move them around if they are overlapping. Is there a different way to prevent overlap within a slope graph? Thanks!!
Reply all
Reply to author
Forward
0 new messages