Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

GraphViz.php

00001 <?php
00002 //
00003 // +----------------------------------------------------------------------+
00004 // | PEAR :: Image :: GraphViz                                            |
00005 // +----------------------------------------------------------------------+
00006 // | Copyright (c) 2002 Sebastian Bergmann <sb@sebastian-bergmann.de> and |
00007 // |                    Dr. Volker Göbbels <vmg@arachnion.de>.            |
00008 // +----------------------------------------------------------------------+
00009 // | This source file is subject to version 3.00 of the PHP License,      |
00010 // | that is available at http://www.php.net/license/3_0.txt.             |
00011 // | If you did not receive a copy of the PHP license and are unable to   |
00012 // | obtain it through the world-wide-web, please send a note to          |
00013 // | license@php.net so we can mail you a copy immediately.               |
00014 // +----------------------------------------------------------------------+
00015 //
00016 // $Id: GraphViz.php,v 1.7 2004/01/25 02:12:37 halon Exp $
00017 //
00018 
00057 class Process_GraphViz {
00063     var $dotCommand = 'dot';
00064     
00065     var $pid;
00066 
00072     var $neatoCommand = 'neato';
00073 
00079     var $graph;
00080 
00088     function Process_GraphViz($directed = true, $attributes = array()) {
00089         $this->setDirected($directed);
00090         $this->setAttributes($attributes);
00091         if (defined('GRAPHVIZ_BIN_DIR') && GRAPHVIZ_BIN_DIR) {
00092             $this->dotCommand = GRAPHVIZ_BIN_DIR.'/'.$this->dotCommand;
00093             $this->neatoCommand = GRAPHVIZ_BIN_DIR.'/'.$this->neatoCommand;
00094         }
00095     }
00096     
00097     function set_pid($pid) 
00098     {
00099       $this->pid = $pid;
00100     }
00101 
00109     function image($format = 'png') {
00110         if ($file = $this->saveParsedGraph()) {
00111             $outputfile = $file . '.' . $format;
00112             $outputfile2 = $file . '.' . 'map';
00113             $command  = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
00114             $command .= " -T$format -o$outputfile $file";
00115 
00116             @`$command`;
00117             $command = $this->dotCommand;
00118             $command.= " -Tcmap -o$outputfile2 $file";
00119             @`$command`;
00120             $fr = fopen($outputfile2,"r");
00121             $map = fread($fr,filesize($outputfile2));
00122             fclose($fr);
00123             @unlink($file);
00124 
00125             switch ($format) {
00126                 case 'gif':
00127                 case 'jpg':
00128                 case 'png':
00129                 case 'svg':
00130                 case 'wbmp': {
00131                     header('Content-Type: image/' . $format);
00132                 }
00133                 break;
00134 
00135                 case 'pdf': {
00136                     header('Content-Type: application/pdf');
00137                 }
00138                 break;
00139             }
00140 
00141             header('Content-Length: ' . filesize($outputfile));
00142 
00143             $fp = fopen($outputfile, 'rb');
00144 
00145             if ($fp) {
00146                 echo fread($fp, filesize($outputfile));
00147                 fclose($fp);
00148                 @unlink($outputfile);
00149             }
00150             @unlink($outputfile2);
00151             return $map;
00152         }
00153     }
00154     
00155     function image_and_map($format = 'png') {
00156         if ($file = $this->saveParsedGraph()) {
00157             $outputfile = $file . '.' . $format;
00158             $outputfile2 = $file . '.' . 'map';
00159             if(!isset($this->graph['directed'])) $this->graph['directed']=true;
00160             $command  = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
00161             $command .= " -T$format -o $outputfile $file";
00162             @`$command`;
00163 
00164             $command = $this->dotCommand;
00165             $command.= " -Tcmap -o $outputfile2 $file";
00166             @`$command`;
00167             @unlink($file);
00168             return true;
00169         }
00170     }
00171 
00172     
00173     function map() {
00174         if ($file = $this->saveParsedGraph()) {
00175             $outputfile2 = $file . '.' . 'map';
00176 
00177             $command = $this->dotCommand;
00178             $command.= " -Tcmap -o$outputfile2 $file";
00179             @`$command`;
00180             $fr = fopen($outputfile2,"r");
00181             $map = fread($fr,filesize($outputfile2));
00182             fclose($fr);
00183 
00184             //@unlink($outputfile2);
00185             @unlink($file);
00186             return $map;
00187         }
00188     }
00189 
00197     function addCluster($id, $title) {
00198         $this->graph['clusters'][$id] = $title;
00199     }
00200 
00209     function addNode($name, $attributes = array(), $group = 'default') {
00210         $this->graph['nodes'][$group][$name] = $attributes;
00211     }
00212 
00219     function removeNode($name, $group = 'default') {
00220         if (isset($this->graph['nodes'][$group][$name])) {
00221             unset($this->graph['nodes'][$group][$name]);
00222         }
00223     }
00224 
00232     function addEdge($edge, $attributes = array()) {
00233         if (is_array($edge)) {
00234             $from = key($edge);
00235             $to   = $edge[$from];
00236             $id   = $from . '_' . $to;
00237 
00238             if (!isset($this->graph['edges'][$id])) {
00239                 $this->graph['edges'][$id] = $edge;
00240             } else {
00241                 $this->graph['edges'][$id] = array_merge(
00242                   $this->graph['edges'][$id],
00243                   $edge
00244                 );
00245             }
00246 
00247             if (is_array($attributes)) {
00248                 if (!isset($this->graph['edgeAttributes'][$id])) {
00249                     $this->graph['edgeAttributes'][$id] = $attributes;
00250                 } else {
00251                     $this->graph['edgeAttributes'][$id] = array_merge(
00252                       $this->graph['edgeAttributes'][$id],
00253                       $attributes
00254                     );
00255                 }
00256             }
00257         }
00258     }
00259 
00266     function removeEdge($edge) {
00267         if (is_array($edge)) {
00268               $from = key($edge);
00269               $to   = $edge[$from];
00270               $id   = $from . '_' . $to;
00271 
00272             if (isset($this->graph['edges'][$id])) {
00273                 unset($this->graph['edges'][$id]);
00274             }
00275 
00276             if (isset($this->graph['edgeAttributes'][$id])) {
00277                 unset($this->graph['edgeAttributes'][$id]);
00278             }
00279         }
00280     }
00281 
00288     function addAttributes($attributes) {
00289         if (is_array($attributes)) {
00290             $this->graph['attributes'] = array_merge(
00291               $this->graph['attributes'],
00292               $attributes
00293             );
00294         }
00295     }
00296 
00303     function setAttributes($attributes) {
00304         if (is_array($attributes)) {
00305             $this->graph['attributes'] = $attributes;
00306         }
00307     }
00308 
00315     function setDirected($directed) {
00316         if (is_bool($directed)) {
00317             $this->graph['directed'] = $directed;
00318         }
00319     }
00320 
00327     function load($file) {
00328         if ($serialized_graph = implode('', @file($file))) {
00329             $this->graph = unserialize($serialized_graph);
00330         }
00331     }
00332 
00340     function save($file = '') {
00341         $serialized_graph = serialize($this->graph);
00342 
00343         if (empty($file)) {
00344             $file = tempnam('temp', 'graph_');
00345         }
00346 
00347         if ($fp = @fopen($file, 'w')) {
00348             @fputs($fp, $serialized_graph);
00349             @fclose($fp);
00350 
00351             return $file;
00352         }
00353 
00354         return false;
00355     }
00356 
00363     function parse() {
00364         $parsedGraph = "digraph G {\n";
00365 
00366         if (isset($this->graph['attributes'])) {
00367             foreach ($this->graph['attributes'] as $key => $value) {
00368                 $attributeList[] = $key . '="' . $value . '"';
00369             }
00370 
00371             if (!empty($attributeList)) {
00372               $parsedGraph .= implode(',', $attributeList) . ";\n";
00373             }
00374         }
00375 
00376         if (isset($this->graph['nodes'])) {
00377             foreach($this->graph['nodes'] as $group => $nodes) {
00378                 if ($group != 'default') {
00379                   $parsedGraph .= sprintf(
00380                     "subgraph \"cluster_%s\" {\nlabel=\"%s\";\n",
00381 
00382                     $group,
00383                     isset($this->graph['clusters'][$group]) ? $this->graph['clusters'][$group] : ''
00384                   );
00385                 }
00386 
00387                 foreach($nodes as $node => $attributes) {
00388                     unset($attributeList);
00389 
00390                     foreach($attributes as $key => $value) {
00391                         $attributeList[] = $key . '="' . $value . '"';
00392                     }
00393 
00394                     if (!empty($attributeList)) {
00395                         $parsedGraph .= sprintf(
00396                           "\"%s\" [ %s ];\n",
00397                           addslashes(stripslashes($node)),
00398                           implode(',', $attributeList)
00399                         );
00400                     }
00401                 }
00402 
00403                 if ($group != 'default') {
00404                   $parsedGraph .= "}\n";
00405                 }
00406             }
00407         }
00408 
00409         if (isset($this->graph['edges'])) {
00410             foreach($this->graph['edges'] as $label => $node) {
00411                 unset($attributeList);
00412 
00413                 $from = key($node);
00414                 $to   = $node[$from];
00415 
00416                 foreach($this->graph['edgeAttributes'][$label] as $key => $value) {
00417                     $attributeList[] = $key . '="' . $value . '"';
00418                 }
00419 
00420                 $parsedGraph .= sprintf(
00421                   '"%s" -> "%s"',
00422                   addslashes(stripslashes($from)),
00423                   addslashes(stripslashes($to))
00424                 );
00425                 
00426                 if (!empty($attributeList)) {
00427                     $parsedGraph .= sprintf(
00428                       ' [ %s ]',
00429                       implode(',', $attributeList)
00430                     );
00431                 }
00432 
00433                 $parsedGraph .= ";\n";
00434             }
00435         }
00436 
00437         return $parsedGraph . "}\n";
00438     }
00439 
00448     function saveParsedGraph($file = '') {
00449         $parsedGraph = $this->parse();
00450         if (!empty($parsedGraph)) {
00451             $file = GALAXIA_PROCESSES.'/'.$this->pid.'/graph/'.$this->pid;
00452 
00453             if ($fp = @fopen($file, 'w')) {
00454                 @fputs($fp, $parsedGraph, strlen($parsedGraph));
00455                 @fclose($fp);
00456 
00457                 return $file;
00458             }
00459         }
00460 
00461         return false;
00462     }
00463 }
00464 ?>

Generated on Mon Jun 7 16:37:37 2004 for Galaxia by doxygen 1.3.4