diff options
author | Kore Nordmann <github@kore-nordmann.de> | 2006-06-28 13:23:00 +0000 |
---|---|---|
committer | Kore Nordmann <github@kore-nordmann.de> | 2006-06-28 13:23:00 +0000 |
commit | 6ed7f3a9b1814879c8fed5f55db1ae409797f76c (patch) | |
tree | f69295bc766e04744f43a8811574c69836049dc0 | |
parent | d6bae028524a0fc548080d7b8ae1d8fa38102248 (diff) | |
download | zetacomponents-graph-6ed7f3a9b1814879c8fed5f55db1ae409797f76c.zip zetacomponents-graph-6ed7f3a9b1814879c8fed5f55db1ae409797f76c.tar.gz |
- Added SVG driver
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | src/driver/gd.php | 4 | ||||
-rw-r--r-- | src/driver/svg.php | 445 | ||||
-rw-r--r-- | src/graph_autoload.php | 2 | ||||
-rw-r--r-- | src/interfaces/chart.php | 2 | ||||
-rw-r--r-- | src/options/svg_driver.php | 10 | ||||
-rw-r--r-- | tests/driver_svg_test.php | 974 | ||||
-rw-r--r-- | tests/suite.php | 2 |
8 files changed, 1432 insertions, 10 deletions
@@ -4,12 +4,11 @@ Alpha: - Fix scaling of background image - Make hilight a function - Tresh hold for pie charts - - Array access for chart datasets - Find reason for offset in big charts Next steps: - 3D-Renderer - - SVG-Driver + - Enhance font configuration with magic - Return datapoinnt positions for imagemap and / or adding additional information with div overlays - TextElement to add copyright info etc. diff --git a/src/driver/gd.php b/src/driver/gd.php index 6aa43f3..922469d 100644 --- a/src/driver/gd.php +++ b/src/driver/gd.php @@ -448,13 +448,13 @@ class ezcGraphGdDriver extends ezcGraphDriver $center->x + ( ( cos( deg2rad( $startAngle ) ) * $width ) / 2 ), $center->y + - ( ( sin( deg2rad( $startAngle ) ) * $height + $size ) / 2 ) + ( ( sin( deg2rad( $startAngle ) ) * $height ) / 2 ) + $size ), new ezcGraphCoordinate( $center->x + ( ( cos( deg2rad( $endAngle ) ) * $width ) / 2 ), $center->y + - ( ( sin( deg2rad( $endAngle ) ) * $height + $size ) / 2 ) + ( ( sin( deg2rad( $endAngle ) ) * $height ) / 2 ) + $size ), new ezcGraphCoordinate( $center->x + diff --git a/src/driver/svg.php b/src/driver/svg.php index 90574a5..4beae78 100644 --- a/src/driver/svg.php +++ b/src/driver/svg.php @@ -13,12 +13,69 @@ * @package Graph */ -class ezcGraphSVGDriver extends ezcGraphDriver +class ezcGraphSvgDriver extends ezcGraphDriver { + /** + * DOM tree of the svg document + * + * @var DOMDocument + */ + protected $dom; + + /** + * DOMElement containing all svg style definitions + * + * @var DOMElement + */ + protected $defs; + + /** + * DOMElement containing all svg objects + * + * @var DOMElement + */ + protected $elements; + + /** + * List of strings to draw + * array ( array( + * 'text' => array( 'strings' ), + * 'options' => ezcGraphFontOptions, + * ) + * + * @var array + */ + protected $strings = array(); + public function __construct( array $options = array() ) { $this->options = new ezcGraphSvgDriverOptions( $options ); + + } + + protected function createDocument() + { + if ( $this->dom === null ) + { + $this->dom = new DOMDocument(); + $svg = $this->dom->createElement( 'svg' ); + + $svg->setAttribute( 'xmlns', 'http://www.w3.org/2000/svg' ); + $svg->setAttribute( 'xmlns:xlink', 'http://www.w3.org/1999/xlink' ); + $svg->setAttribute( 'width', $this->options->width ); + $svg->setAttribute( 'height', $this->options->height ); + $svg->setAttribute( 'version', '1.0' ); + $svg->setAttribute( 'id', 'ezcGraph' ); + $this->dom->appendChild( $svg ); + + $this->defs = $this->dom->createElement( 'defs' ); + $this->defs = $svg->appendChild( $this->defs ); + + $this->elements = $this->dom->createElement( 'g' ); + $this->elements->setAttribute( 'id', 'chart' ); + $this->elements = $svg->appendChild( $this->elements ); + } } /** @@ -31,7 +88,53 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function drawPolygon( array $points, ezcGraphColor $color, $filled = true, $thickness = 1 ) { - + $this->createDocument(); + + $lastPoint = end( $points ); + $pointString = sprintf( ' M %.4f,%.4f', + $lastPoint->x, + $lastPoint->y + ); + + foreach ( $points as $point ) + { + $pointString .= sprintf( ' L %.4f,%.4f', + $point->x, + $point->y + ); + } + $pointString .= ' z '; + + $path = $this->dom->createElement( 'path' ); + $path->setAttribute( 'd', $pointString ); + + if ( $filled ) + { + $path->setAttribute( + 'style', + sprintf( 'fill: #%02x%02x%02x; fill-opacity: %.2f; stroke: none;', + $color->red, + $color->green, + $color->blue, + 1 - ( $color->alpha / 255 ) + ) + ); + } + else + { + $path->setAttribute( + 'style', + sprintf( 'fill: none; stroke: #%02x%02x%02x; stroke-width: %d; stroke-opacity: %.2f;', + $color->red, + $color->green, + $color->blue, + $thickness, + 1 - ( $color->alpha / 255 ) + ) + ); + } + + $this->elements->appendChild( $path ); } /** @@ -44,7 +147,83 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function drawLine( ezcGraphCoordinate $start, ezcGraphCoordinate $end, ezcGraphColor $color, $thickness = 1 ) { + $this->createDocument(); + + $pointString = sprintf( ' M %.4f,%.4f L %.4f,%.4f', + $start->x, + $start->y, + $end->x, + $end->y + ); + + $path = $this->dom->createElement( 'path' ); + $path->setAttribute( 'd', $pointString ); + $path->setAttribute( + 'style', + sprintf( 'fill: none; stroke: #%02x%02x%02x; stroke-width: %d; stroke-opacity: %.2f;', + $color->red, + $color->green, + $color->blue, + $thickness, + 1 - ( $color->alpha / 255 ) + ) + ); + + $this->elements->appendChild( $path ); + } + + protected function testFitStringInTextBox( $string, ezcGraphCoordinate $position, $width, $height, $size ) + { + // Tokenize String + $tokens = preg_split( '/\s+/', $string ); + $lines = array( array() ); + $line = 0; + foreach ( $tokens as $token ) + { + // Add token to tested line + $selectedLine = $lines[$line]; + $selectedLine[] = $token; + + // Assume characters have the same width as height + $strWidth = $size * strlen( implode( ' ', $selectedLine ) ) * $this->options->assumedCharacterWidth; + + // Check if line is too long + if ( $strWidth > $width ) + { + if ( count( $selectedLine ) == 1 ) + { + // Return false if one single word does not fit into one line + return false; + } + else + { + // Put word in next line instead and reduce available height by used space + $lines[++$line][] = $token; + $height -= $size * ( 1 + $this->options->lineSpacing ); + } + } + else + { + // Everything is ok - put token in this line + $lines[$line][] = $token; + } + + // Return false if text exceeds vertical limit + if ( $size > $height ) + { + return false; + } + } + + // Check width of last line + $strWidth = $size * strlen( implode( ' ', $selectedLine ) ) * $this->options->assumedCharacterWidth; + if ( $strWidth > $width ) { + return false; + } + + // It seems to fit - return line array + return $lines; } /** @@ -59,7 +238,107 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function drawTextBox( $string, ezcGraphCoordinate $position, $width, $height, $align ) { - + // Try to get a font size for the text to fit into the box + $maxSize = min( $height, $this->options->font->maxFontSize ); + $result = false; + for ( $size = $maxSize; $size >= $this->options->font->minFontSize; --$size ) + { + $result = $this->testFitStringInTextBox( $string, $position, $width, $height, $size ); + if ( $result !== false ) + { + break; + } + } + + if ( is_array( $result ) ) + { + $this->options->font->minimalUsedFont = $size; + + $this->strings[] = array( + 'text' => $result, + 'position' => $position, + 'width' => $width, + 'height' => $height, + 'align' => $align, + 'options' => $this->options->font, + ); + } + } + + protected function drawAllTexts() + { + foreach ( $this->strings as $text ) + { + $size = $text['options']->minimalUsedFont; + $font = $text['options']->font; + + $completeHeight = count( $text['text'] ) * $size + ( count( $text['text'] ) - 1 ) * $this->options->lineSpacing; + + // Calculate y offset for vertical alignement + switch ( true ) + { + case ( $text['align'] & ezcGraph::BOTTOM ): + $yOffset = $text['height'] - $completeHeight; + break; + case ( $text['align'] & ezcGraph::MIDDLE ): + $yOffset = ( $text['height'] - $completeHeight ) / 2; + break; + case ( $text['align'] & ezcGraph::TOP ): + default: + $yOffset = 0; + break; + } + + // Render text with evaluated font size + foreach ( $text['text'] as $line ) + { + $string = implode( ' ', $line ); + $boundings = imagettfbbox( $size, 0, $font, $string ); + $text['position']->y += $size; + + switch ( true ) + { + case ( $text['align'] & ezcGraph::LEFT ): + $position = new ezcGraphCoordinate( + $text['position']->x, + $text['position']->y + $yOffset + ); + break; + case ( $text['align'] & ezcGraph::RIGHT ): + $position = new ezcGraphCoordinate( + $text['position']->x + ( $text['width'] - $size * strlen( $string ) * $this->options->assumedCharacterWidth ), + $text['position']->y + $yOffset + ); + break; + case ( $text['align'] & ezcGraph::CENTER ): + $position = new ezcGraphCoordinate( + $text['position']->x + ( ( $text['width'] - $size * strlen( $string ) * $this->options->assumedCharacterWidth ) / 2 ), + $text['position']->y + $yOffset + ); + break; + } + + $textNode = $this->dom->createElement( 'text', $string ); + $textNode->setAttribute( 'x', $position->x ); + $textNode->setAttribute( 'text-length', ( $size * strlen( $string ) * $this->options->assumedCharacterWidth ) . 'px' ); + $textNode->setAttribute( 'y', $position->y ); + $textNode->setAttribute( + 'style', + sprintf( + 'font-size: %dpx; font-family: sans-serif; fill: #%02x%02x%02x; fill-opacity: %.2f; stroke: none;', + $size, + $text['options']->color->red, + $text['options']->color->green, + $text['options']->color->blue, + 1 - ( $text['options']->color->alpha / 255 ) + ) + ); + + $this->elements->appendChild( $textNode ); + + $text['position']->y += $size * $this->options->lineSpacing; + } + } } /** @@ -75,7 +354,67 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function drawCircleSector( ezcGraphCoordinate $center, $width, $height, $startAngle, $endAngle, ezcGraphColor $color, $filled = true ) { + $this->createDocument(); + + // Normalize angles + if ( $startAngle > $endAngle ) + { + $tmp = $startAngle; + $startAngle = $endAngle; + $endAngle = $tmp; + } + // We need the radius + $width /= 2; + $height /= 2; + + $Xstart = $center->x + $width * cos( ( -$startAngle / 180 ) * M_PI ); + $Ystart = $center->y + $height * sin( ( $startAngle / 180 ) * M_PI ); + $Xend = $center->x + $width * cos( ( -( $endAngle ) / 180 ) * M_PI ); + $Yend = $center->y + $height * sin( ( ( $endAngle ) / 180 ) * M_PI ); + + $arc = $this->dom->createElement( 'path' ); + $arc->setAttribute('d', sprintf('M %.2f,%.2f L %.2f,%.2f A %.2f,%2f 0 %d,1 %.2f,%.2f z', + // Middle + $center->x, $center->y, + // Startpoint + $Xstart, $Ystart, + // Radius + $width, $height, + // SVG-Stuff + ( $endAngle - $startAngle ) > 180, + // Endpoint + $Xend, $Yend + ) + ); + + if ( $filled ) + { + $arc->setAttribute( + 'style', + sprintf( 'fill: #%02x%02x%02x; fill-opacity: %.2f; stroke: none;', + $color->red, + $color->green, + $color->blue, + 1 - ( $color->alpha / 255 ) + ) + ); + } + else + { + $arc->setAttribute( + 'style', + sprintf( 'fill: none; stroke: #%02x%02x%02x; stroke-width: %d; stroke-opacity: %.2f;', + $color->red, + $color->green, + $color->blue, + 1, // Line Thickness + 1 - ( $color->alpha / 255 ) + ) + ); + } + + $this->elements->appendChild( $arc ); } /** @@ -92,7 +431,60 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function drawCircularArc( ezcGraphCoordinate $center, $width, $height, $size, $startAngle, $endAngle, ezcGraphColor $color ) { + $this->createDocument(); + + // Normalize angles + if ( $startAngle > $endAngle ) + { + $tmp = $startAngle; + $startAngle = $endAngle; + $endAngle = $tmp; + } + // We need the radius + $width /= 2; + $height /= 2; + + $Xstart = $center->x + $width * cos( ( -$startAngle / 180 ) * M_PI ); + $Ystart = $center->y + $height * sin( ( $startAngle / 180 ) * M_PI ); + $Xend = $center->x + $width * cos( ( -( $endAngle ) / 180 ) * M_PI ); + $Yend = $center->y + $height * sin( ( ( $endAngle ) / 180 ) * M_PI ); + + $arc = $this->dom->createElement( 'path' ); + $arc->setAttribute('d', sprintf(' M %.2f,%.2f + A %.2f,%2f 0 %d,0 %.2f,%.2f + L %.2f,%.2f + A %.2f,%2f 0 %d,1 %.2f,%.2f z', + // Endpoint low + $Xend, $Yend + $size, + // Radius + $width, $height, + // SVG-Stuff + ( $endAngle - $startAngle ) > 180, + // Startpoint low + $Xstart, $Ystart + $size, + // Startpoint + $Xstart, $Ystart, + // Radius + $width, $height, + // SVG-Stuff + ( $endAngle - $startAngle ) > 180, + // Endpoint + $Xend, $Yend + ) + ); + + $arc->setAttribute( + 'style', + sprintf( 'fill: #%02x%02x%02x; fill-opacity: %.2f; stroke: none;', + $color->red, + $color->green, + $color->blue, + 1 - ( $color->alpha / 255 ) + ) + ); + + $this->elements->appendChild( $arc ); } /** @@ -108,7 +500,41 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function drawCircle( ezcGraphCoordinate $center, $width, $height, ezcGraphColor $color, $filled = true ) { + $this->createDocument(); + $ellipse = $this->dom->createElement('ellipse'); + $ellipse->setAttribute( 'cx', $center->x ); + $ellipse->setAttribute( 'cy', $center->y ); + $ellipse->setAttribute( 'rx', $width / 2 ); + $ellipse->setAttribute( 'ry', $height / 2 ); + + if ( $filled ) + { + $ellipse->setAttribute( + 'style', + sprintf( 'fill: #%02x%02x%02x; fill-opacity: %.2f; stroke: none;', + $color->red, + $color->green, + $color->blue, + 1 - ( $color->alpha / 255 ) + ) + ); + } + else + { + $ellipse->setAttribute( + 'style', + sprintf( 'fill: none; stroke: #%02x%02x%02x; stroke-width: %d; stroke-opacity: %.2f;', + $color->red, + $color->green, + $color->blue, + 1, // Line Thickness + 1 - ( $color->alpha / 255 ) + ) + ); + } + + $this->elements->appendChild( $ellipse ); } /** @@ -122,7 +548,16 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function drawImage( $file, ezcGraphCoordinate $position, $width, $height ) { + $this->createDocument(); + $image = $this->dom->createElement( 'image' ); + $image->setAttribute( 'x', $position->x ); + $image->setAttribute( 'y', $position->y ); + $image->setAttribute( 'width', $width . 'px' ); + $image->setAttribute( 'height', $height . 'px' ); + $image->setAttribute( 'xlink:href', $file ); + + $this->elements->appendChild( $image ); } /** @@ -133,7 +568,9 @@ class ezcGraphSVGDriver extends ezcGraphDriver */ public function render ( $file ) { - + $this->createDocument(); + $this->drawAllTexts(); + $this->dom->save( $file ); } } diff --git a/src/graph_autoload.php b/src/graph_autoload.php index 912f18a..349a02a 100644 --- a/src/graph_autoload.php +++ b/src/graph_autoload.php @@ -36,7 +36,7 @@ return array( 'ezcGraphGdDriverOptions' => 'Graph/options/gd_driver.php', 'ezcGraphGdDriverInvalidFontException' => 'Graph/exceptions/invalid_font.php', 'ezcGraphGdDriverUnsupportedImageTypeException' => 'Graph/exceptions/unsupported_image_type.php', - 'ezcGraphSVGDriver' => 'Graph/driver/svg.php', + 'ezcGraphSvgDriver' => 'Graph/driver/svg.php', 'ezcGraphSvgDriverOptions' => 'Graph/options/svg_driver.php', 'ezcGraphInvalidDriverException' => 'Graph/exceptions/invalid_driver.php', diff --git a/src/interfaces/chart.php b/src/interfaces/chart.php index 6cc1e8c..18e1849 100644 --- a/src/interfaces/chart.php +++ b/src/interfaces/chart.php @@ -78,7 +78,7 @@ abstract class ezcGraphChart implements ArrayAccess $this->elements['legend']->position = ezcGraph::LEFT; // Define standard renderer and driver - $this->driver = new ezcGraphSVGDriver(); + $this->driver = new ezcGraphSvgDriver(); $this->renderer = new ezcGraphRenderer2D(); $this->renderer->setDriver( $this->driver ); } diff --git a/src/options/svg_driver.php b/src/options/svg_driver.php index 27e362b..b07664e 100644 --- a/src/options/svg_driver.php +++ b/src/options/svg_driver.php @@ -16,6 +16,13 @@ class ezcGraphSvgDriverOptions extends ezcGraphDriverOptions { /** + * Assumed percentual average width of chars with the used font + * + * @var float + */ + protected $assumedCharacterWidth = .55; + + /** * Set an option value * * @param string $propertyName @@ -28,6 +35,9 @@ class ezcGraphSvgDriverOptions extends ezcGraphDriverOptions { switch ( $propertyName ) { + case 'assumedCharacterWidth': + $this->assumedCharacterWidth = min( 1, max( 0, (float) $propertyValue ) ); + break; default: parent::__set( $propertyName, $propertyValue ); break; diff --git a/tests/driver_svg_test.php b/tests/driver_svg_test.php new file mode 100644 index 0000000..00c1ed4 --- /dev/null +++ b/tests/driver_svg_test.php @@ -0,0 +1,974 @@ +<?php +/** + * ezcGraphSvgDriverTest + * + * @package Graph + * @version //autogen// + * @subpackage Tests + * @copyright Copyright (C) 2005, 2006 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +/** + * Tests for ezcGraph class. + * + * @package ImageAnalysis + * @subpackage Tests + */ +class ezcGraphSvgDriverTest extends ezcTestCase +{ + + protected $driver; + + protected $tempDir; + + protected $basePath; + + protected $testFiles = array( + 'jpeg' => 'jpeg.jpg', + 'png' => 'png.png', + ); + + public static function suite() + { + return new ezcTestSuite( "ezcGraphSvgDriverTest" ); + } + + /** + * setUp + * + * @access public + */ + public function setUp() + { + static $i = 0; + $this->tempDir = $this->createTempDir( __CLASS__ . sprintf( '_%03d_', ++$i ) ) . '/'; + $this->basePath = dirname( __FILE__ ) . '/data/'; + + $this->driver = new ezcGraphSvgDriver(); + $this->driver->options->width = 200; + $this->driver->options->height = 100; + $this->driver->options->font->font = $this->basePath . 'font.ttf'; + } + + /** + * tearDown + * + * @access public + */ + public function tearDown() + { + unset( $this->driver ); + $this->removeTempDir(); + } + + public function testDrawLine() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawLine( + new ezcGraphCoordinate( 12, 45 ), + new ezcGraphCoordinate( 134, 12 ), + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '9688d589680400999be566227dbe9c29', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawPolygonThreePointsFilled() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 45, 12 ), + new ezcGraphCoordinate( 122, 34 ), + new ezcGraphCoordinate( 12, 71 ), + ), + ezcGraphColor::fromHex( '#3465A4' ), + true + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '6a41f0c473bbe30915e695bd91b7d6a6', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawPolygonThreePointsNotFilled() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 45, 12 ), + new ezcGraphCoordinate( 122, 34 ), + new ezcGraphCoordinate( 12, 71 ), + ), + ezcGraphColor::fromHex( '#3465A4' ), + false + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '57e1fd8237f9759f56ee5e7ee31a43da', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawPolygonFivePoints() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 45, 12 ), + new ezcGraphCoordinate( 122, 34 ), + new ezcGraphCoordinate( 12, 71 ), + new ezcGraphCoordinate( 3, 45 ), + new ezcGraphCoordinate( 60, 32 ), + ), + ezcGraphColor::fromHex( '#3465A4' ), + true + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'c69c00899b27d6805e4a4e632ec5bdd1', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircleSectorAcute() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircleSector( + new ezcGraphCoordinate( 100, 50 ), + 80, + 40, + 12.5, + 25, + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '89480548f0f4ad16fa2b62ed8a1b405d', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircleSectorAcuteNonFilled() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircleSector( + new ezcGraphCoordinate( 100, 50 ), + 80, + 40, + 12.5, + 45, + ezcGraphColor::fromHex( '#3465A4' ), + false + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'f00974c80a296ea96667e97d8a593d20', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircleSectorAcuteReverse() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircleSector( + new ezcGraphCoordinate( 100, 50 ), + 80, + 40, + 25, + 12.5, + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '89480548f0f4ad16fa2b62ed8a1b405d', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircleSectorObtuse() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircleSector( + new ezcGraphCoordinate( 100, 50 ), + 80, + 40, + 25, + 273, + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'c96a934640494f4e5003eb2782bd387d', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircularArcAcute() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircularArc( + new ezcGraphCoordinate( 100, 50 ), + 150, + 80, + 10, + 12.5, + 55, + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'aecde1739b7672b092038132d11a14d7', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircularArcAcuteReverse() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircularArc( + new ezcGraphCoordinate( 100, 50 ), + 150, + 80, + 10, + 55, + 12.5, + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'aecde1739b7672b092038132d11a14d7', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircularArcObtuse() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircularArc( + new ezcGraphCoordinate( 100, 50 ), + 150, + 80, + 10, + 25, + 300, + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '9ff612c20a94890d1a29c9dae7a13fed', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircleFilled() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircle( + new ezcGraphCoordinate( 100, 50 ), + 80, + 40, + ezcGraphColor::fromHex( '#3465A4' ) + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'b0601d6c18f937f64b1dc2da6f402459', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawCircleNonFilled() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawCircle( + new ezcGraphCoordinate( 100, 50 ), + 80, + 40, + ezcGraphColor::fromHex( '#3465A4' ), + false + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '501214a894f024d6efea307f51dda85b', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawImageJpeg() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawImage( + $this->basePath . $this->testFiles['jpeg'], + new ezcGraphCoordinate( 10, 10 ), + 100, + 50 + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '827ab338a7919bbc5e0e45ddeb517854', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawImagePng() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawImage( + $this->basePath . $this->testFiles['png'], + new ezcGraphCoordinate( 10, 10 ), + 100, + 50 + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'c22c66d4137b36e8bc80a6ed80361d70', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxShortString() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'Short', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::LEFT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'c9deeb042648025df8a07aeafc14597f', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxLongString() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'ThisIsAPrettyLongString', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::LEFT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '32bf93e9173859c287fac43367af03e0', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxLongSpacedString() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'This Is A Pretty Long String', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::LEFT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '808caa0b01a73fd7a4fe7fb139543f48', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxManualBreak() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + "New\nLine", + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::LEFT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '99d9d57e9c8ed9f993201be063f3a103', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxStringSampleRight() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 20, 20 ), + new ezcGraphCoordinate( 110, 20 ), + new ezcGraphCoordinate( 110, 30 ), + new ezcGraphCoordinate( 20, 30 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'sample 4', + new ezcGraphCoordinate( 21, 21 ), + 88, + 8, + ezcGraph::RIGHT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'f20714a112bf26d9f2bcc237024a3fc0', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxStringRight() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'ThisIsAPrettyLongString', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::RIGHT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '566f6da9a6caa44d66b9e8a9ddd440c0', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxLongSpacedStringRight() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'This Is A Pretty Long String', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::RIGHT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'df370e94a8954fa4df90c883acbc40a5', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxStringCenter() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'ThisIsAPrettyLongString', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::CENTER + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'f366d4f787105c526254055a50e3efe8', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxLongSpacedStringCenter() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'This Is A Pretty Long String', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::CENTER + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '3d6129e9c6ef35c1308e289297720a44', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxStringRightBottom() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'ThisIsAPrettyLongString', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::RIGHT | ezcGraph::BOTTOM + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '232aa98c989cb534d25b44b725c977b8', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxLongSpacedStringRightMiddle() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'This Is A Pretty Long String', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::RIGHT | ezcGraph::MIDDLE + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '4b470dcfcc9f386ae47a856cd0c3249b', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxStringCenterMiddle() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'ThisIsAPrettyLongString', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::CENTER | ezcGraph::MIDDLE + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'a70d08ade2d9e723edd042e5f6e19f9c', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawTextBoxLongSpacedStringCenterBottom() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 10, 10 ), + new ezcGraphCoordinate( 160, 10 ), + new ezcGraphCoordinate( 160, 80 ), + new ezcGraphCoordinate( 10, 80 ), + ), + ezcGraphColor::fromHex( '#eeeeec' ), + true + ); + $this->driver->drawTextBox( + 'This Is A Pretty Long String', + new ezcGraphCoordinate( 10, 10 ), + 150, + 70, + ezcGraph::CENTER | ezcGraph::BOTTOM + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + '9a8d85f51a8bf29ff22ab80f42f6dc80', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } + + public function testDrawStringWithSpecialChars() + { + $filename = $this->tempDir . __FUNCTION__ . '.svg'; + + $this->driver->drawPolygon( + array( + new ezcGraphCoordinate( 47, 54 ), + new ezcGraphCoordinate( 47, 84 ), + new ezcGraphCoordinate( 99, 84 ), + new ezcGraphCoordinate( 99, 54 ), + ), + ezcGraphColor::fromHex( '#DDDDDD' ), + true + ); + $this->driver->drawTextBox( + 'Safari (13.8%)', + new ezcGraphCoordinate( 47, 54 ), + 52, + 30, + ezcGraph::LEFT + ); + + $this->driver->render( $filename ); + + $this->assertTrue( + file_exists( $filename ), + 'No image was generated.' + ); + + $this->assertEquals( + 'b99c805e3bef27128614220ebde1dc87', + md5_file( $filename ), + 'Incorrect image rendered.' + ); + } +} + +?> diff --git a/tests/suite.php b/tests/suite.php index 0cd4e11..3c924de 100644 --- a/tests/suite.php +++ b/tests/suite.php @@ -28,6 +28,7 @@ require_once 'numeric_axis_test.php'; require_once 'labeled_axis_test.php'; require_once 'renderer_2d_test.php'; require_once 'driver_gd_test.php'; +require_once 'driver_svg_test.php'; require_once 'font_test.php'; require_once 'palette_test.php'; require_once 'background_image_test.php'; @@ -56,6 +57,7 @@ class ezcGraphSuite extends ezcTestSuite $this->addTest( ezcGraphLabeledAxisTest::suite() ); $this->addTest( ezcGraphRenderer2dTest::suite() ); $this->addTest( ezcGraphGdDriverTest::suite() ); + $this->addTest( ezcGraphSvgDriverTest::suite() ); $this->addTest( ezcGraphFontTest::suite() ); $this->addTest( ezcGraphTextTest::suite() ); $this->addTest( ezcGraphPaletteTest::suite() ); |