Resolved #12 - Add automatic time series downsampling based on maxDataPoints parameter.

This commit is contained in:
Alexander Zobnin
2015-06-29 21:33:31 +03:00
parent c4d2eb5290
commit f7c3e16aa3
2 changed files with 109 additions and 1 deletions

View File

@@ -138,7 +138,17 @@ function (angular, _, kbn) {
}, this);
return $q.all(_.flatten(promises)).then(function (results) {
return { data: _.flatten(results) };
var timeseries_data = _.flatten(results);
var data = _.map(timeseries_data, function (timeseries) {
// Series downsampling
if (timeseries.datapoints.length > options.maxDataPoints) {
var ms_interval = Math.floor((to - from) / options.maxDataPoints) * 1000;
timeseries.datapoints = downsampleSeries(timeseries.datapoints, to, ms_interval);
}
return timeseries;
});
return { data: data };
});
};
@@ -417,3 +427,45 @@ function formatAcknowledges(acknowledges) {
return '';
}
}
/**
* Downsample datapoints series
*
* @param {array} datapoints [[<value>, <unixtime>], ...]
* @param {integer} time_to Panel time to
* @param {integer} ms_interval Interval in milliseconds for grouping datapoints
* @return {array} [[<value>, <unixtime>], ...]
*/
function downsampleSeries(datapoints, time_to, ms_interval) {
var downsampledSeries = new Array();
var timeWindow = {
from: time_to * 1000 - ms_interval,
to: time_to * 1000
};
var points_sum = 0;
var points_num = 0;
var value_avg = 0;
for (var i = datapoints.length - 1; i >= 0; i -= 1) {
if (timeWindow.from < datapoints[i][1] && datapoints[i][1] <= timeWindow.to) {
points_sum += datapoints[i][0];
points_num++;
}
else {
value_avg = points_num ? points_sum / points_num : 0;
downsampledSeries.push([value_avg, timeWindow.to]);
// Shift time window
timeWindow.to = timeWindow.from;
timeWindow.from -= ms_interval;
points_sum = 0;
points_num = 0;
// Process point again
i++;
}
}
return downsampledSeries.reverse();
}

View File

@@ -174,3 +174,59 @@
</div>
</div>
<section class="grafana-metric-options">
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item tight-form-item-icon">
<i class="fa fa-wrench"></i>
</li>
<li class="tight-form-item">
Max data points
</li>
<li>
<input type="text"
class="input-mini tight-form-input"
ng-model="panel.maxDataPoints"
bs-tooltip="'Override max data points, automatically set to graph width in pixels.'"
data-placement="right"
ng-model-onblur ng-change="get_data()"
spellcheck='false'
placeholder="auto">
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item tight-form-item-icon">
<i class="fa fa-info-circle"></i>
</li>
<li class="tight-form-item">
<a ng-click="toggleEditorHelp(1)" bs-tooltip="'click to show helpful info'" data-placement="bottom">
max data points
</a>
</li>
</ul>
<div class="clearfix"></div>
</div>
</section>
<div class="editor-row">
<div class="pull-left" style="margin-top: 30px;">
<div class="grafana-info-box span6" ng-if="editorHelpIndex === 1">
<h5>Max data points</h5>
<ul>
<li>Every graphite request is issued with a maxDataPoints parameter</li>
<li>Graphite uses this parameter to consolidate the real number of values down to this number</li>
<li>If there are more real values, then by default they will be consolidated using averages</li>
<li>This could hide real peaks and max values in your series</li>
<li>You can change how point consolidation is made using the consolidateBy graphite function</li>
<li>Point consolidation will effect series legend values (min,max,total,current)</li>
<li>If you override maxDataPoint and set a high value performance can be severely effected</li>
</ul>
</div>
</div>
</div>