~openerp-groupes/openobject-server/6.0-fix-setup-windows

« back to all changes in this revision

Viewing changes to bin/reportlab/graphics/charts/barcharts.py

  • Committer: pinky
  • Date: 2006-12-07 13:41:40 UTC
  • Revision ID: pinky-3f10ee12cea3c4c75cef44ab04ad33ef47432907
New trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#Copyright ReportLab Europe Ltd. 2000-2004
 
2
#see license.txt for license details
 
3
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/graphics/charts/barcharts.py
 
4
"""This module defines a variety of Bar Chart components.
 
5
 
 
6
The basic flavors are Side-by-side, available in horizontal and
 
7
vertical versions.
 
8
 
 
9
Stacked and percentile bar charts to follow...
 
10
"""
 
11
__version__=''' $Id$ '''
 
12
 
 
13
import string, copy
 
14
from types import FunctionType, StringType
 
15
 
 
16
from reportlab.lib import colors
 
17
from reportlab.lib.validators import isNumber, isColor, isColorOrNone, isListOfStrings, SequenceOf, isBoolean, isNoneOrShape
 
18
from reportlab.lib.formatters import Formatter
 
19
from reportlab.lib.attrmap import AttrMap, AttrMapValue
 
20
from reportlab.pdfbase.pdfmetrics import stringWidth
 
21
from reportlab.graphics.widgetbase import Widget, TypedPropertyCollection, PropHolder
 
22
from reportlab.graphics.shapes import Line, Rect, Group, Drawing, NotImplementedError
 
23
from reportlab.graphics.charts.axes import XCategoryAxis, YValueAxis
 
24
from reportlab.graphics.charts.axes import YCategoryAxis, XValueAxis
 
25
from reportlab.graphics.charts.textlabels import BarChartLabel, NA_Label, NoneOrInstanceOfNA_Label
 
26
from reportlab.graphics.charts.areas import PlotArea
 
27
 
 
28
class BarChartProperties(PropHolder):
 
29
    _attrMap = AttrMap(
 
30
        strokeColor = AttrMapValue(isColorOrNone, desc='Color of the bar border.'),
 
31
        fillColor = AttrMapValue(isColorOrNone, desc='Color of the bar interior area.'),
 
32
        strokeWidth = AttrMapValue(isNumber, desc='Width of the bar border.'),
 
33
        symbol = AttrMapValue(None, desc='A widget to be used instead of a normal bar.'),
 
34
        )
 
35
 
 
36
    def __init__(self):
 
37
        self.strokeColor = None
 
38
        self.fillColor = colors.blue
 
39
        self.strokeWidth = 0.5
 
40
        self.symbol = None
 
41
 
 
42
# Bar chart classes.
 
43
class BarChart(PlotArea):
 
44
    "Abstract base class, unusable by itself."
 
45
 
 
46
    _attrMap = AttrMap(BASE=PlotArea,
 
47
        useAbsolute = AttrMapValue(isNumber, desc='Flag to use absolute spacing values.'),
 
48
        barWidth = AttrMapValue(isNumber, desc='The width of an individual bar.'),
 
49
        groupSpacing = AttrMapValue(isNumber, desc='Width between groups of bars.'),
 
50
        barSpacing = AttrMapValue(isNumber, desc='Width between individual bars.'),
 
51
        bars = AttrMapValue(None, desc='Handle of the individual bars.'),
 
52
        valueAxis = AttrMapValue(None, desc='Handle of the value axis.'),
 
53
        categoryAxis = AttrMapValue(None, desc='Handle of the category axis.'),
 
54
        data = AttrMapValue(None, desc='Data to be plotted, list of (lists of) numbers.'),
 
55
        barLabels = AttrMapValue(None, desc='Handle to the list of bar labels.'),
 
56
        barLabelFormat = AttrMapValue(None, desc='Formatting string or function used for bar labels.'),
 
57
        barLabelCallOut = AttrMapValue(None, desc='Callout function(label)\nlabel._callOutInfo = (self,g,rowNo,colNo,x,y,width,height,x00,y00,x0,y0)'),
 
58
        barLabelArray = AttrMapValue(None, desc='explicit array of bar label values, must match size of data if present.'),
 
59
        reversePlotOrder = AttrMapValue(isBoolean, desc='If true, reverse common category plot order.'),
 
60
        naLabel = AttrMapValue(NoneOrInstanceOfNA_Label, desc='Label to use for N/A values.'),
 
61
        annotations = AttrMapValue(None, desc='list of callables, will be called with self, xscale, yscale.'),
 
62
        )
 
63
 
 
64
    def __init__(self):
 
65
        assert self.__class__.__name__ not in ('BarChart','BarChart3D'), 'Abstract Class %s Instantiated' % self.__class__.__name__
 
66
 
 
67
        if self._flipXY:
 
68
            self.categoryAxis = YCategoryAxis()
 
69
            self.valueAxis = XValueAxis()
 
70
        else:
 
71
            self.categoryAxis = XCategoryAxis()
 
72
            self.valueAxis = YValueAxis()
 
73
 
 
74
        PlotArea.__init__(self)
 
75
        self.barSpacing = 0
 
76
        self.reversePlotOrder = 0
 
77
 
 
78
 
 
79
        # this defines two series of 3 points.  Just an example.
 
80
        self.data = [(100,110,120,130),
 
81
                    (70, 80, 85, 90)]
 
82
 
 
83
        # control bar spacing. is useAbsolute = 1 then
 
84
        # the next parameters are in points; otherwise
 
85
        # they are 'proportions' and are normalized to
 
86
        # fit the available space.  Half a barSpacing
 
87
        # is allocated at the beginning and end of the
 
88
        # chart.
 
89
        self.useAbsolute = 0   #- not done yet
 
90
        self.barWidth = 10
 
91
        self.groupSpacing = 5
 
92
        self.barSpacing = 0
 
93
 
 
94
        self.barLabels = TypedPropertyCollection(BarChartLabel)
 
95
        self.barLabels.boxAnchor = 'c'
 
96
        self.barLabels.textAnchor = 'middle'
 
97
        self.barLabelFormat = None
 
98
        self.barLabelArray = None
 
99
        # this says whether the origin is inside or outside
 
100
        # the bar - +10 means put the origin ten points
 
101
        # above the tip of the bar if value > 0, or ten
 
102
        # points inside if bar value < 0.  This is different
 
103
        # to label dx/dy which are not dependent on the
 
104
        # sign of the data.
 
105
        self.barLabels.nudge = 0
 
106
 
 
107
        # if you have multiple series, by default they butt
 
108
        # together.
 
109
 
 
110
        # we really need some well-designed default lists of
 
111
        # colors e.g. from Tufte.  These will be used in a
 
112
        # cycle to set the fill color of each series.
 
113
        self.bars = TypedPropertyCollection(BarChartProperties)
 
114
##        self.bars.symbol = None
 
115
        self.bars.strokeWidth = 1
 
116
        self.bars.strokeColor = colors.black
 
117
 
 
118
        self.bars[0].fillColor = colors.red
 
119
        self.bars[1].fillColor = colors.green
 
120
        self.bars[2].fillColor = colors.blue
 
121
        self.naLabel = None#NA_Label()
 
122
 
 
123
 
 
124
    def demo(self):
 
125
        """Shows basic use of a bar chart"""
 
126
        if self.__class__.__name__=='BarChart':
 
127
            raise NotImplementedError, 'Abstract Class BarChart has no demo'
 
128
        drawing = Drawing(200, 100)
 
129
        bc = self.__class__()
 
130
        drawing.add(bc)
 
131
        return drawing
 
132
 
 
133
    def _getConfigureData(self):
 
134
        cA = self.categoryAxis
 
135
        data = self.data
 
136
        if cA.style not in ('parallel','parallel_3d'):
 
137
            _data = data
 
138
            data = max(map(len,_data))*[0]
 
139
            for d in _data:
 
140
                for i in xrange(len(d)):
 
141
                    data[i] = data[i] + (d[i] or 0)
 
142
            data = list(_data) + [data]
 
143
        self._configureData = data
 
144
 
 
145
    def _getMinMax(self):
 
146
        '''Attempt to return the data range'''
 
147
        self._getConfigureData()
 
148
        self.valueAxis._setRange(self._configureData)
 
149
        return self.valueAxis._valueMin, self.valueAxis._valueMax
 
150
 
 
151
    def _drawBegin(self,org,length):
 
152
        '''Position and configure value axis, return crossing value'''
 
153
        vA = self.valueAxis
 
154
        vA.setPosition(self.x, self.y, length)
 
155
        self._getConfigureData()
 
156
        vA.configure(self._configureData)
 
157
 
 
158
        # if zero is in chart, put the other axis there, otherwise use low
 
159
        crossesAt = vA.scale(0)
 
160
        if crossesAt > org+length or crossesAt<org:
 
161
            crossesAt = org
 
162
        return crossesAt
 
163
 
 
164
    def _drawFinish(self):
 
165
        '''finalize the drawing of a barchart'''
 
166
        cA = self.categoryAxis
 
167
        vA = self.valueAxis
 
168
        cA.configure(self._configureData)
 
169
        self.calcBarPositions()
 
170
        g = Group()
 
171
        g.add(self.makeBackground())
 
172
 
 
173
        # ensure any axes have correct spacing set
 
174
        # for grids. It sucks that we have to do
 
175
        # this here.
 
176
        if self._flipXY == 0:
 
177
            vA.gridStart = cA._x
 
178
            vA.gridEnd = cA._x+cA._length
 
179
            cA.gridStart = vA._y
 
180
            cA.gridEnd = vA._y+vA._length
 
181
        else:
 
182
            cA.gridStart = vA._x
 
183
            cA.gridEnd = vA._x+vA._length
 
184
            vA.gridStart = cA._y
 
185
            vA.gridEnd = cA._y+cA._length
 
186
 
 
187
        cA.makeGrid(g,parent=self)
 
188
        vA.makeGrid(g,parent=self)
 
189
        g.add(self.makeBars())
 
190
        g.add(cA)
 
191
        g.add(vA)
 
192
        for a in getattr(self,'annotations',()): g.add(a(self,cA.scale,vA.scale))
 
193
        del self._configureData
 
194
        return g
 
195
 
 
196
 
 
197
    def calcBarPositions(self):
 
198
        """Works out where they go. default vertical.
 
199
 
 
200
        Sets an attribute _barPositions which is a list of
 
201
        lists of (x, y, width, height) matching the data.
 
202
        """
 
203
 
 
204
        flipXY = self._flipXY
 
205
        if flipXY:
 
206
            org = self.y
 
207
        else:
 
208
            org = self.x
 
209
        cA = self.categoryAxis
 
210
        cScale = cA.scale
 
211
 
 
212
        data = self.data
 
213
        seriesCount = self._seriesCount = len(data)
 
214
        self._rowLength = rowLength = max(map(len,data))
 
215
        groupSpacing, barSpacing, barWidth = self.groupSpacing, self.barSpacing, self.barWidth
 
216
        style = self.categoryAxis.style
 
217
        if style=='parallel':
 
218
            groupWidth = groupSpacing+(seriesCount*barWidth)+(seriesCount-1)*barSpacing
 
219
            bGap = barWidth+barSpacing
 
220
        else:
 
221
            accum = rowLength*[0]
 
222
            groupWidth = groupSpacing+barWidth
 
223
            bGap = 0
 
224
        self._groupWidth = groupWidth
 
225
        useAbsolute = self.useAbsolute
 
226
 
 
227
        if useAbsolute:
 
228
            # bar dimensions are absolute
 
229
            normFactor = 1.0
 
230
        else:
 
231
            # bar dimensions are normalized to fit.  How wide
 
232
            # notionally is one group of bars?
 
233
            availWidth = cScale(0)[1]
 
234
            normFactor = availWidth/float(groupWidth)
 
235
            if self.debug:
 
236
                print '%d series, %d points per series' % (seriesCount, self._rowLength)
 
237
                print 'width = %d group + (%d bars * %d barWidth) + (%d gaps * %d interBar) = %d total' % (
 
238
                    groupSpacing, seriesCount, barWidth,
 
239
                    seriesCount-1, barSpacing, groupWidth)
 
240
 
 
241
        # 'Baseline' correction...
 
242
        vA = self.valueAxis
 
243
        vScale = vA.scale
 
244
        vm, vM = vA._valueMin, vA._valueMax
 
245
        if vm <= 0 <= vM:
 
246
            baseLine = vScale(0)
 
247
        elif 0 < vm:
 
248
            baseLine = vScale(vm)
 
249
        elif vM < 0:
 
250
            baseLine = vScale(vM)
 
251
        self._baseLine = baseLine
 
252
 
 
253
        COLUMNS = range(max(map(len,data)))
 
254
        if useAbsolute:
 
255
            _cScale = cA._scale
 
256
 
 
257
        self._normFactor = normFactor
 
258
        width = self.barWidth*normFactor
 
259
        self._barPositions = []
 
260
        reversePlotOrder = self.reversePlotOrder
 
261
        for rowNo in range(seriesCount):
 
262
            barRow = []
 
263
            if reversePlotOrder:
 
264
                xVal = seriesCount-1 - rowNo
 
265
            else:
 
266
                xVal = rowNo
 
267
            xVal = 0.5*groupSpacing+xVal*bGap
 
268
            for colNo in COLUMNS:
 
269
                datum = data[rowNo][colNo]
 
270
 
 
271
                # Ufff...
 
272
                if useAbsolute:
 
273
                    x = groupWidth*_cScale(colNo) + xVal + org
 
274
                else:
 
275
                    (g, gW) = cScale(colNo)
 
276
                    x = g + normFactor*xVal
 
277
 
 
278
                if datum is None:
 
279
                    height = None
 
280
                    y = baseLine
 
281
                else:
 
282
                    if style not in ('parallel','parallel_3d'):
 
283
                        y = vScale(accum[colNo])
 
284
                        if y<baseLine: y = baseLine
 
285
                        accum[colNo] = accum[colNo] + datum
 
286
                        datum = accum[colNo]
 
287
                    else:
 
288
                        y = baseLine
 
289
                    height = vScale(datum) - y
 
290
                    if -1e-8<height<=1e-8:
 
291
                        height = 1e-8
 
292
                        if datum<-1e-8: height = -1e-8
 
293
                barRow.append(flipXY and (y,x,height,width) or (x, y, width, height))
 
294
 
 
295
            self._barPositions.append(barRow)
 
296
 
 
297
 
 
298
    def _getLabelText(self, rowNo, colNo):
 
299
        '''return formatted label text'''
 
300
        labelFmt = self.barLabelFormat
 
301
        if labelFmt is None:
 
302
            labelText = None
 
303
        elif labelFmt == 'values':
 
304
            labelText = self.barLabelArray[rowNo][colNo]
 
305
        elif type(labelFmt) is StringType:
 
306
            labelText = labelFmt % self.data[rowNo][colNo]
 
307
        elif callable(labelFmt):
 
308
            labelText = labelFmt(self.data[rowNo][colNo])
 
309
        else:
 
310
            msg = "Unknown formatter type %s, expected string or function" % labelFmt
 
311
            raise Exception, msg
 
312
        return labelText
 
313
 
 
314
    def _labelXY(self,label,x,y,width,height):
 
315
        'Compute x, y for a label'
 
316
        if self._flipXY:
 
317
            return x + width + (width>=0 and 1 or -1) * label.nudge, y + 0.5*height
 
318
        else:
 
319
            return x + 0.5*width, y + height + (height>=0 and 1 or -1) * label.nudge
 
320
 
 
321
    def _addBarLabel(self, g, rowNo, colNo, x, y, width, height):
 
322
        text = self._getLabelText(rowNo,colNo)
 
323
        if text:
 
324
            self._addLabel(text, self.barLabels[(rowNo, colNo)], g, rowNo, colNo, x, y, width, height)
 
325
 
 
326
    def _addNABarLabel(self, g, rowNo, colNo, x, y, width, height):
 
327
        na = self.naLabel
 
328
        if na and na.text:
 
329
            na = copy.copy(na)
 
330
            v = self.valueAxis._valueMax<=0 and -1e-8 or 1e-8
 
331
            if width is None: width = v
 
332
            if height is None: height = v
 
333
            self._addLabel(na.text, na, g, rowNo, colNo, x, y, width, height)
 
334
 
 
335
    def _addLabel(self, text, label, g, rowNo, colNo, x, y, width, height):
 
336
        if label.visible:
 
337
            labelWidth = stringWidth(text, label.fontName, label.fontSize)
 
338
            x0, y0 = self._labelXY(label,x,y,width,height)
 
339
            flipXY = self._flipXY
 
340
            if flipXY:
 
341
                pm = width
 
342
            else:
 
343
                pm = height
 
344
            label._pmv = pm #the plus minus val
 
345
            fixedEnd = getattr(label,'fixedEnd', None)
 
346
            if fixedEnd is not None:
 
347
                v = fixedEnd._getValue(self,pm)
 
348
                x00, y00 = x0, y0
 
349
                if flipXY:
 
350
                    x0 = v
 
351
                else:
 
352
                    y0 = v
 
353
            else:
 
354
                if flipXY:
 
355
                    x00 = x0
 
356
                    y00 = y+height/2.0
 
357
                else:
 
358
                    x00 = x+width/2.0
 
359
                    y00 = y0
 
360
            fixedStart = getattr(label,'fixedStart', None)
 
361
            if fixedStart is not None:
 
362
                v = fixedStart._getValue(self,pm)
 
363
                if flipXY:
 
364
                    x00 = v
 
365
                else:
 
366
                    y00 = v
 
367
 
 
368
            if pm<0:
 
369
                if flipXY:
 
370
                    dx = -2*label.dx
 
371
                    dy = 0
 
372
                else:
 
373
                    dy = -2*label.dy
 
374
                    dx = 0
 
375
            else:
 
376
                dy = dx = 0
 
377
            label.setOrigin(x0+dx, y0+dy)
 
378
            label.setText(text)
 
379
            sC, sW = label.lineStrokeColor, label.lineStrokeWidth
 
380
            if sC and sW: g.insert(0,Line(x00,y00,x0,y0, strokeColor=sC, strokeWidth=sW))
 
381
            g.add(label)
 
382
            alx = getattr(self,'barLabelCallOut',None)
 
383
            if alx:
 
384
                label._callOutInfo = (self,g,rowNo,colNo,x,y,width,height,x00,y00,x0,y0)
 
385
                alx(label)
 
386
                del label._callOutInfo
 
387
 
 
388
    def _makeBar(self,g,x,y,width,height,rowNo,style):
 
389
        r = Rect(x, y, width, height)
 
390
        r.strokeWidth = style.strokeWidth
 
391
        r.fillColor = style.fillColor
 
392
        r.strokeColor = style.strokeColor
 
393
        g.add(r)
 
394
 
 
395
    def _makeBars(self,g,lg):
 
396
        lenData = len(self.data)
 
397
        bars = self.bars
 
398
        for rowNo in range(lenData):
 
399
            row = self._barPositions[rowNo]
 
400
            styleCount = len(bars)
 
401
            styleIdx = rowNo % styleCount
 
402
            rowStyle = bars[styleIdx]
 
403
            for colNo in range(len(row)):
 
404
                barPos = row[colNo]
 
405
                style = bars.has_key((styleIdx,colNo)) and bars[(styleIdx,colNo)] or rowStyle
 
406
                (x, y, width, height) = barPos
 
407
                if None in (width,height):
 
408
                    self._addNABarLabel(lg,rowNo,colNo,x,y,width,height)
 
409
                    continue
 
410
 
 
411
                # Draw a rectangular symbol for each data item,
 
412
                # or a normal colored rectangle.
 
413
                symbol = None
 
414
                if hasattr(style, 'symbol'):
 
415
                    symbol = copy.deepcopy(style.symbol)
 
416
                elif hasattr(self.bars, 'symbol'):
 
417
                    symbol = self.bars.symbol
 
418
 
 
419
                if symbol:
 
420
                    symbol.x = x
 
421
                    symbol.y = y
 
422
                    symbol.width = width
 
423
                    symbol.height = height
 
424
                    g.add(symbol)
 
425
                elif abs(width)>1e-7 and abs(height)>=1e-7 and (style.fillColor is not None or style.strokeColor is not None):
 
426
                    self._makeBar(g,x,y,width,height,rowNo,style)
 
427
 
 
428
                self._addBarLabel(lg,rowNo,colNo,x,y,width,height)
 
429
 
 
430
    def makeBars(self):
 
431
        g = Group()
 
432
        lg = Group()
 
433
        self._makeBars(g,lg)
 
434
        g.add(lg)
 
435
        return g
 
436
 
 
437
    def _desiredCategoryAxisLength(self):
 
438
        '''for dynamically computing the desired category axis length'''
 
439
        style = self.categoryAxis.style
 
440
        data = self.data
 
441
        n = len(data)
 
442
        m = max(map(len,data))
 
443
        if style=='parallel':
 
444
            groupWidth = (n-1)*self.barSpacing+n*self.barWidth
 
445
        else:
 
446
            groupWidth = self.barWidth
 
447
        return m*(self.groupSpacing+groupWidth)
 
448
 
 
449
    def draw(self):
 
450
        cA, vA = self.categoryAxis, self.valueAxis
 
451
        if vA: ovAjA, vA.joinAxis = vA.joinAxis, cA
 
452
        if cA: ocAjA, cA.joinAxis = cA.joinAxis, vA
 
453
        if self._flipXY:
 
454
            cA.setPosition(self._drawBegin(self.x,self.width), self.y, self.height)
 
455
        else:
 
456
            cA.setPosition(self.x, self._drawBegin(self.y,self.height), self.width)
 
457
        return self._drawFinish()
 
458
 
 
459
class VerticalBarChart(BarChart):
 
460
    "Vertical bar chart with multiple side-by-side bars."
 
461
    _flipXY = 0
 
462
 
 
463
class HorizontalBarChart(BarChart):
 
464
    "Horizontal bar chart with multiple side-by-side bars."
 
465
    _flipXY = 1
 
466
 
 
467
class _FakeGroup:
 
468
    def __init__(self, cmp=None):
 
469
        self._data = []
 
470
        self._cmp = cmp
 
471
 
 
472
    def add(self,what):
 
473
        self._data.append(what)
 
474
 
 
475
    def value(self):
 
476
        return self._data
 
477
 
 
478
    def sort(self):
 
479
        self._data.sort(self._cmp)
 
480
 
 
481
class BarChart3D(BarChart):
 
482
    _attrMap = AttrMap(BASE=BarChart,
 
483
        theta_x = AttrMapValue(isNumber, desc='dx/dz'),
 
484
        theta_y = AttrMapValue(isNumber, desc='dy/dz'),
 
485
        zDepth = AttrMapValue(isNumber, desc='depth of an individual series'),
 
486
        zSpace = AttrMapValue(isNumber, desc='z gap around series'),
 
487
        )
 
488
    theta_x = .5
 
489
    theta_y = .5
 
490
    zDepth = None
 
491
    zSpace = None
 
492
 
 
493
    def calcBarPositions(self):
 
494
        BarChart.calcBarPositions(self)
 
495
        seriesCount = self._seriesCount
 
496
        zDepth = self.zDepth
 
497
        if zDepth is None: zDepth = self.barWidth
 
498
        zSpace = self.zSpace
 
499
        if zSpace is None: zSpace = self.barSpacing
 
500
        if self.categoryAxis.style=='parallel_3d':
 
501
            _3d_depth = seriesCount*zDepth+(seriesCount+1)*zSpace
 
502
        else:
 
503
            _3d_depth = zDepth + 2*zSpace
 
504
        _3d_depth *= self._normFactor
 
505
        self._3d_dx = self.theta_x*_3d_depth
 
506
        self._3d_dy = self.theta_y*_3d_depth
 
507
 
 
508
    def _calc_z0(self,rowNo):
 
509
        zDepth = self.zDepth
 
510
        if zDepth is None: zDepth = self.barWidth
 
511
        zSpace = self.zSpace
 
512
        if zSpace is None: zSpace = self.barSpacing
 
513
        if self.categoryAxis.style=='parallel_3d':
 
514
            z0 = self._normFactor*(rowNo*(zDepth+zSpace)+zSpace)
 
515
        else:
 
516
            z0 = self._normFactor*zSpace
 
517
        return z0
 
518
 
 
519
    def _makeBar(self,g,x,y,width,height,rowNo,style):
 
520
        zDepth = self.zDepth
 
521
        if zDepth is None: zDepth = self.barWidth
 
522
        zSpace = self.zSpace
 
523
        if zSpace is None: zSpace = self.barSpacing
 
524
        z0 = self._calc_z0(rowNo)
 
525
        z1 = z0 + zDepth*self._normFactor
 
526
        if width<0:
 
527
            x += width
 
528
            width = -width
 
529
        x += z0*self.theta_x
 
530
        y += z0*self.theta_y
 
531
        if self._flipXY:
 
532
            y += zSpace
 
533
        else:
 
534
            x += zSpace
 
535
        g.add((0,z0,z1,x,y,width,height,rowNo,style))
 
536
 
 
537
    def _addBarLabel(self, g, rowNo, colNo, x, y, width, height):
 
538
        z0 = self._calc_z0(rowNo)
 
539
        zSpace = self.zSpace
 
540
        if zSpace is None: zSpace = self.barSpacing
 
541
        z1 = z0
 
542
        x += z0*self.theta_x
 
543
        y += z0*self.theta_y
 
544
        if self._flipXY:
 
545
            y += zSpace
 
546
        else:
 
547
            x += zSpace
 
548
        g.add((1,z0,z1,x,y,width,height,rowNo,colNo))
 
549
 
 
550
    def makeBars(self):
 
551
        from utils3d import _draw_3d_bar
 
552
        fg = _FakeGroup(cmp=self._cmpZ)
 
553
        self._makeBars(fg,fg)
 
554
        fg.sort()
 
555
        g = Group()
 
556
        theta_x = self.theta_x
 
557
        theta_y = self.theta_y
 
558
        for t in fg.value():
 
559
            if t[0]==1:
 
560
                z0,z1,x,y,width,height,rowNo,colNo = t[1:]
 
561
                BarChart._addBarLabel(self,g,rowNo,colNo,x,y,width,height)
 
562
            elif t[0]==0:
 
563
                z0,z1,x,y,width,height,rowNo,style = t[1:]
 
564
                dz = z1 - z0
 
565
                _draw_3d_bar(g, x, x+width, y, y+height, dz*theta_x, dz*theta_y,
 
566
                            fillColor=style.fillColor, fillColorShaded=None,
 
567
                            strokeColor=style.strokeColor, strokeWidth=style.strokeWidth,
 
568
                            shading=0.45)
 
569
        return g
 
570
 
 
571
class VerticalBarChart3D(BarChart3D,VerticalBarChart):
 
572
    _cmpZ=lambda self,a,b:cmp((-a[1],a[3],a[0],-a[4]),(-b[1],b[3],b[0],-b[4]))
 
573
 
 
574
class HorizontalBarChart3D(BarChart3D,HorizontalBarChart):
 
575
    _cmpZ = lambda self,a,b: cmp((-a[1],a[4],a[0],-a[3]),(-b[1],b[4],b[0],-b[3]))   #t, z0, z1, x, y = a[:5]
 
576
 
 
577
# Vertical samples.
 
578
def sampleV0a():
 
579
    "A slightly pathologic bar chart with only TWO data items."
 
580
 
 
581
    drawing = Drawing(400, 200)
 
582
 
 
583
    data = [(13, 20)]
 
584
 
 
585
    bc = VerticalBarChart()
 
586
    bc.x = 50
 
587
    bc.y = 50
 
588
    bc.height = 125
 
589
    bc.width = 300
 
590
    bc.data = data
 
591
 
 
592
    bc.strokeColor = colors.black
 
593
 
 
594
    bc.valueAxis.valueMin = 0
 
595
    bc.valueAxis.valueMax = 60
 
596
    bc.valueAxis.valueStep = 15
 
597
 
 
598
    bc.categoryAxis.labels.boxAnchor = 'ne'
 
599
    bc.categoryAxis.labels.dx = 8
 
600
    bc.categoryAxis.labels.dy = -2
 
601
    bc.categoryAxis.labels.angle = 30
 
602
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
603
 
 
604
    drawing.add(bc)
 
605
 
 
606
    return drawing
 
607
 
 
608
 
 
609
def sampleV0b():
 
610
    "A pathologic bar chart with only ONE data item."
 
611
 
 
612
    drawing = Drawing(400, 200)
 
613
 
 
614
    data = [(42,)]
 
615
 
 
616
    bc = VerticalBarChart()
 
617
    bc.x = 50
 
618
    bc.y = 50
 
619
    bc.height = 125
 
620
    bc.width = 300
 
621
    bc.data = data
 
622
    bc.strokeColor = colors.black
 
623
 
 
624
    bc.valueAxis.valueMin = 0
 
625
    bc.valueAxis.valueMax = 50
 
626
    bc.valueAxis.valueStep = 15
 
627
 
 
628
    bc.categoryAxis.labels.boxAnchor = 'ne'
 
629
    bc.categoryAxis.labels.dx = 8
 
630
    bc.categoryAxis.labels.dy = -2
 
631
    bc.categoryAxis.labels.angle = 30
 
632
    bc.categoryAxis.categoryNames = ['Jan-99']
 
633
 
 
634
    drawing.add(bc)
 
635
 
 
636
    return drawing
 
637
 
 
638
 
 
639
def sampleV0c():
 
640
    "A really pathologic bar chart with NO data items at all!"
 
641
 
 
642
    drawing = Drawing(400, 200)
 
643
 
 
644
    data = [()]
 
645
 
 
646
    bc = VerticalBarChart()
 
647
    bc.x = 50
 
648
    bc.y = 50
 
649
    bc.height = 125
 
650
    bc.width = 300
 
651
    bc.data = data
 
652
    bc.strokeColor = colors.black
 
653
 
 
654
    bc.valueAxis.valueMin = 0
 
655
    bc.valueAxis.valueMax = 60
 
656
    bc.valueAxis.valueStep = 15
 
657
 
 
658
    bc.categoryAxis.labels.boxAnchor = 'ne'
 
659
    bc.categoryAxis.labels.dx = 8
 
660
    bc.categoryAxis.labels.dy = -2
 
661
    bc.categoryAxis.categoryNames = []
 
662
 
 
663
    drawing.add(bc)
 
664
 
 
665
    return drawing
 
666
 
 
667
 
 
668
def sampleV1():
 
669
    "Sample of multi-series bar chart."
 
670
 
 
671
    drawing = Drawing(400, 200)
 
672
 
 
673
    data = [
 
674
            (13, 5, 20, 22, 37, 45, 19, 4),
 
675
            (14, 6, 21, 23, 38, 46, 20, 5)
 
676
            ]
 
677
 
 
678
    bc = VerticalBarChart()
 
679
    bc.x = 50
 
680
    bc.y = 50
 
681
    bc.height = 125
 
682
    bc.width = 300
 
683
    bc.data = data
 
684
    bc.strokeColor = colors.black
 
685
 
 
686
    bc.valueAxis.valueMin = 0
 
687
    bc.valueAxis.valueMax = 60
 
688
    bc.valueAxis.valueStep = 15
 
689
 
 
690
    bc.categoryAxis.labels.boxAnchor = 'ne'
 
691
    bc.categoryAxis.labels.dx = 8
 
692
    bc.categoryAxis.labels.dy = -2
 
693
    bc.categoryAxis.labels.angle = 30
 
694
 
 
695
    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
 
696
    catNames = map(lambda n:n+'-99', catNames)
 
697
    bc.categoryAxis.categoryNames = catNames
 
698
    drawing.add(bc)
 
699
 
 
700
    return drawing
 
701
 
 
702
 
 
703
def sampleV2a():
 
704
    "Sample of multi-series bar chart."
 
705
 
 
706
    data = [(2.4, -5.7, 2, 5, 9.2),
 
707
            (0.6, -4.9, -3, 4, 6.8)
 
708
            ]
 
709
 
 
710
    labels = ("Q3 2000", "Year to Date", "12 months",
 
711
              "Annualised\n3 years", "Since 07.10.99")
 
712
 
 
713
    drawing = Drawing(400, 200)
 
714
 
 
715
    bc = VerticalBarChart()
 
716
    bc.x = 50
 
717
    bc.y = 50
 
718
    bc.height = 120
 
719
    bc.width = 300
 
720
    bc.data = data
 
721
 
 
722
    bc.barSpacing = 0
 
723
    bc.groupSpacing = 10
 
724
    bc.barWidth = 10
 
725
 
 
726
    bc.valueAxis.valueMin = -15
 
727
    bc.valueAxis.valueMax = +15
 
728
    bc.valueAxis.valueStep = 5
 
729
    bc.valueAxis.labels.fontName = 'Helvetica'
 
730
    bc.valueAxis.labels.fontSize = 8
 
731
    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
 
732
    bc.valueAxis.labels.textAnchor = 'middle'
 
733
 
 
734
    bc.categoryAxis.categoryNames = labels
 
735
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
736
    bc.categoryAxis.labels.fontSize = 8
 
737
    bc.categoryAxis.labels.dy = -60
 
738
 
 
739
    drawing.add(bc)
 
740
 
 
741
    return drawing
 
742
 
 
743
 
 
744
def sampleV2b():
 
745
    "Sample of multi-series bar chart."
 
746
 
 
747
    data = [(2.4, -5.7, 2, 5, 9.2),
 
748
            (0.6, -4.9, -3, 4, 6.8)
 
749
            ]
 
750
 
 
751
    labels = ("Q3 2000", "Year to Date", "12 months",
 
752
              "Annualised\n3 years", "Since 07.10.99")
 
753
 
 
754
    drawing = Drawing(400, 200)
 
755
 
 
756
    bc = VerticalBarChart()
 
757
    bc.x = 50
 
758
    bc.y = 50
 
759
    bc.height = 120
 
760
    bc.width = 300
 
761
    bc.data = data
 
762
 
 
763
    bc.barSpacing = 5
 
764
    bc.groupSpacing = 10
 
765
    bc.barWidth = 10
 
766
 
 
767
    bc.valueAxis.valueMin = -15
 
768
    bc.valueAxis.valueMax = +15
 
769
    bc.valueAxis.valueStep = 5
 
770
    bc.valueAxis.labels.fontName = 'Helvetica'
 
771
    bc.valueAxis.labels.fontSize = 8
 
772
    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
 
773
    bc.valueAxis.labels.textAnchor = 'middle'
 
774
 
 
775
    bc.categoryAxis.categoryNames = labels
 
776
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
777
    bc.categoryAxis.labels.fontSize = 8
 
778
    bc.categoryAxis.labels.dy = -60
 
779
 
 
780
    drawing.add(bc)
 
781
 
 
782
    return drawing
 
783
 
 
784
 
 
785
def sampleV2c():
 
786
    "Sample of multi-series bar chart."
 
787
 
 
788
    data = [(2.4, -5.7, 2, 5, 9.99),
 
789
            (0.6, -4.9, -3, 4, 9.99)
 
790
            ]
 
791
 
 
792
    labels = ("Q3 2000", "Year to Date", "12 months",
 
793
              "Annualised\n3 years", "Since 07.10.99")
 
794
 
 
795
    drawing = Drawing(400, 200)
 
796
 
 
797
    bc = VerticalBarChart()
 
798
    bc.x = 50
 
799
    bc.y = 50
 
800
    bc.height = 120
 
801
    bc.width = 300
 
802
    bc.data = data
 
803
 
 
804
    bc.barSpacing = 2
 
805
    bc.groupSpacing = 10
 
806
    bc.barWidth = 10
 
807
 
 
808
    bc.valueAxis.valueMin = -15
 
809
    bc.valueAxis.valueMax = +15
 
810
    bc.valueAxis.valueStep = 5
 
811
    bc.valueAxis.labels.fontName = 'Helvetica'
 
812
    bc.valueAxis.labels.fontSize = 8
 
813
 
 
814
    bc.categoryAxis.categoryNames = labels
 
815
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
816
    bc.categoryAxis.labels.fontSize = 8
 
817
    bc.valueAxis.labels.boxAnchor = 'n'
 
818
    bc.valueAxis.labels.textAnchor = 'middle'
 
819
    bc.categoryAxis.labels.dy = -60
 
820
 
 
821
    bc.barLabels.nudge = 10
 
822
 
 
823
    bc.barLabelFormat = '%0.2f'
 
824
    bc.barLabels.dx = 0
 
825
    bc.barLabels.dy = 0
 
826
    bc.barLabels.boxAnchor = 'n'  # irrelevant (becomes 'c')
 
827
    bc.barLabels.fontName = 'Helvetica'
 
828
    bc.barLabels.fontSize = 6
 
829
 
 
830
    drawing.add(bc)
 
831
 
 
832
    return drawing
 
833
 
 
834
 
 
835
def sampleV3():
 
836
    "Faked horizontal bar chart using a vertical real one (deprecated)."
 
837
 
 
838
    names = ("UK Equities", "US Equities", "European Equities", "Japanese Equities",
 
839
              "Pacific (ex Japan) Equities", "Emerging Markets Equities",
 
840
              "UK Bonds", "Overseas Bonds", "UK Index-Linked", "Cash")
 
841
 
 
842
    series1 = (-1.5, 0.3, 0.5, 1.0, 0.8, 0.7, 0.4, 0.1, 1.0, 0.3)
 
843
    series2 = (0.0, 0.33, 0.55, 1.1, 0.88, 0.77, 0.44, 0.11, 1.10, 0.33)
 
844
 
 
845
    assert len(names) == len(series1), "bad data"
 
846
    assert len(names) == len(series2), "bad data"
 
847
 
 
848
    drawing = Drawing(400, 200)
 
849
 
 
850
    bc = VerticalBarChart()
 
851
    bc.x = 0
 
852
    bc.y = 0
 
853
    bc.height = 100
 
854
    bc.width = 150
 
855
    bc.data = (series1,)
 
856
    bc.bars.fillColor = colors.green
 
857
 
 
858
    bc.barLabelFormat = '%0.2f'
 
859
    bc.barLabels.dx = 0
 
860
    bc.barLabels.dy = 0
 
861
    bc.barLabels.boxAnchor = 'w' # irrelevant (becomes 'c')
 
862
    bc.barLabels.angle = 90
 
863
    bc.barLabels.fontName = 'Helvetica'
 
864
    bc.barLabels.fontSize = 6
 
865
    bc.barLabels.nudge = 10
 
866
 
 
867
    bc.valueAxis.visible = 0
 
868
    bc.valueAxis.valueMin = -2
 
869
    bc.valueAxis.valueMax = +2
 
870
    bc.valueAxis.valueStep = 1
 
871
 
 
872
    bc.categoryAxis.tickUp = 0
 
873
    bc.categoryAxis.tickDown = 0
 
874
    bc.categoryAxis.categoryNames = names
 
875
    bc.categoryAxis.labels.angle = 90
 
876
    bc.categoryAxis.labels.boxAnchor = 'w'
 
877
    bc.categoryAxis.labels.dx = 0
 
878
    bc.categoryAxis.labels.dy = -125
 
879
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
880
    bc.categoryAxis.labels.fontSize = 6
 
881
 
 
882
    g = Group(bc)
 
883
    g.translate(100, 175)
 
884
    g.rotate(-90)
 
885
 
 
886
    drawing.add(g)
 
887
 
 
888
    return drawing
 
889
 
 
890
 
 
891
def sampleV4a():
 
892
    "A bar chart showing value axis region starting at *exactly* zero."
 
893
 
 
894
    drawing = Drawing(400, 200)
 
895
 
 
896
    data = [(13, 20)]
 
897
 
 
898
    bc = VerticalBarChart()
 
899
    bc.x = 50
 
900
    bc.y = 50
 
901
    bc.height = 125
 
902
    bc.width = 300
 
903
    bc.data = data
 
904
 
 
905
    bc.strokeColor = colors.black
 
906
 
 
907
    bc.valueAxis.valueMin = 0
 
908
    bc.valueAxis.valueMax = 60
 
909
    bc.valueAxis.valueStep = 15
 
910
 
 
911
    bc.categoryAxis.labels.boxAnchor = 'n'
 
912
    bc.categoryAxis.labels.dy = -5
 
913
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
914
 
 
915
    drawing.add(bc)
 
916
 
 
917
    return drawing
 
918
 
 
919
 
 
920
def sampleV4b():
 
921
    "A bar chart showing value axis region starting *below* zero."
 
922
 
 
923
    drawing = Drawing(400, 200)
 
924
 
 
925
    data = [(13, 20)]
 
926
 
 
927
    bc = VerticalBarChart()
 
928
    bc.x = 50
 
929
    bc.y = 50
 
930
    bc.height = 125
 
931
    bc.width = 300
 
932
    bc.data = data
 
933
 
 
934
    bc.strokeColor = colors.black
 
935
 
 
936
    bc.valueAxis.valueMin = -10
 
937
    bc.valueAxis.valueMax = 60
 
938
    bc.valueAxis.valueStep = 15
 
939
 
 
940
    bc.categoryAxis.labels.boxAnchor = 'n'
 
941
    bc.categoryAxis.labels.dy = -5
 
942
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
943
 
 
944
    drawing.add(bc)
 
945
 
 
946
    return drawing
 
947
 
 
948
 
 
949
def sampleV4c():
 
950
    "A bar chart showing value axis region staring *above* zero."
 
951
 
 
952
    drawing = Drawing(400, 200)
 
953
 
 
954
    data = [(13, 20)]
 
955
 
 
956
    bc = VerticalBarChart()
 
957
    bc.x = 50
 
958
    bc.y = 50
 
959
    bc.height = 125
 
960
    bc.width = 300
 
961
    bc.data = data
 
962
 
 
963
    bc.strokeColor = colors.black
 
964
 
 
965
    bc.valueAxis.valueMin = 10
 
966
    bc.valueAxis.valueMax = 60
 
967
    bc.valueAxis.valueStep = 15
 
968
 
 
969
    bc.categoryAxis.labels.boxAnchor = 'n'
 
970
    bc.categoryAxis.labels.dy = -5
 
971
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
972
 
 
973
    drawing.add(bc)
 
974
 
 
975
    return drawing
 
976
 
 
977
 
 
978
def sampleV4d():
 
979
    "A bar chart showing value axis region entirely *below* zero."
 
980
 
 
981
    drawing = Drawing(400, 200)
 
982
 
 
983
    data = [(-13, -20)]
 
984
 
 
985
    bc = VerticalBarChart()
 
986
    bc.x = 50
 
987
    bc.y = 50
 
988
    bc.height = 125
 
989
    bc.width = 300
 
990
    bc.data = data
 
991
 
 
992
    bc.strokeColor = colors.black
 
993
 
 
994
    bc.valueAxis.valueMin = -30
 
995
    bc.valueAxis.valueMax = -10
 
996
    bc.valueAxis.valueStep = 15
 
997
 
 
998
    bc.categoryAxis.labels.boxAnchor = 'n'
 
999
    bc.categoryAxis.labels.dy = -5
 
1000
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1001
 
 
1002
    drawing.add(bc)
 
1003
 
 
1004
    return drawing
 
1005
 
 
1006
 
 
1007
###
 
1008
 
 
1009
##dataSample5 = [(10, 20), (20, 30), (30, 40), (40, 50), (50, 60)]
 
1010
##dataSample5 = [(10, 60), (20, 50), (30, 40), (40, 30), (50, 20)]
 
1011
dataSample5 = [(10, 60), (20, 50), (30, 40), (40, 30)]
 
1012
 
 
1013
def sampleV5a():
 
1014
    "A simple bar chart with no expressed spacing attributes."
 
1015
 
 
1016
    drawing = Drawing(400, 200)
 
1017
 
 
1018
    data = dataSample5
 
1019
 
 
1020
    bc = VerticalBarChart()
 
1021
    bc.x = 50
 
1022
    bc.y = 50
 
1023
    bc.height = 125
 
1024
    bc.width = 300
 
1025
    bc.data = data
 
1026
    bc.strokeColor = colors.black
 
1027
 
 
1028
    bc.valueAxis.valueMin = 0
 
1029
    bc.valueAxis.valueMax = 60
 
1030
    bc.valueAxis.valueStep = 15
 
1031
 
 
1032
    bc.categoryAxis.labels.boxAnchor = 'n'
 
1033
    bc.categoryAxis.labels.dy = -5
 
1034
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1035
 
 
1036
    drawing.add(bc)
 
1037
 
 
1038
    return drawing
 
1039
 
 
1040
 
 
1041
def sampleV5b():
 
1042
    "A simple bar chart with proportional spacing."
 
1043
 
 
1044
    drawing = Drawing(400, 200)
 
1045
 
 
1046
    data = dataSample5
 
1047
 
 
1048
    bc = VerticalBarChart()
 
1049
    bc.x = 50
 
1050
    bc.y = 50
 
1051
    bc.height = 125
 
1052
    bc.width = 300
 
1053
    bc.data = data
 
1054
    bc.strokeColor = colors.black
 
1055
 
 
1056
    bc.useAbsolute = 0
 
1057
    bc.barWidth = 40
 
1058
    bc.groupSpacing = 20
 
1059
    bc.barSpacing = 10
 
1060
 
 
1061
    bc.valueAxis.valueMin = 0
 
1062
    bc.valueAxis.valueMax = 60
 
1063
    bc.valueAxis.valueStep = 15
 
1064
 
 
1065
    bc.categoryAxis.labels.boxAnchor = 'n'
 
1066
    bc.categoryAxis.labels.dy = -5
 
1067
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1068
 
 
1069
    drawing.add(bc)
 
1070
 
 
1071
    return drawing
 
1072
 
 
1073
 
 
1074
def sampleV5c1():
 
1075
    "Make sampe simple bar chart but with absolute spacing."
 
1076
 
 
1077
    drawing = Drawing(400, 200)
 
1078
 
 
1079
    data = dataSample5
 
1080
 
 
1081
    bc = VerticalBarChart()
 
1082
    bc.x = 50
 
1083
    bc.y = 50
 
1084
    bc.height = 125
 
1085
    bc.width = 300
 
1086
    bc.data = data
 
1087
    bc.strokeColor = colors.black
 
1088
 
 
1089
    bc.useAbsolute = 1
 
1090
    bc.barWidth = 40
 
1091
    bc.groupSpacing = 0
 
1092
    bc.barSpacing = 0
 
1093
 
 
1094
    bc.valueAxis.valueMin = 0
 
1095
    bc.valueAxis.valueMax = 60
 
1096
    bc.valueAxis.valueStep = 15
 
1097
 
 
1098
    bc.categoryAxis.labels.boxAnchor = 'n'
 
1099
    bc.categoryAxis.labels.dy = -5
 
1100
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1101
 
 
1102
    drawing.add(bc)
 
1103
 
 
1104
    return drawing
 
1105
 
 
1106
 
 
1107
def sampleV5c2():
 
1108
    "Make sampe simple bar chart but with absolute spacing."
 
1109
 
 
1110
    drawing = Drawing(400, 200)
 
1111
 
 
1112
    data = dataSample5
 
1113
 
 
1114
    bc = VerticalBarChart()
 
1115
    bc.x = 50
 
1116
    bc.y = 50
 
1117
    bc.height = 125
 
1118
    bc.width = 300
 
1119
    bc.data = data
 
1120
    bc.strokeColor = colors.black
 
1121
 
 
1122
    bc.useAbsolute = 1
 
1123
    bc.barWidth = 40
 
1124
    bc.groupSpacing = 20
 
1125
    bc.barSpacing = 0
 
1126
 
 
1127
    bc.valueAxis.valueMin = 0
 
1128
    bc.valueAxis.valueMax = 60
 
1129
    bc.valueAxis.valueStep = 15
 
1130
 
 
1131
    bc.categoryAxis.labels.boxAnchor = 'n'
 
1132
    bc.categoryAxis.labels.dy = -5
 
1133
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1134
 
 
1135
    drawing.add(bc)
 
1136
 
 
1137
    return drawing
 
1138
 
 
1139
 
 
1140
def sampleV5c3():
 
1141
    "Make sampe simple bar chart but with absolute spacing."
 
1142
 
 
1143
    drawing = Drawing(400, 200)
 
1144
 
 
1145
    data = dataSample5
 
1146
 
 
1147
    bc = VerticalBarChart()
 
1148
    bc.x = 50
 
1149
    bc.y = 50
 
1150
    bc.height = 125
 
1151
    bc.width = 300
 
1152
    bc.data = data
 
1153
    bc.strokeColor = colors.black
 
1154
 
 
1155
    bc.useAbsolute = 1
 
1156
    bc.barWidth = 40
 
1157
    bc.groupSpacing = 0
 
1158
    bc.barSpacing = 10
 
1159
 
 
1160
    bc.valueAxis.valueMin = 0
 
1161
    bc.valueAxis.valueMax = 60
 
1162
    bc.valueAxis.valueStep = 15
 
1163
 
 
1164
    bc.categoryAxis.labels.boxAnchor = 'n'
 
1165
    bc.categoryAxis.labels.dy = -5
 
1166
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1167
 
 
1168
    drawing.add(bc)
 
1169
 
 
1170
    return drawing
 
1171
 
 
1172
 
 
1173
def sampleV5c4():
 
1174
    "Make sampe simple bar chart but with absolute spacing."
 
1175
 
 
1176
    drawing = Drawing(400, 200)
 
1177
 
 
1178
    data = dataSample5
 
1179
 
 
1180
    bc = VerticalBarChart()
 
1181
    bc.x = 50
 
1182
    bc.y = 50
 
1183
    bc.height = 125
 
1184
    bc.width = 300
 
1185
    bc.data = data
 
1186
    bc.strokeColor = colors.black
 
1187
 
 
1188
    bc.useAbsolute = 1
 
1189
    bc.barWidth = 40
 
1190
    bc.groupSpacing = 20
 
1191
    bc.barSpacing = 10
 
1192
 
 
1193
    bc.valueAxis.valueMin = 0
 
1194
    bc.valueAxis.valueMax = 60
 
1195
    bc.valueAxis.valueStep = 15
 
1196
 
 
1197
    bc.categoryAxis.labels.boxAnchor = 'n'
 
1198
    bc.categoryAxis.labels.dy = -5
 
1199
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1200
 
 
1201
    drawing.add(bc)
 
1202
 
 
1203
    return drawing
 
1204
 
 
1205
 
 
1206
# Horizontal samples
 
1207
 
 
1208
def sampleH0a():
 
1209
    "Make a slightly pathologic bar chart with only TWO data items."
 
1210
 
 
1211
    drawing = Drawing(400, 200)
 
1212
 
 
1213
    data = [(13, 20)]
 
1214
 
 
1215
    bc = HorizontalBarChart()
 
1216
    bc.x = 50
 
1217
    bc.y = 50
 
1218
    bc.height = 125
 
1219
    bc.width = 300
 
1220
    bc.data = data
 
1221
 
 
1222
    bc.strokeColor = colors.black
 
1223
 
 
1224
    bc.valueAxis.valueMin = 0
 
1225
    bc.valueAxis.valueMax = 60
 
1226
    bc.valueAxis.valueStep = 15
 
1227
 
 
1228
    bc.categoryAxis.labels.boxAnchor = 'se'
 
1229
    bc.categoryAxis.labels.angle = 30
 
1230
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1231
 
 
1232
    drawing.add(bc)
 
1233
 
 
1234
    return drawing
 
1235
 
 
1236
 
 
1237
def sampleH0b():
 
1238
    "Make a pathologic bar chart with only ONE data item."
 
1239
 
 
1240
    drawing = Drawing(400, 200)
 
1241
 
 
1242
    data = [(42,)]
 
1243
 
 
1244
    bc = HorizontalBarChart()
 
1245
    bc.x = 50
 
1246
    bc.y = 50
 
1247
    bc.height = 125
 
1248
    bc.width = 300
 
1249
    bc.data = data
 
1250
    bc.strokeColor = colors.black
 
1251
 
 
1252
    bc.valueAxis.valueMin = 0
 
1253
    bc.valueAxis.valueMax = 50
 
1254
    bc.valueAxis.valueStep = 15
 
1255
 
 
1256
    bc.categoryAxis.labels.boxAnchor = 'se'
 
1257
    bc.categoryAxis.labels.angle = 30
 
1258
    bc.categoryAxis.categoryNames = ['Jan-99']
 
1259
 
 
1260
    drawing.add(bc)
 
1261
 
 
1262
    return drawing
 
1263
 
 
1264
 
 
1265
def sampleH0c():
 
1266
    "Make a really pathologic bar chart with NO data items at all!"
 
1267
 
 
1268
    drawing = Drawing(400, 200)
 
1269
 
 
1270
    data = [()]
 
1271
 
 
1272
    bc = HorizontalBarChart()
 
1273
    bc.x = 50
 
1274
    bc.y = 50
 
1275
    bc.height = 125
 
1276
    bc.width = 300
 
1277
    bc.data = data
 
1278
    bc.strokeColor = colors.black
 
1279
 
 
1280
    bc.valueAxis.valueMin = 0
 
1281
    bc.valueAxis.valueMax = 60
 
1282
    bc.valueAxis.valueStep = 15
 
1283
 
 
1284
    bc.categoryAxis.labels.boxAnchor = 'se'
 
1285
    bc.categoryAxis.labels.angle = 30
 
1286
    bc.categoryAxis.categoryNames = []
 
1287
 
 
1288
    drawing.add(bc)
 
1289
 
 
1290
    return drawing
 
1291
 
 
1292
 
 
1293
def sampleH1():
 
1294
    "Sample of multi-series bar chart."
 
1295
 
 
1296
    drawing = Drawing(400, 200)
 
1297
 
 
1298
    data = [
 
1299
            (13, 5, 20, 22, 37, 45, 19, 4),
 
1300
            (14, 6, 21, 23, 38, 46, 20, 5)
 
1301
            ]
 
1302
 
 
1303
    bc = HorizontalBarChart()
 
1304
    bc.x = 50
 
1305
    bc.y = 50
 
1306
    bc.height = 125
 
1307
    bc.width = 300
 
1308
    bc.data = data
 
1309
    bc.strokeColor = colors.black
 
1310
 
 
1311
    bc.valueAxis.valueMin = 0
 
1312
    bc.valueAxis.valueMax = 60
 
1313
    bc.valueAxis.valueStep = 15
 
1314
 
 
1315
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1316
    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
 
1317
    catNames = map(lambda n:n+'-99', catNames)
 
1318
    bc.categoryAxis.categoryNames = catNames
 
1319
    drawing.add(bc, 'barchart')
 
1320
 
 
1321
    return drawing
 
1322
 
 
1323
 
 
1324
def sampleH2a():
 
1325
    "Sample of multi-series bar chart."
 
1326
 
 
1327
    data = [(2.4, -5.7, 2, 5, 9.2),
 
1328
            (0.6, -4.9, -3, 4, 6.8)
 
1329
            ]
 
1330
 
 
1331
    labels = ("Q3 2000", "Year to Date", "12 months",
 
1332
              "Annualised\n3 years", "Since 07.10.99")
 
1333
 
 
1334
    drawing = Drawing(400, 200)
 
1335
 
 
1336
    bc = HorizontalBarChart()
 
1337
    bc.x = 80
 
1338
    bc.y = 50
 
1339
    bc.height = 120
 
1340
    bc.width = 300
 
1341
    bc.data = data
 
1342
 
 
1343
    bc.barSpacing = 0
 
1344
    bc.groupSpacing = 10
 
1345
    bc.barWidth = 10
 
1346
 
 
1347
    bc.valueAxis.valueMin = -15
 
1348
    bc.valueAxis.valueMax = +15
 
1349
    bc.valueAxis.valueStep = 5
 
1350
    bc.valueAxis.labels.fontName = 'Helvetica'
 
1351
    bc.valueAxis.labels.fontSize = 8
 
1352
    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
 
1353
    bc.valueAxis.labels.textAnchor = 'middle'
 
1354
    bc.valueAxis.configure(bc.data)
 
1355
 
 
1356
    bc.categoryAxis.categoryNames = labels
 
1357
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
1358
    bc.categoryAxis.labels.fontSize = 8
 
1359
    bc.categoryAxis.labels.dx = -150
 
1360
 
 
1361
    drawing.add(bc)
 
1362
 
 
1363
    return drawing
 
1364
 
 
1365
 
 
1366
def sampleH2b():
 
1367
    "Sample of multi-series bar chart."
 
1368
 
 
1369
    data = [(2.4, -5.7, 2, 5, 9.2),
 
1370
            (0.6, -4.9, -3, 4, 6.8)
 
1371
            ]
 
1372
 
 
1373
    labels = ("Q3 2000", "Year to Date", "12 months",
 
1374
              "Annualised\n3 years", "Since 07.10.99")
 
1375
 
 
1376
    drawing = Drawing(400, 200)
 
1377
 
 
1378
    bc = HorizontalBarChart()
 
1379
    bc.x = 80
 
1380
    bc.y = 50
 
1381
    bc.height = 120
 
1382
    bc.width = 300
 
1383
    bc.data = data
 
1384
 
 
1385
    bc.barSpacing = 5
 
1386
    bc.groupSpacing = 10
 
1387
    bc.barWidth = 10
 
1388
 
 
1389
    bc.valueAxis.valueMin = -15
 
1390
    bc.valueAxis.valueMax = +15
 
1391
    bc.valueAxis.valueStep = 5
 
1392
    bc.valueAxis.labels.fontName = 'Helvetica'
 
1393
    bc.valueAxis.labels.fontSize = 8
 
1394
    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
 
1395
    bc.valueAxis.labels.textAnchor = 'middle'
 
1396
 
 
1397
    bc.categoryAxis.categoryNames = labels
 
1398
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
1399
    bc.categoryAxis.labels.fontSize = 8
 
1400
    bc.categoryAxis.labels.dx = -150
 
1401
 
 
1402
    drawing.add(bc)
 
1403
 
 
1404
    return drawing
 
1405
 
 
1406
 
 
1407
def sampleH2c():
 
1408
    "Sample of multi-series bar chart."
 
1409
 
 
1410
    data = [(2.4, -5.7, 2, 5, 9.99),
 
1411
            (0.6, -4.9, -3, 4, 9.99)
 
1412
            ]
 
1413
 
 
1414
    labels = ("Q3 2000", "Year to Date", "12 months",
 
1415
              "Annualised\n3 years", "Since 07.10.99")
 
1416
 
 
1417
    drawing = Drawing(400, 200)
 
1418
 
 
1419
    bc = HorizontalBarChart()
 
1420
    bc.x = 80
 
1421
    bc.y = 50
 
1422
    bc.height = 120
 
1423
    bc.width = 300
 
1424
    bc.data = data
 
1425
 
 
1426
    bc.barSpacing = 2
 
1427
    bc.groupSpacing = 10
 
1428
    bc.barWidth = 10
 
1429
 
 
1430
    bc.valueAxis.valueMin = -15
 
1431
    bc.valueAxis.valueMax = +15
 
1432
    bc.valueAxis.valueStep = 5
 
1433
    bc.valueAxis.labels.fontName = 'Helvetica'
 
1434
    bc.valueAxis.labels.fontSize = 8
 
1435
    bc.valueAxis.labels.boxAnchor = 'n'
 
1436
    bc.valueAxis.labels.textAnchor = 'middle'
 
1437
 
 
1438
    bc.categoryAxis.categoryNames = labels
 
1439
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
1440
    bc.categoryAxis.labels.fontSize = 8
 
1441
    bc.categoryAxis.labels.dx = -150
 
1442
 
 
1443
    bc.barLabels.nudge = 10
 
1444
 
 
1445
    bc.barLabelFormat = '%0.2f'
 
1446
    bc.barLabels.dx = 0
 
1447
    bc.barLabels.dy = 0
 
1448
    bc.barLabels.boxAnchor = 'n'  # irrelevant (becomes 'c')
 
1449
    bc.barLabels.fontName = 'Helvetica'
 
1450
    bc.barLabels.fontSize = 6
 
1451
 
 
1452
    drawing.add(bc)
 
1453
 
 
1454
    return drawing
 
1455
 
 
1456
 
 
1457
def sampleH3():
 
1458
    "A really horizontal bar chart (compared to the equivalent faked one)."
 
1459
 
 
1460
    names = ("UK Equities", "US Equities", "European Equities", "Japanese Equities",
 
1461
              "Pacific (ex Japan) Equities", "Emerging Markets Equities",
 
1462
              "UK Bonds", "Overseas Bonds", "UK Index-Linked", "Cash")
 
1463
 
 
1464
    series1 = (-1.5, 0.3, 0.5, 1.0, 0.8, 0.7, 0.4, 0.1, 1.0, 0.3)
 
1465
    series2 = (0.0, 0.33, 0.55, 1.1, 0.88, 0.77, 0.44, 0.11, 1.10, 0.33)
 
1466
 
 
1467
    assert len(names) == len(series1), "bad data"
 
1468
    assert len(names) == len(series2), "bad data"
 
1469
 
 
1470
    drawing = Drawing(400, 200)
 
1471
 
 
1472
    bc = HorizontalBarChart()
 
1473
    bc.x = 100
 
1474
    bc.y = 20
 
1475
    bc.height = 150
 
1476
    bc.width = 250
 
1477
    bc.data = (series1,)
 
1478
    bc.bars.fillColor = colors.green
 
1479
 
 
1480
    bc.barLabelFormat = '%0.2f'
 
1481
    bc.barLabels.dx = 0
 
1482
    bc.barLabels.dy = 0
 
1483
    bc.barLabels.boxAnchor = 'w' # irrelevant (becomes 'c')
 
1484
    bc.barLabels.fontName = 'Helvetica'
 
1485
    bc.barLabels.fontSize = 6
 
1486
    bc.barLabels.nudge = 10
 
1487
 
 
1488
    bc.valueAxis.visible = 0
 
1489
    bc.valueAxis.valueMin = -2
 
1490
    bc.valueAxis.valueMax = +2
 
1491
    bc.valueAxis.valueStep = 1
 
1492
 
 
1493
    bc.categoryAxis.tickLeft = 0
 
1494
    bc.categoryAxis.tickRight = 0
 
1495
    bc.categoryAxis.categoryNames = names
 
1496
    bc.categoryAxis.labels.boxAnchor = 'w'
 
1497
    bc.categoryAxis.labels.dx = -170
 
1498
    bc.categoryAxis.labels.fontName = 'Helvetica'
 
1499
    bc.categoryAxis.labels.fontSize = 6
 
1500
 
 
1501
    g = Group(bc)
 
1502
    drawing.add(g)
 
1503
 
 
1504
    return drawing
 
1505
 
 
1506
 
 
1507
def sampleH4a():
 
1508
    "A bar chart showing value axis region starting at *exactly* zero."
 
1509
 
 
1510
    drawing = Drawing(400, 200)
 
1511
 
 
1512
    data = [(13, 20)]
 
1513
 
 
1514
    bc = HorizontalBarChart()
 
1515
    bc.x = 50
 
1516
    bc.y = 50
 
1517
    bc.height = 125
 
1518
    bc.width = 300
 
1519
    bc.data = data
 
1520
 
 
1521
    bc.strokeColor = colors.black
 
1522
 
 
1523
    bc.valueAxis.valueMin = 0
 
1524
    bc.valueAxis.valueMax = 60
 
1525
    bc.valueAxis.valueStep = 15
 
1526
 
 
1527
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1528
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1529
 
 
1530
    drawing.add(bc)
 
1531
 
 
1532
    return drawing
 
1533
 
 
1534
 
 
1535
def sampleH4b():
 
1536
    "A bar chart showing value axis region starting *below* zero."
 
1537
 
 
1538
    drawing = Drawing(400, 200)
 
1539
 
 
1540
    data = [(13, 20)]
 
1541
 
 
1542
    bc = HorizontalBarChart()
 
1543
    bc.x = 50
 
1544
    bc.y = 50
 
1545
    bc.height = 125
 
1546
    bc.width = 300
 
1547
    bc.data = data
 
1548
 
 
1549
    bc.strokeColor = colors.black
 
1550
 
 
1551
    bc.valueAxis.valueMin = -10
 
1552
    bc.valueAxis.valueMax = 60
 
1553
    bc.valueAxis.valueStep = 15
 
1554
 
 
1555
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1556
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1557
 
 
1558
    drawing.add(bc)
 
1559
 
 
1560
    return drawing
 
1561
 
 
1562
 
 
1563
def sampleH4c():
 
1564
    "A bar chart showing value axis region starting *above* zero."
 
1565
 
 
1566
    drawing = Drawing(400, 200)
 
1567
 
 
1568
    data = [(13, 20)]
 
1569
 
 
1570
    bc = HorizontalBarChart()
 
1571
    bc.x = 50
 
1572
    bc.y = 50
 
1573
    bc.height = 125
 
1574
    bc.width = 300
 
1575
    bc.data = data
 
1576
 
 
1577
    bc.strokeColor = colors.black
 
1578
 
 
1579
    bc.valueAxis.valueMin = 10
 
1580
    bc.valueAxis.valueMax = 60
 
1581
    bc.valueAxis.valueStep = 15
 
1582
 
 
1583
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1584
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1585
 
 
1586
    drawing.add(bc)
 
1587
 
 
1588
    return drawing
 
1589
 
 
1590
 
 
1591
def sampleH4d():
 
1592
    "A bar chart showing value axis region entirely *below* zero."
 
1593
 
 
1594
    drawing = Drawing(400, 200)
 
1595
 
 
1596
    data = [(-13, -20)]
 
1597
 
 
1598
    bc = HorizontalBarChart()
 
1599
    bc.x = 50
 
1600
    bc.y = 50
 
1601
    bc.height = 125
 
1602
    bc.width = 300
 
1603
    bc.data = data
 
1604
 
 
1605
    bc.strokeColor = colors.black
 
1606
 
 
1607
    bc.valueAxis.valueMin = -30
 
1608
    bc.valueAxis.valueMax = -10
 
1609
    bc.valueAxis.valueStep = 15
 
1610
 
 
1611
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1612
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1613
 
 
1614
    drawing.add(bc)
 
1615
 
 
1616
    return drawing
 
1617
 
 
1618
 
 
1619
dataSample5 = [(10, 60), (20, 50), (30, 40), (40, 30)]
 
1620
 
 
1621
def sampleH5a():
 
1622
    "A simple bar chart with no expressed spacing attributes."
 
1623
 
 
1624
    drawing = Drawing(400, 200)
 
1625
 
 
1626
    data = dataSample5
 
1627
 
 
1628
    bc = HorizontalBarChart()
 
1629
    bc.x = 50
 
1630
    bc.y = 50
 
1631
    bc.height = 125
 
1632
    bc.width = 300
 
1633
    bc.data = data
 
1634
    bc.strokeColor = colors.black
 
1635
 
 
1636
    bc.valueAxis.valueMin = 0
 
1637
    bc.valueAxis.valueMax = 60
 
1638
    bc.valueAxis.valueStep = 15
 
1639
 
 
1640
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1641
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1642
 
 
1643
    drawing.add(bc)
 
1644
 
 
1645
    return drawing
 
1646
 
 
1647
 
 
1648
def sampleH5b():
 
1649
    "A simple bar chart with proportional spacing."
 
1650
 
 
1651
    drawing = Drawing(400, 200)
 
1652
 
 
1653
    data = dataSample5
 
1654
 
 
1655
    bc = HorizontalBarChart()
 
1656
    bc.x = 50
 
1657
    bc.y = 50
 
1658
    bc.height = 125
 
1659
    bc.width = 300
 
1660
    bc.data = data
 
1661
    bc.strokeColor = colors.black
 
1662
 
 
1663
    bc.useAbsolute = 0
 
1664
    bc.barWidth = 40
 
1665
    bc.groupSpacing = 20
 
1666
    bc.barSpacing = 10
 
1667
 
 
1668
    bc.valueAxis.valueMin = 0
 
1669
    bc.valueAxis.valueMax = 60
 
1670
    bc.valueAxis.valueStep = 15
 
1671
 
 
1672
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1673
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1674
 
 
1675
    drawing.add(bc)
 
1676
 
 
1677
    return drawing
 
1678
 
 
1679
 
 
1680
def sampleH5c1():
 
1681
    "A simple bar chart with absolute spacing."
 
1682
 
 
1683
    drawing = Drawing(400, 200)
 
1684
 
 
1685
    data = dataSample5
 
1686
 
 
1687
    bc = HorizontalBarChart()
 
1688
    bc.x = 50
 
1689
    bc.y = 50
 
1690
    bc.height = 125
 
1691
    bc.width = 300
 
1692
    bc.data = data
 
1693
    bc.strokeColor = colors.black
 
1694
 
 
1695
    bc.useAbsolute = 1
 
1696
    bc.barWidth = 10
 
1697
    bc.groupSpacing = 0
 
1698
    bc.barSpacing = 0
 
1699
 
 
1700
    bc.valueAxis.valueMin = 0
 
1701
    bc.valueAxis.valueMax = 60
 
1702
    bc.valueAxis.valueStep = 15
 
1703
 
 
1704
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1705
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1706
 
 
1707
    drawing.add(bc)
 
1708
 
 
1709
    return drawing
 
1710
 
 
1711
 
 
1712
def sampleH5c2():
 
1713
    "Simple bar chart with absolute spacing."
 
1714
 
 
1715
    drawing = Drawing(400, 200)
 
1716
 
 
1717
    data = dataSample5
 
1718
 
 
1719
    bc = HorizontalBarChart()
 
1720
    bc.x = 50
 
1721
    bc.y = 50
 
1722
    bc.height = 125
 
1723
    bc.width = 300
 
1724
    bc.data = data
 
1725
    bc.strokeColor = colors.black
 
1726
 
 
1727
    bc.useAbsolute = 1
 
1728
    bc.barWidth = 10
 
1729
    bc.groupSpacing = 20
 
1730
    bc.barSpacing = 0
 
1731
 
 
1732
    bc.valueAxis.valueMin = 0
 
1733
    bc.valueAxis.valueMax = 60
 
1734
    bc.valueAxis.valueStep = 15
 
1735
 
 
1736
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1737
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1738
 
 
1739
    drawing.add(bc)
 
1740
 
 
1741
    return drawing
 
1742
 
 
1743
 
 
1744
def sampleH5c3():
 
1745
    "Simple bar chart with absolute spacing."
 
1746
 
 
1747
    drawing = Drawing(400, 200)
 
1748
 
 
1749
    data = dataSample5
 
1750
 
 
1751
    bc = HorizontalBarChart()
 
1752
    bc.x = 50
 
1753
    bc.y = 20
 
1754
    bc.height = 155
 
1755
    bc.width = 300
 
1756
    bc.data = data
 
1757
    bc.strokeColor = colors.black
 
1758
 
 
1759
    bc.useAbsolute = 1
 
1760
    bc.barWidth = 10
 
1761
    bc.groupSpacing = 0
 
1762
    bc.barSpacing = 2
 
1763
 
 
1764
    bc.valueAxis.valueMin = 0
 
1765
    bc.valueAxis.valueMax = 60
 
1766
    bc.valueAxis.valueStep = 15
 
1767
 
 
1768
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1769
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1770
 
 
1771
    drawing.add(bc)
 
1772
 
 
1773
    return drawing
 
1774
 
 
1775
 
 
1776
def sampleH5c4():
 
1777
    "Simple bar chart with absolute spacing."
 
1778
 
 
1779
    drawing = Drawing(400, 200)
 
1780
 
 
1781
    data = dataSample5
 
1782
 
 
1783
    bc = HorizontalBarChart()
 
1784
    bc.x = 50
 
1785
    bc.y = 50
 
1786
    bc.height = 125
 
1787
    bc.width = 300
 
1788
    bc.data = data
 
1789
    bc.strokeColor = colors.black
 
1790
 
 
1791
    bc.useAbsolute = 1
 
1792
    bc.barWidth = 10
 
1793
    bc.groupSpacing = 20
 
1794
    bc.barSpacing = 10
 
1795
 
 
1796
    bc.valueAxis.valueMin = 0
 
1797
    bc.valueAxis.valueMax = 60
 
1798
    bc.valueAxis.valueStep = 15
 
1799
 
 
1800
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1801
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1802
 
 
1803
    drawing.add(bc)
 
1804
 
 
1805
    return drawing
 
1806
 
 
1807
def sampleSymbol1():
 
1808
    "Simple bar chart using symbol attribute."
 
1809
 
 
1810
    drawing = Drawing(400, 200)
 
1811
 
 
1812
    data = dataSample5
 
1813
 
 
1814
    bc = VerticalBarChart()
 
1815
    bc.x = 50
 
1816
    bc.y = 50
 
1817
    bc.height = 125
 
1818
    bc.width = 300
 
1819
    bc.data = data
 
1820
    bc.strokeColor = colors.black
 
1821
 
 
1822
    bc.barWidth = 10
 
1823
    bc.groupSpacing = 15
 
1824
    bc.barSpacing = 3
 
1825
 
 
1826
    bc.valueAxis.valueMin = 0
 
1827
    bc.valueAxis.valueMax = 60
 
1828
    bc.valueAxis.valueStep = 15
 
1829
 
 
1830
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1831
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1832
 
 
1833
    from reportlab.graphics.widgets.grids import ShadedRect
 
1834
    sym1 = ShadedRect()
 
1835
    sym1.fillColorStart = colors.black
 
1836
    sym1.fillColorEnd = colors.blue
 
1837
    sym1.orientation = 'horizontal'
 
1838
    sym1.strokeWidth = 0
 
1839
 
 
1840
    sym2 = ShadedRect()
 
1841
    sym2.fillColorStart = colors.black
 
1842
    sym2.fillColorEnd = colors.pink
 
1843
    sym2.orientation = 'horizontal'
 
1844
    sym2.strokeWidth = 0
 
1845
 
 
1846
    sym3 = ShadedRect()
 
1847
    sym3.fillColorStart = colors.blue
 
1848
    sym3.fillColorEnd = colors.white
 
1849
    sym3.orientation = 'vertical'
 
1850
    sym3.cylinderMode = 1
 
1851
    sym3.strokeWidth = 0
 
1852
 
 
1853
    bc.bars.symbol = sym1
 
1854
    bc.bars[2].symbol = sym2
 
1855
    bc.bars[3].symbol = sym3
 
1856
 
 
1857
    drawing.add(bc)
 
1858
 
 
1859
    return drawing
 
1860
 
 
1861
def sampleStacked1():
 
1862
    "Simple bar chart using symbol attribute."
 
1863
 
 
1864
    drawing = Drawing(400, 200)
 
1865
 
 
1866
    data = dataSample5
 
1867
 
 
1868
    bc = VerticalBarChart()
 
1869
    bc.categoryAxis.style = 'stacked'
 
1870
    bc.x = 50
 
1871
    bc.y = 50
 
1872
    bc.height = 125
 
1873
    bc.width = 300
 
1874
    bc.data = data
 
1875
    bc.strokeColor = colors.black
 
1876
 
 
1877
    bc.barWidth = 10
 
1878
    bc.groupSpacing = 15
 
1879
    bc.valueAxis.valueMin = 0
 
1880
 
 
1881
    bc.categoryAxis.labels.boxAnchor = 'e'
 
1882
    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1883
 
 
1884
    from reportlab.graphics.widgets.grids import ShadedRect
 
1885
    bc.bars.symbol = ShadedRect()
 
1886
    bc.bars.symbol.fillColorStart = colors.red
 
1887
    bc.bars.symbol.fillColorEnd = colors.white
 
1888
    bc.bars.symbol.orientation = 'vertical'
 
1889
    bc.bars.symbol.cylinderMode = 1
 
1890
    bc.bars.symbol.strokeWidth = 0
 
1891
 
 
1892
    bc.bars[1].symbol = ShadedRect()
 
1893
    bc.bars[1].symbol.fillColorStart = colors.magenta
 
1894
    bc.bars[1].symbol.fillColorEnd = colors.white
 
1895
    bc.bars[1].symbol.orientation = 'vertical'
 
1896
    bc.bars[1].symbol.cylinderMode = 1
 
1897
    bc.bars[1].symbol.strokeWidth = 0
 
1898
 
 
1899
    bc.bars[2].symbol = ShadedRect()
 
1900
    bc.bars[2].symbol.fillColorStart = colors.green
 
1901
    bc.bars[2].symbol.fillColorEnd = colors.white
 
1902
    bc.bars[2].symbol.orientation = 'vertical'
 
1903
    bc.bars[2].symbol.cylinderMode = 1
 
1904
    bc.bars[2].symbol.strokeWidth = 0
 
1905
 
 
1906
    bc.bars[3].symbol = ShadedRect()
 
1907
    bc.bars[3].symbol.fillColorStart = colors.blue
 
1908
    bc.bars[3].symbol.fillColorEnd = colors.white
 
1909
    bc.bars[3].symbol.orientation = 'vertical'
 
1910
    bc.bars[3].symbol.cylinderMode = 1
 
1911
    bc.bars[3].symbol.strokeWidth = 0
 
1912
 
 
1913
    drawing.add(bc)
 
1914
 
 
1915
    return drawing
 
1916
 
 
1917
#class version of function sampleH5c4 above
 
1918
class SampleH5c4(Drawing):
 
1919
    "Simple bar chart with absolute spacing."
 
1920
 
 
1921
    def __init__(self,width=400,height=200,*args,**kw):
 
1922
        apply(Drawing.__init__,(self,width,height)+args,kw)
 
1923
        bc = HorizontalBarChart()
 
1924
        bc.x = 50
 
1925
        bc.y = 50
 
1926
        bc.height = 125
 
1927
        bc.width = 300
 
1928
        bc.data = dataSample5
 
1929
        bc.strokeColor = colors.black
 
1930
 
 
1931
        bc.useAbsolute = 1
 
1932
        bc.barWidth = 10
 
1933
        bc.groupSpacing = 20
 
1934
        bc.barSpacing = 10
 
1935
 
 
1936
        bc.valueAxis.valueMin = 0
 
1937
        bc.valueAxis.valueMax = 60
 
1938
        bc.valueAxis.valueStep = 15
 
1939
 
 
1940
        bc.categoryAxis.labels.boxAnchor = 'e'
 
1941
        bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
1942
 
 
1943
        self.add(bc,name='HBC')