mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Improvement to InfluxDB query editor and function/value column selection, more space efficient, Closes #473
This commit is contained in:
parent
1409065005
commit
af1855601b
@ -9,6 +9,8 @@ vNext
|
|||||||
- improved asset (css/js) build pipeline, added revision to css and js. Will remove issues related
|
- improved asset (css/js) build pipeline, added revision to css and js. Will remove issues related
|
||||||
to the browser cache when upgrading grafana and improve load performance (Fixes #418)
|
to the browser cache when upgrading grafana and improve load performance (Fixes #418)
|
||||||
- Partial support for url encoded metrics when using Graphite datasource (PR #327) - thx @axe-felix
|
- Partial support for url encoded metrics when using Graphite datasource (PR #327) - thx @axe-felix
|
||||||
|
- Improvement to InfluxDB query editor and function/value column selection (Issue #473)
|
||||||
|
- Initial support for filtering (templated queries) for InfluxDB (PR #375) - thx @mavimo
|
||||||
|
|
||||||
# Fixes
|
# Fixes
|
||||||
- Filter option loading when having muliple nested filters now works better.
|
- Filter option loading when having muliple nested filters now works better.
|
||||||
|
@ -11,9 +11,8 @@ function (angular) {
|
|||||||
module.controller('InfluxTargetCtrl', function($scope, $timeout) {
|
module.controller('InfluxTargetCtrl', function($scope, $timeout) {
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
if (!$scope.target.function) {
|
$scope.target.function = $scope.target.function || 'mean';
|
||||||
$scope.target.function = 'mean';
|
$scope.target.column = $scope.target.column || 'value';
|
||||||
}
|
|
||||||
|
|
||||||
$scope.rawQuery = false;
|
$scope.rawQuery = false;
|
||||||
|
|
||||||
@ -44,6 +43,11 @@ function (angular) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.changeFunction = function(func) {
|
||||||
|
$scope.target.function = func;
|
||||||
|
$scope.get_data();
|
||||||
|
};
|
||||||
|
|
||||||
// called outside of digest
|
// called outside of digest
|
||||||
$scope.listColumns = function(query, callback) {
|
$scope.listColumns = function(query, callback) {
|
||||||
if (!$scope.columnList) {
|
if (!$scope.columnList) {
|
||||||
|
@ -15,5 +15,6 @@ define([
|
|||||||
'./bodyClass',
|
'./bodyClass',
|
||||||
'./addGraphiteFunc',
|
'./addGraphiteFunc',
|
||||||
'./graphiteFuncEditor',
|
'./graphiteFuncEditor',
|
||||||
'./grafanaVersionCheck'
|
'./grafanaVersionCheck',
|
||||||
|
'./influxdbFuncEditor'
|
||||||
], function () {});
|
], function () {});
|
137
src/app/directives/influxdbFuncEditor.js
Normal file
137
src/app/directives/influxdbFuncEditor.js
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
define([
|
||||||
|
'angular',
|
||||||
|
'underscore',
|
||||||
|
'jquery',
|
||||||
|
],
|
||||||
|
function (angular, _, $) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('kibana.directives')
|
||||||
|
.directive('influxdbFuncEditor', function($compile) {
|
||||||
|
|
||||||
|
var funcSpanTemplate = '<a gf-dropdown="functionMenu" class="dropdown-toggle" ' +
|
||||||
|
'data-toggle="dropdown">{{target.function}}</a><span>(</span>';
|
||||||
|
|
||||||
|
var paramTemplate = '<input type="text" style="display:none"' +
|
||||||
|
' class="input-mini grafana-function-param-input"></input>';
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
link: function postLink($scope, elem) {
|
||||||
|
var $funcLink = $(funcSpanTemplate);
|
||||||
|
|
||||||
|
$scope.functionMenu = _.map($scope.functions, function(func) {
|
||||||
|
return {
|
||||||
|
text: func,
|
||||||
|
click: "changeFunction('" + func + "');"
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
function clickFuncParam() {
|
||||||
|
/*jshint validthis:true */
|
||||||
|
|
||||||
|
var $link = $(this);
|
||||||
|
var $input = $link.next();
|
||||||
|
|
||||||
|
$input.val($scope.target.column);
|
||||||
|
$input.css('width', ($link.width() + 16) + 'px');
|
||||||
|
|
||||||
|
$link.hide();
|
||||||
|
$input.show();
|
||||||
|
$input.focus();
|
||||||
|
$input.select();
|
||||||
|
|
||||||
|
var typeahead = $input.data('typeahead');
|
||||||
|
if (typeahead) {
|
||||||
|
$input.val('');
|
||||||
|
typeahead.lookup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputBlur() {
|
||||||
|
/*jshint validthis:true */
|
||||||
|
|
||||||
|
var $input = $(this);
|
||||||
|
var $link = $input.prev();
|
||||||
|
|
||||||
|
if ($input.val() !== '') {
|
||||||
|
$link.text($input.val());
|
||||||
|
|
||||||
|
$scope.target.column = $input.val();
|
||||||
|
$scope.$apply($scope.get_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$input.hide();
|
||||||
|
$link.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputKeyPress(e) {
|
||||||
|
/*jshint validthis:true */
|
||||||
|
|
||||||
|
if(e.which === 13) {
|
||||||
|
inputBlur.call(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputKeyDown() {
|
||||||
|
/*jshint validthis:true */
|
||||||
|
this.style.width = (3 + this.value.length) * 8 + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTypeahead($input) {
|
||||||
|
$input.attr('data-provide', 'typeahead');
|
||||||
|
|
||||||
|
$input.typeahead({
|
||||||
|
source: function () {
|
||||||
|
return $scope.listColumns.apply(null, arguments);
|
||||||
|
},
|
||||||
|
minLength: 0,
|
||||||
|
items: 20,
|
||||||
|
updater: function (value) {
|
||||||
|
setTimeout(function() {
|
||||||
|
inputBlur.call($input[0]);
|
||||||
|
}, 0);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var typeahead = $input.data('typeahead');
|
||||||
|
typeahead.lookup = function () {
|
||||||
|
var items;
|
||||||
|
this.query = this.$element.val() || '';
|
||||||
|
items = this.source(this.query, $.proxy(this.process, this));
|
||||||
|
return items ? this.process(items) : items;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function addElementsAndCompile() {
|
||||||
|
$funcLink.appendTo(elem);
|
||||||
|
|
||||||
|
var $paramLink = $('<a ng-click="" class="graphite-func-param-link">' + $scope.target.column + '</a>');
|
||||||
|
var $input = $(paramTemplate);
|
||||||
|
|
||||||
|
$paramLink.appendTo(elem);
|
||||||
|
$input.appendTo(elem);
|
||||||
|
|
||||||
|
$input.blur(_.partial(inputBlur));
|
||||||
|
$input.keyup(inputKeyDown);
|
||||||
|
$input.keypress(_.partial(inputKeyPress));
|
||||||
|
$paramLink.click(_.partial(clickFuncParam));
|
||||||
|
|
||||||
|
addTypeahead($input);
|
||||||
|
|
||||||
|
$('<span>)</span>').appendTo(elem);
|
||||||
|
|
||||||
|
$compile(elem.contents())($scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
addElementsAndCompile();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
@ -53,13 +53,9 @@
|
|||||||
ng-show="target.rawQuery">
|
ng-show="target.rawQuery">
|
||||||
|
|
||||||
<ul class="grafana-segment-list" role="menu" ng-hide="target.rawQuery">
|
<ul class="grafana-segment-list" role="menu" ng-hide="target.rawQuery">
|
||||||
<li class="grafana-target-segment">
|
|
||||||
from series
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
class="input-small grafana-target-segment-input"
|
class="input-large grafana-target-segment-input"
|
||||||
ng-model="target.series"
|
ng-model="target.series"
|
||||||
spellcheck='false'
|
spellcheck='false'
|
||||||
bs-typeahead="listSeries"
|
bs-typeahead="listSeries"
|
||||||
@ -72,26 +68,11 @@
|
|||||||
select
|
select
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li class="dropdown">
|
||||||
<input type="text"
|
<span influxdb-func-editor class="grafana-target-segment grafana-target-function">
|
||||||
class="input-small grafana-target-segment-input"
|
</span>
|
||||||
ng-model="target.column"
|
|
||||||
placeholder="value column"
|
|
||||||
spellcheck='false'
|
|
||||||
bs-typeahead="listColumns"
|
|
||||||
data-min-length=0
|
|
||||||
ng-blur="get_data()">
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="grafana-target-segment">
|
|
||||||
function
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<select class="input-small grafana-target-segment-input"
|
|
||||||
ng-change="get_data()"
|
|
||||||
ng-model="target.function"
|
|
||||||
ng-options="f for f in functions" ></select>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a class="grafana-target-segment"
|
<a class="grafana-target-segment"
|
||||||
ng-click="target.condiction_filter = !target.condiction_filter; get_data();"
|
ng-click="target.condiction_filter = !target.condiction_filter; get_data();"
|
||||||
@ -139,16 +120,16 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="grafana-target-segment">
|
<li class="grafana-target-segment">
|
||||||
alias as
|
as
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
class="input-small grafana-target-segment-input"
|
class="input-medium grafana-target-segment-input"
|
||||||
ng-model="target.alias"
|
ng-model="target.alias"
|
||||||
spellcheck='false'
|
spellcheck='false'
|
||||||
placeholder="alias"
|
placeholder="alias"
|
||||||
ng-blur="seriesBlur()">
|
ng-blur="get_data()">
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ function (angular, _, kbn) {
|
|||||||
InfluxDatasource.prototype.query = function(filterSrv, options) {
|
InfluxDatasource.prototype.query = function(filterSrv, options) {
|
||||||
var promises = _.map(options.targets, function(target) {
|
var promises = _.map(options.targets, function(target) {
|
||||||
var query;
|
var query;
|
||||||
|
var alias = '';
|
||||||
|
|
||||||
if (target.hide || !((target.series && target.column) || target.query)) {
|
if (target.hide || !((target.series && target.column) || target.query)) {
|
||||||
return [];
|
return [];
|
||||||
@ -80,10 +81,15 @@ function (angular, _, kbn) {
|
|||||||
|
|
||||||
query = _.template(template, templateData, this.templateSettings);
|
query = _.template(template, templateData, this.templateSettings);
|
||||||
query = filterSrv.applyTemplateToTarget(query);
|
query = filterSrv.applyTemplateToTarget(query);
|
||||||
|
|
||||||
|
if (target.alias) {
|
||||||
|
alias = filterSrv.applyTemplateToTarget(target.alias);
|
||||||
|
}
|
||||||
|
|
||||||
target.query = query;
|
target.query = query;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.doInfluxRequest(query, target.alias).then(handleInfluxQueryResponse);
|
return this.doInfluxRequest(query, alias).then(handleInfluxQueryResponse);
|
||||||
|
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
@ -185,9 +191,11 @@ function (angular, _, kbn) {
|
|||||||
|
|
||||||
var target = data.alias || series.name + "." + column;
|
var target = data.alias || series.name + "." + column;
|
||||||
var datapoints = [];
|
var datapoints = [];
|
||||||
|
var value;
|
||||||
|
|
||||||
for(var i = 0; i < series.points.length; i++) {
|
for(var i = 0; i < series.points.length; i++) {
|
||||||
datapoints[i] = [series.points[i][index], series.points[i][timeCol]];
|
value = isNaN(series.points[i][index]) ? null : series.points[i][index];
|
||||||
|
datapoints[i] = [value, series.points[i][timeCol]];
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push({ target:target, datapoints:datapoints });
|
output.push({ target:target, datapoints:datapoints });
|
||||||
|
Loading…
Reference in New Issue
Block a user