如何在d3.js中为时间刻度设置间隔的最小范围?

时间:2012-10-01 21:43:35

标签: coffeescript d3.js data-visualization

我的问题可能很差,你可以编辑它。

我的问题很简单。我正在使用d3以纯HTML格式制作时间轴。时间轴项目(这里的文章)都有一个固定的高度(比方说100px),但我需要它们不要像这样重叠:

Overlapping articles (bad)

这里有4篇文章,你可以看到,这是不可读的。我知道问题是什么,但我不知道如何解决它。这是我的代码:

height = data.length * (articleHeight + margin * 2)

timeScale
    .range([height, 0])
    .domain(d3.extent(data, (d) -> timeFormat.parse(d.date)))

div = selection.selectAll(".article").data(data)

div.enter().append("div")
    .attr("class", "article")
    .html(divHTML)
    .style("top", "0")

div.transition().duration(2000)
    .style("top", (d) -> d3.round(timeScale(timeFormat.parse(d.date))) + "px")

我计算身高的方式很糟糕。我已经研究过蜱,但那是为了生成轴吗?我试图添加1天或3天的刻度并且它不会改变任何事情(不出所料)。

CSV以防万一:

date,title,excerpt
2012-08-13,Most recent article,loremasdjf asdflkasfdlaksjdflasdf kjlasdhflkj asdflkja sdklfjhaskdljhfaskdljhfaskldjhf alksjhdf kaljsd fkljas dfkljash dkfaslkdfj
2012-08-4,Second Most recent article,loremasdjf asdflkasfdlaksjdflasdf kjlasdhflkj asdflkja sdklfjhaskdljhfaskdljhfaskldjhf alksjhdf kaljsd fkljas dfkljash dkfaslkdfj
2012-07-15,"July article, bro",loremasdjf asdflkasfdlaksjdflasdf kjlasdhflkj asdflkja sdklfjhaskdljhfaskdljhfaskldjhf alksjhdf kaljsd fkljas dfkljash dkfaslkdfj
2012-01-16,First article of 2012,loremasdjf asdflkasfdlaksjdflasdf kjlasdhflkj asdflkja sdklfjhaskdljhfaskdljhfaskldjhf alksjhdf kaljsd fkljas dfkljash dkfaslkdfj

编辑:每天可以有多篇文章。

2 个答案:

答案 0 :(得分:1)

问题确实在于高度计算。您计算的是N篇文章所需的高度,其中N是数据中的文章数。但是,在创建比例时,您可以计算从最早日期到最晚日期的范围。因此,如果您的第一个数据项是从01-01-2012开始,而您的最后一个数据项是从31-01-2012开始,则范围将是30(或者懒得检查)。

所以你基本上应该做的是重复使用时间刻度中的d3.extent计算来计算高度。

更新:好的,让我详细说明一下。你想要的是不重叠的文章。因此,您指定最小文章高度。我假设您正在使用d3.time.scale进行timeScale(这是正确的做法)。对于此比例,您(也正确)按如下方式设置域:

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

d3.extent函数为您提供最小和最大值,如果是最早和最晚的日期。现在,要计算所需的高度,您需要考虑可能可见的文章的最大数量,即(假设每天最多一篇文章)第一个和最后一个日期之间的天数,如下所示: d3.extent。为此,您必须计算最小值和最大值之间的天数。

设置一个jsfiddle,在此处演示此计算:http://jsfiddle.net/EA5rP/14/

答案 1 :(得分:1)

我找到了一个修复但它并不理想,我仍然把它放在这里以防有人发现它有用。我没有使用比例尺中的值,而是添加了文章的长度(实际上少了一点......告诉你它并不理想)乘以已经显示的文章数量。远非优雅,但它现在起作用,文章永远不会重叠:

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