D3,基于时间的可变x轴刻度

时间:2014-04-25 16:14:06

标签: javascript graph d3.js charts

我正在使用 D3.js 生成一个随时间变化的响应时间的图表。以前我使用谷歌图表,但它太重了。 D3既漂亮又轻巧,但我无法用谷歌图表做些事情。

问题是这些图表有时会超过一周,有时超过一天,有时超过一小时。对于每种情况,我都必须手动修改X轴上的刻度线的显示方式。我是通过比较X轴的第一个和最后一个值,并检查它们之间的时间来完成的,如下所示:

if (dateDif < 25) { // daily
    xAxis = d3.svg.axis()
        .scale(x)
        .tickFormat(d3.time.format('%H:%M'))
        .ticks(d3.time.hours, 3)
        .orient("bottom");
}

else if (dateDif <= 170) {  // ~ weekly
    xAxis = d3.svg.axis()
        .scale(x)
        .tickFormat(d3.time.format('%d/%m %H:%M'))
        .ticks(d3.time.hours, 24)
        .orient("bottom");
} else { // more than weekly
    xAxis = d3.svg.axis()
        .scale(x)
        .tickFormat(d3.time.format('%d/%m %H:%M'))
        .ticks(d3.time.hours, 96)
        .orient("bottom");
}

但是它根本不好,特别是当图表中只有几个值(它们每分钟生成一次)时,就不会出现滴答声(因为它落在第一种情况下,而且还不够价值跨越3小时)。

你知道在这种情况下自动适应X轴的任何插件或方法吗?

2 个答案:

答案 0 :(得分:2)

您可以根据tickFormat定义一个函数来获取dateDif,这样您就不需要拥有如此大的if-else块。

function getFormat() {
  if (dateDif < 25) {
    return d3.time.format('%H:%M');
  } else {
    return d3.time.format('%d/%m %H:%M');
  }
}

然后您可以将.ticks()设置为一个数字。在输出中,将大致显示许多刻度。 d3选择一些接近您要求的值的刻度,但也做出一些决定以尝试提供最佳输出。

// approximately 10 ticks will be displayed
xAxis = d3.svg.axis()
    .scale(x)
    .tickFormat(getFormat())
    .ticks(10)
    .orient("bottom");

如果您使用此方法,您将失去对将显示的确切滴答数量的一点控制,但您可以保证显示滴答,如果您为滴答值选择合理的数字,输出可能会是令人满意的。

这里有fiddle使用这种技术和一些人为的数据。

答案 1 :(得分:2)

默认情况下,

d3.svg.axis()非常善于处理此类行为 - 尝试从轴中移除.tickFormat(...),并设置.ticks(n)其中n是所需的滴答数你想要在任何比例缩放级别的轴上 - 这可能足以满足你的需求。

以下是几个相关的例子:

http://bl.ocks.org/mbostock/2983699

http://bl.ocks.org/mbostock/1166403