Просмотр исходного кода

feat(mutli db query): major changes to query editor and data source handling, looks promising

Torkel Ödegaard 10 лет назад
Родитель
Сommit
b9cfade18c

+ 42 - 4
public/app/features/panel/panelDirective.js

@@ -44,10 +44,48 @@ function (angular, $, config) {
     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);
+        var editorScope;
+
+        scope.$watch("panel.datasource", function() {
+          var datasource = scope.target.datasource || scope.panel.datasource;
+
+          datasourceSrv.get(datasource).then(function(ds) {
+            if (editorScope) {
+              editorScope.$destroy();
+              elem.empty();
+            }
+
+            editorScope = scope.$new();
+            editorScope.datasource = ds;
+
+            var panelEl = angular.element(document.createElement('metric-query-editor-' + ds.meta.type));
+            elem.append(panelEl);
+            $compile(panelEl)(editorScope);
+          });
+        });
+      }
+    };
+  });
+
+  module.directive('queryOptionsLoader', function($compile, $parse, datasourceSrv) {
+    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);
+          });
         });
       }
     };

+ 2 - 2
public/app/features/panel/panelSrv.js

@@ -43,8 +43,8 @@ function (angular, _, config) {
         });
       };
 
-      $scope.addDataQuery = function() {
-        $scope.panel.targets.push({target: ''});
+      $scope.addDataQuery = function(datasource) {
+        $scope.panel.targets.push({target: '', datasource: datasource});
       };
 
       $scope.removeDataQuery = function (query) {

+ 33 - 15
public/app/partials/metrics.html

@@ -1,31 +1,49 @@
 <div class="editor-row">
 
-	<!-- <div ng&#45;include src="datasource.meta.partials.query"></div> -->
+	<div class="tight-form-container">
+		<query-editor-loader ng-repeat="target in panel.targets">
+		</query-editor-loader>
+	</div>
 
-	<query-editor-loader ng-repeat="target in panel.targets">
-	</query-editor-loader>
+	<div style="margin: 20px 0 0 0">
+		<button class="btn btn-inverse" ng-click="addDataQuery(panel.target)" ng-if="datasource.meta.type !== 'grafana'">
+			<i class="fa fa-plus"></i>&nbsp;
+			Query
+		</button>
+
+		<span class="dropdown" ng-if="datasource.meta.type === 'grafana'">
+			<button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown">
+				<i class="fa fa-plus"></i>&nbsp;
+				Query
+			</button>
+
+			<ul class="dropdown-menu" role="menu">
+				<li ng-repeat="datasource in datasources" role="menuitem">
+					<a ng-click="addDataQuery(datasource.value);">{{datasource.name}}</a>
+				</li>
+			</ul>
+		</span>
+
+	</div>
+
+	<query-options-loader></query-options-loader>
 
- 	</div>
 </div>
 
 <div class="editor-row" style="margin-top: 30px">
-	<button class="btn btn-inverse pull-right" ng-click="addDataQuery(panel.target)">
-		<i class="fa fa-plus"></i>&nbsp;
-		Add query
-	</button>
 
-  <div class="pull-right dropdown" style="margin-right: 10px;">
+	<div class="pull-right dropdown" style="margin-right: 10px;">
 		<button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown" bs-tooltip="'Datasource'">
 			<i class="fa fa-database"></i>&nbsp;
 			{{datasource.name}} <span class="caret"></span>
 		</button>
 
-    <ul class="dropdown-menu" role="menu">
-      <li ng-repeat="datasource in datasources" role="menuitem">
-        <a ng-click="setDatasource(datasource.value);">{{datasource.name}}</a>
-      </li>
-    </ul>
-  </div>
+		<ul class="dropdown-menu" role="menu">
+			<li ng-repeat="datasource in datasources" role="menuitem">
+				<a ng-click="setDatasource(datasource.value);">{{datasource.name}}</a>
+			</li>
+		</ul>
+	</div>
 
 	<div class="clearfix"></div>
 </div>

+ 11 - 6
public/app/plugins/datasource/grafana/datasource.js

@@ -8,7 +8,7 @@ function (angular, _, kbn) {
 
   var module = angular.module('grafana.services');
 
-  module.factory('GrafanaDatasource', function($q, backendSrv) {
+  module.factory('GrafanaDatasource', function($q, backendSrv, datasourceSrv) {
 
     function GrafanaDatasource() {
     }
@@ -24,11 +24,16 @@ function (angular, _, kbn) {
     };
 
     GrafanaDatasource.prototype.query = function(options) {
-      // 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 });
+      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 });
     };
 
     GrafanaDatasource.prototype.metricFindQuery = function() {

+ 0 - 133
public/app/plugins/datasource/graphite/partials/query.editor.html

@@ -80,136 +80,3 @@
 		<div class="clearfix"></div>
 	</div>
 </div>
-
-<!-- <section class="grafana&#45;metric&#45;options"> -->
-	<!-- 	<div class="tight&#45;form"> -->
-		<!-- 		<ul class="tight&#45;form&#45;list"> -->
-			<!-- 			<li class="tight&#45;form&#45;item tight&#45;form&#45;item&#45;icon"> -->
-				<!-- 				<i class="fa fa&#45;wrench"></i> -->
-				<!-- 			</li> -->
-			<!-- 			<li class="tight&#45;form&#45;item"> -->
-				<!-- 				Cache timeout -->
-				<!-- 			</li> -->
-			<!-- 			<li> -->
-				<!-- 				<input type="text" -->
-					<!-- 				class="input&#45;mini tight&#45;form&#45;input" -->
-					<!-- 				ng&#45;model="panel.cacheTimeout" -->
-					<!-- 				bs&#45;tooltip="'Graphite parameter to override memcache default timeout (unit is seconds)'" -->
-					<!-- 				data&#45;placement="right" -->
-					<!-- 				spellcheck='false' -->
-					<!-- 				placeholder="60"> -->
-					<!-- 			</li> -->
-				<!-- 			<li class="tight&#45;form&#45;item"> -->
-					<!-- 				Max data points -->
-					<!-- 			</li> -->
-				<!-- 			<li> -->
-					<!-- 				<input type="text" -->
-						<!-- 				class="input&#45;mini tight&#45;form&#45;input" -->
-						<!-- 				ng&#45;model="panel.maxDataPoints" -->
-						<!-- 				bs&#45;tooltip="'Override max data points, automatically set to graph width in pixels.'" -->
-						<!-- 				data&#45;placement="right" -->
-						<!-- 				ng&#45;model&#45;onblur ng&#45;change="get_data()" -->
-						<!-- 				spellcheck='false' -->
-						<!-- 				placeholder="auto"> -->
-						<!-- 			</li> -->
-					<!-- 		</ul> -->
-				<!-- 		<div class="clearfix"></div> -->
-				<!-- 	</div> -->
-			<!-- 	<div class="tight&#45;form"> -->
-				<!-- 		<ul class="tight&#45;form&#45;list"> -->
-					<!-- 			<li class="tight&#45;form&#45;item tight&#45;form&#45;item&#45;icon"> -->
-						<!-- 				<i class="fa fa&#45;info&#45;circle"></i> -->
-						<!-- 			</li> -->
-					<!-- 			<li class="tight&#45;form&#45;item"> -->
-						<!-- 				<a ng&#45;click="toggleEditorHelp(1);" bs&#45;tooltip="'click to show helpful info'" data&#45;placement="bottom"> -->
-							<!-- 					shorter legend names -->
-							<!-- 				</a> -->
-						<!-- 			</li> -->
-					<!-- 			<li class="tight&#45;form&#45;item"> -->
-						<!-- 				<a ng&#45;click="toggleEditorHelp(2);" bs&#45;tooltip="'click to show helpful info'" data&#45;placement="bottom"> -->
-							<!-- 					series as parameters -->
-							<!-- 				</a> -->
-						<!-- 			</li> -->
-					<!-- 			<li class="tight&#45;form&#45;item"> -->
-						<!-- 				<a ng&#45;click="toggleEditorHelp(3)" bs&#45;tooltip="'click to show helpful info'" data&#45;placement="bottom"> -->
-							<!-- 					stacking -->
-							<!-- 				</a> -->
-						<!-- 			</li> -->
-					<!-- 			<li class="tight&#45;form&#45;item"> -->
-						<!-- 				<a ng&#45;click="toggleEditorHelp(4)" bs&#45;tooltip="'click to show helpful info'" data&#45;placement="bottom"> -->
-							<!-- 					templating -->
-							<!-- 				</a> -->
-						<!-- 			</li> -->
-					<!-- 			<li class="tight&#45;form&#45;item"> -->
-						<!-- 				<a ng&#45;click="toggleEditorHelp(5)" bs&#45;tooltip="'click to show helpful info'" data&#45;placement="bottom"> -->
-							<!-- 					max data points -->
-							<!-- 				</a> -->
-						<!-- 			</li> -->
-					<!-- 		</ul> -->
-				<!-- 		<div class="clearfix"></div> -->
-				<!-- 	</div> -->
-			<!-- </section> -->
-		<!--  -->
-		<!-- <div class="editor&#45;row"> -->
-			<!-- 	<div class="pull&#45;left" style="margin&#45;top: 30px;"> -->
-				<!--  -->
-				<!-- 		<div class="grafana&#45;info&#45;box span8" ng&#45;if="editorHelpIndex === 1"> -->
-					<!-- 			<h5>Shorter legend names</h5> -->
-					<!-- 			<ul> -->
-						<!-- 				<li>alias() function to specify a custom series name</li> -->
-						<!-- 				<li>aliasByNode(2) to alias by a specific part of your metric path</li> -->
-						<!-- 				<li>aliasByNode(2, &#45;1) you can add multiple segment paths, and use negative index</li> -->
-						<!-- 				<li>groupByNode(2, 'sum') is useful if you have 2 wildcards in your metric path and want to sumSeries and group by</li> -->
-						<!-- 			</ul> -->
-					<!-- 		</div> -->
-				<!--  -->
-				<!-- 		<div class="grafana&#45;info&#45;box span8" ng&#45;if="editorHelpIndex === 2"> -->
-					<!-- 			<h5>Series as parameter</h5> -->
-					<!-- 			<ul> -->
-						<!-- 				<li>Some graphite functions allow you to have many series arguments</li> -->
-						<!-- 				<li>Use #[A&#45;Z] to use a graphite query as parameter to a function</li> -->
-						<!-- 				<li> -->
-							<!-- 					Examples: -->
-							<!-- 					<ul> -->
-								<!-- 						<li>asPercent(#A, #B)</li> -->
-								<!-- 						<li>prod.srv&#45;01.counters.count &#45; asPercent(#A) : percentage of count in comparison with A query</li> -->
-								<!-- 						<li>prod.srv&#45;01.counters.count &#45; sumSeries(#A) : sum count and series A </li> -->
-								<!-- 						<li>divideSeries(#A, #B)</li> -->
-								<!-- 					</ul> -->
-							<!-- 				</li> -->
-						<!-- 				<li>If a query is added only to be used as a parameter, hide it from the graph with the eye icon</li> -->
-						<!-- 			</ul> -->
-					<!-- 		</div> -->
-				<!--  -->
-				<!-- 		<div class="grafana&#45;info&#45;box span6" ng&#45;if="editorHelpIndex === 3"> -->
-					<!-- 			<h5>Stacking</h5> -->
-					<!-- 			<ul> -->
-						<!-- 				<li>You find the stacking option under Display Styles tab</li> -->
-						<!-- 				<li>When stacking is enabled make sure null point mode is set to 'null as zero'</li> -->
-						<!-- 			</ul> -->
-					<!-- 		</div> -->
-				<!--  -->
-				<!-- 		<div class="grafana&#45;info&#45;box span6" ng&#45;if="editorHelpIndex === 4"> -->
-					<!-- 			<h5>Templating</h5> -->
-					<!-- 			<ul> -->
-						<!-- 				<li>You can use a template variable in place of metric names</li> -->
-						<!-- 				<li>You can use a template variable in place of function parameters</li> -->
-						<!-- 				<li>You enable the templating feature in Dashboard settings / Feature toggles </li> -->
-						<!-- 			</ul> -->
-					<!-- 		</div> -->
-				<!--  -->
-				<!-- 		<div class="grafana&#45;info&#45;box span6" ng&#45;if="editorHelpIndex === 5"> -->
-					<!-- 			<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> -->

+ 132 - 0
public/app/plugins/datasource/graphite/partials/query.options.html

@@ -0,0 +1,132 @@
+<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">
+				Cache timeout
+			</li>
+			<li>
+				<input type="text"
+					class="input-mini tight-form-input"
+					ng-model="panel.cacheTimeout"
+					bs-tooltip="'Graphite parameter to override memcache default timeout (unit is seconds)'"
+					data-placement="right"
+					spellcheck='false'
+					placeholder="60"></input>
+			</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"></input>
+			</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">
+					shorter legend names
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<a ng-click="toggleEditorHelp(2);" bs-tooltip="'click to show helpful info'" data-placement="bottom">
+					series as parameters
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<a ng-click="toggleEditorHelp(3)" bs-tooltip="'click to show helpful info'" data-placement="bottom">
+					stacking
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<a ng-click="toggleEditorHelp(4)" bs-tooltip="'click to show helpful info'" data-placement="bottom">
+					templating
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<a ng-click="toggleEditorHelp(5)" 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 span8" ng-if="editorHelpIndex === 1">
+			<h5>Shorter legend names</h5>
+			<ul>
+				<li>alias() function to specify a custom series name</li>
+				<li>aliasByNode(2) to alias by a specific part of your metric path</li>
+				<li>aliasByNode(2, -1) you can add multiple segment paths, and use negative index</li>
+				<li>groupByNode(2, 'sum') is useful if you have 2 wildcards in your metric path and want to sumSeries and group by</li>
+			</ul>
+		</div>
+
+		<div class="grafana-info-box span8" ng-if="editorHelpIndex === 2">
+			<h5>Series as parameter</h5>
+			<ul>
+				<li>Some graphite functions allow you to have many series arguments</li>
+				<li>Use #[A-Z] to use a graphite query as parameter to a function</li>
+				<li>
+					Examples:
+					<ul>
+						<li>asPercent(#A, #B)</li>
+						<li>prod.srv-01.counters.count - asPercent(#A) : percentage of count in comparison with A query</li>
+						<li>prod.srv-01.counters.count - sumSeries(#A) : sum count and series A </li>
+						<li>divideSeries(#A, #B)</li>
+					</ul>
+				</li>
+				<li>If a query is added only to be used as a parameter, hide it from the graph with the eye icon</li>
+			</ul>
+		</div>
+
+		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 3">
+			<h5>Stacking</h5>
+			<ul>
+				<li>You find the stacking option under Display Styles tab</li>
+				<li>When stacking is enabled make sure null point mode is set to 'null as zero'</li>
+			</ul>
+		</div>
+
+		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 4">
+			<h5>Templating</h5>
+			<ul>
+				<li>You can use a template variable in place of metric names</li>
+				<li>You can use a template variable in place of function parameters</li>
+				<li>You enable the templating feature in Dashboard settings / Feature toggles </li>
+			</ul>
+		</div>
+
+		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 5">
+			<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>

+ 6 - 0
public/app/plugins/datasource/graphite/queryCtrl.js

@@ -18,6 +18,12 @@ function (angular, _, config, gfunc, Parser) {
     };
   });
 
+  module.directive('metricQueryOptionsGraphite', function() {
+    return {
+      templateUrl: 'app/plugins/datasource/graphite/partials/query.options.html',
+    };
+  });
+
   module.controller('GraphiteQueryCtrl', function($scope, $sce, templateSrv) {
 
     $scope.init = function() {

+ 61 - 149
public/app/plugins/datasource/influxdb/partials/query.editor.html

@@ -1,65 +1,63 @@
-<div class="editor-row">
-
-	<div ng-repeat="target in panel.targets" ng-controller="InfluxQueryCtrl" ng-init="init()" ng-class="{'tight-form-disabled': target.hide}" class="tight-form-container-no-item-borders" style="margin-bottom: 10px">
-		<div  class="tight-form">
-			<ul class="tight-form-list pull-right">
-				<li ng-show="parserError" class="tight-form-item">
-					<a bs-tooltip="parserError" style="color: rgb(229, 189, 28)" role="menuitem">
-						<i class="fa fa-warning"></i>
-					</a>
-				</li>
-				<li class="tight-form-item">
-					<a class="pointer" tabindex="1" ng-click="toggleQueryMode()">
-						<i class="fa fa-pencil"></i>
-					</a>
-				</li>
-				<li class="tight-form-item">
-					<div class="dropdown">
-						<a  class="pointer dropdown-toggle"
-							data-toggle="dropdown"
-							tabindex="1">
-							<i class="fa fa-bars"></i>
-						</a>
-						<ul class="dropdown-menu pull-right" role="menu">
-							<li role="menuitem">
-								<a  tabindex="1"
-									ng-click="duplicate()">
-									Duplicate
-								</a>
-							</li>
-							<li role="menuitem">
-								<a  tabindex="1"
-									ng-click="moveMetricQuery($index, $index-1)">
-									Move up
-								</a>
-							</li>
-							<li role="menuitem">
-								<a  tabindex="1"
-									ng-click="moveMetricQuery($index, $index+1)">
-									Move down
-								</a>
-							</li>
-						</ul>
-					</div>
-				</li>
-				<li class="tight-form-item last">
-					<a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
-						<i class="fa fa-remove"></i>
+<div class="tight-form-container-no-item-borders" style="margin-bottom: 10px">
+	<div  class="tight-form">
+		<ul class="tight-form-list pull-right">
+			<li ng-show="parserError" class="tight-form-item">
+				<a bs-tooltip="parserError" style="color: rgb(229, 189, 28)" role="menuitem">
+					<i class="fa fa-warning"></i>
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<a class="pointer" tabindex="1" ng-click="toggleQueryMode()">
+					<i class="fa fa-pencil"></i>
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<div class="dropdown">
+					<a  class="pointer dropdown-toggle"
+						data-toggle="dropdown"
+						tabindex="1">
+						<i class="fa fa-bars"></i>
 					</a>
-				</li>
-			</ul>
+					<ul class="dropdown-menu pull-right" role="menu">
+						<li role="menuitem">
+							<a  tabindex="1"
+								ng-click="duplicate()">
+								Duplicate
+							</a>
+						</li>
+						<li role="menuitem">
+							<a  tabindex="1"
+								ng-click="moveMetricQuery($index, $index-1)">
+								Move up
+							</a>
+						</li>
+						<li role="menuitem">
+							<a  tabindex="1"
+								ng-click="moveMetricQuery($index, $index+1)">
+								Move down
+							</a>
+						</li>
+					</ul>
+				</div>
+			</li>
+			<li class="tight-form-item last">
+				<a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
+					<i class="fa fa-remove"></i>
+				</a>
+			</li>
+		</ul>
 
-			<ul class="tight-form-list">
-				<li>
-					<a  class="tight-form-item"
-						ng-click="target.hide = !target.hide; get_data();"
-						role="menuitem">
-						<i class="fa fa-eye"></i>
-					</a>
-				</li>
-			</ul>
+		<ul class="tight-form-list">
+			<li>
+				<a  class="tight-form-item"
+					ng-click="target.hide = !target.hide; get_data();"
+					role="menuitem">
+					<i class="fa fa-eye"></i>
+				</a>
+			</li>
+		</ul>
 
-			<input type="text" class="tight-form-clear-input" style="width: 80%" ng-model="target.query" give-focus="target.rawQuery" spellcheck='false' ng-model-onblur ng-change="get_data()" ng-show="target.rawQuery"/>
+		<input type="text" class="tight-form-clear-input" style="width: 80%" ng-model="target.query" give-focus="target.rawQuery" spellcheck='false' ng-model-onblur ng-change="get_data()" ng-show="target.rawQuery"/>
 
 			<ul class="tight-form-list" role="menu" ng-hide="target.rawQuery">
 				<li class="tight-form-item query-keyword" style="width: 75px;">
@@ -151,98 +149,12 @@
 				</li>
 				<li>
 					<input type="text" class="input-medium tight-form-input" ng-model="target.alias" spellcheck='false' placeholder="alias" ng-model-onblur ng-change="get_data()">
-				</li>
-			</ul>
-			<div class="clearfix"></div>
-		</div>
+					</li>
+				</ul>
+				<div class="clearfix"></div>
+			</div>
 
-	</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">
-				 Group by time interval
-			</li>
-			<li>
-				<input type="text" class="input-medium tight-form-input" ng-model="panel.interval" ng-blur="get_data();"
-				spellcheck='false' placeholder="example: >10s">
-			</li>
-			<li class="tight-form-item">
-				<i class="fa fa-question-circle" bs-tooltip="'Set a low limit by having a greater sign: example: >60s'" data-placement="right"></i>
-			</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">
-					alias patterns
-				</a>
-			</li>
-			<li class="tight-form-item">
-				<a ng-click="toggleEditorHelp(2)" bs-tooltip="'click to show helpful info'" data-placement="bottom">
-					stacking &amp; and fill
-				</a>
-			</li>
-			<li class="tight-form-item">
-				<a ng-click="toggleEditorHelp(3)" bs-tooltip="'click to show helpful info'" data-placement="bottom">
-					group by time
-				</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>Alias patterns</h5>
-			<ul>
-				<li>$m = replaced with measurement name</li>
-				<li>$measurement = replaced with measurement name</li>
-				<li>$col = replaced with column name</li>
-				<li>$tag_hostname = replaced with the value of the hostname tag</li>
-				<li>You can also use [[tag_hostname]] pattern replacement syntax</li>
-			</ul>
 		</div>
-
-		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 2">
-			<h5>Stacking and fill</h5>
-			<ul>
-				<li>When stacking is enabled it important that points align</li>
-				<li>If there are missing points for one series it can cause gaps or missing bars</li>
-				<li>You must use fill(0), and select a group by time low limit</li>
-				<li>Use the group by time option below your queries and specify for example &gt;10s if your metrics are written every 10 seconds</li>
-				<li>This will insert zeros for series that are missing measurements and will make stacking work properly</li>
-			</ul>
-		</div>
-
-		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 3">
-			<h5>Group by time</h5>
-			<ul>
-				<li>Group by time is important, otherwise the query could return many thousands of datapoints that will slow down Grafana</li>
-				<li>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</li>
-				<li>If you use fill(0) or fill(null) set a low limit for the auto group by time interval</li>
-				<li>The low limit can only be set in the group by time option below your queries</li>
-				<li>You set a low limit by adding a greater sign before the interval</li>
-				<li>Example: &gt;60s if you write metrics to InfluxDB every 60 seconds</li>
-			</ul>
-		</div>
-
-
 	</div>
-</div>
 
 

+ 87 - 0
public/app/plugins/datasource/influxdb/partials/query.options.html

@@ -0,0 +1,87 @@
+<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">
+				 Group by time interval
+			</li>
+			<li>
+				<input type="text" class="input-medium tight-form-input" ng-model="panel.interval" ng-blur="get_data();"
+				spellcheck='false' placeholder="example: >10s">
+			</li>
+			<li class="tight-form-item">
+				<i class="fa fa-question-circle" bs-tooltip="'Set a low limit by having a greater sign: example: >60s'" data-placement="right"></i>
+			</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">
+					alias patterns
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<a ng-click="toggleEditorHelp(2)" bs-tooltip="'click to show helpful info'" data-placement="bottom">
+					stacking &amp; and fill
+				</a>
+			</li>
+			<li class="tight-form-item">
+				<a ng-click="toggleEditorHelp(3)" bs-tooltip="'click to show helpful info'" data-placement="bottom">
+					group by time
+				</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>Alias patterns</h5>
+			<ul>
+				<li>$m = replaced with measurement name</li>
+				<li>$measurement = replaced with measurement name</li>
+				<li>$col = replaced with column name</li>
+				<li>$tag_hostname = replaced with the value of the hostname tag</li>
+				<li>You can also use [[tag_hostname]] pattern replacement syntax</li>
+			</ul>
+		</div>
+
+		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 2">
+			<h5>Stacking and fill</h5>
+			<ul>
+				<li>When stacking is enabled it important that points align</li>
+				<li>If there are missing points for one series it can cause gaps or missing bars</li>
+				<li>You must use fill(0), and select a group by time low limit</li>
+				<li>Use the group by time option below your queries and specify for example &gt;10s if your metrics are written every 10 seconds</li>
+				<li>This will insert zeros for series that are missing measurements and will make stacking work properly</li>
+			</ul>
+		</div>
+
+		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 3">
+			<h5>Group by time</h5>
+			<ul>
+				<li>Group by time is important, otherwise the query could return many thousands of datapoints that will slow down Grafana</li>
+				<li>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</li>
+				<li>If you use fill(0) or fill(null) set a low limit for the auto group by time interval</li>
+				<li>The low limit can only be set in the group by time option below your queries</li>
+				<li>You set a low limit by adding a greater sign before the interval</li>
+				<li>Example: &gt;60s if you write metrics to InfluxDB every 60 seconds</li>
+			</ul>
+		</div>
+
+
+	</div>
+</div>
+
+

+ 15 - 0
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();
+
   });
 
 });

+ 3 - 4
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 {