fix(panel): fixes for panel height and alignment management and scrollable legends, closes #4266
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -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
|
||||
|
||||
@@ -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", "");
|
||||
}
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
top: 38%;
|
||||
right: 6px;
|
||||
font-size: 14px;
|
||||
color: $link-color;
|
||||
color: $text-color-weak;
|
||||
}
|
||||
|
||||
.sidemenu-org-avatar,
|
||||
|
||||
@@ -142,7 +142,7 @@ div.flot-text {
|
||||
}
|
||||
|
||||
.panel-title-container {
|
||||
min-height: 5px;
|
||||
min-height: 9px;
|
||||
padding-top: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -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: {}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user