diegodacal
diegodacal

Reputation: 97

Javascript adding dates that don't exist on a series

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

Answers (1)

dreyescat
dreyescat

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

Related Questions