[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 // 3 // +----------------------------------------------------------------------+ 4 // | PEAR :: Image :: GraphViz | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 2002 Sebastian Bergmann <sb@sebastian-bergmann.de> and | 7 // | Dr. Volker Göbbels <vmg@arachnion.de>. | 8 // +----------------------------------------------------------------------+ 9 // | This source file is subject to version 3.00 of the PHP License, | 10 // | that is available at http://www.php.net/license/3_0.txt. | 11 // | If you did not receive a copy of the PHP license and are unable to | 12 // | obtain it through the world-wide-web, please send a note to | 13 // | license@php.net so we can mail you a copy immediately. | 14 // +----------------------------------------------------------------------+ 15 // 16 // $Id: GraphViz.php 18759 2005-07-08 18:54:28Z regis_glc $ 17 // 18 19 /** 20 * PEAR::Image_GraphViz 21 * 22 * Purpose 23 * 24 * Allows for the creation of and the work with directed 25 * and undirected graphs and their visualization with 26 * AT&T's GraphViz tools. These can be found at 27 * http://www.research.att.com/sw/tools/graphviz/ 28 * 29 * Example 30 * 31 * require_once 'Image/GraphViz.php'; 32 * $graph = new Image_GraphViz(); 33 * 34 * $graph->addNode('Node1', array('URL' => 'http://link1', 35 * 'label' => 'This is a label', 36 * 'shape' => 'box' 37 * ) 38 * ); 39 * $graph->addNode('Node2', array('URL' => 'http://link2', 40 * 'fontsize' => '14' 41 * ) 42 * ); 43 * $graph->addNode('Node3', array('URL' => 'http://link3', 44 * 'fontsize' => '20' 45 * ) 46 * ); 47 * 48 * $graph->addEdge(array('Node1' => 'Node2'), array('label' => 'Edge Label')); 49 * $graph->addEdge(array('Node1' => 'Node2'), array('color' => 'red')); 50 * 51 * $graph->image(); 52 * 53 * @author Sebastian Bergmann <sb@sebastian-bergmann.de> 54 * Dr. Volker Göbbels <vmg@arachnion.de> 55 * @package Image 56 */ 57 class Process_GraphViz { 58 /** 59 * Path to GraphViz/dot command 60 * 61 * @var string 62 */ 63 var $dotCommand = 'dot'; 64 65 var $pid; 66 67 /** 68 * Path to GraphViz/neato command 69 * 70 * @var string 71 */ 72 var $neatoCommand = 'neato'; 73 74 /** 75 * Representation of the graph 76 * 77 * @var array 78 */ 79 var $graph; 80 81 /** 82 * Constructor 83 * 84 * @param boolean Directed (true) or undirected (false) graph. 85 * @param array Attributes of the graph 86 * @access public 87 */ 88 function Process_GraphViz($directed = true, $attributes = array()) { 89 $this->setDirected($directed); 90 $this->setAttributes($attributes); 91 if (defined('GRAPHVIZ_BIN_DIR') && GRAPHVIZ_BIN_DIR) { 92 $this->dotCommand = GRAPHVIZ_BIN_DIR.'/'.$this->dotCommand; 93 $this->neatoCommand = GRAPHVIZ_BIN_DIR.'/'.$this->neatoCommand; 94 } 95 } 96 97 function set_pid($pid) 98 { 99 $this->pid = $pid; 100 } 101 102 /** 103 * Output image of the graph in a given format. 104 * 105 * @param string Format of the output image. 106 * This may be one of the formats supported by GraphViz. 107 * @access public 108 */ 109 function image($format = 'png') { 110 if ($file = $this->saveParsedGraph()) { 111 $outputfile = $file . '.' . $format; 112 $outputfile2 = $file . '.' . 'map'; 113 $command = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand; 114 $command .= " -T$format -o$outputfile $file"; 115 116 @`$command`; 117 $command = $this->dotCommand; 118 $command.= " -Tcmap -o$outputfile2 $file"; 119 @`$command`; 120 $fr = fopen($outputfile2,"r"); 121 $map = fread($fr,filesize($outputfile2)); 122 fclose($fr); 123 @unlink($file); 124 125 switch ($format) { 126 case 'gif': 127 case 'jpg': 128 case 'png': 129 case 'svg': 130 case 'wbmp': { 131 header('Content-Type: image/' . $format); 132 } 133 break; 134 135 case 'pdf': { 136 header('Content-Type: application/pdf'); 137 } 138 break; 139 } 140 141 header('Content-Length: ' . filesize($outputfile)); 142 143 $fp = fopen($outputfile, 'rb'); 144 145 if ($fp) { 146 echo fread($fp, filesize($outputfile)); 147 fclose($fp); 148 @unlink($outputfile); 149 } 150 @unlink($outputfile2); 151 return $map; 152 } 153 } 154 155 function image_and_map($format = 'png') { 156 if ($file = $this->saveParsedGraph()) { 157 $outputfile = $file . '.' . $format; 158 $outputfile2 = $file . '.' . 'map'; 159 if(!isset($this->graph['directed'])) $this->graph['directed']=true; 160 $command = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand; 161 $command .= " -T$format -o $outputfile $file"; 162 @`$command`; 163 164 $command = $this->dotCommand; 165 $command.= " -Tcmap -o $outputfile2 $file"; 166 @`$command`; 167 @unlink($file); 168 return true; 169 } 170 } 171 172 173 function map() { 174 if ($file = $this->saveParsedGraph()) { 175 176 $outputfile2 = $file . '.' . 'map'; 177 178 $command = $this->dotCommand; 179 $command.= " -Tcmap -o$outputfile2 $file"; 180 @`$command`; 181 $fr = fopen($outputfile2,"r"); 182 $map = fread($fr,filesize($outputfile2)); 183 fclose($fr); 184 185 @unlink($outputfile2); 186 @unlink($file); 187 return $map; 188 } 189 } 190 191 /** 192 * Add a cluster to the graph. 193 * 194 * @param string ID. 195 * @param array Title. 196 * @access public 197 */ 198 function addCluster($id, $title) { 199 $this->graph['clusters'][$id] = $title; 200 } 201 202 /** 203 * Add a note to the graph. 204 * 205 * @param string Name of the node. 206 * @param array Attributes of the node. 207 * @param string Group of the node. 208 * @access public 209 */ 210 function addNode($name, $attributes = array(), $group = 'default') { 211 $this->graph['nodes'][$group][$name] = $attributes; 212 } 213 214 /** 215 * Remove a node from the graph. 216 * 217 * @param Name of the node to be removed. 218 * @access public 219 */ 220 function removeNode($name, $group = 'default') { 221 if (isset($this->graph['nodes'][$group][$name])) { 222 unset($this->graph['nodes'][$group][$name]); 223 } 224 } 225 226 /** 227 * Add an edge to the graph. 228 * 229 * @param array Start and End node of the edge. 230 * @param array Attributes of the edge. 231 * @access public 232 */ 233 function addEdge($edge, $attributes = array()) { 234 if (is_array($edge)) { 235 $from = key($edge); 236 $to = $edge[$from]; 237 $id = $from . '_' . $to; 238 239 if (!isset($this->graph['edges'][$id])) { 240 $this->graph['edges'][$id] = $edge; 241 } else { 242 $this->graph['edges'][$id] = array_merge( 243 $this->graph['edges'][$id], 244 $edge 245 ); 246 } 247 248 if (is_array($attributes)) { 249 if (!isset($this->graph['edgeAttributes'][$id])) { 250 $this->graph['edgeAttributes'][$id] = $attributes; 251 } else { 252 $this->graph['edgeAttributes'][$id] = array_merge( 253 $this->graph['edgeAttributes'][$id], 254 $attributes 255 ); 256 } 257 } 258 } 259 } 260 261 /** 262 * Remove an edge from the graph. 263 * 264 * @param array Start and End node of the edge to be removed. 265 * @access public 266 */ 267 function removeEdge($edge) { 268 if (is_array($edge)) { 269 $from = key($edge); 270 $to = $edge[$from]; 271 $id = $from . '_' . $to; 272 273 if (isset($this->graph['edges'][$id])) { 274 unset($this->graph['edges'][$id]); 275 } 276 277 if (isset($this->graph['edgeAttributes'][$id])) { 278 unset($this->graph['edgeAttributes'][$id]); 279 } 280 } 281 } 282 283 /** 284 * Add attributes to the graph. 285 * 286 * @param array Attributes to be added to the graph. 287 * @access public 288 */ 289 function addAttributes($attributes) { 290 if (is_array($attributes)) { 291 $this->graph['attributes'] = array_merge( 292 $this->graph['attributes'], 293 $attributes 294 ); 295 } 296 } 297 298 /** 299 * Set attributes of the graph. 300 * 301 * @param array Attributes to be set for the graph. 302 * @access public 303 */ 304 function setAttributes($attributes) { 305 if (is_array($attributes)) { 306 $this->graph['attributes'] = $attributes; 307 } 308 } 309 310 /** 311 * Set directed/undirected flag for the graph. 312 * 313 * @param boolean Directed (true) or undirected (false) graph. 314 * @access public 315 */ 316 function setDirected($directed) { 317 if (is_bool($directed)) { 318 $this->graph['directed'] = $directed; 319 } 320 } 321 322 /** 323 * Load graph from file. 324 * 325 * @param string File to load graph from. 326 * @access public 327 */ 328 function load($file) { 329 if ($serialized_graph = implode('', @file($file))) { 330 $this->graph = unserialize($serialized_graph); 331 } 332 } 333 334 /** 335 * Save graph to file. 336 * 337 * @param string File to save the graph to. 338 * @return mixed File the graph was saved to, false on failure. 339 * @access public 340 */ 341 function save($file = '') { 342 $serialized_graph = serialize($this->graph); 343 344 if (empty($file)) { 345 $file = tempnam('temp', 'graph_'); 346 } 347 348 if ($fp = @fopen($file, 'w')) { 349 @fputs($fp, $serialized_graph); 350 @fclose($fp); 351 352 return $file; 353 } 354 355 return false; 356 } 357 358 /** 359 * Parse the graph into GraphViz markup. 360 * 361 * @return string GraphViz markup 362 * @access public 363 */ 364 function parse() { 365 $parsedGraph = "digraph G {\n"; 366 367 if (isset($this->graph['attributes'])) { 368 foreach ($this->graph['attributes'] as $key => $value) { 369 $attributeList[] = $key . '="' . $value . '"'; 370 } 371 372 if (!empty($attributeList)) { 373 $parsedGraph .= implode(',', $attributeList) . ";\n"; 374 } 375 } 376 377 if (isset($this->graph['nodes'])) { 378 foreach($this->graph['nodes'] as $group => $nodes) { 379 if ($group != 'default') { 380 $parsedGraph .= sprintf( 381 "subgraph \"cluster_%s\" {\nlabel=\"%s\";\n", 382 383 $group, 384 isset($this->graph['clusters'][$group]) ? $this->graph['clusters'][$group] : '' 385 ); 386 } 387 388 foreach($nodes as $node => $attributes) { 389 unset($attributeList); 390 391 foreach($attributes as $key => $value) { 392 $attributeList[] = $key . '="' . $value . '"'; 393 } 394 395 if (!empty($attributeList)) { 396 $parsedGraph .= sprintf( 397 "\"%s\" [ %s ];\n", 398 addslashes(stripslashes($node)), 399 implode(',', $attributeList) 400 ); 401 } 402 } 403 404 if ($group != 'default') { 405 $parsedGraph .= "}\n"; 406 } 407 } 408 } 409 410 if (isset($this->graph['edges'])) { 411 foreach($this->graph['edges'] as $label => $node) { 412 unset($attributeList); 413 414 $from = key($node); 415 $to = $node[$from]; 416 417 foreach($this->graph['edgeAttributes'][$label] as $key => $value) { 418 $attributeList[] = $key . '="' . $value . '"'; 419 } 420 421 $parsedGraph .= sprintf( 422 '"%s" -> "%s"', 423 addslashes(stripslashes($from)), 424 addslashes(stripslashes($to)) 425 ); 426 427 if (!empty($attributeList)) { 428 $parsedGraph .= sprintf( 429 ' [ %s ]', 430 implode(',', $attributeList) 431 ); 432 } 433 434 $parsedGraph .= ";\n"; 435 } 436 } 437 438 return $parsedGraph . "}\n"; 439 } 440 441 /** 442 * Save GraphViz markup to file. 443 * 444 * @param string File to write the GraphViz markup to. 445 * @return mixed File to which the GraphViz markup was 446 * written, false on failure. 447 * @access public 448 */ 449 function saveParsedGraph($file = '') { 450 $parsedGraph = $this->parse(); 451 if (!empty($parsedGraph)) { 452 453 $file = GALAXIA_PROCESSES.'/'.$this->pid.'/graph/'.$this->pid; 454 if ($fp = @fopen($file, 'w')) { 455 @fputs($fp, $parsedGraph); 456 @fclose($fp); 457 458 return $file; 459 } 460 } 461 462 return false; 463 } 464 } 465 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |