javascript – 如何让D3数据驱动文档在正确的时区显示moment.js日期时间?

我正在开发一个AngularJS单页面应用程序,它使用D3图表来显示在全世界不同时区记录的数据.图表上的时间轴需要以原始时区显示时间.

要绘制的数据是值,时间戳对的数组.时间戳包含其自己的时区信息并以ISO格式编码(例如“2003-12-14T12:00:00.000 08:00”).所以json看起来像这样:

"values": [
   ["2003-12-14T12:00:00.000+08:00", 10],
   ["2003-12-14T13:00:00.000+08:00", 20],
   ["2003-12-14T14:00:00.000+08:00", 30],
   ["2003-12-14T15:00:00.000+08:00", 40],
   ["2003-12-14T16:00:00.000+08:00", 50]
]

然后将时间戳和值添加到对象中,其中时间戳转换为片刻:

data = values[1];
timeStamp = moment.parseZone(values[0]);

然后将这些样品传递给D3进行显示.但是,当它们传递给D3时,时间标记会以本地浏览器时间显示.这不好 – 我无法弄清楚如何让它在正确的时区显示数据.

我尝试使用自定义方法设置xAxis.tickFormat,但传递给它的时间是本地时区中的标准Javascript Date对象.

此外,时区可能会在图表中间发生变化(由于DST),因此无法简单地保持时区偏移的值并进行手动调整.

最佳答案 答案是编写一个计算并返回刻度值的方法,以及类似于刻度格式,如 this link从@LarsKotthoff给出的那样.

最终的代码必须是这样的:

xAxis = d3.svg.axis()
    .scale(xScale)
    .tickValues(calculateTickValue)
    .tickFormat(getTickFormat);

var getTickFormat = function(date){
    var diff = date.format("DD") != previousDate.format("DD");                    
    if (diff){
        previousDate = date;
        return date.format("MMM Do, HH:mm");
    }
    return date.format(tickFormat);
}

var calculateTickValue = function(){
    var startTime = scope.segment.startTime;
    var endTime = scope.segment.endTime;
    var tickValues = [];
    var difference = moment.duration(endTime.diff(startTime));
    var maximumTicks = calculateMaximumTicks(); 
    if (difference.asHours() >= maximumTicks){
       tickValues = calculateHoursTicks(startTime, endTime, maximumTicks);
       tickFormat = "HH:mm";
    }
    else {
        tickValues = caclulateMinutesTicks(startTime, endTime, maximumTicks);
        tickFormat = "HH:mm";
    }

    previousDate = startTime;
    return tickValues;
}

显然,根据您需要的规模,可以定制数年,数月,数天,数小时等.

点赞