Commit bd6e2d6c by Torkel Ödegaard

Merge branch 'master' into external-plugins

parents df0bc7bb 9d1906d3
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
* **dashboard**: fix for collapse row by clicking on row title, fixes [#3065](https://github.com/grafana/grafana/issues/3065) * **dashboard**: fix for collapse row by clicking on row title, fixes [#3065](https://github.com/grafana/grafana/issues/3065)
* **influxdb**: fix for relative time ranges `last x months` and `last x years`, fixes [#3067](https://github.com/grafana/grafana/issues/3067) * **influxdb**: fix for relative time ranges `last x months` and `last x years`, fixes [#3067](https://github.com/grafana/grafana/issues/3067)
* **graph**: layout fix for color picker when right side legend was enabled, fixes [#3093](https://github.com/grafana/grafana/issues/3093) * **graph**: layout fix for color picker when right side legend was enabled, fixes [#3093](https://github.com/grafana/grafana/issues/3093)
* **elasticsearch**: disabling elastic query (via eye) caused error, fixes [#3300](https://github.com/grafana/grafana/issues/3300)
# 2.5 (2015-10-28) # 2.5 (2015-10-28)
......
...@@ -27,7 +27,7 @@ export class TablePanelCtrl { ...@@ -27,7 +27,7 @@ export class TablePanelCtrl {
var panelDefaults = { var panelDefaults = {
targets: [{}], targets: [{}],
transform: 'timeseries_to_rows', transform: 'timeseries_to_rows',
pageSize: 50, pageSize: null,
showHeader: true, showHeader: true,
styles: [ styles: [
{ {
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
Pagination (Page size) Pagination (Page size)
</li> </li>
<li> <li>
<input type="number" class="input-small tight-form-input" placeholder="50" <input type="number" class="input-small tight-form-input" placeholder="100"
empty-to-null ng-model="panel.pageSize" ng-change="render()" ng-model-onblur> empty-to-null ng-model="panel.pageSize" ng-change="render()" ng-model-onblur>
</li> </li>
<li class="tight-form-item"> <li class="tight-form-item">
......
...@@ -38,7 +38,7 @@ export function tablePanelEditor() { ...@@ -38,7 +38,7 @@ export function tablePanelEditor() {
scope.updateColumnsMenu = function(data) { scope.updateColumnsMenu = function(data) {
scope.columnsMenu = transformers[scope.panel.transform].getColumns(data); scope.columnsMenu = transformers[scope.panel.transform].getColumns(data);
scope.showColumnOptions = scope.columnsMenu.length > 0; scope.showColumnOptions = true;
}; };
scope.$on('render', function(event, table, rawData) { scope.$on('render', function(event, table, rawData) {
...@@ -51,6 +51,7 @@ export function tablePanelEditor() { ...@@ -51,6 +51,7 @@ export function tablePanelEditor() {
}; };
scope.transformChanged = function() { scope.transformChanged = function() {
scope.panel.columns = [];
scope.updateColumnsMenu(); scope.updateColumnsMenu();
scope.render(); scope.render();
}; };
......
...@@ -45,7 +45,8 @@ export function tablePanel() { ...@@ -45,7 +45,8 @@ export function tablePanel() {
function appendPaginationControls(footerElem) { function appendPaginationControls(footerElem) {
footerElem.empty(); footerElem.empty();
var pageCount = Math.ceil(data.rows.length / panel.pageSize); var pageSize = panel.pageSize || 100;
var pageCount = Math.ceil(data.rows.length / pageSize);
if (pageCount === 1) { if (pageCount === 1) {
return; return;
} }
...@@ -55,18 +56,12 @@ export function tablePanel() { ...@@ -55,18 +56,12 @@ export function tablePanel() {
var paginationList = $('<ul></ul>'); var paginationList = $('<ul></ul>');
// var prevLink = $('<li><a class="table-panel-page-link pointer">«</a></li>');
// paginationList.append(prevLink);
for (var i = startPage; i < endPage; i++) { for (var i = startPage; i < endPage; i++) {
var activeClass = i === scope.pageIndex ? 'active' : ''; var activeClass = i === scope.pageIndex ? 'active' : '';
var pageLinkElem = $('<li><a class="table-panel-page-link pointer ' + activeClass + '">' + (i+1) + '</a></li>'); var pageLinkElem = $('<li><a class="table-panel-page-link pointer ' + activeClass + '">' + (i+1) + '</a></li>');
paginationList.append(pageLinkElem); paginationList.append(pageLinkElem);
} }
// var nextLink = $('<li><a href="#">»</a></li>');
// paginationList.append(nextLink);
footerElem.append(paginationList); footerElem.append(paginationList);
} }
......
...@@ -119,8 +119,9 @@ export class TableRenderer { ...@@ -119,8 +119,9 @@ export class TableRenderer {
} }
render(page) { render(page) {
let startPos = page * this.panel.pageSize; let pageSize = this.panel.pageSize || 100;
let endPos = Math.min(startPos + this.panel.pageSize, this.table.rows.length); let startPos = page * pageSize;
let endPos = Math.min(startPos + pageSize, this.table.rows.length);
var html = ""; var html = "";
for (var y = startPos; y < endPos; y++) { for (var y = startPos; y < endPos; y++) {
......
...@@ -145,7 +145,7 @@ transformers['json'] = { ...@@ -145,7 +145,7 @@ transformers['json'] = {
var names: any = {}; var names: any = {};
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
var series = data[i]; var series = data[i];
if (series.type === 'docs') { if (series.type !== 'docs') {
continue; continue;
} }
......
...@@ -163,11 +163,10 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -163,11 +163,10 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
var payload = ""; var payload = "";
var target; var target;
var sentTargets = []; var sentTargets = [];
var headerAdded = false;
for (var i = 0; i < options.targets.length; i++) { for (var i = 0; i < options.targets.length; i++) {
target = options.targets[i]; target = options.targets[i];
if (target.hide) {return;} if (target.hide) {continue;}
var queryObj = this.queryBuilder.build(target); var queryObj = this.queryBuilder.build(target);
var esQuery = angular.toJson(queryObj); var esQuery = angular.toJson(queryObj);
...@@ -176,12 +175,9 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -176,12 +175,9 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
luceneQuery = luceneQuery.substr(1, luceneQuery.length - 2); luceneQuery = luceneQuery.substr(1, luceneQuery.length - 2);
esQuery = esQuery.replace("$lucene_query", luceneQuery); esQuery = esQuery.replace("$lucene_query", luceneQuery);
if (!headerAdded) { var searchType = queryObj.size === 0 ? 'count' : 'query_then_fetch';
var searchType = queryObj.size === 0 ? 'count' : 'query_then_fetch'; var header = this.getQueryHeader(searchType, options.range.from, options.range.to);
var header = this.getQueryHeader(searchType, options.range.from, options.range.to); payload += header + '\n';
payload += header + '\n';
headerAdded = true;
}
payload += esQuery + '\n'; payload += esQuery + '\n';
sentTargets.push(target); sentTargets.push(target);
......
...@@ -86,20 +86,71 @@ function (_, queryDef) { ...@@ -86,20 +86,71 @@ function (_, queryDef) {
} }
}; };
ElasticResponse.prototype.processAggregationDocs = function(esAgg, aggDef, target, docs, props) {
var metric, y, i, bucket, metricName, doc;
for (i = 0; i < esAgg.buckets.length; i++) {
bucket = esAgg.buckets[i];
doc = _.defaults({}, props);
doc[aggDef.field] = bucket.key;
for (y = 0; y < target.metrics.length; y++) {
metric = target.metrics[y];
switch(metric.type) {
case "count": {
metricName = this._getMetricName(metric.type);
doc[metricName] = bucket.doc_count;
break;
}
case 'extended_stats': {
for (var statName in metric.meta) {
if (!metric.meta[statName]) {
continue;
}
var stats = bucket[metric.id];
// add stats that are in nested obj to top level obj
stats.std_deviation_bounds_upper = stats.std_deviation_bounds.upper;
stats.std_deviation_bounds_lower = stats.std_deviation_bounds.lower;
metricName = this._getMetricName(statName);
doc[metricName] = stats[statName];
}
break;
}
default: {
metricName = this._getMetricName(metric.type);
doc[metricName] =bucket[metric.id].value;
break;
}
}
}
docs.push(doc);
}
};
// This is quite complex // This is quite complex
// neeed to recurise down the nested buckets to build series // neeed to recurise down the nested buckets to build series
ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, props) { ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, docs, props, depth) {
var bucket, aggDef, esAgg, aggId; var bucket, aggDef, esAgg, aggId;
var maxDepth = target.bucketAggs.length-1;
for (aggId in aggs) { for (aggId in aggs) {
aggDef = _.findWhere(target.bucketAggs, {id: aggId}); aggDef = _.findWhere(target.bucketAggs, {id: aggId});
esAgg = aggs[aggId]; esAgg = aggs[aggId];
if (!aggDef) { if (!aggDef) {
continue; continue;
} }
if (aggDef.type === 'date_histogram') { if (depth === maxDepth) {
this.processMetrics(esAgg, target, seriesList, props); if (aggDef.type === 'date_histogram') {
this.processMetrics(esAgg, target, seriesList, props);
} else {
this.processAggregationDocs(esAgg, aggDef, target, docs, props);
}
} else { } else {
for (var nameIndex in esAgg.buckets) { for (var nameIndex in esAgg.buckets) {
bucket = esAgg.buckets[nameIndex]; bucket = esAgg.buckets[nameIndex];
...@@ -109,7 +160,7 @@ function (_, queryDef) { ...@@ -109,7 +160,7 @@ function (_, queryDef) {
} else { } else {
props["filter"] = nameIndex; props["filter"] = nameIndex;
} }
this.processBuckets(bucket, target, seriesList, props); this.processBuckets(bucket, target, seriesList, docs, props, depth+1);
} }
} }
} }
...@@ -217,13 +268,18 @@ function (_, queryDef) { ...@@ -217,13 +268,18 @@ function (_, queryDef) {
var aggregations = response.aggregations; var aggregations = response.aggregations;
var target = this.targets[i]; var target = this.targets[i];
var tmpSeriesList = []; var tmpSeriesList = [];
var docs = [];
this.processBuckets(aggregations, target, tmpSeriesList, {}); this.processBuckets(aggregations, target, tmpSeriesList, docs, {}, 0);
this.nameSeries(tmpSeriesList, target); this.nameSeries(tmpSeriesList, target);
for (var y = 0; y < tmpSeriesList.length; y++) { for (var y = 0; y < tmpSeriesList.length; y++) {
seriesList.push(tmpSeriesList[y]); seriesList.push(tmpSeriesList[y]);
} }
if (seriesList.length === 0 && docs.length > 0) {
seriesList.push({target: 'docs', type: 'docs', datapoints: docs});
}
} }
} }
......
...@@ -10,7 +10,7 @@ function (angular) { ...@@ -10,7 +10,7 @@ function (angular) {
ElasticQueryBuilder.prototype.getRangeFilter = function() { ElasticQueryBuilder.prototype.getRangeFilter = function() {
var filter = {}; var filter = {};
filter[this.timeField] = {"gte": "$timeFrom", "lte": "$timeTo", "format": "epoch_millis"}; filter[this.timeField] = {"gte": "$timeFrom", "lte": "$timeTo"};
return filter; return filter;
}; };
...@@ -127,7 +127,6 @@ function (angular) { ...@@ -127,7 +127,6 @@ function (angular) {
"interval": this.getInterval(aggDef), "interval": this.getInterval(aggDef),
"field": this.timeField, "field": this.timeField,
"min_doc_count": 0, "min_doc_count": 0,
"format": "epoch_millis",
"extended_bounds": { "min": "$timeFrom", "max": "$timeTo" } "extended_bounds": { "min": "$timeFrom", "max": "$timeTo" }
}; };
break; break;
......
...@@ -411,6 +411,51 @@ describe('ElasticResponse', function() { ...@@ -411,6 +411,51 @@ describe('ElasticResponse', function() {
}); });
}); });
describe('No group by time', function() {
beforeEach(function() {
targets = [{
refId: 'A',
metrics: [{type: 'avg', id: '1'}, {type: 'count' }],
bucketAggs: [{id: '2', type: 'terms', field: 'host'}],
}];
response = {
responses: [{
aggregations: {
"2": {
buckets: [
{
"1": { value: 1000},
key: "server-1",
doc_count: 369,
},
{
"1": { value: 2000},
key: "server-2",
doc_count: 200,
},
]
}
}
}]
};
result = new ElasticResponse(targets, response).getTimeSeries();
});
it.only('should return table', function() {
expect(result.data.length).to.be(1);
expect(result.data[0].type).to.be('docs');
expect(result.data[0].datapoints.length).to.be(2);
expect(result.data[0].datapoints[0].host).to.be("server-1");
expect(result.data[0].datapoints[0].Average).to.be(1000);
expect(result.data[0].datapoints[0].Count).to.be(369);
expect(result.data[0].datapoints[1].host).to.be("server-2");
expect(result.data[0].datapoints[1].Average).to.be(2000);
});
});
describe('Raw documents query', function() { describe('Raw documents query', function() {
beforeEach(function() { beforeEach(function() {
targets = [{ refId: 'A', metrics: [{type: 'raw_document', id: '1'}], bucketAggs: [] }]; targets = [{ refId: 'A', metrics: [{type: 'raw_document', id: '1'}], bucketAggs: [] }];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment