diff options
author | Kore Nordmann <github@kore-nordmann.de> | 2009-07-21 15:30:28 +0000 |
---|---|---|
committer | Kore Nordmann <github@kore-nordmann.de> | 2009-07-21 15:30:28 +0000 |
commit | d3098e04fc668f56dc3a5ac23b2030df2e33931b (patch) | |
tree | 5b2fa5a282941ae8b81476cedd7984fca0764c9d | |
parent | 7eb8eaccc84eb2f8e505b415b186631f2366c693 (diff) | |
download | zetacomponents-graph-d3098e04fc668f56dc3a5ac23b2030df2e33931b.zip zetacomponents-graph-d3098e04fc668f56dc3a5ac23b2030df2e33931b.tar.gz |
- Refactored rotated axis label renderer for better extensibility
# Groundwork for #15095
-rw-r--r-- | src/renderer/axis_label_rotated.php | 451 |
1 files changed, 254 insertions, 197 deletions
diff --git a/src/renderer/axis_label_rotated.php b/src/renderer/axis_label_rotated.php index 6187494..201cdb3 100644 --- a/src/renderer/axis_label_rotated.php +++ b/src/renderer/axis_label_rotated.php @@ -151,53 +151,23 @@ class ezcGraphAxisRotatedLabelRenderer extends ezcGraphAxisLabelRenderer } /** - * Render Axis labels + * Determine text offset. * - * Render labels for an axis. + * Calculate the label offset and angle, from the configured or evaluated + * text angle. * - * @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 + * Returns the text angle in degrees. + * + * @param ezcGraphChartElementAxis $axis + * @param array $steps + * @return float */ - public function renderLabels( - ezcGraphRenderer $renderer, - ezcGraphBoundings $boundings, - ezcGraphCoordinate $start, - ezcGraphCoordinate $end, - ezcGraphChartElementAxis $axis, - ezcGraphBoundings $innerBoundings = null ) - { - // 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 ) ); - - // Get axis space - $gridBoundings = null; - list( $xSpace, $ySpace ) = $this->getAxisSpace( $renderer, $boundings, $axis, $innerBoundings, $gridBoundings ); - - // Determine optimal angle if none specified - $this->determineAngle( $steps, $xSpace, $ySpace, $axisBoundings ); - + 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 ) ); @@ -221,6 +191,69 @@ class ezcGraphAxisRotatedLabelRenderer extends ezcGraphAxisLabelRenderer $this->offset = 0; } + return $degTextAngle; + } + + /** + * Calculate label size + * + * Calculate the size of a single lable in a single step. + * + * @param array $steps + * @param int $nr + * @param array $step + * @param float $xSpace + * @param float $ySpace + * @param ezcGraphBoundings $axisBoundings + * @return float + */ + protected function calculateLabelSize( array $steps, $nr, $step, $xSpace, $ySpace, ezcGraphBoundings $axisBoundings ) + { + switch ( true ) + { + case ( $nr === 0 ): + $labelSize = min( + abs( + $xSpace * 2 * $this->direction->y + + $ySpace * 2 * $this->direction->x ), + abs( + $step->width * $axisBoundings->width * $this->direction->x + + $step->width * $axisBoundings->height * $this->direction->y ) + ); + break; + case ( $step->isLast ): + $labelSize = min( + abs( + $xSpace * 2 * $this->direction->y + + $ySpace * 2 * $this->direction->x ), + abs( + $steps[$nr - 1]->width * $axisBoundings->width * $this->direction->x + + $steps[$nr - 1]->width * $axisBoundings->height * $this->direction->y ) + ); + break; + default: + $labelSize = abs( + $step->width * $axisBoundings->width * $this->direction->x + + $step->width * $axisBoundings->height * $this->direction->y + ); + break; + } + + return $labelSize * cos( deg2rad( $this->angle ) ); + } + + /** + * Calculate general label length + * + * @param ezcGraphCoordinate $start + * @param ezcGraphCoordinate $end + * @param float $xSpace + * @param float $ySpace + * @param ezcGraphBoundings $axisBoundings + * @return float + */ + protected function calculateLabelLength( ezcGraphCoordinate $start, ezcGraphCoordinate $end, $xSpace, $ySpace, ezcGraphBoundings $axisBoundings ) + { $axisSpaceFactor = abs( ( $this->direction->x == 0 ? 0 : $this->direction->x * $ySpace / $axisBoundings->width ) + @@ -228,14 +261,14 @@ class ezcGraphAxisRotatedLabelRenderer extends ezcGraphAxisLabelRenderer $this->direction->y * $xSpace / $axisBoundings->height ) ); - $start = new ezcGraphCoordinate( - $start->x + max( 0., $axisSpaceFactor * $this->offset ) * ( $end->x - $start->x ), - $start->y + max( 0., $axisSpaceFactor * $this->offset ) * ( $end->y - $start->y ) - ); - $end = new ezcGraphCoordinate( - $end->x + min( 0., $axisSpaceFactor * $this->offset ) * ( $end->x - $start->x ), - $end->y + min( 0., $axisSpaceFactor * $this->offset ) * ( $end->y - $start->y ) - ); + $axisWidth = $end->x - $start->x; + $axisHeight = $end->y - $start->y; + + $start->x += max( 0., $axisSpaceFactor * $this->offset ) * $axisWidth; + $start->y += max( 0., $axisSpaceFactor * $this->offset ) * $axisHeight; + + $end->x += min( 0., $axisSpaceFactor * $this->offset ) * $axisWidth; + $end->y += min( 0., $axisSpaceFactor * $this->offset ) * $axisHeight; $labelLength = sqrt( pow( @@ -249,6 +282,173 @@ class ezcGraphAxisRotatedLabelRenderer extends ezcGraphAxisLabelRenderer ); $this->offset *= $axisSpaceFactor; + return $labelLength; + } + + /** + * Render label text. + * + * Render the text of a single label, depending on the position, length and + * rotation of the label. + * + * @param ezcGraphRenderer $renderer + * @param ezcGraphChartElementAxis $axis + * @param ezcGraphCoordinate $position + * @param string $label + * @param float $degTextAngle + * @param float $labelLength + * @param float $labelSize + * @param float $lengthReducement + * @return void + */ + protected function renderLabelText( ezcGraphRenderer $renderer, ezcGraphChartElementAxis $axis, ezcGraphCoordinate $position, $label, $degTextAngle, $labelLength, $labelSize, $lengthReducement ) + { + 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, + $position->x - abs( $labelLength ) + $lengthReducement, + $position->y + $labelSize + ); + $labelAlignement = ezcGraph::LEFT | ezcGraph::TOP; + $labelRotation = $degTextAngle; + break; + } + + $renderer->drawText( + $labelBoundings, + $label, + $labelAlignement, + new ezcGraphRotation( + $labelRotation, + $position + ) + ); + } + + /** + * 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, + ezcGraphBoundings $innerBoundings = null ) + { + // receive rendering parameters from axis + $steps = $axis->getSteps(); + + $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(); + + // Get axis space + $gridBoundings = null; + list( $xSpace, $ySpace ) = $this->getAxisSpace( $renderer, $boundings, $axis, $innerBoundings, $gridBoundings ); + + // Determine optimal angle if none specified + $this->determineAngle( $steps, $xSpace, $ySpace, $axisBoundings ); + $degTextAngle = $this->determineTextOffset( $axis, $steps ); + $labelLength = $this->calculateLabelLength( $start, $end, $xSpace, $ySpace, $axisBoundings ); // Draw steps and grid foreach ( $steps as $nr => $step ) @@ -264,165 +464,22 @@ class ezcGraphAxisRotatedLabelRenderer extends ezcGraphAxisLabelRenderer ); // Calculate label boundings - switch ( true ) - { - case ( $nr === 0 ): - $labelSize = min( - abs( - $xSpace * 2 * $this->direction->y + - $ySpace * 2 * $this->direction->x ), - abs( - $step->width * $axisBoundings->width * $this->direction->x + - $step->width * $axisBoundings->height * $this->direction->y ) - ); - break; - case ( $step->isLast ): - $labelSize = min( - abs( - $xSpace * 2 * $this->direction->y + - $ySpace * 2 * $this->direction->x ), - abs( - $steps[$nr - 1]->width * $axisBoundings->width * $this->direction->x + - $steps[$nr - 1]->width * $axisBoundings->height * $this->direction->y ) - ); - break; - default: - $labelSize = abs( - $step->width * $axisBoundings->width * $this->direction->x + - $step->width * $axisBoundings->height * $this->direction->y - ); - break; - } - - $labelSize = $labelSize * cos( deg2rad( $this->angle ) ); + $labelSize = $this->calculateLabelSize( $steps, $nr, $step, $xSpace, $ySpace, $axisBoundings ); $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, - $position->x - abs( $labelLength ) + $lengthReducement, - $position->y + $labelSize - ); - $labelAlignement = ezcGraph::LEFT | ezcGraph::TOP; - $labelRotation = $degTextAngle; - break; - } - - $renderer->drawText( - $labelBoundings, - $step->label, - $labelAlignement, - new ezcGraphRotation( - $labelRotation, - $position - ) - ); + $this->renderLabelText( $renderer, $axis, $position, $step->label, $degTextAngle, $labelLength, $labelSize, $lengthReducement ); - // major grid + // Major grid if ( $axis->majorGrid ) { - $this->drawGrid( - $renderer, - $gridBoundings, - $position, - $stepSize, - $axis->majorGrid - ); + $this->drawGrid( $renderer, $gridBoundings, $position, $stepSize, $axis->majorGrid ); } - // major step - $this->drawStep( - $renderer, - $position, - $this->direction, - $axis->position, - $this->majorStepSize, - $axis->border - ); + // Major step + $this->drawStep( $renderer, $position, $this->direction, $axis->position, $this->majorStepSize, $axis->border ); } } |