From a5476184b65f07f983d9f676d74550bcfe1925d6 Mon Sep 17 00:00:00 2001 From: Kore Nordmann Date: Tue, 23 May 2006 16:18:27 +0000 Subject: - Implemented tests for line chart legend rendering - Implemented legend rendering --- src/charts/line.php | 2 +- src/element/labeled_axis.php | 2 +- src/element/legend.php | 161 ++++++++++++++++++++++++++++++++++++++++++- src/element/numeric_axis.php | 2 +- src/element/text.php | 2 +- src/graph.php | 2 + src/graph_autoload.php | 2 +- src/interfaces/chart.php | 8 ++- src/interfaces/element.php | 128 +++++++++++++++++++++++++++++++++- src/interfaces/renderer.php | 16 +++-- src/renderer/2d.php | 20 ++---- src/structs/coordinate.php | 4 +- 12 files changed, 322 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/charts/line.php b/src/charts/line.php index f639439..6f664b6 100644 --- a/src/charts/line.php +++ b/src/charts/line.php @@ -50,7 +50,7 @@ class ezcGraphLineChart extends ezcGraphChart foreach ( $this->elements as $element ) { - $boundings = $element->render( $boundings ); + $boundings = $element->render( $this->renderer, $boundings ); } // Render graph diff --git a/src/element/labeled_axis.php b/src/element/labeled_axis.php index 41fc75b..b0ce7ba 100644 --- a/src/element/labeled_axis.php +++ b/src/element/labeled_axis.php @@ -86,7 +86,7 @@ class ezcGraphChartElementLabeledAxis extends ezcGraphChartElement * @access public * @return void */ - public function render( ezcGraphBoundings $boundings ) + public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings ) { return $boundings; } diff --git a/src/element/legend.php b/src/element/legend.php index d88409f..3736848 100644 --- a/src/element/legend.php +++ b/src/element/legend.php @@ -21,6 +21,7 @@ class ezcGraphChartElementLegend extends ezcGraphChartElement * array( * 'label' => (string) 'Label of data element', * 'color' => (ezcGraphColor) $color, + * 'symbol' => (integer) ezcGraph::DIAMOND, * ), * ... * ) @@ -30,6 +31,44 @@ class ezcGraphChartElementLegend extends ezcGraphChartElement protected $labels; /** + * Size of a portrait style legend in percent of the size of the complete + * chart + * + * @var float + */ + protected $portraitSize = .2; + + /** + * Size of a landscape style legend in percent of the size of the complete + * chart + * + * @var float + */ + protected $landscapeSize = .1; + + /** + * Standard size of symbols and text in legends + * + * @var integer + */ + protected $symbolSize = 14; + + /** + * Padding for label elements + * + * @var integer + */ + protected $padding = 1; + + /** + * Scale symbol size up to to percent of complete legends size for very + * big legends + * + * @var float + */ + protected $minimumSymbolSize = .05; + + /** * Generate legend from several datasets with on entry per dataset * * @param array $datasets @@ -43,6 +82,9 @@ class ezcGraphChartElementLegend extends ezcGraphChartElement $this->labels[] = array( 'label' => $dataset->label->default, 'color' => $dataset->color->default, + 'symbol' => ( $dataset->symbol->default === null ? + ezcGraph::NO_SYMBOL : + $dataset->symbol->default ), ); } } @@ -61,10 +103,117 @@ class ezcGraphChartElementLegend extends ezcGraphChartElement $this->labels[] = array( 'label' => $label, 'color' => $dataset->color[$label], + 'symbol' => ( $dataset->symbol[$label] === null ? + ezcGraph::NO_SYMBOL : + $dataset->symbol[$label] ), ); } } + protected function calculateBoundings( ezcGraphBoundings $boundings ) + { + switch ( $this->position ) + { + case ezcGraph::TOP: + $this->boundings = clone $boundings; + + $this->boundings->y1 = $boundings->y0 + ($boundings->y1 - $boundings->y0) * $this->landscapeSize; + $boundings->y0 = $boundings->y0 + ($boundings->y1 - $boundings->y0) * $this->landscapeSize; + break; + case ezcGraph::LEFT: + $this->boundings = clone $boundings; + + $this->boundings->x1 = $boundings->x0 + ($boundings->x1 - $boundings->x0) * $this->portraitSize; + $boundings->x0 = $boundings->x0 + ($boundings->x1 - $boundings->x0) * $this->portraitSize; + break; + case ezcGraph::RIGHT: + $this->boundings = clone $boundings; + + $this->boundings->x0 = $boundings->x1 - ($boundings->x1 - $boundings->x0) * $this->portraitSize; + $boundings->x1 = $boundings->x1 - ($boundings->x1 - $boundings->x0) * $this->portraitSize; + break; + case ezcGraph::BOTTOM: + $this->boundings = clone $boundings; + + $this->boundings->y0 = $boundings->y1 - ($boundings->y1 - $boundings->y0) * $this->landscapeSize; + $boundings->y1 = $boundings->y1 - ($boundings->y1 - $boundings->y0) * $this->landscapeSize; + break; + } + + return $boundings; + } + + protected function renderLegend( ezcGraphRenderer $renderer ) + { + switch ( $this->position ) + { + case ezcGraph::LEFT: + case ezcGraph::RIGHT: + $symbolSize = min( + max( + $this->symbolSize, + ( $this->boundings->y1 - $this->boundings->y0 ) * $this->minimumSymbolSize + ), + ( $this->boundings->y1 - $this->boundings->y0 ) / count( $this->labels ) + ); + + foreach ( $this->labels as $labelNr => $label ) + { + $renderer->drawSymbol( + $label['color'], + new ezcGraphCoordinate( + $this->boundings->x0 + $this->padding, + $this->boundings->y0 + $labelNr * $symbolSize + $this->padding + ), + $symbolSize - 2 * $this->padding, + $symbolSize - 2 * $this->padding, + $label['symbol'] + ); + $renderer->drawTextBox( + new ezcGraphCoordinate( + $this->boundings->x0 + $symbolSize, + $this->boundings->y0 + $labelNr * $symbolSize + $this->padding + ), + $label['label'], + $this->boundings->x1 - $this->boundings->x0 - $symbolSize - $this->padding, + $symbolSize - 2 * $this->padding + ); + } + break; + case ezcGraph::TOP: + case ezcGraph::BOTTOM: + $symbolSize = min( + $this->symbolSize, + ( $this->boundings->y1 - $this->boundings->y0 ) + ); + $width = ( $this->boundings->x1 - $this->boundings->x0 ) / count( $this->labels ); + + foreach ( $this->labels as $labelNr => $label ) + { + $renderer->drawSymbol( + $label['color'], + new ezcGraphCoordinate( + $this->boundings->x0 + $labelNr * $width + $this->padding, + $this->boundings->y0 + $this->padding + ), + $symbolSize - 2 * $this->padding, + $symbolSize - 2 * $this->padding, + $label['symbol'] + ); + $renderer->drawTextBox( + new ezcGraphCoordinate( + $this->boundings->x0 + $labelNr * $width + $this->padding + $symbolSize, + $this->boundings->y0 + $this->padding + ), + $label['label'], + $width - $this->padding - $symbolSize, + $symbolSize - 2 * $this->padding + ); + } + break; + } + } + /** * Render a legend * @@ -72,8 +221,18 @@ class ezcGraphChartElementLegend extends ezcGraphChartElement * @access public * @return void */ - public function render( ezcGraphBoundings $boundings ) + public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings ) { + $boundings = $this->calculateBoundings( $boundings ); + + // Render standard elements + $this->renderBorder( $renderer ); + $this->renderBackground( $renderer ); + $this->renderTitle( $renderer ); + + // Render legend + $this->renderLegend( $renderer ); + return $boundings; } } diff --git a/src/element/numeric_axis.php b/src/element/numeric_axis.php index d84ac4d..2685c55 100644 --- a/src/element/numeric_axis.php +++ b/src/element/numeric_axis.php @@ -252,7 +252,7 @@ class ezcGraphChartElementNumericAxis extends ezcGraphChartElement * @access public * @return void */ - public function render( ezcGraphBoundings $boundings ) + public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings ) { return $boundings; } diff --git a/src/element/text.php b/src/element/text.php index 07cb229..fc2e930 100644 --- a/src/element/text.php +++ b/src/element/text.php @@ -21,7 +21,7 @@ class ezcGraphChartElementText extends ezcGraphChartElement * @access public * @return void */ - public function render( ezcGraphBoundings $boundings ) + public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings ) { return $boundings; } diff --git a/src/graph.php b/src/graph.php index 6f64078..0037e68 100644 --- a/src/graph.php +++ b/src/graph.php @@ -15,12 +15,14 @@ class ezcGraph { + const NO_SYMBOL = 0; const DIAMOND = 1; const TOP = 1; const BOTTOM = 2; const LEFT = 3; const RIGHT = 4; + const CENTER = 5; static protected $chartTypes = array( 'pie' => 'ezcGraphPieChart', diff --git a/src/graph_autoload.php b/src/graph_autoload.php index bcbcb98..b1055dc 100644 --- a/src/graph_autoload.php +++ b/src/graph_autoload.php @@ -50,7 +50,7 @@ return array( 'ezcGraphUnknownDatasetSourceException' => 'Graph/exceptions/unknown_dataset_source.php', 'ezcGraphBoundings' => 'Graph/structs/boundings.php', - 'ezcGraphCoordiinate' => 'Graph/structs/coordinate.php', + 'ezcGraphCoordinate' => 'Graph/structs/coordinate.php', ); ?> diff --git a/src/interfaces/chart.php b/src/interfaces/chart.php index b40c733..7cf1e1e 100644 --- a/src/interfaces/chart.php +++ b/src/interfaces/chart.php @@ -83,7 +83,9 @@ abstract class ezcGraphChart case 'renderer': if ( $propertyValue instanceof ezcGraphRenderer ) { - return $this->renderer = $propertyValue; + $this->renderer = $propertyValue; + $this->renderer->setDriver( $this->driver ); + return $this->renderer; } else { @@ -93,7 +95,9 @@ abstract class ezcGraphChart case 'driver': if ( $propertyValue instanceof ezcGraphDriver ) { - return $this->driver = $propertyValue; + $this->driver = $propertyValue; + $this->renderer->setDriver( $this->driver ); + return $this->driver; } else { diff --git a/src/interfaces/element.php b/src/interfaces/element.php index 73b0f52..8448739 100644 --- a/src/interfaces/element.php +++ b/src/interfaces/element.php @@ -30,6 +30,13 @@ abstract class ezcGraphChartElement extends ezcBaseOptions protected $background; /** + * Boundings of this elements + * + * @var ezcGraphBoundings + */ + protected $boundings; + + /** * Border color of chart element * * @var ezcGraphColor @@ -51,6 +58,37 @@ abstract class ezcGraphChartElement extends ezcBaseOptions protected $position; /** + * Maximum size of the title + * + * @var integer + */ + protected $maxTitleHeight = 16; + + /** + * Percentage of boundings which are used for the title with position + * left, right or center + * + * @var float + */ + protected $portraitTitleSize = .15; + + /** + * Percentage of boundings which are used for the title with position + * top otr bottom + * + * @var float + */ + protected $landscapeTitleSize = .2; + + public function __construct( array $options = array() ) + { + $this->boundings = new ezcGraphBoundings(); + $this->position = ezcGraph::LEFT; + + parent::__construct( $options ); + } + + /** * __set * * @param mixed $propertyName @@ -109,7 +147,95 @@ abstract class ezcGraphChartElement extends ezcBaseOptions * @param ezcGraphBoundings $boundings Part of canvase to render element on * @return ezcGraphBoundings Part of canvas, which is still free to draw on */ - abstract public function render( ezcGraphBoundings $boundings ); + abstract public function render( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings ); + + protected function renderBorder( ezcGraphRenderer $renderer ) + { + if ( $this->border instanceof ezcGraphColor ) + { + // Default bordervalue to 1 + $this->borderWidth = max( 1, $this->borderWidth ); + + // Draw border + $renderer->drawRect( + $this->border, + new ezcGraphCoordinate( $this->boundings->x0, $this->boundings->y0 ), + $this->boundings->x1 - $this->boundings->x0, + $this->boundings->y1 - $this->boundings->y0, + $this->borderWidth + ); + + // Reduce local boundings by borderWidth + $this->boundings->x0 += $this->borderWidth; + $this->boundings->y0 += $this->borderWidth; + $this->boundings->x1 -= $this->borderWidth; + $this->boundings->y1 -= $this->borderWidth; + } + } + + protected function renderBackground( ezcGraphRenderer $renderer ) + { + if ( $this->background instanceof ezcGraphColor ) + { + $renderer->drawBackground( + $this->background, + new ezcGraphCoordinate( $this->boundings->x0, $this->boundings->y0 ), + $this->boundings->x1 - $this->boundings->x0, + $this->boundings->y1 - $this->boundings->y0 + ); + } + } + + protected function renderTitle( ezcGraphRenderer $renderer ) + { + if ( !empty( $this->title ) ) + { + switch ( $this->position ) + { + case ezcGraph::LEFT: + case ezcGraph::RIGHT: + case ezcGraph::CENTER: + $height = min( + $this->maxTitleHeight, + ( $this->boundings->y1 - $this->boundings->y0 ) * $this->portraitTitleSize + ); + $renderer->drawTextBox( + new ezcGraphCoordinate( $this->boundings->x0, $this->boundings->y0 ), + $this->title, + $this->boundings->x1 - $this->boundings->x0, + $height + ); + $this->boundings->y0 += $height; + break; + case ezcGraph::TOP: + $height = min( + $this->maxTitleHeight, + ( $this->boundings->y1 - $this->boundings->y0 ) * $this->landscapeTitleSize + ); + $renderer->drawTextBox( + new ezcGraphCoordinate( $this->boundings->x0, $this->boundings->y0 ), + $this->title, + $this->boundings->x1 - $this->boundings->x0, + $height + ); + $this->boundings->y0 += $height; + break; + case ezcGraph::BOTTOM: + $height = min( + $this->maxTitleHeight, + ( $this->boundings->y1 - $this->boundings->y0 ) * $this->landscapeTitleSize + ); + $renderer->drawTextBox( + new ezcGraphCoordinate( $this->boundings->x0, $this->boundings->y1 - $height ), + $this->title, + $this->boundings->x1 - $this->boundings->x0, + $height + ); + $this->boundings->y1 -= $height; + break; + } + } + } } ?> diff --git a/src/interfaces/renderer.php b/src/interfaces/renderer.php index b14ecde..f49f92a 100644 --- a/src/interfaces/renderer.php +++ b/src/interfaces/renderer.php @@ -15,6 +15,14 @@ */ abstract class ezcGraphRenderer { + + protected $driver; + + public function setDriver( ezcGraphDriver $driver ) + { + $this->driver = $driver; + } + /** * Draw a pie segment * @@ -25,7 +33,7 @@ abstract class ezcGraphRenderer * @param float $moveOut * @return void */ - abstract public function drawPieSegment( ezcGraphCoordinate $position, $radius, $startAngle = .0, $endAngle = 360., $moveOut = .0 ); + abstract public function drawPieSegment( ezcGraphColor $color, ezcGraphCoordinate $position, $radius, $startAngle = .0, $endAngle = 360., $moveOut = .0 ); /** * Draw a line @@ -38,7 +46,7 @@ abstract class ezcGraphRenderer * @param mixed $filled * @return void */ - abstract public function drawLine( ezcGraphCoordinate $position, ezcGraphCoordinate $end, $filled = true ); + abstract public function drawLine( ezcGraphColor $color, ezcGraphCoordinate $position, ezcGraphCoordinate $end, $filled = true ); /** * Draws a text box @@ -49,7 +57,7 @@ abstract class ezcGraphRenderer * @param mixed $height * @return void */ - abstract public function drawTextBox( ezcGraphCoordinate $position, $text, $width = null, $height = null ); + abstract public function drawTextBox( ezcGraphCoordinate $position, $text, $width = null, $height = null, $align = ezcGraph::LEFT ); /** * Draws a rectangle @@ -96,5 +104,5 @@ abstract class ezcGraphRenderer * @param int $symbol * @return void */ - abstract public function drawSymbol( ezcGraphCoordinate $position, $width, $height, $symbol = ezcGraph::NO_SYMBOL); + abstract public function drawSymbol( ezcGraphColor $color, ezcGraphCoordinate $position, $width, $height, $symbol = ezcGraph::NO_SYMBOL); } diff --git a/src/renderer/2d.php b/src/renderer/2d.php index 994a0ed..2711374 100644 --- a/src/renderer/2d.php +++ b/src/renderer/2d.php @@ -12,8 +12,9 @@ * * @package Graph */ -class ezcGraphRenderer2D extends ezcGraphRenderer { - +class ezcGraphRenderer2D extends ezcGraphRenderer +{ + /** * Draw a pie segment * @@ -22,10 +23,9 @@ class ezcGraphRenderer2D extends ezcGraphRenderer { * @param float $startAngle * @param float $endAngle * @param float $moveOut - * @access public * @return void */ - public function drawPieSegment( ezcGraphCoordinate $position, $radius, $startAngle = .0, $endAngle = 360., $moveOut = .0 ) + public function drawPieSegment( ezcGraphColor $color, ezcGraphCoordinate $position, $radius, $startAngle = .0, $endAngle = 360., $moveOut = .0 ) { } @@ -39,10 +39,9 @@ class ezcGraphRenderer2D extends ezcGraphRenderer { * @param ezcGraphCoordinate $position * @param ezcGraphCoordinate $end * @param mixed $filled - * @access public * @return void */ - public function drawLine( ezcGraphCoordinate $position, ezcGraphCoordinate $end, $filled = true ) + public function drawLine( ezcGraphColor $color, ezcGraphCoordinate $position, ezcGraphCoordinate $end, $filled = true ) { } @@ -54,10 +53,9 @@ class ezcGraphRenderer2D extends ezcGraphRenderer { * @param mixed $text * @param mixed $width * @param mixed $height - * @access public * @return void */ - public function drawTextBox( ezcGraphCoordinate $position, $text, $width = null, $height = null ) + public function drawTextBox( ezcGraphCoordinate $position, $text, $width = null, $height = null, $align = ezcGraph::LEFT ) { } @@ -70,7 +68,6 @@ class ezcGraphRenderer2D extends ezcGraphRenderer { * @param mixed $width * @param mixed $height * @param float $borderWidth - * @access public * @return void */ public function drawRect( ezcGraphColor $color, ezcGraphCoordinate $position = null, $width = null, $height = null, $borderWidth = 1 ) @@ -87,7 +84,6 @@ class ezcGraphRenderer2D extends ezcGraphRenderer { * @param ezcGraphCoordinate $position * @param mixed $width * @param mixed $height - * @access public * @return void */ public function drawBackground( ezcGraphColor $color, ezcGraphCoordinate $position = null, $width = null, $height = null ) @@ -102,7 +98,6 @@ class ezcGraphRenderer2D extends ezcGraphRenderer { * @param ezcGraphCoordinate $position * @param mixed $width * @param mixed $height - * @access public * @return void */ public function drawBackgroundImage( $file, ezcGraphCoordinate $position = null, $width = null, $height = null ) @@ -117,10 +112,9 @@ class ezcGraphRenderer2D extends ezcGraphRenderer { * @param float $width * @param float $height * @param int $symbol - * @access public * @return void */ - public function drawSymbol( ezcGraphCoordinate $position, $width, $height, $symbol = ezcGraph::NO_SYMBOL) + public function drawSymbol( ezcGraphColor $color, ezcGraphCoordinate $position, $width, $height, $symbol = ezcGraph::NO_SYMBOL) { } diff --git a/src/structs/coordinate.php b/src/structs/coordinate.php index 10ec1c3..d7093d4 100644 --- a/src/structs/coordinate.php +++ b/src/structs/coordinate.php @@ -9,8 +9,10 @@ class ezcGraphCoordinate /** * Empty constructor */ - public function __construct() + public function __construct( $x, $y ) { + $this->x = $x; + $this->y = $y; } /** -- cgit v1.1