Reputation: 97
I have a javascript that reads a JSON object and plots a graph. In my JSON I have a series of ordered dates, but I'm missing some in-between dates that didnt have any elements when it was built. Something like:
[
{
"date": "2014-09-22",
"similar": 1,
"trend": 0
},
{
"date": "2014-09-28",
"similar": 1,
"trend": 0
},
{
"date": "2014-09-29",
"similar": 16,
"trend": 1
},
{
"date": "2014-10-11",
"similar": 3,
"trend": 0
},
{
"date": "2014-10-10",
"similar": 2,
"trend": 0
},
{
"date": "2014-10-16",
"similar": 2,
"trend": 0
},
{
"date": "2014-10-15",
"similar": 1,
"trend": 0
},
{
"date": "2014-10-19",
"similar": 3,
"trend": 0
},
{
"date": "2014-10-18",
"similar": 1,
"trend": 0
},
{
"date": "2014-10-22",
"similar": 1,
"trend": 0
}
]
So, my idea is to plot this information on a graph, adding the dates that don't exist. To plot on a graph I create 3 different arrays, one with the dates, one with similar and one with trend, to be used with a Chart.js. So I created the following script to create the 3 mentioned arrays:
/*plot timeline on chart*/
var d = new Array;
var t = new Array;
var s = new Array;
$.each (timeline, function(i,item){
idt = new Date(item.date);
idt.setDate(idt.getDate()+1);
month = idt.getMonth()+1;
day = idt.getDate();
if (month<10){month = "0" + month;}
if (day<10){day = "0" + day;}
nextdt = new Date();
d.push(item.date);
t.push(item.trend);
s.push(item.similar);
if (i+1 < timeline.length && item.date != timeline[i+1].date && idt!=nextdt){
nextdt = new Date (timeline[i+1].date);
nextdt.setDate(nextdt.getDate()+1);
month = nextdt.getMonth()+1;
day = nextdt.getDate();
if (month<10){month = "0" + month;}
if (day<10){day = "0" + day;}
idt.setDate(idt.getDate()+1);
while(nextdt > idt){
month = (idt.getMonth())+1;
day = idt.getDate();
if (month<10){month = "0" + month;}
if (day<10){day = "0" + day;}
d.push(idt.getFullYear()+'-'+ month +'-'+ day);
t.push(0);
s.push(0);
idt.setDate(idt.getDate()+1);
}
}
});
The problem is that I am having some duplicate dates and in some points it's writing the next day before the day I am in. I'm trying to solve this problem for days and still no success, tried many things and many options, but none of them worked. :( The dates are using the format dd-mm-YYYY, if you take a look at 10-10-2014 you can see a problem.
The three outputs for the above JSON are:
d s t
22/09/2014 1 0
23/09/2014 0 0
24/09/2014 0 0
25/09/2014 0 0
26/09/2014 0 0
27/09/2014 0 0
28/09/2014 1 0
29/09/2014 16 1
30/09/2014 0 0
01/10/2014 0 0
02/10/2014 0 0
03/10/2014 0 0
04/10/2014 0 0
05/10/2014 0 0
06/10/2014 0 0
07/10/2014 0 0
08/10/2014 0 0
09/10/2014 0 0
10/10/2014 0 0
11/10/2014 3 0
10/10/2014 2 0
11/10/2014 0 0
12/10/2014 0 0
13/10/2014 0 0
14/10/2014 0 0
15/10/2014 0 0
16/10/2014 2 0
15/10/2014 1 0
16/10/2014 0 0
17/10/2014 0 0
18/10/2014 0 0
19/10/2014 3 0
18/10/2014 1 0
19/10/2014 0 0
20/10/2014 0 0
21/10/2014 0 0
22/10/2014 0 0
22/10/2014 1 0
Thanks a lot!
Upvotes: 0
Views: 102
Reputation: 13798
I see that your timeline is not in ascending order, and you are assuming it is in your code.
You have
{
"date": "2014-10-11",
"similar": 3,
"trend": 0
}
before
{
"date": "2014-10-10",
"similar": 2,
"trend": 0
},
Trying to stick to your idea of iterating over the timeline
and generating the missing dates, I have refactored a little bit the code to something like this. Of course, it only works if the timeline
is in ascending order by date.
var d = [];
var t = [];
var s = [];
if (timeline.length > 0) {
// Assuming dates are 'yyyy-mm-dd'. Sort by date in ascending order.
timeline.sort(function (s1, s2) {
return s2.date < s1.date;
});
// Adds a new point in the three arrays.
var addSerie = function (date, trend, similar) {
// NOTE: Maybe the way I'm using to get the dd/mm/yyyy is a little bit obscure,
// you can use your way here if you see it more clear.
d.push(date.toISOString().slice(0, 10).split('-').reverse().join('/'));
t.push(trend);
s.push(similar);
}
// Insert the first serie
addSerie(new Date(timeline[0].date), timeline[0].trend, timeline[0].similar);
// Then the rest
for (var i = 1; i < timeline.length; i++) {
var d1 = new Date(timeline[i - 1].date);
d1.setDate(d1.getDate() + 1);
var d2 = new Date(timeline[i].date);
// Generate the empty gap dates starting on the next date
while (d1 < d2) {
addSerie(d1, 0, 0);
d1 = new Date(d1);
d1.setDate(d1.getDate() + 1);
}
addSerie(d2, timeline[i].trend, timeline[i].similar);
}
}
Upvotes: 1