根据数据范围动态设置D3刻度

时间:2016-02-11 19:06:00

标签: javascript d3.js

是否有办法根据当前数据集在D3轴上动态设置ticks。我遇到的问题是我的时间范围(x轴)可能会有很大差异。对于某些数据集,它需要几年的时间,对于其他数据集需要几个月,在某些情况下只需几毫秒。我目前为ticks设置了此设置:

.ticks(d3.time.month, 3)

...每隔三个月显示一次。对于跨越数月或数年的数据,这是一个不错的季度轴。但是,如果数据的范围仅为几周,几天甚至几秒,则我的轴标签上不会显示任何内容。

1 个答案:

答案 0 :(得分:6)

从我(相当广泛的)经验来看,没有自动神奇的方法来做到这一点。但是"硬"方式,您明确指定您希望在任何时间范围内发生的事情,非常有效。

基本上,你知道图表的全部时间范围 - 让我们说它被称为timeSpan并且它以毫秒为单位 - 所以你可以制作一个大的if ...响应它的else块。例如

var interval, count;
if (timeSpan <= 3600000) { // 1 hour or less
  interval = d3.time.minute;
  count = 15; // every 15 minutes
}
else if (timeSpan <= 8.64e7) { // 24 hours {
  interval = d3.time.hour;
  count = 1;
}
else if (timeSpan <= 7 * 8.64e7) { // 7 days {
  interval = d3.time.day;
  count = 1;
}
// etc....

timeAxis.ticks(interval, count);

在许多情况下,这对我来说非常有效。您可以根据需要通过添加更多条件来扩展它。此外,您的图表可能有两个轴 - 一个用于主要标记,标记为刻度线,另一个用于辅助刻度线或网格线。然后,您可以引入另一个变量secondaryInterval,并以相同的方式将其用于if ... else块。同样,您可能会发现您还需要按.tickFormat()指定timeSpan,这也可以在此代码中使用。

var interval, count, format;
if (timeSpan <= 3600000) { // 1 hour or less
  interval = d3.time.minute;
  count = 15; // every 15 minutes
  format = d3.time.format("%H:%M");
}
// etc....
timeAxis
  .ticks(interval, count)
  .tickFormat(format);

此外,如果您的图表具有响应性,意味着有时它的宽度为900像素,而其他图表宽度为200像素,您可能还需要根据密度调整刻度。在这种情况下,您需要计算密度值,例如&#34;每像素毫秒数&#34;:

msPerPixel = timeSpan / chartWidth

对于任何给定的timeSpan,根据浏览器(或图表的)宽度,msPerPixel会更小或更大,您可以使用msPerPixel来细化条件逻辑以上显示更多或更少的刻度,取决于msPerPixel大于某个常数。

希望有所帮助。祝你好运。