diff options
author | Kore Nordmann <github@kore-nordmann.de> | 2006-08-07 07:09:04 +0000 |
---|---|---|
committer | Kore Nordmann <github@kore-nordmann.de> | 2006-08-07 07:09:04 +0000 |
commit | f0c3843559d630bcd9458e8f5b15185445dd173b (patch) | |
tree | da3f9a6d307e9c04a2071448c99694f74dc37034 /src | |
parent | c020e565ff041c311340311aa8064aa36da87b7f (diff) | |
download | zetacomponents-graph-f0c3843559d630bcd9458e8f5b15185445dd173b.zip zetacomponents-graph-f0c3843559d630bcd9458e8f5b15185445dd173b.tar.gz |
- Fixed pie chart labeling
- Fixed post processing for line chart symbols
- Fixed polygon sorting order in 3d pie charts
Diffstat (limited to 'src')
-rw-r--r-- | src/renderer/2d.php | 60 | ||||
-rw-r--r-- | src/renderer/3d.php | 230 |
2 files changed, 181 insertions, 109 deletions
diff --git a/src/renderer/2d.php b/src/renderer/2d.php index 8e54de0..193a11c 100644 --- a/src/renderer/2d.php +++ b/src/renderer/2d.php @@ -23,6 +23,8 @@ class ezcGraphRenderer2d extends ezcGraphRenderer protected $pieSegmentBoundings = false; + protected $linePostSymbols = array(); + protected $options; public function __construct( array $options = array() ) @@ -154,15 +156,21 @@ class ezcGraphRenderer2d extends ezcGraphRenderer ( $boundings->y1 - $boundings->y0 ) / 2 ); + $pieChartHeight = min( + $radius * 2 + $this->options->maxLabelHeight * 2, + $boundings->y1 - $boundings->y0 + ); + $pieChartYPosition = $boundings->y0 + ( ( $boundings->y1 - $boundings->y0 ) - $pieChartHeight ) / 2; + // Calculate maximum height of labels $labelHeight = (int) round( min( ( count( $this->pieSegmentLabels[0] ) - ? ( $boundings->y1 - $boundings->y0 ) / count( $this->pieSegmentLabels[0] ) - : ( $boundings->y1 - $boundings->y0 ) + ? $pieChartHeight / count( $this->pieSegmentLabels[0] ) + : $pieChartHeight ), ( count( $this->pieSegmentLabels[1] ) - ? ( $boundings->y1 - $boundings->y0 ) / count( $this->pieSegmentLabels[1] ) - : ( $boundings->y1 - $boundings->y0 ) + ? $pieChartHeight / count( $this->pieSegmentLabels[1] ) + : $pieChartHeight ), ( $boundings->y1 - $boundings->y0 ) * $this->options->maxLabelHeight ) ); @@ -171,8 +179,8 @@ class ezcGraphRenderer2d extends ezcGraphRenderer foreach ( $this->pieSegmentLabels as $side => $labelPart ) { - $minHeight = $boundings->y0; - $toShare = ( $boundings->y1 - $boundings->y0 ) - count( $labelPart ) * $labelHeight; + $minHeight = $pieChartYPosition; + $toShare = $pieChartHeight - count( $labelPart ) * $labelHeight; // Sort to draw topmost label first ksort( $labelPart ); @@ -181,12 +189,21 @@ class ezcGraphRenderer2d extends ezcGraphRenderer foreach ( $labelPart as $height => $label ) { // Determine position of label - $minHeight += max( 0, $height - $minHeight - $labelHeight ) / ( $boundings->y1 - $boundings->y0 ) * $toShare; + $minHeight += max( 0, $height - $minHeight - $labelHeight ) / $pieChartHeight * $toShare; + $verticalDistance = ( $center->y - $minHeight - $labelHeight / 2 ) / $radius; + $labelPosition = new ezcGraphCoordinate( $center->x - - $sign * ( - cos ( asin ( ( $center->y - $minHeight - $labelHeight / 2 ) / $radius ) ) * $radius + - $symbolSize * (int) $this->options->showSymbol + $sign * ( + abs( $verticalDistance ) > 1 ? + // If vertical distance to center is greater then the + // radius, use the centerline for the horizontal + // position + 5 : + // Else place the label outside of the pie chart + ( cos ( asin ( $verticalDistance ) ) * $radius + + $symbolSize * (int) $this->options->showSymbol + ) ), $minHeight + $labelHeight / 2 ); @@ -233,6 +250,18 @@ class ezcGraphRenderer2d extends ezcGraphRenderer } } } + + protected function finishLineSymbols() + { + foreach ( $this->linePostSymbols as $symbol ) + { + $this->drawSymbol( + $symbol['boundings'], + $symbol['color'], + $symbol['symbol'] + ); + } + } /** * Draw data line @@ -373,16 +402,16 @@ class ezcGraphRenderer2d extends ezcGraphRenderer { $symbolColor = $color; } - - $this->drawSymbol( - new ezcGraphBoundings( + + $this->linePostSymbols[] = array( + 'boundings' => new ezcGraphBoundings( $boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $end->x - $this->options->symbolSize / 2, $boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $end->y - $this->options->symbolSize / 2, $boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $end->x + $this->options->symbolSize / 2, $boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $end->y + $this->options->symbolSize / 2 ), - $symbolColor, - $symbol + 'color' => $symbolColor, + 'symbol' => $symbol, ); } } @@ -927,6 +956,7 @@ class ezcGraphRenderer2d extends ezcGraphRenderer protected function finish() { $this->finishPieSegmentLabels(); + $this->finishLineSymbols(); return true; } diff --git a/src/renderer/3d.php b/src/renderer/3d.php index 9d53af4..aa320a6 100644 --- a/src/renderer/3d.php +++ b/src/renderer/3d.php @@ -23,6 +23,8 @@ class ezcGraphRenderer3d extends ezcGraphRenderer protected $pieSegmentBoundings = false; + protected $linePostSymbols = array(); + protected $frontLines = array(); protected $circleSectors = array(); @@ -179,11 +181,20 @@ class ezcGraphRenderer3d extends ezcGraphRenderer { // Determine position of label $minHeight += max( 0, $height - $minHeight - $labelHeight ) / ( $boundings->y1 - $boundings->y0 ) * $toShare; + $verticalDistance = ( $center->y - $minHeight - $labelHeight / 2 ) / $radius; + $labelPosition = new ezcGraphCoordinate( $center->x - - $sign * ( - cos ( asin ( ( $center->y - $minHeight - $labelHeight / 2 ) / $radius ) ) * $radius + - $symbolSize * (int) $this->options->showSymbol + $sign * ( + abs( $verticalDistance ) > 1 ? + // If vertical distance to center is greater then the + // radius, use the centerline for the horizontal + // position + 5 : + // Else place the label outside of the pie chart + ( cos ( asin ( $verticalDistance ) ) * $radius + + $symbolSize * (int) $this->options->showSymbol + ) ), $minHeight + $labelHeight / 2 ); @@ -233,107 +244,125 @@ class ezcGraphRenderer3d extends ezcGraphRenderer protected function finishCirleSectors() { - // Draw circular arcs - foreach ( $this->circleSectors as $circleSector ) - { - $this->driver->drawCircularArc( - $circleSector['center'], - $circleSector['width'], - $circleSector['height'], - $this->options->pieChartHeight, - $circleSector['start'], - $circleSector['end'], - $circleSector['color'] - ); - } + $zBuffer = array(); - // Draw borders + // Add circle sector sides to simple z buffer prioriry list foreach ( $this->circleSectors as $circleSector ) { $darkenedColor = $circleSector['color']->darken( $this->options->dataBorder ); - $this->driver->drawPolygon( - array( + $zBuffer[ + (int) ( $circleSector['center']->y + sin( deg2rad( $circleSector['start'] + ( $circleSector['end'] - $circleSector['start'] ) / 2 ) ) * $circleSector['height'] / 2 ) + ][] = array( + 'method' => 'drawCircularArc', + 'paramenters' => array( $circleSector['center'], - new ezcGraphCoordinate( - $circleSector['center']->x, - $circleSector['center']->y + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['start'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['start'] ) ) * $circleSector['height'] / 2 + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['start'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['start'] ) ) * $circleSector['height'] / 2 - ), + $circleSector['width'], + $circleSector['height'], + $this->options->pieChartHeight, + $circleSector['start'], + $circleSector['end'], + $circleSector['color'] + ) + ); + + // Left side + $polygonPoints = array( + $circleSector['center'], + new ezcGraphCoordinate( + $circleSector['center']->x, + $circleSector['center']->y + $this->options->pieChartHeight + ), + new ezcGraphCoordinate( + $circleSector['center']->x + cos( deg2rad( $circleSector['start'] ) ) * $circleSector['width'] / 2, + $circleSector['center']->y + sin( deg2rad( $circleSector['start'] ) ) * $circleSector['height'] / 2 + $this->options->pieChartHeight + ), + new ezcGraphCoordinate( + $circleSector['center']->x + cos( deg2rad( $circleSector['start'] ) ) * $circleSector['width'] / 2, + $circleSector['center']->y + sin( deg2rad( $circleSector['start'] ) ) * $circleSector['height'] / 2 ), - $circleSector['color'], - true ); - $this->driver->drawPolygon( - array( - $circleSector['center'], - new ezcGraphCoordinate( - $circleSector['center']->x, - $circleSector['center']->y + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['start'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['start'] ) ) * $circleSector['height'] / 2 + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['start'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['start'] ) ) * $circleSector['height'] / 2 - ), + // Get average y coordinate for polygon to use for zBuffer + $center = 0; + foreach( $polygonPoints as $point ) + { + $center += $point->y; + } + $center = (int) ( $center / count( $polygonPoints ) ); + + $zBuffer[$center][] = array( + 'method' => 'drawPolygon', + 'paramenters' => array( + $polygonPoints, + $circleSector['color'], + true ), - $darkenedColor, - false ); - $this->driver->drawPolygon( - array( - $circleSector['center'], - new ezcGraphCoordinate( - $circleSector['center']->x, - $circleSector['center']->y + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['end'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['end'] ) ) * $circleSector['height'] / 2 + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['end'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['end'] ) ) * $circleSector['height'] / 2 - ), + $zBuffer[$center][] = array( + 'method' => 'drawPolygon', + 'paramenters' => array( + $polygonPoints, + $darkenedColor, + false ), - $circleSector['color'], - true ); - $this->driver->drawPolygon( - array( - $circleSector['center'], - new ezcGraphCoordinate( - $circleSector['center']->x, - $circleSector['center']->y + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['end'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['end'] ) ) * $circleSector['height'] / 2 + $this->options->pieChartHeight - ), - new ezcGraphCoordinate( - $circleSector['center']->x + cos( deg2rad( $circleSector['end'] ) ) * $circleSector['width'] / 2, - $circleSector['center']->y + sin( deg2rad( $circleSector['end'] ) ) * $circleSector['height'] / 2 - ), + // Right side + $polygonPoints = array( + $circleSector['center'], + new ezcGraphCoordinate( + $circleSector['center']->x, + $circleSector['center']->y + $this->options->pieChartHeight + ), + new ezcGraphCoordinate( + $circleSector['center']->x + cos( deg2rad( $circleSector['end'] ) ) * $circleSector['width'] / 2, + $circleSector['center']->y + sin( deg2rad( $circleSector['end'] ) ) * $circleSector['height'] / 2 + $this->options->pieChartHeight + ), + new ezcGraphCoordinate( + $circleSector['center']->x + cos( deg2rad( $circleSector['end'] ) ) * $circleSector['width'] / 2, + $circleSector['center']->y + sin( deg2rad( $circleSector['end'] ) ) * $circleSector['height'] / 2 ), - $darkenedColor, - false ); + + // Get average y coordinate for polygon to use for zBuffer + $center = 0; + foreach( $polygonPoints as $point ) + { + $center += $point->y; + } + $center = (int) ( $center / count( $polygonPoints ) ); + + $zBuffer[$center][] = array( + 'method' => 'drawPolygon', + 'paramenters' => array( + $polygonPoints, + $circleSector['color'], + true + ), + ); + + $zBuffer[$center][] = array( + 'method' => 'drawPolygon', + 'paramenters' => array( + $polygonPoints, + $darkenedColor, + false + ), + ); + } + + ksort( $zBuffer ); + foreach ( $zBuffer as $sides ) + { + foreach ( $sides as $side ) + { + call_user_func_array( array( $this->driver, $side['method'] ), $side['paramenters'] ); + } } - // Draw circle sector + // Draw circle sector for front foreach ( $this->circleSectors as $circleSector ) { $this->driver->drawCircleSector( @@ -364,13 +393,25 @@ class ezcGraphRenderer3d extends ezcGraphRenderer foreach ( $this->frontLines as $line ) { $this->driver->drawLine( - $line[0], + $line[0], $line[1], $line[2], $line[3] ); } } + + protected function finishLineSymbols() + { + foreach ( $this->linePostSymbols as $symbol ) + { + $this->drawSymbol( + $symbol['boundings'], + $symbol['color'], + $symbol['symbol'] + ); + } + } /** * Draw data line @@ -580,15 +621,15 @@ class ezcGraphRenderer3d extends ezcGraphRenderer $symbolColor = $color; } - $this->drawSymbol( - new ezcGraphBoundings( - $pointModifier + $depth / 2 + $boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $end->x - $this->options->symbolSize / 2, - -$pointModifier - $depth / 2 + $boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $end->y - $this->options->symbolSize / 2, - $pointModifier + $depth / 2 + $boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $end->x + $this->options->symbolSize / 2, - -$pointModifier - $depth / 2 + $boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $end->y + $this->options->symbolSize / 2 + $this->linePostSymbols[] = array( + 'boundings' => new ezcGraphBoundings( + $pointModifier + $boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $end->x - $this->options->symbolSize / 2, + -$pointModifier + $boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $end->y - $this->options->symbolSize / 2, + $pointModifier + $boundings->x0 + ( $boundings->x1 - $boundings->x0 ) * $end->x + $this->options->symbolSize / 2, + -$pointModifier + $boundings->y0 + ( $boundings->y1 - $boundings->y0 ) * $end->y + $this->options->symbolSize / 2 ), - $symbolColor, - $symbol + 'color' => $symbolColor, + 'symbol' => $symbol, ); } } @@ -1312,6 +1353,7 @@ class ezcGraphRenderer3d extends ezcGraphRenderer { $this->finishCirleSectors(); $this->finishPieSegmentLabels(); + $this->finishLineSymbols(); $this->finishFrontLines(); return true; |