1

I need to draw axis with time scale and show only days on it. Here is my code:

            var xScale = d3.time.scale.utc()
            .domain([beginning, ending])
            .range([margin.left, availableWidth - margin.right]);

        var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient(orient)
            .tickFormat(tickFormat)
            .ticks(d3.time.days.utc, 1)
            .tickSize(tickSize);

But on long intervals it is bad overlapping (because I show every tick):

https://pp.vk.me/c620728/v620728099/16ab9/HdJByiakoKA.jpg

I make some math operations and calculate acceptable amount of ticks:

var xAxis = d3.svg.axis()
            ...
            .ticks(d3.time.days.utc, stepTick) // for example 20 for a year interval
            .tickSize(tickSize);

So every 20th tick on axis will be shown for a year and it looks great! Except joint of month:

https://pp.vk.me/c620728/v620728099/16aaf/PjM4KJ0ofTM.jpg (31.05/01.06)

Labels on joint of month are still overlapping, because in docs for d3.time.days we can see that

If step is specified, then every step'th date will be returned, based on the day of the month.

How should I do to prevent labels overlapping ?

1 Answers1

1

It seems like choosing an interval based on a desired tick-spacing will give you reference dates that aren't much help in deciphering your chart. The dates labeled in the image you provided (the 6th, 11th, 16th, 21st, 26th, and 31st of each month) are actually distracting. They don't provide a good point of reference, since their only significance is that they are spaced at a given interval.

I would recommend that when the tick labels become crowded, you fall back to using only a few labeled ticks that lie on significant dates. The start of each month would seem like a logical choice. Then you could create some unlabeled ticks to give you some extra precision in reading the chart.

This answer gives a good method for creating minor (unlabeled) ticks. You could adapt that code to your time-scale. Say you wanted to create minor ticks for each day:

d3.select('.axis.x').selectAll('line')
  .data(xScale.ticks(d3.time.days.utc,1), function(d) {return d;})
  .enter().append('line')
    .attr('class', 'day-ticks')
    .attr('y1', 0)
    .attr('y2', 5)
    .attr('x1', xScale)
    .attr('x2', xScale);

HERE is a demo of what that would give you.

You could go a step further and create intermediate ticks for each week as well to give you better context inside of each month:

d3.select('.axis.x')
  .selectAll('line')
  .data(xScale.ticks(d3.time.days.utc,7), function(d) {return d;})
  .enter().append('line')
    .attr('class', 'week-ticks')
    .attr('y1', 0)
    .attr('y2', 8)
    .attr('x1', xScale)
    .attr('x2', xScale);

HERE is what that would look like.

Community
  • 1
  • 1
jshanley
  • 9,048
  • 2
  • 37
  • 44