logo4 Evolution is progress—                          
progress is creativity.        

Graphviz with Django and Creole

view blog view wiki view wiki view wiki

This page describes just another creole macro which renders graphviz instructions from a creole page into an image.

The macro is included by the instruction.

digraph G {Hello->World}

As with mathplot there are optional parameters.

  • title that defines the title and alt attributes of the <img> tag
  • show_source is False by default. If True the content of the graph source is displayed

Here is the simple test example.

graphviz image

Rendering a dot macro is a two tier process.

  1. When the creole markup language is translated the macro gives the HTML code of an <img> tag and the graph source is stored temporarily into the database. The key to that database is the src attribute of the <img> tag.
  2. When rendering the image the graph source is taken from the database and stored temporarily into a file, rendered to a png image file. Both temporary files are removed after the procedure returned the image to the server.

graphviz image

The Creole Macro

The graph source is taken from the macro's body and stored with a unique key into the database.

def dot(macro,environ,title="no title",show_source=False):
# remove outdated database records
    Plot.objects.filter(created__lt = date.today()).delete()
# create a url safe unique identifier for this file
    key = uuid.uuid4()
    query = urllib.quote(key.__str__())
# save in the database
    p = Plot.objects.create(key=key)
# generate the url to the image rendering view
    plot = "/pat-to-graphviz-view/graphviz/" + query + "/"

    if show_source:
        output = bldr.tag.pre(macro.body.encode("utf-8"))
        output += bldr.tag.img(src=plot,title=title,alt=title) 
        output = bldr.tag.img(src=plot,title=title,alt=title)
    return output

The Graphviz View

The vie translates the graphviz source into a png image and returns the image as a HttpResponse object. As the the translation is accomplished by a system call to the dot routine, the files have to be stored temporarily. That process require 3 external prerequisites.

  1. The installation of graphviz
  2. The command to launch the dot routine settings.GRAPHVIZ_DOT_CMD. (On a linux platform you can use the "whereis dot" command to locate it.)
  3. A temporary directory should exist somewhere settings.GRAPHVIZ_TMP_DIR. Write permissions have to be granted to the server.

For convenience i stored the latter two parameters in my setting.

GRAPHVIZ_DOT_CMD = '/path-to-dot/dot'
GRAPHVIZ_TMP_DIR = '/path-to-temporary-directory/'

And this is the view code.

def view_graphviz(request, dot = None, extra_context={}):
    from os import system
    from os.path import join
    from django.conf import settings
# get the graphviz source
        pobj = Plot.objects.get(key = unquote(dot))
    except Plot.DoesNotExist:
        dot_content = "digraph G {No->%s}" % dot
        dot_content = pobj.content
# save it to a file    
    path_dot = join(settings.GRAPHVIZ_TMP_DIR, '%s.dot' % dot)
    tdot = open(path_dot, 'w')
# execute the translation to an image file    
    path_dot_png = '%s.png' % path_dot
    system('%s %s -Tpng -o %s' % (settings.GRAPHVIZ_DOT_CMD, path_dot, path_dot_png))
# open file
    with open(path_dot_png, "rb") as fid:
        filedata = fid.read()
# remove the files
    system("rm %s" % path_dot)
    system("rm %s" % path_dot_png)
# make and return the response object
    return HttpResponse(filedata, content_type='image/png')

Tags: Software


(c) Mato Nagel, Weißwasser 2004-2013, Disclaimer