[英]Browser hangs when parsing dates
當我使用虛擬數據作為日期時,即當我僅使用數年時,我已經成功地使這種可視化(小倍數的堆積區域圖表)工作,形式略有不同。 但是,當我使用這樣的實際日期時,這是有問題的:
Record,Code,2008-1-1,2008-2-1,2008-3-1,2008-4-1,2008-5-1,2008-6-1,2008-7-1...
而不是這個虛擬數據,工作正常
Record,Code,1895,1896,1897,1898,1899,1900,1901...
當我使用完整日期時,瀏覽器會掛起; 沒有錯誤消息。 我之前已修復過解析錯誤,但這個錯誤似乎超出了我的能力范圍。
這是不工作的Plunker: https ://plnkr.co/edit/fOlpxo648OyCSM7Sq8ak ? p = preview另一個Plunker,一個實際加載,但使用虛擬數據,在這個問題的底部。
這段代碼似乎特別成問題:
function createDatesArr(start, end) {
var arr = [];
for (var i = start; i <= end; i++ ) {
arr.push((i)); // arr.push(String(i));
}
return arr;
}
在稍微不同的形式,我將收到一條錯誤消息,“日期”尚未定義。 我試圖用以下代碼解決這個問題:
var dateFormat = d3.time.format("%Y-%m-%d");
var startDate = new Date('2008-1-1');
var endDate = new Date ('2017-12-1');
var dates = createDatesArr(startDate, endDate);
或者像這樣:
var dateFormat = d3.time.format("%Y-%m-%d");
var startYear = "2008-1-1";
var endYear = "2017-12-1";
var dates = createYearsArr(startYear, endYear);
或者像這樣:
var dateFormat = d3.time.format("%Y-%m-%d");
var startDate = d3.min(dataset, function(d) { return d.Date; });
var endDate = d3.max(dataset, function(d) { return d.Date; });
var dates = createDatesArr(startDate, endDate);
或者,通過定義“日期”,如下所示:
d3.csv(dataPath, function(data) {
var dates = d3.keys(data[0]).slice(1);
data = data.filter(function(d) {
return true;
});
var dates = d3.keys(data[0]).slice(1);
這些都沒有奏效,但我希望有人可以幫我解決這個問題。
這是另一個真正有效的Plunker,它展示了我最終想要實現的目標,盡管使用虛擬數據(僅限年份)來表示日期: http ://plnkr.co/edit/jRC8iQg2kdtlZWtGE020?p = preview
請幫忙。
你是對的,你在這段代碼中的問題
function createDatesArr(start, end) {
var arr = [];
for (var i = start; i <= end; i++ ) {
arr.push((i)); // arr.push(String(i));
}
return arr;
}
更精確的是 - i++
;
看下面的圖片,變量i
是一個以毫秒為單位的日期。 在每次循環迭代后,將它增加一毫秒。 但是,我可以看到你的數據點之間是一個月。
Record,Code,2008-1-1,2008-2-1,2008-3-1,2008-4-1,2008-5-1,2008-6-1,2008-7-1...
所以你應該在每次循環迭代后增加i
一個月來解決你的問題。
您可以使用d3.time.month.offset
執行此d3.time.month.offset
:
for (var i = start; i <= end; i = d3.time.month.offset(i, 1)) {
arr.push((i));
}
在那之后,你應該刪除dateFormat(...)
因為數據項它是完全有效的javascript日期並重寫了transformData
函數,看看你的plnkr的叉子 (看起來不正確應用顏色,我想你可以解決它,但否則它的工作原理)。
首先在這個片段中:
function createDatesArr(start, end) {
var arr = [];
for (var i = start; i <= end; i++ ) {
arr.push((i)); // arr.push(String(i));
}
return arr;
}
使用i ++將無法正常工作,因為您嘗試在有效表達式上使用后綴操作。 你不能用這個來跳過這些日子:
( Fri Dec 01 2017 00:00:00 GMT+0400 (+04) ) ++
如果你試圖在diapason中獲得所有月份,你可以使用下面這個簡單的片段:
function createDatesArr(startDate, endDate) {
var _start = new Date(startDate),
_end = new Date(endDate),
_result = [];
while(_start < _end){
_result.push(_start);
// going next
var _newDate = _start.setDate(_start.getDate() + 1);
_start = new Date(_newDate);
}
return _result;
}
只是為了提供這個問題的其他信息,已經有兩個好的答案:你不需要那個可怕的createDatesArr
函數(這是你問題的原因)。
使用time.ticks([interval])
,您可以使用time.ticks([interval])
輕松獲取開始日期和結束日期之間的日期數組,其中包括:
從比例域中返回代表日期。 返回的刻度值均勻間隔(大部分),具有合理的值(例如每天午夜),並且保證在域的范圍內。
這不僅比你的功能更安全,而且它也是慣用的 D3,這意味着其目的很容易被其他D3程序員理解。
這是一個使用v3的演示,這是你的版本。 我將結束日期更改為2009而不是2017,因此我們在控制台中的日期會更少。 核實:
var startDate = new Date('2008-1-1'); var endDate = new Date('2009-6-1'); var dates = d3.time.scale() .domain([startDate, endDate]) .ticks(d3.time.months, 1); console.log(dates)
<script src="https://d3js.org/d3.v3.min.js"></script>
實際上,這可以更短,只有一行,減少時間尺度,只使用d3.time.months
或d3.time.month.range
:
var dates = d3.time.month.range(new Date('2008-1-1'), new Date('2009-6-1'), 1) console.log(dates)
<script src="https://d3js.org/d3.v3.min.js"></script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.