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

时间:2021-03-04 21:38:36

This seems like it should be trivial. I want to use d3.time.scale() to get an array of evenly spaced dates that covers a certain range of time. For example, years

这似乎是微不足道的。我想使用d3.time.scale()获得一个包含一定时间范围的均匀间隔日期数组。例如,年

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

or months

或者几个月

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

or whatever.

之类的。

So I start out like this:

我这样开始:

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

I would then assume from the documentation that I'd be able to do this

然后我将从文档中假设我可以这样做

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

...but that just returns a single date.

…但它只返回一个日期。

This gives me an array of months

这给了我一个月的数组

var ticks = t.ticks(30)

...but only because I told it roughly how many ticks to generate (30), which I won't know in advance (unless I do some heavy lifting on my own, which kind of defeats the purpose of using d3 for this).

…但只是因为我粗略地告诉了它生成了多少个节拍(30),这是我事先不知道的(除非我自己做一些繁重的工作,这就违背了使用d3的目的)。

I don't understand why it's not working to just tell it that I want every year, or every month, or every 3 months, or whatever.

我不明白为什么它不能告诉我,我想要每年,或每个月,或每三个月,或其他什么。

I've put up a fiddle here: http://jsfiddle.net/herbcaudill/LgGpd/4/

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

2 个解决方案

#1


5  

Using the Date() constructor doesn't work reliably -- it basically depends on the browser. It's much safer to parse explicitly. The constructor doesn't parse as such.

使用Date()构造函数并不可靠——它基本上取决于浏览器。显式解析要安全得多。构造函数不会那样解析。

Instead of

而不是

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

use this:

用这个:

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

Modified jsfiddle here.

修改jsfiddle这里。

#2


2  

Using a dataset such as

使用数据集,例如。

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();

I had a similar problem, and found that

我也遇到过类似的问题

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

Dropped the first item in the scale (it still remains a mystery as to why that was the case), whereas

在量表中删除第一个条目(为什么会这样仍然是个谜),然而

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);

worked fine.

工作得很好。

So, my only explanation is the one Lars provided. Date() is unpredictable, so use d3.time.format instead.

我唯一的解释是佬司提供的。日期()是不可预测的,所以使用d3.time。格式。

#1


5  

Using the Date() constructor doesn't work reliably -- it basically depends on the browser. It's much safer to parse explicitly. The constructor doesn't parse as such.

使用Date()构造函数并不可靠——它基本上取决于浏览器。显式解析要安全得多。构造函数不会那样解析。

Instead of

而不是

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

use this:

用这个:

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

Modified jsfiddle here.

修改jsfiddle这里。

#2


2  

Using a dataset such as

使用数据集,例如。

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();

I had a similar problem, and found that

我也遇到过类似的问题

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

Dropped the first item in the scale (it still remains a mystery as to why that was the case), whereas

在量表中删除第一个条目(为什么会这样仍然是个谜),然而

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);

worked fine.

工作得很好。

So, my only explanation is the one Lars provided. Date() is unpredictable, so use d3.time.format instead.

我唯一的解释是佬司提供的。日期()是不可预测的,所以使用d3.time。格式。