summaryrefslogtreecommitdiff
path: root/jrrd.js
blob: 44fdb95894ad3fcc5c1bd1b670a05747b7ab71b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

if(typeof jrrd == 'undefined') {
    var jrrd = {};
}

jrrd.downloadBinary = function(url) {
    var d = new MochiKit.Async.Deferred();

    $.ajax({
        url: url,
        dataType: 'text',
        cache: false,
        beforeSend: function(request) {
            try {
                request.overrideMimeType('text/plain; charset=x-user-defined');
            } catch(e) {
                // IE doesn't support overrideMimeType
            }
        },
        success: function(data) {
            try {
                d.callback(new BinaryFile(data));
            } catch(e) {
                d.errback(e);
            }
        },
        error: function(xhr, textStatus, errorThrown) {
            // Special case for IE which handles binary data slightly
            // differently.
            if(textStatus == 'parsererror') {
                if (typeof xhr.responseBody != 'undefined') {
                    return this.success(xhr.responseBody);
                }
            }
            d.errback(new Error(xhr.status));
        }
    });
    return d;
};


jrrd.RrdQuery = function(rrd) {
    this.rrd = rrd;
};

jrrd.RrdQuery.prototype.getData = function(startTime, endTime, dsId) {
    var startTimestamp = startTime.getTime()/1000;
    var endTimestamp = endTime.getTime()/1000;

    if(dsId == null) {
        dsId = 0;
    }
    var ds = this.rrd.getDS(dsId);

    var consolidationFunc = 'AVERAGE';
    var lastUpdated = this.rrd.getLastUpdate();

    var bestRRA = null;
    for(var i=0; i<this.rrd.getNrRRAs(); i++) {
        // Look through all RRAs looking for the most suitable
        // data resolution.
        var rra = this.rrd.getRRA(i);

        if(rra.getCFName() != consolidationFunc) {
            continue;
        }
        bestRRA = rra;
        var step = rra.getStep();
        var rraRowCount = rra.getNrRows();
        var firstUpdated = lastUpdated - (rraRowCount - 1) * step;
        if(firstUpdated <= startTimestamp) {
            break;
        }
    }

    if(!bestRRA) {
        throw new Error('Unrecognised consolidation function: ' + consolidationFunc);
    }

    startRow = rraRowCount - parseInt((lastUpdated - startTimestamp)/step);
    endRow = rraRowCount - parseInt((lastUpdated - endTimestamp)/step);

    flotData = [];
    timestamp = firstUpdated + (startRow - 1) * step;
    dsIndex = ds.getIdx();
    for (var i=startRow; i<=endRow; i++) {
        var val = bestRRA.getEl(i, dsIndex);
        flotData.push([timestamp*1000.0, val]);
        timestamp += step;
    }
    return {label: ds.getName(), data: flotData};
};


jrrd.RrdQueryRemote = function(url) {
    this.url = url;
    this.rrd = null;
};

jrrd.RrdQueryRemote.prototype.getData = function(startTime, endTime) {
    var endTimestamp = endTime.getTime()/1000;

    var d, self = this;
    if(!this.rrd || this.rrd.getLastUpdate() < endTimestamp) {
        d = jrrd.downloadBinary(this.url)
                .addCallback(
                    function(binary) {
                        var rrd = new RRDFile(binary);
                        self.rrd = rrd;
                        return rrd;
                    });
    } else {
        d = new MochiKit.Async.Deferred()
        d.callback(this.rrd);
    }

    d.addCallback(
        function(rrd) {
            return new jrrd.RrdQuery(rrd).getData(startTime, endTime);
        });

    return d;
};