Skip to content

Commit

Permalink
evol(histogram): adding SUM aggregate function
Browse files Browse the repository at this point in the history
evol: adding the SUM aggregate function of "value field" in the mode "values"
fix(histogram): view all the values in the tooltip in multiserie  in the case of an intersection
  • Loading branch information
sju66 committed Sep 30, 2015
1 parent 6d07515 commit ae3e405
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/app/panels/histogram/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
<label class="small">Group By Field <tip>This field must be a single value field. Leave blank if you do not want to group the result.</tip></label>
<input ng-change="set_refresh(true)" placeholder="Optional" bs-typeahead="fields.list" type="text" class="input-small" ng-model="panel.group_field">
</div>
<div class="span3">
<label class="small">SUM the group's values <tip>The point value (Y) is the sum of value field in the group</tip></label>
<input type="checkbox" ng-model="panel.sum_value" ng-checked="panel.sum_value">
</div>
<!-- <div class="span3">
<label class="small">Max Rows/Group <tip>Specify the number of results to return for each group.</tip></label>
<input ng-change="set_refresh(true)" placeholder="10" type="number" class="input-small" ng-model="panel.group_limit">
Expand Down
95 changes: 86 additions & 9 deletions src/app/panels/histogram/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
max_rows : 100000, // maximum number of rows returned from Solr (also use this for group.limit to simplify UI setting)
value_field : null,
group_field : null,
sum_value : false,
auto_int : true,
resolution : 100,
interval : '5m',
Expand Down Expand Up @@ -199,7 +200,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {

var request = $scope.sjs.Request().indices(dashboard.indices[segment]);
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);


$scope.panel.queries.query = "";
// Build the query
Expand All @@ -210,6 +211,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
);

var facet = $scope.sjs.DateHistogramFacet(id);

if($scope.panel.mode === 'count') {
facet = facet.field(filterSrv.getTimeField());
} else {
Expand All @@ -221,7 +223,6 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
}
facet = facet.interval(_interval).facetFilter($scope.sjs.QueryFilter(query));
request = request.facet(facet).size(0);

});

// Populate the inspector panel
Expand Down Expand Up @@ -347,6 +348,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {

for (var j = 0; j < groups.length; j++) { // jshint ignore: line
var docs = groups[j].doclist.docs;
var numFound = groups[j].doclist.numFound;
var group_time_series = new timeSeries.ZeroFilled({
interval: _interval,
start_date: _range && _range.from,
Expand All @@ -359,11 +361,17 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
for (var k = 0; k < docs.length; k++) {
entry_time = new Date(docs[k][time_field]).getTime(); // convert to millisec
entry_value = docs[k][$scope.panel.value_field];
group_time_series.addValue(entry_time, entry_value);
if($scope.panel.sum_value) {
group_time_series.sumValue(entry_time, entry_value);
}else {
group_time_series.addValue(entry_time, entry_value);
}

hits += 1;
$scope.hits += 1;
}


$scope.data[j] = {
// info: querySrv.list[id],
// Need to define chart info here according to the results, cannot use querySrv.list[id]
Expand All @@ -376,6 +384,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
hits: hits
};
}

} else { // Group By Field is not specified
entries = results[index].response.docs;
for (var j = 0; j < entries.length; j++) { // jshint ignore: line
Expand Down Expand Up @@ -598,7 +607,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
scope.plot = $.plot(elem, scope.data, options);
} catch(e) {
// TODO: Need to fix bug => "Invalid dimensions for plot, width = 0, height = 200"
// console.log(e);
console.log(e);
}
}

Expand Down Expand Up @@ -634,12 +643,80 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
} else {
value = item.datapoint[1];
}

var lnLastValue = value;

var lbPositiveValue = (lnLastValue>0);

var lsItemTT = group + dashboard.numberWithCommas(value) + " @ " + (scope.panel.timezone === 'utc'? moment.utc(item.datapoint[0]).format('MM/DD HH:mm:ss') : moment(item.datapoint[0]).format('MM/DD HH:mm:ss'));

var hoverSeries = item.series;
var x = item.datapoint[0],
y = item.datapoint[1];

var lsTT = lsItemTT;
var allSeries = scope.plot.getData();
var posSerie = -1;
for (var i= allSeries.length - 1 ; i>=0; i--) {

//if stack stop at the first positive value
if (scope.panel.stack && lbPositiveValue){
break;
}

var s = allSeries[i];
i = parseInt(i);


if (s == hoverSeries ) {
posSerie = i;
}

//not consider serie "upper" the hover serie
if ( i >= posSerie ){
continue;
}

//search in current serie a point with de same position.
for(var j= 0; j< s.data.length;j++){
var p = s.data[j];
if (p[0] == x ){

if (scope.panel.stack && scope.panel.tooltip.value_type === 'individual' && !isNaN(p[2])) {
value = p[1] - p[2];
} else {
value = p[1];
}

lbPositiveValue = value > 0;

if (! scope.panel.stack && value != lnLastValue){
break;
}

posSerie = i;
lnLastValue = value;


if (s.info.alias || scope.panel.tooltip.query_as_alias) {
group = '<small style="font-size:0.9em;">' +
'<i class="icon-circle" style="color:'+s.color+';"></i>' + ' ' +
(s.info.alias || s.info.query)+
'</small><br>';
} else {
group = kbn.query_color_dot(s.color, 15) + ' ';
}

lsItemTT = group + dashboard.numberWithCommas(value) + " @ " + (scope.panel.timezone === 'utc'? moment.utc(p[0]).format('MM/DD HH:mm:ss') : moment(p[0]).format('MM/DD HH:mm:ss'));
lsTT = lsTT +"</br>"+ lsItemTT;
break;
}
}
}


$tooltip
.html(
group + dashboard.numberWithCommas(value) + " @ " + (scope.panel.timezone === 'utc'? moment.utc(item.datapoint[0]).format('MM/DD HH:mm:ss') : moment(item.datapoint[0]).format('MM/DD HH:mm:ss'))
// group + dashboard.numberWithCommas(value) + " @ " + moment(item.datapoint[0]).format('MM/DD HH:mm:ss')
// group + dashboard.numberWithCommas(value) + " @ " + moment(item.datapoint[0])
)
.html( lsTT )
.place_tt(pos.pageX, pos.pageY);
} else {
$tooltip.detach();
Expand Down
24 changes: 24 additions & 0 deletions src/app/panels/histogram/timeSeries.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,30 @@ function (_, Interval) {
this._cached_times = null;
};

/**
* Add a row and sum the value
* @param {int} time The time for the value, in
* @param {any} value The value at this time
*/
ts.ZeroFilled.prototype.sumValue = function (time, value) {
if (time instanceof Date) {
time = getDatesTime(time);
} else {
time = base10Int(time);
}
if (!isNaN(time)) {

var curValue = 0;
if (!isNaN(this._data[time])){
curValue = this._data[time];
};


this._data[time] = curValue + (_.isUndefined(value) ? 0 : value);
}
this._cached_times = null;
};

/**
* Get an array of the times that have been explicitly set in the series
* @param {array} include (optional) list of timestamps to include in the response
Expand Down

0 comments on commit ae3e405

Please sign in to comment.