Extension talk:GraphViz/v0.9

New "improved improved" version of the GraphViz-Extension
Dear Users of the GraphViz-Extension,

I am a student assistant at the FZI, a German research center. We're using the Graphviz-Extension(s) for some of our own projects.

Actually the problem is that it is not that easy to use a GraphViz Extension, because there are many different versions and improvements circulating around on mediawiki.org: some for windows and others for linux, some work out of the box and others don't, some support different renderers and others have automatic clean-up. I think you know what I mean.

So I'm currently combining the various GraphViz Extensions into one functional and up to date Extension. This means that I try to get the best out of each extension and I think that the result is a very good "improved improved" GraphViz-Extension.

My question is now if you'd mind if I was refreshing the Extension-Page (Extension:GraphViz) on MediaWiki as well. I'd like to clean up the old parts and the Discussion-Page so that there is space for some instructions.

If this is a problem, I will create another "Graphviz"-Extension, but I think that this would not help to get rid of the current chaos.

You can have a look at my current code and the corresponding page here: User:Hummel-riegel/GraphViz

Of course I'll try to name all the actual and previous contributors like the FDL/GPL-Licences specify. And as this is a wiki feel free to add some stuff if you want to.

Thanks for your response in advance, Yours sincerely

Thomas Hummel    --Hummel-riegel 13:28, 1 November 2010 (UTC)

Does this work on MW 1.12+?
If anyone has gotten this working on MW 1.12+, please post. I've tried nearly everything (the original Graphviz.php, the 'updated' one, and various combinations of the fixes supplied on this page) and MW1.13.2 never processes the element. I also tried the newest Graphviz 2.20, and the oldest one I could find (1.14). This is on windows. For paths I have tried backslash, two backslashes, and forward slash, as well as pointing at the Graphviz in Program Files or copying it to the wiki extensions directory. I'm inclined to believe this won't work on newer wikis.

Hi, i'm running graphviz under windows with MW 1.13.4. without problems. I use the latest graphviz extension and also the latest dot. --Ozz 09:50, 10 February 2009 (UTC)

I realized this was due to a change in how plugins are 'activated' in recent MW's. The documentation says 1.12+ but I found the old way worked on 1.12.0 but not 1.13.2. Here is my final working version for Windows (based off the updated plugin):

dotCommand *   Describes where your actual dot executable remains. * *    Windows Default: C:/Programme/ATT/Graphviz/bin/dot.exe *   Other Platform : /usr/local/bin/dot * *  $wgGraphVizSettings->named *   Describes the way graph-files are named. * *    named: name of your graph and its type determine its filename *   md5  : name of your graph is based on a md5 hash of its source. *   sha1 : name of your graph is based on a SHA1 hash of its source. * *    Default : named * *  $wgGraphVizSettings->install *   Gets you an errormessage if something fails, but maybe ruins your *   wiki's look. This message is in English, always. * *    Default : false * * Improvements * - Selects defaults for Windows or Unix-like automatically. * - should runs out of the box * - Creates PNG + MAP File * - additional storage modes (see discussion below) *  - Meaningful filename *  - Hash based filename *  - Configurable (name/md5/sha1) * * Storage Modes: * MD5: * + don't worry about graphnames * + pretty fast hash * - permanent cleanup necesary (manually or scripted) * - md5 is buggy - possibility that 2 graphs have the same hash but *  are not the same * SHA1: * + don't worry about graphnames * + no hash-bug as md5 * - permanent cleanup necessary (manually or scripted) * - not so fast as md5 * Named: * + Graphs have a name, now it's used * + no permanent cleanup necessary. * - Naming Conflicts *  a) if you have multiple graphs of the same name in the same  *      article, you will only get 1 picture - independently if they're  *            the same or not.  *   b) possible naming conflicts in obscure cases (that should not happen) *     Read code for possibilities / exploits *  */ class GraphVizSettings { public $dotCommand, $named, $install; }; $wgGraphVizSettings = new GraphVizSettings; // Config // -- if ( ! (stristr (PHP_OS, 'WIN' ) === FALSE) ) { $wgGraphVizSettings->dotCommand = 'C:/Program Files/Graphviz2.20/bin/dot'; } else { $wgGraphVizSettings->dotCommand = '/usr/local/bin/dot'; } $wgGraphVizSettings->named = 'named'; $wgGraphVizSettings->install = false; // Media Wiki Plugin Stuff // --- //$wgExtensionFunctions[] = "wfGraphVizExtension"; if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) { $wgHooks['ParserFirstCallInit'][] = 'wfGraphVizExtension'; } else { // Otherwise do things the old fashioned way $wgExtensionFunctions[] = 'wfGraphVizExtension'; } $wgExtensionCredits['parserhook'][] = array(  'name'=&gt;'Graphviz',   'author'=&gt;'CoffMan &lt;http://wickle.com&gt;, MasterOfDesaster &lt;mailto://arno.venner@gmail.com&gt;',   'url'=&gt; 'http://www.mediawiki.org/wiki/Extension:GraphViz',   'description'=&gt;'Graphviz (http://www.graphviz.org) is a program/language that allows the creation of numerous types of graphs.  This extension allows the embedding of graphviz markup in MediaWiki pages and generates inline images to display.',   'version'=&gt;'0.4' ); function wfGraphVizExtension { global $wgParser; $wgParser->setHook( "graphviz", "renderGraphviz" ); return true; } function renderGraphviz( $timelinesrc, $params, &$parser )     // Raw Script data {      global $wgUploadDirectory,     // Storage of the final png & map $wgUploadPath,                 // HTML Reference $wgGraphVizSettings;     // Plugin Config $parser->disableCache; $output = ""; //$output = "&lt;pre&gt;Called render&lt;/pre&gt;"; // Prepare Directories $dest = $wgUploadDirectory."/graphviz/"; if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); } $output .= "&lt;pre&gt;Dir=$dest&lt;/pre&gt;"; $storagename = urldecode($_GET['title']).'---'; $storagename = str_replace("&",'_amp_',$storagename); $storagename = str_replace("#",'_shrp_',$storagename); $storagename = str_replace("/",'_sd_',$storagename); $storagename = str_replace("\\",'_sd_',$storagename); $wgGraphVizSettings->named = strtolower($wgGraphVizSettings->named); $output .= "&lt;pre&gt;dotCommand=".$wgGraphVizSettings->dotCommand ."&lt;/pre&gt;"; $output .= "&lt;pre&gt;named=".$wgGraphVizSettings->named ."&lt;/pre&gt;"; if($wgGraphVizSettings->named == 'md5') { $storagename .= md5($timelinesrc); } else if ($wgGraphVizSettings->named == 'sha1') { $storagename .= sha1($timelinesrc); } else { $storagename .= trim(                  str_replace("\n",'', str_replace("\\",'/',                              substr($timelinesrc, 0, strpos($timelinesrc,'{') ))      )); }      $src = $dest. $storagename; $imgn = $dest. $storagename. '.png'; $mapn = $dest. $storagename. '.map'; $output .= "&lt;pre&gt;Src=$src&lt;/pre&gt;"; if ( $wgGraphVizSettings->named == 'named' || ! ( file_exists( $src.".png" ) || file_exists($src.".err"))) {            $handle = fopen($src, "w"); $ret2 = fwrite($handle, $timelinesrc); $ret3=fclose($handle); $output.="&lt;pre&gt;Opened and closed $src, handle=$handle, timeelinesrc=$timelinesrc, ret2=$ret2, ret3=$ret3&lt;/pre&gt;"; $cmdline   = wfEscapeShellArg($wgGraphVizSettings->dotCommand).' -Tpng   -o '.wfEscapeShellArg($imgn).' '.wfEscapeShellArg($src); $cmdlinemap = wfEscapeShellArg($wgGraphVizSettings->dotCommand).' -Tcmapx -o '.wfEscapeShellArg($mapn).' '.wfEscapeShellArg($src); //$ret = shell_exec($cmdline); $WshShell = new COM("WScript.Shell"); $WshShell->Exec($cmdline); $WshShell->Exec($cmdlinemap); $output.="&lt;pre&gt;Ran cmd line. ret=$ret cmd=$cmdline&lt;/pre&gt;"; if ($wgGraphVizSettings->install && $ret == "" ) { //echo '&lt;div id="toc"&gt;&lt;tt&gt;Timeline error: Executable not found.'. "\n".'Command line was: '.$cmdline.'&lt;/tt&gt;&lt;/div&gt;'; $output.= '&lt;div id="toc"&gt;&lt;tt&gt;Timeline error: Executable not found.'. "\n".'Command line was: '.$cmdline.'&lt;/tt&gt;&lt;/div&gt;'; exit; }            //$ret = shell_exec($cmdlinemap); if ($wgGraphVizSettings->install && $ret == "" ) { echo '&lt;div id="toc"&gt;&lt;tt&gt;Timeline error: Executable not found.'. "\n".'Command line was: '.$cmdlinemap.'&lt;/tt&gt;&lt;/div&gt;'; exit; }            //unlink($src); }      @$err=file_get_contents( $src.".err" ); if ( $err != "" ) { $txt = '&lt;div id="toc"&gt;&lt;tt&gt;'.$err.'&lt;/tt&gt;&lt;/div&gt;'; } else { @$map = file_get_contents( $mapn ); $map = preg_replace('#&lt;ma(.*)&gt;#',' ',$map); $map = str_replace('&lt;/map&gt;','',$map); $txt = '&lt;map name="'.$storagename.'"&gt;'.$map.'&lt;/map&gt;'. '&lt;img src="'.$wgUploadPath.'/graphviz/'.$storagename.'.png"'. ' usemap="#'.$storagename.'" /&gt;'; }      $txt .= $output;//"&lt;pre&gt;MOOOO&lt;/pre&gt;"; return $txt; } ?>

Fix for Darwin
auto-detection fails for Darwin (because it matches "WIN"). Fix:

if ( stristr(PHP_OS, 'WIN' ) && !stristr(PHP_OS, 'Darwin') ) { $wgGraphVizSettings->dotCommand = 'C:/Programme/ATT/Graphviz/bin/dot.exe'; } else { $wgGraphVizSettings->dotCommand = '/usr/local/bin/dot'; }

Problems with mediawiki 1.16 (ubuntu 8.10) - dot command not found
I'm currently using the svn version of mediawiki, which is currently at 1.16. Although I have correctly set the location of dot,I keep getting the error:

Solution: This problem arises only when you set the because it gives and error when dot output is an empty string "", which is exactly the case of a succesful execution. To fix this we must look at the dot command return value rather than its stdout/stderr output.

--Drunken sapo 14:26, 22 June 2009 (UTC)

Do away with serverfiles
I have img_auth.php installed on the wiki, hence could not use this extension directly. Don't really want to touch permissions, so I did as suggested here and embedded the graphviz output inside the response html. Just threw together some code to verify this (missing all the error handling and what not, but works fine on sample graphs); feel free to reuse whatever you see fit as I am definitely still missing much functionality. --Vopap 03:56, 23 September 2009 (UTC)

Display Examples
I tried to display the example graphics that get produced by the examples on this page, but it seemed to just display the text even though I took it out of the 'code' tag. Any reason this would happen? Daviddoria 18:05, 1 November 2009 (UTC)

Bug in extreme fast redrawings
In case of redrawing the same graphic very fastly, the new graphviz call gets stuck. In the process list, the CMD and graphviz call does not get cleaned, because the created file is locked by the previous call.

A work around is to unlink the bare file ($fname) and the $fname.map before opening the handle to $fname: if (file_exists($fname)) unlink($fname); if (file_exists($fname.'.map')) unlink($fname.'.map');

This should solve the issue, but it needs to be tested thoroughly.

Custom Shapes
Is there any trick to getting a custom shape (image) rendered in the graphs? I have uploaded a "stick figure" image to my mediawiki, and can see it if I include the markup in page bodies, but it is not rendered when I include that markup in my graphviz code --srl100 11:18, 14 April 2010 (UTC)

e.g.

graph G { subgraph clusterMain { subgraph clusterActor1 { color=white; label="actor1"; actor1 ; }       system [shape=circle]; actor1 -- system; } }

Update 15 April 2010, by srl100...

It turns out that I needed to include the relative path to the image, in the (hashed) images directory structure.

graph G { subgraph clusterMain { subgraph clusterActor1 { color=white; label="actor1"; actor1 [image="images/a/aa/Stick.png" shape=none label=""]; }       system [shape=circle]; actor1 -- system; } }


 * I think you have to hack this feature into the extension by yourself. Perhaps this can help you on the way: --Danwe 21:39, 16 April 2010 (UTC)

Category pages and graphviz
The extension cannot work on category pages unless you include the following at line 117:

... $storagename = str_replace("\\",'_sd_',$storagename); $storagename = str_replace(":",'_colon_',$storagename); #<-- added... $wgGraphVizSettings->named = strtolower($wgGraphVizSettings->named); ...