From ed49962120f436e0d912ae32570068ed91fc2a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 15 Aug 2015 21:49:30 +0200 Subject: [PATCH 01/15] refactor(): began work on big design change for how data source query editors are loaded --- public/app/features/panel/panelDirective.js | 74 ++-- public/app/partials/metrics.html | 9 +- .../graphite/partials/query.editor.html | 414 +++++++++--------- .../plugins/datasource/graphite/queryCtrl.js | 23 +- .../influxdb/partials/query.editor.html | 2 +- .../influxdb_08/partials/query.editor.html | 2 +- 6 files changed, 267 insertions(+), 257 deletions(-) diff --git a/public/app/features/panel/panelDirective.js b/public/app/features/panel/panelDirective.js index 7330bb627de..041980f9d44 100644 --- a/public/app/features/panel/panelDirective.js +++ b/public/app/features/panel/panelDirective.js @@ -6,35 +6,51 @@ define([ function (angular, $, config) { 'use strict'; - angular - .module('grafana.directives') - .directive('panelLoader', function($compile, $parse) { - return { - restrict: 'E', - link: function(scope, elem, attr) { - var getter = $parse(attr.type), panelType = getter(scope); - var panelPath = config.panels[panelType].path; + var module = angular.module('grafana.directives'); - scope.require([panelPath + "/module"], function () { - var panelEl = angular.element(document.createElement('grafana-panel-' + panelType)); - elem.append(panelEl); - $compile(panelEl)(scope); - }); - } - }; - }).directive('grafanaPanel', function() { - return { - restrict: 'E', - templateUrl: 'app/features/panel/partials/panel.html', - transclude: true, - link: function(scope, elem) { - var panelContainer = elem.find('.panel-container'); + module.directive('panelLoader', function($compile, $parse) { + return { + restrict: 'E', + link: function(scope, elem, attr) { + var getter = $parse(attr.type), panelType = getter(scope); + var panelPath = config.panels[panelType].path; + + scope.require([panelPath + "/module"], function () { + var panelEl = angular.element(document.createElement('grafana-panel-' + panelType)); + elem.append(panelEl); + $compile(panelEl)(scope); + }); + } + }; + }); + + module.directive('grafanaPanel', function() { + return { + restrict: 'E', + templateUrl: 'app/features/panel/partials/panel.html', + transclude: true, + link: function(scope, elem) { + var panelContainer = elem.find('.panel-container'); + + scope.$watchGroup(['fullscreen', 'height', 'panel.height', 'row.height'], function() { + panelContainer.css({ minHeight: scope.height || scope.panel.height || scope.row.height, display: 'block' }); + elem.toggleClass('panel-fullscreen', scope.fullscreen ? true : false); + }); + } + }; + }); + + module.directive('queryEditorLoader', function($compile, $parse, datasourceSrv) { + return { + restrict: 'E', + link: function(scope, elem) { + datasourceSrv.get(scope.panel.datasource).then(function(ds) { + var panelEl = angular.element(document.createElement('metric-query-editor-' + ds.meta.type)); + elem.append(panelEl); + $compile(panelEl)(scope); + }); + } + }; + }); - scope.$watchGroup(['fullscreen', 'height', 'panel.height', 'row.height'], function() { - panelContainer.css({ minHeight: scope.height || scope.panel.height || scope.row.height, display: 'block' }); - elem.toggleClass('panel-fullscreen', scope.fullscreen ? true : false); - }); - } - }; - }); }); diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index db304d1c232..56571bfa203 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -1,5 +1,12 @@ -
+
+ + + + + +
+
- -
-
-
    -
  • - +
- -
- -
-
- -
-
Shorter legend names
-
    -
  • alias() function to specify a custom series name
  • -
  • aliasByNode(2) to alias by a specific part of your metric path
  • -
  • aliasByNode(2, -1) you can add multiple segment paths, and use negative index
  • -
  • groupByNode(2, 'sum') is useful if you have 2 wildcards in your metric path and want to sumSeries and group by
  • -
-
- -
-
Series as parameter
-
    -
  • Some graphite functions allow you to have many series arguments
  • -
  • Use #[A-Z] to use a graphite query as parameter to a function
  • -
  • - Examples: -
      -
    • asPercent(#A, #B)
    • -
    • prod.srv-01.counters.count - asPercent(#A) : percentage of count in comparison with A query
    • -
    • prod.srv-01.counters.count - sumSeries(#A) : sum count and series A
    • -
    • divideSeries(#A, #B)
    • -
    -
  • -
  • If a query is added only to be used as a parameter, hide it from the graph with the eye icon
  • -
-
- -
-
Stacking
-
    -
  • You find the stacking option under Display Styles tab
  • -
  • When stacking is enabled make sure null point mode is set to 'null as zero'
  • -
-
- -
-
Templating
-
    -
  • You can use a template variable in place of metric names
  • -
  • You can use a template variable in place of function parameters
  • -
  • You enable the templating feature in Dashboard settings / Feature toggles
  • -
-
- -
-
Max data points
-
    -
  • Every graphite request is issued with a maxDataPoints parameter
  • -
  • Graphite uses this parameter to consolidate the real number of values down to this number
  • -
  • If there are more real values, then by default they will be consolidated using averages
  • -
  • This could hide real peaks and max values in your series
  • -
  • You can change how point consolidation is made using the consolidateBy graphite function
  • -
  • Point consolidation will effect series legend values (min,max,total,current)
  • -
  • If you override maxDataPoint and set a high value performance can be severely effected
  • -
-
- -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/app/plugins/datasource/graphite/queryCtrl.js b/public/app/plugins/datasource/graphite/queryCtrl.js index 040386e03d6..1e5d34a816f 100644 --- a/public/app/plugins/datasource/graphite/queryCtrl.js +++ b/public/app/plugins/datasource/graphite/queryCtrl.js @@ -11,6 +11,13 @@ function (angular, _, config, gfunc, Parser) { var module = angular.module('grafana.controllers'); var targetLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + module.directive('metricQueryEditorGraphite', function() { + return { + controller: 'GraphiteQueryCtrl', + templateUrl: 'app/plugins/datasource/graphite/partials/query.editor.html', + }; + }); + module.controller('GraphiteQueryCtrl', function($scope, $sce, templateSrv) { $scope.init = function() { @@ -313,22 +320,8 @@ function (angular, _, config, gfunc, Parser) { return new MetricSegment({value: 'select metric', fake: true}); }; - }); + $scope.init(); - module.directive('focusMe', function($timeout, $parse) { - return { - //scope: true, // optionally create a child scope - link: function(scope, element, attrs) { - var model = $parse(attrs.focusMe); - scope.$watch(model, function(value) { - if(value === true) { - $timeout(function() { - element[0].focus(); - }); - } - }); - } - }; }); }); diff --git a/public/app/plugins/datasource/influxdb/partials/query.editor.html b/public/app/plugins/datasource/influxdb/partials/query.editor.html index cbcfcb9f4c3..824ba36ab20 100644 --- a/public/app/plugins/datasource/influxdb/partials/query.editor.html +++ b/public/app/plugins/datasource/influxdb/partials/query.editor.html @@ -59,7 +59,7 @@ - + +
+ + - - - - -
-
-
    -
  • - -
  • -
  • - Group by time interval -
  • -
  • - -
  • -
  • - -
  • -
-
- -
- -
-
- -
-
Alias patterns
-
    -
  • $m = replaced with measurement name
  • -
  • $measurement = replaced with measurement name
  • -
  • $col = replaced with column name
  • -
  • $tag_hostname = replaced with the value of the hostname tag
  • -
  • You can also use [[tag_hostname]] pattern replacement syntax
  • -
-
- -
-
Stacking and fill
-
    -
  • When stacking is enabled it important that points align
  • -
  • If there are missing points for one series it can cause gaps or missing bars
  • -
  • You must use fill(0), and select a group by time low limit
  • -
  • Use the group by time option below your queries and specify for example >10s if your metrics are written every 10 seconds
  • -
  • This will insert zeros for series that are missing measurements and will make stacking work properly
  • -
-
- -
-
Group by time
-
    -
  • Group by time is important, otherwise the query could return many thousands of datapoints that will slow down Grafana
  • -
  • Leave the group by time field empty for each query and it will be calculated based on time range and pixel width of the graph
  • -
  • If you use fill(0) or fill(null) set a low limit for the auto group by time interval
  • -
  • The low limit can only be set in the group by time option below your queries
  • -
  • You set a low limit by adding a greater sign before the interval
  • -
  • Example: >60s if you write metrics to InfluxDB every 60 seconds
  • -
-
- - -
-
- diff --git a/public/app/plugins/datasource/influxdb/partials/query.options.html b/public/app/plugins/datasource/influxdb/partials/query.options.html new file mode 100644 index 00000000000..c794e0b5323 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/partials/query.options.html @@ -0,0 +1,87 @@ +
+
+
    +
  • + +
  • +
  • + Group by time interval +
  • +
  • + +
  • +
  • + +
  • +
+
+
+ + +
+ +
+
+ +
+
Alias patterns
+
    +
  • $m = replaced with measurement name
  • +
  • $measurement = replaced with measurement name
  • +
  • $col = replaced with column name
  • +
  • $tag_hostname = replaced with the value of the hostname tag
  • +
  • You can also use [[tag_hostname]] pattern replacement syntax
  • +
+
+ +
+
Stacking and fill
+
    +
  • When stacking is enabled it important that points align
  • +
  • If there are missing points for one series it can cause gaps or missing bars
  • +
  • You must use fill(0), and select a group by time low limit
  • +
  • Use the group by time option below your queries and specify for example >10s if your metrics are written every 10 seconds
  • +
  • This will insert zeros for series that are missing measurements and will make stacking work properly
  • +
+
+ +
+
Group by time
+
    +
  • Group by time is important, otherwise the query could return many thousands of datapoints that will slow down Grafana
  • +
  • Leave the group by time field empty for each query and it will be calculated based on time range and pixel width of the graph
  • +
  • If you use fill(0) or fill(null) set a low limit for the auto group by time interval
  • +
  • The low limit can only be set in the group by time option below your queries
  • +
  • You set a low limit by adding a greater sign before the interval
  • +
  • Example: >60s if you write metrics to InfluxDB every 60 seconds
  • +
+
+ + +
+
+ + diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index 2772587ddf8..40306cfab38 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -8,6 +8,19 @@ function (angular, _, InfluxQueryBuilder) { var module = angular.module('grafana.controllers'); + module.directive('metricQueryEditorInfluxdb', function() { + return { + controller: 'InfluxQueryCtrl', + templateUrl: 'app/plugins/datasource/influxdb/partials/query.editor.html', + }; + }); + + module.directive('metricQueryOptionsInfluxdb', function() { + return { + templateUrl: 'app/plugins/datasource/influxdb/partials/query.options.html', + }; + }); + module.controller('InfluxQueryCtrl', function($scope, $timeout, $sce, templateSrv, $q) { $scope.init = function() { @@ -337,6 +350,8 @@ function (angular, _, InfluxQueryBuilder) { return new MetricSegment({value: 'select tag value', fake: true}); }; + $scope.init(); + }); }); diff --git a/public/css/less/tightform.less b/public/css/less/tightform.less index a85e852bcbc..ff43316263d 100644 --- a/public/css/less/tightform.less +++ b/public/css/less/tightform.less @@ -42,12 +42,11 @@ } .tight-form-container { + border-bottom: 1px solid @grafanaTargetBorder; + .tight-form:last-child { border-bottom: none; } - &:last-child { - border-bottom: 1px solid @grafanaTargetBorder; - } } .tight-form-btn { @@ -63,7 +62,7 @@ } .grafana-metric-options { - margin-top: 35px; + margin-top: 25px; } .tight-form-item { From b30dfcf28a92d770e02c007dc67b309acb287cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sun, 16 Aug 2015 01:34:09 +0200 Subject: [PATCH 03/15] feat(datasource): added new mixed data source --- public/app/features/panel/panelDirective.js | 3 ++ public/app/features/panel/panelSrv.js | 13 ++++++ public/app/partials/metrics.html | 4 +- .../plugins/datasource/graphite/queryCtrl.js | 3 -- .../influxdb/partials/query.editor.html | 18 ++++---- .../plugins/datasource/mixed/datasource.js | 42 +++++++++++++++++++ .../app/plugins/datasource/mixed/plugin.json | 15 +++++++ public/css/less/tightform.less | 1 + 8 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 public/app/plugins/datasource/mixed/datasource.js create mode 100644 public/app/plugins/datasource/mixed/plugin.json diff --git a/public/app/features/panel/panelDirective.js b/public/app/features/panel/panelDirective.js index a697aab4722..18ab6d7891c 100644 --- a/public/app/features/panel/panelDirective.js +++ b/public/app/features/panel/panelDirective.js @@ -40,6 +40,8 @@ function (angular, $, config) { }; }); + var targetLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + module.directive('queryEditorLoader', function($compile, $parse, datasourceSrv) { return { restrict: 'E', @@ -57,6 +59,7 @@ function (angular, $, config) { editorScope = scope.$new(); editorScope.datasource = ds; + editorScope.targetLetters = targetLetters; var panelEl = angular.element(document.createElement('metric-query-editor-' + ds.meta.type)); elem.append(panelEl); diff --git a/public/app/features/panel/panelSrv.js b/public/app/features/panel/panelSrv.js index 881cab29dc0..718e20caa34 100644 --- a/public/app/features/panel/panelSrv.js +++ b/public/app/features/panel/panelSrv.js @@ -55,6 +55,19 @@ function (angular, _, config) { $scope.setDatasource = function(datasource) { $scope.panel.datasource = datasource; $scope.datasource = null; + $scope.panel.targets = _.filter($scope.panel.targets, function(target) { + delete target.datasource; + return target.datasource === void 0; + }); + + if ($scope.panel.targets.length === 0) { + $scope.panel.targets = [{}]; + } + + if (datasource === 'mixed') { + $scope.panel.targets = []; + } + $scope.get_data(); }; diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index eca15e905d9..9343747f53f 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -6,12 +6,12 @@
- - +
diff --git a/public/app/plugins/datasource/opentsdb/queryCtrl.js b/public/app/plugins/datasource/opentsdb/queryCtrl.js index 72ae9710d08..4f16983848f 100644 --- a/public/app/plugins/datasource/opentsdb/queryCtrl.js +++ b/public/app/plugins/datasource/opentsdb/queryCtrl.js @@ -8,6 +8,13 @@ function (angular, _, kbn) { var module = angular.module('grafana.controllers'); + module.directive('metricQueryEditorOpentsdb', function() { + return { + controller: 'OpenTSDBQueryCtrl', + templateUrl: 'app/plugins/datasource/opentsdb/partials/query.editor.html', + }; + }); + module.controller('OpenTSDBQueryCtrl', function($scope, $timeout) { $scope.init = function() { @@ -113,6 +120,7 @@ function (angular, _, kbn) { return errs; } + $scope.init(); }); }); diff --git a/public/css/less/tightform.less b/public/css/less/tightform.less index 515124b7ad9..7961cef775a 100644 --- a/public/css/less/tightform.less +++ b/public/css/less/tightform.less @@ -29,6 +29,7 @@ } } + .spaced-form { .tight-form { margin: 7px 0; @@ -209,3 +210,7 @@ select.tight-form-input { } } +.tight-form-align { + padding-left: 66px; +} + From e916f9378725c579776e4f1330af71a8f8494b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sun, 16 Aug 2015 10:06:36 +0200 Subject: [PATCH 05/15] feat(mixed datasource): fixed failing unit tests --- .../plugins/datasource/grafana/datasource.js | 57 ++----------------- .../plugins/datasource/graphite/queryCtrl.js | 6 +- .../plugins/datasource/influxdb/queryCtrl.js | 2 + public/test/specs/graphiteTargetCtrl-specs.js | 4 +- 4 files changed, 13 insertions(+), 56 deletions(-) diff --git a/public/app/plugins/datasource/grafana/datasource.js b/public/app/plugins/datasource/grafana/datasource.js index 2a88969a55c..c6d47da8552 100644 --- a/public/app/plugins/datasource/grafana/datasource.js +++ b/public/app/plugins/datasource/grafana/datasource.js @@ -8,68 +8,23 @@ function (angular, _, kbn) { var module = angular.module('grafana.services'); - module.factory('GrafanaDatasource', function($q, backendSrv, datasourceSrv) { + module.factory('GrafanaDatasource', function($q, backendSrv) { function GrafanaDatasource() { } - GrafanaDatasource.prototype.getDashboard = function(slug, isTemp) { - var url = '/dashboards/' + slug; - - if (isTemp) { - url = '/temp/' + slug; - } - - return backendSrv.get('/api/dashboards/db/' + slug); - }; - GrafanaDatasource.prototype.query = function(options) { - return datasourceSrv.get(options.targets[0].datasource).then(function(ds) { - options.targets = [options.targets[0]]; - return ds.query(options); - }); - // console.log(options.targets); - // // get from & to in seconds - // var from = kbn.parseDate(options.range.from).getTime(); - // var to = kbn.parseDate(options.range.to).getTime(); - // - // return backendSrv.get('/api/metrics/test', { from: from, to: to, maxDataPoints: options.maxDataPoints }); + // get from & to in seconds + var from = kbn.parseDate(options.range.from).getTime(); + var to = kbn.parseDate(options.range.to).getTime(); + + return backendSrv.get('/api/metrics/test', { from: from, to: to, maxDataPoints: options.maxDataPoints }); }; GrafanaDatasource.prototype.metricFindQuery = function() { return $q.when([]); }; - GrafanaDatasource.prototype.starDashboard = function(dashId) { - return backendSrv.post('/api/user/stars/dashboard/' + dashId); - }; - - GrafanaDatasource.prototype.unstarDashboard = function(dashId) { - return backendSrv.delete('/api/user/stars/dashboard/' + dashId); - }; - - GrafanaDatasource.prototype.saveDashboard = function(dashboard) { - return backendSrv.post('/api/dashboards/db/', { dashboard: dashboard }) - .then(function(data) { - return { title: dashboard.title, url: '/dashboard/db/' + data.slug }; - }, function(err) { - err.isHandled = true; - err.data = err.data || {}; - throw err.data.message || "Unknown error"; - }); - }; - - GrafanaDatasource.prototype.deleteDashboard = function(id) { - return backendSrv.delete('/api/dashboards/db/' + id); - }; - - GrafanaDatasource.prototype.searchDashboards = function(query) { - return backendSrv.get('/api/search/', query) - .then(function(data) { - return data; - }); - }; - return GrafanaDatasource; }); diff --git a/public/app/plugins/datasource/graphite/queryCtrl.js b/public/app/plugins/datasource/graphite/queryCtrl.js index 8f8affc3e03..0d1087dc53c 100644 --- a/public/app/plugins/datasource/graphite/queryCtrl.js +++ b/public/app/plugins/datasource/graphite/queryCtrl.js @@ -26,8 +26,10 @@ function (angular, _, config, gfunc, Parser) { module.controller('GraphiteQueryCtrl', function($scope, $sce, templateSrv) { $scope.init = function() { - $scope.target.target = $scope.target.target || ''; - parseTarget(); + if ($scope.target) { + $scope.target.target = $scope.target.target || ''; + parseTarget(); + } }; $scope.toggleEditorMode = function() { diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index 40306cfab38..0d8a18ebd33 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -24,6 +24,8 @@ function (angular, _, InfluxQueryBuilder) { module.controller('InfluxQueryCtrl', function($scope, $timeout, $sce, templateSrv, $q) { $scope.init = function() { + if (!$scope.target) { return; } + var target = $scope.target; target.tags = target.tags || []; target.groupByTags = target.groupByTags || []; diff --git a/public/test/specs/graphiteTargetCtrl-specs.js b/public/test/specs/graphiteTargetCtrl-specs.js index 31916cc2802..9680ffb5742 100644 --- a/public/test/specs/graphiteTargetCtrl-specs.js +++ b/public/test/specs/graphiteTargetCtrl-specs.js @@ -13,9 +13,7 @@ define([ beforeEach(ctx.createControllerPhase('GraphiteQueryCtrl')); beforeEach(function() { - ctx.scope.target = { - target: 'aliasByNode(scaleToSeconds(test.prod.*,1),2)' - }; + ctx.scope.target = {target: 'aliasByNode(scaleToSeconds(test.prod.*,1),2)'}; ctx.scope.datasource = ctx.datasource; ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([])); From 31052154257f4ee72a1aef0a1f23e8da1c70dc90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sun, 16 Aug 2015 11:24:25 +0200 Subject: [PATCH 06/15] feat(mixed datasource): changed how query ref ids (letters) are assigned, now they are persisted --- public/app/features/panel/panelDirective.js | 3 - public/app/features/panel/panelSrv.js | 15 ++++- .../plugins/datasource/graphite/datasource.js | 26 ++++----- .../graphite/partials/query.editor.html | 2 +- .../opentsdb/partials/query.editor.html | 2 +- public/test/specs/panelSrv-specs.js | 58 +++++++++++++++++++ public/test/test-main.js | 1 + 7 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 public/test/specs/panelSrv-specs.js diff --git a/public/app/features/panel/panelDirective.js b/public/app/features/panel/panelDirective.js index 18ab6d7891c..a697aab4722 100644 --- a/public/app/features/panel/panelDirective.js +++ b/public/app/features/panel/panelDirective.js @@ -40,8 +40,6 @@ function (angular, $, config) { }; }); - var targetLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - module.directive('queryEditorLoader', function($compile, $parse, datasourceSrv) { return { restrict: 'E', @@ -59,7 +57,6 @@ function (angular, $, config) { editorScope = scope.$new(); editorScope.datasource = ds; - editorScope.targetLetters = targetLetters; var panelEl = angular.element(document.createElement('metric-query-editor-' + ds.meta.type)); elem.append(panelEl); diff --git a/public/app/features/panel/panelSrv.js b/public/app/features/panel/panelSrv.js index 718e20caa34..784525c0528 100644 --- a/public/app/features/panel/panelSrv.js +++ b/public/app/features/panel/panelSrv.js @@ -44,7 +44,20 @@ function (angular, _, config) { }; $scope.addDataQuery = function(datasource) { - $scope.panel.targets.push({target: '', datasource: datasource}); + var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + var target = {}; + + if (datasource) { + target.datasource = datasource; + } + + target.refId = _.find(letters, function(refId) { + return _.every($scope.panel.targets, function(other) { + return other.refId !== refId; + }); + }); + + $scope.panel.targets.push(target); }; $scope.removeDataQuery = function (query) { diff --git a/public/app/plugins/datasource/graphite/datasource.js b/public/app/plugins/datasource/graphite/datasource.js index e9f2a6efe5d..cd7c66d67a8 100644 --- a/public/app/plugins/datasource/graphite/datasource.js +++ b/public/app/plugins/datasource/graphite/datasource.js @@ -228,21 +228,13 @@ function (angular, _, $, config, kbn, moment) { return backendSrv.datasourceRequest(options); }; - GraphiteDatasource.prototype._seriesRefLetters = [ - '#A', '#B', '#C', '#D', - '#E', '#F', '#G', '#H', - '#I', '#J', '#K', '#L', - '#M', '#N', '#O', '#P', - '#Q', '#R', '#S', '#T', - '#U', '#V', '#W', '#X', - '#Y', '#Z' - ]; + GraphiteDatasource.prototype._seriesRefLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; GraphiteDatasource.prototype.buildGraphiteParams = function(options, scopedVars) { var graphite_options = ['from', 'until', 'rawData', 'format', 'maxDataPoints', 'cacheTimeout']; var clean_options = [], targets = {}; var target, targetValue, i; - var regex = /(\#[A-Z])/g; + var regex = /\#([A-Z])/g; var intervalFormatFixRegex = /'(\d+)m'/gi; if (options.format !== 'png') { @@ -259,13 +251,17 @@ function (angular, _, $, config, kbn, moment) { continue; } + if (!target.refId) { + target.refId = this._seriesRefLetters[i]; + } + targetValue = templateSrv.replace(target.target, scopedVars); targetValue = targetValue.replace(intervalFormatFixRegex, fixIntervalFormat); - targets[this._seriesRefLetters[i]] = targetValue; + targets[target.refId] = targetValue; } - function nestedSeriesRegexReplacer(match) { - return targets[match]; + function nestedSeriesRegexReplacer(match, g1) { + return targets[g1]; } for (i = 0; i < options.targets.length; i++) { @@ -274,9 +270,9 @@ function (angular, _, $, config, kbn, moment) { continue; } - targetValue = targets[this._seriesRefLetters[i]]; + targetValue = targets[target.refId]; targetValue = targetValue.replace(regex, nestedSeriesRegexReplacer); - targets[this._seriesRefLetters[i]] = targetValue; + targets[target.refId] = targetValue; if (!target.hide) { clean_options.push("target=" + encodeURIComponent(targetValue)); diff --git a/public/app/plugins/datasource/graphite/partials/query.editor.html b/public/app/plugins/datasource/graphite/partials/query.editor.html index 6361f05f584..a26dfd0e52e 100755 --- a/public/app/plugins/datasource/graphite/partials/query.editor.html +++ b/public/app/plugins/datasource/graphite/partials/query.editor.html @@ -48,7 +48,7 @@
  • - {{targetLetters[$index]}} + {{target.refId}}
  • - {{targetLetters[$index]}} + {{target.refId}}
  • Date: Sun, 16 Aug 2015 20:52:30 +0200 Subject: [PATCH 07/15] feat(mixed datasources): continued work on editor design change --- pkg/api/datasources.go | 10 +++- pkg/api/frontendsettings.go | 5 ++ .../features/annotations/partials/editor.html | 3 +- public/app/features/panel/panelDirective.js | 53 +++++++++++++------ public/app/features/panel/panelSrv.js | 2 +- public/app/partials/metrics.html | 5 +- .../plugins/datasource/grafana/plugin.json | 6 +-- .../plugins/datasource/graphite/datasource.js | 1 + .../plugins/datasource/graphite/directives.js | 21 ++++++++ .../plugins/datasource/graphite/plugin.json | 2 - .../plugins/datasource/graphite/queryCtrl.js | 13 ----- .../plugins/datasource/influxdb/datasource.js | 1 + .../plugins/datasource/influxdb/directives.js | 21 ++++++++ .../plugins/datasource/influxdb/plugin.json | 2 - .../plugins/datasource/influxdb/queryCtrl.js | 13 ----- .../app/plugins/datasource/mixed/plugin.json | 6 +-- .../plugins/datasource/opentsdb/directives.js | 16 ++++++ .../plugins/datasource/opentsdb/plugin.json | 3 +- .../plugins/datasource/opentsdb/queryCtrl.js | 7 --- 19 files changed, 117 insertions(+), 73 deletions(-) create mode 100644 public/app/plugins/datasource/graphite/directives.js create mode 100644 public/app/plugins/datasource/influxdb/directives.js create mode 100644 public/app/plugins/datasource/opentsdb/directives.js diff --git a/pkg/api/datasources.go b/pkg/api/datasources.go index e0253df3cdb..52655556483 100644 --- a/pkg/api/datasources.go +++ b/pkg/api/datasources.go @@ -112,5 +112,13 @@ func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) { } func GetDataSourcePlugins(c *middleware.Context) { - c.JSON(200, plugins.DataSources) + dsList := make(map[string]interface{}) + + for key, value := range plugins.DataSources { + if value.(map[string]interface{})["hide"] == nil { + dsList[key] = value + } + } + + c.JSON(200, dsList) } diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 7851f1d8f0d..98f8ee338b9 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -90,6 +90,11 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro "type": "grafana", "meta": grafanaDatasourceMeta, } + // add mixed backend data source + datasources["mixed"] = map[string]interface{}{ + "type": "mixed", + "meta": plugins.DataSources["mixed"], + } if defaultDatasource == "" { defaultDatasource = "grafana" diff --git a/public/app/features/annotations/partials/editor.html b/public/app/features/annotations/partials/editor.html index 799b1f69fe4..2ff4040d098 100644 --- a/public/app/features/annotations/partials/editor.html +++ b/public/app/features/annotations/partials/editor.html @@ -72,8 +72,7 @@ -
    -
    +
    diff --git a/public/app/features/panel/panelDirective.js b/public/app/features/panel/panelDirective.js index a697aab4722..bb60d209aad 100644 --- a/public/app/features/panel/panelDirective.js +++ b/public/app/features/panel/panelDirective.js @@ -40,6 +40,31 @@ function (angular, $, config) { }; }); + module.service('dynamicDirectiveSrv', function($compile, $parse, datasourceSrv) { + var self = this; + + this.addDirective = function(options, type, editorScope) { + var panelEl = angular.element(document.createElement(options.name + '-' + type)); + options.parentElem.append(panelEl); + $compile(panelEl)(editorScope); + }; + + this.define = function(options) { + var editorScope; + options.scope.$watch(options.datasourceProperty, function(newVal) { + if (editorScope) { + editorScope.$destroy(); + options.parentElem.empty(); + } + + editorScope = options.scope.$new(); + datasourceSrv.get(newVal).then(function(ds) { + self.addDirective(options, ds.meta.type, editorScope); + }); + }); + }; + }); + module.directive('queryEditorLoader', function($compile, $parse, datasourceSrv) { return { restrict: 'E', @@ -58,6 +83,10 @@ function (angular, $, config) { editorScope = scope.$new(); editorScope.datasource = ds; + if (!scope.target.refId) { + scope.target.refId = 'A'; + } + var panelEl = angular.element(document.createElement('metric-query-editor-' + ds.meta.type)); elem.append(panelEl); $compile(panelEl)(editorScope); @@ -67,25 +96,15 @@ function (angular, $, config) { }; }); - module.directive('queryOptionsLoader', function($compile, $parse, datasourceSrv) { + module.directive('datasourceEditorView', function(dynamicDirectiveSrv) { return { restrict: 'E', - link: function(scope, elem) { - var editorScope; - - scope.$watch("panel.datasource", function() { - - datasourceSrv.get(scope.panel.datasource).then(function(ds) { - if (editorScope) { - editorScope.$destroy(); - elem.empty(); - } - - editorScope = scope.$new(); - var panelEl = angular.element(document.createElement('metric-query-options-' + ds.meta.type)); - elem.append(panelEl); - $compile(panelEl)(editorScope); - }); + link: function(scope, elem, attrs) { + dynamicDirectiveSrv.define({ + datasourceProperty: attrs.datasource, + name: attrs.name, + scope: scope, + parentElem: elem, }); } }; diff --git a/public/app/features/panel/panelSrv.js b/public/app/features/panel/panelSrv.js index 784525c0528..adb28031a4b 100644 --- a/public/app/features/panel/panelSrv.js +++ b/public/app/features/panel/panelSrv.js @@ -74,7 +74,7 @@ function (angular, _, config) { }); if ($scope.panel.targets.length === 0) { - $scope.panel.targets = [{}]; + $scope.panel.targets = [{refId: 'A'}]; } if (datasource === 'mixed') { diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index 9343747f53f..7b30c42a066 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -19,15 +19,14 @@
    - - +
    diff --git a/public/app/plugins/datasource/grafana/plugin.json b/public/app/plugins/datasource/grafana/plugin.json index 9358cb29af1..2baffb991eb 100644 --- a/public/app/plugins/datasource/grafana/plugin.json +++ b/public/app/plugins/datasource/grafana/plugin.json @@ -1,15 +1,11 @@ { "pluginType": "datasource", "name": "Grafana (for testing)", + "hide": true, "type": "grafana", "serviceName": "GrafanaDatasource", "module": "plugins/datasource/grafana/datasource", - - "partials": { - "query": "app/plugins/datasource/grafana/partials/query.editor.html" - }, - "metrics": true } diff --git a/public/app/plugins/datasource/graphite/datasource.js b/public/app/plugins/datasource/graphite/datasource.js index cd7c66d67a8..400ec7abc77 100644 --- a/public/app/plugins/datasource/graphite/datasource.js +++ b/public/app/plugins/datasource/graphite/datasource.js @@ -5,6 +5,7 @@ define([ 'config', 'kbn', 'moment', + './directives', './queryCtrl', './funcEditor', './addGraphiteFunc', diff --git a/public/app/plugins/datasource/graphite/directives.js b/public/app/plugins/datasource/graphite/directives.js new file mode 100644 index 00000000000..91e52bb9546 --- /dev/null +++ b/public/app/plugins/datasource/graphite/directives.js @@ -0,0 +1,21 @@ +define([ + 'angular', +], +function (angular) { + 'use strict'; + + var module = angular.module('grafana.directives'); + + module.directive('metricQueryEditorGraphite', function() { + return {controller: 'GraphiteQueryCtrl', templateUrl: 'app/plugins/datasource/graphite/partials/query.editor.html'}; + }); + + module.directive('metricQueryOptionsGraphite', function() { + return {templateUrl: 'app/plugins/datasource/graphite/partials/query.options.html'}; + }); + + module.directive('annotationsQueryEditorGraphite', function() { + return {templateUrl: 'app/plugins/datasource/graphite/partials/annotations.editor.html'}; + }); + +}); diff --git a/public/app/plugins/datasource/graphite/plugin.json b/public/app/plugins/datasource/graphite/plugin.json index 8e6766f087a..d45c446f40f 100644 --- a/public/app/plugins/datasource/graphite/plugin.json +++ b/public/app/plugins/datasource/graphite/plugin.json @@ -9,8 +9,6 @@ "partials": { "config": "app/plugins/datasource/graphite/partials/config.html", - "query": "app/plugins/datasource/graphite/partials/query.editor.html", - "annotations": "app/plugins/datasource/graphite/partials/annotations.editor.html" }, "metrics": true, diff --git a/public/app/plugins/datasource/graphite/queryCtrl.js b/public/app/plugins/datasource/graphite/queryCtrl.js index 0d1087dc53c..21b1534fbe1 100644 --- a/public/app/plugins/datasource/graphite/queryCtrl.js +++ b/public/app/plugins/datasource/graphite/queryCtrl.js @@ -10,19 +10,6 @@ function (angular, _, config, gfunc, Parser) { var module = angular.module('grafana.controllers'); - module.directive('metricQueryEditorGraphite', function() { - return { - controller: 'GraphiteQueryCtrl', - templateUrl: 'app/plugins/datasource/graphite/partials/query.editor.html', - }; - }); - - module.directive('metricQueryOptionsGraphite', function() { - return { - templateUrl: 'app/plugins/datasource/graphite/partials/query.options.html', - }; - }); - module.controller('GraphiteQueryCtrl', function($scope, $sce, templateSrv) { $scope.init = function() { diff --git a/public/app/plugins/datasource/influxdb/datasource.js b/public/app/plugins/datasource/influxdb/datasource.js index cca93fd4e3b..71714b7b40c 100644 --- a/public/app/plugins/datasource/influxdb/datasource.js +++ b/public/app/plugins/datasource/influxdb/datasource.js @@ -4,6 +4,7 @@ define([ 'kbn', './influxSeries', './queryBuilder', + './directives', './queryCtrl', './funcEditor', ], diff --git a/public/app/plugins/datasource/influxdb/directives.js b/public/app/plugins/datasource/influxdb/directives.js new file mode 100644 index 00000000000..a4c66137751 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/directives.js @@ -0,0 +1,21 @@ +define([ + 'angular', +], +function (angular) { + 'use strict'; + + var module = angular.module('grafana.directives'); + + module.directive('metricQueryEditorInfluxdb', function() { + return {controller: 'InfluxQueryCtrl', templateUrl: 'app/plugins/datasource/influxdb/partials/query.editor.html'}; + }); + + module.directive('metricQueryOptionsInfluxdb', function() { + return {templateUrl: 'app/plugins/datasource/influxdb/partials/query.options.html'}; + }); + + module.directive('annotationsQueryEditorInfluxdb', function() { + return {templateUrl: 'app/plugins/datasource/influxdb/partials/annotations.editor.html'}; + }); + +}); diff --git a/public/app/plugins/datasource/influxdb/plugin.json b/public/app/plugins/datasource/influxdb/plugin.json index c93b41747a7..560b7cfb8f9 100644 --- a/public/app/plugins/datasource/influxdb/plugin.json +++ b/public/app/plugins/datasource/influxdb/plugin.json @@ -9,8 +9,6 @@ "partials": { "config": "app/plugins/datasource/influxdb/partials/config.html", - "query": "app/plugins/datasource/influxdb/partials/query.editor.html", - "annotations": "app/plugins/datasource/influxdb/partials/annotations.editor.html" }, "metrics": true, diff --git a/public/app/plugins/datasource/influxdb/queryCtrl.js b/public/app/plugins/datasource/influxdb/queryCtrl.js index 0d8a18ebd33..be87edcad21 100644 --- a/public/app/plugins/datasource/influxdb/queryCtrl.js +++ b/public/app/plugins/datasource/influxdb/queryCtrl.js @@ -8,19 +8,6 @@ function (angular, _, InfluxQueryBuilder) { var module = angular.module('grafana.controllers'); - module.directive('metricQueryEditorInfluxdb', function() { - return { - controller: 'InfluxQueryCtrl', - templateUrl: 'app/plugins/datasource/influxdb/partials/query.editor.html', - }; - }); - - module.directive('metricQueryOptionsInfluxdb', function() { - return { - templateUrl: 'app/plugins/datasource/influxdb/partials/query.options.html', - }; - }); - module.controller('InfluxQueryCtrl', function($scope, $timeout, $sce, templateSrv, $q) { $scope.init = function() { diff --git a/public/app/plugins/datasource/mixed/plugin.json b/public/app/plugins/datasource/mixed/plugin.json index af737142548..e9f99e6ead9 100644 --- a/public/app/plugins/datasource/mixed/plugin.json +++ b/public/app/plugins/datasource/mixed/plugin.json @@ -1,15 +1,11 @@ { "pluginType": "datasource", "name": "Mixed datasource", + "hide": true, "type": "mixed", "serviceName": "MixedDatasource", "module": "plugins/datasource/mixed/datasource", - - "partials": { - "query": "app/plugins/datasource/mixed/partials/query.editor.html" - }, - "metrics": true } diff --git a/public/app/plugins/datasource/opentsdb/directives.js b/public/app/plugins/datasource/opentsdb/directives.js new file mode 100644 index 00000000000..3ff4c3c2ccc --- /dev/null +++ b/public/app/plugins/datasource/opentsdb/directives.js @@ -0,0 +1,16 @@ +define([ + 'angular', +], +function (angular) { + 'use strict'; + + var module = angular.module('grafana.directives'); + + module.directive('metricQueryEditorOpentsdb', function() { + return { + controller: 'OpenTSDBQueryCtrl', + templateUrl: 'app/plugins/datasource/opentsdb/partials/query.editor.html', + }; + }); + +}); diff --git a/public/app/plugins/datasource/opentsdb/plugin.json b/public/app/plugins/datasource/opentsdb/plugin.json index dd7ab96d828..de0eb037d78 100644 --- a/public/app/plugins/datasource/opentsdb/plugin.json +++ b/public/app/plugins/datasource/opentsdb/plugin.json @@ -8,8 +8,7 @@ "module": "plugins/datasource/opentsdb/datasource", "partials": { - "config": "app/plugins/datasource/opentsdb/partials/config.html", - "query": "app/plugins/datasource/opentsdb/partials/query.editor.html" + "config": "app/plugins/datasource/opentsdb/partials/config.html" }, "metrics": true diff --git a/public/app/plugins/datasource/opentsdb/queryCtrl.js b/public/app/plugins/datasource/opentsdb/queryCtrl.js index 4f16983848f..44c8496ca8a 100644 --- a/public/app/plugins/datasource/opentsdb/queryCtrl.js +++ b/public/app/plugins/datasource/opentsdb/queryCtrl.js @@ -8,13 +8,6 @@ function (angular, _, kbn) { var module = angular.module('grafana.controllers'); - module.directive('metricQueryEditorOpentsdb', function() { - return { - controller: 'OpenTSDBQueryCtrl', - templateUrl: 'app/plugins/datasource/opentsdb/partials/query.editor.html', - }; - }); - module.controller('OpenTSDBQueryCtrl', function($scope, $timeout) { $scope.init = function() { From 56d5b0b12a633e80fc0c946e4d07de80723f86be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 17 Aug 2015 10:31:54 +0200 Subject: [PATCH 08/15] feat(mixed datasource): minor progress --- public/app/partials/metrics.html | 6 +++--- public/css/less/bootswatch.dark.less | 8 -------- public/vendor/bootstrap/less/bootstrap.less | 1 + 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index 7b30c42a066..80ab429e950 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -14,7 +14,7 @@
    - - +
    diff --git a/public/app/plugins/datasource/grafana/plugin.json b/public/app/plugins/datasource/grafana/plugin.json index 2baffb991eb..b32045b9ef8 100644 --- a/public/app/plugins/datasource/grafana/plugin.json +++ b/public/app/plugins/datasource/grafana/plugin.json @@ -1,7 +1,7 @@ { "pluginType": "datasource", - "name": "Grafana (for testing)", - "hide": true, + "name": "Grafana", + "builtIn": true, "type": "grafana", "serviceName": "GrafanaDatasource", diff --git a/public/app/plugins/datasource/graphite/plugin.json b/public/app/plugins/datasource/graphite/plugin.json index d45c446f40f..dd69d847bd4 100644 --- a/public/app/plugins/datasource/graphite/plugin.json +++ b/public/app/plugins/datasource/graphite/plugin.json @@ -8,7 +8,7 @@ "module": "plugins/datasource/graphite/datasource", "partials": { - "config": "app/plugins/datasource/graphite/partials/config.html", + "config": "app/plugins/datasource/graphite/partials/config.html" }, "metrics": true, diff --git a/public/app/plugins/datasource/influxdb/plugin.json b/public/app/plugins/datasource/influxdb/plugin.json index 560b7cfb8f9..3511ed8c167 100644 --- a/public/app/plugins/datasource/influxdb/plugin.json +++ b/public/app/plugins/datasource/influxdb/plugin.json @@ -8,7 +8,7 @@ "module": "plugins/datasource/influxdb/datasource", "partials": { - "config": "app/plugins/datasource/influxdb/partials/config.html", + "config": "app/plugins/datasource/influxdb/partials/config.html" }, "metrics": true, diff --git a/public/app/plugins/datasource/mixed/plugin.json b/public/app/plugins/datasource/mixed/plugin.json index e9f99e6ead9..c8327d6e4fc 100644 --- a/public/app/plugins/datasource/mixed/plugin.json +++ b/public/app/plugins/datasource/mixed/plugin.json @@ -1,7 +1,8 @@ { "pluginType": "datasource", "name": "Mixed datasource", - "hide": true, + "builtIn": true, + "mixed": true, "type": "mixed", "serviceName": "MixedDatasource", diff --git a/public/app/plugins/datasource/opentsdb/datasource.js b/public/app/plugins/datasource/opentsdb/datasource.js index b8786761beb..64f6afcdb62 100644 --- a/public/app/plugins/datasource/opentsdb/datasource.js +++ b/public/app/plugins/datasource/opentsdb/datasource.js @@ -3,6 +3,7 @@ define([ 'lodash', 'kbn', 'moment', + './directives', './queryCtrl', ], function (angular, _, kbn) { diff --git a/public/app/services/datasourceSrv.js b/public/app/services/datasourceSrv.js index 35256c9fe4f..644e84e8801 100644 --- a/public/app/services/datasourceSrv.js +++ b/public/app/services/datasourceSrv.js @@ -20,13 +20,24 @@ function (angular, _, config) { if (value.meta && value.meta.metrics) { self.metricSources.push({ value: key === config.defaultDatasource ? null : key, - name: key + name: key, + meta: value.meta, }); } if (value.meta && value.meta.annotations) { self.annotationSources.push(value); } }); + + this.metricSources.sort(function(a, b) { + if (a.meta.builtIn || a.name > b.name) { + return 1; + } + if (a.name < b.name) { + return -1; + } + return 0; + }); }; this.get = function(name) { diff --git a/public/vendor/bootstrap/less/bootstrap.less b/public/vendor/bootstrap/less/bootstrap.less index 79621cebf4c..9529c54cda4 100644 --- a/public/vendor/bootstrap/less/bootstrap.less +++ b/public/vendor/bootstrap/less/bootstrap.less @@ -32,7 +32,7 @@ // Components: Buttons & Alerts @import "buttons.less"; -// @import "button-groups.less"; +@import "button-groups.less"; @import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less // Components: Nav From b4115b036234e5c413af437ee3e2b2ee481a583b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 17 Aug 2015 17:28:03 +0200 Subject: [PATCH 10/15] feat(query editor): updated influxdb 0.8.x data source query editors to new abstraction --- public/app/partials/metrics.html | 2 +- .../datasource/influxdb_08/datasource.js | 1 + .../datasource/influxdb_08/directives.js | 21 + .../influxdb_08/partials/query.editor.html | 392 +++++++----------- .../influxdb_08/partials/query.options.html | 85 ++++ .../datasource/influxdb_08/plugin.json | 4 +- 6 files changed, 261 insertions(+), 244 deletions(-) create mode 100644 public/app/plugins/datasource/influxdb_08/directives.js create mode 100644 public/app/plugins/datasource/influxdb_08/partials/query.options.html diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index dd7199c336c..4aaffed9791 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -1,7 +1,7 @@
    - +
    diff --git a/public/app/plugins/datasource/influxdb_08/datasource.js b/public/app/plugins/datasource/influxdb_08/datasource.js index 0e4adba072c..5c1590168f1 100644 --- a/public/app/plugins/datasource/influxdb_08/datasource.js +++ b/public/app/plugins/datasource/influxdb_08/datasource.js @@ -4,6 +4,7 @@ define([ 'kbn', './influxSeries', './queryBuilder', + './directives', './queryCtrl', './funcEditor', ], diff --git a/public/app/plugins/datasource/influxdb_08/directives.js b/public/app/plugins/datasource/influxdb_08/directives.js new file mode 100644 index 00000000000..35a29975442 --- /dev/null +++ b/public/app/plugins/datasource/influxdb_08/directives.js @@ -0,0 +1,21 @@ +define([ + 'angular', +], +function (angular) { + 'use strict'; + + var module = angular.module('grafana.directives'); + + module.directive('metricQueryEditorInfluxdb08', function() { + return {controller: 'InfluxQueryCtrl_08', templateUrl: 'app/plugins/datasource/influxdb_08/partials/query.editor.html'}; + }); + + module.directive('metricQueryOptionsInfluxdb08', function() { + return {templateUrl: 'app/plugins/datasource/influxdb_08/partials/query.options.html'}; + }); + + module.directive('annotationsQueryEditorInfluxdb08', function() { + return {templateUrl: 'app/plugins/datasource/influxdb_08/partials/annotations.editor.html'}; + }); + +}); diff --git a/public/app/plugins/datasource/influxdb_08/partials/query.editor.html b/public/app/plugins/datasource/influxdb_08/partials/query.editor.html index 6744e00e5b1..61622d1069c 100644 --- a/public/app/plugins/datasource/influxdb_08/partials/query.editor.html +++ b/public/app/plugins/datasource/influxdb_08/partials/query.editor.html @@ -1,256 +1,168 @@ -
    -
    -
    - +
    + - + - -
      -
    • - -
    • -
    + +
      +
    • + +
    • +
    - - -
    -
    - -
    - -
      -
    • - -
    • -
    • - alias -
    • -
    • - -
    • -
    • - group by time -
    • -
    • - -
    • -
    - - - -
    -
    -
    +
    -
    -
    -
      -
    • - -
    • -
    • - group by time -
    • -
    • - -
    • -
    • - -
    • -
    -
    -
    +
    + +
      +
    • + +
    • +
    • + alias +
    • +
    • + +
    • +
    • + group by time +
    • +
    • + +
    • +
    - -
    + + +
    diff --git a/public/app/plugins/datasource/influxdb_08/partials/query.options.html b/public/app/plugins/datasource/influxdb_08/partials/query.options.html new file mode 100644 index 00000000000..413616fb4be --- /dev/null +++ b/public/app/plugins/datasource/influxdb_08/partials/query.options.html @@ -0,0 +1,85 @@ +
    +
    +
      +
    • + +
    • +
    • + group by time +
    • +
    • + +
    • +
    • + +
    • +
    +
    +
    + + +
    + +
    +
    + +
    +
    Alias patterns
    +
      +
    • $s = series name
    • +
    • $g = group by
    • +
    • $[0-9] part of series name for series names seperated by dots.
    • +
    +
    + +
    +
    Stacking and fill
    +
      +
    • When stacking is enabled it important that points align
    • +
    • If there are missing points for one series it can cause gaps or missing bars
    • +
    • You must use fill(0), and select a group by time low limit
    • +
    • Use the group by time option below your queries and specify for example >10s if your metrics are written every 10 seconds
    • +
    • This will insert zeros for series that are missing measurements and will make stacking work properly
    • +
    +
    + +
    +
    Group by time
    +
      +
    • Group by time is important, otherwise the query could return many thousands of datapoints that will slow down Grafana
    • +
    • Leave the group by time field empty for each query and it will be calculated based on time range and pixel width of the graph
    • +
    • If you use fill(0) or fill(null) set a low limit for the auto group by time interval
    • +
    • The low limit can only be set in the group by time option below your queries
    • +
    • You set a low limit by adding a greater sign before the interval
    • +
    • Example: >60s if you write metrics to InfluxDB every 60 seconds
    • +
    +
    + + +
    +
    + + diff --git a/public/app/plugins/datasource/influxdb_08/plugin.json b/public/app/plugins/datasource/influxdb_08/plugin.json index 16dedc730a8..5b88ba2736a 100644 --- a/public/app/plugins/datasource/influxdb_08/plugin.json +++ b/public/app/plugins/datasource/influxdb_08/plugin.json @@ -8,9 +8,7 @@ "module": "plugins/datasource/influxdb_08/datasource", "partials": { - "config": "app/plugins/datasource/influxdb_08/partials/config.html", - "query": "app/plugins/datasource/influxdb_08/partials/query.editor.html", - "annotations": "app/plugins/datasource/influxdb_08/partials/annotations.editor.html" + "config": "app/plugins/datasource/influxdb_08/partials/config.html" }, "metrics": true, From 95f1343a591c492403dc41e36cf8f6be7698b95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 17 Aug 2015 20:53:40 +0200 Subject: [PATCH 11/15] feat(mixed datasource): fixing varios issues with the query editor changes, updated kariosdb data source editor to work with the new model, #436 --- public/app/directives/giveFocus.js | 7 +- public/app/directives/metric.segment.js | 2 +- .../influxdb/partials/query.editor.html | 2 +- .../influxdb_08/partials/query.editor.html | 13 +- .../plugins/datasource/kairosdb/datasource.js | 1 + .../plugins/datasource/kairosdb/directives.js | 17 + .../kairosdb/partials/query.editor.html | 696 ++++++++---------- .../kairosdb/partials/query.options.html | 37 + .../plugins/datasource/kairosdb/plugin.json | 3 +- 9 files changed, 388 insertions(+), 390 deletions(-) create mode 100644 public/app/plugins/datasource/kairosdb/directives.js create mode 100644 public/app/plugins/datasource/kairosdb/partials/query.options.html diff --git a/public/app/directives/giveFocus.js b/public/app/directives/giveFocus.js index ef395d27fbd..6493676e0f9 100644 --- a/public/app/directives/giveFocus.js +++ b/public/app/directives/giveFocus.js @@ -16,8 +16,11 @@ function (angular) { } setTimeout(function() { element.focus(); - var pos = element.val().length * 2; - element[0].setSelectionRange(pos, pos); + var domEl = element[0]; + if (domEl.setSelectionRange) { + var pos = element.val().length * 2; + domEl.setSelectionRange(pos, pos); + } }, 200); },true); }; diff --git a/public/app/directives/metric.segment.js b/public/app/directives/metric.segment.js index c585be21291..3b5f473b6dc 100644 --- a/public/app/directives/metric.segment.js +++ b/public/app/directives/metric.segment.js @@ -15,7 +15,7 @@ function (angular, app, _, $) { ' spellcheck="false" style="display:none">'; var buttonTemplate = ''; + 'tabindex="1" give-focus="segment.focus" ng-bind-html="segment.html">'; return { scope: { diff --git a/public/app/plugins/datasource/influxdb/partials/query.editor.html b/public/app/plugins/datasource/influxdb/partials/query.editor.html index 7f800420b9c..17bdc0647b8 100644 --- a/public/app/plugins/datasource/influxdb/partials/query.editor.html +++ b/public/app/plugins/datasource/influxdb/partials/query.editor.html @@ -49,7 +49,7 @@
    - -
  • -
  • - - - +
  • + {{target.datasource}}
  • @@ -51,9 +43,7 @@ {{target.refId}}
  • - +
  • From 3de041a4116d7aeed8f9e8420e5fc314d7e95af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 17 Aug 2015 21:25:08 +0200 Subject: [PATCH 13/15] feat(mixed datasource): added datasource name to left of query hamburger #436 --- .../graphite/partials/query.editor.html | 2 +- .../influxdb/partials/query.editor.html | 28 ++++++------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/public/app/plugins/datasource/graphite/partials/query.editor.html b/public/app/plugins/datasource/graphite/partials/query.editor.html index 9ae415369ae..3608c2573cb 100755 --- a/public/app/plugins/datasource/graphite/partials/query.editor.html +++ b/public/app/plugins/datasource/graphite/partials/query.editor.html @@ -6,7 +6,7 @@
  • - {{target.datasource}} + {{target.datasource}}
  • -
  • - - - +
  • + {{target.datasource}}
  • From 5c2d49f7ced85e2169c16fc845964cb256c8c1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 18 Aug 2015 07:57:58 +0200 Subject: [PATCH 14/15] feat(mixed datasource): updated Elasticsearch so it uses new way to define annotations editor --- .../plugins/datasource/elasticsearch/datasource.js | 3 ++- .../plugins/datasource/elasticsearch/directives.js | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 public/app/plugins/datasource/elasticsearch/directives.js diff --git a/public/app/plugins/datasource/elasticsearch/datasource.js b/public/app/plugins/datasource/elasticsearch/datasource.js index 9568b66ad74..bd23f0cc2b2 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.js +++ b/public/app/plugins/datasource/elasticsearch/datasource.js @@ -3,7 +3,8 @@ define([ 'lodash', 'config', 'kbn', - 'moment' + 'moment', + './directives' ], function (angular, _, config, kbn, moment) { 'use strict'; diff --git a/public/app/plugins/datasource/elasticsearch/directives.js b/public/app/plugins/datasource/elasticsearch/directives.js new file mode 100644 index 00000000000..8ab75f8e4ad --- /dev/null +++ b/public/app/plugins/datasource/elasticsearch/directives.js @@ -0,0 +1,13 @@ +define([ + 'angular', +], +function (angular) { + 'use strict'; + + var module = angular.module('grafana.directives'); + + module.directive('annotationsQueryEditorElasticsearch', function() { + return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/annotations.editor.html'}; + }); + +}); From d4432ddd64b1bd711d15104d115f46d2d3e51fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 18 Aug 2015 08:21:53 +0200 Subject: [PATCH 15/15] feat(mixed datasources): feature ready to merge to master, closes #436 --- CHANGELOG.md | 12 +++++++- docs/sources/datasources/plugin_api.md | 40 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 docs/sources/datasources/plugin_api.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bcd1fbd231..9b0869df7ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,22 @@ # 2.2 (unreleased) -**New Features && Enhancements** +** New Feature: Mix data sources ** +A built in data source is now available named `-- Mixed --`, When picked in the metrics tab, +it allows you to add queries of differnet data source types & instances to the same graph/panel! +[Issue #436](https://github.com/grafana/grafana/issues/436) + +** Other new Features && Enhancements** - [Issue #2457](https://github.com/grafana/grafana/issues/2457). Admin: admin page for all grafana organizations (list / edit view) - [Issue #1186](https://github.com/grafana/grafana/issues/1186). Time Picker: New option `today`, will set time range from midnight to now **Fixes** - [Issue #2490](https://github.com/grafana/grafana/issues/2490). Graphite: Dashboard import was broken in 2.1 and 2.1.1, working now +** Breaking Changes ** +- Notice to makers/users of custom data sources, there is a minor breaking change in 2.2 that +require and update to custom data sources for them to work in 2.2. [Read this doc](https://github.com/grafana/grafana/tree/master/docs/sources/datasources/plugin_api.md) for more on the +data source api change. + # 2.1.1 (2015-08-11) **Fixes** diff --git a/docs/sources/datasources/plugin_api.md b/docs/sources/datasources/plugin_api.md new file mode 100644 index 00000000000..cdcaca29460 --- /dev/null +++ b/docs/sources/datasources/plugin_api.md @@ -0,0 +1,40 @@ +---- +page_title: Data source Plugin API +page_description: Data Source Plugin Description +page_keywords: grafana, data source, plugin, api, docs +--- + +# Data source plugin API + +All data sources in Grafana are implemented as plugins. + +## Breaking change in 2.2 + +In Grafana 2.2 a breaking change was introduced for how data source query editors +are structured, defined and loaded. This was in order to support mixing multiple data sources +in the same panel. + +In Grafana 2.2, the query editor is no longer defined using the partials section in +`plugin.json`, but defined via an angular directive named using convention naming +scheme like `metricQueryEditor`. For example + +Graphite defines a directive like this: + +```javascript +module.directive('metricQueryEditorGraphite', function() { + return {controller: 'GraphiteQueryCtrl', templateUrl: 'app/plugins/datasource/graphite/partials/query.editor.html'}; +}); +``` + +Even though the data source type name is with lowercase `g`, the directive uses capital `G` in `Graphite` because +that is how angular directives needs to be named in order to match an element with name ``. +You also specify the query controller here instead of in the query.editor.html partial like before. + +### query.editor.html + +This partial needs to be updated, remove the `np-repeat` this is done in the outer partial now,m the query.editor.html +should only render a single query. Take a look at the Graphite or InfluxDB partials for `query.editor.html` for reference. +You should also add a `tight-form-item` with `{{target.refId}}`, all queries needs to be assigned a letter (`refId`). +These query reference letters are going to be utilized in a later feature. + +