summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--src/driver/gd.php4
-rw-r--r--src/driver/svg.php445
-rw-r--r--src/graph_autoload.php2
-rw-r--r--src/interfaces/chart.php2
-rw-r--r--src/options/svg_driver.php10
-rw-r--r--tests/driver_svg_test.php974
-rw-r--r--tests/suite.php2
8 files changed, 1432 insertions, 10 deletions
diff --git a/TODO b/TODO
index 1d95ed1..4cf33b9 100644
--- a/TODO
+++ b/TODO
@@ -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() );
OpenPOWER on IntegriCloud