Пример #1
0
 /**
  * Determine text offset.
  *
  * Calculate the label offset and angle, from the configured or evaluated
  * text angle.
  *
  * Returns the text angle in degrees.
  * 
  * @param ezcGraphChartElementAxis $axis
  * @param array $steps
  * @return float
  */
 protected function determineTextOffset(ezcGraphChartElementAxis $axis, array $steps)
 {
     // Determine additional required axis space by boxes
     $firstStep = reset($steps);
     $lastStep = end($steps);
     $axisAngle = -$this->direction->angle(new ezcGraphVector(1, 0));
     $textAngle = $axisAngle + deg2rad($this->angle) + ($axis->position & (ezcGraph::TOP | ezcGraph::BOTTOM) ? deg2rad(270) : deg2rad(90));
     // Ensure angle between 0 and 360 degrees
     $degTextAngle = rad2deg($textAngle);
     while ($degTextAngle < 0) {
         $degTextAngle += 360.0;
     }
     if ($this->properties['labelOffset']) {
         $this->offset = ($this->angle < 0 ? -1 : 1) * ($axis->position & (ezcGraph::TOP | ezcGraph::LEFT) ? 1 : -1) * (1 - cos(deg2rad($this->angle * 2)));
     } else {
         $this->offset = 0;
     }
     return $degTextAngle;
 }
Пример #2
0
 /**
  * Draw all left axis labels
  * 
  * @return void
  */
 protected function drawAxisLabels()
 {
     foreach ($this->axisLabels as $nr => $axisLabel) {
         // If font should not be synchronized, use font configuration from
         // each axis
         if ($this->options->syncAxisFonts === false) {
             $this->driver->options->font = $axisLabel['axis']->font;
         }
         $start = $axisLabel['start'];
         $end = $axisLabel['end'];
         $direction = new ezcGraphVector($end->x - $start->x, $end->y - $start->y);
         $direction->unify();
         // Convert elipse to circle for correct angle calculation
         $direction->y *= $this->xAxisSpace / $this->yAxisSpace;
         $angle = $direction->angle(new ezcGraphVector(0, 1));
         $movement = new ezcGraphVector(sin($angle) * $this->xAxisSpace * ($direction->x < 0 ? -1 : 1), cos($angle) * $this->yAxisSpace);
         $start->x += $movement->x;
         $start->y += $movement->y;
         $end->x -= $movement->x;
         $end->y -= $movement->y;
         $axisLabel['object']->renderLabels($this, $axisLabel['boundings'], $start, $end, $axisLabel['axis']);
         // Prevent from redrawing axis on more then 2 axis.
         unset($this->axisLabels[$nr]);
     }
 }
 /**
  * Render Axis labels
  *
  * Render labels for an axis.
  *
  * @param ezcGraphRenderer $renderer Renderer used to draw the chart
  * @param ezcGraphBoundings $boundings Boundings of the axis
  * @param ezcGraphCoordinate $start Axis starting point
  * @param ezcGraphCoordinate $end Axis ending point
  * @param ezcGraphChartElementAxis $axis Axis instance
  * @return void
  */
 public function renderLabels(ezcGraphRenderer $renderer, ezcGraphBoundings $boundings, ezcGraphCoordinate $start, ezcGraphCoordinate $end, ezcGraphChartElementAxis $axis)
 {
     // receive rendering parameters from axis
     $steps = $axis->getSteps();
     $this->steps = $steps;
     $axisBoundings = new ezcGraphBoundings($start->x, $start->y, $end->x, $end->y);
     // Determine normalized axis direction
     $this->direction = new ezcGraphVector($end->x - $start->x, $end->y - $start->y);
     $this->direction->unify();
     $axisAngle = -$this->direction->angle(new ezcGraphVector(1, 0));
     if ($this->outerGrid) {
         $gridBoundings = $boundings;
     } else {
         $gridBoundings = new ezcGraphBoundings($boundings->x0 + $renderer->xAxisSpace, $boundings->y0 + $renderer->yAxisSpace, $boundings->x1 - $renderer->xAxisSpace, $boundings->y1 - $renderer->yAxisSpace);
     }
     // Determine optimal angle if none specified
     if ($this->angle === null) {
         $minimumStepWidth = null;
         foreach ($steps as $nr => $step) {
             if ($minimumStepWidth === null || $step->width < $minimumStepWidth) {
                 $minimumStepWidth = $step->width;
             }
         }
         $width = abs($axisBoundings->width * $minimumStepWidth * $this->direction->x + $axisBoundings->height * $minimumStepWidth * $this->direction->y);
         $height = abs($renderer->yAxisSpace * $this->direction->x + $renderer->xAxisSpace * $this->direction->y);
         $length = sqrt(pow($width, 2) + pow($height, 2));
         $this->angle = rad2deg(acos($height / $length));
     }
     // Determine additional required axis space by boxes
     $firstStep = reset($steps);
     $lastStep = end($steps);
     $textAngle = $axisAngle + deg2rad($this->angle) + ($axis->position & (ezcGraph::TOP | ezcGraph::BOTTOM) ? deg2rad(270) : deg2rad(90));
     // Ensure angle between 0 and 360 degrees
     $degTextAngle = rad2deg($textAngle);
     while ($degTextAngle < 0) {
         $degTextAngle += 360.0;
     }
     $this->offset = ($this->angle < 0 ? -1 : 1) * ($axis->position & (ezcGraph::TOP | ezcGraph::LEFT) ? 1 : -1) * (1 - cos(deg2rad($this->angle * 2)));
     $axisSpaceFactor = abs(($this->direction->x == 0 ? 0 : $this->direction->x * $renderer->yAxisSpace / $axisBoundings->width) + ($this->direction->y == 0 ? 0 : $this->direction->y * $renderer->xAxisSpace / $axisBoundings->height));
     $start = new ezcGraphCoordinate($start->x + max(0.0, $axisSpaceFactor * $this->offset) * ($end->x - $start->x), $start->y + max(0.0, $axisSpaceFactor * $this->offset) * ($end->y - $start->y));
     $end = new ezcGraphCoordinate($end->x + min(0.0, $axisSpaceFactor * $this->offset) * ($end->x - $start->x), $end->y + min(0.0, $axisSpaceFactor * $this->offset) * ($end->y - $start->y));
     $labelLength = sqrt(pow($renderer->xAxisSpace * $this->direction->y + $axisSpaceFactor * $this->offset * ($end->x - $start->x), 2) + pow($renderer->yAxisSpace * $this->direction->x + $axisSpaceFactor * $this->offset * ($end->y - $start->y), 2));
     $this->offset *= $axisSpaceFactor;
     // Draw steps and grid
     foreach ($steps as $nr => $step) {
         $position = new ezcGraphCoordinate($start->x + ($end->x - $start->x) * $step->position * abs($this->direction->x), $start->y + ($end->y - $start->y) * $step->position * abs($this->direction->y));
         $stepSize = new ezcGraphCoordinate(($end->x - $start->x) * $step->width, ($end->y - $start->y) * $step->width);
         // Calculate label boundings
         switch (true) {
             case $nr === 0:
                 $labelSize = min(abs($renderer->xAxisSpace * 2 * $this->direction->x + $renderer->yAxisSpace * 2 * $this->direction->y), abs($step->width * $axisBoundings->width * $this->direction->x + $step->width * $axisBoundings->height * $this->direction->y));
                 break;
             case $step->isLast:
                 $labelSize = min(abs($renderer->xAxisSpace * 2 * $this->direction->x + $renderer->yAxisSpace * 2 * $this->direction->y), abs($steps[$nr - 1]->width * $axisBoundings->width * $this->direction->x + $steps[$nr - 1]->width * $axisBoundings->height * $this->direction->y));
                 break;
             default:
                 $labelSize = min(abs($step->width * $axisBoundings->width * $this->direction->x + $step->width * $axisBoundings->height * $this->direction->y), abs($steps[$nr - 1]->width * $axisBoundings->width * $this->direction->x + $steps[$nr - 1]->width * $axisBoundings->height * $this->direction->y));
                 break;
         }
         $labelSize = $labelSize * cos(deg2rad($this->angle));
         $lengthReducement = min(abs(tan(deg2rad($this->angle)) * ($labelSize / 2)), abs($labelLength / 2));
         switch (true) {
             case $degTextAngle >= 0 && $degTextAngle < 90 && ($axis->position === ezcGraph::LEFT || $axis->position === ezcGraph::RIGHT) || $degTextAngle >= 270 && $degTextAngle < 360 && ($axis->position === ezcGraph::TOP || $axis->position === ezcGraph::BOTTOM):
                 $labelBoundings = new ezcGraphBoundings($position->x, $position->y, $position->x + abs($labelLength) - $lengthReducement, $position->y + $labelSize);
                 $labelAlignement = ezcGraph::LEFT | ezcGraph::TOP;
                 $labelRotation = $degTextAngle;
                 break;
             case $degTextAngle >= 90 && $degTextAngle < 180 && ($axis->position === ezcGraph::LEFT || $axis->position === ezcGraph::RIGHT) || $degTextAngle >= 180 && $degTextAngle < 270 && ($axis->position === ezcGraph::TOP || $axis->position === ezcGraph::BOTTOM):
                 $labelBoundings = new ezcGraphBoundings($position->x - abs($labelLength) + $lengthReducement, $position->y, $position->x, $position->y + $labelSize);
                 $labelAlignement = ezcGraph::RIGHT | ezcGraph::TOP;
                 $labelRotation = $degTextAngle - 180;
                 break;
             case $degTextAngle >= 180 && $degTextAngle < 270 && ($axis->position === ezcGraph::LEFT || $axis->position === ezcGraph::RIGHT) || $degTextAngle >= 90 && $degTextAngle < 180 && ($axis->position === ezcGraph::TOP || $axis->position === ezcGraph::BOTTOM):
                 $labelBoundings = new ezcGraphBoundings($position->x - abs($labelLength) + $lengthReducement, $position->y - $labelSize, $position->x, $position->y);
                 $labelAlignement = ezcGraph::RIGHT | ezcGraph::BOTTOM;
                 $labelRotation = $degTextAngle - 180;
                 break;
             case $degTextAngle >= 270 && $degTextAngle < 360 && ($axis->position === ezcGraph::LEFT || $axis->position === ezcGraph::RIGHT) || $degTextAngle >= 0 && $degTextAngle < 90 && ($axis->position === ezcGraph::TOP || $axis->position === ezcGraph::BOTTOM):
                 $labelBoundings = new ezcGraphBoundings($position->x, $position->y + $labelSize, $position->x + abs($labelLength) - $lengthReducement, $position->y);
                 $labelAlignement = ezcGraph::LEFT | ezcGraph::BOTTOM;
                 $labelRotation = $degTextAngle;
                 break;
         }
         $renderer->drawText($labelBoundings, $step->label, $labelAlignement, new ezcGraphRotation($labelRotation, $position));
         // major grid
         if ($axis->majorGrid) {
             $this->drawGrid($renderer, $gridBoundings, $position, $stepSize, $axis->majorGrid);
         }
         // major step
         $this->drawStep($renderer, $position, $this->direction, $axis->position, $this->majorStepSize, $axis->border);
     }
 }
Пример #4
0
 /**
  * Draw grid
  *
  * Draws a grid line at the current position
  * 
  * @param ezcGraphRenderer $renderer Renderer to draw the grid with
  * @param ezcGraphBoundings $boundings Boundings of axis
  * @param ezcGraphCoordinate $position Position of step
  * @param ezcGraphCoordinate $direction Direction of axis
  * @param ezcGraphColor $color Color of axis
  * @param int $stepPosition
  * @return void
  */
 protected function drawGrid(ezcGraphRenderer $renderer, ezcGraphBoundings $boundings, ezcGraphCoordinate $position, ezcGraphCoordinate $direction, ezcGraphColor $color, $stepPosition = null)
 {
     // Calculate position on last axis
     $start = new ezcGraphCoordinate($boundings->x0 + ($width = $boundings->width / 2), $boundings->y0 + ($height = $boundings->height / 2));
     $lastAngle = $this->lastStep * 2 * M_PI;
     $end = new ezcGraphCoordinate($start->x + sin($lastAngle) * $width, $start->y - cos($lastAngle) * $height);
     $direction = new ezcGraphVector($end->x - $start->x, $end->y - $start->y);
     $direction->unify();
     // Convert elipse to circle for correct angle calculation
     $direction->y *= $renderer->xAxisSpace / $renderer->yAxisSpace;
     $angle = $direction->angle(new ezcGraphVector(0, 1));
     $movement = new ezcGraphVector(sin($angle) * $renderer->xAxisSpace * ($direction->x < 0 ? -1 : 1), cos($angle) * $renderer->yAxisSpace);
     $start->x += $movement->x;
     $start->y += $movement->y;
     $end->x -= $movement->x;
     $end->y -= $movement->y;
     $lastPosition = new ezcGraphCoordinate($start->x + ($end->x - $start->x) * $stepPosition, $start->y + ($end->y - $start->y) * $stepPosition);
     $renderer->drawGridLine($position, $lastPosition, $color);
 }
Пример #5
0
 public function testVectorAngle180Vector2()
 {
     $vector = new ezcGraphVector(0, 1);
     $result = $vector->angle(new ezcGraphVector(0, -1));
     $this->assertEquals($result, M_PI, 'Wrong angle returned', 0.01);
 }
Пример #6
0
 /**
  * Draw all left axis labels
  * 
  * @return void
  */
 protected function drawAxisLabels()
 {
     foreach ($this->axisLabels as $nr => $axisLabel) {
         $start = $axisLabel['start'];
         $end = $axisLabel['end'];
         $direction = new ezcGraphVector($end->x - $start->x, $end->y - $start->y);
         $direction->unify();
         // Convert elipse to circle for correct angle calculation
         $direction->y *= $this->xAxisSpace / $this->yAxisSpace;
         $angle = $direction->angle(new ezcGraphVector(0, 1));
         $movement = new ezcGraphVector(sin($angle) * $this->xAxisSpace * ($direction->x < 0 ? -1 : 1), cos($angle) * $this->yAxisSpace);
         $start->x += $movement->x;
         $start->y += $movement->y;
         $end->x -= $movement->x;
         $end->y -= $movement->y;
         $axisLabel['object']->renderLabels($this, $axisLabel['boundings'], $start, $end, $axisLabel['axis']);
         // Prevent from redrawing axis on more then 2 axis.
         unset($this->axisLabels[$nr]);
     }
 }