Add basic tests and meta attributes for graphs

refs #4614
This commit is contained in:
Jannis Moßhammer 2013-09-23 12:09:40 +02:00 committed by Marius Hein
parent b78d1a236a
commit 7690b0ec7f
14 changed files with 201 additions and 5 deletions

View File

@ -84,12 +84,14 @@ class BarGraph extends Styleable implements Drawable
{ {
$doc = $ctx->getDocument(); $doc = $ctx->getDocument();
$group = $doc->createElement('g'); $group = $doc->createElement('g');
$idx = 0;
foreach ($this->dataSet as $point) { foreach ($this->dataSet as $point) {
$rect = new Rect($point[0]-1, $point[1], 2, 100- $point[1]); $rect = new Rect($point[0]-1, $point[1], 2, 100- $point[1]);
$rect->setFill($this->fill); $rect->setFill($this->fill);
$rect->setStrokeWidth($this->strokeWidth); $rect->setStrokeWidth($this->strokeWidth);
$rect->setStrokeColor('black'); $rect->setStrokeColor('black');
$rect->setAttribute('data-icinga-graph-index', $idx++);
$rect->setAttribute('data-icinga-graph-type', 'bar');
$rect->setAdditionalStyle('clip-path: url(#clip);'); $rect->setAdditionalStyle('clip-path: url(#clip);');
$rect->setAnimation( $rect->setAnimation(
new Animation( new Animation(

View File

@ -144,6 +144,7 @@ class LineGraph extends Styleable implements Drawable
$path->setStrokeColor($this->strokeColor); $path->setStrokeColor($this->strokeColor);
$path->setStrokeWidth($this->strokeWidth); $path->setStrokeWidth($this->strokeWidth);
$path->setAttribute('data-icinga-graph-type', 'line');
if ($this->fill !== 'none') { if ($this->fill !== 'none') {
$firstX = $this->dataset[0][0]; $firstX = $this->dataset[0][0];
$lastX = $this->dataset[count($this->dataset)-1][0]; $lastX = $this->dataset[count($this->dataset)-1][0];
@ -151,6 +152,7 @@ class LineGraph extends Styleable implements Drawable
->append(array($lastX, 100)); ->append(array($lastX, 100));
$path->setFill($this->fill); $path->setFill($this->fill);
} }
$path->setAdditionalStyle('clip-path: url(#clip);'); $path->setAdditionalStyle('clip-path: url(#clip);');
$path->setId($this->id); $path->setId($this->id);
$group = $path->toSvg($ctx); $group = $path->toSvg($ctx);

View File

@ -190,7 +190,7 @@ class PieChart extends Chart
->setFill($this->getColorForPieSlice($pie, $idx)); ->setFill($this->getColorForPieSlice($pie, $idx));
$innerBox->addElement($slice); $innerBox->addElement($slice);
// add caption if not disabled // add caption if not disabled
if (!$this->noCaption) { if (!$this->noCaption && isset($pie['labels'])) {
$slice->setCaption($pie['labels'][$labelPos++]) $slice->setCaption($pie['labels'][$labelPos++])
->setLabelGroup($labelBox); ->setLabelGroup($labelBox);
@ -231,7 +231,7 @@ class PieChart extends Chart
->setFill($this->getColorForPieSlice($pie, $idx)) ->setFill($this->getColorForPieSlice($pie, $idx))
->setLabelGroup($labelBox); ->setLabelGroup($labelBox);
if (!$this->noCaption) { if (!$this->noCaption && isset($pie['labels'])) {
$slice->setCaption($pie['labels'][$labelPos++]) $slice->setCaption($pie['labels'][$labelPos++])
->setCaptionOffset($offset) ->setCaptionOffset($offset)
->setOuterCaptionBound(50); ->setOuterCaptionBound(50);

View File

@ -65,4 +65,4 @@ abstract class Animatable extends Styleable
$dom->appendChild($this->animation->toSvg($ctx)); $dom->appendChild($this->animation->toSvg($ctx));
} }
} }
} }

View File

@ -82,6 +82,7 @@ class Circle extends Styleable implements Drawable
$circle->setAttribute('cy', $coords[1]); $circle->setAttribute('cy', $coords[1]);
$circle->setAttribute('r', 5); $circle->setAttribute('r', 5);
$circle->setAttribute('style', $this->getStyle()); $circle->setAttribute('style', $this->getStyle());
$this->applyAttributes($circle);
return $circle; return $circle;
} }
} }

View File

@ -100,6 +100,7 @@ class Line extends Styleable implements Drawable
$line->setAttribute('y1', $y1); $line->setAttribute('y1', $y1);
$line->setAttribute('y2', $y2); $line->setAttribute('y2', $y2);
$line->setAttribute('style', $this->getStyle()); $line->setAttribute('style', $this->getStyle());
$this->applyAttributes($line);
return $line; return $line;
} }
} }

View File

@ -170,6 +170,7 @@ class Path extends Styleable implements Drawable
} }
$path->setAttribute('d', $pathDescription); $path->setAttribute('d', $pathDescription);
$path->setAttribute('style', $this->getStyle()); $path->setAttribute('style', $this->getStyle());
$this->applyAttributes($path);
$group->appendChild($path); $group->appendChild($path);
return $group; return $group;
} }

View File

@ -288,7 +288,9 @@ class PieSlice extends Animatable implements Drawable
$slicePath->setAttribute('d', $this->getPieSlicePath($x, $y, $r)); $slicePath->setAttribute('d', $this->getPieSlicePath($x, $y, $r));
$slicePath->setAttribute('style', $this->getStyle()); $slicePath->setAttribute('style', $this->getStyle());
$slicePath->setAttribute('data-icinga-graph-type', 'pieslice');
$this->applyAttributes($slicePath);
$group->appendChild($slicePath); $group->appendChild($slicePath);
if ($this->caption != "") { if ($this->caption != "") {
$lblGroup = ($this->labelGroup ? $this->labelGroup : $group); $lblGroup = ($this->labelGroup ? $this->labelGroup : $group);

View File

@ -115,6 +115,7 @@ class Rect extends Animatable implements Drawable
$rect->setAttribute('height', $height); $rect->setAttribute('height', $height);
$rect->setAttribute('style', $this->getStyle()); $rect->setAttribute('style', $this->getStyle());
$this->applyAttributes($rect);
$this->appendAnimation($rect, $ctx); $this->appendAnimation($rect, $ctx);
return $rect; return $rect;

View File

@ -29,6 +29,8 @@
namespace Icinga\Chart\Primitive; namespace Icinga\Chart\Primitive;
use DOMElement;
/** /**
* Base class for stylable drawables * Base class for stylable drawables
*/ */
@ -65,6 +67,13 @@ class Styleable
*/ */
public $id = null; public $id = null;
/**
* Additional attributes to be set
*
* @var array
*/
public $attributes = array();
/** /**
* Set the stroke width for this drawable * Set the stroke width for this drawable
* *
@ -142,4 +151,19 @@ class Styleable
$base .= ';' . $this->additionalStyle . ';'; $base .= ';' . $this->additionalStyle . ';';
return $base; return $base;
} }
/**
* Add an additional attribte to this element
*/
public function setAttribute($key, $value)
{
$this->attributes[$key] = $value;
}
protected function applyAttributes(DOMElement $el)
{
foreach ($this->attributes as $name => $value) {
$el->setAttribute($name, $value);
}
}
} }

View File

@ -152,7 +152,6 @@ class Text extends Styleable implements Drawable
{ {
list($x, $y) = $ctx->toAbsolute($this->x, $this->y); list($x, $y) = $ctx->toAbsolute($this->x, $this->y);
$text = $ctx->getDocument()->createElement('text'); $text = $ctx->getDocument()->createElement('text');
$text->setAttribute('x', $x - 15); $text->setAttribute('x', $x - 15);
$text->setAttribute( $text->setAttribute(
'style', 'style',
@ -162,6 +161,7 @@ class Text extends Styleable implements Drawable
. 'font-weight: normal; font-style: normal;' . 'font-weight: normal; font-style: normal;'
. 'text-anchor: ' . $this->alignment . 'text-anchor: ' . $this->alignment
); );
$text->setAttribute('y', $y); $text->setAttribute('y', $y);
$text->appendChild(new DOMText($this->text)); $text->appendChild(new DOMText($this->text));
return $text; return $text;

View File

@ -0,0 +1,88 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Chart;
use DOMXPath;
use DOMDocument;
use Icinga\Chart\GridChart;
use Icinga\Test\BaseTestCase;
use Test\Icinga\LibraryLoader;
// TODO: Use autoloader #4673
require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php');
require_once realpath(BaseTestCase::$testDir . '/library/Icinga/LibraryLoader.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Drawable.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Styleable.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Animatable.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/AxisUnit.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/LinearUnit.php');
LibraryLoader::loadFolder(realpath(BaseTestCase::$libDir . '/Chart'));
class GraphChartTest extends BaseTestCase
{
public function testBarChartCreation()
{
$chart = new GridChart();
$chart->drawBars(
array(
'label' => 'My bar',
'color' => 'black',
'data' => array(array(0, 0), array(1,1), array(1,2))
)
);
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadXML($chart->render());
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('x', 'http://www.w3.org/2000/svg');
$path = $xpath->query('//x:rect[@data-icinga-graph-type="bar"]');
$this->assertEquals(3, $path->length, 'Assert the correct number of datapoints being drawn as SVG bars');
}
public function testLineChartCreation()
{
$chart = new GridChart();
$chart->drawLines(
array(
'label' => 'My bar',
'color' => 'black',
'data' => array(array(0, 0), array(1,1), array(1,2))
)
);
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadXML($chart->render());
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('x', 'http://www.w3.org/2000/svg');
$path = $xpath->query('//x:path[@data-icinga-graph-type="line"]');
$this->assertEquals(1, $path->length, 'Assert the correct number of datapoints being drawn as SVG lines');
}
}

View File

@ -0,0 +1,70 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Chart;
use DOMXPath;
use DOMDocument;
use Icinga\Chart\GridChart;
use Icinga\Chart\PieChart;
use Icinga\Test\BaseTestCase;
use Test\Icinga\LibraryLoader;
// TODO: Use autoloader #4673
require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php');
require_once realpath(BaseTestCase::$testDir . '/library/Icinga/LibraryLoader.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Drawable.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Styleable.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Animatable.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/AxisUnit.php');
require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/LinearUnit.php');
LibraryLoader::loadFolder(realpath(BaseTestCase::$libDir . '/Chart'));
class PieChartTest extends BaseTestCase
{
public function testPieChartCreation()
{
$chart = new PieChart();
$chart->drawPie(
array(
'label' => 'My bar',
'color' => 'black', 'green', 'red',
'data' => array(50,50,50)
)
);
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadXML($chart->render());
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('x', 'http://www.w3.org/2000/svg');
$path = $xpath->query('//x:path[@data-icinga-graph-type="pieslice"]');
$this->assertEquals(3, $path->length, 'Assert the correct number of datapoints being drawn as SVG bars');
}
}

View File

@ -31,7 +31,11 @@ abstract class LibraryLoader {
{ {
$files = scandir($folder); $files = scandir($folder);
foreach ($files as $file) { foreach ($files as $file) {
if ($file[0] == '.') {
continue;
}
if ($recursive && is_dir(realpath($folder."/".$file))) { if ($recursive && is_dir(realpath($folder."/".$file))) {
self::loadFolder(realpath($folder."/".$file)); self::loadFolder(realpath($folder."/".$file));
} }
if (!preg_match('/php$/', $file)) { if (!preg_match('/php$/', $file)) {