You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
5.2 KiB
224 lines
5.2 KiB
<?php declare(strict_types = 0);
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** 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.
|
|
**/
|
|
|
|
|
|
/**
|
|
* SVG graphs axis class.
|
|
*/
|
|
class CSvgGraphAxis extends CSvgGroup {
|
|
|
|
private const ZBX_STYLE_CLASS = 'svg-graph-axis';
|
|
|
|
private const ZBX_STYLE_GRAPH_AXIS_LEFT = 'svg-graph-axis-left';
|
|
private const ZBX_STYLE_GRAPH_AXIS_RIGHT = 'svg-graph-axis-right';
|
|
private const ZBX_STYLE_GRAPH_AXIS_BOTTOM = 'svg-graph-axis-bottom';
|
|
|
|
/**
|
|
* Axis triangle icon size.
|
|
*
|
|
* @var int
|
|
*/
|
|
private const ZBX_ARROW_SIZE = 5;
|
|
|
|
private const ZBX_ARROW_OFFSET = 5;
|
|
|
|
/**
|
|
* Array of labels. Key is coordinate, value is text label.
|
|
*
|
|
* @var array
|
|
*/
|
|
private $labels;
|
|
|
|
/**
|
|
* Axis type. One of CSvgGraphAxis::AXIS_* constants.
|
|
*
|
|
* @var int
|
|
*/
|
|
private $type;
|
|
|
|
/**
|
|
* Color for labels.
|
|
*
|
|
* @var string
|
|
*/
|
|
private $text_color;
|
|
|
|
/**
|
|
* Color for axis.
|
|
*
|
|
* @var string
|
|
*/
|
|
private $line_color;
|
|
|
|
public function __construct(array $labels, int $type) {
|
|
parent::__construct();
|
|
|
|
$this->labels = $labels;
|
|
$this->type = $type;
|
|
}
|
|
|
|
public function setTextColor(string $color): self {
|
|
$this->text_color = $color;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setLineColor(string $color): self {
|
|
$this->line_color = $color;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Return CSS style definitions for axis as array.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function makeStyles(): array {
|
|
$this
|
|
->addClass(self::ZBX_STYLE_CLASS)
|
|
->addClass([
|
|
GRAPH_YAXIS_SIDE_RIGHT => self::ZBX_STYLE_GRAPH_AXIS_RIGHT,
|
|
GRAPH_YAXIS_SIDE_LEFT => self::ZBX_STYLE_GRAPH_AXIS_LEFT,
|
|
GRAPH_YAXIS_SIDE_BOTTOM => self::ZBX_STYLE_GRAPH_AXIS_BOTTOM
|
|
][$this->type]);
|
|
|
|
return [
|
|
'.'.self::ZBX_STYLE_CLASS.' path' => [
|
|
'stroke' => $this->line_color,
|
|
'fill' => 'transparent'
|
|
],
|
|
'.'.self::ZBX_STYLE_CLASS.' text' => [
|
|
'fill' => $this->text_color,
|
|
'font-size' => '11px',
|
|
'alignment-baseline' => 'middle',
|
|
'dominant-baseline' => 'middle'
|
|
],
|
|
'.'.self::ZBX_STYLE_GRAPH_AXIS_RIGHT.' text' => [
|
|
'text-anchor' => 'start'
|
|
],
|
|
'.'.self::ZBX_STYLE_GRAPH_AXIS_LEFT.' text' => [
|
|
'text-anchor' => 'end'
|
|
],
|
|
'.'.self::ZBX_STYLE_GRAPH_AXIS_BOTTOM.' text' => [
|
|
'text-anchor' => 'middle'
|
|
]
|
|
];
|
|
}
|
|
|
|
private function getAxis(): array {
|
|
$offset = ceil(self::ZBX_ARROW_SIZE / 2);
|
|
|
|
if ($this->type == GRAPH_YAXIS_SIDE_BOTTOM) {
|
|
$x = $this->x + $this->width + self::ZBX_ARROW_OFFSET;
|
|
$y = $this->y;
|
|
|
|
return [
|
|
// Draw axis line.
|
|
(new CSvgPath())
|
|
->setAttribute('shape-rendering', 'crispEdges')
|
|
->moveTo($this->x, $y)
|
|
->lineTo($x, $y),
|
|
// Draw arrow.
|
|
(new CSvgPath())
|
|
->moveTo($x + self::ZBX_ARROW_SIZE, $y)
|
|
->lineTo($x, $y - $offset)
|
|
->lineTo($x, $y + $offset)
|
|
->closePath()
|
|
];
|
|
}
|
|
|
|
$x = ($this->type == GRAPH_YAXIS_SIDE_RIGHT) ? $this->x : $this->x + $this->width;
|
|
$y = $this->y - self::ZBX_ARROW_OFFSET;
|
|
|
|
return [
|
|
// Draw axis line.
|
|
(new CSvgPath())
|
|
->setAttribute('shape-rendering', 'crispEdges')
|
|
->moveTo($x, $y)
|
|
->lineTo($x, $this->height + $y + self::ZBX_ARROW_OFFSET),
|
|
// Draw arrow.
|
|
(new CSvgPath())
|
|
->moveTo($x, $y - self::ZBX_ARROW_SIZE)
|
|
->lineTo($x - $offset, $y)
|
|
->lineTo($x + $offset, $y)
|
|
->closePath()
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Return array of initialized CSvgText objects for axis labels.
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getLabels(): array {
|
|
$x = 0;
|
|
$y = 0;
|
|
$labels = [];
|
|
|
|
if ($this->type == GRAPH_YAXIS_SIDE_BOTTOM) {
|
|
$axis = 'x';
|
|
$y = $this->height - CSvgGraph::SVG_GRAPH_X_AXIS_LABEL_MARGIN;
|
|
}
|
|
else {
|
|
$axis = 'y';
|
|
$x = ($this->type == GRAPH_YAXIS_SIDE_RIGHT)
|
|
? CSvgGraph::SVG_GRAPH_Y_AXIS_RIGHT_LABEL_MARGIN
|
|
: $this->width - CSvgGraph::SVG_GRAPH_Y_AXIS_LEFT_LABEL_MARGIN;
|
|
}
|
|
|
|
foreach ($this->labels as $pos => $label) {
|
|
$$axis = $pos;
|
|
|
|
if ($this->type == GRAPH_YAXIS_SIDE_LEFT || $this->type == GRAPH_YAXIS_SIDE_RIGHT) {
|
|
// Flip upside down.
|
|
$y = $this->height - $y;
|
|
}
|
|
|
|
if ($this->type == GRAPH_YAXIS_SIDE_BOTTOM) {
|
|
if (count($labels) == 0) {
|
|
$text_tag_x = max($this->x + $x, strlen($label) * 4);
|
|
}
|
|
elseif (end($this->labels) === $label) {
|
|
$text_tag_x = (strlen($label) * 4 > $this->width - $x) ? $this->x + $x - 10 : $this->x + $x;
|
|
}
|
|
else {
|
|
$text_tag_x = $this->x + $x;
|
|
}
|
|
}
|
|
else {
|
|
$text_tag_x = $this->x + $x;
|
|
}
|
|
|
|
$labels[] = new CSvgText($label, $text_tag_x, $this->y + $y);
|
|
}
|
|
|
|
return $labels;
|
|
}
|
|
|
|
public function toString($destroy = true): string {
|
|
$this
|
|
->additem($this->getAxis())
|
|
->additem($this->getLabels());
|
|
|
|
return parent::toString($destroy);
|
|
}
|
|
}
|