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

Lots of progress on per series overrides

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

+ 1 - 1
package.json

@@ -34,7 +34,7 @@
     "grunt-string-replace": "~0.2.4",
     "grunt-usemin": "^2.1.1",
     "jshint-stylish": "~0.1.5",
-    "karma": "~0.12.16",
+    "karma": "~0.12.21",
     "karma-chrome-launcher": "~0.1.4",
     "karma-coffee-preprocessor": "~0.1.2",
     "karma-coverage": "^0.2.5",

+ 1 - 1
src/app/directives/grafanaGraph.js

@@ -156,7 +156,7 @@ function (angular, $, kbn, moment, _) {
           for (var i = 0; i < data.length; i++) {
             var _d = data[i].getFlotPairs(panel.nullPointMode, panel.y_formats);
             data[i].data = _d;
-            data[0].lines = { show: false };
+            data[0].lines = { show: false, dashes: true };
             data[0].bars = { show: true  };
           }
 

+ 1 - 1
src/app/panels/graph/module.html

@@ -27,7 +27,7 @@
       </div>
     </div>
 
-    <div class="tab-content" ng-repeat="tab in panelMeta.fullEditorTabs" ng-show="editorTabs[editor.index] == tab.title">
+    <div class="tab-content" ng-repeat="tab in panelMeta.fullEditorTabs" ng-if="editorTabs[editor.index] == tab.title">
       <div ng-include src="tab.src"></div>
     </div>
   </div>

+ 6 - 57
src/app/panels/graph/module.js

@@ -1,16 +1,3 @@
-/** @scratch /panels/5
- * include::panels/histogram.asciidoc[]
- */
-
-/** @scratch /panels/histogram/0
- * == Histogram
- * Status: *Stable*
- *
- * The histogram panel allow for the display of time charts. It includes several modes and tranformations
- * to display event counts, mean, min, max and total of numeric fields, and derivatives of counter
- * fields.
- *
- */
 define([
   'angular',
   'app',
@@ -19,6 +6,7 @@ define([
   'kbn',
   'moment',
   './timeSeries',
+  './seriesOverridesCtrl',
   'services/panelSrv',
   'services/annotationsSrv',
   'services/datasourceSrv',
@@ -30,10 +18,9 @@ define([
   'jquery.flot.stackpercent'
 ],
 function (angular, app, $, _, kbn, moment, timeSeries) {
-
   'use strict';
 
-  var module = angular.module('grafana.panels.graph', []);
+  var module = angular.module('grafana.panels.graph');
   app.useModule(module);
 
   module.controller('GraphCtrl', function($scope, $rootScope, $timeout, panelSrv, annotationsSrv) {
@@ -363,49 +350,11 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
       $scope.panel.seriesOverrides.push({});
     };
 
+    $scope.removeSeriesOverride = function(override) {
+      $scope.panel.seriesOverrides = _.without($scope.panel.seriesOverrides, override);
+    };
+
     panelSrv.init($scope);
   });
 
-  angular
-    .module('grafana.directives')
-    .directive('seriesOverrideOption', function($compile) {
-      var template =
-          '<div class="dropdown"> ' +
-             '<a  class="dropdown-toggle" gf-dropdown="options" data-toggle="dropdown">' +
-                '<i class="icon-minus"></i></a>' +
-          '</div>';
-
-      return {
-        scope: true,
-        link: function($scope, elem, attrs) {
-          var $template = $(template);
-          elem.append($template);
-          var $link = $(elem).find('a');
-
-          $scope.options = $scope.$eval(attrs.options);
-          $scope.options.unshift(null);
-
-          $scope.options = _.map($scope.options, function(option, index) {
-            return {
-              text: option === null ? '<i class="icon-minus"></i>' : String(option),
-              value: option,
-              click: 'setValue(' + index + ')'
-            };
-          });
-
-          $scope.setValue = function(index) {
-            var value = $scope.options[index].value;
-            if (value === null) {
-              $link.html('<i class="icon-minus"></i>');
-            }
-            else {
-              $link.html(value);
-            }
-          };
-
-          $compile(elem.contents())($scope);
-        }
-      };
-    });
-
 });

+ 66 - 0
src/app/panels/graph/seriesOverridesCtrl.js

@@ -0,0 +1,66 @@
+define([
+  'angular',
+  'app',
+  'lodash',
+], function(angular, app, _) {
+  'use strict';
+
+  var module = angular.module('grafana.panels.graph', []);
+  app.useModule(module);
+
+  module.controller('SeriesOverridesCtrl', function($scope) {
+    $scope.overrideMenu = [];
+    $scope.currentOverrides = [];
+    $scope.override = $scope.override || {};
+
+    $scope.addOverrideOption = function(name, propertyName, values) {
+      var option = {};
+      option.text = name;
+      option.propertyName = propertyName;
+      option.index = $scope.overrideMenu.length;
+      option.values = values;
+
+      option.submenu = _.map(values, function(value, index) {
+        return {
+          text: String(value),
+          click: 'setOverride(' + option.index + ',' + index + ')'
+        };
+      });
+
+      $scope.overrideMenu.push(option);
+    };
+
+    $scope.setOverride = function(optionIndex, valueIndex) {
+      var option = $scope.overrideMenu[optionIndex];
+      var value = option.values[valueIndex];
+      $scope.override[option.propertyName] = value;
+      $scope.updateCurrentOverrides();
+    };
+
+    $scope.removeOverride = function(option) {
+      delete $scope.override[option.propertyName];
+      $scope.updateCurrentOverrides();
+    };
+
+    $scope.updateCurrentOverrides = function() {
+      $scope.currentOverrides = [];
+      _.each($scope.overrideMenu, function(option) {
+        if (!_.isUndefined($scope.override[option.propertyName])) {
+          $scope.currentOverrides.push({
+            name: option.text,
+            propertyName: option.propertyName,
+            value: String($scope.override[option.propertyName])
+          });
+        }
+      });
+    };
+
+    $scope.addOverrideOption('Bars', 'bars', [true, false]);
+    $scope.addOverrideOption('Lines', 'lines', [true, false]);
+    $scope.addOverrideOption('Points', 'points', [true, false]);
+    $scope.addOverrideOption('Line fill', 'fill', [1,2,3,4,5,6,7,8]);
+    $scope.updateCurrentOverrides();
+
+  });
+
+});

+ 37 - 30
src/app/panels/graph/styleEditor.html

@@ -66,36 +66,43 @@
 <div class="editor-row">
   <div class="section">
 		<h5>Series specific overrides</h5>
-		<table class="table table-striped">
-			<tr>
-				<th>Series alias/regex</th>
-				<th>Bars</th>
-				<th>Lines</th>
-				<th>Points</th>
-				<th>Fill</th>
-				<th>Width</th>
-				<th>Radius</th>
-				<th>Staircase</th>
-				<th>Stack</th>
-				<th>Y-axis</th>
-				<th>Z-index</th>
-				<th>Color</th>
-			</tr>
-			<tr ng-repeat="override in panel.seriesOverrides">
-				<td>
-					<input type="text" class="input input-medium">
-				</td>
-				<td>
-					<series-override-option data-options="[true, false]" data-attr="override.bars">
-					</series-override-option>
-				</td>
-				<td>
-					<series-override-option data-options="[1,2,3,4,5]">
-					</series-override-option>
-				</td>
-			</tr>
-		</table>
-		<button class="btn btn-success" ng-click="addSeriesOverride()">Add</button>
 
+		<div class="grafana-target" ng-repeat="override in panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
+			<div class="grafana-target-inner-wrapper">
+				<div class="grafana-target-inner">
+
+					<ul class="grafana-target-controls-left">
+						<li>
+							<a class="grafana-target-segment" ng-click="removeSeriesOverride(override)" role="menuitem">
+								<i class="icon-remove"></i>
+							</a>
+						</li>
+					</ul>
+
+					<ul class="grafana-segment-list">
+						<li class="grafana-target-segment">
+							alias or regex
+						</li>
+						<li>
+							<input type="text" class="input-medium grafana-target-segment-input" >
+						</li>
+						<li class="grafana-target-segment" ng-repeat="option in currentOverrides">
+							<a class="pointer" ng-click="removeOverride(option)">
+								<i class="icon-remove"></i>
+							</a>
+							{{option.name}}: {{option.value}}
+						</li>
+						<li class="dropdown">
+							<a class="dropdown-toggle grafana-target-segment" data-toggle="dropdown" gf-dropdown="overrideMenu" bs-tooltip="'set option to override'">
+								<i class="icon-plus"></i>
+							</a>
+						</li>
+					</ul>
+					<div class="clearfix"></div>
+				</div>
+			</div>
+		</div>
+
+		<button class="btn btn-success" style="margin-top: 20px" ng-click="addSeriesOverride()">Add series override rule</button>
 	</div>
 </div>

+ 14 - 0
src/css/less/graph.less

@@ -154,3 +154,17 @@
 .annotation-tags {
   color: @purple;
 }
+
+.graph-series-override {
+  input {
+    float: left;
+    margin-right: 10px;
+  }
+  .graph-series-override-option {
+    float: left;
+    padding: 2px 6px;
+  }
+  .graph-series-override-selector {
+    float: left;
+  }
+}

+ 68 - 0
src/test/specs/grafanaGraph-specs.js

@@ -0,0 +1,68 @@
+define([
+  './helpers',
+  'angular',
+  'jquery',
+  'directives/grafanaGraph'
+], function(helpers, angular, $) {
+  'use strict';
+
+  describe('grafanaGraph', function() {
+
+    beforeEach(module('grafana.directives'));
+
+    function graphScenario(desc, func)  {
+      describe(desc, function() {
+        var ctx = {};
+        ctx.setup = function (setupFunc) {
+          beforeEach(inject(function($rootScope, $compile) {
+            var scope = $rootScope.$new();
+            var element = angular.element("<div style='width:500px' grafana-graph><div>");
+
+            scope.height = '200px';
+            scope.panel = {
+              legend: {},
+              grid: {},
+              y_formats: []
+            };
+            scope.dashboard = { timezone: 'browser' };
+            scope.range = {
+              from: new Date('2014-08-09 10:00:00'),
+              to: new Date('2014-09-09 13:00:00')
+            };
+
+            setupFunc(scope);
+
+            $compile(element)(scope);
+            scope.$digest();
+            $.plot = ctx.plotSpy = sinon.spy();
+
+            scope.$emit('render', []);
+            ctx.plotData = ctx.plotSpy.getCall(0).args[1];
+            ctx.plotOptions = ctx.plotSpy.getCall(0).args[2];
+          }));
+        };
+
+        func(ctx);
+      });
+    }
+
+    graphScenario('simple lines options', function(ctx) {
+      ctx.setup(function(scope) {
+        scope.panel.lines = true;
+        scope.panel.fill = 5;
+        scope.panel.linewidth = 3;
+        scope.panel.steppedLine = true;
+      });
+
+      it('should configure plot with correct options', function() {
+        expect(ctx.plotOptions.series.lines.show).to.be(true);
+        expect(ctx.plotOptions.series.lines.fill).to.be(0.5);
+        expect(ctx.plotOptions.series.lines.lineWidth).to.be(3);
+        expect(ctx.plotOptions.series.lines.steps).to.be(true);
+      });
+
+    });
+
+  });
+});
+

+ 1 - 1
src/test/specs/helpers.js

@@ -69,7 +69,7 @@ define([
       }
       return {
         from : kbn.parseDate(this.time.from),
-             to : kbn.parseDate(this.time.to)
+        to : kbn.parseDate(this.time.to)
       };
     };
 

+ 40 - 0
src/test/specs/seriesOverridesCtrl-specs.js

@@ -0,0 +1,40 @@
+define([
+  './helpers',
+  'panels/graph/seriesOverridesCtrl'
+], function(helpers) {
+  'use strict';
+
+  describe('SeriesOverridesCtrl', function() {
+    var ctx = new helpers.ControllerTestContext();
+
+    beforeEach(module('grafana.services'));
+    beforeEach(module('grafana.panels.graph'));
+
+    beforeEach(ctx.providePhase());
+    beforeEach(ctx.createControllerPhase('SeriesOverridesCtrl'));
+
+    describe('Controller should init overrideMenu', function() {
+      it('click should include option and value index', function() {
+        expect(ctx.scope.overrideMenu[1].submenu[1].click).to.be('setOverride(1,1)');
+      });
+    });
+
+    describe('When setting an override', function() {
+      beforeEach(function() {
+        ctx.scope.setOverride(1, 0);
+      });
+
+      it('should set override property', function() {
+        expect(ctx.scope.override.lines).to.be(true);
+      });
+
+      it('should update view model', function() {
+        expect(ctx.scope.currentOverrides[0].name).to.be('Lines');
+        expect(ctx.scope.currentOverrides[0].value).to.be('true');
+      });
+    });
+
+  });
+
+});
+

+ 2 - 0
src/test/test-main.js

@@ -122,6 +122,8 @@ require([
     'specs/graphiteTargetCtrl-specs',
     'specs/influxdb-datasource-specs',
     'specs/graph-ctrl-specs',
+    'specs/grafanaGraph-specs',
+    'specs/seriesOverridesCtrl-specs',
     'specs/filterSrv-specs',
     'specs/kbn-format-specs',
     'specs/dashboardSrv-specs',