From 8ca6cc32b2c789a3149861159ad258f2cb9491e3 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 14:39:39 +0200 Subject: Adding upstream version 2.11.4. Signed-off-by: Daniel Baumann --- library/Icinga/Chart/SVGRenderer.php | 331 +++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 library/Icinga/Chart/SVGRenderer.php (limited to 'library/Icinga/Chart/SVGRenderer.php') diff --git a/library/Icinga/Chart/SVGRenderer.php b/library/Icinga/Chart/SVGRenderer.php new file mode 100644 index 0000000..d3891f2 --- /dev/null +++ b/library/Icinga/Chart/SVGRenderer.php @@ -0,0 +1,331 @@ +createDocumentType( + 'svg', + '-//W3C//DTD SVG 1.1//EN', + 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' + ); + + $this->document = $implementation->createDocument(null, '', $docType); + $this->svg = $this->createOuterBox(); + $this->document->appendChild($this->svg); + } + + /** + * Create the outer SVG box containing the root svg element and namespace and return it + * + * @return DOMElement The SVG root node + */ + private function createOuterBox() + { + $ctx = $this->createRenderContext(); + $svg = $this->document->createElement('svg'); + $svg->setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + $svg->setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + $svg->setAttribute('role', $this->ariaRole); + $svg->setAttribute('width', '100%'); + $svg->setAttribute('height', '100%'); + $svg->setAttribute( + 'viewBox', + sprintf( + '0 0 %s %s', + $ctx->getNrOfUnitsX(), + $ctx->getNrOfUnitsY() + ) + ); + if ($this->preserveAspectRatio) { + $svg->setAttribute( + 'preserveAspectRatio', + sprintf( + '%s%s %s', + $this->xAspectRatio, + $this->yAspectRatio, + $this->xFillMode + ) + ); + } + return $svg; + } + + /** + * Add aria title and description + * + * Adds an aria title and desc element to the given SVG node, which are used to describe this SVG by accessibility + * tools such as screen readers. + * + * @param DOMNode $svg The SVG DOMNode to which the aria attributes should be attached + * @param $title The title text + * @param $description The description text + */ + private function addAriaDescription(DOMNode $svg, $titleText, $descriptionText) + { + $doc = $svg->ownerDocument; + + $titleId = $descId = ''; + if (isset($this->ariaTitle)) { + $titleId = 'aria-title-' . $this->stripNonAlphanumeric($titleText); + $title = $doc->createElement('title'); + $title->setAttribute('id', $titleId); + + $title->appendChild($doc->createTextNode($titleText)); + $svg->appendChild($title); + } + + if (isset($this->ariaDescription)) { + $descId = 'aria-desc-' . $this->stripNonAlphanumeric($descriptionText); + $desc = $doc->createElement('desc'); + $desc->setAttribute('id', $descId); + + $desc->appendChild($doc->createTextNode($descriptionText)); + $svg->appendChild($desc); + } + + $svg->setAttribute('aria-labelledby', join(' ', array($titleId, $descId))); + } + + /** + * Initialises the XML-document, SVG-element and this figure's root canvas + * + * @param int $width The width ratio + * @param int $height The height ratio + */ + public function __construct($width, $height) + { + $this->width = $width; + $this->height = $height; + $this->rootCanvas = new Canvas('root', new LayoutBox(0, 0)); + } + + /** + * Render the SVG-document + * + * @return string The resulting XML structure + */ + public function render() + { + $this->createRootDocument(); + $ctx = $this->createRenderContext(); + $this->addAriaDescription($this->svg, $this->ariaTitle, $this->ariaDescription); + $this->svg->appendChild($this->rootCanvas->toSvg($ctx)); + $this->document->formatOutput = true; + $this->document->encoding = 'UTF-8'; + return $this->document->saveXML(); + } + + /** + * Create a render context that will be used for rendering elements + * + * @return RenderContext The created RenderContext instance + */ + public function createRenderContext() + { + return new RenderContext($this->document, $this->width, $this->height); + } + + /** + * Return the root canvas of this rendered + * + * @return Canvas The canvas that will be the uppermost element in this figure + */ + public function getCanvas() + { + return $this->rootCanvas; + } + + /** + * Preserve the aspect ratio of the rendered object + * + * Do not deform the content of the SVG when the aspect ratio of the viewBox + * differs from the aspect ratio of the SVG element, but add padding or cutoff + * instead + * + * @param bool $preserve Whether the aspect ratio should be preserved + */ + public function preserveAspectRatio($preserve = true) + { + $this->preserveAspectRatio = $preserve; + } + + /** + * Change the horizontal alignment of the SVG element + * + * Change the horizontal alignment of the svg, when preserveAspectRatio is used and + * padding is present. Defaults to + */ + public function setXAspectRatioAlignment($alignment) + { + $this->xAspectRatio = $alignment; + } + + /** + * Change the vertical alignment of the SVG element + * + * Change the vertical alignment of the svg, when preserveAspectRatio is used and + * padding is present. + */ + public function setYAspectRatioAlignment($alignment) + { + $this->yAspectRatio = $alignment; + } + + /** + * Set the aria description, that is used as a title for this SVG in screen readers + * + * @param $text + */ + public function setAriaTitle($text) + { + $this->ariaTitle = $text; + } + + /** + * Set the aria description, that is used to describe this SVG in screen readers + * + * @param $text + */ + public function setAriaDescription($text) + { + $this->ariaDescription = $text; + } + + /** + * Set the aria role, that is used to describe the purpose of this SVG in screen readers + * + * @param $text + */ + public function setAriaRole($text) + { + $this->ariaRole = $text; + } + + + private function stripNonAlphanumeric($str) + { + return preg_replace('/[^A-Za-z]+/', '', $str); + } +} -- cgit v1.2.3