Browse files

Patches by Karsten Dambekalns <k.dambekalns@fishfarm.de>

git-svn-id: http://svn.php.net/repository/pear/packages/Image_GraphViz/trunk@174058 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information...
1 parent 1e0ccb6 commit 7c6c0096a8c88d091cc34acaec22c3d07cd33254 @sebastianbergmann sebastianbergmann committed Dec 4, 2004
Showing with 171 additions and 92 deletions.
  1. +144 −68 GraphViz.php
  2. +27 −24 package.xml
View
212 GraphViz.php
@@ -19,43 +19,72 @@
require_once 'System.php';
/**
-* PEAR::Image_GraphViz
-*
-* Purpose
-*
-* Allows for the creation of and the work with directed
-* and undirected graphs and their visualization with
-* AT&T's GraphViz tools. These can be found at
-* http://www.research.att.com/sw/tools/graphviz/
-*
-* Example
-*
-* require_once 'Image/GraphViz.php';
-* $graph = new Image_GraphViz();
-*
-* $graph->addNode('Node1', array('URL' => 'http://link1',
-* 'label' => 'This is a label',
-* 'shape' => 'box'
-* )
-* );
-* $graph->addNode('Node2', array('URL' => 'http://link2',
-* 'fontsize' => '14'
-* )
-* );
-* $graph->addNode('Node3', array('URL' => 'http://link3',
-* 'fontsize' => '20'
-* )
-* );
-*
-* $graph->addEdge(array('Node1' => 'Node2'), array('label' => 'Edge Label'));
-* $graph->addEdge(array('Node1' => 'Node2'), array('color' => 'red'));
-*
-* $graph->image();
-*
-* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
-* Dr. Volker Göbbels <vmg@arachnion.de>
-* @package Image
-*/
+ * Interface to AT&T's GraphViz tools.
+ *
+ * The GraphViz class allows for the creation of and the work with directed
+ * and undirected graphs and their visualization with AT&T's GraphViz tools.
+ *
+ * <code>
+ * <?php
+ * require_once 'Image/GraphViz.php';
+ *
+ * $graph = new Image_GraphViz();
+ *
+ * $graph->addNode(
+ * 'Node1',
+ * array(
+ * 'URL' => 'http://link1',
+ * 'label' => 'This is a label',
+ * 'shape' => 'box'
+ * )
+ * );
+ *
+ * $graph->addNode(
+ * 'Node2',
+ * array(
+ * 'URL' => 'http://link2',
+ * 'fontsize' => '14'
+ * )
+ * );
+ *
+ * $graph->addNode(
+ * 'Node3',
+ * array(
+ * 'URL' => 'http://link3',
+ * 'fontsize' => '20'
+ * )
+ * );
+ *
+ * $graph->addEdge(
+ * array(
+ * 'Node1' => 'Node2'
+ * ),
+ * array(
+ * 'label' => 'Edge Label'
+ * )
+ * );
+ *
+ * $graph->addEdge(
+ * array(
+ * 'Node1' => 'Node2'
+ * ),
+ * array(
+ * 'color' => 'red'
+ * )
+ * );
+ *
+ * $graph->image();
+ * ?>
+ * </code>
+ *
+ * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @author Dr. Volker Göbbels <vmg@arachnion.de>
+ * @author Karsten Dambekalns <k.dambekalns@fishfarm.de>
+ * @copyright Copyright &copy; 2002-2004 Sebastian Bergmann <sb@sebastian-bergmann.de> and Dr. Volker Göbbels <vmg@arachnion.de>
+ * @license http://www.php.net/license/3_0.txt The PHP License, Version 3.0
+ * @category Image
+ * @package Image_GraphViz
+ */
class Image_GraphViz {
/**
* Path to GraphViz/dot command
@@ -79,15 +108,20 @@ class Image_GraphViz {
var $graph;
/**
- * Constructor
+ * Constructor.
*
- * @param boolean Directed (true) or undirected (false) graph.
- * @param array Attributes of the graph
+ * Setting the name of the Graph is useful for including multiple image maps on
+ * one page. If not set, the graph will be named 'G'.
+ *
+ * @param boolean $directed Directed (TRUE) or undirected (FALSE) graph.
+ * @param array $attributes Attributes of the graph
+ * @param string $name Name of the Graph
* @access public
*/
- function Image_GraphViz($directed = true, $attributes = array()) {
+ function Image_GraphViz($directed = TRUE, $attributes = array(), $name = NULL) {
$this->setDirected($directed);
$this->setAttributes($attributes);
+ $this->graph['name'] = $name;
}
/**
@@ -98,15 +132,8 @@ function Image_GraphViz($directed = true, $attributes = array()) {
* @access public
*/
function image($format = 'svg') {
- if ($file = $this->saveParsedGraph()) {
- $outputfile = $file . '.' . $format;
- $command = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
- $command .= " -T$format -o$outputfile $file";
-
- @`$command`;
- @unlink($file);
-
- $sendContentLengthHeader = true;
+ if ($data = $this->fetch($format)) {
+ $sendContentLengthHeader = TRUE;
switch ($format) {
case 'gif':
@@ -132,33 +159,61 @@ function image($format = 'svg') {
break;
default: {
- $sendContentLengthHeader = false;
+ $sendContentLengthHeader = FALSE;
}
}
if ($sendContentLengthHeader) {
- header('Content-Length: ' . filesize($outputfile));
+ header('Content-Length: ' . strlen($data));
}
- $fp = fopen($outputfile, 'rb');
+ echo $data;
+ }
+ }
+ /**
+ * Return image (data) of the graph in a given format.
+ *
+ * @param string Format of the output image.
+ * This may be one of the formats supported by GraphViz.
+ * @return string The image (data) created by GraphViz.
+ * @access public
+ * @since 1.1.0
+ */
+ function fetch($format = 'svg') {
+ if ($file = $this->saveParsedGraph()) {
+ $outputfile = $file . '.' . $format;
+ $command = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
+ $command .= " -T$format -o$outputfile $file";
+
+ @`$command`;
+ @unlink($file);
+
+ $fp = fopen($outputfile, 'rb');
+
if ($fp) {
- echo fread($fp, filesize($outputfile));
+ $data = fread($fp, filesize($outputfile));
fclose($fp);
@unlink($outputfile);
}
+
+ return $data;
}
+
+ return FALSE;
}
/**
* Add a cluster to the graph.
*
* @param string ID.
* @param array Title.
+ * @param array Attributes of the cluster.
* @access public
*/
- function addCluster($id, $title) {
- $this->graph['clusters'][$id] = $title;
+ function addCluster($id, $title, $attributes = array()) {
+ $this->graph['clusters'][$id]['title'] = $title;
+ $this->graph['clusters'][$id]['attributes'] = $attributes;
}
/**
@@ -188,6 +243,11 @@ function removeNode($name, $group = 'default') {
/**
* Add an edge to the graph.
*
+ * Caveat! This cannot handle multiple identical edges. If you use non-numeric
+ * IDs for the nodes, this will not do (too much) harm. For numeric IDs the
+ * array_merge() that is used will change the keys when merging arrays, leading
+ * to new nodes appearing in the graph.
+ *
* @param array Start and End node of the edge.
* @param array Attributes of the edge.
* @access public
@@ -272,7 +332,7 @@ function setAttributes($attributes) {
/**
* Set directed/undirected flag for the graph.
*
- * @param boolean Directed (true) or undirected (false) graph.
+ * @param boolean Directed (TRUE) or undirected (FALSE) graph.
* @access public
*/
function setDirected($directed) {
@@ -297,7 +357,7 @@ function load($file) {
* Save graph to file.
*
* @param string File to save the graph to.
- * @return mixed File the graph was saved to, false on failure.
+ * @return mixed File the graph was saved to, FALSE on failure.
* @access public
*/
function save($file = '') {
@@ -314,7 +374,7 @@ function save($file = '') {
return $file;
}
- return false;
+ return FALSE;
}
/**
@@ -324,27 +384,43 @@ function save($file = '') {
* @access public
*/
function parse() {
- $parsedGraph = "digraph G {\n";
+ if (isset($this->graph['name']) && is_string($this->graph['name'])) {
+ $parsedGraph = "digraph " . $this->graph['name'] . " {\n";
+ } else {
+ $parsedGraph = "digraph G {\n";
+ }
if (isset($this->graph['attributes'])) {
foreach ($this->graph['attributes'] as $key => $value) {
$attributeList[] = $key . '="' . $value . '"';
}
if (!empty($attributeList)) {
- $parsedGraph .= implode(',', $attributeList) . ";\n";
+ $parsedGraph .= 'graph [ '.implode(',', $attributeList) . " ];\n";
}
}
if (isset($this->graph['nodes'])) {
foreach($this->graph['nodes'] as $group => $nodes) {
if ($group != 'default') {
- $parsedGraph .= sprintf(
- "subgraph \"cluster_%s\" {\nlabel=\"%s\";\n",
+ $parsedGraph .= sprintf(
+ "subgraph \"cluster_%s\" {\nlabel=\"%s\";\n",
+
+ $group,
+ isset($this->graph['clusters'][$group]) ? $this->graph['clusters'][$group]['title'] : ''
+ );
+
+ if (isset($this->graph['clusters'][$group]['attributes'])) {
+ unset($attributeList);
- $group,
- isset($this->graph['clusters'][$group]) ? $this->graph['clusters'][$group] : ''
- );
+ foreach ($this->graph['clusters'][$group]['attributes'] as $key => $value) {
+ $attributeList[] = $key . '="' . $value . '"';
+ }
+
+ if (!empty($attributeList)) {
+ $parsedGraph .= implode(',', $attributeList) . ";\n";
+ }
+ }
}
foreach($nodes as $node => $attributes) {
@@ -405,7 +481,7 @@ function parse() {
*
* @param string File to write the GraphViz markup to.
* @return mixed File to which the GraphViz markup was
- * written, false on failure.
+ * written, FALSE on failure.
* @access public
*/
function saveParsedGraph($file = '') {
@@ -424,7 +500,7 @@ function saveParsedGraph($file = '') {
}
}
- return false;
+ return FALSE;
}
}
?>
View
51 package.xml
@@ -3,13 +3,7 @@
<package version="1.0">
<name>Image_GraphViz</name>
<summary><![CDATA[Interface to AT&T's GraphViz tools]]></summary>
- <description>
- <![CDATA[
- The GraphViz class allows for the creation of and the work with
- directed and undirected graphs and their visualization with
- AT&T's GraphViz tools.
- ]]>
- </description>
+ <description><![CDATA[The GraphViz class allows for the creation of and the work with directed and undirected graphs and their visualization with AT&T's GraphViz tools.]]></description>
<maintainers>
<maintainer>
<user>sebastian</user>
@@ -19,12 +13,18 @@
</maintainers>
<license>PHP License</license>
<release>
- <version>1.0.3</version>
- <date>2004-02-25</date>
+ <version>1.1.0</version>
+ <date>200Y-MM-DD</date>
<state>stable</state>
<notes>
<![CDATA[
-* Fixed bugs #109 and #852.
++ Added fetch() method that returns the generated image.
+
++ Added support for named graphs.
+
++ Added support for cluster attributes.
+
+* Fixed a bug with graph attributes.
]]>
</notes>
<filelist>
@@ -35,15 +35,24 @@
</release>
<changelog>
<release>
+ <version>1.0.3</version>
+ <date>2004-02-25</date>
+ <state>stable</state>
+ <notes>
+<![CDATA[
+* Fixed bugs #109 and #852.
+]]>
+ </notes>
+ </release>
+ <release>
<version>1.0.2</version>
<date>2004-02-20</date>
<state>stable</state>
<notes>
<![CDATA[
* Fixed Content-Type header for SVG images.
-* Improved temporary file creation by using
- System::mktemp() instead of tempnam().
+* Improved temporary file creation by using System::mktemp() instead of tempnam().
]]>
</notes>
</release>
@@ -53,11 +62,9 @@
<state>stable</state>
<notes>
<![CDATA[
-+ Nodes can be grouped now by passing a group name as 3rd parameter
- to the addNode() method.
++ Nodes can be grouped now by passing a group name as 3rd parameter to the addNode() method.
-+ The new addCluster() method can be used to give a label to a
- group of nodes and let GraphViz treat it as a node cluster.
++ The new addCluster() method can be used to give a label to a group of nodes and let GraphViz treat it as a node cluster.
]]>
</notes>
</release>
@@ -77,8 +84,7 @@
<state>stable</state>
<notes>
<![CDATA[
-* Send correct Content-Type in image() header depending on
- generated format.
+* Send correct Content-Type in image() header depending on generated format.
* Renamed methods to conform with PEAR standard.
]]>
@@ -90,8 +96,7 @@
<state>stable</state>
<notes>
<![CDATA[
-* Allow for edges without attributes.
- (Patch by Carsten Saathoff <kodemaniak@gmx.de>)
+* Allow for edges without attributes. (Patch by Carsten Saathoff <kodemaniak@gmx.de>)
]]>
</notes>
</release>
@@ -100,11 +105,9 @@
<date>2002-04-06</date>
<notes>
<![CDATA[
-* Added escaping of node descriptions.
- (Patch by Garvin Hicking <hicking@faktor-e.de>)
+* Added escaping of node descriptions. (Patch by Garvin Hicking <hicking@faktor-e.de>)
-* Improved compatibility with Win32 version of dot/neato.
- (Patch by Garvin Hicking <hicking@faktor-e.de>)
+* Improved compatibility with Win32 version of dot/neato. (Patch by Garvin Hicking <hicking@faktor-e.de>)
* Changed Image_GraphViz.php to Image/GraphViz.php.
]]>

0 comments on commit 7c6c009

Please sign in to comment.