--- ./graphviz_formats.module.orig	2010-08-02 19:30:28.000000000 +0200
+++ ./graphviz_formats.module	2010-08-02 21:03:09.794168638 +0200
@@ -2,10 +2,67 @@
 // $Id: graphviz_formats.module,v 1.1.2.3.2.3 2010/03/22 03:42:30 kratib Exp $
 
 /**
+ * Implementation of hook_requirements().
+ */
+function graphviz_formats_requirements($phase) {
+  $requirements = array();
+  $t = get_t();
+
+  // Check for presence respectively download canviz javascript files.
+  $errors = 0;
+  $requirements['canviz'] = array('title' => $t('Graphviz JS renderer'));
+  $canviz_path = drupal_get_path('module', 'graphviz_formats') .'/canviz';
+  if (file_check_directory($canviz_path, FILE_CREATE_DIRECTORY, 'canviz')) {
+    $js_urls = array(
+      'canviz.js' => 'http://canviz.googlecode.com/svn/canviz/trunk/canviz.js',
+      'excanvas.js' => 'http://explorercanvas.googlecode.com/svn/trunk/excanvas.js',
+      'path.js' => 'http://canviz.googlecode.com/svn/path/trunk/libs/path.js',
+      'prototype.js' => 'http://prototypejs.org/assets/2010/5/13/prototype.js',
+    );
+    foreach ($js_urls as $filename => $url) {
+      $filepath = "$canviz_path/$filename";
+      if (!is_file($filepath)) {
+        if ($file = fopen($filepath, 'w')) {
+          // download javascript
+          $result = drupal_http_request($url);
+          if (in_array($result->code, array(200, 302, 307))) {
+            //replace $() with $$$() for jquery compability
+            fwrite($file, preg_replace('/(?<!\$)\$\(/', '$$$(', $result->data));
+            fclose($file);
+          }
+          else {
+            $errors++;
+          }
+        }
+        else {
+          $errors++;
+        }
+      }
+    }
+  }
+  else {
+    $errors++;
+  }
+  if ($errors) {
+    $requirements['canviz']['value'] = $t('Canviz, Excanvas and Prototype Javascript files could not be downloaded to !path. That means the graphviz_filter output format canviz can not be used, please !bugreport.', array('!path' => $canviz_path, '!bugreport' => l('file a bug report', 'http://drupal.org/project/issues/graphviz_filter')));
+    $requirements['canviz']['severity'] = REQUIREMENT_ERROR;
+  }
+  else {
+    $requirements['canviz']['value'] = $t('Canviz, Excanvas and Prototype Javascript files successfully downloaded to !path.', array('!path' => $canviz_path));
+    $requirements['canviz']['severity'] = REQUIREMENT_OK;
+  }
+  return $requirements;
+}
+
+/**
  * Implementation of hook_graphviz_formats().
  */
 function graphviz_formats_graphviz_formats() {
   return array(
+    'canviz' => array(
+      'description' => t('Dynamic client-side graph rendering via JavaScript and Canviz'),
+      'format' => 'xdot',
+    ),
     'svg' => array(
       'description' => t('SVG rendering using &lt;object&gt; embedding or the <a href="@zgrviewer">ZGRViewer applet</a>.', array('@zgrviewer' => 'http://zvtm.sourceforge.net/zgrviewer/applet/')),
       'format' => 'svg',
@@ -20,14 +77,46 @@
 }
 
 /**
+ * Loads Canviz (Javascript GraphViz renderer) JS and dependencies.
+ */
+function graphviz_formats_add_canviz_js() {
+  static $canviz_added = FALSE;
+
+  if (!$canviz_added) {
+    $path = drupal_get_path('module', 'graphviz_formats') .'/canviz';
+    drupal_add_js($path .'/excanvas.js');
+    drupal_add_js($path .'/prototype.js');
+    drupal_add_js($path .'/path.js');
+    drupal_add_js($path .'/canviz.js');
+    drupal_add_js(array('graphviz_filter' => array('files_path' => GRAPHVIZ_FILTER_FILES_PATH)), 'setting');
+    $js = <<<JS
+Drupal.behaviors.canvizInit = function (context) {
+  $('.canviz:not(.canviz-processed)').each(function() {
+    var id = $(this).attr('id');
+    var path = '/' +  Drupal.settings.graphviz_filter.files_path;
+    new Canviz(id, path + '/' + id);
+  }).addClass('canviz-processed');
+}
+JS;
+    drupal_add_js($js, 'inline', 'footer');
+    $canviz_added = TRUE;
+  }
+}
+
+/**
  * Implementation of hook_graphviz_render().
  */
 function graphviz_formats_graphviz_render($inpath, $outpath, $format, $args) {
-  $outurl = url($outpath, array('absolute' => TRUE));
-  $modurl = url(drupal_get_path('module', 'graphviz_formats'), array('absolute' => TRUE));
-  if ($args['zgrviewer']['value']) {
-    return <<<EOS
-
+  switch ($format) {
+    case 'canviz':
+      graphviz_formats_add_canviz_js();
+      $filename = basename($outpath);
+      return '<div id="debug_output"></div><div id="'. $filename .'" class="canviz"></div>';
+    case 'svg':
+      $outurl = url($outpath, array('absolute' => TRUE));
+      $modurl = url(drupal_get_path('module', 'graphviz_formats'), array('absolute' => TRUE));
+      if ($args['zgrviewer']['value']) {
+        return <<<EOS
 <applet code="net.claribole.zgrviewer.ZGRApplet.class" archive="$modurl/zvtm.jar,$modurl/zgrviewer.jar" width="720" height="480">
   <param name="type" value="application/x-java-applet;version=1.4" />
   <param name="scriptable" value="false" />
@@ -40,17 +129,14 @@
   <param name="highlightColor" value="red" />
   <param name="displayOverview" value="true" />
 </applet>
-
 EOS;
-  }
-  else {
-    return <<<EOS
-
+      }
+      else {
+        return <<<EOS
 <object type="image/svg+xml" data="$outurl">
   <embed type="image/svg+xml" src="$outurl" pluginspage="http://www.adobe.com/svg/viewer/install/" />
 </object>
-
 EOS;
+      }
   }
 }
-
--- ./graphviz_filter.module.orig	2010-08-02 19:30:28.000000000 +0200
+++ ./graphviz_filter.module	2010-08-02 19:41:44.416126999 +0200
@@ -9,6 +9,8 @@
 
 define('GRAPHVIZ_REGEX', '/\[graphviz\](.*?)\[\/graphviz\]/si');
 define('GRAPHVIZ_FILTER_SUPPORTED_COMMANDS', 'dot, neato, twopi, fdp, circo');
+define('GRAPHVIZ_FILTER_FILES_PATH', file_directory_path() .'/graphviz');
+
 
 /**
  * Implementation of hook_requirements().
@@ -203,7 +205,7 @@
   }
 
   // Create a temporary file with the DOT script.
-  $outdir = file_directory_path() .'/graphviz';
+  $outdir = GRAPHVIZ_FILTER_FILES_PATH;
   file_check_directory($outdir, FILE_CREATE_DIRECTORY);
   $inpath = file_create_path($outdir .'/'. md5($text) .'.dot');
   if (!file_exists($inpath)) {
@@ -221,16 +223,17 @@
       watchdog('graphviz filter', $msg, $arg, WATCHDOG_ERROR);
       continue;
     }
+
     $outpath = file_create_path($outdir .'/'. md5($text) .'.out.'. $formats[$format]['format']);
     if (file_exists($outpath) || _graphviz_filter_render($inpath, $outpath, $formats[$format]['format'], $args['command']['value'])) {
-      $output .= '<div class="graphviz graphviz-"'. $format .'>';
+      $output .= '<span class="graphviz graphviz-'. $format .'">';
       if ($args['link-output']['value']) {
         $output .= l(t($args['title']['value']), file_create_url($outpath), array('attributes' => array('class' => 'graphviz-link-output')));
       }
       else {
         $output .= module_invoke($formats[$format]['module'], 'graphviz_render', $inpath, $outpath, $format, $args);
       }
-      $output .= '</div>';
+      $output .= '</span>';
       if ($args['link-input']['value']) {
         $output .= '<div class="graphviz graphviz-"'. $format .'>';
         $output .= l(t('Download input script for %title', array('%title' => $args['title']['value'])), file_create_url($inpath),
@@ -356,29 +359,29 @@
  * Implementation of hook_graphviz_render().
  */
 function graphviz_filter_graphviz_render($inpath, $outpath, $format, $args) {
-  if ($format == 'dot' ) {
-    $output = '<pre>' . file_get_contents($outpath) . '</pre>' . "\n";
-  }
-  else {
-    $output = '<img src="'. file_create_url($outpath) .'" title="'. check_plain(t($args['title']['value'])) .'" ';
-    $mappath = file_create_path($outpath .'.map');
-    if ($args['imagemap']['value'] && _graphviz_filter_render($inpath, $mappath, 'cmapx', $args['command']['value'])) {
-      $map = file_get_contents($mappath);
-      $id = 'G';
-      $match = array();
-      if (preg_match('/<map[^>]*id\s*=\s*"(.*?)"/', $map, $match)) {
-        $id = $match[1];
+  switch ($format) {
+    case 'dot':
+      return '<pre>' . file_get_contents($outpath) . "</pre>\n";
+    default:
+      $output = '<img src="'. file_create_url($outpath) .'" title="'. check_plain(t($args['title']['value'])) .'" ';
+      $mappath = file_create_path($outpath .'.map');
+      if ($args['imagemap']['value'] && _graphviz_filter_render($inpath, $mappath, 'cmapx', $args['command']['value'])) {
+        $map = file_get_contents($mappath);
+        $id = 'G';
+        $match = array();
+        if (preg_match('/<map[^>]*id\s*=\s*"(.*?)"/', $map, $match)) {
+          $id = $match[1];
+        }
+        $output .= 'usemap="#'. $id .'" />';
+        $output .= $map;
+        $output .= "\n";
+      }
+      else {
+        $output .= ' />';
       }
-      $output .= 'usemap="#'. $id .'" />';
-      $output .= $map;
       $output .= "\n";
-    }
-    else {
-      $output .= ' />';
-    }
-    $output .= "\n";
+      return $output;
   }
-  return $output;
 }
 
 /**
