mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-23 01:42:17 +00:00
EZ-Components
This commit is contained in:
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphAxisLabelRenderer class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Abstract class to render labels and grids on axis. Will be extended to
|
||||
* make it possible using different algorithms for rendering axis labels.
|
||||
*
|
||||
* @property bool $majorStepCount
|
||||
* Count of major steps.
|
||||
* @property bool $minorStepCount
|
||||
* Count of minor steps.
|
||||
* @property int $majorStepSize
|
||||
* Size of major steps.
|
||||
* @property int $minorStepSize
|
||||
* Size of minor steps.
|
||||
* @property bool $innerStep
|
||||
* Indicates if steps are shown on the inner side of axis.
|
||||
* @property bool $outerStep
|
||||
* Indicates if steps are shown on the outer side of axis.
|
||||
* @property bool $outerGrid
|
||||
* Indicates if the grid is shown on the outer side of axis.
|
||||
* @property bool $showLables
|
||||
* Indicates if the labels should be shown
|
||||
* @property int $labelPadding
|
||||
* Padding of labels.
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
abstract class ezcGraphAxisLabelRenderer extends ezcBaseOptions
|
||||
{
|
||||
/**
|
||||
* Driver to render axis labels
|
||||
*
|
||||
* @var ezcGraphDriver
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options Default option array
|
||||
* @return void
|
||||
* @ignore
|
||||
*/
|
||||
public function __construct( array $options = array() )
|
||||
{
|
||||
$this->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
|
||||
);
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphChart class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Class to represent a complete chart.
|
||||
*
|
||||
* @property ezcGraphRenderer $renderer
|
||||
* Renderer used to render chart
|
||||
* @property ezcGraphDriver $driver
|
||||
* Output driver used for chart
|
||||
* @property ezcGraphPalette $palette
|
||||
* Palette used for colorization of chart
|
||||
* @property-read mixed $renderedFile
|
||||
* Contains the filename of the rendered file, if rendered.
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
*/
|
||||
abstract class ezcGraphChart
|
||||
{
|
||||
|
||||
/**
|
||||
* Contains all general chart options
|
||||
*
|
||||
* @var ezcGraphChartConfig
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Contains subelelemnts of the chart like legend and axes
|
||||
*
|
||||
* @var array(ezcGraphChartElement)
|
||||
*/
|
||||
protected $elements = array();
|
||||
|
||||
/**
|
||||
* Contains the data of the chart
|
||||
*
|
||||
* @var ezcGraphChartDataContainer
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Array containing chart properties
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $properties;
|
||||
|
||||
/**
|
||||
* Contains the status wheather an element should be rendered
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $renderElement;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options Default option array
|
||||
* @return void
|
||||
* @ignore
|
||||
*/
|
||||
public function __construct( array $options = array() )
|
||||
{
|
||||
$this->palette = new ezcGraphPaletteTango();
|
||||
$this->data = new ezcGraphChartDataContainer( $this );
|
||||
|
||||
// Add standard elements
|
||||
$this->addElement( 'background', new ezcGraphChartElementBackground() );
|
||||
$this->elements['background']->position = ezcGraph::CENTER | ezcGraph::MIDDLE;
|
||||
|
||||
$this->addElement( 'title', new ezcGraphChartElementText() );
|
||||
$this->elements['title']->position = ezcGraph::TOP;
|
||||
$this->renderElement['title'] = false;
|
||||
|
||||
$this->addElement( 'legend', new ezcGraphChartElementLegend() );
|
||||
$this->elements['legend']->position = ezcGraph::LEFT;
|
||||
|
||||
// Define standard renderer and driver
|
||||
$this->properties['driver'] = new ezcGraphSvgDriver();
|
||||
$this->properties['renderer'] = new ezcGraphRenderer2d();
|
||||
$this->properties['renderer']->setDriver( $this->driver );
|
||||
|
||||
// Initialize other properties
|
||||
$this->properties['renderedFile'] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add element to chart
|
||||
*
|
||||
* Add a chart element to the chart and perform the required configuration
|
||||
* tasks for the chart element.
|
||||
*
|
||||
* @param string $name Element name
|
||||
* @param ezcGraphChartElement $element Chart element
|
||||
* @return void
|
||||
*/
|
||||
protected function addElement( $name, ezcGraphChartElement $element )
|
||||
{
|
||||
$this->elements[$name] = $element;
|
||||
$this->elements[$name]->font = $this->options->font;
|
||||
$this->elements[$name]->setFromPalette( $this->palette );
|
||||
|
||||
// Render element by default
|
||||
$this->renderElement[$name] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options write access
|
||||
*
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If Option could not be found
|
||||
* @throws ezcBaseValueException
|
||||
* If value is out of range
|
||||
* @param mixed $propertyName Option name
|
||||
* @param mixed $propertyValue Option value;
|
||||
* @return void
|
||||
* @ignore
|
||||
*/
|
||||
public function __set( $propertyName, $propertyValue )
|
||||
{
|
||||
switch ( $propertyName ) {
|
||||
case 'title':
|
||||
$this->elements['title']->title = $propertyValue;
|
||||
$this->renderElement['title'] = true;
|
||||
break;
|
||||
case 'legend':
|
||||
if ( !is_bool( $propertyValue ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'boolean' );
|
||||
}
|
||||
|
||||
$this->renderElement['legend'] = (bool) $propertyValue;
|
||||
break;
|
||||
case 'renderer':
|
||||
if ( $propertyValue instanceof ezcGraphRenderer )
|
||||
{
|
||||
$this->properties['renderer'] = $propertyValue;
|
||||
$this->properties['renderer']->setDriver( $this->driver );
|
||||
return $this->properties['renderer'];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'ezcGraphRenderer' );
|
||||
}
|
||||
break;
|
||||
case 'driver':
|
||||
if ( $propertyValue instanceof ezcGraphDriver )
|
||||
{
|
||||
$this->properties['driver'] = $propertyValue;
|
||||
$this->properties['renderer']->setDriver( $this->driver );
|
||||
return $this->properties['driver'];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'ezcGraphDriver' );
|
||||
}
|
||||
break;
|
||||
case 'palette':
|
||||
if ( $propertyValue instanceof ezcGraphPalette )
|
||||
{
|
||||
$this->properties['palette'] = $propertyValue;
|
||||
$this->setFromPalette( $this->palette );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcBaseValueException( "palette", $propertyValue, "instanceof ezcGraphPalette" );
|
||||
}
|
||||
|
||||
break;
|
||||
case 'renderedFile':
|
||||
$this->properties['renderedFile'] = (string) $propertyValue;
|
||||
break;
|
||||
case 'options':
|
||||
if ( $propertyValue instanceof ezcGraphChartOptions )
|
||||
{
|
||||
$this->options = $propertyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcBaseValueException( "options", $propertyValue, "instanceof ezcGraphOptions" );
|
||||
}
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $propertyName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set colors and border fro this element
|
||||
*
|
||||
* @param ezcGraphPalette $palette Palette
|
||||
* @return void
|
||||
*/
|
||||
public function setFromPalette( ezcGraphPalette $palette )
|
||||
{
|
||||
$this->options->font->name = $palette->fontName;
|
||||
$this->options->font->color = $palette->fontColor;
|
||||
|
||||
foreach ( $this->elements as $element )
|
||||
{
|
||||
$element->setFromPalette( $palette );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* @param mixed $propertyName
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If a the value for the property options is not an instance of
|
||||
* @return mixed
|
||||
* @ignore
|
||||
*/
|
||||
public function __get( $propertyName )
|
||||
{
|
||||
if ( array_key_exists( $propertyName, $this->properties ) )
|
||||
{
|
||||
return $this->properties[$propertyName];
|
||||
}
|
||||
|
||||
if ( isset( $this->elements[$propertyName] ) )
|
||||
{
|
||||
return $this->elements[$propertyName];
|
||||
}
|
||||
|
||||
if ( ( $propertyName === 'options' ) ||
|
||||
( $propertyName === 'data' ) )
|
||||
{
|
||||
return $this->$propertyName;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcGraphNoSuchElementException( $propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default display type of the current chart type.
|
||||
*
|
||||
* @return int Display type
|
||||
*/
|
||||
abstract public function getDefaultDisplayType();
|
||||
|
||||
/**
|
||||
* Return filename of rendered file, and false if no file was yet rendered.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRenderedFile()
|
||||
{
|
||||
return ( $this->renderedFile !== null ? $this->renderedFile : false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders this chart
|
||||
*
|
||||
* Creates basic visual chart elements from the chart to be processed by
|
||||
* the renderer.
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
abstract public function render( $width, $height, $file = null );
|
||||
|
||||
/**
|
||||
* Renders this chart to direct output
|
||||
*
|
||||
* Does the same as ezcGraphChart::render(), but renders directly to
|
||||
* output and not into a file.
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @return void
|
||||
*/
|
||||
abstract public function renderToOutput( $width, $height );
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphDataSetProperty class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Abstract class for properties of datasets
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
abstract class ezcGraphDataSetProperty implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Default value for this property
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $defaultValue;
|
||||
|
||||
/**
|
||||
* Contains specified values for single dataset elements
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dataValue;
|
||||
|
||||
/**
|
||||
* Contains a reference to the dataset to check for availability of data
|
||||
* keys
|
||||
*
|
||||
* @var ezcGraphDataSet
|
||||
*/
|
||||
protected $dataset;
|
||||
|
||||
/**
|
||||
* Abstract method to contain the check for validity of the value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function checkValue( &$value );
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ezcGraphDataSet $dataset
|
||||
* @ignore
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( ezcGraphDataSet $dataset )
|
||||
{
|
||||
$this->dataset = $dataset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default value for this property
|
||||
*
|
||||
* @param string $name Property name
|
||||
* @param mixed $value Property value
|
||||
* @return void
|
||||
*/
|
||||
public function __set( $name, $value )
|
||||
{
|
||||
if ( $name === 'default' &&
|
||||
$this->checkValue( $value ) )
|
||||
{
|
||||
$this->defaultValue = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value for this property
|
||||
*
|
||||
* @param string $name Property name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $name )
|
||||
{
|
||||
if ( $name === 'default' )
|
||||
{
|
||||
return $this->defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if an option exists.
|
||||
* Allows isset() using ArrayAccess.
|
||||
*
|
||||
* @param string $key The name of the option to get.
|
||||
* @return bool Wether the option exists.
|
||||
*/
|
||||
final public function offsetExists( $key )
|
||||
{
|
||||
return isset( $this->dataset[$key] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an option value.
|
||||
* Get an option value by ArrayAccess.
|
||||
*
|
||||
* @param string $key The name of the option to get.
|
||||
* @return mixed The option value.
|
||||
*
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If a the value for the property options is not an instance of
|
||||
*/
|
||||
final public function offsetGet( $key )
|
||||
{
|
||||
if ( isset( $this->dataValue[$key] ) )
|
||||
{
|
||||
return $this->dataValue[$key];
|
||||
}
|
||||
elseif ( isset( $this->dataset[$key] ) )
|
||||
{
|
||||
return $this->defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcGraphNoSuchDataException( $key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an option.
|
||||
* Sets an option using ArrayAccess.
|
||||
*
|
||||
* @param string $key The option to set.
|
||||
* @param mixed $value The value for the option.
|
||||
* @return void
|
||||
*
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If a the value for the property options is not an instance of
|
||||
* @throws ezcBaseValueException
|
||||
* If a the value for a property is out of range.
|
||||
*/
|
||||
public function offsetSet( $key, $value )
|
||||
{
|
||||
if ( isset( $this->dataset[$key] ) &&
|
||||
$this->checkValue( $value ) )
|
||||
{
|
||||
$this->dataValue[$key] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcGraphNoSuchDataException( $key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset an option.
|
||||
* Unsets an option using ArrayAccess.
|
||||
*
|
||||
* @param string $key The options to unset.
|
||||
* @return void
|
||||
*
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If a the value for the property options is not an instance of
|
||||
* @throws ezcBaseValueException
|
||||
* If a the value for a property is out of range.
|
||||
*/
|
||||
final public function offsetUnset( $key )
|
||||
{
|
||||
if ( isset( $this->dataset[$key] ) )
|
||||
{
|
||||
unset( $this->dataValue[$key] );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcGraphNoSuchDataException( $key );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,740 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphDriver class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Abstract class to be extended for ezcGraph output drivers.
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
abstract class ezcGraphDriver
|
||||
{
|
||||
/**
|
||||
* Driveroptions
|
||||
*
|
||||
* @var ezcDriverOptions
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options Default option array
|
||||
* @return void
|
||||
* @ignore
|
||||
*/
|
||||
abstract public function __construct( array $options = array() );
|
||||
|
||||
/**
|
||||
* Options write access
|
||||
*
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If Option could not be found
|
||||
* @throws ezcBaseValueException
|
||||
* If value is out of range
|
||||
* @param mixed $propertyName Option name
|
||||
* @param mixed $propertyValue Option value;
|
||||
* @return mixed
|
||||
* @ignore
|
||||
*/
|
||||
public function __set( $propertyName, $propertyValue )
|
||||
{
|
||||
switch ( $propertyName ) {
|
||||
case 'options':
|
||||
if ( $propertyValue instanceof ezcGraphDriverOptions )
|
||||
{
|
||||
$this->options = $propertyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcBaseValueException( "options", $propertyValue, "instanceof ezcGraphOptions" );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $propertyName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* @param mixed $propertyName
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If a the value for the property options is not an instance of
|
||||
* @return mixed
|
||||
* @ignore
|
||||
*/
|
||||
public function __get( $propertyName )
|
||||
{
|
||||
switch ( $propertyName )
|
||||
{
|
||||
case 'options':
|
||||
return $this->options;
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the size of a polygon
|
||||
*
|
||||
* The method takes a polygon defined by a list of points and reduces its
|
||||
* size by moving all lines to the middle by the given $size value.
|
||||
*
|
||||
* The detection of the inner side of the polygon depends on the angle at
|
||||
* each edge point. This method will always work for 3 edged polygones,
|
||||
* because the smaller angle will always be on the inner side. For
|
||||
* polygons with more then 3 edges this method may fail. For ezcGraph this
|
||||
* is a valid simplification, because we do not have any polygones which
|
||||
* have an inner angle >= 180 degrees.
|
||||
*
|
||||
* @param array(ezcGraphCoordinate) $points
|
||||
* @param float $size
|
||||
* @throws ezcGraphReducementFailedException
|
||||
* @return array( ezcGraphCoordinate )
|
||||
*/
|
||||
protected function reducePolygonSize( array $points, $size )
|
||||
{
|
||||
$pointCount = count( $points );
|
||||
|
||||
// Build normalized vectors between polygon edge points
|
||||
$vectors = array();
|
||||
$vectorLength = array();
|
||||
for ( $i = 0; $i < $pointCount; ++$i )
|
||||
{
|
||||
$nextPoint = ( $i + 1 ) % $pointCount;
|
||||
$vectors[$i] = ezcGraphVector::fromCoordinate( $points[$nextPoint] )
|
||||
->sub( $points[$i] );
|
||||
|
||||
// Throw exception if polygon is too small to reduce
|
||||
$vectorLength[$i] = $vectors[$i]->length();
|
||||
if ( $vectorLength[$i] < $size )
|
||||
{
|
||||
throw new ezcGraphReducementFailedException();
|
||||
}
|
||||
$vectors[$i]->unify();
|
||||
|
||||
// Remove point from list if it the same as the next point
|
||||
if ( ( $vectors[$i]->x == $vectors[$i]->y ) && ( $vectors[$i]->x == 0 ) )
|
||||
{
|
||||
$pointCount--;
|
||||
if ( $i === 0 )
|
||||
{
|
||||
$points = array_slice( $points, $i + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$points = array_merge(
|
||||
array_slice( $points, 0, $i ),
|
||||
array_slice( $points, $i + 1 )
|
||||
);
|
||||
}
|
||||
$i--;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove vectors and appendant point, if local angle equals zero
|
||||
// dergrees.
|
||||
for ( $i = 0; $i < $pointCount; ++$i )
|
||||
{
|
||||
$nextPoint = ( $i + 1 ) % $pointCount;
|
||||
|
||||
if ( ( abs( $vectors[$i]->x - $vectors[$nextPoint]->x ) < .0001 ) &&
|
||||
( abs( $vectors[$i]->y - $vectors[$nextPoint]->y ) < .0001 ) )
|
||||
{
|
||||
$pointCount--;
|
||||
|
||||
$points = array_merge(
|
||||
array_slice( $points, 0, $i + 1 ),
|
||||
array_slice( $points, $i + 2 )
|
||||
);
|
||||
$vectors = array_merge(
|
||||
array_slice( $vectors, 0, $i + 1 ),
|
||||
array_slice( $vectors, $i + 2 )
|
||||
);
|
||||
$i--;
|
||||
}
|
||||
}
|
||||
|
||||
// No reducements for lines
|
||||
if ( $pointCount <= 2 )
|
||||
{
|
||||
return $points;
|
||||
}
|
||||
|
||||
// Determine one of the angles - we need to know where the smaller
|
||||
// angle is, to determine if the inner side of the polygon is on
|
||||
// the left or right hand.
|
||||
//
|
||||
// This is a valid simplification for ezcGraph(, for now).
|
||||
//
|
||||
// The sign of the scalar products results indicates on which site
|
||||
// the smaller angle is, when comparing the orthogonale vector of
|
||||
// one of the vectors with the other. Why? .. use pen and paper ..
|
||||
//
|
||||
// It is sufficant to do this once before iterating over the points,
|
||||
// because the inner side of the polygon is on the same side of the
|
||||
// point for each point.
|
||||
$last = 0;
|
||||
$next = 1;
|
||||
|
||||
$sign = (
|
||||
-$vectors[$last]->y * $vectors[$next]->x +
|
||||
$vectors[$last]->x * $vectors[$next]->y
|
||||
) < 0 ? 1 : -1;
|
||||
|
||||
// Move points to center
|
||||
$newPoints = array();
|
||||
for ( $i = 0; $i < $pointCount; ++$i )
|
||||
{
|
||||
$last = $i;
|
||||
$next = ( $i + 1 ) % $pointCount;
|
||||
|
||||
// Orthogonal vector with direction based on the side of the inner
|
||||
// angle
|
||||
$v = clone $vectors[$next];
|
||||
if ( $sign > 0 )
|
||||
{
|
||||
$v->rotateCounterClockwise()->scalar( $size );
|
||||
}
|
||||
else
|
||||
{
|
||||
$v->rotateClockwise()->scalar( $size );
|
||||
}
|
||||
|
||||
// get last vector not pointing in reverse direction
|
||||
$lastVector = clone $vectors[$last];
|
||||
$lastVector->scalar( -1 );
|
||||
|
||||
// Calculate new point: Move point to the center site of the
|
||||
// polygon using the normalized orthogonal vectors next to the
|
||||
// point and the size as distance to move.
|
||||
// point + v + size / tan( angle / 2 ) * startVector
|
||||
$newPoint = clone $vectors[$next];
|
||||
$v ->add(
|
||||
$newPoint
|
||||
->scalar(
|
||||
$size /
|
||||
tan(
|
||||
$lastVector->angle( $vectors[$next] ) / 2
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// A fast guess: If the movement of the point exceeds the length of
|
||||
// the surrounding edge vectors the angle was to small to perform a
|
||||
// valid size reducement. In this case we just reduce the length of
|
||||
// the movement to the minimal length of the surrounding vectors.
|
||||
// This should fit in most cases.
|
||||
//
|
||||
// The correct way to check would be a test, if the calculated
|
||||
// point is still in the original polygon, but a test for a point
|
||||
// in a polygon is too expensive.
|
||||
$movement = $v->length();
|
||||
if ( ( $movement > $vectorLength[$last] ) &&
|
||||
( $movement > $vectorLength[$next] ) )
|
||||
{
|
||||
$v->unify()->scalar( min( $vectorLength[$last], $vectorLength[$next] ) );
|
||||
}
|
||||
|
||||
$newPoints[$next] = $v->add( $points[$next] );
|
||||
}
|
||||
|
||||
return $newPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the size of an ellipse
|
||||
*
|
||||
* The method returns a the edgepoints and angles for an ellipse where all
|
||||
* borders are moved to the inner side of the ellipse by the give $size
|
||||
* value.
|
||||
*
|
||||
* The method returns an
|
||||
* array (
|
||||
* 'center' => (ezcGraphCoordinate) New center point,
|
||||
* 'start' => (ezcGraphCoordinate) New outer start point,
|
||||
* 'end' => (ezcGraphCoordinate) New outer end point,
|
||||
* )
|
||||
*
|
||||
* @param ezcGraphCoordinate $center
|
||||
* @param float $width
|
||||
* @param float $height
|
||||
* @param float $startAngle
|
||||
* @param float $endAngle
|
||||
* @param float $size
|
||||
* @throws ezcGraphReducementFailedException
|
||||
* @return array
|
||||
*/
|
||||
protected function reduceEllipseSize( ezcGraphCoordinate $center, $width, $height, $startAngle, $endAngle, $size )
|
||||
{
|
||||
$oldStartPoint = new ezcGraphVector(
|
||||
$width * cos( deg2rad( $startAngle ) ) / 2,
|
||||
$height * sin( deg2rad( $startAngle ) ) / 2
|
||||
);
|
||||
|
||||
$oldEndPoint = new ezcGraphVector(
|
||||
$width * cos( deg2rad( $endAngle ) ) / 2,
|
||||
$height * sin( deg2rad( $endAngle ) ) / 2
|
||||
);
|
||||
|
||||
// We always need radian values..
|
||||
$degAngle = abs( $endAngle - $startAngle );
|
||||
$startAngle = deg2rad( $startAngle );
|
||||
$endAngle = deg2rad( $endAngle );
|
||||
|
||||
// Calculate normalized vectors for the lines spanning the ellipse
|
||||
$unifiedStartVector = ezcGraphVector::fromCoordinate( $oldStartPoint )->unify();
|
||||
$unifiedEndVector = ezcGraphVector::fromCoordinate( $oldEndPoint )->unify();
|
||||
$startVector = ezcGraphVector::fromCoordinate( $oldStartPoint );
|
||||
$endVector = ezcGraphVector::fromCoordinate( $oldEndPoint );
|
||||
|
||||
$oldStartPoint->add( $center );
|
||||
$oldEndPoint->add( $center );
|
||||
|
||||
// Use orthogonal vectors of normalized ellipse spanning vectors to
|
||||
$v = clone $unifiedStartVector;
|
||||
$v->rotateClockwise()->scalar( $size );
|
||||
|
||||
// calculate new center point
|
||||
// center + v + size / tan( angle / 2 ) * startVector
|
||||
$centerMovement = clone $unifiedStartVector;
|
||||
$newCenter = $v->add( $centerMovement->scalar( $size / tan( ( $endAngle - $startAngle ) / 2 ) ) )->add( $center );
|
||||
|
||||
// Test if center is still inside the ellipse, otherwise the sector
|
||||
// was to small to be reduced
|
||||
$innerBoundingBoxSize = 0.7 * min( $width, $height );
|
||||
if ( ( $newCenter->x < ( $center->x + $innerBoundingBoxSize ) ) &&
|
||||
( $newCenter->x > ( $center->x - $innerBoundingBoxSize ) ) &&
|
||||
( $newCenter->y < ( $center->y + $innerBoundingBoxSize ) ) &&
|
||||
( $newCenter->y > ( $center->y - $innerBoundingBoxSize ) ) )
|
||||
{
|
||||
// Point is in inner bounding box -> everything is OK
|
||||
}
|
||||
elseif ( ( $newCenter->x < ( $center->x - $width ) ) ||
|
||||
( $newCenter->x > ( $center->x + $width ) ) ||
|
||||
( $newCenter->y < ( $center->y - $height ) ) ||
|
||||
( $newCenter->y > ( $center->y + $height ) ) )
|
||||
{
|
||||
// Quick outer boundings check
|
||||
if ( $degAngle > 180 )
|
||||
{
|
||||
// Use old center for very big angles
|
||||
$newCenter = clone $center;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not draw for very small angles
|
||||
throw new ezcGraphReducementFailedException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Perform exact check
|
||||
$distance = new ezcGraphVector(
|
||||
$newCenter->x - $center->x,
|
||||
$newCenter->y - $center->y
|
||||
);
|
||||
|
||||
// Convert elipse to circle for correct angle calculation
|
||||
$direction = clone $distance;
|
||||
$direction->y *= ( $width / $height );
|
||||
$angle = $direction->angle( new ezcGraphVector( 0, 1 ) );
|
||||
|
||||
$outerPoint = new ezcGraphVector(
|
||||
sin( $angle ) * $width / 2,
|
||||
cos( $angle ) * $height / 2
|
||||
);
|
||||
|
||||
// Point is not in ellipse any more
|
||||
if ( abs( $distance->x ) > abs( $outerPoint->x ) )
|
||||
{
|
||||
if ( $degAngle > 180 )
|
||||
{
|
||||
// Use old center for very big angles
|
||||
$newCenter = clone $center;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not draw for very small angles
|
||||
throw new ezcGraphReducementFailedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use start spanning vector and its orthogonal vector to calculate
|
||||
// new start point
|
||||
$newStartPoint = clone $oldStartPoint;
|
||||
|
||||
// Create tangent vector from tangent angle
|
||||
|
||||
// Ellipse tangent factor
|
||||
$ellipseTangentFactor = sqrt(
|
||||
pow( $height, 2 ) *
|
||||
pow( cos( $startAngle ), 2 ) +
|
||||
pow( $width, 2 ) *
|
||||
pow( sin( $startAngle ), 2 )
|
||||
);
|
||||
$ellipseTangentVector = new ezcGraphVector(
|
||||
$width * -sin( $startAngle ) / $ellipseTangentFactor,
|
||||
$height * cos( $startAngle ) / $ellipseTangentFactor
|
||||
);
|
||||
|
||||
// Reverse spanning vector
|
||||
$innerVector = clone $unifiedStartVector;
|
||||
$innerVector->scalar( $size )->scalar( -1 );
|
||||
|
||||
$newStartPoint->add( $innerVector)->add( $ellipseTangentVector->scalar( $size ) );
|
||||
$newStartVector = clone $startVector;
|
||||
$newStartVector->add( $ellipseTangentVector );
|
||||
|
||||
// Use end spanning vector and its orthogonal vector to calculate
|
||||
// new end point
|
||||
$newEndPoint = clone $oldEndPoint;
|
||||
|
||||
// Create tangent vector from tangent angle
|
||||
|
||||
// Ellipse tangent factor
|
||||
$ellipseTangentFactor = sqrt(
|
||||
pow( $height, 2 ) *
|
||||
pow( cos( $endAngle ), 2 ) +
|
||||
pow( $width, 2 ) *
|
||||
pow( sin( $endAngle ), 2 )
|
||||
);
|
||||
$ellipseTangentVector = new ezcGraphVector(
|
||||
$width * -sin( $endAngle ) / $ellipseTangentFactor,
|
||||
$height * cos( $endAngle ) / $ellipseTangentFactor
|
||||
);
|
||||
|
||||
// Reverse spanning vector
|
||||
$innerVector = clone $unifiedEndVector;
|
||||
$innerVector->scalar( $size )->scalar( -1 );
|
||||
|
||||
$newEndPoint->add( $innerVector )->add( $ellipseTangentVector->scalar( $size )->scalar( -1 ) );
|
||||
$newEndVector = clone $endVector;
|
||||
$newEndVector->add( $ellipseTangentVector );
|
||||
|
||||
return array(
|
||||
'center' => $newCenter,
|
||||
'start' => $newStartPoint,
|
||||
'end' => $newEndPoint,
|
||||
'startAngle' => rad2deg( $startAngle + $startVector->angle( $newStartVector ) ),
|
||||
'endAngle' => rad2deg( $endAngle - $endVector->angle( $newEndVector ) ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a single polygon.
|
||||
*
|
||||
* @param array $points Point array
|
||||
* @param ezcGraphColor $color Polygon color
|
||||
* @param mixed $filled Filled
|
||||
* @param float $thickness Line thickness
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawPolygon( array $points, ezcGraphColor $color, $filled = true, $thickness = 1. );
|
||||
|
||||
/**
|
||||
* Draws a line
|
||||
*
|
||||
* @param ezcGraphCoordinate $start Start point
|
||||
* @param ezcGraphCoordinate $end End point
|
||||
* @param ezcGraphColor $color Line color
|
||||
* @param float $thickness Line thickness
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawLine( ezcGraphCoordinate $start, ezcGraphCoordinate $end, ezcGraphColor $color, $thickness = 1. );
|
||||
|
||||
/**
|
||||
* Returns boundings of text depending on the available font extension
|
||||
*
|
||||
* @param float $size Textsize
|
||||
* @param ezcGraphFontOptions $font Font
|
||||
* @param string $text Text
|
||||
* @return ezcGraphBoundings Boundings of text
|
||||
*/
|
||||
abstract protected function getTextBoundings( $size, ezcGraphFontOptions $font, $text );
|
||||
|
||||
/**
|
||||
* Test if string fits in a box with given font size
|
||||
*
|
||||
* This method splits the text up into tokens and tries to wrap the text
|
||||
* in an optimal way to fit in the Box defined by width and height.
|
||||
*
|
||||
* If the text fits into the box an array with lines is returned, which
|
||||
* can be used to render the text later:
|
||||
* array(
|
||||
* // Lines
|
||||
* array( 'word', 'word', .. ),
|
||||
* )
|
||||
* Otherwise the function will return false.
|
||||
*
|
||||
* @param string $string Text
|
||||
* @param ezcGraphCoordinate $position Topleft position of the text box
|
||||
* @param float $width Width of textbox
|
||||
* @param float $height Height of textbox
|
||||
* @param int $size Fontsize
|
||||
* @return mixed Array with lines or false on failure
|
||||
*/
|
||||
protected function testFitStringInTextBox( $string, ezcGraphCoordinate $position, $width, $height, $size )
|
||||
{
|
||||
// Tokenize String
|
||||
$tokens = preg_split( '/\s+/', $string );
|
||||
$initialHeight = $height;
|
||||
|
||||
$lines = array( array() );
|
||||
$line = 0;
|
||||
foreach ( $tokens as $nr => $token )
|
||||
{
|
||||
// Add token to tested line
|
||||
$selectedLine = $lines[$line];
|
||||
$selectedLine[] = $token;
|
||||
|
||||
$boundings = $this->getTextBoundings( $size, $this->options->font, implode( ' ', $selectedLine ) );
|
||||
// Check if line is too long
|
||||
if ( $boundings->width > $width )
|
||||
{
|
||||
if ( count( $selectedLine ) == 1 )
|
||||
{
|
||||
// Return false if one single word does not fit into one line
|
||||
// Scale down font size to fit this word in one line
|
||||
return $width / $boundings->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Put word in next line instead and reduce available height by used space
|
||||
$lines[++$line][] = $token;
|
||||
$height -= $size * ( 1 + $this->options->lineSpacing );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything is ok - put token in this line
|
||||
$lines[$line][] = $token;
|
||||
}
|
||||
|
||||
// Return false if text exceeds vertical limit
|
||||
if ( $size > $height )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Check width of last line
|
||||
$boundings = $this->getTextBoundings( $size, $this->options->font, implode( ' ', $lines[$line] ) );
|
||||
if ( $boundings->width > $width )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// It seems to fit - return line array
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* If it is allow to shortened the string, this method tries to extract as
|
||||
* many chars as possible to display a decent amount of characters.
|
||||
*
|
||||
* If no complete token (word) does fit, the largest possible amount of
|
||||
* chars from the first word are taken. If the amount of chars is bigger
|
||||
* then strlen( shortenedStringPostFix ) * 2 the last chars are replace by
|
||||
* the postfix.
|
||||
*
|
||||
* If one complete word fits the box as many words are taken as possible
|
||||
* including a appended shortenedStringPostFix.
|
||||
*
|
||||
* @param mixed $string
|
||||
* @param ezcGraphCoordinate $position
|
||||
* @param mixed $width
|
||||
* @param mixed $height
|
||||
* @param mixed $size
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function tryFitShortenedString( $string, ezcGraphCoordinate $position, $width, $height, $size )
|
||||
{
|
||||
$tokens = preg_split( '/\s+/', $string );
|
||||
|
||||
// Try to fit a complete word first
|
||||
$boundings = $this->getTextBoundings(
|
||||
$size,
|
||||
$this->options->font,
|
||||
reset( $tokens ) . ( $postfix = $this->options->autoShortenStringPostFix )
|
||||
);
|
||||
|
||||
if ( $boundings->width > $width )
|
||||
{
|
||||
// Not even one word fits the box
|
||||
$word = reset( $tokens );
|
||||
|
||||
// Test if first character fits the box
|
||||
$boundigs = $this->getTextBoundings(
|
||||
$size,
|
||||
$this->options->font,
|
||||
$hit = $word[0]
|
||||
);
|
||||
|
||||
if ( $boundigs->width > $width )
|
||||
{
|
||||
// That is a really small box.
|
||||
throw new ezcGraphFontRenderingException( $string, $size, $width, $height );
|
||||
}
|
||||
|
||||
// Try to put more charactes in there
|
||||
$postLength = strlen( $postfix );
|
||||
$wordLength = strlen( $word );
|
||||
for ( $i = 2; $i <= $wordLength; ++$i )
|
||||
{
|
||||
$string = substr( $word, 0, $i );
|
||||
if ( strlen( $string ) > ( $postLength << 1 ) )
|
||||
{
|
||||
$string = substr( $string, 0, -$postLength ) . $postfix;
|
||||
}
|
||||
|
||||
$boundigs = $this->getTextBoundings( $size, $this->options->font, $string );
|
||||
|
||||
if ( $boundigs->width < $width )
|
||||
{
|
||||
$hit = $string;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use last string which fit
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to use as many words as possible
|
||||
$hit = reset( $tokens );
|
||||
|
||||
for ( $i = 2; $i < count( $tokens ); ++$i )
|
||||
{
|
||||
$string = implode( ' ', array_slice( $tokens, 0, $i ) ) .
|
||||
$postfix;
|
||||
|
||||
$boundings = $this->getTextBoundings( $size, $this->options->font, $string );
|
||||
|
||||
if ( $boundings->width <= $width )
|
||||
{
|
||||
$hit .= ' ' . $tokens[$i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use last valid hit
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$hit .= $postfix;
|
||||
}
|
||||
|
||||
return array( array( $hit ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes text in a box of desired size
|
||||
*
|
||||
* @param string $string Text
|
||||
* @param ezcGraphCoordinate $position Top left position
|
||||
* @param float $width Width of text box
|
||||
* @param float $height Height of text box
|
||||
* @param int $align Alignement of text
|
||||
* @param ezcGraphRotation $rotation
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawTextBox( $string, ezcGraphCoordinate $position, $width, $height, $align, ezcGraphRotation $rotation = null );
|
||||
|
||||
/**
|
||||
* Draws a sector of cirlce
|
||||
*
|
||||
* @param ezcGraphCoordinate $center Center of circle
|
||||
* @param mixed $width Width
|
||||
* @param mixed $height Height
|
||||
* @param mixed $startAngle Start angle of circle sector
|
||||
* @param mixed $endAngle End angle of circle sector
|
||||
* @param ezcGraphColor $color Color
|
||||
* @param mixed $filled Filled
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawCircleSector( ezcGraphCoordinate $center, $width, $height, $startAngle, $endAngle, ezcGraphColor $color, $filled = true );
|
||||
|
||||
/**
|
||||
* Draws a circular arc
|
||||
*
|
||||
* @param ezcGraphCoordinate $center Center of ellipse
|
||||
* @param integer $width Width of ellipse
|
||||
* @param integer $height Height of ellipse
|
||||
* @param integer $size Height of border
|
||||
* @param float $startAngle Starting angle of circle sector
|
||||
* @param float $endAngle Ending angle of circle sector
|
||||
* @param ezcGraphColor $color Color of Border
|
||||
* @param bool $filled Fill state
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawCircularArc( ezcGraphCoordinate $center, $width, $height, $size, $startAngle, $endAngle, ezcGraphColor $color, $filled = true );
|
||||
|
||||
/**
|
||||
* Draw circle
|
||||
*
|
||||
* @param ezcGraphCoordinate $center Center of ellipse
|
||||
* @param mixed $width Width of ellipse
|
||||
* @param mixed $height height of ellipse
|
||||
* @param ezcGraphColor $color Color
|
||||
* @param mixed $filled Filled
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawCircle( ezcGraphCoordinate $center, $width, $height, ezcGraphColor $color, $filled = true );
|
||||
|
||||
/**
|
||||
* Draw an image
|
||||
*
|
||||
* @param mixed $file Image file
|
||||
* @param ezcGraphCoordinate $position Top left position
|
||||
* @param mixed $width Width of image in destination image
|
||||
* @param mixed $height Height of image in destination image
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawImage( $file, ezcGraphCoordinate $position, $width, $height );
|
||||
|
||||
/**
|
||||
* Return mime type for current image format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getMimeType();
|
||||
|
||||
/**
|
||||
* Render image directly to output
|
||||
*
|
||||
* The method renders the image directly to the standard output. You
|
||||
* normally do not want to use this function, because it makes it harder
|
||||
* to proper cache the generated graphs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function renderToOutput()
|
||||
{
|
||||
header( 'Content-Type: ' . $this->getMimeType() );
|
||||
$this->render( 'php://output' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Finally save image
|
||||
*
|
||||
* @param string $file Destination filename
|
||||
* @return void
|
||||
*/
|
||||
abstract public function render( $file );
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphChartElement class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Class for basic chart elements
|
||||
*
|
||||
* @property string $title
|
||||
* Title of chart element.
|
||||
* @property ezcGraphColor $background
|
||||
* Background color of chart element.
|
||||
* @property ezcGraphColor $border
|
||||
* Border color of chart element.
|
||||
* @property int $padding
|
||||
* Distance between border and content of element.
|
||||
* @property int $margin
|
||||
* Distance between outer boundings and border of an element.
|
||||
* @property int $borderWidth
|
||||
* Border width.
|
||||
* @property int $position
|
||||
* Integer defining the elements position in the chart.
|
||||
* @property int $maxTitleHeight
|
||||
* Maximum size of the title.
|
||||
* @property float $portraitTitleSize
|
||||
* Percentage of boundings which are used for the title with
|
||||
* position left, right or center.
|
||||
* @property float $landscapeTitleSize
|
||||
* Percentage of boundings which are used for the title with
|
||||
* position top or bottom.
|
||||
* @property ezcGraphFontOptions $font
|
||||
* Font used for this element.
|
||||
* @property-read bool $fontCloned
|
||||
* Indicates if font configuration was already cloned for this
|
||||
* specific element.
|
||||
* @property-read ezcGraphBoundings $boundings
|
||||
* Boundings of this elements.
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
abstract class ezcGraphChartElement extends ezcBaseOptions
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options Default option array
|
||||
* @return void
|
||||
* @ignore
|
||||
*/
|
||||
public function __construct( array $options = array() )
|
||||
{
|
||||
$this->properties['title'] = false;
|
||||
$this->properties['background'] = false;
|
||||
$this->properties['boundings'] = new ezcGraphBoundings();
|
||||
$this->properties['border'] = false;
|
||||
$this->properties['borderWidth'] = 0;
|
||||
$this->properties['padding'] = 0;
|
||||
$this->properties['margin'] = 0;
|
||||
$this->properties['position'] = ezcGraph::LEFT;
|
||||
$this->properties['maxTitleHeight'] = 16;
|
||||
$this->properties['portraitTitleSize'] = .15;
|
||||
$this->properties['landscapeTitleSize'] = .2;
|
||||
$this->properties['font'] = new ezcGraphFontOptions();
|
||||
$this->properties['fontCloned'] = false;
|
||||
|
||||
parent::__construct( $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set colors and border fro this element
|
||||
*
|
||||
* @param ezcGraphPalette $palette Palette
|
||||
* @return void
|
||||
*/
|
||||
public function setFromPalette( ezcGraphPalette $palette )
|
||||
{
|
||||
$this->properties['border'] = $palette->elementBorderColor;
|
||||
$this->properties['borderWidth'] = $palette->elementBorderWidth;
|
||||
$this->properties['background'] = $palette->elementBackground;
|
||||
$this->properties['padding'] = $palette->padding;
|
||||
$this->properties['margin'] = $palette->margin;
|
||||
}
|
||||
|
||||
/**
|
||||
* __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 'title':
|
||||
$this->properties['title'] = (string) $propertyValue;
|
||||
break;
|
||||
case 'background':
|
||||
$this->properties['background'] = ezcGraphColor::create( $propertyValue );
|
||||
break;
|
||||
case 'border':
|
||||
$this->properties['border'] = ezcGraphColor::create( $propertyValue );
|
||||
break;
|
||||
case 'padding':
|
||||
if ( !is_numeric( $propertyValue ) ||
|
||||
( $propertyValue < 0 ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
|
||||
}
|
||||
|
||||
$this->properties['padding'] = (int) $propertyValue;
|
||||
break;
|
||||
case 'margin':
|
||||
if ( !is_numeric( $propertyValue ) ||
|
||||
( $propertyValue < 0 ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
|
||||
}
|
||||
|
||||
$this->properties['margin'] = (int) $propertyValue;
|
||||
break;
|
||||
case 'borderWidth':
|
||||
if ( !is_numeric( $propertyValue ) ||
|
||||
( $propertyValue < 0 ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
|
||||
}
|
||||
|
||||
$this->properties['borderWidth'] = (int) $propertyValue;
|
||||
break;
|
||||
case 'font':
|
||||
if ( $propertyValue instanceof ezcGraphFontOptions )
|
||||
{
|
||||
$this->properties['font'] = $propertyValue;
|
||||
}
|
||||
elseif ( is_string( $propertyValue ) )
|
||||
{
|
||||
if ( !$this->fontCloned )
|
||||
{
|
||||
$this->properties['font'] = clone $this->font;
|
||||
$this->properties['fontCloned'] = true;
|
||||
}
|
||||
|
||||
$this->properties['font']->path = $propertyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'ezcGraphFontOptions' );
|
||||
}
|
||||
break;
|
||||
case 'position':
|
||||
$positions = array(
|
||||
ezcGraph::TOP,
|
||||
ezcGraph::BOTTOM,
|
||||
ezcGraph::LEFT,
|
||||
ezcGraph::RIGHT,
|
||||
);
|
||||
|
||||
if ( in_array( $propertyValue, $positions, true ) )
|
||||
{
|
||||
$this->properties['position'] = $propertyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ezcBaseValueException( 'position', $propertyValue, 'integer' );
|
||||
}
|
||||
break;
|
||||
case 'maxTitleHeight':
|
||||
if ( !is_numeric( $propertyValue ) ||
|
||||
( $propertyValue < 0 ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
|
||||
}
|
||||
|
||||
$this->properties['maxTitleHeight'] = (int) $propertyValue;
|
||||
break;
|
||||
case 'portraitTitleSize':
|
||||
if ( !is_numeric( $propertyValue ) ||
|
||||
( $propertyValue < 0 ) ||
|
||||
( $propertyValue > 1 ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float <= 1' );
|
||||
}
|
||||
|
||||
$this->properties['portraitTitleSize'] = (float) $propertyValue;
|
||||
break;
|
||||
case 'landscapeTitleSize':
|
||||
if ( !is_numeric( $propertyValue ) ||
|
||||
( $propertyValue < 0 ) ||
|
||||
( $propertyValue > 1 ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float <= 1' );
|
||||
}
|
||||
|
||||
$this->properties['landscapeTitleSize'] = (float) $propertyValue;
|
||||
break;
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $propertyName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* @param mixed $propertyName
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If a the value for the property options is not an instance of
|
||||
* @return mixed
|
||||
* @ignore
|
||||
*/
|
||||
public function __get( $propertyName )
|
||||
{
|
||||
switch ( $propertyName )
|
||||
{
|
||||
case 'font':
|
||||
// Clone font configuration when requested for this element
|
||||
if ( !$this->fontCloned )
|
||||
{
|
||||
$this->properties['font'] = clone $this->properties['font'];
|
||||
$this->properties['fontCloned'] = true;
|
||||
}
|
||||
return $this->properties['font'];
|
||||
default:
|
||||
return parent::__get( $propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders this chart element
|
||||
*
|
||||
* This method receives and returns a part of the canvas where it can be
|
||||
* rendered on.
|
||||
*
|
||||
* @param ezcGraphRenderer $renderer
|
||||
* @param ezcGraphBoundings $boundings
|
||||
* @return ezcGraphBoundings Part of canvas, which is still free to draw on
|
||||
*/
|
||||
abstract public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings );
|
||||
|
||||
/**
|
||||
* Returns calculated boundings based on available percentual space of
|
||||
* given bounding box specified in the elements options and direction of
|
||||
* the box.
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings
|
||||
* @param int $direction
|
||||
* @return ezcGraphBoundings
|
||||
*/
|
||||
protected function getTitleSize( ezcGraphBoundings $boundings, $direction = ezcGraph::HORIZONTAL )
|
||||
{
|
||||
if ( $direction === ezcGraph::HORIZONTAL )
|
||||
{
|
||||
return min(
|
||||
$this->maxTitleHeight,
|
||||
( $boundings->y1 - $boundings->y0 ) * $this->landscapeTitleSize
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return min(
|
||||
$this->maxTitleHeight,
|
||||
( $boundings->y1 - $boundings->y0 ) * $this->portraitTitleSize
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphOdometerRenderer interface
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Interface which adds the methods required for rendering radar charts to a
|
||||
* renderer
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
interface ezcGraphOdometerRenderer
|
||||
{
|
||||
/**
|
||||
* Render odometer chart
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings
|
||||
* @param ezcGraphChartElementAxis $axis
|
||||
* @param ezcGraphOdometerChartOptions $options
|
||||
* @return ezcGraphBoundings
|
||||
*/
|
||||
public function drawOdometer(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphChartElementAxis $axis,
|
||||
ezcGraphOdometerChartOptions $options
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw a single odometer marker.
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings
|
||||
* @param ezcGraphCoordinate $position
|
||||
* @param int $symbol
|
||||
* @param ezcGraphColor $color
|
||||
* @param int $width
|
||||
*/
|
||||
public function drawOdometerMarker(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphCoordinate $position,
|
||||
$symbol,
|
||||
ezcGraphColor $color,
|
||||
$width
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphPalette class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Abstract class to contain pallet definitions
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
* @mainclass
|
||||
*/
|
||||
abstract class ezcGraphPalette
|
||||
{
|
||||
/**
|
||||
* Indicates which color should be used for the next dataset
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $colorIndex = -1;
|
||||
|
||||
/**
|
||||
* Indicates which symbol should be used for the nect dataset
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $symbolIndex = -1;
|
||||
|
||||
/**
|
||||
* Axiscolor
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $axisColor;
|
||||
|
||||
/**
|
||||
* Color of grid lines
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $majorGridColor;
|
||||
|
||||
/**
|
||||
* Color of minor grid lines
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $minorGridColor;
|
||||
|
||||
/**
|
||||
* Array with colors for datasets
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dataSetColor;
|
||||
|
||||
/**
|
||||
* Array with symbols for datasets
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dataSetSymbol;
|
||||
|
||||
/**
|
||||
* Name of font to use
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fontName;
|
||||
|
||||
/**
|
||||
* Fontcolor
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $fontColor;
|
||||
|
||||
/**
|
||||
* Backgroundcolor
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $chartBackground;
|
||||
|
||||
/**
|
||||
* Bordercolor the chart
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $chartBorderColor;
|
||||
|
||||
/**
|
||||
* Borderwidth for the chart
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
protected $chartBorderWidth = 0;
|
||||
|
||||
/**
|
||||
* Backgroundcolor for elements
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $elementBackground;
|
||||
|
||||
/**
|
||||
* Bordercolor for elements
|
||||
*
|
||||
* @var ezcGraphColor
|
||||
*/
|
||||
protected $elementBorderColor;
|
||||
|
||||
/**
|
||||
* Borderwidth for elements
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
protected $elementBorderWidth = 0;
|
||||
|
||||
/**
|
||||
* Padding in elements
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $padding = 1;
|
||||
|
||||
/**
|
||||
* Margin of elements
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $margin = 0;
|
||||
|
||||
/**
|
||||
* Ensure value to be a color
|
||||
*
|
||||
* @param mixed $color Color to transform into a ezcGraphColor object
|
||||
* @return ezcGraphColor
|
||||
*/
|
||||
protected function checkColor( &$color )
|
||||
{
|
||||
if ( $color == null )
|
||||
{
|
||||
return ezcGraphColor::fromHex( '#000000FF' );
|
||||
}
|
||||
elseif ( !( $color instanceof ezcGraphColor ) )
|
||||
{
|
||||
$color = ezcGraphColor::create( $color );
|
||||
}
|
||||
|
||||
return $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually reset the color counter to use the first color again
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function resetColorCounter()
|
||||
{
|
||||
$this->colorIndex = -1;
|
||||
$this->symbolIndex = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested property
|
||||
*
|
||||
* @param string $propertyName Name of property
|
||||
* @return mixed
|
||||
* @ignore
|
||||
*/
|
||||
public function __get( $propertyName )
|
||||
{
|
||||
switch ( $propertyName )
|
||||
{
|
||||
case 'axisColor':
|
||||
case 'majorGridColor':
|
||||
case 'minorGridColor':
|
||||
case 'fontColor':
|
||||
case 'chartBackground':
|
||||
case 'chartBorderColor':
|
||||
case 'elementBackground':
|
||||
case 'elementBorderColor':
|
||||
return ( $this->$propertyName = $this->checkColor( $this->$propertyName ) );
|
||||
|
||||
case 'dataSetColor':
|
||||
$this->colorIndex = ( ( $this->colorIndex + 1 ) % count( $this->dataSetColor ) );
|
||||
return $this->checkColor( $this->dataSetColor[ $this->colorIndex ] );
|
||||
case 'dataSetSymbol':
|
||||
$this->symbolIndex = ( ( $this->symbolIndex + 1 ) % count( $this->dataSetSymbol ) );
|
||||
return $this->dataSetSymbol[ $this->symbolIndex ];
|
||||
|
||||
case 'fontName':
|
||||
case 'chartBorderWidth':
|
||||
case 'elementBorderWidth':
|
||||
case 'padding':
|
||||
case 'margin':
|
||||
return $this->$propertyName;
|
||||
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __set
|
||||
*
|
||||
* @param mixed $propertyName Property name
|
||||
* @param mixed $propertyValue Property value
|
||||
* @access public
|
||||
* @ignore
|
||||
*/
|
||||
public function __set( $propertyName, $propertyValue )
|
||||
{
|
||||
switch ( $propertyName )
|
||||
{
|
||||
case 'axisColor':
|
||||
case 'majorGridColor':
|
||||
case 'minorGridColor':
|
||||
case 'fontColor':
|
||||
case 'chartBackground':
|
||||
case 'chartBorderColor':
|
||||
case 'elementBackground':
|
||||
case 'elementBorderColor':
|
||||
$this->$propertyName = ezcGraphColor::create( $propertyValue );
|
||||
break;
|
||||
|
||||
case 'dataSetColor':
|
||||
if ( !is_array( $propertyValue ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'array( ezcGraphColor )' );
|
||||
}
|
||||
|
||||
$this->dataSetColor = array();
|
||||
foreach ( $propertyValue as $value )
|
||||
{
|
||||
$this->dataSetColor[] = ezcGraphColor::create( $value );
|
||||
}
|
||||
$this->colorIndex = -1;
|
||||
break;
|
||||
case 'dataSetSymbol':
|
||||
if ( !is_array( $propertyValue ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'array( (int) ezcGraph::SYMBOL_TYPE )' );
|
||||
}
|
||||
|
||||
$this->dataSetSymbol = array();
|
||||
foreach ( $propertyValue as $value )
|
||||
{
|
||||
$this->dataSetSymbol[] = (int) $value;
|
||||
}
|
||||
$this->symbolIndex = -1;
|
||||
break;
|
||||
|
||||
case 'fontName':
|
||||
$this->$propertyName = (string) $propertyValue;
|
||||
break;
|
||||
|
||||
case 'chartBorderWidth':
|
||||
case 'elementBorderWidth':
|
||||
case 'padding':
|
||||
case 'margin':
|
||||
if ( !is_numeric( $propertyValue ) ||
|
||||
( $propertyValue < 0 ) )
|
||||
{
|
||||
throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 0' );
|
||||
}
|
||||
|
||||
$this->$propertyName = (int) $propertyValue;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $propertyName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphRadarRenderer interface
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Interface which adds the methods required for rendering radar charts to a
|
||||
* renderer
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
interface ezcGraphRadarRenderer
|
||||
{
|
||||
/**
|
||||
* Draw radar chart data line
|
||||
*
|
||||
* Draws a line as a data element in a radar chart
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Chart boundings
|
||||
* @param ezcGraphContext $context Context of call
|
||||
* @param ezcGraphColor $color Color of line
|
||||
* @param ezcGraphCoordinate $center Center of radar chart
|
||||
* @param ezcGraphCoordinate $start Starting point
|
||||
* @param ezcGraphCoordinate $end Ending point
|
||||
* @param int $dataNumber Number of dataset
|
||||
* @param int $dataCount Count of datasets in chart
|
||||
* @param int $symbol Symbol to draw for line
|
||||
* @param ezcGraphColor $symbolColor Color of the symbol, defaults to linecolor
|
||||
* @param ezcGraphColor $fillColor Color to fill line with
|
||||
* @param float $thickness Line thickness
|
||||
* @return void
|
||||
*/
|
||||
public function drawRadarDataLine(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphContext $context,
|
||||
ezcGraphColor $color,
|
||||
ezcGraphCoordinate $center,
|
||||
ezcGraphCoordinate $start,
|
||||
ezcGraphCoordinate $end,
|
||||
$dataNumber = 1,
|
||||
$dataCount = 1,
|
||||
$symbol = ezcGraph::NO_SYMBOL,
|
||||
ezcGraphColor $symbolColor = null,
|
||||
ezcGraphColor $fillColor = null,
|
||||
$thickness = 1.
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,571 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphRenderer class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Abstract class to transform the basic chart components. To be extended by
|
||||
* three- and twodimensional renderers.
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
abstract class ezcGraphRenderer
|
||||
{
|
||||
|
||||
/**
|
||||
* Driver used to render results
|
||||
*
|
||||
* @var ezcGraphDriver
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* Axis space used for the x axis
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $xAxisSpace = false;
|
||||
|
||||
/**
|
||||
* Axis space used for the y axis
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $yAxisSpace = false;
|
||||
|
||||
/**
|
||||
* Context sensitive references to chart elements to use for referencing
|
||||
* image elements depending on the output driver, like image maps, etc.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $elements = array();
|
||||
|
||||
/**
|
||||
* Set renderers driver
|
||||
*
|
||||
* @param ezcGraphDriver $driver Output driver
|
||||
* @return void
|
||||
*/
|
||||
public function setDriver( ezcGraphDriver $driver )
|
||||
{
|
||||
$this->driver = $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a element reference for context
|
||||
*
|
||||
* @param ezcGraphContext $context Dataoint context
|
||||
* @param mixed $reference Driver dependant reference
|
||||
* @return void
|
||||
*/
|
||||
protected function addElementReference( ezcGraphContext $context, $reference )
|
||||
{
|
||||
$this->elements['data'][$context->dataset][$context->datapoint][] = $reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all chart element references
|
||||
*
|
||||
* @return array chart element references
|
||||
*/
|
||||
public function getElementReferences()
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* __get
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @throws ezcBasePropertyNotFoundException
|
||||
* If a the value for the property options is not an instance of
|
||||
* @return mixed
|
||||
* @ignore
|
||||
*/
|
||||
public function __get( $propertyName )
|
||||
{
|
||||
switch ( $propertyName )
|
||||
{
|
||||
case 'xAxisSpace':
|
||||
case 'yAxisSpace':
|
||||
return $this->$propertyName;
|
||||
case 'elements':
|
||||
return $this->elements;
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw pie segment
|
||||
*
|
||||
* Draws a single pie segment
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Chart boundings
|
||||
* @param ezcGraphContext $context Context of call
|
||||
* @param ezcGraphColor $color Color of pie segment
|
||||
* @param float $startAngle Start angle
|
||||
* @param float $endAngle End angle
|
||||
* @param mixed $label Label of pie segment
|
||||
* @param bool $moveOut Move out from middle for hilighting
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawPieSegment(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphContext $context,
|
||||
ezcGraphColor $color,
|
||||
$startAngle = .0,
|
||||
$endAngle = 360.,
|
||||
$label = false,
|
||||
$moveOut = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw bar
|
||||
*
|
||||
* Draws a bar as a data element in a line chart
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Chart boundings
|
||||
* @param ezcGraphContext $context Context of call
|
||||
* @param ezcGraphColor $color Color of line
|
||||
* @param ezcGraphCoordinate $position Position of data point
|
||||
* @param float $stepSize Space which can be used for bars
|
||||
* @param int $dataNumber Number of dataset
|
||||
* @param int $dataCount Count of datasets in chart
|
||||
* @param int $symbol Symbol to draw for line
|
||||
* @param float $axisPosition Position of axis for drawing filled lines
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawBar(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphContext $context,
|
||||
ezcGraphColor $color,
|
||||
ezcGraphCoordinate $position,
|
||||
$stepSize,
|
||||
$dataNumber = 1,
|
||||
$dataCount = 1,
|
||||
$symbol = ezcGraph::NO_SYMBOL,
|
||||
$axisPosition = 0.
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw data line
|
||||
*
|
||||
* Draws a line as a data element in a line chart
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Chart boundings
|
||||
* @param ezcGraphContext $context Context of call
|
||||
* @param ezcGraphColor $color Color of line
|
||||
* @param ezcGraphCoordinate $start Starting point
|
||||
* @param ezcGraphCoordinate $end Ending point
|
||||
* @param int $dataNumber Number of dataset
|
||||
* @param int $dataCount Count of datasets in chart
|
||||
* @param int $symbol Symbol to draw for line
|
||||
* @param ezcGraphColor $symbolColor Color of the symbol, defaults to linecolor
|
||||
* @param ezcGraphColor $fillColor Color to fill line with
|
||||
* @param float $axisPosition Position of axis for drawing filled lines
|
||||
* @param float $thickness Line thickness
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawDataLine(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphContext $context,
|
||||
ezcGraphColor $color,
|
||||
ezcGraphCoordinate $start,
|
||||
ezcGraphCoordinate $end,
|
||||
$dataNumber = 1,
|
||||
$dataCount = 1,
|
||||
$symbol = ezcGraph::NO_SYMBOL,
|
||||
ezcGraphColor $symbolColor = null,
|
||||
ezcGraphColor $fillColor = null,
|
||||
$axisPosition = 0.,
|
||||
$thickness = 1.
|
||||
);
|
||||
|
||||
/**
|
||||
* Draws a highlight textbox for a datapoint.
|
||||
*
|
||||
* A highlight textbox for line and bar charts means a box with the current
|
||||
* value in the graph.
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Chart boundings
|
||||
* @param ezcGraphContext $context Context of call
|
||||
* @param ezcGraphCoordinate $end Ending point
|
||||
* @param float $axisPosition Position of axis for drawing filled lines
|
||||
* @param int $dataNumber Number of dataset
|
||||
* @param int $dataCount Count of datasets in chart
|
||||
* @param ezcGraphFontOptions $font Font used for highlight string
|
||||
* @param string $text Acutual value
|
||||
* @param int $size Size of highlight text
|
||||
* @param ezcGraphColor $markLines
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawDataHighlightText(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphContext $context,
|
||||
ezcGraphCoordinate $end,
|
||||
$axisPosition = 0.,
|
||||
$dataNumber = 1,
|
||||
$dataCount = 1,
|
||||
ezcGraphFontOptions $font,
|
||||
$text,
|
||||
$size,
|
||||
ezcGraphColor $markLines = null
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw legend
|
||||
*
|
||||
* Will draw a legend in the bounding box
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Bounding of legend
|
||||
* @param ezcGraphChartElementLegend $legend Legend to draw
|
||||
* @param int $type Type of legend: Protrait or landscape
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawLegend(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphChartElementLegend $legend,
|
||||
$type = ezcGraph::VERTICAL
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw box
|
||||
*
|
||||
* Box are wrapping each major chart element and draw border, background
|
||||
* and title to each chart element.
|
||||
*
|
||||
* Optionally a padding and margin for each box can be defined.
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Boundings of the box
|
||||
* @param ezcGraphColor $background Background color
|
||||
* @param ezcGraphColor $borderColor Border color
|
||||
* @param int $borderWidth Border width
|
||||
* @param int $margin Margin
|
||||
* @param int $padding Padding
|
||||
* @param mixed $title Title of the box
|
||||
* @param int $titleSize Size of title in the box
|
||||
* @return ezcGraphBoundings Remaining inner boundings
|
||||
*/
|
||||
abstract public function drawBox(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphColor $background = null,
|
||||
ezcGraphColor $borderColor = null,
|
||||
$borderWidth = 0,
|
||||
$margin = 0,
|
||||
$padding = 0,
|
||||
$title = false,
|
||||
$titleSize = 16
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw text
|
||||
*
|
||||
* Draws the provided text in the boundings
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Boundings of text
|
||||
* @param string $text Text
|
||||
* @param int $align Alignement of text
|
||||
* @param ezcGraphRotation $rotation
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawText(
|
||||
ezcGraphBoundings $boundings,
|
||||
$text,
|
||||
$align = ezcGraph::LEFT,
|
||||
ezcGraphRotation $rotation = null
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw axis
|
||||
*
|
||||
* Draws an axis form the provided start point to the end point. A specific
|
||||
* angle of the axis is not required.
|
||||
*
|
||||
* For the labeleing of the axis a sorted array with major steps and an
|
||||
* array with minor steps is expected, which are build like this:
|
||||
* array(
|
||||
* array(
|
||||
* 'position' => (float),
|
||||
* 'label' => (string),
|
||||
* )
|
||||
* )
|
||||
* where the label is optional.
|
||||
*
|
||||
* The label renderer class defines how the labels are rendered. For more
|
||||
* documentation on this topic have a look at the basic label renderer
|
||||
* class.
|
||||
*
|
||||
* Additionally it can be specified if a major and minor grid are rendered
|
||||
* by defining a color for them. Teh axis label is used to add a caption
|
||||
* for the axis.
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Boundings of axis
|
||||
* @param ezcGraphCoordinate $start Start point of axis
|
||||
* @param ezcGraphCoordinate $end Endpoint of axis
|
||||
* @param ezcGraphChartElementAxis $axis Axis to render
|
||||
* @param ezcGraphAxisLabelRenderer $labelClass Used label renderer
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawAxis(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphCoordinate $start,
|
||||
ezcGraphCoordinate $end,
|
||||
ezcGraphChartElementAxis $axis,
|
||||
ezcGraphAxisLabelRenderer $labelClass = null
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw background image
|
||||
*
|
||||
* Draws a background image at the defined position. If repeat is set the
|
||||
* background image will be repeated like any texture.
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Boundings for the background image
|
||||
* @param string $file Filename of background image
|
||||
* @param int $position Position of background image
|
||||
* @param int $repeat Type of repetition
|
||||
* @return void
|
||||
*/
|
||||
abstract public function drawBackgroundImage(
|
||||
ezcGraphBoundings $boundings,
|
||||
$file,
|
||||
$position = 48, // ezcGraph::CENTER | ezcGraph::MIDDLE
|
||||
$repeat = ezcGraph::NO_REPEAT
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw Symbol
|
||||
*
|
||||
* Draws a single symbol defined by the symbol constants in ezcGraph. for
|
||||
* NO_SYMBOL a rect will be drawn.
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Boundings of symbol
|
||||
* @param ezcGraphColor $color Color of symbol
|
||||
* @param int $symbol Type of symbol
|
||||
* @return void
|
||||
*/
|
||||
public function drawSymbol(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphColor $color,
|
||||
$symbol = ezcGraph::NO_SYMBOL )
|
||||
{
|
||||
switch ( $symbol )
|
||||
{
|
||||
case ezcGraph::NO_SYMBOL:
|
||||
$return = $this->driver->drawPolygon(
|
||||
array(
|
||||
new ezcGraphCoordinate( $boundings->x0, $boundings->y0 ),
|
||||
new ezcGraphCoordinate( $boundings->x1, $boundings->y0 ),
|
||||
new ezcGraphCoordinate( $boundings->x1, $boundings->y1 ),
|
||||
new ezcGraphCoordinate( $boundings->x0, $boundings->y1 ),
|
||||
),
|
||||
$color,
|
||||
true
|
||||
);
|
||||
|
||||
// Draw optional gleam
|
||||
if ( $this->options->legendSymbolGleam !== false )
|
||||
{
|
||||
$this->driver->drawPolygon(
|
||||
array(
|
||||
$topLeft = new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $this->options->legendSymbolGleamSize,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $this->options->legendSymbolGleamSize
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x1 - ( $boundings->x1 - $boundings->x0 ) * $this->options->legendSymbolGleamSize,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $this->options->legendSymbolGleamSize
|
||||
),
|
||||
$bottomRight = new ezcGraphCoordinate(
|
||||
$boundings->x1 - ( $boundings->x1 - $boundings->x0 ) * $this->options->legendSymbolGleamSize,
|
||||
$boundings->y1 - ( $boundings->y1 - $boundings->y0 ) * $this->options->legendSymbolGleamSize
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $this->options->legendSymbolGleamSize,
|
||||
$boundings->y1 - ( $boundings->y1 - $boundings->y0 ) * $this->options->legendSymbolGleamSize
|
||||
),
|
||||
),
|
||||
new ezcGraphLinearGradient(
|
||||
$bottomRight,
|
||||
$topLeft,
|
||||
$color->darken( -$this->options->legendSymbolGleam ),
|
||||
$color->darken( $this->options->legendSymbolGleam )
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
return $return;
|
||||
case ezcGraph::DIAMOND:
|
||||
$return = $this->driver->drawPolygon(
|
||||
array(
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) / 2,
|
||||
$boundings->y0
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x1,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) / 2
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) / 2,
|
||||
$boundings->y1
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) / 2
|
||||
),
|
||||
),
|
||||
$color,
|
||||
true
|
||||
);
|
||||
|
||||
// Draw optional gleam
|
||||
if ( $this->options->legendSymbolGleam !== false )
|
||||
{
|
||||
$this->driver->drawPolygon(
|
||||
array(
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) / 2,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $this->options->legendSymbolGleamSize
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x1 - ( $boundings->x1 - $boundings->x0 ) * $this->options->legendSymbolGleamSize,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) / 2
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) / 2,
|
||||
$boundings->y1 - ( $boundings->y1 - $boundings->y0 ) * $this->options->legendSymbolGleamSize
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $this->options->legendSymbolGleamSize,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) / 2
|
||||
),
|
||||
),
|
||||
new ezcGraphLinearGradient(
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * 0.353553391,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * 0.353553391
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * ( 1 - 0.353553391 ),
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * ( 1 - 0.353553391 )
|
||||
),
|
||||
$color->darken( -$this->options->legendSymbolGleam ),
|
||||
$color->darken( $this->options->legendSymbolGleam )
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
return $return;
|
||||
case ezcGraph::BULLET:
|
||||
$return = $this->driver->drawCircle(
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) / 2,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) / 2
|
||||
),
|
||||
$boundings->x1 - $boundings->x0,
|
||||
$boundings->y1 - $boundings->y0,
|
||||
$color,
|
||||
true
|
||||
);
|
||||
|
||||
// Draw optional gleam
|
||||
if ( $this->options->legendSymbolGleam !== false )
|
||||
{
|
||||
$this->driver->drawCircle(
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) / 2,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) / 2
|
||||
),
|
||||
( $boundings->x1 - $boundings->x0 ) * $this->options->legendSymbolGleamSize,
|
||||
( $boundings->y1 - $boundings->y0 ) * $this->options->legendSymbolGleamSize,
|
||||
new ezcGraphLinearGradient(
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * 0.292893219,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * 0.292893219
|
||||
),
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * 0.707106781,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * 0.707106781
|
||||
),
|
||||
$color->darken( -$this->options->legendSymbolGleam ),
|
||||
$color->darken( $this->options->legendSymbolGleam )
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
return $return;
|
||||
case ezcGraph::CIRCLE:
|
||||
return $this->driver->drawCircle(
|
||||
new ezcGraphCoordinate(
|
||||
$boundings->x0 + ( $boundings->x1 - $boundings->x0 ) / 2,
|
||||
$boundings->y0 + ( $boundings->y1 - $boundings->y0 ) / 2
|
||||
),
|
||||
$boundings->x1 - $boundings->x0,
|
||||
$boundings->y1 - $boundings->y0,
|
||||
$color,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish rendering
|
||||
*
|
||||
* Method is called before the final image is renderer, so that finishing
|
||||
* operations can be performed here.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function finish();
|
||||
|
||||
/**
|
||||
* Reset renderer properties
|
||||
*
|
||||
* Reset all renderer properties, which were calculated during the
|
||||
* rendering process, to offer a clean environment for rerendering.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function resetRenderer()
|
||||
{
|
||||
$this->xAxisSpace = false;
|
||||
$this->yAxisSpace = false;
|
||||
|
||||
// Reset driver, maintaining its configuration
|
||||
$driverClass = get_class( $this->driver );
|
||||
$driverOptions = $this->driver->options;
|
||||
$this->driver = new $driverClass();
|
||||
$this->driver->options = $driverOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finally renders the image
|
||||
*
|
||||
* @param string $file Filename of destination file
|
||||
* @return void
|
||||
*/
|
||||
public function render( $file = null )
|
||||
{
|
||||
$this->finish();
|
||||
|
||||
if ( $file === null )
|
||||
{
|
||||
$this->driver->renderToOutput();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->driver->render( $file );
|
||||
}
|
||||
|
||||
$this->resetRenderer();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphRadarRenderer interface
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Interface which adds the methods required for rendering radar charts to a
|
||||
* renderer
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
interface ezcGraphStackedBarsRenderer
|
||||
{
|
||||
/**
|
||||
* Draw stacked bar
|
||||
*
|
||||
* Draws a stacked bar part as a data element in a line chart
|
||||
*
|
||||
* @param ezcGraphBoundings $boundings Chart boundings
|
||||
* @param ezcGraphContext $context Context of call
|
||||
* @param ezcGraphColor $color Color of line
|
||||
* @param ezcGraphCoordinate $start
|
||||
* @param ezcGraphCoordinate $position
|
||||
* @param float $stepSize Space which can be used for bars
|
||||
* @param int $symbol Symbol to draw for line
|
||||
* @param float $axisPosition Position of axis for drawing filled lines
|
||||
* @return void
|
||||
*/
|
||||
public function drawStackedBar(
|
||||
ezcGraphBoundings $boundings,
|
||||
ezcGraphContext $context,
|
||||
ezcGraphColor $color,
|
||||
ezcGraphCoordinate $start,
|
||||
ezcGraphCoordinate $position,
|
||||
$stepSize,
|
||||
$symbol = ezcGraph::NO_SYMBOL,
|
||||
$axisPosition = 0.
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user