在d3中映射到有序比例时,如何计算闰年?

时间:2016-04-12 19:03:41

标签: javascript d3.js

当我将日期映射到我的x.domain()比例时,我错过了“02-29”的闰年日期。我尝试使用这种方法添加它:

x.domain(data.map(function(d) { return d.xPos, "02-29"; }));

但它只是将它添加到数组的末尾。另一种方法是重新排列CSV文件并将闰年放在第一位。这有效,但看起来很黑。所以我看看如下添加它但是卡住了:

    // define the x-scale 'manually' using a leap year
        var mindate = new Date(2016,0,1),
            maxdate = new Date(2016,11,31);

   // I then need to set the x.domain but the problem is I want it to be an Ordinal scale
       var x = d3.time.scale()
            .domain([mindate, maxdate]) 

当我正确设置x.domain()时,我就遇到了缩放非闰年的问题。如何在没有2月29日值的情况下添加一年的条件,以便为y值赋予“02-29”x值相应的0?

您可以看到我的blockbuilder here或我的blo.ck here。请注意2016年的偏离02-29栏向右移动..

2 个答案:

答案 0 :(得分:1)

尝试不同的方法,已经有一些功能可以帮助你了解闰年的年份。如:

function leapYear(year){ return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); }

然后获取返回的值并使用if语句更改maxdate的值

if (leapYear(maxdate[0]) && maxdate[1] == 2 && maxdate[2] == 28){ maxdate = new Date(year, 2 , 29) }else{ /* work as usual */ }

答案 1 :(得分:0)

一种方法是确保x.domain()设置为在典型的闰年中包含日期的数组。即域应该是

["01-01", "01-02", ... , "02-28", "02-29", "03-01", ... "12-31"]

这意味着每个图表年都将包括闰日 - 甚至是非闰年,在这种情况下,闰日将是无条件的。我不确定这对你来说是否可以接受,但对我来说似乎是合理的。

为了构建这种域,你需要遍历闰年的每一天(2016年和任何一样好)并将其附加到数组:

var leapYearDays = [];// will be populated with all dates
var currentDate = new Date(2016, 0, 1);// the date we'll be incrementing
var safety = 0;// helps prevent infinite looping during development

while(safety < 400 && currentDate.getFullYear() == 2016) {
  leapYearDays.push(formatMth(currentDate));
  currentDate.setDate(currentDate.getDate() + 1);
  safety++;
}

x.domain(leapYearDays);// apply as the x domain

更新了blockbuilder here