Extension talk:GraphViz/v0.9

From mediawiki.org
Latest comment: 10 years ago by Gborgonovo in topic Template inside GraphViz

New "improved improved" version of the GraphViz-Extension[edit]

Dear Users of the GraphViz-Extension,

I am a student assistant at the FZI [1], 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)Reply


Does this work on MW 1.12+?[edit]

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 <graphviz> 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)Reply

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):

 <?php
 /*
  * Extension to allow Graphviz to work inside MediaWiki.
  * This Version is based on CoffMan's nice Graphviz Extension.
  *
  * Licence: http://www.gnu.org/copyleft/fdl.html
  *
  * Configuration
  *
  *  These settings can be overwritten in LocalSettings.php.
  *  Configuration must be done AFTER including this extension using
  *  require("extensions/Graphviz.php");
  *
  *  $wgGraphVizSettings->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'=>'Graphviz',
   'author'=>'CoffMan <http://wickle.com>, MasterOfDesaster <mailto://arno.venner@gmail.com>',
   'url'=> 'http://www.mediawiki.org/wiki/Extension:GraphViz',
   'description'=>'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'=>'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 = "<pre>Called render</pre>";
       
       // Prepare Directories
       $dest = $wgUploadDirectory."/graphviz/";
       if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); }
 
       $output .= "<pre>Dir=$dest</pre>";
       $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 .= "<pre>dotCommand=".$wgGraphVizSettings->dotCommand ."</pre>";
       $output .= "<pre>named=".$wgGraphVizSettings->named ."</pre>";
       
       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 .= "<pre>Src=$src</pre>";
 
       if ( $wgGraphVizSettings->named == 'named' || ! ( file_exists( $src.".png" ) || file_exists($src.".err")))
       {
             $handle = fopen($src, "w");
             $ret2 = fwrite($handle, $timelinesrc);
             $ret3=fclose($handle);
             
             $output.="<pre>Opened and closed $src, handle=$handle, timeelinesrc=$timelinesrc, ret2=$ret2, ret3=$ret3</pre>";
 
             $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.="<pre>Ran cmd line. ret=$ret cmd=$cmdline</pre>";
             
             if ($wgGraphVizSettings->install && $ret == "" ) {
                   //echo '<div id="toc"><tt>Timeline error: Executable not found.'.      "\n".'Command line was: '.$cmdline.'</tt></div>';
                   $output.= '<div id="toc"><tt>Timeline error: Executable not found.'.      "\n".'Command line was: '.$cmdline.'</tt></div>';
                   exit;
             }
 
             //$ret = shell_exec($cmdlinemap);
             if ($wgGraphVizSettings->install && $ret == "" ) {
                   echo '<div id="toc"><tt>Timeline error: Executable not found.'.
                         "\n".'Command line was: '.$cmdlinemap.'</tt></div>';
                   exit;
             }
 
             //unlink($src);
       }
       
       @$err=file_get_contents( $src.".err" ); 
 
       if ( $err != "" ) {
             $txt = '<div id="toc"><tt>'.$err.'</tt></div>';
       } else {
             @$map = file_get_contents( $mapn );
             $map  = preg_replace('#<ma(.*)>#',' ',$map);
             $map  = str_replace('</map>','',$map);
 
             $txt  = '<map name="'.$storagename.'">'.$map.'</map>'.
                     '<img src="'.$wgUploadPath.'/graphviz/'.$storagename.'.png"'.
                               ' usemap="#'.$storagename.'" />';
       }
       $txt .= $output;//"<pre>MOOOO</pre>";
       return $txt;
 }
 ?>

Fix for Darwin[edit]

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[edit]

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: Timeline error: Executable not found. Command line was: '/usr/bin/dot' -Tpng -o 'images/graphviz/Extensions---digraph G.png' 'images/graphviz/Extensions---digraph G' (I will post more info later)

Solution: This problem arises only when you set the $wgGraphVizSettings->install=true 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)Reply

Do away with serverfiles[edit]

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)Reply

Display Examples[edit]

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)Reply

Bug in extreme fast redrawings[edit]

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[edit]

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 [[File:Stick.png]] in page bodies, but it is not rendered when I include that markup in my graphviz code --srl100 11:18, 14 April 2010 (UTC)Reply

e.g.

<graphviz>
graph G {
    subgraph clusterMain {
        subgraph clusterActor1 {
            color=white;
            label="actor1";
            actor1 [image="[[File:Stick.png]]" shape=none label=""];
        }
        system [shape=circle];
        actor1 -- system;
    }
}
</graphviz>

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.

<graphviz>
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;
    }
}
</graphviz>
I think you have to hack this feature into the extension by yourself. Perhaps this can help you on the way: Extension talk:GraphViz/v0.9#local_wiki_URLs --Danwe 21:39, 16 April 2010 (UTC)Reply

Category pages and graphviz[edit]

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);
...

Text inside nodes is pruned[edit]

In the Hello World example (and in other examples too), the text inside the nodes is pruned at the bottom.

I assume it is a problem in GraphViz, but I wonder if anyone has found a workaround?

Yeah I'm having this problem too. Using underscores to get round it atm, but it's not ideal

Install Instructions - path to graphviz[edit]

Using MediaWiki v1.16.2 I got an error while following Installation instructions. I changed line (LocalSettings.php) to

include("$IP/extensions/Graphviz/Graphviz.php");

Also. I was using Ubuntu 10.10 with lampp and pictures in graphviz folder was 0 bytes size. To solve this problem: [2]

What version of MediaWiki is required?[edit]

Hi, what version(s) of MediaWiki is required for this extension? I saw the reference to "The documentation says 1.12+" but can't see any documentation. We are currently on 1.5.3, I'm guessing that is too old?

bugs and filenames[edit]

Hi! I'm Extension:Collaboration Diagram developer, I really impressed by the description of new Graphviz extension and tried to update. However here are some problems that took place on my Debian:

  1. By default the extension does nothing except displaying the message: string(5) . It's caused by the line 293 in the source code.
  2. After fixing that I started to get error messages about too long filenames. The extension uses strange method of naming when - it generates filenames like PAGENAME---GRAPHNAME and replaces all '%' to _perc_ . Sure thing it provoked errors on my Russian wiki, where all letters are replaced to codes after calling urlencode function.
  3. If I set $wgGraphVizSettings->named = 'md5'; I get filenames like PAGENAME---md5(GRAPHNAME)

Idea: why not hashing with md5 or sha1 both PAGENAME and GRAPHNAME? And probably it would be better to set

$wgGraphVizSettings->named = 'md5' 

by default because otherwise it will cause problems on non-English wikis. --Katkov Yury 19:29, 7 June 2011 (UTC)Reply


jeroendedauw has put this into svn. Thanks! (r89857 -Diff) --Hummel-riegel 12:00, 11 June 2011 (UTC)Reply

Problems with SVG[edit]

It doesn't seem that SVG output format work. after settings up the following:

 $wgGraphVizSettings->outputType = "svg";
 $wgGraphVizSettings->info = true; 
 $wgAllowTitlesInSVG = true;  
 $wgSVGConverter = 'ImageMagick';
 $wgFileExtensions[] = 'svg';
 $wgAllowExternalImages = true;

I'm still not able to see the pictures of my graphs, although they have being generated by the extension. Any other SVG files that I upload to the wiki displayed correctly because ImageMagick generates thumbnails for them.

So for commonly uploaded SVGs on a page the following html is produced:

<a href="/colldia/index.php/%D0%A4%D0%B0%D0%B9%D0%BB:Bu.svg"
   class="image">
   <img alt="Bu.svg"
        src="/colldia/images/thumb/a/ae/Bu.svg/1063px-Bu.svg.png"
        width="1063"
        height="638"
   />
</a>

However graphviz extension generates for svg filetype the same code as for other fileformats: x

<img class="" 
 style=""
 alt="This is a graph with borders and nodes. Maybe there is an Imagemap used so the nodes may be linking to some Pages." 
 src="/colldia/images/graphviz/a2166e59be54c3b94615e6f3269a4569.svg"
 usemap="#a2166e59be54c3b94615e6f3269a4569" />


In Manual:Image_Administration#SVG they say that it's forbidden to include svg images directly in a wikipage, so that was the source of the bug.

UPDATE

I have fixed it by generating pngs with SvgHandler class and now with the help of Hokstad I can draw graphs like that

Where can I send the patches with that? I think it could be really handy.

--Katkov Yury 20:20, 7 June 2011 (UTC)Reply

If you don't want to put it in svn yourself (or have no access like me ;-)) the best way would be to fill a bug on https://bugzilla.wikimedia.org/enter_bug.cgi?product=MediaWiki%20extensions.

--Hummel-riegel 11:58, 11 June 2011 (UTC)Reply

Problem with Font / Charset[edit]

Hi, I have a problem with Graphviz on my wiki. The dot command is found and I can create Graphs, but instead of letters I only see rectangles. Here is a picture of what my graph looks like: http://tinypic.com/r/w8vlhi/7 (Uploadet 20.07.2011)

I hope someone can give my some hints of how to fix this :D

Thanks

Niklas


Automatically adding Wiki links[edit]

I am generating graphs representing sutuctures in my Wiki using Extension:DPL to generate a set of GraphViz dot commands. I am including the generation of the Graphviz commands to add URLs to each node so I can link back to the original pages in the Wiki. However this is a tedious process. I would like Extension:GraphViz to do this for me, i.e. scan the input commands before writing them out to a file and

replace 
	Foo -> Bar
with
	Foo  -> Bar
	Foo [URL=”Foo”]
	Bar [URL=”Bar”]

Is there any interest in this? --Teskeyn 15:10, 26 July 2011 (UTC)Reply

Hi, I think this is an interesting idea. At the moment I don't have any time to do work here, but as everybody could submit a patch, someone could do this.

In my opinion a good and easy solution would be a parameter, to activate or deactivate the replacement process. Not everybody wants to have the Nodes linked to the pages.
A more complex solution would be checking if the name of the page exists. But I'm not sure if this is necessary. --Hummel-riegel 16:24, 26 July 2011 (UTC)Reply

Teskeyn, I would very much love to know how you got DPL and GraphViz to play nice with each other - somehow I cannot get DPL output to be rendered correctly by GraphViz other than C&P it into the source code myself :/ I'd appreciate any hint!

As for your replacement: Why don't you just generate the missing lines for the URL parameter like this?

 {{#dpl:
    |category=...
    |mode=userformat
    |listseparators=,\n  "%PAGE%" [URL="%PAGE%"],,
  }}

--Dnowak 16:24, 20 Sep 2011 CET

failed to open stream: No such file or directory[edit]

Hey all, I have just installed graphviz and this extension, but kept seeing the following error message when I tried to put an example graph in my Sandbox:

Warning: file_get_contents(/path/to/wiki/images/graphviz/Sandbox---digraph+example.map):
failed to open stream: No such file or directory in 
/path/to/wiki/extensions/GraphViz/GraphViz.php on line 420    


The reason here was, the path to my Graphviz installation was wrong (I put /usr/bin/dot/ but correct was /usr/bin/ ). After changing this, the error dissappered. --Kebap 16:39, 6 September 2011 (UTC)Reply

Why don't we keep pruning simple?[edit]

I think all the different ways of storing the generated graph image files are a huge overkill.

Why don't you just use a modified 'named' method. Name each file with the article name and a count or if you must, the graph name and a count. This means if you have several graphs with the same name on one page (which is quite likely if you use templates to generate graphs), you just add a incremented number to the name.

Now we only have to take care of orphaned files, not needed anymore. Preventing that, we just get all files prefixed with the current article name and delete them when the page has been edited/purged (graph re-rendering) or moved/deleted. Of course we can add a caching mechanism, save the graph source with the image and check before rendering again whether the new source is equal to the new source, in that case we don't do anything. Special case would be if the number of graphs with same name changes on a page, in this case the easiest would be to prune all graphs with that name of that page.

Am I missing anything here, wouldn't it be that simple really? --Danwe 09:26, 26 September 2011 (UTC)Reply

Maintainers?[edit]

Is this extension still being maintained? It appears that it could be very useful, especially when combined with Extension:Semantic Result Formats. Badon 06:33, 26 November 2011 (UTC)Reply

Jeroen has maintained it for some time but he has no big plans about developing this extension. I have a project Extension:CollaborationDiagram that uses GraphViz, so I will probably occasionally contribute something here (like SVG support, shadows and gradients). I think without funding or really huge graphviz fans this extension will remain frozen. Katkov Yury 22:21, 28 November 2011 (UTC)Reply
I am using GraphViz extension extensively in my wiki, having templates generating huge graphs with SMW, Loops and Variables extensions. I have already fixed some things but didn't release them yet. I am thinking about re-writing the whole thing, solving the image caching issue and prettifying the extension design. Can't say when that's going to happen right now since I am rather busy with other extensions at the moment. --Danwe 17:00, 29 November 2011 (UTC)Reply

Running graphviz on web host[edit]

Hello, I'm trying to figure out how to properly install & use Graphviz. My wiki is installed a web host, which is running PEAR module Image_GraphViz 1.1.0 stable. In that case, where would the dot binary typically be for $wgGraphVizSettings->execPath? I'm at a loss as to how to properly configure this.Patelmm79 22:07, 20 January 2012 (UTC)Reply

same here[edit]

Hello, I seem to have the same problem as the User before. My Mediawiki is installed on an external server, I manage the files via ftp. I followed the installation instruction and noticed that the extension was probably made for installation on local PC or workstation. The installation path of GraphViz extension ist clear, I can add that. But when it comes to the installation execution path of graphviz it makes no sense to store "C:\xxx". Is it possible to run graphviz-extension on a webhost? Any help would be great, thanks, Jessy

Long filename with non-English letters[edit]

Patch Fix it:

commit 75f47c2499286b1196e888c611520dd765d91f89
Author: Pavel Astakhov <pastakhov@yandex.ru>
Date:   Thu Jul 5 09:43:37 2012 +0600

    Hotfix: Long filename with non-English letters

diff --git a/GraphViz.php b/GraphViz.php
index 583bf4f..818ed2a 100644
--- a/GraphViz.php
+++ b/GraphViz.php
@@ -283,18 +283,14 @@ $wgExtensionCredits['parserhook'][] = array(
 			$title = $wgTitle->getFulltext();
 		}
 
-		$storagename = str_replace( "%", '_perc_', urlencode( $title ) ) . '---'; // clean up pagename (special chars etc)
+		$storagename = str_replace( array('\\', '/', ':', '*', '?', '"', '<', '>', "\n", "\r" ), '_', $title ); // clean up pagename (special chars etc)
 
 		if ( $wgGraphVizSettings->named == 'md5' ) {
 			$storagename = md5( $storagename . $timelinesrc );  // produce md5-hash out of the storagename !can be duplicate!
 		} elseif ( $wgGraphVizSettings->named == 'sha1' ) {
 			$storagename = sha1( $storagename . $timelinesrc );  // produce sha1-hash
 		} else { // named == 'named'
-			$storagename .=  str_replace( "%", '_perc_',
-				urlencode( trim( str_replace( array( "\n", "\\" ), array( '', '/' ),
-					substr( $timelinesrc, 0, strpos( $timelinesrc, '{' ) )  // extract the name of the graph out of the graph
-				) ) )
-			);
+			$storagename .= str_replace( array('\\', '/', ':', '*', '?', '"', '<', '>', "\n", "\r" ), '_', substr( $timelinesrc, 0, strpos( $timelinesrc, '{' )) ); // clean up pagename (special chars etc)
 		}
 		$info .= "<pre>storagename=" . $storagename . "</pre>";
 
@@ -441,7 +437,7 @@ $wgExtensionCredits['parserhook'][] = array(
 				$txt = imageAtrributes( $args, $storagename, $map, $outputType, $wgUploadPath ); // if we want borders/position/...
 			} else {
 				$txt  = '<map name="' . $storagename . '">' . $map . '</map>' .
-					 '<img src="' . $wgUploadPath . '/graphviz/' . $storagename . '.' . $outputType . '"' .
+					 '<img src="' . $wgUploadPath . '/graphviz/' . urlencode($storagename) . '.' . $outputType . '"' .
 							   ' usemap="#' . $storagename . '" />';
 			}

This works for me --Pastakhov (talk) 08:16, 20 June 2012 (UTC)Reply

Shape shorthand[edit]

I made some changes to our implementation to support a shorthand/alias for shapes. The implementation is not very robust in that it relies on a basic find and replace but works out pretty well.

<graphviz border='frame' format='png' caption='this is my caption'>
digraph example1 {
  node1 [ type=input, label="Shiny Tire", URL="Shiny Tire" ]
  node2 [ type=output, label="Eastern Panther", URL="Eastern Panther" ]
  node3 [ type=procedure, label="White Poseidon", URL="White Poseidon" ]
  nodeGoogle [ type=process, label="Google", URL="http://www.google.com/" ]
  nodeTMC [ type=agent, label="Facebook", URL="https://www.facebook.com/" ]
  nodeMail [ type=decision, label="Mail", URL="mailto:DL-WikiCoordinator@tmhp.com" ]
  nodeInvalid [ type=workelement, label="Invalid link", URL="[[Main Page]]" ]

  node1 -> node2
  node1 -> node3
  node1 -> nodeGoogle
  node1 -> nodeTMC
  node1 -> nodeMail
  node1 -> nodeInvalid
}
</graphviz>

The "type=" shorthand syntax will get replaced with the expanded definition and can look like this:

Add this line:

$timelinesrc = replaceShorthand( $timelinesrc );

Right after the rewriteWikiUrls line like so:

$timelinesrc = rewriteWikiUrls( $timelinesrc ); // if we use wiki-links we transform them to real urls
$timelinesrc = replaceShorthand( $timelinesrc );

Add the following method to the end of the GraphViz.php file. Of course, change the $search and $replace pairs as necessary to support the style that you are trying to achieve. In this case, we were trying to mimic an existing style and nomenclature.

/**
 * replaceShorthand
 * Replaces the shorthand shape notation used to apply a
 * consistent style to the shapes in the graph.
 * In theory this could be bubbled out to a setting in LocalSettings.
 *
 * @param $graphsrc String: Raw source of the graph
 */
function replaceShorthand( $graphsrc )  {

	$search = array();
	$replace = array();

	// replace the custom node types
	$search[] = 'type=input';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=palegreen, shape=ellipse';

	$search[] = 'type=output';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=palegoldenrod, shape=ellipse';

	$search[] = 'type=procedure';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=orange, shape=box';

	$search[] = 'type=process';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=salmon, shape=parallelogram';

	$search[] = 'type=agent';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=yellow, shape=hexagon';

	$search[] = 'type=decision';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=salmon, shape=diamond';

	$search[] = 'type=workelement';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=paleturquoise, shape=rectangle';

	$search[] = 'type=workproduct';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=palegreen, shape=ellipse';

	$search[] = 'type=workelementstruct';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=violet, shape=rectangle';

	$search[] = 'type=workproductstruct';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=paleturquoise, shape=ellipse';

	$search[] = 'type=subprocess';
	$replace[] = 'fontname=Verdana, fontsize=9, style=filled, fillcolor=lightsteelblue, shape=ellipse';

	return str_replace($search, $replace, $graphsrc);
}

Possible enhancements: The $search and $replace pairs could be brought out to LocalSettings.php and modified there instead of having to modify the source.

Mattsmith321 (talk) 15:53, 1 September 2012 (UTC)Reply

Registering and listing pagelinks[edit]

I made some changes to the extension to support listing the links below the diagram and registering the links with wiki. I originally worked through the issues at MediaWiki + Graphviz + Image maps + Pagelinks but I will now provide ongoing updates/fixes here.

Note that my solution doesn't fully support all of the capabilities of the current GraphViz extension as there is functionality we do not need and I do not want to support. Here are the assumptions / limitations of this solution:

  • Does not support MscGen: We only have a need for Graphviz.
  • Does not support imageAtrributes: We wanted to control the format and presentation and it seemed like there were inconsistencies in the imageAttributes implementation that would then cause further support issues.
  • Does not support wikilinks: While it would be nice to provide consistent link usage through wiki and the Graphviz extension, the reality is that Graphviz is a completely different markup environment. While the current extension 'supports' wikilinks, the implementation is a little weak and leaves areas for confusion. Example: Wikilinks support giving the link an optional description but Graphviz already uses the node label for the description. So then you end up ignoring the wikilink description and telling users that 'Yes, we support wikilinks but don't use the description part' So since we aren't really using wikilinks correctly, just implement a regular link implementation and try to avoid the confusion entirely.

Here is what the output looks like:

Here are the changes that were made

Comment out this line:

// We don't want to support wikilinks so don't replace them
//$timelinesrc = rewriteWikiUrls( $timelinesrc ); // if we use wiki-links we transform them to real urls

Replace this block of code:

// clean up map-name
$map  = preg_replace( '#<ma(.*)>#', ' ', $map );
$map  = str_replace( '</map>', '', $map );
if ( $renderer == 'mscgen' ) {
	$mapbefore = $map;
	$map = preg_replace( '/(\w+)\s([_:%#/\w]+)\s(\d+,\d+)\s(\d+,\d+)/',
   '<area shape="$1" href="$2" title="$2" alt="$2" coords="$3,$4" />',
	$map );
}

/* Procduce html
 */
if ( $wgGraphVizSettings->imageFormatting )
{
	$txt = imageAtrributes( $args, $storagename, $map, $outputType, $wgUploadPath ); // if we want borders/position/...
} else {
	$txt  = '<map name="' . $storagename . '">' . $map . '</map>' .
		 '<img src="' . $wgUploadPath . '/graphviz/' . $storagename . '.' . $outputType . '"' .
				   ' usemap="#' . $storagename . '" />';
}

With this code (note that the str_replace of the xml tag in the code below is what is causing the syntaxhighlight tag to not highlight as expected):

$intHtml = '';
$extHtml = '';
$badHtml = '';

$intLinks = array();
$extLinks = array();
$badLinks = array();

// Wrap the map/area info with top level nodes and load into xml object
$xmlObj = new SimpleXMLElement( $map );

// What does map look like before we start working with it?
wfDebugLog( 'graphviz', 'map before: ' . $map . "\n" );

// Loop through each of the <area> nodes and update the values
// that will get used in the embedded map info in the html.
foreach($xmlObj->area as $areaNode) {

	wfDebugLog( 'graphviz', "areaNode: " . $areaNode->asXML() . "\n" );

	// Get the data from the XML attributes
	$hrefValue = (string)$areaNode->attributes()->href;
	$textValue = (string)$areaNode->attributes()->title;

	wfDebugLog( 'graphviz', '$hrefValue before: ' . $hrefValue . "\n" );
	wfDebugLog( 'graphviz', '$textValue before: ' . $textValue . "\n" );

	// For the text fields, multiple spaces ("   ") in the Graphviz source (label)
	// turns into a regular space followed by encoded representations of
	// non-breaking spaces (" &#xA0;&#xA0;") in the .map file which then turns
	// into the following in the local variables: ("   ").
	// The following two options appear to convert/decode the characters
	// appropriately. Leaving the lines commented out for now, as we have
	// not seen a graph in the wild with multiple spaces in the label -
	// just happened to stumble on the scenario.
	// See http://www.php.net/manual/en/simplexmlelement.asxml.php
	// and http://stackoverflow.com/questions/2050723/how-can-i-preg-replace-special-character-like-pret-a-porter
	//$textValue = iconv("UTF-8", "ASCII//TRANSLIT", $textValue);
	//$textValue = html_entity_decode($textValue, ENT_NOQUOTES, 'UTF-8');

	// Now we need to deal with the whitespace characters like tabs and newlines
	// and also deal with them correctly to replace multiple occurences.
	// Unfortunately, the \n and \t values in the variable aren't actually
	// tab or newline characters but literal characters '\' + 't' or '\' + 'n'.
	// So the normally recommended regex '/\s+/u' to replace the whitespace 
	// characters does not work.
	// See http://stackoverflow.com/questions/6579636/preg-replace-n-in-string
	$hrefValue = preg_replace("/( |\\\\n|\\\\t)+/", ' ', $hrefValue);
	$textValue = preg_replace("/( |\\\\n|\\\\t)+/", ' ', $textValue);

	// check to see if the url matches any of the
	// allowed protocols for external links
	if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $hrefValue ) ) {
		// external link
		$extLinks[] = $textValue . '++|++' . $hrefValue;
	}
	else {
		$first = substr( $hrefValue, 0, 1 );
		if ( $first == '\\' || $first == '[' || $first == '/' ) {
			// potential UNC path, wikilink, absolute or relative path
			$hrefValue = '#InvalidLink';
			$badLinks[] = $textValue . '++|++' . $hrefValue;
			$textValue = 'Invalid link. Check Graphviz source.';
		}
		else {
			$title = Title::newFromText( $hrefValue );
			if ( is_null( $title ) ) {
				// invalid link
				$hrefValue = '#InvalidLink';
				$badLinks[] = $textValue . '++|++' . $hrefValue;
				$textValue = 'Invalid link. Check Graphviz source.';
			}
			else {
				// internal link
				$intLinks[] = $textValue . '++|++' . $hrefValue;
				// Need to use the full url in the map since we support
				// hierarchy and without the full url it would end up
				// relative to the page.
				$hrefValue = $title->getFullURL();
			}
		}
	}

	$areaNode->attributes()->href = $hrefValue;
	$areaNode->attributes()->title = $textValue;

}

$map = $xmlObj->asXML();

// The contents of $map, which is now XML, gets embedded
// in the HTML sent to the browser so we need to strip
// the XML version tag and we also strip the <map> because
// it will get replaced with a new one with the correct name.
$map = str_replace( '<?xml version="1.0"?>', '', $map );
$map = preg_replace( '#<ma(.*)>#', ' ', $map );
$map = str_replace( '</map>', '', $map );

// Let's see what it looks like now that we are done with it.
wfDebugLog( 'graphviz', 'map after: ' . $map . "\n" );

// Now that we have all of the links, we can sort and de-dupe them, 
// register them with the wiki and create the actual html for the links.

// Process internal links
asort( $intLinks, SORT_NATURAL );
foreach ( $intLinks as $intLink ) {
	list($textValue, $hrefValue) = explode('++|++', $intLink);
	$title = Title::newFromText( $hrefValue );
	$parser->mOutput->addLink( $title );
	$intHtml .= Linker::link( $title, $textValue ) . ', ';
}

// Process external links
asort( $extLinks, SORT_NATURAL );
foreach ( $extLinks as $extLink ) {
	list($textValue, $hrefValue) = explode('++|++', $extLink);
	$parser->mOutput->addExternalLink( $hrefValue );
	$extHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
}			

// Process invalid links
asort( $badLinks, SORT_NATURAL );
foreach ( $badLinks as $badLink ) {
	list($textValue, $hrefValue) = explode('++|++', $badLink);
	//$parser->mOutput->addExternalLink( $hrefValue );
	$badHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
}									

// Format the html response to send back with the page.
$txt = '' .
	'<table style="background-color:#f9f9f9;border:1px solid #ddd;">' .
		'<tr>' .
			'<td style="border:1px solid #ddd;text-align:center;">' .
				'<map name="' . $storagename . '">' . $map . '</map>' .
				'<img src="' . $wgUploadPath . '/graphviz/' . $storagename . '.' . $outputType . '"' . ' usemap="#' . $storagename . '" />' .
			'</td>' .
		'</tr>' .
		'<tr>' .
			'<td style="font:10px verdana;">' .
				'This Graphviz diagram links to the following pages:' .
				'<br /><strong>Internal</strong>: ' . ( $intHtml != '' ?  rtrim( $intHtml, ' ,' ) : '<em>none</em>' ) .
				'<br /><strong>External</strong>: ' . ( $extHtml != '' ?  rtrim( $extHtml, ' ,' ) : '<em>none</em>' ) .
				( $badHtml != '' ? '<br /><strong>Invalid</strong>: ' . rtrim($badHtml, ' ,') .
				'<br /><em>Tip: Do not use wikilinks ([]), UNC paths (\\) or relative links (/) when creating links in Graphviz diagrams.</em>' : '' ) .
			'</td>' .
		'</tr>' .
	'</table>';

Mattsmith321 (talk) 15:17, 1 September 2012 (UTC)Reply

No dot executable found[edit]

I would like to install this extension to my mediawiki which is on my computer. However, when I installed the GraphViz into my computer, my wiki could not found the dot.exe Is it because of this line?

$wgGraphVizSettings->execPath = "C:/Program_Files_(x86)/Graphviz/bin/"; //Path to the Graphviz Installation

any help is appreciated, thank you. --Shinghinyeung (talk) 12:48, 11 September 2012 (UTC)Reply

I have the same problem[edit]

Firt your path seems no to be right with the underscores which should be spaces as "C:/Program Files (x86)/Graphviz/bin/". You can also try the short 8.3 dos name, you can get this in the CMD with the DIR command and some parameters. You should also add GraphViz and MSC-gen to the path variable of your system or the user you have created for the server. The server user (the user under which your server runs as a service) must also have read and execute permission on the executables and the temp directory of the system. From there i am lost too... Some suggest to add a system variable HOME that points into a temp folder. but this does nothing. In the debug of the wiki i dont see much, just the picture is missing. In the apache log i see a error which tells me that the command "X:\blah\graphViz\dot.exe" -T "png" -o "X:\www\" could not be found or is wrong. The same happens with the MSC-gen. But graphViz from the CMD works. Were you able to run this extension on windows? How, please tell me?! Thanks in advance :D

Fatal error[edit]

Fatal error: Class 'COM' not found in C:\wiki2\extensions\Graphviz\GraphViz.php on line 377

It was working fine when the server (XAMPP) was running on a Windows XP system, but I've moved it to a Windows 7 system and now this error pops up. --Korby (talk) 12:07, 18 October 2012 (UTC)Reply

You need dot-net in php.ini
I had the same issue. It worked fine on one machine and it didn't work on another.
You must install vcredist_x86 from Microsoft as suggested by the xampp-installer.
Then you have to add extension=php_com_dotnet.dll to your php.ini

--Mosero (talk) 19:25, 20 February 2013 (UTC)Reply

Cannot find the file specified[edit]

If you get the error:

Unexpected non-MediaWiki exception encountered, of type "com_exception"
exception 'com_exception' with message 'Source: WshShell.Exec
Description: The system cannot find the file specified. ' in C:\wamp\www\wiki\extensions\GraphViz\GraphViz.php:378

Chances are you are missing the final slash at the end of your $wgGraphVizSettings->execPath in LocalSettings.php. —The preceding unsigned comment was added by Mykro (talk • contribs) 07:10, 1 March 2013‎

save as pdf[edit]

if I print as PDF the graph disappear. how to generate it also in pdf ?

thanks —The preceding unsigned comment was added by 178.250.203.114 (talk • contribs) 12:56, 30 April 2013‎

FYI. --Nemo 12:19, 17 September 2013 (UTC)Reply

Template inside GraphViz[edit]

Is it possible to use wiki templates to generate a table with parameters in the label of a "record"? Like this:

<graphviz border='frame' format='png'>
 digraph MeYou{
Me->{{mytemplate|You}}
}
</graphviz>

Thank you --Gborgonovo (talk) 15:46, 5 March 2014 (UTC)Reply