Author: kn Date: Wed Nov 21 12:36:02 2007 New Revision: 6780 Log: - Added support for odometer charts # Thanks to Lars Jankowski from Oxid esales for the initial patch.
Added: trunk/Graph/src/charts/odometer.php (with props) trunk/Graph/src/interfaces/odometer_renderer.php (with props) trunk/Graph/src/options/odometer_chart.php (with props) trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometer.svg (with props) trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerToOutput.svg (with props) trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerWithDifferentOptions.svg (with props) Modified: trunk/Graph/design/class_diagram.png trunk/Graph/src/element/axis.php trunk/Graph/src/graph.php trunk/Graph/src/graph_autoload.php trunk/Graph/src/renderer/2d.php Modified: trunk/Graph/design/class_diagram.png ============================================================================== Binary files - no diff available. Added: trunk/Graph/src/charts/odometer.php ============================================================================== --- trunk/Graph/src/charts/odometer.php (added) +++ trunk/Graph/src/charts/odometer.php [iso-8859-1] Wed Nov 21 12:36:02 2007 @@ -1,0 +1,191 @@ +<?php +/** + * File containing the ezcGraphPieChart class + * + * @package Graph + * @version 1.1 + * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +class ezcGraphOdometerChart extends ezcGraphChart +{ + + /** + * Constructor + * + * @param array $options Default option array + * @return void + * @ignore + */ + public function __construct( array $options = array() ) + { + $this->options = new ezcGraphOdometerChartOptions( $options ); + + parent::__construct( $options ); + + $this->data = new ezcGraphChartSingleDataContainer( $this ); + + $this->addElement( 'axis', new ezcGraphChartElementNumericAxis()); + $this->elements['axis']->axisLabelRenderer = new ezcGraphAxisCenteredLabelRenderer(); + $this->elements['axis']->position = ezcGraph::LEFT; + $this->elements['axis']->axisSpace = .05; + } + + /** + * Render the assigned data + * + * Will renderer all charts data in the remaining boundings after drawing + * all other chart elements. The data will be rendered depending on the + * settings in the dataset. + * + * @param ezcGraphRenderer $renderer Renderer + * @param ezcGraphBoundings $boundings Remaining boundings + * @return void + */ + protected function renderData( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings ) + { + // Draw the odometer data + $dataset = $this->data->rewind(); + + foreach ( $dataset as $key => $value ) + { + $renderer->drawOdometerMarker( + $boundings, + $this->elements['axis']->axisLabelRenderer->modifyChartDataPosition( + new ezcGraphCoordinate( + $this->elements['axis']->getCoordinate( $value ), + 0 + ) + ), + $dataset->symbol[$key], + $dataset->color[$key], + $this->options->markerWidth + ); + } + } + + /** + * Returns the default display type of the current chart type. + * + * @return int Display type + */ + public function getDefaultDisplayType() + { + return ezcGraph::ODOMETER; + } + + /** + * 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(); + } + + // Set image properties in driver + $this->driver->options->width = $width; + $this->driver->options->height = $height; + + // no legend + $this->renderElement['legend'] = false; + + // Get boundings from parameters + $this->options->width = $width; + $this->options->height = $height; + + $boundings = new ezcGraphBoundings(); + $boundings->x1 = $this->options->width; + $boundings->y1 = $this->options->height; + + // Get values out the single used dataset to calculate axis boundings + $values = array(); + foreach( $this->data->rewind() as $value ) + { + $values[] = $value; + } + + // Set values for Axis + $this->elements['axis']->addData( $values ); + $this->elements['axis']->nullPosition = 0.5 + $this->options->odometerHeight / 2; + $this->elements['axis']->calculateAxisBoundings(); + + // Render subelements exept axis, which will be drawn together with the + // odometer bar + foreach ( $this->elements as $name => $element ) + { + // Skip element, if it should not get rendered + if ( $this->renderElement[$name] === false || + $name === 'axis' ) + { + continue; + } + + $this->driver->options->font = $element->font; + $boundings = $element->render( $this->renderer, $boundings ); + } + + // Draw basic odometer + $this->driver->options->font = $this->elements['axis']->font; + $boundings = $this->renderer->drawOdometer( + $boundings, + $this->elements['axis'], + $this->options + ); + + // Render graph + $this->renderData( $this->renderer, $boundings ); + } + + /** + * Render the pie chart + * + * Renders the chart into a file or stream. The width and height are + * needed to specify the dimensions of the resulting image. For direct + * output use 'php://stdout' as output file. + * + * @param int $width Image width + * @param int $height Image height + * @param string $file Output file + * @apichange + * @return void + */ + public function render( $width, $height, $file = null ) + { + $this->renderElements( $width, $height ); + + if ( !empty( $file ) ) + { + $this->renderer->render( $file ); + } + + $this->renderedFile = $file; + } + + /** + * 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 + * @apichange + * @return void + */ + public function renderToOutput( $width, $height ) + { + // @TODO: merge this function with render an deprecate ommit of third + // argument in render() when API break is possible + $this->renderElements( $width, $height ); + $this->renderer->render( null ); + } +} + +?> Propchange: trunk/Graph/src/charts/odometer.php ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/Graph/src/element/axis.php ============================================================================== --- trunk/Graph/src/element/axis.php [iso-8859-1] (original) +++ trunk/Graph/src/element/axis.php [iso-8859-1] Wed Nov 21 12:36:02 2007 @@ -19,6 +19,7 @@ * Color of major majorGrid. * @property ezcGraphColor $minorGrid * Color of minor majorGrid. + * @TODO: Move next two options to numeric axis * @property mixed $majorStep * Labeled major steps displayed on the axis. * @property mixed $minorStep Modified: trunk/Graph/src/graph.php ============================================================================== --- trunk/Graph/src/graph.php [iso-8859-1] (original) +++ trunk/Graph/src/graph.php [iso-8859-1] Wed Nov 21 12:36:02 2007 @@ -98,6 +98,10 @@ * type ezcGraph::BAR. */ const BAR = 3; + /** + * @TODO: + */ + const ODOMETER = 4; /** * Font type definition. Used for True Type fonts. Modified: trunk/Graph/src/graph_autoload.php ============================================================================== --- trunk/Graph/src/graph_autoload.php [iso-8859-1] (original) +++ trunk/Graph/src/graph_autoload.php [iso-8859-1] Wed Nov 21 12:36:02 2007 @@ -52,6 +52,7 @@ 'ezcGraphDriver' => 'Graph/interfaces/driver.php', 'ezcGraphDriverOptions' => 'Graph/options/driver.php', 'ezcGraphLineChart' => 'Graph/charts/line.php', + 'ezcGraphOdometerRenderer' => 'Graph/interfaces/odometer_renderer.php', 'ezcGraphPalette' => 'Graph/interfaces/palette.php', 'ezcGraphRadarRenderer' => 'Graph/interfaces/radar_renderer.php', 'ezcGraphRenderer' => 'Graph/interfaces/renderer.php', @@ -93,6 +94,8 @@ 'ezcGraphLineChartOptions' => 'Graph/options/line_chart.php', 'ezcGraphLinearGradient' => 'Graph/colors/linear_gradient.php', 'ezcGraphNumericDataSet' => 'Graph/datasets/numeric.php', + 'ezcGraphOdometerChart' => 'Graph/charts/odometer.php', + 'ezcGraphOdometerChartOptions' => 'Graph/options/odometer_chart.php', 'ezcGraphPaletteBlack' => 'Graph/palette/black.php', 'ezcGraphPaletteEz' => 'Graph/palette/ez.php', 'ezcGraphPaletteEzBlue' => 'Graph/palette/ez_blue.php', Added: trunk/Graph/src/interfaces/odometer_renderer.php ============================================================================== --- trunk/Graph/src/interfaces/odometer_renderer.php (added) +++ trunk/Graph/src/interfaces/odometer_renderer.php [iso-8859-1] Wed Nov 21 12:36:02 2007 @@ -1,0 +1,51 @@ +<?php +/** + * File containing the ezcGraphRadarRenderer interface + * + * @package Graph + * @version 1.1 + * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved. + 2006 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.1 + * @package Graph + */ +interface ezcGraphOdometerRenderer +{ + /** + * Render odometer chart + * + * @param ezcGraphBoundings $boundings + * @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 + ); +} + +?> Propchange: trunk/Graph/src/interfaces/odometer_renderer.php ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/Graph/src/options/odometer_chart.php ============================================================================== --- trunk/Graph/src/options/odometer_chart.php (added) +++ trunk/Graph/src/options/odometer_chart.php [iso-8859-1] Wed Nov 21 12:36:02 2007 @@ -1,0 +1,113 @@ +<?php +/** + * File containing the ezcGraphPieChartOption class + * + * @package Graph + * @version 1.1 + * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +/** + * Class containing the options for odometer charts + * + * <code> + * $graph = new ezcGraphOdoMeterChart(); + * + * $graph->data['Test'] = new ezcGraphArrayDataSet( array( 0, 1, 23, 30 ) ); + * + * $graph->options->odometerHeight = .3; + * $graph->options->borderColor = '#2e3436'; + * + * $graph->render( 150, 50, 'odometer.svg' ); + * </code> + * + * @property ezcGraphColor $borderColor + * Color of border around odometer chart + * @property int $borderWidth + * Width of border around odometer chart + * @property ezcGraphColor $startColor + * Start color of grdient used as the odometer chart background. + * @property ezcGraphColor $endColor + * End color of grdient used as the odometer chart background. + * @property int $markerWidth + * Width of odometer markers + * @property float $odometerHeight + * Height consumed by odometer chart + * + * @version //autogentag// + * @package Graph + */ +class ezcGraphOdometerChartOptions extends ezcGraphChartOptions +{ + /** + * Constructor + * + * @param array $options Default option array + * @return void + * @ignore + */ + public function __construct( array $options = array() ) + { + $this->properties['borderColor'] = ezcGraphColor::create( '#000000' ); + $this->properties['borderWidth'] = 0; + + $this->properties['startColor'] = ezcGraphColor::create( '#4e9a06A0' ); + $this->properties['endColor'] = ezcGraphColor::create( '#A40000A0' ); + + $this->properties['markerWidth'] = 2; + + $this->properties['odometerHeight'] = 0.5; + + parent::__construct( $options ); + } + + /** + * Set an option value + * + * @param string $propertyName + * @param mixed $propertyValue + * @throws ezcBasePropertyNotFoundException + * If a property is not defined in this class + * @return void + * @ignore + */ + public function __set( $propertyName, $propertyValue ) + { + switch ( $propertyName ) + { + case 'borderWidth': + case 'markerWidth': + if ( !is_numeric( $propertyValue ) || + ( $propertyValue < 1 ) ) + { + throw new ezcBaseValueException( $propertyName, $propertyValue, 'int >= 1' ); + } + + $this->properties[$propertyName] = (int) $propertyValue; + break; + + case 'borderColor': + case 'startColor': + case 'endColor': + $this->properties[$propertyName] = ezcGraphColor::create( $propertyValue ); + break; + + case 'odometerHeight': + if ( !is_numeric( $propertyValue ) || + ( $propertyValue < 0 ) || + ( $propertyValue > 1 ) ) + { + throw new ezcBaseValueException( $propertyName, $propertyValue, '0 <= float <= 1' ); + } + + $this->properties[$propertyName] = (float) $propertyValue; + break; + + default: + return parent::__set( $propertyName, $propertyValue ); + } + } +} + +?> Propchange: trunk/Graph/src/options/odometer_chart.php ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/Graph/src/renderer/2d.php ============================================================================== --- trunk/Graph/src/renderer/2d.php [iso-8859-1] (original) +++ trunk/Graph/src/renderer/2d.php [iso-8859-1] Wed Nov 21 12:36:02 2007 @@ -60,8 +60,7 @@ extends ezcGraphRenderer implements - ezcGraphRadarRenderer, - ezcGraphStackedBarsRenderer + ezcGraphRadarRenderer, ezcGraphStackedBarsRenderer, ezcGraphOdometerRenderer { /** @@ -1430,42 +1429,52 @@ if ( $this->xAxisSpace && $this->yAxisSpace ) { - foreach ( $this->axisLabels as $nr => $axisLabel ) - { - $start = $axisLabel['start']; - $end = $axisLabel['end']; - - $direction = new ezcGraphVector( - $end->x - $start->x, - $end->y - $start->y - ); - $direction->unify(); - - // Convert elipse to circle for correct angle calculation - $direction->y *= ( $this->xAxisSpace / $this->yAxisSpace ); - $angle = $direction->angle( new ezcGraphVector( 0, 1 ) ); - - $movement = new ezcGraphVector( - sin( $angle ) * $this->xAxisSpace * ( $direction->x < 0 ? -1 : 1 ), - cos( $angle ) * $this->yAxisSpace - ); - - $start->x += $movement->x; - $start->y += $movement->y; - $end->x -= $movement->x; - $end->y -= $movement->y; - - $axisLabel['object']->renderLabels( - $this, - $axisLabel['boundings'], - $start, - $end, - $axisLabel['axis'] - ); - - // Prevent from redrawing axis on more then 2 axis. - unset( $this->axisLabels[$nr] ); - } + $this->drawAxisLabels(); + } + } + + /** + * Draw all left axis labels + * + * @return void + */ + protected function drawAxisLabels() + { + foreach ( $this->axisLabels as $nr => $axisLabel ) + { + $start = $axisLabel['start']; + $end = $axisLabel['end']; + + $direction = new ezcGraphVector( + $end->x - $start->x, + $end->y - $start->y + ); + $direction->unify(); + + // Convert elipse to circle for correct angle calculation + $direction->y *= ( $this->xAxisSpace / $this->yAxisSpace ); + $angle = $direction->angle( new ezcGraphVector( 0, 1 ) ); + + $movement = new ezcGraphVector( + sin( $angle ) * $this->xAxisSpace * ( $direction->x < 0 ? -1 : 1 ), + cos( $angle ) * $this->yAxisSpace + ); + + $start->x += $movement->x; + $start->y += $movement->y; + $end->x -= $movement->x; + $end->y -= $movement->y; + + $axisLabel['object']->renderLabels( + $this, + $axisLabel['boundings'], + $start, + $end, + $axisLabel['axis'] + ); + + // Prevent from redrawing axis on more then 2 axis. + unset( $this->axisLabels[$nr] ); } } @@ -1584,6 +1593,88 @@ return true; } + + + /** + * Render odometer chart + * + * @param ezcGraphBoundings $boundings + * @param ezcGraphOdometerChartOptions $options + * @return ezcGraphBoundings + */ + public function drawOdometer( + ezcGraphBoundings $boundings, + ezcGraphChartElementAxis $axis, + ezcGraphOdometerChartOptions $options ) + { + $height = $boundings->height * $options->odometerHeight; + + // Draw axis + $oldAxisSpace = $axis->axisSpace; + $axis->axisSpace = 0; + + $axis->render( $this, $boundings ); + + // Reset axisspaces to correct values + $this->xAxisSpace = $boundings->width * $oldAxisSpace; + $this->yAxisSpace = ( $boundings->height - $height ) / 2; + + $this->drawAxisLabels(); + + // Reduce size of chart boundings respecting requested odometer height + $boundings->x0 += $this->xAxisSpace; + $boundings->x1 -= $this->xAxisSpace; + $boundings->y0 += $this->yAxisSpace; + $boundings->y1 -= $this->yAxisSpace; + + $gradient = new ezcGraphLinearGradient( + new ezcGraphCoordinate( $boundings->x0, $boundings->y0 ), + new ezcGraphCoordinate( $boundings->x1, $boundings->y0 ), + $options->startColor, + $options->endColor + ); + + // Simply draw box with gradient and optional border + $this->drawBox( + $boundings, + $gradient, + $options->borderColor, + $options->borderWidth + ); + + // Return modified chart boundings + return $boundings; + } + + /** + * 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 ) + { + $this->driver->drawLine( + new ezcGraphCoordinate( + $xPos = $boundings->x0 + ( $position->x * $boundings->width ), + $boundings->y0 + ), + new ezcGraphCoordinate( + $xPos, + $boundings->y1 + ), + $color, + $width + ); + } } ?> Added: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometer.svg ============================================================================== Binary file - no diff available. Propchange: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometer.svg ------------------------------------------------------------------------------ svn:eol-style = native Propchange: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometer.svg ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerToOutput.svg ============================================================================== Binary file - no diff available. Propchange: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerToOutput.svg ------------------------------------------------------------------------------ svn:eol-style = native Propchange: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerToOutput.svg ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerWithDifferentOptions.svg ============================================================================== Binary file - no diff available. Propchange: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerWithDifferentOptions.svg ------------------------------------------------------------------------------ svn:eol-style = native Propchange: trunk/Graph/tests/data/compare/ezcGraphOdometerChartTest_testRenderCompleteOdometerWithDifferentOptions.svg ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components