Merge pull request #4235 from Icinga/fix/sparkline-js-performance

Drop sparkline.js and render inline-pies as SVG
This commit is contained in:
Johannes Meyer 2020-11-18 09:37:31 +01:00 committed by GitHub
commit d918d6c86f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 3148 deletions

View File

@ -27,7 +27,6 @@ class JavaScript
'js/icinga/behavior/autofocus.js', 'js/icinga/behavior/autofocus.js',
'js/icinga/behavior/collapsible.js', 'js/icinga/behavior/collapsible.js',
'js/icinga/behavior/detach.js', 'js/icinga/behavior/detach.js',
'js/icinga/behavior/sparkline.js',
'js/icinga/behavior/dropdown.js', 'js/icinga/behavior/dropdown.js',
'js/icinga/behavior/navigation.js', 'js/icinga/behavior/navigation.js',
'js/icinga/behavior/form.js', 'js/icinga/behavior/form.js',
@ -41,8 +40,7 @@ class JavaScript
protected static $vendorFiles = array( protected static $vendorFiles = array(
'js/vendor/jquery-3.4.1', 'js/vendor/jquery-3.4.1',
'js/vendor/jquery-migrate-3.1.0', 'js/vendor/jquery-migrate-3.1.0'
'js/vendor/jquery.sparkline'
); );
public static function sendMinified() public static function sendMinified()

View File

@ -73,23 +73,7 @@ class InlinePie extends AbstractWidget
* *
* @var string * @var string
*/ */
private $template =<<<'EOD' private $template = '<div class="inline-pie {class}">{svg}</div>';
<span sparkType="pie" class="sparkline {class}" title="{title}" role="img" aria-label="{title}"
sparkSliceColors="[{colors}]" values="{data}"></span>
{noscript}
EOD;
private $noscript =<<<'EOD'
<noscript>
<img width={size} height={size} class="inlinepie {class}" title="{title}" role="img" aria-label="{title}"
src="{url}" data-icinga-colors="{colors}" data-icinga-values="{data}"/>
</noscript>
EOD;
/**
* @var Url
*/
private $url;
/** /**
* The colors used to display the slices of this pie-chart. * The colors used to display the slices of this pie-chart.
@ -106,9 +90,9 @@ EOD;
private $title; private $title;
/** /**
* @var * @var int
*/ */
private $size; private $size = 16;
/** /**
* The data displayed by the pie-chart * The data displayed by the pie-chart
@ -132,7 +116,7 @@ EOD;
public function setData(array $data) public function setData(array $data)
{ {
$this->data = $data; $this->data = $data;
$this->url->setParam('data', implode(',', $data));
return $this; return $this;
} }
@ -146,15 +130,17 @@ EOD;
public function setSize($size = null) public function setSize($size = null)
{ {
$this->size = $size; $this->size = $size;
return $this; return $this;
} }
/** /**
* Do not display the NoScript fallback html * Do not display the NoScript fallback html
*
* @deprecated noop
*/ */
public function disableNoScript() public function disableNoScript()
{ {
$this->noscript = '';
} }
/** /**
@ -167,6 +153,7 @@ EOD;
public function setSparklineClass($class) public function setSparklineClass($class)
{ {
$this->class = $class; $this->class = $class;
return $this; return $this;
} }
@ -180,11 +167,7 @@ EOD;
public function setColors(array $colors = null) public function setColors(array $colors = null)
{ {
$this->colors = $colors; $this->colors = $colors;
if (isset($colors)) {
$this->url->setParam('colors', implode(',', $colors));
} else {
$this->url->setParam('colors', null);
}
return $this; return $this;
} }
@ -198,6 +181,7 @@ EOD;
public function setTitle($title) public function setTitle($title)
{ {
$this->title = $this->view()->escape($title); $this->title = $this->view()->escape($title);
return $this; return $this;
} }
@ -211,7 +195,7 @@ EOD;
public function __construct(array $data, $title, $colors = null) public function __construct(array $data, $title, $colors = null)
{ {
$this->setTitle($title); $this->setTitle($title);
$this->url = Url::fromPath('svg/chart.php');
if (array_key_exists('data', $data)) { if (array_key_exists('data', $data)) {
$this->data = $data['data']; $this->data = $data['data'];
if (array_key_exists('colors', $data)) { if (array_key_exists('colors', $data)) {
@ -220,12 +204,14 @@ EOD;
} else { } else {
$this->setData($data); $this->setData($data);
} }
if (isset($colors)) { if (isset($colors)) {
$this->setColors($colors); $this->setColors($colors);
} else { } else {
$this->setColors($this->colors); $this->setColors($this->colors);
} }
} }
/** /**
* Renders this widget via the given view and returns the * Renders this widget via the given view and returns the
* HTML as a string * HTML as a string
@ -234,14 +220,15 @@ EOD;
*/ */
public function render() public function render()
{ {
if ($this->view()->layout()->getLayout() === 'pdf') {
$pie = new PieChart(); $pie = new PieChart();
$pie->alignTopLeft(); $pie->alignTopLeft();
$pie->disableLegend(); $pie->disableLegend();
$pie->drawPie(array( $pie->drawPie([
'data' => $this->data, 'colors' => $this->colors 'data' => $this->data,
)); 'colors' => $this->colors
]);
if ($this->view()->layout()->getLayout() === 'pdf') {
try { try {
$png = $pie->toPng($this->size, $this->size); $png = $pie->toPng($this->size, $this->size);
return '<img class="inlinepie" src="data:image/png;base64,' . base64_encode($png) . '" />'; return '<img class="inlinepie" src="data:image/png;base64,' . base64_encode($png) . '" />';
@ -250,39 +237,27 @@ EOD;
} }
} }
$pie->title = $this->title;
$pie->description = $this->title;
$template = $this->template; $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('{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; return $template;
} }
public static function createFromStateSummary(stdClass $states, $title, array $colors) public static function createFromStateSummary(stdClass $states, $title, array $colors)
{ {
$handledUnhandledStates = array(); $handledUnhandledStates = [];
foreach ($states as $key => $value) { foreach ($states as $key => $value) {
if (StringHelper::endsWith($key, '_handled') || StringHelper::endsWith($key, '_unhandled')) { if (StringHelper::endsWith($key, '_handled') || StringHelper::endsWith($key, '_unhandled')) {
$handledUnhandledStates[$key] = $value; $handledUnhandledStates[$key] = $value;
} }
} }
$chart = new self(array_values($handledUnhandledStates), $title, $colors); $chart = new self(array_values($handledUnhandledStates), $title, $colors);
return $chart return $chart
->setSize(50) ->setSize(50)
->setTitle('') ->setTitle('')

View File

@ -425,9 +425,6 @@ class Perfdata
$pieChart = new InlinePie($data, $this); $pieChart = new InlinePie($data, $this);
$pieChart->setColors(array('#44bb77', '#ffaa44', '#ff5566', '#ddccdd')); $pieChart->setColors(array('#44bb77', '#ffaa44', '#ff5566', '#ddccdd'));
if (Zend_Controller_Front::getInstance()->getRequest()->isXmlHttpRequest()) {
$pieChart->disableNoScript();
}
return $pieChart; return $pieChart;
} }

View File

@ -147,12 +147,13 @@
} }
// Performance data pie charts // Performance data pie charts
.sparkline { .inline-pie {
height: 1em; display: inline-block;
height: 14/12em;
margin-right: 0.1em; margin-right: 0.1em;
position: relative; position: relative;
top: 0.1em; top: 0.1em;
width: 1em; width: 14/12em;
} }
// Host and service summaries in detail and list views // Host and service summaries in detail and list views

View File

@ -1,27 +0,0 @@
/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
(function(Icinga, $) {
'use strict';
Icinga.Behaviors = Icinga.Behaviors || {};
var Sparkline = function (icinga) {
Icinga.EventListener.call(this, icinga);
this.on('rendered', this.onRendered, this);
};
Sparkline.prototype = new Icinga.EventListener();
Sparkline.prototype.onRendered = function(e) {
$(e.target).find('.sparkline').each(function() {
$(this).sparkline('html', {
enableTagOptions: true,
disableTooltips: true
});
});
};
Icinga.Behaviors.Sparkline = Sparkline;
})(Icinga, jQuery);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long