<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>/dev/stu &#187; django</title>
	<atom:link href="http://www.stuartaxon.com/tag/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stuartaxon.com</link>
	<description>Adding LOC to the web.</description>
	<lastBuildDate>Mon, 09 Jan 2012 18:11:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Using PyCha with Django</title>
		<link>http://www.stuartaxon.com/2011/02/25/using-pycha-with-django/</link>
		<comments>http://www.stuartaxon.com/2011/02/25/using-pycha-with-django/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 00:10:50 +0000</pubDate>
		<dc:creator>stu</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cairo]]></category>
		<category><![CDATA[charting]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pycha]]></category>

		<guid isPermaLink="false">http://www.stuartaxon.com/?p=290</guid>
		<description><![CDATA[A quick post on using Python Charts to generate nice SVG charts for your django website (I&#8217;ve had the code hanging around for ages &#8211; so should just post it). The code is based on the examples there, here I integrate it into Django. To install you&#8217;ll need to do pip install pycha Heres the [...]]]></description>
			<content:encoded><![CDATA[<p>A quick post on using <a href="http://bitbucket.org/lgs/pycha/">Python Charts</a> to generate nice SVG charts for your django website (I&#8217;ve had the code hanging around for ages &#8211; so should just post it).  The code is based on the examples there, here I integrate it into Django.</p>
<p>To install you&#8217;ll need to do</p>
<pre>pip install pycha</pre>
<p>Heres the code for a simple view to output a chart directly to SVG:</p>
<p><a href="http://www.stuartaxon.com/wp-content/uploads/2011/02/linechart.png"><img class="alignnone size-full wp-image-291" title="linechart" src="http://www.stuartaxon.com/wp-content/uploads/2011/02/linechart.png" alt="" width="401" height="316" /></a></p>
<pre class="brush:python"># views.py

from StringIO import StringIO
from django.http import HttpResponse

import cairo

def colors(request):
    in_req = 1

    svg_buffer = StringIO()

    width, height = (500, 400)
    surface = cairo.SVGSurface(svg_buffer, width, height)

    dataSet = (
     ('dataSet 1', ((0, 1), (1, 3), (2, 2.5))),
     ('dataSet 2', ((0, 2), (1, 4), (2, 3))),
     ('dataSet 3', ((0, 5), (1, 1), (2, 0.5))),
    )

    options = {
       'legend': {'hide': True},
       'background': {'color': '#f0f0f0'},
    }

    #import pycha.bar
    #chart = pycha.bar.VerticalBarChart(surface, options)

    import pycha.line
    chart = pycha.line.LineChart(surface, options)
    chart.addDataset(dataSet)
    chart.render()

    del chart
    del surface

    response = ''
    response = HttpResponse(mimetype='image/svg+xml')
    svg_buffer.seek(0)
    response.write( svg_buffer.read() )
    return response
</pre>
<p>The basic idea is that &#8211; instead of the chart outputting to an svg file, the output goes to a buffer, this is triggered by calling the destructors of the chart and it&#8217;s cairo surface.  Once the data is in the buffer, it is rewound and played back to the Http Response.</p>
<p>&nbsp;</p>
<h2>Inline SVG</h2>
<p>As is, this won&#8217;t work as inline svg, because outputting the XML preamble in the middle of the page will cause problems.  Below is an example that let&#8217;s you decide if you need the preamble (full SVG output), or not (SVG fragment for inclusion in a page or another SVG):</p>
<pre class="brush:python"># Create your views here.

from StringIO import StringIO
from django.http import HttpResponse
from django.shortcuts import render_to_response

import cairo

XML_PREAMBLE = '&lt;?xml version="1.0" encoding="UTF-8"?&gt;'

def colors_chart(inline = False):
    """
    Generate colours chart

    Set inline to True to disable the XML preamble
    """
    in_req = 1

    svg_buffer = StringIO()

    width, height = (500, 400)
    surface = cairo.SVGSurface(svg_buffer, width, height)

    dataSet = (
     ('dataSet 1', ((0, 1), (1, 3), (2, 2.5))),
     ('dataSet 2', ((0, 2), (1, 4), (2, 3))),
     ('dataSet 3', ((0, 5), (1, 1), (2, 0.5))),
    )

    options = {
       'legend': {'hide': True},
       'background': {'color': '#f0f0f0'},
    }

    import pycha.bar
    chart = pycha.bar.VerticalBarChart(surface, options)

    #import pycha.line
    #chart = pycha.line.LineChart(surface, options)
    chart.addDataset(dataSet)
    chart.render()

    del chart
    del surface

    response = ''

    if inline:
        svg_buffer.seek(len(XML_PREAMBLE))
    else:
        svg_buffer.seek(0)
    return svg_buffer.read()

def colors_svg(request):
    """ render a pure SVG chart """
    response = HttpResponse(mimetype='image/svg+xml')
    response.write(colors_chart(inline = False))
    return response

def index(request):
    """ render a chart into the template """
    chart_svg = colors_chart(inline = True)

    return render_to_response(
        'shapes_index.html',
        { "chart" : chart_svg },
        mimetype='application/xhtml+xml')
</pre>
<p>An example project with the above code is available here:<br />
<a href="http://www.stuartaxon.com/wp-content/uploads/2011/02/pycha_django.zip">pycha_django</a></p>
<p>&nbsp;</p>
<p>[EDIT 25/2/2011] Fixed PyCha URL</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stuartaxon.com/2011/02/25/using-pycha-with-django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Cairo to generate SVG in Django</title>
		<link>http://www.stuartaxon.com/2010/02/03/using-cairo-to-generate-svg-in-django/</link>
		<comments>http://www.stuartaxon.com/2010/02/03/using-cairo-to-generate-svg-in-django/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 00:36:27 +0000</pubDate>
		<dc:creator>stu</dc:creator>
				<category><![CDATA[projects]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[cairo]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.stuartaxon.com/?p=217</guid>
		<description><![CDATA[Cairo is a 2D vector graphics api used by Firefox, Gtk and other desktop projects. I&#8217;m going to show here that it can also be used to generate web content, using Django. I&#8217;m going to port two examples from the Michael Urmans Cairo Tutorial for PyGTK Programmers. To understand the cairo and it&#8217;s drawing model [...]]]></description>
			<content:encoded><![CDATA[<p>Cairo is a 2D vector graphics api used by Firefox, Gtk and other desktop projects.</p>
<p>I&#8217;m going to show here that it can also be used to generate web content, using Django.</p>
<p>I&#8217;m going to port two examples from the Michael Urmans <a href="http://www.tortall.net/mu/wiki/PyGTKCairoTutorial">Cairo Tutorial  for PyGTK Programmers</a>.</p>
<p>To understand the cairo and it&#8217;s drawing model I&#8217;d recommend his his <a href="http://www.tortall.net/mu/wiki/CairoTutorial">Cairo Tutorial for Python  Programmers.</a></p>
<blockquote><p>Note:  In this example I&#8217;ll be generating SVGs&#8230;  as I.E. (as of 2010) does not support them, you might want to generate PNG or PDF &#8211; if you need to do this with cairo, look for one of the many cairo tutorials on the web.</p></blockquote>
<p>The example django project can be downloaded at the end of the article.</p>
<p><a href="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_shapes.png"><img class="alignnone size-full wp-image-223" title="django_cairo_shapes" src="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_shapes.png" alt="" width="302" height="230" /></a></p>
<p><span id="more-217"></span></p>
<h2>Prerequisites</h2>
<p>You&#8217;ll need django and pycairo installed&#8230; and a little bit of Django knowledge.</p>
<p>In Windows you can do use easy_install to get the python dependencies:</p>
<pre class="brush:shell">
easy_install pycairo
easy_install django
</pre>
<p>In linux you&#8217;ll need to use your favourite package manager.</p>
<p>Onto the code&#8230;</p>
<h2>Hosting Framework</h2>
<p>The pygtk example starts by building a simple hosting framework</p>
<pre class="brush:python">#! /usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk, gobject, cairo

# Create a GTK+ widget on which we will draw using Cairo
class Screen(gtk.DrawingArea):

    # Draw in response to an expose-event
    __gsignals__ = { "expose-event": "override" }

    # Handle the expose-event by drawing
    def do_expose_event(self, event):

        # Create the cairo context
        cr = self.window.cairo_create()

        # Restrict Cairo to the exposed area; avoid extra work
        cr.rectangle(event.area.x, event.area.y,
                event.area.width, event.area.height)
        cr.clip()

        self.draw(cr, *self.window.get_size())

    def draw(self, cr, width, height):
        # Fill the background with gray
        cr.set_source_rgb(0.5, 0.5, 0.5)
        cr.rectangle(0, 0, width, height)
        cr.fill()

# GTK mumbo-jumbo to show the widget in a window and quit when it's closed
def run(Widget):
    window = gtk.Window()
    window.connect("delete-event", gtk.main_quit)
    widget = Widget()
    widget.show()
    window.add(widget)
    window.present()
    gtk.main()

if __name__ == "__main__":
    run(Screen)
</pre>
<p>This needs to be made ready for the web and the Gtkisms removed:</p>
<p>cairodraw.py</p>
<pre class="brush:python">from cairo import Context, SVGSurface

# Create a GTK+ widget on which we will draw using Cairo
class CairoWidget:

    def __init__(self, Surface = None):
        if Surface == None:
            Surface = SVGSurface

        self.Surface = Surface

    def draw(self, cr, width, height):
        # Fill the background with gray
        cr.set_source_rgb(0.5, 0.5, 0.5)
        cr.rectangle(0, 0, width, height)
        cr.fill()

def draw_widget(dest, Widget, Surface = SVGSurface, width = 100, height = 100):
    """
    Convenience function to output CairoWidget to a buffer
    """
    widget = Widget(Surface)
    surface = widget.Surface(dest, width, height)
    widget.draw(Context(surface), width, height)
    surface.finish()
</pre>
<h3>Changes:</h3>
<ul>
<li> Screen class is now CairoWidget as Screen made less sense in this context.</li>
<li>run() is replaced with draw_widget() and it has some new parameters to help it be rendered with django.</li>
<li>The new file is &#8216;cairodraw.py&#8217;, not &#8216;framework.py&#8217;</li>
</ul>
<h2>Initial view&#8230;</h2>
<p>Heres the initial views.py</p>
<pre class="brush:python"># Create your views here.

from django.http import HttpResponse
from cairo import SVGSurface

import cairodraw

from math import pi

class Shapes(cairodraw.CairoWidget):
    def draw(self, cr, width, height):
        cr.set_source_rgb(0.5, 0.5, 0.5)
        cr.rectangle(0, 0, width, height)
        cr.fill()

        # draw a rectangle
        cr.set_source_rgb(1.0, 1.0, 1.0)
        cr.rectangle(10, 10, width - 20, height - 20)
        cr.fill()

        # draw lines
        cr.set_source_rgb(0.0, 0.0, 0.8)
        cr.move_to(width / 3.0, height / 3.0)
        cr.rel_line_to(0, height / 6.0)
        cr.move_to(2 * width / 3.0, height / 3.0)
        cr.rel_line_to(0, height / 6.0)
        cr.stroke()

        # and a circle
        cr.set_source_rgb(1.0, 0.0, 0.0)
        radius = min(width, height)
        cr.arc(width / 2.0, height / 2.0, radius / 2.0 - 20, 0, 2 * pi)
        cr.stroke()
        cr.arc(width / 2.0, height / 2.0, radius / 3.0 - 10, pi / 3, 2 * pi / 3)
        cr.stroke()

class Transform(cairodraw.CairoWidget):
    def draw(self, cr, width, height):
        cr.set_source_rgb(0.5, 0.5, 0.5)
        cr.rectangle(0, 0, width, height)
        cr.fill()

        # draw a rectangle
        cr.set_source_rgb(1.0, 1.0, 1.0)
        cr.rectangle(10, 10, width - 20, height - 20)
        cr.fill()

        # set up a transform so that (0,0) to (1,1)
        # maps to (20, 20) to (width - 40, height - 40)
        cr.translate(20, 20)
        cr.scale((width - 40) / 1.0, (height - 40) / 1.0)

        # draw lines
        cr.set_line_width(0.01)
        cr.set_source_rgb(0.0, 0.0, 0.8)
        cr.move_to(1 / 3.0, 1 / 3.0)
        cr.rel_line_to(0, 1 / 6.0)
        cr.move_to(2 / 3.0, 1 / 3.0)
        cr.rel_line_to(0, 1 / 6.0)
        cr.stroke()

        # and a circle
        cr.set_source_rgb(1.0, 0.0, 0.0)
        radius = 1
        cr.arc(0.5, 0.5, 0.5, 0, 2 * pi)
        cr.stroke()
        cr.arc(0.5, 0.5, 0.33, pi / 3, 2 * pi / 3)
        cr.stroke()

def shapes(request):
    response = HttpResponse(mimetype='image/svg+xml')
    cairodraw.draw_widget(response, Shapes)
    return response

def transform(request):
    response = HttpResponse(mimetype='image/svg+xml')
    cairodraw.draw_widget(response, Transform)
    return response
</pre>
<p>The main difference is that Shape and Transform are the same, except they extend cairodraw.CairoWidget.</p>
<h3>urls.py</h3>
<p>This is pretty straightforward.</p>
<pre>(r'^shapes/shapes/$', 'shapes.views.shapes'),</pre>
<pre>(r'^shapes/transform/$', 'shapes.views.transform'),</pre>
<h2>Taking stock&#8230;</h2>
<p>This is a good stage to try things out, heres the django project so far: <a href="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_1a.zip">django_cairo_1a</a>.</p>
<p>Enter the svgsite directory and run</p>
<pre>python manage.py runserver</pre>
<p>If all is well it should output something like this:</p>
<pre>Validating models...
0 errors found

Django version 1.1.1, using settings 'svgsite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.</pre>
<p>If you visit the two URLs in most browsers except I.E. the output will look like this:</p>
<h3>http://127.0.0.1:8000/shapes/transform/</h3>
<p><a href="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_transform.png"><img class="alignnone size-full wp-image-222" title="django_cairo_transform" src="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_transform.png" alt="" width="302" height="230" /></a></p>
<h3>http://127.0.0.1:8000/shapes/shapes/</h3>
<p><a href="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_shapes.png"><img class="alignnone size-full wp-image-223" title="django_cairo_shapes" src="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_shapes.png" alt="" width="302" height="230" /></a></p>
<h2>Inline SVG and templates&#8230;</h2>
<p>The previous examples output straight SVG, however it would be much better to be able to incorperate SVG into templates and use it with HTML.</p>
<p>Luckily modern browsers support this, and with a couple of changes we can make templates that will output mixed documents like <a href="http://jwatt.org/svg/demos/xhtml-with-inline-svg.xhtml">this</a>.</p>
<h3>Example template:</h3>
<pre>&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
 &lt;head&gt;
 &lt;title&gt;SVG embedded inline in XHTML&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
 &lt;h1&gt;Transform&lt;/h1&gt;
 &lt;div style="width:50%, height:40px"&gt;{{transform|safe}}&lt;/div&gt;
 &lt;div&gt;&lt;a href="transform"&gt;Full screen svg&lt;/a&gt;&lt;/div&gt;
 &lt;h1&gt;Shapes&lt;/h1&gt;
 &lt;div style="width:50%"&gt;{{shapes|safe}}&lt;/div&gt;
 &lt;div&gt;&lt;a href="shapes"&gt;Full screen svg&lt;/a&gt;&lt;/div&gt;
 &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The variables &#8216;shapes&#8217; and &#8216;transform&#8217; will be the svg, the key is the &#8216;|safe&#8217;, which means the XML won&#8217;t be processed by django.</p>
<h3>Changes to views to support inline</h3>
<p>To use templates the SVG data is needed as a string to pass to the template.</p>
<p>Heres an index view demonstrating this:</p>
<pre class="brush:python">def index(request):
    buff = StringIO()
    cairodraw.draw_widget(buff, Shapes)
    shapes = buff.getvalue()[38:]

    buff = StringIO()
    cairodraw.draw_widget(buff, Transform)
    transform = buff.getvalue()[38:]

    return render_to_response(
    'shapes_index.html',
    {"transform": transform, "shapes": shapes},
    mimetype='application/xhtml+xml')
</pre>
<p>The main differences are that -<br />
cairodraw.draw_widget() is called with a temporary buffer, we use templates.</p>
<blockquote>
<h4>Evil hack alert:</h4>
<p>OK, I did something naughty&#8230; notice the [38:] ?   Unfortunately django doesn&#8217;t like having  in the middle of the output.  I couldn&#8217;t find a way to turn this off so we chop it off the beginning of the string.</p></blockquote>
<p>Apart from the evil hack this works well and you get output like this:</p>
<h3>http://127.0.0.1:8000/shapes/</h3>
<p><a href="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_inline_svg.png"><img class="alignnone size-full wp-image-230" title="django_cairo_inline_svg" src="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_inline_svg.png" alt="" width="294" height="652" /></a></p>
<h1></h1>
<h2>Final Version</h2>
<p>Cool, every thing seems to be working !</p>
<p>The final version to try <a href="http://www.stuartaxon.com/wp-content/uploads/2010/02/django_cairo_1b.zip">django_cairo_1b</a>.</p>
<h2>Next time&#8230;.</h2>
<p>I&#8217;ll be looking at using a Cairo based library,  <a href="http://bitbucket.org/lgs/pycha/wiki/Home">PyCha</a> library with django to output smooth looking charts in SVG.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stuartaxon.com/2010/02/03/using-cairo-to-generate-svg-in-django/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

