diff options
author | Kore Nordmann <github@kore-nordmann.de> | 2007-09-06 12:45:09 +0000 |
---|---|---|
committer | Kore Nordmann <github@kore-nordmann.de> | 2007-09-06 12:45:09 +0000 |
commit | a3a7f0b264223ec011b46fd4e0ce2674af7e0087 (patch) | |
tree | 345bb747e3c8311795c154f9849bbc30aca8ee0b /src/charts | |
parent | c87432c04b6b68d8a1e210947acb3f260f013707 (diff) | |
download | zetacomponents-graph-a3a7f0b264223ec011b46fd4e0ce2674af7e0087.zip zetacomponents-graph-a3a7f0b264223ec011b46fd4e0ce2674af7e0087.tar.gz |
- Implemented feature #10978: Add support for stacked bar charts
Diffstat (limited to 'src/charts')
-rw-r--r-- | src/charts/line.php | 166 |
1 files changed, 136 insertions, 30 deletions
diff --git a/src/charts/line.php b/src/charts/line.php index 971834a..9e4dc77 100644 --- a/src/charts/line.php +++ b/src/charts/line.php @@ -281,19 +281,20 @@ class ezcGraphLineChart extends ezcGraphChart $lastPoint = false; foreach ( $data as $key => $value ) { + // Calculate point in chart + $point = $xAxis->axisLabelRenderer->modifyChartDataPosition( + $yAxis->axisLabelRenderer->modifyChartDataPosition( + new ezcGraphCoordinate( + $xAxis->getCoordinate( $key ), + $yAxis->getCoordinate( $value ) + ) + ) + ); + // Render depending on display type of dataset - switch ( $data->displayType->default ) + switch ( true ) { - case ezcGraph::LINE: - $point = $xAxis->axisLabelRenderer->modifyChartDataPosition( - $yAxis->axisLabelRenderer->modifyChartDataPosition( - new ezcGraphCoordinate( - $xAxis->getCoordinate( $key ), - $yAxis->getCoordinate( $value ) - ) - ) - ); - + case $data->displayType->default === ezcGraph::LINE: $renderer->drawDataLine( $boundings, new ezcGraphContext( $datasetName, $key, $data->url[$key] ), @@ -308,21 +309,65 @@ class ezcGraphLineChart extends ezcGraphChart $yAxisNullPosition ); break; - case ezcGraph::BAR: - $point = new ezcGraphCoordinate( - $xAxis->getCoordinate( $key ), - $yAxis->getCoordinate( $value ) - ); + case ( $data->displayType->default === ezcGraph::BAR ) && + $this->options->stackBars : + // Check if a bar has already been stacked + if ( !isset( $stackedValue[(int) ( $point->x * 10000 )][(int) $value > 0] ) ) + { + $start = new ezcGraphCoordinate( + $point->x, + $yAxisNullPosition + ); + + $stackedValue[(int) ( $point->x * 10000 )][(int) $value > 0] = $value; + } + else + { + $start = $xAxis->axisLabelRenderer->modifyChartDataPosition( + $yAxis->axisLabelRenderer->modifyChartDataPosition( + new ezcGraphCoordinate( + $xAxis->getCoordinate( $key ), + $yAxis->getCoordinate( $stackedValue[(int) ( $point->x * 10000 )][(int) $value > 0] ) + ) + ) + ); + + $point = $xAxis->axisLabelRenderer->modifyChartDataPosition( + $yAxis->axisLabelRenderer->modifyChartDataPosition( + new ezcGraphCoordinate( + $xAxis->getCoordinate( $key ), + $yAxis->getCoordinate( $stackedValue[(int) ( $point->x * 10000 )][(int) $value > 0] += $value ) + ) + ) + ); + } + + // Force one symbol for each stacked bar + if ( !isset( $stackedSymbol[(int) ( $point->x * 10000 )] ) ) + { + $stackedSymbol[(int) ( $point->x * 10000 )] = $data->symbol[$key]; + } + // Store stacked value for next iteration + $stacked[(int) ( $point->x * 10000 )][$point->y / abs( $point->y )] = $point; + + $renderer->drawStackedBar( + $boundings, + new ezcGraphContext( $datasetName, $key, $data->url[$key] ), + $data->color->default, + $start, + $point, + $width, + $stackedSymbol[(int) ( $point->x * 10000 )], + $yAxisNullPosition + ); + break; + case $data->displayType->default === ezcGraph::BAR: $renderer->drawBar( $boundings, new ezcGraphContext( $datasetName, $key, $data->url[$key] ), $data->color->default, - $point = $xAxis->axisLabelRenderer->modifyChartDataPosition( - $yAxis->axisLabelRenderer->modifyChartDataPosition( - $point - ) - ), + $point, $width, $nr[$data->displayType->default], $count[$data->displayType->default], @@ -369,32 +414,60 @@ class ezcGraphLineChart extends ezcGraphChart } /** - * Renders the basic elements of this chart type + * Check if renderer supports features requested by some special chart + * options. * - * @param int $width - * @param int $height + * @throw ezcBaseValueException + * If some feature is not supported + * * @return void */ - protected function renderElements( $width, $height ) + protected function checkRenderer() { - if ( !count( $this->data ) ) + // When stacked bars are enabled, check if renderer supports them + if ( $this->options->stackBars ) { - throw new ezcGraphNoDataException(); + if ( !$this->renderer instanceof ezcGraphStackedBarsRenderer ) + { + throw new ezcBaseValueException( 'renderer', $this->renderer, 'ezcGraphStackedBarsRenderer' ); + } } + } - // Set image properties in driver - $this->driver->options->width = $width; - $this->driver->options->height = $height; + /** + * Aggregate and calculate value boundings on axis. + * + * @return void + */ + protected function setAxisValues() + { + // Virtual data set build for agrregated values sums for bar charts + $virtualBarSumDataSet = array( array(), array() ); // Calculate axis scaling and labeling foreach ( $this->data as $dataset ) { + $nr = 0; $labels = array(); $values = array(); foreach ( $dataset as $label => $value ) { $labels[] = $label; $values[] = $value; + + // Build sum of all bars + if ( $this->options->stackBars && + ( $dataset->displayType->default === ezcGraph::BAR ) ) + { + if ( !isset( $virtualBarSumDataSet[(int) $value >= 0][$nr] ) ) + { + $virtualBarSumDataSet[(int) $value >= 0][$nr++] = $value; + } + else + { + $virtualBarSumDataSet[(int) $value >= 0][$nr++] += $value; + } + } } // Check if data has been associated with another custom axis, use @@ -418,6 +491,14 @@ class ezcGraphLineChart extends ezcGraphChart } } + // Also use stacked bar values as base for y axis value span + // calculation + if ( $this->options->stackBars ) + { + $this->elements['yAxis']->addData( $virtualBarSumDataSet[0] ); + $this->elements['yAxis']->addData( $virtualBarSumDataSet[1] ); + } + // There should always be something assigned to the main x and y axis. if ( !$this->elements['xAxis']->initialized || !$this->elements['yAxis']->initialized ) @@ -428,6 +509,27 @@ class ezcGraphLineChart extends ezcGraphChart // Calculate boundings from assigned data $this->elements['xAxis']->calculateAxisBoundings(); $this->elements['yAxis']->calculateAxisBoundings(); + } + + /** + * Renders the basic elements of this chart type + * + * @param int $width + * @param int $height + * @return void + */ + protected function renderElements( $width, $height ) + { + if ( !count( $this->data ) ) + { + throw new ezcGraphNoDataException(); + } + + // Check if renderer supports requested features + $this->checkRenderer(); + + // Set values form datasets on axis to calculate correct spans + $this->setAxisValues(); // Generate legend $this->elements['legend']->generateFromDataSets( $this->data ); @@ -436,6 +538,10 @@ class ezcGraphLineChart extends ezcGraphChart $this->options->width = $width; $this->options->height = $height; + // Set image properties in driver + $this->driver->options->width = $width; + $this->driver->options->height = $height; + // Render subelements $boundings = new ezcGraphBoundings(); $boundings->x1 = $this->options->width; |