* @license BSD */ namespace Domframework; /** * Manage the vertical axis */ class GraphAxisVertical extends GraphAxisGeneral { /** * The angle choosed to draw the graph */ private $angle; /** * The padding between the label and the axis */ protected $padding = 7; /** * The width of the labels + padding (it is the base of the graph) in pixels */ protected $width; /** * The number of chars to be displayed in one label */ protected $nbcharsLabel = 0; /** * Look for the width of the Y axis * @param resource $gd The resource to modify */ public function getWidth($gd) { if ($this->numerical) { if ($this->max === null) { throw new \Exception(dgettext( "domframework", "The max is not defined for graphAxisVertical" ), 406); } // Look at the minimum distance between two labeled values $bbox = imagettfbbox($this->fontsize, 0, $this->fontfile, "NOT"); $height = abs($bbox[5] - $bbox[1]) + $this->padding; for ($nbMaxValues = 10; $nbMaxValues > 2; $nbMaxValues--) { if ($nbMaxValues * $height < abs($this->top - $this->bottom)) { break; } } $labels = $this->labels($nbMaxValues); $labelBiggest = ""; $this->nbcharsLabel = 0; foreach ($labels as $label) { if (strlen($label) > $this->nbcharsLabel) { $this->nbcharsLabel = strlen($label); $labelBiggest = $label; } } $bbox = imagettfbbox( $this->fontsize, $this->angle, $this->fontfile, $labelBiggest ); $width = abs($bbox[4] - $bbox[0]); $this->width = $width + 2 * $this->padding; return $this->width; } else { if ($this->data === null) { return $this->padding; } die("TODO : getWidth in labeled line " . __LINE__ . "\n"); } } /** * Calculate the position in pixels for a value * If the value is out of range, return null to not draw the point * @param string|float|integer $value The value to position */ public function position($value) { if ($value === null) { return null; } if (! is_numeric($value) && ! is_string($value)) { throw new \Exception(dgettext( "domframework", "Invalid value provided to graph Axis for position" ) . " " . get_class($this), 406); } if ($this->numerical === null) { throw new \Exception(dgettext( "domframework", "No numerical type defined for Axis" ) . " " . get_class($this), 406); } if ($this->numerical) { // Numerical axis, use a standard scale if ($value > $this->labelMax || $value < $this->labelMin) { return null; } $scale = ($value - $this->labelMin) / ($this->labelMax - $this->labelMin); $pos = intval($this->bottom + $scale * ($this->top - $this->bottom)); return $pos; } else { // Label axis, count them if (! is_array($this->data)) { throw new \Exception(dgettext( "domframework", "No data defined for Axis" ) . " " . get_class($this), 406); } $pos = array_search($value, $this->data, true); if ($pos === false) { return null; } $width = ($this->top - $this->bottom) / count($this->data); $pos = intval($this->bottom + $width * $pos + $width / 2); return $pos; } } /** * Calculate the positionMin, used for labeled axies * If the value is out of range, return null to not draw the point * @param string|float|integer $value The value to position */ public function positionMin($value) { $posCenter = $this->position($value); if ($this->numerical) { return $posCenter; } if (! is_array($this->data)) { throw new \Exception(dgettext( "domframework", "No data defined for Axis" ) . " " . get_class($this), 406); } $pos = array_search($value, $this->data, true); if ($pos === false) { return null; } $width = ($this->top - $this->bottom) / count($this->data); return intval($this->bottom + $width * $pos); } /** * Calculate the positionMax, used for labeled axies * If the value is out of range, return null to not draw the point * @param string|float|integer $value The value to position */ public function positionMax($value) { $posCenter = $this->position($value); if ($this->numerical) { return $posCenter; } if (! is_array($this->data)) { throw new \Exception(dgettext( "domframework", "No data defined for Axis" ) . " " . get_class($this), 406); } $pos = array_search($value, $this->data, true); if ($pos === false) { return null; } $width = ($this->top - $this->bottom) / count($this->data); return intval($this->bottom + $width * $pos + $width); } /** * Draw the axis labels and lines * @param resource $gd The resource to modify */ public function draw($gd) { $axisColor = Color::allocateFromText($gd, $this->axisColor); if ($this->numerical) { // Look at the minimum distance between two labeled values $bbox = imagettfbbox($this->fontsize, 0, $this->fontfile, "NOT"); $height = abs($bbox[5] - $bbox[1]) + $this->padding; for ($nbMaxValues = 10; $nbMaxValues > 2; $nbMaxValues--) { if ($nbMaxValues * $height < abs($this->top - $this->bottom)) { break; } } $width = $this->getWidth($gd); $labels = $this->labels($nbMaxValues); if (count($labels) > $nbMaxValues) { die("Too much labels to display (" . count($labels) . " > $nbMaxValues)\n"); } foreach ($labels as $label) { $this->drawOne($gd, $width, $label); $this->drawGrid($gd, $width, $label); } $this->drawAxis($gd, $width); } else { // Labeled // If there is no data, there is nothing to draw : return if ($this->data === null) { return; } die("graphAxisVertical::draw labeled TBD line " . __LINE__ . "\n"); } } }