properties['majorStepCount'] = false; $this->properties['minorStepCount'] = false; $this->properties['majorStepSize'] = 3; $this->properties['minorStepSize'] = 1; $this->properties['innerStep'] = true; $this->properties['outerStep'] = false; $this->properties['outerGrid'] = false; $this->properties['showLabels'] = true; $this->properties['labelPadding'] = 2; parent::__construct( $options ); } /** * __set * * @param mixed $propertyName * @param mixed $propertyValue * @throws ezcBaseValueException * If a submitted parameter was out of range or type. * @throws ezcBasePropertyNotFoundException * If a the value for the property options is not an instance of * @return void * @ignore */ public function __set( $propertyName, $propertyValue ) { switch ( $propertyName ) { case 'driver': if ( $propertyValue instanceof ezcGraphDriver ) { $this->properties['driver'] = $propertyValue; } else { throw new ezcGraphInvalidDriverException( $propertyValue ); } break; case 'majorStepCount': if ( ( $propertyValue !== false ) && !is_numeric( $propertyValue ) || ( $propertyValue < 0 ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); } $this->properties['majorStepCount'] = (int) $propertyValue; break; case 'minorStepCount': if ( ( $propertyValue !== false ) && !is_numeric( $propertyValue ) || ( $propertyValue < 0 ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); } $this->properties['minorStepCount'] = (int) $propertyValue; break; case 'majorStepSize': if ( !is_numeric( $propertyValue ) || ( $propertyValue < 0 ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); } $this->properties['majorStepSize'] = (int) $propertyValue; break; case 'minorStepSize': if ( !is_numeric( $propertyValue ) || ( $propertyValue < 0 ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); } $this->properties['minorStepSize'] = (int) $propertyValue; break; case 'innerStep': if ( !is_bool( $propertyValue ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'bool' ); } $this->properties['innerStep'] = (bool) $propertyValue; break; case 'outerStep': if ( !is_bool( $propertyValue ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'bool' ); } $this->properties['outerStep'] = (bool) $propertyValue; break; case 'outerGrid': if ( !is_bool( $propertyValue ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'bool' ); } $this->properties['outerGrid'] = (bool) $propertyValue; break; case 'showLabels': if ( !is_bool( $propertyValue ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'bool' ); } $this->properties['showLabels'] = (bool) $propertyValue; break; case 'labelPadding': if ( !is_numeric( $propertyValue ) || ( $propertyValue < 0 ) ) { throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' ); } $this->properties['labelPadding'] = (int) $propertyValue; break; default: throw new ezcBasePropertyNotFoundException( $propertyName ); } } /** * Checks for the cutting point of two lines. * * The lines are given by a start position and the direction of the line, * both as instances of {@link ezcGraphCoordinate}. If no cutting point * could be calculated, because the lines are parallel the function will * return false. Otherwise the factor returned can be used to calculate the * cutting point using the following equatation: * point = $aStart + $factor * $aDir; * * We return the factor instead of the resulting point because it can be * easily determined from the factor if the cutting point is in "behind" * the line starting point, or if the distance to the cutting point is * bigger then the direction vector is long ( $factor > 1 ). * * @param ezcGraphCoordinate $aStart * @param ezcGraphCoordinate $aDir * @param ezcGraphCoordinate $bStart * @param ezcGraphCoordinate $bDir * @return mixed */ public function determineLineCuttingPoint( ezcGraphCoordinate $aStart, ezcGraphCoordinate $aDir, ezcGraphCoordinate $bStart, ezcGraphCoordinate $bDir ) { // Check if lines are parallel if ( ( ( abs( $aDir->x ) < .000001 ) && ( abs( $bDir->x ) < .000001 ) ) || ( ( abs( $aDir->y ) < .000001 ) && ( abs( $bDir->y ) < .000001 ) ) || ( ( abs( $aDir->x * $bDir->x * $aDir->y * $bDir->y ) > .000001 ) && ( abs( ( $aDir->x / $aDir->y ) - ( $bDir->x / $bDir->y ) ) < .000001 ) ) ) { return false; } // Use ? : to prevent division by zero $denominator = ( abs( $aDir->y ) > .000001 ? $bDir->y / $aDir->y : .0 ) - ( abs( $aDir->x ) > .000001 ? $bDir->x / $aDir->x : .0 ); // Solve equatation if ( abs( $denominator ) < .000001 ) { return - ( ( abs( $aDir->y ) > .000001 ? $bStart->y / $aDir->y : .0 ) - ( abs( $aDir->y ) > .000001 ? $aStart->y / $aDir->y : .0 ) - ( abs( $aDir->x ) > .000001 ? $bStart->x / $aDir->x : .0 ) + ( abs( $aDir->x ) > .000001 ? $aStart->x / $aDir->x : .0 ) ); } else { return - ( ( abs( $aDir->y ) > .000001 ? $bStart->y / $aDir->y : .0 ) - ( abs( $aDir->y ) > .000001 ? $aStart->y / $aDir->y : .0 ) - ( abs( $aDir->x ) > .000001 ? $bStart->x / $aDir->x : .0 ) + ( abs( $aDir->x ) > .000001 ? $aStart->x / $aDir->x : .0 ) ) / $denominator; } } /** * Draw single step on a axis * * Draws a step on a axis at the current position * * @param ezcGraphRenderer $renderer Renderer to draw the step with * @param ezcGraphCoordinate $position Position of step * @param ezcGraphCoordinate $direction Direction of axis * @param int $axisPosition Position of axis * @param int $size Step size * @param ezcGraphColor $color Color of axis * @return void */ public function drawStep( ezcGraphRenderer $renderer, ezcGraphCoordinate $position, ezcGraphCoordinate $direction, $axisPosition, $size, ezcGraphColor $color ) { if ( ! ( $this->innerStep || $this->outerStep ) ) { return false; } $drawStep = false; if ( ( ( $axisPosition === ezcGraph::CENTER ) && $this->innerStep ) || ( ( $axisPosition === ezcGraph::BOTTOM ) && $this->outerStep ) || ( ( $axisPosition === ezcGraph::TOP ) && $this->innerStep ) || ( ( $axisPosition === ezcGraph::RIGHT ) && $this->outerStep ) || ( ( $axisPosition === ezcGraph::LEFT ) && $this->innerStep ) ) { // Turn direction vector to left by 90 degrees and multiply // with major step size $stepStart = new ezcGraphCoordinate( $position->x - $direction->y * $size, $position->y + $direction->x * $size ); $drawStep = true; } else { $stepStart = $position; } if ( ( ( $axisPosition === ezcGraph::CENTER ) && $this->innerStep ) || ( ( $axisPosition === ezcGraph::BOTTOM ) && $this->innerStep ) || ( ( $axisPosition === ezcGraph::TOP ) && $this->outerStep ) || ( ( $axisPosition === ezcGraph::RIGHT ) && $this->innerStep ) || ( ( $axisPosition === ezcGraph::LEFT ) && $this->outerStep ) ) { // Turn direction vector to right by 90 degrees and multiply // with major step size $stepEnd = new ezcGraphCoordinate( $position->x + $direction->y * $size, $position->y - $direction->x * $size ); $drawStep = true; } else { $stepEnd = $position; } if ( $drawStep ) { $renderer->drawStepLine( $stepStart, $stepEnd, $color ); } } /** * 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 * @return void */ protected function drawGrid( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings, ezcGraphCoordinate $position, ezcGraphCoordinate $direction, ezcGraphColor $color ) { // Direction of grid line is direction of axis turned right by 90 // degrees $gridDirection = new ezcGraphCoordinate( $direction->y, - $direction->x ); $cuttingPoints = array(); foreach ( array( // Bounding lines array( 'start' => new ezcGraphCoordinate( $boundings->x0, $boundings->y0 ), 'dir' => new ezcGraphCoordinate( 0, $boundings->y1 - $boundings->y0 ) ), array( 'start' => new ezcGraphCoordinate( $boundings->x0, $boundings->y0 ), 'dir' => new ezcGraphCoordinate( $boundings->x1 - $boundings->x0, 0 ) ), array( 'start' => new ezcGraphCoordinate( $boundings->x1, $boundings->y1 ), 'dir' => new ezcGraphCoordinate( 0, $boundings->y0 - $boundings->y1 ) ), array( 'start' => new ezcGraphCoordinate( $boundings->x1, $boundings->y1 ), 'dir' => new ezcGraphCoordinate( $boundings->x0 - $boundings->x1, 0 ) ), ) as $boundingLine ) { // Test for cutting points with bounding lines, where cutting // position is between 0 and 1, which means, that the line is hit // on the bounding box rectangle. Use these points as a start and // ending point for the grid lines. There should *always* be // exactly two points returned. $cuttingPosition = $this->determineLineCuttingPoint( $boundingLine['start'], $boundingLine['dir'], $position, $gridDirection ); if ( $cuttingPosition === false ) { continue; } // Round to prevent minor float incorectnesses $cuttingPosition = abs( round( $cuttingPosition, 2 ) ); if ( ( $cuttingPosition >= 0 ) && ( $cuttingPosition <= 1 ) ) { $cuttingPoints[] = new ezcGraphCoordinate( $boundingLine['start']->x + $cuttingPosition * $boundingLine['dir']->x, $boundingLine['start']->y + $cuttingPosition * $boundingLine['dir']->y ); } } if ( count( $cuttingPoints ) < 2 ) { // This should not happpen return false; } // Finally draw grid line $renderer->drawGridLine( $cuttingPoints[0], $cuttingPoints[1], $color ); } /** * Modify chart boundings * * Optionally modify boundings of chart data * * @param ezcGraphBoundings $boundings Current boundings of chart * @param ezcGraphCoordinate $direction Direction of the current axis * @return ezcGraphBoundings Modified boundings */ public function modifyChartBoundings( ezcGraphBoundings $boundings, ezcGraphCoordinate $direction ) { return $boundings; } /** * Modify chart data position * * Optionally additionally modify the coodinate of a data point * * @param ezcGraphCoordinate $coordinate Data point coordinate * @return ezcGraphCoordinate Modified coordinate */ public function modifyChartDataPosition( ezcGraphCoordinate $coordinate ) { return $coordinate; } /** * 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 */ abstract public function renderLabels( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings, ezcGraphCoordinate $start, ezcGraphCoordinate $end, ezcGraphChartElementAxis $axis ); } ?>