Browse Source

fix(panel): fixes for panel height and alignment management and scrollable legends, closes #4266

Torkel Ödegaard 9 years ago
parent
commit
260c731f6b

+ 0 - 5
public/app/features/dashboard/viewStateSrv.js

@@ -129,7 +129,6 @@ function (angular, _, $) {
 
       ctrl.editMode = false;
       ctrl.fullscreen = false;
-      delete ctrl.height;
 
       this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id});
 
@@ -147,13 +146,9 @@ function (angular, _, $) {
     };
 
     DashboardViewState.prototype.enterFullscreen = function(panelScope) {
-      var docHeight = $(window).height();
-      var editHeight = Math.floor(docHeight * 0.3);
-      var fullscreenHeight = Math.floor(docHeight * 0.7);
       var ctrl = panelScope.ctrl;
 
       ctrl.editMode = this.state.edit && this.$scope.dashboardMeta.canEdit;
-      ctrl.height = ctrl.editMode ? editHeight : fullscreenHeight;
       ctrl.fullscreen = true;
 
       this.oldTimeRange = ctrl.range;

+ 29 - 3
public/app/features/panel/panel_ctrl.ts

@@ -3,6 +3,11 @@
 import config from 'app/core/config';
 import _ from 'lodash';
 import angular from 'angular';
+import $ from 'jquery';
+
+const TITLE_HEIGHT = 25;
+const EMPTY_TITLE_HEIGHT = 9;
+const PANEL_PADDING = 5;
 
 export class PanelCtrl {
   panel: any;
@@ -20,6 +25,9 @@ export class PanelCtrl {
   inspector: any;
   editModeInitiated: boolean;
   editorHelpIndex: number;
+  editMode: any;
+  height: any;
+  containerHeight: any;
 
   constructor($scope, $injector) {
     this.$injector = $injector;
@@ -34,6 +42,7 @@ export class PanelCtrl {
     }
 
     $scope.$on("refresh", () => this.refresh());
+    $scope.$on("render", () => this.calculatePanelHeight());
   }
 
   init() {
@@ -111,6 +120,23 @@ export class PanelCtrl {
     return this.dashboard.meta.fullscreen && !this.fullscreen;
   }
 
+  calculatePanelHeight() {
+
+    if (this.fullscreen) {
+      var docHeight = $(window).height();
+      var editHeight = Math.floor(docHeight * 0.3);
+      var fullscreenHeight = Math.floor(docHeight * 0.7);
+      this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
+    } else {
+      this.containerHeight = this.panel.height || this.row.height;
+      if (_.isString(this.containerHeight)) {
+        this.containerHeight = parseInt(this.containerHeight.replace('px', ''), 10);
+      }
+    }
+
+    this.height = this.containerHeight - (PANEL_PADDING + (this.panel.title ? TITLE_HEIGHT : EMPTY_TITLE_HEIGHT));
+  }
+
   broadcastRender(arg1?, arg2?) {
     this.$scope.$broadcast('render', arg1, arg2);
   }
@@ -172,9 +198,9 @@ export class PanelCtrl {
     shareScope.dashboard = this.dashboard;
 
     this.publishAppEvent('show-modal', {
-     src: 'public/app/features/dashboard/partials/shareModal.html',
-     scope: shareScope
-   });
+      src: 'public/app/features/dashboard/partials/shareModal.html',
+      scope: shareScope
+    });
   }
 
   openInspector() {

+ 2 - 2
public/app/features/panel/panel_directive.ts

@@ -65,8 +65,8 @@ module.directive('grafanaPanel', function() {
     link: function(scope, elem) {
       var panelContainer = elem.find('.panel-container');
       var ctrl = scope.ctrl;
-      scope.$watchGroup(['ctrl.fullscreen', 'ctrl.height', 'ctrl.panel.height', 'ctrl.row.height'], function() {
-        panelContainer.css({ minHeight: ctrl.height || ctrl.panel.height || ctrl.row.height, display: 'block' });
+      scope.$watchGroup(['ctrl.fullscreen', 'ctrl.containerHeight'], function() {
+        panelContainer.css({minHeight: ctrl.containerHeight});
         elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false);
       });
     }

+ 0 - 135
public/app/features/panel/panel_helper.js

@@ -1,135 +0,0 @@
-define([
-  'angular',
-  'lodash',
-  'jquery',
-  'app/core/utils/kbn',
-  'app/core/utils/datemath',
-  'app/core/utils/rangeutil',
-],
-function (angular, _, $, kbn, dateMath, rangeUtil) {
-  'use strict';
-
-  var module = angular.module('grafana.services');
-
-  module.service('panelHelper', function(timeSrv, $rootScope, $q) {
-    var self = this;
-
-    this.setTimeQueryStart = function(scope) {
-      scope.timing = {};
-      scope.timing.queryStart = new Date().getTime();
-    };
-
-    this.setTimeQueryEnd = function(scope) {
-      scope.timing.queryEnd = new Date().getTime();
-    };
-
-    this.setTimeRenderStart = function(scope) {
-      scope.timing = scope.timing || {};
-      scope.timing.renderStart = new Date().getTime();
-    };
-
-    this.setTimeRenderEnd = function(scope) {
-      scope.timing.renderEnd = new Date().getTime();
-    };
-
-    this.broadcastRender = function(scope, arg1, arg2) {
-      this.setTimeRenderStart(scope);
-      scope.$broadcast('render', arg1, arg2);
-      this.setTimeRenderEnd(scope);
-
-      if ($rootScope.profilingEnabled) {
-        $rootScope.performance.panels.push({
-          panelId: scope.panel.id,
-          query: scope.timing.queryEnd - scope.timing.queryStart,
-          render: scope.timing.renderEnd - scope.timing.renderStart,
-        });
-      }
-    };
-
-    this.updateTimeRange = function(scope) {
-      scope.range = timeSrv.timeRange();
-      scope.rangeRaw = timeSrv.timeRange(false);
-
-      this.applyPanelTimeOverrides(scope);
-
-      if (scope.panel.maxDataPoints) {
-        scope.resolution = scope.panel.maxDataPoints;
-      }
-      else {
-        scope.resolution = Math.ceil($(window).width() * (scope.panel.span / 12));
-      }
-
-      var panelInterval = scope.panel.interval;
-      var datasourceInterval = (scope.datasource || {}).interval;
-      scope.interval = kbn.calculateInterval(scope.range, scope.resolution, panelInterval || datasourceInterval);
-    };
-
-    this.applyPanelTimeOverrides = function(scope) {
-      scope.panelMeta.timeInfo = '';
-
-      // check panel time overrrides
-      if (scope.panel.timeFrom) {
-        var timeFromInfo = rangeUtil.describeTextRange(scope.panel.timeFrom);
-        if (timeFromInfo.invalid) {
-          scope.panelMeta.timeFromInfo = 'invalid time override';
-          return;
-        }
-
-        if (_.isString(scope.rangeRaw.from)) {
-          var timeFromDate = dateMath.parse(timeFromInfo.from);
-          scope.panelMeta.timeInfo = timeFromInfo.display;
-          scope.rangeRaw.from = timeFromInfo.from;
-          scope.rangeRaw.to = timeFromInfo.to;
-          scope.range.from = timeFromDate;
-        }
-      }
-
-      if (scope.panel.timeShift) {
-        var timeShiftInfo = rangeUtil.describeTextRange(scope.panel.timeShift);
-        if (timeShiftInfo.invalid) {
-          scope.panelMeta.timeInfo = 'invalid timeshift';
-          return;
-        }
-
-        var timeShift = '-' + scope.panel.timeShift;
-        scope.panelMeta.timeInfo += ' timeshift ' + timeShift;
-        scope.range.from = dateMath.parseDateMath(timeShift, scope.range.from, false);
-        scope.range.to = dateMath.parseDateMath(timeShift, scope.range.to, true);
-
-        scope.rangeRaw = scope.range;
-      }
-
-      if (scope.panel.hideTimeOverride) {
-        scope.panelMeta.timeInfo = '';
-      }
-    };
-
-    this.issueMetricQuery = function(scope, datasource) {
-      if (!scope.panel.targets || scope.panel.targets.length === 0) {
-        return $q.when([]);
-      }
-
-      var metricsQuery = {
-        range: scope.range,
-        rangeRaw: scope.rangeRaw,
-        interval: scope.interval,
-        targets: scope.panel.targets,
-        format: scope.panel.renderer === 'png' ? 'png' : 'json',
-        maxDataPoints: scope.resolution,
-        scopedVars: scope.panel.scopedVars,
-        cacheTimeout: scope.panel.cacheTimeout
-      };
-
-      this.setTimeQueryStart(scope);
-      return datasource.query(metricsQuery).then(function(results) {
-        self.setTimeQueryEnd(scope);
-
-        if (scope.dashboard.snapshot) {
-          scope.panel.snapshotData = results;
-        }
-
-        return results;
-      });
-    };
-  });
-});

+ 3 - 13
public/app/plugins/panel/graph/graph.js

@@ -29,7 +29,6 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
         var panel = ctrl.panel;
         var data, annotations;
         var sortedSeries;
-        var graphHeight;
         var legendSideLastValue = null;
         var rootScope = scope.$root;
 
@@ -67,14 +66,13 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
 
         function getLegendHeight(panelHeight) {
           if (!panel.legend.show || panel.legend.rightSide) {
-            return 0;
+            return 2;
           }
 
           if (panel.legend.alignAsTable) {
             var legendSeries = _.filter(data, function(series) {
               return series.hideFromLegend(panel.legend) === false;
             });
-            console.log(legendSeries.length);
             var total = 23 + (22 * legendSeries.length);
             return Math.min(total, Math.floor(panelHeight/2));
           } else {
@@ -84,16 +82,8 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
 
         function setElementHeight() {
           try {
-            graphHeight = ctrl.height || panel.height || ctrl.row.height;
-            if (_.isString(graphHeight)) {
-              graphHeight = parseInt(graphHeight.replace('px', ''), 10);
-            }
-
-            graphHeight -= 5; // padding
-            graphHeight -= panel.title ? 25 : 5; // subtract panel title bar
-            graphHeight = graphHeight - getLegendHeight(graphHeight); // subtract one line legend
-
-            elem.css('height', graphHeight + 'px');
+            var height = ctrl.height - getLegendHeight(ctrl.height);
+            elem.css('height', height + 'px');
 
             return true;
           } catch(e) { // IE throws errors sometimes

+ 10 - 7
public/app/plugins/panel/graph/legend.js

@@ -142,6 +142,7 @@ function (angular, _, $) {
             }
           }
 
+          var seriesShown = 0;
           for (i = 0; i < seriesList.length; i++) {
             var series = seriesList[i];
 
@@ -175,17 +176,19 @@ function (angular, _, $) {
 
             html += '</div>';
             $container.append($(html));
+
+            seriesShown++;
           }
 
-          var legendContainerHeight = $container.parent().height();
-          var legendHeight = $container.height();
+          if (panel.legend.alignAsTable) {
+            var maxHeight = ctrl.height;
 
-          if (panel.legend.rightSide && legendHeight >= legendContainerHeight) {
-            $container.toggleClass('graph-legend-fixed-height', true);
-          }
+            if (!panel.legend.rightSide) {
+              maxHeight = maxHeight/2;
+            }
 
-          if (panel.legend.rightSide) {
-            $container.css("height", scope.ctrl.height || scope.ctrl.panel.height || scope.ctrl.row.height);
+            var topPadding = 6;
+            $container.css("height", maxHeight - topPadding);
           } else {
             $container.css("height", "");
           }

+ 2 - 17
public/app/plugins/panel/singlestat/module.ts

@@ -241,7 +241,6 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     var panel = ctrl.panel;
     var templateSrv = this.templateSrv;
     var data, linkInfo;
-    var elemHeight;
     var $panelContainer = elem.find('.panel-container');
     // change elem to singlestat panel
     elem = elem.find('.singlestat-panel');
@@ -253,21 +252,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     });
 
     function setElementHeight() {
-      try {
-        elemHeight = ctrl.height || panel.height || ctrl.row.height;
-        if (_.isString(elemHeight)) {
-          elemHeight = parseInt(elemHeight.replace('px', ''), 10);
-        }
-
-        elemHeight -= 5; // padding
-        elemHeight -= panel.title ? 24 : 9; // subtract panel title bar
-
-        elem.css('height', elemHeight + 'px');
-
-        return true;
-      } catch (e) { // IE throws errors sometimes
-        return false;
-      }
+      elem.css('height', ctrl.height + 'px');
     }
 
     function applyColoringThresholds(value, valueString) {
@@ -306,7 +291,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
 
     function addSparkline() {
       var width = elem.width() + 20;
-      var height = elemHeight;
+      var height = ctrl.height;
 
       var plotCanvas = $('<div></div>');
       var plotCss: any = {};

+ 5 - 8
public/sass/components/_panel_graph.scss

@@ -22,8 +22,11 @@
 }
 
 .graph-legend {
+  @include clearfix();
   margin: 0 $spacer;
   text-align: center;
+  width: calc(100% - $spacer);
+  padding-top: 6px;
 
   .popover-content {
     padding: 0;
@@ -71,7 +74,6 @@
   float: left;
   white-space: nowrap;
   padding-left: 10px;
-  padding-top: 6px;
 }
 
 .graph-legend-value {
@@ -79,11 +81,9 @@
 }
 
 .graph-legend-table {
-  width: 100%;
-  margin-top: 4px;
+  overflow-y: scroll;
 
-  .graph-legend-series {
-    display: table-row;
+  .graph-legend-series { display: table-row;
     float: none;
     padding-left: 0;
     &.pull-right {
@@ -314,6 +314,3 @@
   font-size: 12px;
 }
 
-.graph-legend-fixed-height {
-  overflow-y: scroll;
-}

+ 1 - 1
public/sass/components/_sidemenu.scss

@@ -179,7 +179,7 @@
   top: 38%;
   right: 6px;
   font-size: 14px;
-  color: $link-color;
+  color: $text-color-weak;
 }
 
 .sidemenu-org-avatar,

+ 1 - 1
public/sass/pages/_dashboard.scss

@@ -142,7 +142,7 @@ div.flot-text {
 }
 
 .panel-title-container {
-  min-height: 5px;
+  min-height: 9px;
   padding-top: 4px;
   cursor: pointer;
 }

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

@@ -54,7 +54,7 @@ define([
 
         config.panels['test'] = {info: {}};
         self.ctrl = $controller(Ctrl, {$scope: self.scope}, {
-          panel: self.panel, dashboard: self.dashboard
+          panel: self.panel, dashboard: self.dashboard, row: {}
         });
       });
     };