Time scale automatic ticks overlapping on x axis

2,574 views
Skip to first unread message

Rein Henrichs

unread,
Jun 4, 2012, 8:26:59 PM6/4/12
to d3...@googlegroups.com
As subject says, the tick text automatically generated by d3.time.scale.ticks has some overlaps at certain domain/data sizes. I can see a few options:

1) Rotate the tick text around its center as was possible when drawing the ticks by hand.
2) Suggest a tick number that keeps the ticks more spread out.
3) Modify the time intervals used to generate automatic d3.time.scale.ticks.

Unfortunately, (1) seems currently impossible without digging deeply into the tick rendering (but could perhaps be implemented as a new fluent method on axis()), (2) prevents the ticks from scaling as well when the domain transitions to other sizes, and (3) seems like a lot of one-off work for relatively little gain.

How would you recommend I handle this?

Rein Henrichs

unread,
Jun 4, 2012, 8:43:42 PM6/4/12
to d3...@googlegroups.com
Quick update:

I found a group post on rotating the tick text created by the axis that looks reasonable and will hopefully be sufficient:

Ted Adams

unread,
Dec 11, 2014, 6:38:51 PM12/11/14
to d3...@googlegroups.com
This is an old thread, but I ran in to this problem recently and this post was all I found on Google.

If for visual reasons you don't want to rotate the ticks, I found another solution.

After creating the x axis I saved all of the '.tick' classed elements back to an array:

var dateTicks = svg.append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0, ' + height + ')')
        .call(xAxis)
      .selectAll('.tick');

I then iterated through the collection of ticks and used the .getBoundingRect() method to detect whether the tick was colliding with its neighbors:

for (var j = 0; j < dateTicks[0].length; j++) {
  var c = dateTicks[0][j],
      n = dateTicks[0][j+1];
  if (!c || !n || !c.getBoundingClientRect || !n.getBoundingClientRect)
    continue;
  while (c.getBoundingClientRect().right > n.getBoundingClientRect().left) {
    d3.select(n).remove();
    j++;
    n = dateTicks[0][j+1];
    if (!n)
      break;
  }
}

Still looking for a cleaner way to do this that is more "d3", but just wanted to share this solution if anyone else is going crazy with the ticks overlapping!
Reply all
Reply to author
Forward
0 new messages