Accepted answer

I've found a fix but it's not ideal, I'm still putting it here in case someone finds it useful. Instead of just using the value from the scale, I add a length of the article (a little less actually… told you it wasn't ideal) times the number of articles already displayed. Far from elegant but it works for now, articles never overlap:

    .style("top", (d, i) ->
        d3.round(timeScale(timeFormat.parse( + i * articleHeight + "px")


The problem is indeed with the height calculation. What you are calculating is the needed height for N articles, where N is the number of articles in your data. However, when you create the scale, you calculate the range from the earliest date to the the latest. So if your first data item is from 01-01-2012 and your last from 31-01-2012, the range will be 30 (or 31 too lazy to check).

So what you basically should do is reuse the d3.extent calculation in the timescale to calculate the height.

Update: Okay, so let me elaborate a bit on this. What you want is non-overlapping articles. Therefore you specify a minimal article height. I assume you are using d3.time.scale for timeScale (which is the correct thing to do). For this scale you (also correctly) set the domain as follows:

   .domain(d3.extent(data, (d) -> timeFormat.parse(

The d3.extent function gives you the min and max values, in the case the earliest and the latest date. Now, to calculate the required height, you'll need to take account for the maximum number of articles that might be visible, which is (assuming max one article per day) the number of days between the first and the last date as calculated by d3.extent. To do this you have to calculate the number of days between min and max.

Is set up a jsfiddle which demonstrates this calculation here:

Related Query

More Query from same tag