如何使用d3.time.scale()生成一个间隔均匀的日期数组?

时间:2013-11-24 21:32:05

标签: javascript arrays date d3.js

这似乎应该是微不足道的。我想使用d3.time.scale()来获得一系列均匀分布的日期,这些日期涵盖了一定的时间范围。例如,年

 [2012-01-01, 2013-01-01, 2014-01-01]

或几个月

 [2012-01-01, 2012-02-01, 2012-03-01 ... 2014-12-01]

或其他什么。

所以我从这样开始:

var t = d3.time.scale()
    .domain(d3.extent(dates))
    .nice(d3.time.year);

然后我会从documentation假设我能够做到这一点

var ticks = t.ticks(d3.time.month,1);

...但这只会返回一个日期。

这给了我几个月的数组

var ticks = t.ticks(30)

...但仅仅是因为我大致告诉它生成了多少个刻度(30),我事先不知道(除非我自己做了一些繁重的工作,哪种打败了使用d3的目的为了这)。

我不明白为什么每年,每月,每3个月或其他任何事情只是告诉我我想要的。

我在这里竖起了一个小提琴:http://jsfiddle.net/herbcaudill/LgGpd/4/

2 个答案:

答案 0 :(得分:5)

使用Date()构造函数不能可靠地工作 - 它基本上取决于浏览器。明确解析更安全。构造函数不会这样解析。

而不是

var dates = getDates().map(function(d) { return new Date(d) });

使用它:

var dates = getDates().map(function(d) {
    return d3.time.format("%Y-%m-%d").parse(d);
});

修改了jsfiddle here

答案 1 :(得分:2)

使用

等数据集
var dataset = [ 
      { "active" : false,
        "date" : "2014-12-12"
      },
      { "active" : true,
        "date" : "2014-12-13"
      },
      { "active" : true,
        "date" : "2014-12-14"
      },
      { "active" : true,
        "date" : "2014-12-15"
      }
    ]

var slicedData = var slicedData = dataset.slice();

我有类似的问题,发现

var x = d3.time.scale()
    .domain([new Date(slicedData[0].date), new Date(slicedData[slicedData.length - 1].date)])
    .range([0,width]);

放弃了比例中的第一项(为什么会出现这种情况仍然是一个谜),而

var dates = slicedData.map(function(d) {
        return d3.time.format("%Y-%m-%d").parse(d.date);
    });
    var t = d3.time.scale()
        .domain(d3.extent(dates))
        .range([0,width])
        .nice(d3.time.day);

工作正常。

所以,我唯一的解释是Lars提供的那个。 Date()是不可预测的,所以请改用d3.time.format。