1

我的问题可能措辞不佳,欢迎您对其进行编辑。

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

重叠的文章(坏)

这里有 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

编辑:每天可以有不止一篇文章。

4

2 回答 2

1

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

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

更新:好的,让我详细说明一下。你想要的是不重叠的文章。因此,您指定最小文章高度。我假设您将 d3.time.scale 用于 timeScale (这是正确的做法)。对于这个规模,您(也正确地)设置域如下:

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

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

设置了一个 jsfiddle,在这里演示了这个计算:http: //jsfiddle.net/EA5rP/14/

于 2012-10-02T10:10:17.577 回答
1

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

div.transition().duration(2000)
    .style("top", (d, i) ->
        d3.round(timeScale(timeFormat.parse(d.date))) + i * articleHeight + "px")
于 2012-10-02T20:16:32.430 回答