| | 115 | |
| | 116 | = Creating a Line chart = |
| | 117 | The reportlab/graphics framework provides a Drawing object and many Shape objects, |
| | 118 | which include primitive shapes, and high-level objects like charts and legends. You |
| | 119 | can easily write your own too if you want to make dynamic bitmap buttons or fancy |
| | 120 | dashboard apps. |
| | 121 | |
| | 122 | The usual pattern we follow is to create a Drawing class with all of your widgets, |
| | 123 | some sensible default data, and any visual settings you want. Here is such a class, |
| | 124 | which has a bar chart and a string for the chart title. |
| | 125 | |
| | 126 | {{{ |
| | 127 | # mycharts.py |
| | 128 | from reportlab.graphics.shapes import Drawing, String |
| | 129 | from reportlab.graphics.charts.lineplots import LinePlot |
| | 130 | from reportlab.graphics.charts.lineplots import ScatterPlot |
| | 131 | from reportlab.lib import colors |
| | 132 | from reportlab.graphics.charts.legends import Legend |
| | 133 | from reportlab.graphics.charts.textlabels import Label |
| | 134 | from reportlab.graphics.widgets.markers import makeMarker |
| | 135 | |
| | 136 | |
| | 137 | class MyLineChartDrawing(Drawing): |
| | 138 | def __init__(self, width=600, height=400, *args, **kw): |
| | 139 | apply(Drawing.__init__,(self,width,height)+args,kw) |
| | 140 | self.add(LinePlot(), name='chart') |
| | 141 | |
| | 142 | self.add(String(200,180,'Hello World'), name='title') |
| | 143 | |
| | 144 | #set any shapes, fonts, colors you want here. We'll just |
| | 145 | #set a title font and place the chart within the drawing. |
| | 146 | #pick colors for all the lines, do as many as you need |
| | 147 | self.chart.x = 20 |
| | 148 | self.chart.y = 30 |
| | 149 | self.chart.width = self.width - 100 |
| | 150 | self.chart.height = self.height - 75 |
| | 151 | self.chart.lines[0].strokeColor = colors.blue |
| | 152 | self.chart.lines[1].strokeColor = colors.green |
| | 153 | self.chart.lines[2].strokeColor = colors.yellow |
| | 154 | self.chart.lines[3].strokeColor = colors.red |
| | 155 | self.chart.lines[4].strokeColor = colors.black |
| | 156 | self.chart.lines[5].strokeColor = colors.orange |
| | 157 | self.chart.lines[6].strokeColor = colors.cyan |
| | 158 | self.chart.lines[7].strokeColor = colors.magenta |
| | 159 | self.chart.lines[8].strokeColor = colors.brown |
| | 160 | |
| | 161 | self.chart.fillColor = colors.white |
| | 162 | self.title.fontName = 'Times-Roman' |
| | 163 | self.title.fontSize = 18 |
| | 164 | self.chart.data = [((0, 50), (100,100), (200,200), (250,210), (300,300), (400,500))] |
| | 165 | self.chart.xValueAxis.labels.fontSize = 12 |
| | 166 | self.chart.xValueAxis.forceZero = 0 |
| | 167 | self.chart.xValueAxis.gridEnd = 115 |
| | 168 | self.chart.xValueAxis.tickDown = 3 |
| | 169 | self.chart.xValueAxis.visibleGrid = 1 |
| | 170 | self.chart.yValueAxis.tickLeft = 3 |
| | 171 | self.chart.yValueAxis.labels.fontName = 'Times-Roman' |
| | 172 | self.chart.yValueAxis.labels.fontSize = 12 |
| | 173 | self.title.x = self.width/2 |
| | 174 | self.title.y = 0 |
| | 175 | self.title.textAnchor ='middle' |
| | 176 | self.add(Legend(),name='Legend') |
| | 177 | self.Legend.fontName = 'Times-Roman' |
| | 178 | self.Legend.fontSize = 12 |
| | 179 | self.Legend.x = self.width |
| | 180 | self.Legend.y = 85 |
| | 181 | self.Legend.dxTextSpace = 5 |
| | 182 | self.Legend.dy = 5 |
| | 183 | self.Legend.dx = 5 |
| | 184 | self.Legend.deltay = 5 |
| | 185 | self.Legend.alignment ='right' |
| | 186 | self.add(Label(),name='XLabel') |
| | 187 | self.XLabel.fontName = 'Times-Roman' |
| | 188 | self.XLabel.fontSize = 12 |
| | 189 | self.XLabel.x = 85 |
| | 190 | self.XLabel.y = 5 |
| | 191 | self.XLabel.textAnchor ='middle' |
| | 192 | #self.XLabel.height = 20 |
| | 193 | self.XLabel._text = "" |
| | 194 | self.add(Label(),name='YLabel') |
| | 195 | self.YLabel.fontName = 'Times-Roman' |
| | 196 | self.YLabel.fontSize = 12 |
| | 197 | self.YLabel.x = 2 |
| | 198 | self.YLabel.y = 80 |
| | 199 | self.YLabel.angle = 90 |
| | 200 | self.YLabel.textAnchor ='middle' |
| | 201 | self.YLabel._text = "" |
| | 202 | self.chart.yValueAxis.forceZero = 1 |
| | 203 | self.chart.xValueAxis.forceZero = 1 |
| | 204 | }}} |
| | 205 | |
| | 206 | = Integrating into Django = |
| | 207 | |
| | 208 | Now we add a view to our ''views.py''. |
| | 209 | |
| | 210 | {{{ |
| | 211 | |
| | 212 | def linechart(request): |
| | 213 | |
| | 214 | #instantiate a drawing object |
| | 215 | d = MyLineChartDrawing() |
| | 216 | |
| | 217 | #extract the request params of interest. |
| | 218 | #I suggest having a default for everything. |
| | 219 | |
| | 220 | |
| | 221 | d.height = 300 |
| | 222 | d.chart.height = 300 |
| | 223 | |
| | 224 | |
| | 225 | d.width = 300 |
| | 226 | d.chart.width = 300 |
| | 227 | |
| | 228 | d.title.text = request.session.get('Some custom title') |
| | 229 | |
| | 230 | |
| | 231 | |
| | 232 | d.XLabel._text = request.session.get('X Axis Labell') |
| | 233 | d.YLabel._text = request.session.get('Y Axis Label') |
| | 234 | |
| | 235 | d.chart.data = [((1,1), (2,2), (2.5,1), (3,3), (4,5)),((1,2), (2,3), (2.5,2), (3.5,5), (4,6))] |
| | 236 | |
| | 237 | |
| | 238 | |
| | 239 | labels = ["Label One","Label Two"] |
| | 240 | if labels: |
| | 241 | cnt=0 |
| | 242 | # set colors in the legend |
| | 243 | d.Legend.colorNamePairs = [] |
| | 244 | for label in labels: |
| | 245 | d.Legend.colorNamePairs.append((d.chart.lines[cnt].strokeColor,label)) |
| | 246 | cnt=cnt+1 |
| | 247 | |
| | 248 | |
| | 249 | #get a GIF (or PNG, JPG, or whatever) |
| | 250 | binaryStuff = d.asString('gif') |
| | 251 | return HttpResponse(binaryStuff, 'image/gif') |
| | 252 | }}} |
| | 253 | |
| | 254 | |
| | 255 | Finally, you need a URL mapping. In this case I have added this: |
| | 256 | |
| | 257 | {{{ |
| | 258 | (r'^charts/line/$', 'myapp.views.linechart'), |
| | 259 | |
| | 260 | }}} |
| | 261 | |
| | 262 | Now you can start Django, point your browser at the URL with no arguments, |
| | 263 | and should see the chart. Then try out a few parameters such as |
| | 264 | http://localhost:8000/charts/line?title=awesome |
| | 265 | and watch it redraw. |
| | 266 | |