From 4c85aee953e34bb0f997af13fc9b35e5ed29699c Mon Sep 17 00:00:00 2001 From: Kore Nordmann Date: Tue, 15 Aug 2006 12:10:39 +0000 Subject: - Added implementation for bar charts to 3d renderer --- src/options/renderer_3d.php | 20 ++++ src/renderer/3d.php | 106 ++++++++++++++++++++- .../ezcGraphRenderer3dTest_testRenderBarChart.png | Bin 0 -> 73671 bytes tests/renderer_3d_test.php | 32 ++++++- 4 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 tests/data/compare/ezcGraphRenderer3dTest_testRenderBarChart.png diff --git a/src/options/renderer_3d.php b/src/options/renderer_3d.php index 04994d1..92c0194 100644 --- a/src/options/renderer_3d.php +++ b/src/options/renderer_3d.php @@ -133,6 +133,20 @@ class ezcGraphRenderer3dOptions extends ezcGraphChartOptions protected $barPadding = .05; /** + * Factor to darken the color used for the bars side polygon + * + * @var float + */ + protected $barDarkenSide = .2; + + /** + * Factor to darken the color used for the bars top polygon + * + * @var float + */ + protected $barDarkenTop = .4; + + /** * Set an option value * * @param string $propertyName @@ -196,6 +210,12 @@ class ezcGraphRenderer3dOptions extends ezcGraphChartOptions case 'barPadding': $this->barPadding = min( 1, max( 0, (float) $propertyValue ) ); break; + case 'barDarkenSide': + $this->barDarkenSide = min( 1, max( 0, (float) $propertyValue ) ); + break; + case 'barDarkenTop': + $this->barDarkenTop = min( 1, max( 0, (float) $propertyValue ) ); + break; default: return parent::__set( $propertyName, $propertyValue ); } diff --git a/src/renderer/3d.php b/src/renderer/3d.php index 4537fa7..2af00c3 100644 --- a/src/renderer/3d.php +++ b/src/renderer/3d.php @@ -29,6 +29,8 @@ class ezcGraphRenderer3d extends ezcGraphRenderer protected $circleSectors = array(); + protected $barPostProcessing = array(); + protected $options; protected $depth = false; @@ -455,9 +457,108 @@ class ezcGraphRenderer3d extends ezcGraphRenderer $dataCount = 1, $axisPosition = 0. ) { - // @TODO: implement + // Apply margin + $margin = $stepSize * $this->options->barMargin; + $padding = $stepSize * $this->options->barPadding; + $barWidth = ( $stepSize - $margin ) / $dataCount - $padding; + $offset = - $stepSize / 2 + $margin / 2 + ( $dataCount - $dataNumber - 1 ) * ( $padding + $barWidth ) + $padding / 2; + + $startDepth = $this->options->barMargin; + $endDepth = 1 - $this->options->barMargin; + + $barPolygonArray = array( + new ezcGraphCoordinate( + $this->dataBoundings->x0 + $this->xAxisSpace + $position->x * ( $this->dataBoundings->x1 - ( $this->dataBoundings->x0 + 2 * $this->xAxisSpace ) ) + $offset, + $this->dataBoundings->y0 + $this->yAxisSpace + $axisPosition * ( $this->dataBoundings->y1 - ( $this->dataBoundings->y0 + 2 * $this->yAxisSpace ) ) + ), + new ezcGraphCoordinate( + $this->dataBoundings->x0 + $this->xAxisSpace + $position->x * ( $this->dataBoundings->x1 - ( $this->dataBoundings->x0 + 2 * $this->xAxisSpace ) ) + $offset, + $this->dataBoundings->y0 + $this->yAxisSpace + $position->y * ( $this->dataBoundings->y1 - ( $this->dataBoundings->y0 + 2 * $this->yAxisSpace ) ) + ), + new ezcGraphCoordinate( + $this->dataBoundings->x0 + $this->xAxisSpace + $position->x * ( $this->dataBoundings->x1 - ( $this->dataBoundings->x0 + 2 * $this->xAxisSpace ) ) + $offset + $barWidth, + $this->dataBoundings->y0 + $this->yAxisSpace + $position->y * ( $this->dataBoundings->y1 - ( $this->dataBoundings->y0 + 2 * $this->yAxisSpace ) ) + ), + new ezcGraphCoordinate( + $this->dataBoundings->x0 + $this->xAxisSpace + $position->x * ( $this->dataBoundings->x1 - ( $this->dataBoundings->x0 + 2 * $this->xAxisSpace ) ) + $offset + $barWidth, + $this->dataBoundings->y0 + $this->yAxisSpace + $axisPosition * ( $this->dataBoundings->y1 - ( $this->dataBoundings->y0 + 2 * $this->yAxisSpace ) ) + ), + ); + + // Draw right bar side + $this->barPostProcessing[] = array( + 'polygone' => array( + $this->get3dCoordinate( $barPolygonArray[2], $startDepth ), + $this->get3dCoordinate( $barPolygonArray[3], $startDepth ), + $this->get3dCoordinate( $barPolygonArray[3], $endDepth ), + $this->get3dCoordinate( $barPolygonArray[2], $endDepth ), + ), + 'color' => $color->darken( $this->options->barDarkenSide ), + ); + + // Draw bar top + $this->barPostProcessing[] = array( + 'polygone' => array( + $this->get3dCoordinate( $barPolygonArray[1], $startDepth ), + $this->get3dCoordinate( $barPolygonArray[2], $startDepth ), + $this->get3dCoordinate( $barPolygonArray[2], $endDepth ), + $this->get3dCoordinate( $barPolygonArray[1], $endDepth ), + ), + 'color' => $color->darken( $this->options->barDarkenTop ), + ); + + // Draw front side + $this->barPostProcessing[] = array( + 'polygone' => array( + $this->get3dCoordinate( $barPolygonArray[0], $startDepth ), + $this->get3dCoordinate( $barPolygonArray[1], $startDepth ), + $this->get3dCoordinate( $barPolygonArray[2], $startDepth ), + $this->get3dCoordinate( $barPolygonArray[3], $startDepth ), + ), + 'color' => $color, + ); } - + + protected function finishBars() + { + $zBuffer = array(); + + foreach ( $this->barPostProcessing as $bar ) + { + $zIndex = (int) ( $bar['polygone'][0]->x * 10 ); + if ( !isset( $zBuffer[$zIndex] ) ) + { + $zBuffer[$zIndex] = array(); + } + + $zBuffer[$zIndex][] = $bar; + } + + ksort( $zBuffer ); + + foreach ( $zBuffer as $bars ) + { + foreach ( $bars as $bar ) + { + $this->driver->drawPolygon( + $bar['polygone'], + $bar['color'], + true + ); + + if ( $this->options->dataBorder > 0 ) + { + $borderColor = $bar['color']->darken( $this->options->dataBorder ); + $this->driver->drawPolygon( + $bar['polygone'], + $borderColor, + false + ); + } + } + } + } + /** * Draw data line * @@ -1381,6 +1482,7 @@ class ezcGraphRenderer3d extends ezcGraphRenderer { $this->finishCirleSectors(); $this->finishPieSegmentLabels(); + $this->finishBars(); $this->finishLineSymbols(); $this->finishFrontLines(); diff --git a/tests/data/compare/ezcGraphRenderer3dTest_testRenderBarChart.png b/tests/data/compare/ezcGraphRenderer3dTest_testRenderBarChart.png new file mode 100644 index 0000000..2636c84 Binary files /dev/null and b/tests/data/compare/ezcGraphRenderer3dTest_testRenderBarChart.png differ diff --git a/tests/renderer_3d_test.php b/tests/renderer_3d_test.php index 8b0074b..7491169 100644 --- a/tests/renderer_3d_test.php +++ b/tests/renderer_3d_test.php @@ -46,7 +46,10 @@ class ezcGraphRenderer3dTest extends ezcImageTestCase */ public function tearDown() { - $this->removeTempDir(); + if( !$this->hasFailed() ) + { + $this->removeTempDir(); + } } public function testRenderBackgroundImage() @@ -559,6 +562,33 @@ class ezcGraphRenderer3dTest extends ezcImageTestCase ); } + public function testRenderBarChart() + { + $filename = $this->tempDir . __FUNCTION__ . '.png'; + + $chart = new ezcGraphLineChart(); + $chart->palette = new ezcGraphPaletteBlack(); + + $chart->data['Line 0'] = new ezcGraphArrayDataSet( array( 'sample 1' => 432, 'sample 2' => 43, 'sample 3' => 65, 'sample 4' => 97, 'sample 5' => 154) ); + $chart->data['Line 0']->displayType = ezcGraph::BAR; + $chart->data['Line 1'] = new ezcGraphArrayDataSet( array( 'sample 1' => 234, 'sample 2' => 21, 'sample 3' => 324, 'sample 4' => 120, 'sample 5' => 1) ); + $chart->data['Line 1']->displayType = ezcGraph::BAR; + + $chart->xAxis->axisLabelRenderer = new ezcGraphAxisBoxedLabelRenderer(); + + $chart->driver = new ezcGraphGdDriver(); + $chart->renderer = new ezcGraphRenderer3d(); + $chart->options->font = $this->basePath . 'font.ttf'; + $chart->render( 500, 200, $filename ); + + $this->assertImageSimilar( + $filename, + $this->basePath . 'compare/' . __CLASS__ . '_' . __FUNCTION__ . '.png', + 'Image does not look as expected.', + 2000 + ); + } + public function testRender3dLineChart() { $filename = $this->tempDir . __FUNCTION__ . '.png'; -- cgit v1.1