From 8c73f0462e0960f96954f70c142e7b6df01a276a Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Mon, 28 Sep 2020 16:40:39 +0200 Subject: [PATCH] InlinePie: Utilize SVG to render charts instantly Inline pie charts usually don't contain that much data and the SVG should be rather small in size. So it doesn't hurt rendering them instantly. --- library/Icinga/Web/Widget/Chart/InlinePie.php | 81 +++++++------------ .../library/Monitoring/Plugin/Perfdata.php | 3 - modules/monitoring/public/css/module.less | 7 +- 3 files changed, 32 insertions(+), 59 deletions(-) diff --git a/library/Icinga/Web/Widget/Chart/InlinePie.php b/library/Icinga/Web/Widget/Chart/InlinePie.php index a88fc8a12..de1bbea7c 100644 --- a/library/Icinga/Web/Widget/Chart/InlinePie.php +++ b/library/Icinga/Web/Widget/Chart/InlinePie.php @@ -73,23 +73,7 @@ class InlinePie extends AbstractWidget * * @var string */ - private $template =<<<'EOD' - -{noscript} -EOD; - - private $noscript =<<<'EOD' - -EOD; - - /** - * @var Url - */ - private $url; + private $template = '
{svg}
'; /** * The colors used to display the slices of this pie-chart. @@ -106,9 +90,9 @@ EOD; private $title; /** - * @var + * @var int */ - private $size; + private $size = 16; /** * The data displayed by the pie-chart @@ -132,7 +116,7 @@ EOD; public function setData(array $data) { $this->data = $data; - $this->url->setParam('data', implode(',', $data)); + return $this; } @@ -146,15 +130,17 @@ EOD; public function setSize($size = null) { $this->size = $size; + return $this; } /** * Do not display the NoScript fallback html + * + * @deprecated noop */ public function disableNoScript() { - $this->noscript = ''; } /** @@ -167,6 +153,7 @@ EOD; public function setSparklineClass($class) { $this->class = $class; + return $this; } @@ -180,11 +167,7 @@ EOD; public function setColors(array $colors = null) { $this->colors = $colors; - if (isset($colors)) { - $this->url->setParam('colors', implode(',', $colors)); - } else { - $this->url->setParam('colors', null); - } + return $this; } @@ -198,6 +181,7 @@ EOD; public function setTitle($title) { $this->title = $this->view()->escape($title); + return $this; } @@ -211,7 +195,7 @@ EOD; public function __construct(array $data, $title, $colors = null) { $this->setTitle($title); - $this->url = Url::fromPath('svg/chart.php'); + if (array_key_exists('data', $data)) { $this->data = $data['data']; if (array_key_exists('colors', $data)) { @@ -220,12 +204,14 @@ EOD; } else { $this->setData($data); } + if (isset($colors)) { $this->setColors($colors); } else { $this->setColors($this->colors); } } + /** * Renders this widget via the given view and returns the * HTML as a string @@ -234,14 +220,15 @@ EOD; */ public function render() { - if ($this->view()->layout()->getLayout() === 'pdf') { - $pie = new PieChart(); - $pie->alignTopLeft(); - $pie->disableLegend(); - $pie->drawPie(array( - 'data' => $this->data, 'colors' => $this->colors - )); + $pie = new PieChart(); + $pie->alignTopLeft(); + $pie->disableLegend(); + $pie->drawPie([ + 'data' => $this->data, + 'colors' => $this->colors + ]); + if ($this->view()->layout()->getLayout() === 'pdf') { try { $png = $pie->toPng($this->size, $this->size); return ''; @@ -250,39 +237,27 @@ EOD; } } + $pie->title = $this->title; + $pie->description = $this->title; + $template = $this->template; - // TODO: Check whether we are XHR and don't send - $template = str_replace('{noscript}', $this->noscript, $template); - $template = str_replace('{url}', $this->url, $template); $template = str_replace('{class}', $this->class, $template); + $template = str_replace('{svg}', $pie->render(), $template); - // style - $template = str_replace('{size}', isset($this->size) ? $this->size : 16, $template); - $template = str_replace('{title}', $this->title, $template); - - $template = str_replace('{colors}', implode(',', $this->colors), $template); - - // Locale-ignorant string cast. Please. Do. NOT. Remove. This. Again. - // Problem is that implode respects locales when casting floats. This means - // that implode(',', array(1.1, 1.2)) would read '1,1,1,2'. - $data = array(); - foreach ($this->data as $dat) { - $data[] = sprintf('%F', $dat); - } - - $template = str_replace('{data}', htmlspecialchars(implode(',', $data)), $template); return $template; } public static function createFromStateSummary(stdClass $states, $title, array $colors) { - $handledUnhandledStates = array(); + $handledUnhandledStates = []; foreach ($states as $key => $value) { if (StringHelper::endsWith($key, '_handled') || StringHelper::endsWith($key, '_unhandled')) { $handledUnhandledStates[$key] = $value; } } + $chart = new self(array_values($handledUnhandledStates), $title, $colors); + return $chart ->setSize(50) ->setTitle('') diff --git a/modules/monitoring/library/Monitoring/Plugin/Perfdata.php b/modules/monitoring/library/Monitoring/Plugin/Perfdata.php index b6f81ec50..15aacea33 100644 --- a/modules/monitoring/library/Monitoring/Plugin/Perfdata.php +++ b/modules/monitoring/library/Monitoring/Plugin/Perfdata.php @@ -425,9 +425,6 @@ class Perfdata $pieChart = new InlinePie($data, $this); $pieChart->setColors(array('#44bb77', '#ffaa44', '#ff5566', '#ddccdd')); - if (Zend_Controller_Front::getInstance()->getRequest()->isXmlHttpRequest()) { - $pieChart->disableNoScript(); - } return $pieChart; } diff --git a/modules/monitoring/public/css/module.less b/modules/monitoring/public/css/module.less index adc45181f..c760a9cdc 100644 --- a/modules/monitoring/public/css/module.less +++ b/modules/monitoring/public/css/module.less @@ -147,12 +147,13 @@ } // Performance data pie charts -.sparkline { - height: 1em; +.inline-pie { + display: inline-block; + height: 14/12em; margin-right: 0.1em; position: relative; top: 0.1em; - width: 1em; + width: 14/12em; } // Host and service summaries in detail and list views