Commit 260c731f by Torkel Ödegaard

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

parent e73e7aea
...@@ -129,7 +129,6 @@ function (angular, _, $) { ...@@ -129,7 +129,6 @@ function (angular, _, $) {
ctrl.editMode = false; ctrl.editMode = false;
ctrl.fullscreen = false; ctrl.fullscreen = false;
delete ctrl.height;
this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id}); this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id});
...@@ -147,13 +146,9 @@ function (angular, _, $) { ...@@ -147,13 +146,9 @@ function (angular, _, $) {
}; };
DashboardViewState.prototype.enterFullscreen = function(panelScope) { 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; var ctrl = panelScope.ctrl;
ctrl.editMode = this.state.edit && this.$scope.dashboardMeta.canEdit; ctrl.editMode = this.state.edit && this.$scope.dashboardMeta.canEdit;
ctrl.height = ctrl.editMode ? editHeight : fullscreenHeight;
ctrl.fullscreen = true; ctrl.fullscreen = true;
this.oldTimeRange = ctrl.range; this.oldTimeRange = ctrl.range;
......
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
import config from 'app/core/config'; import config from 'app/core/config';
import _ from 'lodash'; import _ from 'lodash';
import angular from 'angular'; import angular from 'angular';
import $ from 'jquery';
const TITLE_HEIGHT = 25;
const EMPTY_TITLE_HEIGHT = 9;
const PANEL_PADDING = 5;
export class PanelCtrl { export class PanelCtrl {
panel: any; panel: any;
...@@ -20,6 +25,9 @@ export class PanelCtrl { ...@@ -20,6 +25,9 @@ export class PanelCtrl {
inspector: any; inspector: any;
editModeInitiated: boolean; editModeInitiated: boolean;
editorHelpIndex: number; editorHelpIndex: number;
editMode: any;
height: any;
containerHeight: any;
constructor($scope, $injector) { constructor($scope, $injector) {
this.$injector = $injector; this.$injector = $injector;
...@@ -34,6 +42,7 @@ export class PanelCtrl { ...@@ -34,6 +42,7 @@ export class PanelCtrl {
} }
$scope.$on("refresh", () => this.refresh()); $scope.$on("refresh", () => this.refresh());
$scope.$on("render", () => this.calculatePanelHeight());
} }
init() { init() {
...@@ -111,6 +120,23 @@ export class PanelCtrl { ...@@ -111,6 +120,23 @@ export class PanelCtrl {
return this.dashboard.meta.fullscreen && !this.fullscreen; 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?) { broadcastRender(arg1?, arg2?) {
this.$scope.$broadcast('render', arg1, arg2); this.$scope.$broadcast('render', arg1, arg2);
} }
...@@ -172,9 +198,9 @@ export class PanelCtrl { ...@@ -172,9 +198,9 @@ export class PanelCtrl {
shareScope.dashboard = this.dashboard; shareScope.dashboard = this.dashboard;
this.publishAppEvent('show-modal', { this.publishAppEvent('show-modal', {
src: 'public/app/features/dashboard/partials/shareModal.html', src: 'public/app/features/dashboard/partials/shareModal.html',
scope: shareScope scope: shareScope
}); });
} }
openInspector() { openInspector() {
......
...@@ -65,8 +65,8 @@ module.directive('grafanaPanel', function() { ...@@ -65,8 +65,8 @@ module.directive('grafanaPanel', function() {
link: function(scope, elem) { link: function(scope, elem) {
var panelContainer = elem.find('.panel-container'); var panelContainer = elem.find('.panel-container');
var ctrl = scope.ctrl; var ctrl = scope.ctrl;
scope.$watchGroup(['ctrl.fullscreen', 'ctrl.height', 'ctrl.panel.height', 'ctrl.row.height'], function() { scope.$watchGroup(['ctrl.fullscreen', 'ctrl.containerHeight'], function() {
panelContainer.css({ minHeight: ctrl.height || ctrl.panel.height || ctrl.row.height, display: 'block' }); panelContainer.css({minHeight: ctrl.containerHeight});
elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false); elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false);
}); });
} }
......
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;
});
};
});
});
...@@ -29,7 +29,6 @@ function (angular, $, moment, _, kbn, GraphTooltip) { ...@@ -29,7 +29,6 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
var panel = ctrl.panel; var panel = ctrl.panel;
var data, annotations; var data, annotations;
var sortedSeries; var sortedSeries;
var graphHeight;
var legendSideLastValue = null; var legendSideLastValue = null;
var rootScope = scope.$root; var rootScope = scope.$root;
...@@ -67,14 +66,13 @@ function (angular, $, moment, _, kbn, GraphTooltip) { ...@@ -67,14 +66,13 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
function getLegendHeight(panelHeight) { function getLegendHeight(panelHeight) {
if (!panel.legend.show || panel.legend.rightSide) { if (!panel.legend.show || panel.legend.rightSide) {
return 0; return 2;
} }
if (panel.legend.alignAsTable) { if (panel.legend.alignAsTable) {
var legendSeries = _.filter(data, function(series) { var legendSeries = _.filter(data, function(series) {
return series.hideFromLegend(panel.legend) === false; return series.hideFromLegend(panel.legend) === false;
}); });
console.log(legendSeries.length);
var total = 23 + (22 * legendSeries.length); var total = 23 + (22 * legendSeries.length);
return Math.min(total, Math.floor(panelHeight/2)); return Math.min(total, Math.floor(panelHeight/2));
} else { } else {
...@@ -84,16 +82,8 @@ function (angular, $, moment, _, kbn, GraphTooltip) { ...@@ -84,16 +82,8 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
function setElementHeight() { function setElementHeight() {
try { try {
graphHeight = ctrl.height || panel.height || ctrl.row.height; var height = ctrl.height - getLegendHeight(ctrl.height);
if (_.isString(graphHeight)) { elem.css('height', height + 'px');
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');
return true; return true;
} catch(e) { // IE throws errors sometimes } catch(e) { // IE throws errors sometimes
......
...@@ -142,6 +142,7 @@ function (angular, _, $) { ...@@ -142,6 +142,7 @@ function (angular, _, $) {
} }
} }
var seriesShown = 0;
for (i = 0; i < seriesList.length; i++) { for (i = 0; i < seriesList.length; i++) {
var series = seriesList[i]; var series = seriesList[i];
...@@ -175,17 +176,19 @@ function (angular, _, $) { ...@@ -175,17 +176,19 @@ function (angular, _, $) {
html += '</div>'; html += '</div>';
$container.append($(html)); $container.append($(html));
seriesShown++;
} }
var legendContainerHeight = $container.parent().height(); if (panel.legend.alignAsTable) {
var legendHeight = $container.height(); var maxHeight = ctrl.height;
if (panel.legend.rightSide && legendHeight >= legendContainerHeight) { if (!panel.legend.rightSide) {
$container.toggleClass('graph-legend-fixed-height', true); maxHeight = maxHeight/2;
} }
if (panel.legend.rightSide) { var topPadding = 6;
$container.css("height", scope.ctrl.height || scope.ctrl.panel.height || scope.ctrl.row.height); $container.css("height", maxHeight - topPadding);
} else { } else {
$container.css("height", ""); $container.css("height", "");
} }
......
...@@ -241,7 +241,6 @@ class SingleStatCtrl extends MetricsPanelCtrl { ...@@ -241,7 +241,6 @@ class SingleStatCtrl extends MetricsPanelCtrl {
var panel = ctrl.panel; var panel = ctrl.panel;
var templateSrv = this.templateSrv; var templateSrv = this.templateSrv;
var data, linkInfo; var data, linkInfo;
var elemHeight;
var $panelContainer = elem.find('.panel-container'); var $panelContainer = elem.find('.panel-container');
// change elem to singlestat panel // change elem to singlestat panel
elem = elem.find('.singlestat-panel'); elem = elem.find('.singlestat-panel');
...@@ -253,21 +252,7 @@ class SingleStatCtrl extends MetricsPanelCtrl { ...@@ -253,21 +252,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
}); });
function setElementHeight() { function setElementHeight() {
try { elem.css('height', ctrl.height + 'px');
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;
}
} }
function applyColoringThresholds(value, valueString) { function applyColoringThresholds(value, valueString) {
...@@ -306,7 +291,7 @@ class SingleStatCtrl extends MetricsPanelCtrl { ...@@ -306,7 +291,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
function addSparkline() { function addSparkline() {
var width = elem.width() + 20; var width = elem.width() + 20;
var height = elemHeight; var height = ctrl.height;
var plotCanvas = $('<div></div>'); var plotCanvas = $('<div></div>');
var plotCss: any = {}; var plotCss: any = {};
......
...@@ -22,8 +22,11 @@ ...@@ -22,8 +22,11 @@
} }
.graph-legend { .graph-legend {
@include clearfix();
margin: 0 $spacer; margin: 0 $spacer;
text-align: center; text-align: center;
width: calc(100% - $spacer);
padding-top: 6px;
.popover-content { .popover-content {
padding: 0; padding: 0;
...@@ -71,7 +74,6 @@ ...@@ -71,7 +74,6 @@
float: left; float: left;
white-space: nowrap; white-space: nowrap;
padding-left: 10px; padding-left: 10px;
padding-top: 6px;
} }
.graph-legend-value { .graph-legend-value {
...@@ -79,11 +81,9 @@ ...@@ -79,11 +81,9 @@
} }
.graph-legend-table { .graph-legend-table {
width: 100%; overflow-y: scroll;
margin-top: 4px;
.graph-legend-series { .graph-legend-series { display: table-row;
display: table-row;
float: none; float: none;
padding-left: 0; padding-left: 0;
&.pull-right { &.pull-right {
...@@ -314,6 +314,3 @@ ...@@ -314,6 +314,3 @@
font-size: 12px; font-size: 12px;
} }
.graph-legend-fixed-height {
overflow-y: scroll;
}
...@@ -179,7 +179,7 @@ ...@@ -179,7 +179,7 @@
top: 38%; top: 38%;
right: 6px; right: 6px;
font-size: 14px; font-size: 14px;
color: $link-color; color: $text-color-weak;
} }
.sidemenu-org-avatar, .sidemenu-org-avatar,
......
...@@ -142,7 +142,7 @@ div.flot-text { ...@@ -142,7 +142,7 @@ div.flot-text {
} }
.panel-title-container { .panel-title-container {
min-height: 5px; min-height: 9px;
padding-top: 4px; padding-top: 4px;
cursor: pointer; cursor: pointer;
} }
......
...@@ -54,7 +54,7 @@ define([ ...@@ -54,7 +54,7 @@ define([
config.panels['test'] = {info: {}}; config.panels['test'] = {info: {}};
self.ctrl = $controller(Ctrl, {$scope: self.scope}, { self.ctrl = $controller(Ctrl, {$scope: self.scope}, {
panel: self.panel, dashboard: self.dashboard panel: self.panel, dashboard: self.dashboard, row: {}
}); });
}); });
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment