Graphviz-plugin

This is a quick graphviz-plugin for Dokuwiki.

Read more about graphviz at http://www.graphviz.org/Documentation.php.

Feel free to try this out in the sandbox.

This is slightly broken as of 2005-06-22

Are there any plans to fix this and make it work as of 2005-06-22?
Hi, I slightly modify this plugins by using dokuwiki framework http://danjer.doudouke.org/tech/dokutexit#other_rendering_plugins Danjer@doudouke.org

Installation Notes

By default, graphviz-plugin expects to find graphviz binaries (dot, neato, etc) and ImageMagick binaries in /usr/bin.

Some OSes store these binaries in other directories:

OS Graphviz bin directory
FreeBSD /usr/local/bin

If you use such an OS, you must manually edit graphviz-plugin syntax.php.
Windows specific additional steps

Example 1

Before

      +-----------+          +-----------+
      |           |  Input   |  Client   |
      |  Parser   |<---------|   Code    |
      |           |  String  |           |
      +-----.-----+          +-----|-----+
    Modes   |                     /|\
      +     |             Renderer |
    Input   |          Instructions|
    String \|/                     |
      +-----'-----+          +-----------+
      |           |          |           |
      |  Lexer    |--------->|  Handler  |
      |           |  Tokens  |           |
      +-----.-----+          +-----------+
            |
            |
       +----+---+
       | Modes  |-+
       +--------+ |-+
         +--------+ |
           +--------+

After

Graph

Graphviz source

digraph DokuWikiParser {
        node [style=rounded, fontname=Arial, fontsize=13];
        edge [fontname=Arial, fontsize=11];
        P [label=Parser,         shape=box, pin=true, pos="1,3.5"];
        H [label=Handler,        shape=box, pin=true, pos="3,2"];
        CC [label="Client Code", shape=box, pin=true, pos="3,3.5"];
        L [label=Lexer,          shape=box, pin=true, pos="1,2"];
        M [label=Modes,          shape=box, pin=true, pos="1,1"];
        CC -> P [label="Input String"];
        H -> CC [label="Render\nInstructions"];
        P -> L  [label="Modes\n+\nInput String"];
        L -> H  [label=Tokens];
        L -> M  [arrowhead=none];
}

Installation

  1. Go fetch the latest and greatest graphviz. I’m using 2.2.1. Also install ImageMagick and GhostScript. Throw in some nice TTF-fonts. Stir.
  2. Download syntax.php from http://svn.ioslo.net/svn/dokuwiki-plugin-graphviz/trunk/ and put it into dokuwiki root/plugins/graphviz.
  3. Make sure that dokuwiki root/data/media/graphviz is directory is readable by the web server (e.g. chmod 755 dokuwiki root/data/media/graphviz);
  4. Enjoy

Todo

  1. It should inject a internal media link, not plain xhtml. Will the parser reparse my code?
  2. Autocreate the namespace if it doesn’t exists
  3. It should detect graphviz 1.x or 2.x. It should also detect Imagemagick automagically.
  4. Provide some kind of interface to graphviz’ errors and warnings. Maybe they sould get printed on preview?
  5. Namespace security. Maybe the graph should inherit the originating page’s namespace? A graph at dokuwiki:graphviz becomes media:dokuwiki:graphviz:graphviz-MD5.png
  6. Package the plugin in a nice zip. Write README
  7. The file_put_contents() should be replaced with a full fopen()-block to make compatible with older versions of PHP.
  8. Add a alternative, simpler syntax.
  9. Make the ImageMagick antialiasing configurable
  10. The graphs should be put in media/<current/namespace>/graphviz-<md5>.png

Changelog

0.1.20050525

  • Initial release

Source

More examples

Modes

dot

Graph

neato

Graph

twopi

Graph

circo

Graph

fdp

Graph

Huge thing

Comments, Ideas and Bugs

In a word, awesome! — Harry Fuecks 2005/05/25 01:40
Thank you :-) Let me know if you use it — Carl-Christian Salvesen 2005/05/25 10:02
E-Razor: well, first of all, you’ll have to use a devel version of dokuwiki (darcs >=2005-05-23 should work) für the new plugin interface.
Next, why do you use -Tps?
$retval = exec('/usr/bin/'.$graphcmd.' -Tpng '.$tmpfname.' -o '.$filename);

is working quite fine here too!

Well, and a last thing, all non php5 users should use the PECL-PHP_Compat package with

require_once '/usr/lib/php/PHP/Compat/Function/file_put_contents.php';

for the file_put_contents function.

Yes, this uses the new plugin interface. Hopefully, it will be included in the next release. I use -Tps and pipe it to ImageMagick to get antializing. Smoother lines. It’s not a must, but it looks better. And the file_put_contents should be replaced with a full fopen()-block to make compatible with older versions of PHP. Thank you for your comments :-)Carl-Christian Salvesen 2005/05/26 09:01
E-Razor: I’ve played a bit with dot and convert and it looks like
$retval = exec('/usr/bin/'.$graphcmd.' -Tsvg '.$tmpfname.'|/usr/bin/convert svg:- png:'.$filename);

ends with mutch better quality.

Changes I needed for 2005-07-13: (this does not include copying inc/plugins/graphviz/syntax.php to lib/plugins/graphviz/diff –normal graphviz/syntax.php ../../inc/plugins/graphviz/syntax.php
10,13c10,11
< if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
< if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
< require_once(DOKU_INC.'inc/parser/parser.php');
< require_once('/wiki/PHP_Compat-1.4.1/Compat/Function/file_put_contents.php');
---
> if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
> if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'inc/plugins/');
73c71
<                               $url = DOKU_BASE.'lib/exe/fetch.php?cache='.$cache.'&amp;media='.urlencode('graphviz:'.$hash.'.png');
---
>                               $url = DOKU_BASE.'fetch.php?cache='.$cache.'&amp;media='.urlencode('graphviz:'.$hash.'.png');
98c96
<                       #$retval = exec('/usr/bin/'.$graphcmd.' -Tpng -o '.$filename .' '.$tmpfname);
---
>                       // $retval = exec('/usr/bin/'.$graphcmd.' -Tpng -o '.$filename .' '.$tmpfname);
I had to introduce two changes to make it work:
1. Replace a call to file_put_contents with these lines (not necessary if you use PHP5):
if(!($handle = fopen($tmpfname, "w")))
	die("Error opening " . $tmpfname . " for writing");

if (!fwrite($handle, $data))
	die("Error writing to " . $tmpfname);

fclose($handle);

2. Remove a slash from before “lib” in render function so that it looks like this:

$url = DOKU_BASE.'lib/exe/fetch.php?cache='.$cache.'&amp;media='.urlencode('graphviz:'.$hash.'.png');

Also I believe that the line with exec should look like this (note how return value is acquired):

exec('/usr/bin/'.$graphcmd.' -Tps '.$tmpfname.'|/usr/bin/convert ps:- png:'.$filename, $output, $retval);

Michał Tkacz 2006/01/11 22:23

Excellent Plugin! Our company has been using both dokuwiki and graphviz for awhile. Now the two are one! One suggestion: Support for node [URL=”http:\\...”]. For example:

Graph

Tom 2006/04/07
I’ve installed graphviz, ghostscript and the graphviz plugin, but instead of showing a graph graphviz code only produces a text “Graph”. Take a look at my playground. I tested the “dot” command through a terminal connection and it produces flawless PostScript output. — Daniel Link 2006/05/22 01:17
I’ve also installed this graphviz-plugin but without succuess. I know graphviz is working since i’m using it together with other applications. Is the plugin broken? Could someone please fix it? — David Sveningsson 2006/07/08 11:41

WINDOWS Specific additional steps:

In windows you need propertly installed graphviz (in clean windows XP sp 2 you need to install Microsoft Visual C++ 2005 Redistributable Package (x86).). And change path to you binaries in line about 100: exec(’/usr/bin/’) ... to exec(’C:/Program files/...’)

		function createImage($filename, &$data, $graphcmd='dot') {
 
			$cmds = array('dot','neato','twopi','circo','fdp');
			if ( !in_array($graphcmd, $cmds) ) $graphcmd = 'dot';
			$tmpfname = tempnam("/tmp", "dokuwiki.graphviz");  
 //"/tmp" is unix-specific file path, but it will work in windows too. no need to change
			file_put_contents($tmpfname, $data);
			$retval = exec('/usr/bin/'.$graphcmd.' -Tps '.$tmpfname.'|/usr/bin/convert ps:- png:'.$filename);
//!!THIS IS UNIX SPECIFIC FILE PATH change '/usr/bin/ to where your graphviz binaries are placed and |/usr/bin/convert to where your imagemagick placed.
			// Comment out the line over this and uncomment the line below to NOT use ImageMagick for antialiazing.
			// $retval = exec('/usr/bin/'.$graphcmd.' -Tpng -o '.$filename .' '.$tmpfname);  
//!!THIS IS UNIX SPECIFIC FILE PATH change it to where your graphviz binaries are
			unlink($tmpfname);
			return $retval;
		}

Anton Reshetnikov 2008/april/04

Plugging UmlGraph infront of graphviz

Wanting a for coders intuitive way to produce uml graphs, i’ve found Uml Graph by D. Spinellis. Because of it’s java plus a javadoc plugin, you need some prerequisites in order to make it work. You need Sun Java 5 Jsdk or how they call it atm. Gcj doesn’t work. I’ve used a howto on Debian Administration org to plug java into my sid. License issues and so on, you know, it’s complicated. Then replace the createImage function by the following, and doing

<graphviz juml>
class Person {
	String Name;
}

class Employee extends Person {}

class Client extends Person {}
</graphviz>

gives you the neat graph you can find on Spinelis UmlGraph page.

Since Spinellis offers allso a way of adding sequence diagrams in another way, i’ve allso realized a way to do this too. You need the Gnu Plotutils as external dependency and Spinellis Plotutils lib in a place where the plotutils find it. I’ve added a ‘cd’ to the code, this is the best location for it. Happy Graphing!

  function createImageps($filename, &$data, $graphcmd='dot') { //Latex mode have better rendering with ps
    $cmds = array('dot','neato','twopi','circo','fdp', 'juml');
    if ( !in_array($graphcmd, $cmds) ) $graphcmd = 'dot';
 
    $tmpfname = tempnam("/tmp", "dokuwiki.graphviz");
    if ($graphcmd == 'juml')
    { /* we have to create our own file, because we need it to be named .java */
	    $tmpdir = "/tmp/dokuwiki".md5(date("%H%i%s%".microtime()));
	    mkdir($tmpdir, 0700);
	    $tmpfile = ($tmpdir."/temp.java");
            $tmpdotfile = $tmpdir."/temp.dot";
	    touch($tmpfile);
	    touch($tmpdotfile);
	    io_saveFile($tmpfile, $data); //Using dokuwiki framework
	    $retval = exec('cd /;/usr/lib/j2sdk1.5-sun/bin/javadoc '.
			   '-classpath '.DOKU_PLUGIN.'/graphviz/UmlGraph.jar '.
			   '-private -doclet '.
			   'gr.spinellis.umlgraph.doclet.UmlGraph -output '.
			   $tmpdotfile.' '.$tmpfile);
	    $retval = exec('/usr/bin/dot -Gsize="5,4" -Tps '.$tmpdotfile.' -o '.$filename);
	    unlink($tmpfile);
	    unlink($tmpdotfile);
	    rmdir($tmpdir);
    }
    else if ($graphcmd == 'pic'){
        $tmpfname = tempnam("/tmp", "dokuwiki.graphviz");
        io_saveFile($tmpfname, $data); //Using dokuwiki framework
 
        $retval = exec('cd '.DOKU_PLUGIN.'/graphviz/; /usr/bin/pic2plot -Tps '
                       .$tmpfname.' > '.$filename);
        unlink($tmpfname);
    }
    else {
	    io_saveFile($tmpfname, $data);
	    $retval = exec('/usr/bin/'.$graphcmd.' -Gsize="5,4" -Tps ' .
			   $tmpfname.' -o '. $filename);
	    unlink($tmpfname);
    }
    return $retval;
  }
 
 
  function createImage($filename, &$data, $graphcmd='dot') {
 
    $cmds = array('dot','neato','twopi','circo','fdp', 'juml');
    if ( !in_array($graphcmd, $cmds) ) $graphcmd = 'dot';
 
    //    file_put_contents($tmpfname, $data); 
    if ($graphcmd == 'juml')
    { /* we have to create our own file, because we need it to be named .java */
	    $tmpdir = "/tmp/dokuwiki".md5(date("%H%i%s%".microtime()));
	    mkdir($tmpdir, 0700);
	    $tmpfile = ($tmpdir."/temp.java");
            $tmpdotfile = $tmpdir."/temp.dot";
	    touch($tmpfile);
	    touch($tmpdotfile);
	    io_saveFile($tmpfile, $data); //Using dokuwiki framework
	    $retval = exec('cd /;/usr/lib/j2sdk1.5-sun/bin/javadoc '.
			   '-classpath '.DOKU_PLUGIN.'/graphviz/UmlGraph.jar '.
			   '-private -doclet '.
			   'gr.spinellis.umlgraph.doclet.UmlGraph -output '.
			   $tmpdotfile.' '.$tmpfile);
	    $retval = exec('/usr/bin/dot -Tps '.$tmpdotfile.
			   '|/usr/bin/convert ps:- png:'.$filename);
	    unlink($tmpfile);
	    unlink($tmpdotfile);
	    rmdir($tmpdir);
    }
    else if ($graphcmd == 'pic'){
	    $tmpfname = tempnam("/tmp", "dokuwiki.graphviz");
	    io_saveFile($tmpfname, $data); //Using dokuwiki framework
	    
	    $retval = exec('cd '.DOKU_PLUGIN.'/graphviz/; /usr/bin/pic2plot -Tps '
			   .$tmpfname.'|/usr/bin/convert ps:- png:'.$filename);
	    unlink($tmpfname);
    }
 
    else {
	    $tmpfname = tempnam("/tmp", "dokuwiki.graphviz");
	    io_saveFile($tmpfname, $data); //Using dokuwiki framework
 
	    $retval = exec('/usr/bin/'.$graphcmd.' -Tps '
			   .$tmpfname.'|/usr/bin/convert ps:- png:'.$filename);
    // Comment out the line over this and uncomment the line below to NOT use ImageMagick for antialiazing.
    // $retval = exec('/usr/bin/'.$graphcmd.' -Tpng -o '.$filename .' '.$tmpfname);
	    unlink($tmpfname);
    }
    return $retval;
  }

123 Maps graph on dokuwiki

Hello Dokuwiki community:

This is my 2 cents to all this excellent group of developers and friends that have create this great product dokuwiki and Carl-Christian for this plugin, that I have been using for many years at work and to organize my everyday activities.

After a lot of digging into the code .php and review the documents from this website:

http://www.cems.uwe.ac.uk/~cjwallac/viz/#php

I realize the way to “hack” this puglin to allow using MAP-images into your wiki pages :-)

Notes:
1- you can include as many graphics as you want per page since the signature(md5 name) it is base on the values from the .dot syntax that you create.
2- It is a HACK may not be the most elegant and/or best code but it works :-) , your modifications/suggestions are welcome.

example:

<graphviz map>
digraph DokuWikiParser {
    wiki [URL="http://wiki.org"];
    graphs [URL="http://http://wiki.ioslo.net/dokuwiki/graphviz"];
    wiki -> graphs;
}
</graphviz>
 
  /**
   * Create output
   */
  function render($mode, &$renderer, $data) {
    global $conf;
    global $gr_ext;
    $gr_ext='png';
    $grf_ext='.'.$gr_ext;
    if($data[1] == 'map' && strlen($data[0]) > 1) {
      if ( !is_dir($conf['mediadir'] . '/graphviz') ) 
        io_mkdir_p($conf['mediadir'] . '/graphviz'); //Using dokuwiki framework
      $hash = md5(serialize($data));
      $filename = $conf['mediadir'] . '/graphviz/'.$hash.$grf_ext;
      $url = ml('graphviz:'.$hash.$grf_ext); //Using dokuwiki framework
 
      // if already exist render
      if ( is_readable($filename) ) {
        // cached.
        // generate the map to variable
        $kk1 = $data[0];
        exec("echo '$kk1' | /usr/bin/dot -Tcmap ", $map);
        //$renderer->doc .= '<p> valor map=['.$map .']</p>';
        $maphtml = implode("\n",$map);
        // add the target - cant do this with DOT
        $maphtml = str_replace("<area ", "<area target=\"".$hash."\" ",$maphtml);
 
        // Include Map in the page
        $renderer->doc .= '<map id="'.$hash.'" name="'.$hash.'">';
        $renderer->doc .= $maphtml;
        $renderer->doc .= '</map>';
 
        // Link the Image below with the map above by hash
        $renderer->doc .= '<img src="'.$url.'" border="0" usemap="#'.$hash.'" Ismap>';
 
        return true;
      }
 
      if (!$this->createImageMap($filename, $data[0], $data[1])) {
 
        // generate the map 
        $kk1 = $data[0];
        exec("echo '$kk1' | /usr/bin/dot -Tcmap ", $map);
        $maphtml= implode("\n",$map);
        // add the target - cant do this with DOT
        $maphtml=str_replace("<area ", "<area target=\"".$hash."\"",$maphtml);
 
        // Include Map in the page
        $renderer->doc .= '<map id="'.$hash.'" name="'.$hash.'">';
        $renderer->doc .= $maphtml;
        $renderer->doc .= '</map>';
 
        // Link the Image below with the map above by hash
        $renderer->doc .= '<img src="'.$url.'" border="0" usemap="#'.$hash.'" Ismap>';
 
      } else {
        $renderer->doc .= '**ERROR RENDERING GRAPHVIZ**';
      }
      return true;
   }
 
    if($mode == 'xhtml' && strlen($data[0]) > 1) {
      if ( !is_dir($conf['mediadir'] . '/graphviz') ) 
        io_mkdir_p($conf['mediadir'] . '/graphviz'); //Using dokuwiki framework
      $hash = md5(serialize($data));
      $filename = $conf['mediadir'] . '/graphviz/'.$hash.'.png';
      $url = ml('graphviz:'.$hash.'.png'); //Using dokuwiki framework
 
      if ( is_readable($filename) ) {
        // cached.
        $renderer->doc .= '<img src="'.$url.'" class="media" title="Graph" alt="Graph" />';
        //                                              $renderer->doc .= $renderer->internalmedialink('graphviz:'.$hash.'.png');
        return true;
      }
 
 
      if (!$this->createImage($filename, $data[0], $data[1])) {
        $renderer->doc .= '<img src="'.$url.'" class="media" title="Graph" alt="Graph" />';
        //                                      $renderer->doc .= $renderer->internalmedialink('graphviz:'.$hash.'.png');
      } else {
        $renderer->doc .= '**ERROR RENDERING GRAPHVIZ**';
      }
      return true;
    }
 
  function createImage($filename, &$data, $graphcmd='dot') {
 
    $cmds = array('dot','neato','twopi','circo','fdp','dotmap');
    # $cmds = array('dot','neato','twopi','circo','fdp');
    if ( !in_array($graphcmd, $cmds) ) $graphcmd = 'dot';
 
    $tmpfname = tempnam("/tmp", "dokuwiki.graphviz");
    io_saveFile($tmpfname, $data); //Using dokuwiki framework
    $retval = exec('/usr/bin/'.$graphcmd.' -Tpng -o '.$filename .' '.$tmpfname);
    unlink($tmpfname);
    return $retval;
  }
 
  function createImageMap($filename, &$data, $graphcmd='dot') {
 
    $cmds = array('dot','neato','twopi','circo','fdp','dot');
    # $cmds = array('dot','neato','twopi','circo','fdp');
 
    if ( !in_array($graphcmd, $cmds) ) $graphcmd = 'dot';
 
    $tmpfname = tempnam("/tmp", "dokuwiki.graphviz");
    io_saveFile($tmpfname, $data); //Using dokuwiki framework
    $retval = exec('/usr/bin/dot -Tpng -o '.$filename.' '.$tmpfname);
 
    unlink($tmpfname);
    return $retval;
  }
 

ps: cheers and happy graphs :-) !! (Regards Enrique )

 
dokuwiki/graphviz.txt · Last modified: 2008/05/20 05:22 by kilargo
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki