A quick post on using Python Charts to generate nice SVG charts for your django website (I've had the code hanging around for ages - so should just post it). The code is based on the examples there, here I integrate it into Django.
To install you'll need to do
pip install pycha
Heres the code for a simple view to output a chart directly to SVG:
{: .alignnone .size-full .wp-image-291 width="401" height="316"}
```
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
```
The basic idea is that - 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's cairo surface. Once the data is in the buffer, it is rewound and played back to the Http Response.
Inline SVG
As is, this won'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's you decide if you need the preamble (full SVG output), or not (SVG fragment for inclusion in a page or another SVG):
```
Create your views here.
from StringIO import StringIO from django.http import HttpResponse from django.shortcuts import render_to_response
import cairo
XML_PREAMBLE = '<?xml version="1.0" encoding="UTF-8"?>'
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')
```
An example project with the above code is available here:
pycha_django
[EDIT 25/2/2011] Fixed PyCha URL