diff options
Diffstat (limited to 'library/Icinga/Chart/Chart.php')
-rw-r--r-- | library/Icinga/Chart/Chart.php | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/library/Icinga/Chart/Chart.php b/library/Icinga/Chart/Chart.php new file mode 100644 index 0000000..eaf69d1 --- /dev/null +++ b/library/Icinga/Chart/Chart.php @@ -0,0 +1,162 @@ +<?php +/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Chart; + +use Imagick; +use Icinga\Chart\Legend; +use Icinga\Chart\Palette; +use Icinga\Chart\Primitive\Drawable; +use Icinga\Chart\SVGRenderer; +use Icinga\Exception\IcingaException; + +/** + * Base class for charts, extended by all other Chart classes. + */ +abstract class Chart implements Drawable +{ + protected $align = false; + + /** + * SVG renderer that handles + * + * @var SVGRenderer + */ + protected $renderer; + + /** + * Legend to use for this chart + * + * @var Legend + */ + protected $legend; + + /** + * The style-palette for this chart + * + * @var Palette + */ + protected $palette; + + /** + * The title of this chart, used for providing accessibility features + * + * @var string + */ + public $title; + + /** + * The description for this chart, mandatory for providing accessibility features + * + * @var string + */ + public $description; + + /** + * Create a new chart object and create internal objects + * + * If you want to extend this class use the init() method as an extension point, + * as this will be called at the end of the construct call + */ + public function __construct() + { + $this->legend = new Legend(); + $this->palette = new Palette(); + $this->init(); + } + + /** + * Extension point for subclasses, called on __construct + */ + protected function init() + { + } + + /** + * Extension point for implementing rendering logic + * + * This method is called after data validation, but before toSvg is called + */ + protected function build() + { + } + + /** + * Check if the current dataset has the proper structure for this chart. + * + * Needs to be overwritten by extending classes. The default implementation returns false. + * + * @return bool True when the dataset is valid, otherwise false + */ + abstract public function isValidDataFormat(); + + + /** + * Disable the legend for this chart + */ + public function disableLegend() + { + $this->legend = null; + } + + /** + * Render this graph and return the created SVG + * + * @return string The SVG created by the SvgRenderer + * + * @throws IcingaException Thrown wen the dataset is not valid for this graph + * @see SVGRenderer::render + */ + public function render() + { + if (!$this->isValidDataFormat()) { + throw new IcingaException('Dataset for graph doesn\'t have the proper structure'); + } + $this->build(); + if ($this->align) { + $this->renderer->preserveAspectRatio(); + $this->renderer->setXAspectRatioAlignment(SVGRenderer::X_ASPECT_RATIO_MIN); + $this->renderer->setYAspectRatioAlignment(SVGRenderer::Y_ASPECT_RATIO_MIN); + } + + $this->renderer->setAriaDescription($this->description); + $this->renderer->setAriaTitle($this->title); + $this->renderer->getCanvas()->setAriaRole('presentation'); + + $this->renderer->getCanvas()->addElement($this); + return $this->renderer->render(); + } + + /** + * Return this graph rendered as PNG + * + * @param int $width The width of the PNG in pixel + * @param int $height The height of the PNG in pixel + * + * @return string A PNG binary string + * + * @throws IcingaException In case ImageMagick is not available + */ + public function toPng($width, $height) + { + if (! class_exists('Imagick')) { + throw new IcingaException('Cannot render PNGs without ImageMagick'); + } + + $image = new Imagick(); + $image->readImageBlob($this->render()); + $image->setImageFormat('png24'); + $image->resizeImage($width, $height, imagick::FILTER_LANCZOS, 1); + return $image; + } + + /** + * Align the chart to the top left corner instead of centering it + * + * @param bool $align + */ + public function alignTopLeft($align = true) + { + $this->align = $align; + } +} |