From be74138f527b22a704bdee2533a8f7ab85fadfad Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 14 Nov 2017 14:34:19 +0100 Subject: [PATCH] Show a maximum of two graphs in the detail view, by default It's still possible for the user to expand all graphs. refs #60 --- .../Monitoring/DetailviewExtension.php | 1 + library/Graphite/Web/Widget/Graphs.php | 74 +++++++++++++++++-- library/Graphite/Web/Widget/Graphs/Host.php | 5 ++ .../Graphite/Web/Widget/Graphs/Service.php | 5 ++ public/css/module.less | 52 ++++++++++++- 5 files changed, 127 insertions(+), 10 deletions(-) diff --git a/library/Graphite/ProvidedHook/Monitoring/DetailviewExtension.php b/library/Graphite/ProvidedHook/Monitoring/DetailviewExtension.php index e5495ee..0b3f163 100644 --- a/library/Graphite/ProvidedHook/Monitoring/DetailviewExtension.php +++ b/library/Graphite/ProvidedHook/Monitoring/DetailviewExtension.php @@ -20,6 +20,7 @@ class DetailviewExtension extends DetailviewExtensionHook ->setWidth(440) ->setHeight(220) ->setClasses(['monitored-object-detail-view']) + ->setMaxVisibleGraphs(2) ->setPreloadDummy() ->handleRequest(); } diff --git a/library/Graphite/Web/Widget/Graphs.php b/library/Graphite/Web/Widget/Graphs.php index b4861c8..799e12f 100644 --- a/library/Graphite/Web/Widget/Graphs.php +++ b/library/Graphite/Web/Widget/Graphs.php @@ -78,6 +78,13 @@ abstract class Graphs extends AbstractWidget */ protected $classes = []; + /** + * The amount of graphs to show + * + * @var int + */ + protected $maxVisibleGraphs; + /** * Whether to serve a transparent dummy image first and let the JS code load the actual graph * @@ -157,19 +164,34 @@ abstract class Graphs extends AbstractWidget $imageBaseUrl = $this->preloadDummy ? $this->getDummyImageBaseUrl() : $this->getImageBaseUrl(); $templates = static::getAllTemplates()->getTemplates(); $checkCommand = $this->obscuredCheckCommand === null ? $this->checkCommand : $this->obscuredCheckCommand; + $limit = $this->maxVisibleGraphs; $classes = $this->classes; $classes[] = 'images'; $div = '
'; + $renderedGraphs = 0; foreach ($templates as $templateName => $template) { - if ($this->designedForMyMonitoredObjectType($template) - && $template->getCheckCommand() === $checkCommand) { + if ($this->designedForMyMonitoredObjectType($template) && $template->getCheckCommand() === $checkCommand) { $charts = $template->getCharts(static::getMetricsDataSource(), $filter, $this->checkCommand); if (! empty($charts)) { - $result[] = $div; - foreach ($charts as $chart) { + if (empty($result)) { + $result[] = $div; + } elseif ($limit && $renderedGraphs === $limit) { + $result[] = sprintf( + '' + . '' + . '
', + $view->protectId($this->getMonitoredObjectIdentifier()), + $view->translate('Show More'), + $view->translate('Show Less') + ); + } + $imageUrl = $this->filterImageUrl($imageBaseUrl->with($chart->getMetricVariables())) ->setParam('template', $templateName) ->setParam('start', $this->start) @@ -188,14 +210,22 @@ abstract class Graphs extends AbstractWidget $result[] = '" height="'; $result[] = $this->height; $result[] = '">'; + $renderedGraphs++; } - - $result[] = '
'; } } } - return empty($result) ? "

{$view->escape($view->translate('No graphs found'))}

" : implode($result); + if (! empty($result)) { + if ($limit && $renderedGraphs > $limit) { + $result[] = '
'; + } + + $result[] = ''; + return implode($result); + } else { + return "

{$view->escape($view->translate('No graphs found'))}

"; + } } /** @@ -226,6 +256,13 @@ abstract class Graphs extends AbstractWidget */ abstract protected function designedForMyMonitoredObjectType(Template $template); + /** + * Return a identifier specifying the monitored object we display graphs for + * + * @return string + */ + abstract protected function getMonitoredObjectIdentifier(); + /** * Return a filter specifying the monitored object we display graphs for * @@ -351,6 +388,29 @@ abstract class Graphs extends AbstractWidget return $this; } + /** + * Get the amount of graphs to show + * + * @return int + */ + public function getMaxVisbileGraphs() + { + return $this->maxVisibleGraphs; + } + + /** + * Set the amount of graphs to show + * + * @param int $count + * + * @return $this + */ + public function setMaxVisibleGraphs($count) + { + $this->maxVisibleGraphs = (int) $count; + return $this; + } + /** * Get whether to serve a transparent dummy image first and let the JS code load the actual graph * diff --git a/library/Graphite/Web/Widget/Graphs/Host.php b/library/Graphite/Web/Widget/Graphs/Host.php index 21a669f..1b67ca9 100644 --- a/library/Graphite/Web/Widget/Graphs/Host.php +++ b/library/Graphite/Web/Widget/Graphs/Host.php @@ -56,6 +56,11 @@ class Host extends Graphs return false; } + protected function getMonitoredObjectIdentifier() + { + return $this->host; + } + protected function getMonitoredObjectFilter() { return ['host.name' => $this->host]; diff --git a/library/Graphite/Web/Widget/Graphs/Service.php b/library/Graphite/Web/Widget/Graphs/Service.php index 3b292d2..f102ebf 100644 --- a/library/Graphite/Web/Widget/Graphs/Service.php +++ b/library/Graphite/Web/Widget/Graphs/Service.php @@ -65,6 +65,11 @@ class Service extends Graphs return false; } + protected function getMonitoredObjectIdentifier() + { + return $this->host . ':' . $this->service; + } + protected function getMonitoredObjectFilter() { return ['host.name' => $this->host, 'service.name' => $this->service]; diff --git a/public/css/module.less b/public/css/module.less index 0f11b38..df0ceba 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -1,7 +1,4 @@ div.images { - - display: inline-block; - h3 { clear: both; } @@ -13,6 +10,55 @@ div.images { } +.collapsible { + clear: right; // Because the label is floating right + + height: 0; + opacity: 0; + visibility: hidden; + + -webkit-transition: opacity 0.2s linear, visibility 0.2s; + -moz-transition: opacity 0.2s linear, visibility 0.2s; + -o-transition: opacity 0.2s linear, visibility 0.2s; + transition: opacity 0.2s linear, visibility 0.2s; +} + +input[type="checkbox"].collapsible-toggle { + display: none; + + & + label { + float: right; + margin-right: 1em; + + cursor: pointer; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + } + + &:checked ~ .collapsible { + height: auto; + opacity: 1; + visibility: visible; + + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + -o-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } + & ~ label span.collapsible-hide { + display: none; + } + + &:checked ~ label span.collapsible-show { + display: none; + } + &:checked ~ label span.collapsible-hide { + display: inline; + } +} + div.images.monitored-object-detail-view { display: block;