-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtimestamp-binning.js
126 lines (114 loc) · 3.71 KB
/
timestamp-binning.js
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
124
125
126
#!/bin/env node
"use strict";
//TODO:
//rework filtering of bursts
//Update documentation to npm and github
//Publish article on blog ;-)
module.exports = function(evalPeriodString, binSizeString, excludeBursts) {
if (typeof evalPeriodString === "undefined") evalPeriodString = "week";
if (typeof binSizeString === "undefined") binSizeString = "hour";
//the parameter excludeBursts allows to disregard any additional timestamps
//for a bin that had already seen a timestamp. This makes the histrogram
//to only have values 0 or 1.
if (typeof excludeBursts === "undefined") excludeBursts = false;
//the week starts on Monday at 00:00 am
//calculate the reference date (the next Monday based on the current date)
var now = new Date();
var oneDay = 1000*60*60*24;
var dayOfWeek = now.getDay();
var day = now.getDate();
var month = now.getMonth();
var year = now.getFullYear();
var refDate = new Date((new Date(year, month, day, 0,0,0,0)).getTime() + oneDay * (8-dayOfWeek));
var binSize = 3600000; //in msec, default: 1000 * 60 * 60 = 1 hour
//day, hour, minute, second
switch (binSizeString.toLowerCase()) {
case "day":
binSize = 86400000; //1000 * 60 * 60 * 24 = 1 day
break;
case "hour":
binSize = 3600000; //1000 * 60 * 60 = 1 hour
break;
case "minute":
binSize = 60000; //1000 * 60 = 1 minute
break;
case "second":
binSize = 1000; //1000 = 1 second
break;
}
var evalPeriod = 604800000 / binSize; //default: 1 week = 1000*60*60*24*7
//evalPeriod also corresponds to the number of possible bins
//week, day, hour
switch (evalPeriodString.toLowerCase()) {
case "year":
evalPeriod = 31536000000 / binSize;
break;
case "month":
evalPeriod = 2592000000 / binSize;
break;
case "week":
evalPeriod = 604800000 / binSize;
break;
case "day":
evalPeriod = 86400000 / binSize;
break;
case "hour":
evalPeriod = 3600000 / binSize;
break;
}
//initialize histogram array and object:
this.hist_array = [];
this.hist_object = [];
for (var i = 0; i < evalPeriod; i++) {
this.hist_array[i] = 0;
this.hist_object[i] = {
timestampbin: new Date(refDate.getTime() + i * binSize),
count: 0
};
}
//public properties and functions:
return {
hist_array: this.hist_array,
hist_object: this.hist_object,
getBin : function (date) {
//bins start at 0
return Math.floor(evalPeriod - ((refDate.getTime() - date.getTime()) / binSize) % evalPeriod);
},
addTimestamp : function (date) {
//add one timestamp
var bin = Math.floor(evalPeriod - ((refDate.getTime() - date.getTime()) / binSize) % evalPeriod);
if (excludeBursts) {
this.hist_array[bin] = 1;
this.hist_object[bin].count = 1;
} else {
this.hist_array[bin]++;
this.hist_object[bin].count++;
}
},
addTimestamps : function (dates, excludeBurstsOnce) {
//add an array of timestamps
//excludeBurstsOnce allowes to only count one occurence
//in each bin for the addition of this dates array
if (typeof excludeBurstsOnce === "undefined") {
excludeBurstsOnce = false;
}
var updated = []; //used to keep track of updated bins in histogram.
for (var i in dates) {
var bin = Math.floor(evalPeriod - ((refDate.getTime() - dates[i].getTime()) / binSize) % evalPeriod);
if (excludeBursts) {
this.hist_array[bin] = 1;
this.hist_object[bin].count = 1;
} else {
if (excludeBurstsOnce && !updated[bin]) {
this.hist_array[bin]++;
this.hist_object[bin].count++;
updated[bin] = true; //mark bin as updated => do not increment again
} else if (!excludeBurstsOnce) {
this.hist_array[bin]++;
this.hist_object[bin].count++;
}
}
}
}
};
};