我正在开发一个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;
}
显然,根据您需要的规模,可以定制数年,数月,数天,数小时等.