Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Height Panels #10

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
copy patch from ryantxu
ryantxu committed May 9, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit f593bf75158a49be8b975645aa745c20a7293d04
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -198,6 +198,7 @@
"calculate-size": "1.1.1",
"classnames": "2.2.6",
"clipboard": "2.0.4",
"css-element-queries": "^1.1.1",
"d3": "4.13.0",
"d3-scale-chromatic": "1.3.3",
"eventemitter3": "2.0.3",
9 changes: 9 additions & 0 deletions public/app/features/dashboard/services/ChangeTracker.ts
Original file line number Diff line number Diff line change
@@ -110,6 +110,7 @@ export class ChangeTracker {
// ignore iteration property
delete dash.iteration;

let hasDynamicHeight = false;
dash.panels = _.filter(dash.panels, panel => {
if (panel.repeatPanelId) {
return false;
@@ -124,6 +125,14 @@ export class ChangeTracker {
delete panel.legend.sortDesc;
}

// ignore all h parameters after a dynamic height
if (panel.dynamicHeight) {
hasDynamicHeight = true;
}
if (hasDynamicHeight) {
delete panel.gridPos.h;
}

return true;
});

21 changes: 20 additions & 1 deletion public/app/features/panel/panel_ctrl.ts
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import {
calculateInnerPanelHeight,
} from 'app/features/dashboard/utils/panel';

import { GRID_COLUMN_COUNT } from 'app/core/constants';
import { GRID_COLUMN_COUNT, GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';

export class PanelCtrl {
panel: any;
@@ -63,6 +63,25 @@ export class PanelCtrl {
profiler.renderingCompleted(this.panel.id);
}

dynamicHeightChanged(height: number): boolean {
const min = this.panel.dynamicHeightMIN || 50;
if (height < min) {
height = min;
}
if (this.panel.dynamicHeightMAX && height > this.panel.dynamicHeightMAX) {
height = this.panel.dynamicHeightMAX;
}
const h = Math.ceil((height + 5) / (GRID_CELL_HEIGHT + GRID_CELL_VMARGIN)) + 1;
if (h !== this.panel.gridPos.h) {
//console.log('Dynamic Height Changed', height, 'new:', h, 'old', this.panel.gridPos.h);
this.panel.gridPos.h = h;
this.events.emit('panel-size-changed');
this.dashboard.events.emit('row-expanded'); // triggers grid re-layout
return true;
}
return false;
}

refresh() {
this.panel.refresh();
}
31 changes: 29 additions & 2 deletions public/app/features/panel/panel_directive.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ import angular from 'angular';
import $ from 'jquery';
import Drop from 'tether-drop';
import baron from 'baron';
import ResizeSensor from 'css-element-queries/src/ResizeSensor.js';

const module = angular.module('grafana.directives');

@@ -17,7 +18,7 @@ const panelTemplate = `
<i class="fa fa-spinner fa-spin"></i>
</span>

<panel-header class="panel-title-container" panel-ctrl="ctrl" aria-label="Panel Title"></panel-header>
<panel-header class="panel-title-container" panel-ctrl="ctrl"></panel-header>
</div>

<div class="panel-content">
@@ -40,6 +41,8 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
const ctrl = scope.ctrl;
let infoDrop;
let panelScrollbar;
let panelInnerContent;
let panelInnerContentHeight = -1;

// the reason for handling these classes this way is for performance
// limit the watchers on panels etc
@@ -58,6 +61,16 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
ctrl.dashboard.setPanelFocus(0);
}

function checkInnerContentHeight() {
if (ctrl.panel.dynamicHeight && panelInnerContent) {
const v = panelInnerContent.outerHeight(true);
if (v !== panelInnerContentHeight) {
panelInnerContentHeight = v;
ctrl.dynamicHeightChanged(panelInnerContentHeight);
}
}
}

function resizeScrollableContent() {
if (panelScrollbar) {
panelScrollbar.update();
@@ -82,7 +95,21 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
`;

const scrollRoot = panelContent;
const scroller = panelContent.find(':first').find(':first');
let scroller = panelContent.find(':first').find(':first');

// Add a div under the scroller and watch for changes
if (ctrl.panel.dynamicHeight) {
$(scroller).wrap('<div class="panel-height-helper"></div>');
scroller = panelContent.find(':first');

panelInnerContent = $(scroller).find(':first');
panelInnerContent.removeClass('panel-height-helper');
panelInnerContent.css('margin-right', '20px');
panelInnerContent.css('border', '2px solid #F0F');

// tslint:disable-next-line
new ResizeSensor(panelInnerContent, checkInnerContentHeight);
}

scrollRoot.addClass(scrollRootClass);
$(scrollBarHTML).appendTo(scrollRoot);
18 changes: 18 additions & 0 deletions public/app/features/panel/partials/general_tab.html
Original file line number Diff line number Diff line change
@@ -52,3 +52,21 @@
<panel-links-editor panel="ctrl.panel"></panel-links-editor>
</div>
</div>


<div class="panel-option-section">
<div class="panel-option-section__header">Height</div>
<div class="panel-option-section__body">
<gf-form-switch class="gf-form" label-class="width-7" switch-class="max-width-6" label="Dynamic" checked="ctrl.panel.dynamicHeight" on-change="ctrl.render()"></gf-form-switch>
<div class="gf-form" ng-if="ctrl.panel.dynamicHeight">
<span class="gf-form-label width-7">Minimum</span>
<input type="number" class="gf-form-input width-6" placeholder="10px" ng-model="ctrl.panel.dynamicHeightMIN"></input>
</div>
<div class="gf-form" ng-if="ctrl.panel.dynamicHeight">
<span class="gf-form-label width-7">Maximum</span>
<input type="number" class="gf-form-input width-6" placeholder="none" ng-model="ctrl.panel.dynamicHeightMAX"></input>
</div>
</div>
</div>


5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -5367,6 +5367,11 @@ css-declaration-sorter@^4.0.1:
postcss "^7.0.1"
timsort "^0.3.0"

css-element-queries@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/css-element-queries/-/css-element-queries-1.1.1.tgz#129e104ecb277aa6337b7302cbb6d511c2d1633a"
integrity sha512-/PX6Bkk77ShgbOx/mpawHdEvS3PGgy1mmMktcztDPndWdMJxcorcQiivrs+nEljqtBpvNEhAmQky9tQR6FSm8Q==

[email protected], css-loader@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea"