getAggByInterval = function (start, end, data) {
if (data.length == 0) {
return [];
}
var agg_times = new Array();
var tmp = start;
while (tmp <= end) {
agg_times.push(tmp);
tmp = tmp.add(15, "minutes");
}
const all_times = [
...new Set(
Array.prototype.concat(
data.map((d) => d.startDate),
data.map((d) => d.endDate.add(1, "second")),
agg_times
)
)
].sort();
var x = new Array();
var first_match = 0;
for (var d in data) {
var found_first_match = false;
for (var t = first_match; t < all_times.length; t++) {
if (data[d].startDate < all_times[t] && all_times[t] <= data[d].endDate) {
if (!found_first_match) {
// console.log("found first match at", t);
first_match = t;
found_first_match = true;
}
var startDate = data[d].startDate;
var endDate = all_times[t];
if (t > 0) {
if (data[d].startDate < all_times[t - 1]) {
var startDate = all_times[t - 1];
}
}
var endDate = all_times[t].subtract(1, "second");
var endDate = all_times[t].subtract(1, "second");
x.push({
...data[d],
startDate: startDate,
endDate: endDate,
value:
(((endDate - startDate) / 1000 + 1) /
((data[d].endDate - data[d].startDate) / 1000 + 1)) *
data[d].value
});
} else if (
data[d].startDate < all_times[t - 1] &&
all_times[t - 1] <= data[d].endDate
) {
// console.log("catching hanging times");
var startDate = all_times[t - 1];
var endDate = data[d].endDate;
x.push({
...data[d],
startDate: startDate,
endDate: endDate,
value:
(((endDate - startDate) / 1000 + 1) /
((data[d].endDate - data[d].startDate) / 1000 + 1)) *
data[d].value
});
} else if (all_times[t] > data[d].endDate) {
// console.log("breaking");
break;
}
}
}
// add the aggTime to each row we just created
for (var d in x) {
for (var i = 0; i < agg_times.length - 1; i++) {
if (Math.abs(x[d].startDate - agg_times[i]) < 1000) {
x[d].aggTime = agg_times[i];
} else if (
x[d].startDate > agg_times[i] &&
x[d].endDate < agg_times[i + 1]
) {
x[d].aggTime = agg_times[i];
}
}
}
const y = x.filter((d) => d.aggTime != null);
// to compute the rank by hand, first sort like;
// grouperArray.sort((a, b) => a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize
// then iterate over, if prev value != current value, set 1 and increment from there
// to roll up, loop over and create a fresh data structure
// keep rolling sum (and count) adding up, if prev value != current value then append to that
// new data structure and reset rolling values
const dt = aq.from(y);
const obj = dt
.groupby("startDate")
.orderby("source")
.filter((d) => op.rank() === 1)
.groupby("aggTime")
.rollup({
value: (d) => op.sum(d.value),
count: (d) => op.count()
})
.orderby("aggTime")
.objects();
return obj;
}