D3 时区偏移量转移到前一天
D3 timezone offset shifting to previous day
详情
- 初始时间戳是来自服务器的 Unix 编码的 EST 日期(没有时间)。
- NVD3(D3 分支)正在渲染带有焦点栏(画笔)的堆叠面积图,以允许导航数据。
问题
- 图表显示本地时间的 x 轴,当您偏移时,它落在不同的日期。
- 画笔(焦点图)正在处理以小时为单位的时间线,尽管事实上任何时间戳中都没有使用小时。
期望的解决方案
- 图表应以 EST 显示,忽略本地 TZ。
- 刷机应该设置天数块,而不是设置小时数,应该是美国东部时间。
图表初始化代码
function createStackedTimeSeriesChart(chartName, data, margins, tableName, ajaxPath, filterType, timeColumn, statuses, document_types, showLegend, percentage) {
if(typeof(data) == 'undefined') {
$('#' + chartName).parent().text('no data found');
return;
}
if(data.length == 0) {
$('#' + chartName).parent().text('no data found');
return;
}
try {
var maxValue = data[0]['values'][0]['x'];
var minValue = maxValue;
for(var i = 0; i < data.length; i++) {
for(var v = 0; v < data[i]['values'].length; v++) {
if(data[i]['values'][v]['x'] > maxValue) maxValue = data[i]['values'][v]['x'];
if(data[i]['values'][v]['x'] < minValue) minValue = data[i]['values'][v]['x'];
data[i]['values'][v]['x'] = new Date(data[i]['values'][v]['x']);
}
}
var chart;
nv.addGraph(function() {
chart = nv.models.stackedAreaWithFocusChart()
.useInteractiveGuideline(true)
.x(function(d) { return d['x'] })
.y(function(d) { return d['y'] })
.controlLabels({stacked: "Stacked", expanded: "Expanded"})
.duration(300)
.color(function(d){return getChartColorByValue(d)})
.showControls(false)
.showLegend(showLegend)
.clipEdge(false);
var chart_wrapper = new Chart(chartName, chart, tableName, ajaxPath, data, filterType, timeColumn, statuses, document_types);
chart_wrapper.oldest_date = moment(maxValue);
chart_wrapper.dataTable.percentage = percentage;
chart.interactiveLayer.tooltip.contentGenerator(tooltipContentGenerator(chart_wrapper));
var extentPeriod = chart_wrapper.getCurrentYearSpan();
chart.brushExtent([extentPeriod.begDate, extentPeriod.endDate]);
chart.xAxis.tickFormat(function(d) { return d3.time.format('%d/%m/%Y') (new Date(d)) });
chart.x2Axis.tickFormat(function(d) { return d3.time.format('%d/%m/%Y') (new Date(d)) });
chart.xAxis.axisLabel("date");
chart.yAxis.tickFormat(d3.format(',.0f'));
chart.y2Axis.tickFormat(d3.format(',.4f'));
chart.legend.vers('furious');
chart.legend.margin(margins);
atleastOnePoint = false;
d3.select('#' + chartName)
.datum(data)
.transition().duration(1000)
.call(chart)
.each('start', function() {
setTimeout(function() {
d3.selectAll('#' + chartName + ' *').each(function() {
if(this.__transition__)
this.__transition__.duration = 1;
})
}, 0)
});
nv.utils.windowResize(chart.update);
charts_array[chartName] = chart_wrapper;
chart.update();
chart.dispatch.on('renderEnd', function(e) { chart_wrapper.refreshDataTable(); });
return chart;
});
} catch(e) {
$('#' + chartName).parent().text(e);
}
}
我已经解决了我的问题,不再使用 TZ 感知 API,而是切换到日期字符串。
- 服务器转换为所需的 TZ (EST) 并将结果作为日期字符串传递。
- 客户端主要使用moment JS,从日期创建对象
带本地 TZ 的字符串。时间没有意义,我只用日期。
- 对于带有本地 TZ 集的 NVD3,时刻对象转换为 JS 日期对象。
- 为了只获取日期刷范围,我将其转换为时刻,然后将开始日期四舍五入到第二天(如果小于一天的开始)。我掉到地板上的结束日期。
- 当使用新的日期范围调用服务器时,我转换为日期字符串(碰巧一直是 EST)。
事实证明,这个解决方案比我之前尝试做的更容易遵循。
详情
- 初始时间戳是来自服务器的 Unix 编码的 EST 日期(没有时间)。
- NVD3(D3 分支)正在渲染带有焦点栏(画笔)的堆叠面积图,以允许导航数据。
问题
- 图表显示本地时间的 x 轴,当您偏移时,它落在不同的日期。
- 画笔(焦点图)正在处理以小时为单位的时间线,尽管事实上任何时间戳中都没有使用小时。
期望的解决方案
- 图表应以 EST 显示,忽略本地 TZ。
- 刷机应该设置天数块,而不是设置小时数,应该是美国东部时间。
图表初始化代码
function createStackedTimeSeriesChart(chartName, data, margins, tableName, ajaxPath, filterType, timeColumn, statuses, document_types, showLegend, percentage) {
if(typeof(data) == 'undefined') {
$('#' + chartName).parent().text('no data found');
return;
}
if(data.length == 0) {
$('#' + chartName).parent().text('no data found');
return;
}
try {
var maxValue = data[0]['values'][0]['x'];
var minValue = maxValue;
for(var i = 0; i < data.length; i++) {
for(var v = 0; v < data[i]['values'].length; v++) {
if(data[i]['values'][v]['x'] > maxValue) maxValue = data[i]['values'][v]['x'];
if(data[i]['values'][v]['x'] < minValue) minValue = data[i]['values'][v]['x'];
data[i]['values'][v]['x'] = new Date(data[i]['values'][v]['x']);
}
}
var chart;
nv.addGraph(function() {
chart = nv.models.stackedAreaWithFocusChart()
.useInteractiveGuideline(true)
.x(function(d) { return d['x'] })
.y(function(d) { return d['y'] })
.controlLabels({stacked: "Stacked", expanded: "Expanded"})
.duration(300)
.color(function(d){return getChartColorByValue(d)})
.showControls(false)
.showLegend(showLegend)
.clipEdge(false);
var chart_wrapper = new Chart(chartName, chart, tableName, ajaxPath, data, filterType, timeColumn, statuses, document_types);
chart_wrapper.oldest_date = moment(maxValue);
chart_wrapper.dataTable.percentage = percentage;
chart.interactiveLayer.tooltip.contentGenerator(tooltipContentGenerator(chart_wrapper));
var extentPeriod = chart_wrapper.getCurrentYearSpan();
chart.brushExtent([extentPeriod.begDate, extentPeriod.endDate]);
chart.xAxis.tickFormat(function(d) { return d3.time.format('%d/%m/%Y') (new Date(d)) });
chart.x2Axis.tickFormat(function(d) { return d3.time.format('%d/%m/%Y') (new Date(d)) });
chart.xAxis.axisLabel("date");
chart.yAxis.tickFormat(d3.format(',.0f'));
chart.y2Axis.tickFormat(d3.format(',.4f'));
chart.legend.vers('furious');
chart.legend.margin(margins);
atleastOnePoint = false;
d3.select('#' + chartName)
.datum(data)
.transition().duration(1000)
.call(chart)
.each('start', function() {
setTimeout(function() {
d3.selectAll('#' + chartName + ' *').each(function() {
if(this.__transition__)
this.__transition__.duration = 1;
})
}, 0)
});
nv.utils.windowResize(chart.update);
charts_array[chartName] = chart_wrapper;
chart.update();
chart.dispatch.on('renderEnd', function(e) { chart_wrapper.refreshDataTable(); });
return chart;
});
} catch(e) {
$('#' + chartName).parent().text(e);
}
}
我已经解决了我的问题,不再使用 TZ 感知 API,而是切换到日期字符串。
- 服务器转换为所需的 TZ (EST) 并将结果作为日期字符串传递。
- 客户端主要使用moment JS,从日期创建对象 带本地 TZ 的字符串。时间没有意义,我只用日期。
- 对于带有本地 TZ 集的 NVD3,时刻对象转换为 JS 日期对象。
- 为了只获取日期刷范围,我将其转换为时刻,然后将开始日期四舍五入到第二天(如果小于一天的开始)。我掉到地板上的结束日期。
- 当使用新的日期范围调用服务器时,我转换为日期字符串(碰巧一直是 EST)。
事实证明,这个解决方案比我之前尝试做的更容易遵循。