Exterminated all tab characters and added a test to make sure
authorandy_robinson
Wed, 17 Jul 2002 22:46:24 +0000
changeset 1677 1450177dd19e
parent 1676 babec3b2f097
child 1678 cb91b1bab75d
Exterminated all tab characters and added a test to make sure they never come back.
reportlab/demos/odyssey/dodyssey.py
reportlab/demos/odyssey/fodyssey.py
reportlab/demos/odyssey/odyssey.py
reportlab/demos/tests/testdemos.py
reportlab/docs/genAll.py
reportlab/docs/graphguide/gengraphguide.py
reportlab/docs/userguide/ch2a_fonts.py
reportlab/docs/userguide/ch4_platypus_concepts.py
reportlab/docs/userguide/ch6_tables.py
reportlab/docs/userguide/ch7_custom.py
reportlab/docs/userguide/genuserguide.py
reportlab/graphics/charts/axes.py
reportlab/graphics/charts/barcharts.py
reportlab/graphics/charts/legends.py
reportlab/graphics/charts/linecharts.py
reportlab/graphics/charts/lineplots.py
reportlab/graphics/charts/piecharts.py
reportlab/graphics/charts/textlabels.py
reportlab/graphics/charts/utils.py
reportlab/graphics/renderPM.py
reportlab/graphics/renderPS.py
reportlab/graphics/renderbase.py
reportlab/graphics/shapes.py
reportlab/graphics/testshapes.py
reportlab/graphics/widgetbase.py
reportlab/graphics/widgets/flags.py
reportlab/graphics/widgets/grids.py
reportlab/graphics/widgets/markers.py
reportlab/graphics/widgets/signsandsymbols.py
reportlab/lib/PyFontify.py
reportlab/lib/abag.py
reportlab/lib/attrmap.py
reportlab/lib/colors.py
reportlab/lib/corp.py
reportlab/lib/fonts.py
reportlab/lib/formatters.py
reportlab/lib/logger.py
reportlab/lib/normalDate.py
reportlab/lib/pagesizes.py
reportlab/lib/randomtext.py
reportlab/lib/sequencer.py
reportlab/lib/setup.py
reportlab/lib/units.py
reportlab/lib/utils.py
reportlab/lib/validators.py
reportlab/lib/xmllib.py
reportlab/pdfbase/_fontdata.py
reportlab/pdfbase/pdfdoc.py
reportlab/pdfbase/pdfmetrics.py
reportlab/pdfgen/textobject.py
reportlab/platypus/__init__.py
reportlab/platypus/doctemplate.py
reportlab/platypus/figures.py
reportlab/platypus/flowables.py
reportlab/platypus/frames.py
reportlab/platypus/paragraph.py
reportlab/platypus/paraparser.py
reportlab/platypus/tables.py
reportlab/platypus/xpreformatted.py
reportlab/rl_config.py
reportlab/test/test_lib_validators.py
reportlab/test/test_paragraphs.py
reportlab/test/test_pdfbase_ttfonts.py
reportlab/test/test_platypus_breaking.py
reportlab/test/test_source_chars.py
reportlab/test/test_tools_pythonpoint.py
reportlab/test/test_widgetbase_tpc.py
reportlab/tools/docco/codegrab.py
reportlab/tools/docco/examples.py
reportlab/tools/docco/graphdocpy.py
reportlab/tools/docco/rl_doc_utils.py
reportlab/tools/py2pdf/idle_print.py
reportlab/tools/pythonpoint/customshapes.py
--- a/reportlab/demos/odyssey/dodyssey.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/demos/odyssey/dodyssey.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/demos/odyssey/dodyssey.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/demos/odyssey/dodyssey.py,v 1.11 2002/05/22 12:22:42 rgbecker Exp $
-__version__=''' $Id: dodyssey.py,v 1.11 2002/05/22 12:22:42 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/demos/odyssey/dodyssey.py,v 1.12 2002/07/17 22:46:22 andy_robinson Exp $
+__version__=''' $Id: dodyssey.py,v 1.12 2002/07/17 22:46:22 andy_robinson Exp $ '''
 __doc__=''
 
 #REPORTLAB_TEST_SCRIPT
@@ -12,9 +12,9 @@
 _REDCAP=int(os.environ.get('REDCAP','0'))
 _CALLBACK=os.environ.get('CALLBACK','0')[0] in ('y','Y','1')
 if _NEW_PARA:
-	def Paragraph(s,style):
-		from rlextra.radxml.para import Paragraph as PPPP
-		return PPPP(s,style)
+    def Paragraph(s,style):
+        from rlextra.radxml.para import Paragraph as PPPP
+        return PPPP(s,style)
 
 from reportlab.lib.units import inch
 from reportlab.lib.styles import getSampleStyleSheet
@@ -26,37 +26,37 @@
 Author = "Homer"
 
 def myTitlePage(canvas, doc):
-	canvas.saveState()
-	canvas.restoreState()
+    canvas.saveState()
+    canvas.restoreState()
 
 def myLaterPages(canvas, doc):
-	canvas.saveState()
-	canvas.setFont('Times-Roman',9)
-	canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
-	canvas.restoreState()
-	
+    canvas.saveState()
+    canvas.setFont('Times-Roman',9)
+    canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
+    canvas.restoreState()
+    
 def go():
-	def myCanvasMaker(fn,**kw):
-		from reportlab.pdfgen.canvas import Canvas
-		canv = apply(Canvas,(fn,),kw)
-		# attach our callback to the canvas
-		canv.myOnDrawCB = myOnDrawCB
-		return canv
+    def myCanvasMaker(fn,**kw):
+        from reportlab.pdfgen.canvas import Canvas
+        canv = apply(Canvas,(fn,),kw)
+        # attach our callback to the canvas
+        canv.myOnDrawCB = myOnDrawCB
+        return canv
 
-	doc = BaseDocTemplate('dodyssey.pdf',showBoundary=0)
+    doc = BaseDocTemplate('dodyssey.pdf',showBoundary=0)
 
-	#normal frame as for SimpleFlowDocument
-	frameT = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
+    #normal frame as for SimpleFlowDocument
+    frameT = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
 
-	#Two Columns
-	frame1 = Frame(doc.leftMargin, doc.bottomMargin, doc.width/2-6, doc.height, id='col1')
-	frame2 = Frame(doc.leftMargin+doc.width/2+6, doc.bottomMargin, doc.width/2-6,
-						doc.height, id='col2')
-	doc.addPageTemplates([PageTemplate(id='First',frames=frameT, onPage=myTitlePage),
-						PageTemplate(id='OneCol',frames=frameT, onPage=myLaterPages),
-						PageTemplate(id='TwoCol',frames=[frame1,frame2], onPage=myLaterPages),
-						])
-	doc.build(Elements,canvasmaker=myCanvasMaker)
+    #Two Columns
+    frame1 = Frame(doc.leftMargin, doc.bottomMargin, doc.width/2-6, doc.height, id='col1')
+    frame2 = Frame(doc.leftMargin+doc.width/2+6, doc.bottomMargin, doc.width/2-6,
+                        doc.height, id='col2')
+    doc.addPageTemplates([PageTemplate(id='First',frames=frameT, onPage=myTitlePage),
+                        PageTemplate(id='OneCol',frames=frameT, onPage=myLaterPages),
+                        PageTemplate(id='TwoCol',frames=[frame1,frame2], onPage=myLaterPages),
+                        ])
+    doc.build(Elements,canvasmaker=myCanvasMaker)
 
 Elements = []
 
@@ -69,166 +69,166 @@
 PreStyle = styles["Code"] 
 
 def newPage():
-	Elements.append(PageBreak())
+    Elements.append(PageBreak())
 
 chNum = 0
 def myOnDrawCB(canv,kind,label):
-	print 'myOnDrawCB(%s)'%kind, 'Page number=', canv.getPageNumber(), 'label value=', label
+    print 'myOnDrawCB(%s)'%kind, 'Page number=', canv.getPageNumber(), 'label value=', label
 
 def chapter(txt, style=ChapterStyle):
-	global chNum
-	Elements.append(NextPageTemplate('OneCol'))
-	newPage()
-	chNum = chNum + 1
-	if _NEW_PARA or not _CALLBACK:
-		Elements.append(Paragraph(('chap %d'%chNum)+txt, style))
-	else:
-		Elements.append(Paragraph(('foo<onDraw name="myOnDrawCB" label="chap %d"/> '%chNum)+txt, style))
-	Elements.append(Spacer(0.2*inch, 0.3*inch))
-	if useTwoCol:
-		Elements.append(NextPageTemplate('TwoCol'))
+    global chNum
+    Elements.append(NextPageTemplate('OneCol'))
+    newPage()
+    chNum = chNum + 1
+    if _NEW_PARA or not _CALLBACK:
+        Elements.append(Paragraph(('chap %d'%chNum)+txt, style))
+    else:
+        Elements.append(Paragraph(('foo<onDraw name="myOnDrawCB" label="chap %d"/> '%chNum)+txt, style))
+    Elements.append(Spacer(0.2*inch, 0.3*inch))
+    if useTwoCol:
+        Elements.append(NextPageTemplate('TwoCol'))
 
 def fTitle(txt,style=InitialStyle):
-	Elements.append(Paragraph(txt, style))
-	
+    Elements.append(Paragraph(txt, style))
+    
 ParaStyle = copy.deepcopy(styles["Normal"])
 ParaStyle.spaceBefore = 0.1*inch
 if 'right' in sys.argv:
-	ParaStyle.alignment = TA_RIGHT
+    ParaStyle.alignment = TA_RIGHT
 elif 'left' in sys.argv:
-	ParaStyle.alignment = TA_LEFT
+    ParaStyle.alignment = TA_LEFT
 elif 'justify' in sys.argv:
-	ParaStyle.alignment = TA_JUSTIFY
+    ParaStyle.alignment = TA_JUSTIFY
 elif 'center' in sys.argv or 'centre' in sys.argv:
-	ParaStyle.alignment = TA_CENTER
+    ParaStyle.alignment = TA_CENTER
 else:
-	ParaStyle.alignment = TA_JUSTIFY
+    ParaStyle.alignment = TA_JUSTIFY
 
 useTwoCol = 'notwocol' not in sys.argv 
 
 def spacer(inches):
-	Elements.append(Spacer(0.1*inch, inches*inch))
+    Elements.append(Spacer(0.1*inch, inches*inch))
 
 def p(txt, style=ParaStyle):
-	if _REDCAP:
-		fs, fe = '<font color="red" size="+2">', '</font>'
-		n = len(txt)
-		for i in xrange(n):
-			if 'a'<=txt[i]<='z' or 'A'<=txt[i]<='Z':
-				txt = (txt[:i]+(fs+txt[i]+fe))+txt[i+1:]
-				break
-		if _REDCAP>=2 and n>20:
-			j = i+len(fs)+len(fe)+1+int((n-1)/2)
-			while not ('a'<=txt[j]<='z' or 'A'<=txt[j]<='Z'): j += 1
-			txt = (txt[:j]+('<b><i><font size="+2" color="blue">'+txt[j]+'</font></i></b>'))+txt[j+1:]
+    if _REDCAP:
+        fs, fe = '<font color="red" size="+2">', '</font>'
+        n = len(txt)
+        for i in xrange(n):
+            if 'a'<=txt[i]<='z' or 'A'<=txt[i]<='Z':
+                txt = (txt[:i]+(fs+txt[i]+fe))+txt[i+1:]
+                break
+        if _REDCAP>=2 and n>20:
+            j = i+len(fs)+len(fe)+1+int((n-1)/2)
+            while not ('a'<=txt[j]<='z' or 'A'<=txt[j]<='Z'): j += 1
+            txt = (txt[:j]+('<b><i><font size="+2" color="blue">'+txt[j]+'</font></i></b>'))+txt[j+1:]
 
-		if _REDCAP==3 and n>20:
-			n = len(txt)
-			fs = '<font color="green" size="+1">'
-			for i in xrange(n-1,-1,-1):
-				if 'a'<=txt[i]<='z' or 'A'<=txt[i]<='Z':
-					txt = txt[:i]+((fs+txt[i]+fe)+txt[i+1:])
-					break
+        if _REDCAP==3 and n>20:
+            n = len(txt)
+            fs = '<font color="green" size="+1">'
+            for i in xrange(n-1,-1,-1):
+                if 'a'<=txt[i]<='z' or 'A'<=txt[i]<='Z':
+                    txt = txt[:i]+((fs+txt[i]+fe)+txt[i+1:])
+                    break
 
-	Elements.append(Paragraph(txt, style))
+    Elements.append(Paragraph(txt, style))
 
 firstPre = 1
 def pre(txt, style=PreStyle):
-	global firstPre
-	if firstPre:
-		Elements.append(NextPageTemplate('OneCol'))
-		newPage()
-		firstPre = 0
+    global firstPre
+    if firstPre:
+        Elements.append(NextPageTemplate('OneCol'))
+        newPage()
+        firstPre = 0
 
-	spacer(0.1)
-	p = Preformatted(txt, style)
-	Elements.append(p)
+    spacer(0.1)
+    p = Preformatted(txt, style)
+    Elements.append(p)
 
 def parseOdyssey(fn):
-	from time import time
-	E = []
-	t0=time()
-	L = open(fn,'r').readlines()
-	t1 = time()
-	print "open(%s,'r').readlines() took %.4f seconds" %(fn,t1-t0)
-	for i in xrange(len(L)):
-		if L[i][-1]=='\012':
-			L[i] = L[i][:-1]
-	t2 = time()
-	print "Removing all linefeeds took %.4f seconds" %(t2-t1)
-	L.append('')
-	L.append('-----')
+    from time import time
+    E = []
+    t0=time()
+    L = open(fn,'r').readlines()
+    t1 = time()
+    print "open(%s,'r').readlines() took %.4f seconds" %(fn,t1-t0)
+    for i in xrange(len(L)):
+        if L[i][-1]=='\012':
+            L[i] = L[i][:-1]
+    t2 = time()
+    print "Removing all linefeeds took %.4f seconds" %(t2-t1)
+    L.append('')
+    L.append('-----')
 
-	def findNext(L, i):
-		while 1:
-			if string.strip(L[i])=='':
-				del L[i]
-				kind = 1
-				if i<len(L):
-					while string.strip(L[i])=='':
-						del L[i]
+    def findNext(L, i):
+        while 1:
+            if string.strip(L[i])=='':
+                del L[i]
+                kind = 1
+                if i<len(L):
+                    while string.strip(L[i])=='':
+                        del L[i]
 
-					if i<len(L):
-						kind = L[i][-1]=='-' and L[i][0]=='-'
-						if kind:
-							del L[i]
-							if i<len(L):
-								while string.strip(L[i])=='':
-									del L[i]
-				break
-			else:
-				i = i + 1
+                    if i<len(L):
+                        kind = L[i][-1]=='-' and L[i][0]=='-'
+                        if kind:
+                            del L[i]
+                            if i<len(L):
+                                while string.strip(L[i])=='':
+                                    del L[i]
+                break
+            else:
+                i = i + 1
 
-		return i, kind
+        return i, kind
 
-	f = s = 0
-	while 1:
-		f, k = findNext(L,0)
-		if k: break
+    f = s = 0
+    while 1:
+        f, k = findNext(L,0)
+        if k: break
 
-	E.append([spacer,2])
-	E.append([fTitle,'<font color="red">%s</font>' % Title, InitialStyle])
-	E.append([fTitle,'<font size="-4">by</font> <font color="green">%s</font>' % Author, InitialStyle])
+    E.append([spacer,2])
+    E.append([fTitle,'<font color="red">%s</font>' % Title, InitialStyle])
+    E.append([fTitle,'<font size="-4">by</font> <font color="green">%s</font>' % Author, InitialStyle])
 
-	while 1:
-		if f>=len(L): break
+    while 1:
+        if f>=len(L): break
 
-		if string.upper(L[f][0:5])=='BOOK ':
-			E.append([chapter,L[f]])
-			f=f+1
-			while string.strip(L[f])=='': del L[f]
-			style = ParaStyle
-			func = p
-		else:
-			style = PreStyle
-			func = pre
-	
-		while 1:
-			s=f
-			f, k=findNext(L,s)
-			sep= (func is pre) and '\012' or ' '
-			E.append([func,string.join(L[s:f],sep),style])
-			if k: break
-	t3 = time()
-	print "Parsing into memory took %.4f seconds" %(t3-t2)
-	del L
-	t4 = time()
-	print "Deleting list of lines took %.4f seconds" %(t4-t3)
-	for i in xrange(len(E)):
-		apply(E[i][0],E[i][1:])
-	t5 = time()
-	print "Moving into platypus took %.4f seconds" %(t5-t4)
-	del E
-	t6 = time()
-	print "Deleting list of actions took %.4f seconds" %(t6-t5)
-	go()
-	t7 = time()
-	print "saving to PDF took %.4f seconds" %(t7-t6)
-	print "Total run took %.4f seconds"%(t7-t0)
+        if string.upper(L[f][0:5])=='BOOK ':
+            E.append([chapter,L[f]])
+            f=f+1
+            while string.strip(L[f])=='': del L[f]
+            style = ParaStyle
+            func = p
+        else:
+            style = PreStyle
+            func = pre
+    
+        while 1:
+            s=f
+            f, k=findNext(L,s)
+            sep= (func is pre) and '\012' or ' '
+            E.append([func,string.join(L[s:f],sep),style])
+            if k: break
+    t3 = time()
+    print "Parsing into memory took %.4f seconds" %(t3-t2)
+    del L
+    t4 = time()
+    print "Deleting list of lines took %.4f seconds" %(t4-t3)
+    for i in xrange(len(E)):
+        apply(E[i][0],E[i][1:])
+    t5 = time()
+    print "Moving into platypus took %.4f seconds" %(t5-t4)
+    del E
+    t6 = time()
+    print "Deleting list of actions took %.4f seconds" %(t6-t5)
+    go()
+    t7 = time()
+    print "saving to PDF took %.4f seconds" %(t7-t6)
+    print "Total run took %.4f seconds"%(t7-t0)
 
 for fn in ('odyssey.full.txt','odyssey.txt'):
-	if os.path.isfile(fn):
-		break
+    if os.path.isfile(fn):
+        break
 
 if __name__=='__main__':
-	parseOdyssey(fn)
+    parseOdyssey(fn)
--- a/reportlab/demos/odyssey/fodyssey.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/demos/odyssey/fodyssey.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/demos/odyssey/fodyssey.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/demos/odyssey/fodyssey.py,v 1.15 2001/03/07 18:57:11 rgbecker Exp $
-__version__=''' $Id: fodyssey.py,v 1.15 2001/03/07 18:57:11 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/demos/odyssey/fodyssey.py,v 1.16 2002/07/17 22:46:22 andy_robinson Exp $
+__version__=''' $Id: fodyssey.py,v 1.16 2002/07/17 22:46:22 andy_robinson Exp $ '''
 __doc__=''
 
 #REPORTLAB_TEST_SCRIPT
@@ -18,19 +18,19 @@
 Author = "Homer"
 
 def myFirstPage(canvas, doc):
-	canvas.saveState()
-	canvas.restoreState()
-	
+    canvas.saveState()
+    canvas.restoreState()
+    
 def myLaterPages(canvas, doc):
-	canvas.saveState()
-	canvas.setFont('Times-Roman',9)
-	canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
-	canvas.restoreState()
-	
+    canvas.saveState()
+    canvas.setFont('Times-Roman',9)
+    canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
+    canvas.restoreState()
+    
 def go():
-	doc = SimpleDocTemplate('fodyssey.pdf',showBoundary='showboundary' in sys.argv)
-	doc.allowSplitting = not 'nosplitting' in sys.argv
-	doc.build(Elements,myFirstPage,myLaterPages)
+    doc = SimpleDocTemplate('fodyssey.pdf',showBoundary='showboundary' in sys.argv)
+    doc.allowSplitting = not 'nosplitting' in sys.argv
+    doc.build(Elements,myFirstPage,myLaterPages)
 
 Elements = []
 
@@ -43,124 +43,124 @@
 PreStyle = styles["Code"] 
 
 def newPage():
-	Elements.append(PageBreak())
+    Elements.append(PageBreak())
 
 def chapter(txt, style=ChapterStyle):
-	newPage()
-	Elements.append(Paragraph(txt, style))
-	Elements.append(Spacer(0.2*inch, 0.3*inch))
+    newPage()
+    Elements.append(Paragraph(txt, style))
+    Elements.append(Spacer(0.2*inch, 0.3*inch))
 
 def fTitle(txt,style=InitialStyle):
-	Elements.append(Paragraph(txt, style))
+    Elements.append(Paragraph(txt, style))
 
 ParaStyle = copy.deepcopy(styles["Normal"])
 ParaStyle.spaceBefore = 0.1*inch
 if 'right' in sys.argv:
-	ParaStyle.alignment = TA_RIGHT
+    ParaStyle.alignment = TA_RIGHT
 elif 'left' in sys.argv:
-	ParaStyle.alignment = TA_LEFT
+    ParaStyle.alignment = TA_LEFT
 elif 'justify' in sys.argv:
-	ParaStyle.alignment = TA_JUSTIFY
+    ParaStyle.alignment = TA_JUSTIFY
 elif 'center' in sys.argv or 'centre' in sys.argv:
-	ParaStyle.alignment = TA_CENTER
+    ParaStyle.alignment = TA_CENTER
 else:
-	ParaStyle.alignment = TA_JUSTIFY
+    ParaStyle.alignment = TA_JUSTIFY
 
 def spacer(inches):
-	Elements.append(Spacer(0.1*inch, inches*inch))
+    Elements.append(Spacer(0.1*inch, inches*inch))
 
 def p(txt, style=ParaStyle):
-	Elements.append(Paragraph(txt, style))
+    Elements.append(Paragraph(txt, style))
 
 def pre(txt, style=PreStyle):
-	spacer(0.1)
-	p = Preformatted(txt, style)
-	Elements.append(p)
+    spacer(0.1)
+    p = Preformatted(txt, style)
+    Elements.append(p)
 
 def parseOdyssey(fn):
-	from time import time
-	E = []
-	t0=time()
-	L = open(fn,'r').readlines()
-	t1 = time()
-	print "open(%s,'r').readlines() took %.4f seconds" %(fn,t1-t0)
-	for i in xrange(len(L)):
-		if L[i][-1]=='\012':
-			L[i] = L[i][:-1]
-	t2 = time()
-	print "Removing all linefeeds took %.4f seconds" %(t2-t1)
-	L.append('')
-	L.append('-----')
+    from time import time
+    E = []
+    t0=time()
+    L = open(fn,'r').readlines()
+    t1 = time()
+    print "open(%s,'r').readlines() took %.4f seconds" %(fn,t1-t0)
+    for i in xrange(len(L)):
+        if L[i][-1]=='\012':
+            L[i] = L[i][:-1]
+    t2 = time()
+    print "Removing all linefeeds took %.4f seconds" %(t2-t1)
+    L.append('')
+    L.append('-----')
 
-	def findNext(L, i):
-		while 1:
-			if string.strip(L[i])=='':
-				del L[i]
-				kind = 1
-				if i<len(L):
-					while string.strip(L[i])=='':
-						del L[i]
+    def findNext(L, i):
+        while 1:
+            if string.strip(L[i])=='':
+                del L[i]
+                kind = 1
+                if i<len(L):
+                    while string.strip(L[i])=='':
+                        del L[i]
 
-					if i<len(L):
-						kind = L[i][-1]=='-' and L[i][0]=='-'
-						if kind:
-							del L[i]
-							if i<len(L):
-								while string.strip(L[i])=='':
-									del L[i]
-				break
-			else:
-				i = i + 1
+                    if i<len(L):
+                        kind = L[i][-1]=='-' and L[i][0]=='-'
+                        if kind:
+                            del L[i]
+                            if i<len(L):
+                                while string.strip(L[i])=='':
+                                    del L[i]
+                break
+            else:
+                i = i + 1
 
-		return i, kind
+        return i, kind
 
-	f = s = 0
-	while 1:
-		f, k = findNext(L,0)
-		if k: break
+    f = s = 0
+    while 1:
+        f, k = findNext(L,0)
+        if k: break
 
-	E.append([spacer,2])
-	E.append([fTitle,'<font color=red>%s</font>' % Title, InitialStyle])
-	E.append([fTitle,'<font size=-4>by</font> <font color=green>%s</font>' % Author, InitialStyle])
+    E.append([spacer,2])
+    E.append([fTitle,'<font color=red>%s</font>' % Title, InitialStyle])
+    E.append([fTitle,'<font size=-4>by</font> <font color=green>%s</font>' % Author, InitialStyle])
 
-	while 1:
-		if f>=len(L): break
+    while 1:
+        if f>=len(L): break
 
-		if string.upper(L[f][0:5])=='BOOK ':
-			E.append([chapter,L[f]])
-			f=f+1
-			while string.strip(L[f])=='': del L[f]
-			style = ParaStyle
-			func = p
-		else:
-			style = PreStyle
-			func = pre
-	
-		while 1:
-			s=f
-			f, k=findNext(L,s)
-			sep= (func is pre) and '\012' or ' '
-			E.append([func,string.join(L[s:f],sep),style])
-			if k: break
-	t3 = time()
-	print "Parsing into memory took %.4f seconds" %(t3-t2)
-	del L
-	t4 = time()
-	print "Deleting list of lines took %.4f seconds" %(t4-t3)
-	for i in xrange(len(E)):
-		apply(E[i][0],E[i][1:])
-	t5 = time()
-	print "Moving into platypus took %.4f seconds" %(t5-t4)
-	del E
-	t6 = time()
-	print "Deleting list of actions took %.4f seconds" %(t6-t5)
-	go()
-	t7 = time()
-	print "saving to PDF took %.4f seconds" %(t7-t6)
-	print "Total run took %.4f seconds"%(t7-t0)
+        if string.upper(L[f][0:5])=='BOOK ':
+            E.append([chapter,L[f]])
+            f=f+1
+            while string.strip(L[f])=='': del L[f]
+            style = ParaStyle
+            func = p
+        else:
+            style = PreStyle
+            func = pre
+    
+        while 1:
+            s=f
+            f, k=findNext(L,s)
+            sep= (func is pre) and '\012' or ' '
+            E.append([func,string.join(L[s:f],sep),style])
+            if k: break
+    t3 = time()
+    print "Parsing into memory took %.4f seconds" %(t3-t2)
+    del L
+    t4 = time()
+    print "Deleting list of lines took %.4f seconds" %(t4-t3)
+    for i in xrange(len(E)):
+        apply(E[i][0],E[i][1:])
+    t5 = time()
+    print "Moving into platypus took %.4f seconds" %(t5-t4)
+    del E
+    t6 = time()
+    print "Deleting list of actions took %.4f seconds" %(t6-t5)
+    go()
+    t7 = time()
+    print "saving to PDF took %.4f seconds" %(t7-t6)
+    print "Total run took %.4f seconds"%(t7-t0)
 
 for fn in ('odyssey.full.txt','odyssey.txt'):
-	if os.path.isfile(fn):
-		break
+    if os.path.isfile(fn):
+        break
 if __name__=='__main__':
-	parseOdyssey(fn)
+    parseOdyssey(fn)
--- a/reportlab/demos/odyssey/odyssey.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/demos/odyssey/odyssey.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/demos/odyssey/odyssey.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/demos/odyssey/odyssey.py,v 1.9 2000/10/25 08:57:44 rgbecker Exp $
-__version__=''' $Id: odyssey.py,v 1.9 2000/10/25 08:57:44 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/demos/odyssey/odyssey.py,v 1.10 2002/07/17 22:46:22 andy_robinson Exp $
+__version__=''' $Id: odyssey.py,v 1.10 2002/07/17 22:46:22 andy_robinson Exp $ '''
 ___doc__=''
 #odyssey.py
 #
@@ -110,7 +110,7 @@
         canv.drawText(tx)
         canv.showPage()
         drawPageFrame(canv)
-		
+        
     print 'about to write to disk...'
     
     canv.save()
--- a/reportlab/demos/tests/testdemos.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/demos/tests/testdemos.py	Wed Jul 17 22:46:24 2002 +0000
@@ -2,14 +2,14 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/demos/tests/testdemos.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/demos/tests/testdemos.py,v 1.5 2000/10/25 08:57:45 rgbecker Exp $
-__version__=''' $Id: testdemos.py,v 1.5 2000/10/25 08:57:45 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/demos/tests/testdemos.py,v 1.6 2002/07/17 22:46:22 andy_robinson Exp $
+__version__=''' $Id: testdemos.py,v 1.6 2002/07/17 22:46:22 andy_robinson Exp $ '''
 __doc__='Test all demos'
 _globals=globals().copy()
 import os, sys
 from reportlab import pdfgen
 
 for p in ('pythonpoint/pythonpoint.py','stdfonts/stdfonts.py','odyssey/odyssey.py', 'gadflypaper/gfe.py'):
-	fn = os.path.normcase(os.path.normpath(os.path.join(os.path.dirname(pdfgen.__file__),'..','demos',p)))
-	os.chdir(os.path.dirname(fn))
-	execfile(fn,_globals.copy())
+    fn = os.path.normcase(os.path.normpath(os.path.join(os.path.dirname(pdfgen.__file__),'..','demos',p)))
+    os.chdir(os.path.dirname(fn))
+    execfile(fn,_globals.copy())
--- a/reportlab/docs/genAll.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/docs/genAll.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,37 +1,37 @@
 #!/bin/env python
 import os, sys
 def _genAll(d=None,verbose=1):
-	if not d: d = '.'
-	if not os.path.isabs(d):
-		d = os.path.normpath(os.path.join(os.getcwd(),d))
-	L = ['reference/genreference.py',
-		'userguide/genuserguide.py',
-		'graphguide/gengraphguide.py',
-		'../tools/docco/graphdocpy.py',
-		]
-	if os.path.isdir('../rl_addons'):
-		L = L + ['../rl_addons/pyRXP/docs/PyRXP_Documentation.rml']
-	elif os.path.isdir('../../rl_addons'):
-		L = L + ['../../rl_addons/pyRXP/docs/PyRXP_Documentation.rml']
-	for p in L:
-		os.chdir(d)
-		os.chdir(os.path.dirname(p))
-		if p[-4:]=='.rml':
-			try:
-				from rlextra.rml2pdf.rml2pdf import main
-				main(exe=0,fn=[os.path.basename(p)], quiet=not verbose, outDir=d)
-			except:
-				pass
-		else:
-			cmd = '%s %s %s' % (sys.executable,os.path.basename(p), not verbose and '-s' or '')
-			if verbose: print cmd
-			os.system(cmd)
+    if not d: d = '.'
+    if not os.path.isabs(d):
+        d = os.path.normpath(os.path.join(os.getcwd(),d))
+    L = ['reference/genreference.py',
+        'userguide/genuserguide.py',
+        'graphguide/gengraphguide.py',
+        '../tools/docco/graphdocpy.py',
+        ]
+    if os.path.isdir('../rl_addons'):
+        L = L + ['../rl_addons/pyRXP/docs/PyRXP_Documentation.rml']
+    elif os.path.isdir('../../rl_addons'):
+        L = L + ['../../rl_addons/pyRXP/docs/PyRXP_Documentation.rml']
+    for p in L:
+        os.chdir(d)
+        os.chdir(os.path.dirname(p))
+        if p[-4:]=='.rml':
+            try:
+                from rlextra.rml2pdf.rml2pdf import main
+                main(exe=0,fn=[os.path.basename(p)], quiet=not verbose, outDir=d)
+            except:
+                pass
+        else:
+            cmd = '%s %s %s' % (sys.executable,os.path.basename(p), not verbose and '-s' or '')
+            if verbose: print cmd
+            os.system(cmd)
 
 """Runs the manual-building scripts"""
 if __name__=='__main__':
-	#need a quiet mode for the test suite	
-	if '-s' in sys.argv:  # 'silent
-		verbose = 0
-	else:
-		verbose = 1
-	_genAll(os.path.dirname(sys.argv[0]),verbose)
+    #need a quiet mode for the test suite   
+    if '-s' in sys.argv:  # 'silent
+        verbose = 0
+    else:
+        verbose = 1
+    _genAll(os.path.dirname(sys.argv[0]),verbose)
--- a/reportlab/docs/graphguide/gengraphguide.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/docs/graphguide/gengraphguide.py	Wed Jul 17 22:46:24 2002 +0000
@@ -2,56 +2,56 @@
 #copyright ReportLab Inc. 2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/docs/graphguide/gengraphguide.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/docs/graphguide/gengraphguide.py,v 1.3 2001/10/28 21:18:03 andy_robinson Exp $
-__version__=''' $Id: gengraphguide.py,v 1.3 2001/10/28 21:18:03 andy_robinson Exp $ '''
+#$Header: /tmp/reportlab/reportlab/docs/graphguide/gengraphguide.py,v 1.4 2002/07/17 22:46:22 andy_robinson Exp $
+__version__=''' $Id: gengraphguide.py,v 1.4 2002/07/17 22:46:22 andy_robinson Exp $ '''
 __doc__ = """
 This module contains the script for building the graphics guide.
 """
 from reportlab.tools.docco.rl_doc_utils import *
 def run(pagesize, verbose=1):
-	doc = RLDocTemplate('graphguide.pdf',pagesize = pagesize)
-	import ch1_intro
-	import ch2_concepts
-	import ch3_shapes
-	import ch4_widgets
-	import ch5_charts
+    doc = RLDocTemplate('graphguide.pdf',pagesize = pagesize)
+    import ch1_intro
+    import ch2_concepts
+    import ch3_shapes
+    import ch4_widgets
+    import ch5_charts
 
-	story = getStory()
-	if verbose: print 'Built story contains %d flowables...' % len(story)
-	doc.build(story)
-	if verbose: print 'Saved graphguide.pdf'
+    story = getStory()
+    if verbose: print 'Built story contains %d flowables...' % len(story)
+    doc.build(story)
+    if verbose: print 'Saved graphguide.pdf'
 
-	# copy to target
-	import reportlab
-	docdir = os.path.dirname(reportlab.__file__) + os.sep + 'docs'
-	destfn = docdir + os.sep + 'graphguide.pdf'
-	import shutil
-	shutil.copyfile('graphguide.pdf',
-					destfn)
-	if verbose: print 'copied to %s' % destfn
+    # copy to target
+    import reportlab
+    docdir = os.path.dirname(reportlab.__file__) + os.sep + 'docs'
+    destfn = docdir + os.sep + 'graphguide.pdf'
+    import shutil
+    shutil.copyfile('graphguide.pdf',
+                    destfn)
+    if verbose: print 'copied to %s' % destfn
 
-	# remove *.pyc files
-	pat = os.path.join(os.path.dirname(sys.argv[0]), '*.pyc')
-	for file in glob.glob(pat):
-		os.remove(file)
+    # remove *.pyc files
+    pat = os.path.join(os.path.dirname(sys.argv[0]), '*.pyc')
+    for file in glob.glob(pat):
+        os.remove(file)
 
 def makeSuite():
     "standard test harness support - run self as separate process"
     from reportlab.test.utils import ScriptThatMakesFileTest
     return ScriptThatMakesFileTest('../docs/graphguide',
-								   'gengraphguide.py',
-								   'graphguide.pdf')
+                                   'gengraphguide.py',
+                                   'graphguide.pdf')
 
 if __name__=="__main__":
-	verbose = '-s' not in sys.argv
-	if not verbose: sys.argv.remove('-s')
-	if len(sys.argv) > 1:
-		try:
-			(w, h) = eval(sys.argv[1])
-		except:
-			print 'Expected page size in argument 1', sys.argv[1]
-			raise
-		print 'set page size to',sys.argv[1]
-	else:
-		(w, h) = defaultPageSize
-	run((w, h),verbose)
+    verbose = '-s' not in sys.argv
+    if not verbose: sys.argv.remove('-s')
+    if len(sys.argv) > 1:
+        try:
+            (w, h) = eval(sys.argv[1])
+        except:
+            print 'Expected page size in argument 1', sys.argv[1]
+            raise
+        print 'set page size to',sys.argv[1]
+    else:
+        (w, h) = defaultPageSize
+    run((w, h),verbose)
--- a/reportlab/docs/userguide/ch2a_fonts.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/docs/userguide/ch2a_fonts.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,7 +1,7 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/docs/userguide/ch2_graphics.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/docs/userguide/ch2a_fonts.py,v 1.4 2002/05/28 15:06:55 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/docs/userguide/ch2a_fonts.py,v 1.5 2002/07/17 22:46:22 andy_robinson Exp $
 from reportlab.tools.docco.rl_doc_utils import *
 from reportlab.lib.codecharts import SingleByteEncodingChart
 from reportlab.platypus import Image
@@ -248,9 +248,9 @@
 # include a bitmap of some Asian text
 I=os.path.join(os.path.dirname(__file__),'..','images','jpnchars.jpg')
 try:
-	getStory().append(Image(I))
+    getStory().append(Image(I))
 except:
-	disc("""An image should have appeared here.""")
+    disc("""An image should have appeared here.""")
 
 disc("""Asian multi-byte fonts are called 'CIDFonts'.  CID stands for 'Character ID'.  The
 central idea is that a font contains many thousands of glyphs each identified by a numeric
@@ -581,7 +581,7 @@
 illust(examples.ttffont1, "Using a the Rina TrueType Font")
 disc("""In the above example the true type font object is created using""")
 eg("""
-	TTFont(name,filename)
+    TTFont(name,filename)
 """)
 disc("""so that the ReportLab internal name is given by the first argument and the second argument
 is a string(or file like object) denoting the font's TTF file. In Marius' original patch the filename
@@ -602,10 +602,10 @@
 
 eg("""
 from reportlab.lib.fonts import addMapping
-addMapping('Rina', 0, 0, 'Rina')	#normal
-addMapping('Rina', 0, 1, 'Rina')	#italic
-addMapping('Rina', 1, 0, 'Rina')	#bold
-addMapping('Rina', 1, 1, 'Rina')	#italic and bold
+addMapping('Rina', 0, 0, 'Rina')    #normal
+addMapping('Rina', 0, 1, 'Rina')    #italic
+addMapping('Rina', 1, 0, 'Rina')    #bold
+addMapping('Rina', 1, 1, 'Rina')    #italic and bold
 """)
 
 disc("""we only have Rina regular so we map all to the same internal fontname. After registering and mapping
--- a/reportlab/docs/userguide/ch4_platypus_concepts.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/docs/userguide/ch4_platypus_concepts.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,7 +1,7 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/docs/userguide/ch4_platypus_concepts.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/docs/userguide/ch4_platypus_concepts.py,v 1.2 2001/10/27 22:37:02 andy_robinson Exp $
+#$Header: /tmp/reportlab/reportlab/docs/userguide/ch4_platypus_concepts.py,v 1.3 2002/07/17 22:46:22 andy_robinson Exp $
 from reportlab.tools.docco.rl_doc_utils import *
 
 #####################################################################################################3
@@ -168,7 +168,7 @@
 endKeep(k)
 heading3("$Flowable$ User Methods")
 eg("""
-	Flowable.draw()
+    Flowable.draw()
 """)
 disc("""This will be called to ask the flowable to actually render itself.
 The $Flowable$ class does not implement $draw$.
@@ -179,7 +179,7 @@
 must implement this method.
 """)
 eg("""
-	Flowable.drawOn(canvas,x,y)
+    Flowable.drawOn(canvas,x,y)
 """)
 disc("""
 This is the method which controlling programs use to render the flowable to a particular
@@ -189,16 +189,16 @@
 absolute coordinate frame.
 """)
 eg("""
-	Flowable.wrap(availWidth, availHeight)
+    Flowable.wrap(availWidth, availHeight)
 """)
 disc("""This will be called by the enclosing frame before objects
 are asked their size, drawn or whatever.  It returns the
 size actually used.""")
 eg("""
-	Flowable.split(self, availWidth, availheight):
+    Flowable.split(self, availWidth, availheight):
 """)
 disc("""This will be called by more sophisticated frames when
-		wrap fails. Stupid flowables should return [] meaning that they are unable to split.
+        wrap fails. Stupid flowables should return [] meaning that they are unable to split.
 Clever flowables should split themselves and return a list of flowables. It is up to
 the client code to ensure that repeated attempts to split are avoided.
 If the space is sufficient the split method should return [self].
@@ -209,8 +209,8 @@
 passes over a list of flowables.
 """)
 eg("""
-	Flowable.getSpaceAfter(self):
-	Flowable.getSpaceBefore(self):
+    Flowable.getSpaceAfter(self):
+    Flowable.getSpaceBefore(self):
 """)
 disc("""These methods return how much space should follow or precede
 the flowable. The space doesn't belong to the flowable itself i.e. the flowable's
@@ -231,8 +231,8 @@
 """)
 
 eg("""
-	Frame(x1, y1, width,height, leftPadding=6, bottomPadding=6,
-			rightPadding=6, topPadding=6, id=None, showBoundary=0)
+    Frame(x1, y1, width,height, leftPadding=6, bottomPadding=6,
+            rightPadding=6, topPadding=6, id=None, showBoundary=0)
 """)
 disc("""creates a $Frame$ instance with lower left hand corner at coordinate $(x1,y1)$
 (relative to the canvas at use time) and with dimensions $width$ x $height$. The $Padding$
@@ -243,21 +243,21 @@
 """)
 heading3("$Frame$ User Methods")
 eg("""
-	Frame.addFromList(drawlist, canvas)
+    Frame.addFromList(drawlist, canvas)
 """)
 disc("""consumes $Flowables$ from the front of $drawlist$ until the
-	frame is full.	If it cannot fit one object, raises
-	an exception.""")
+    frame is full.  If it cannot fit one object, raises
+    an exception.""")
 
 eg("""
-	Frame.split(flowable,canv)
+    Frame.split(flowable,canv)
 """)
 disc('''Asks the flowable to split using up the available space and return
 the list of flowables.
 ''')
 
 eg("""
-	Frame.drawBoundary(canvas)
+    Frame.drawBoundary(canvas)
 """)
 disc("draws the frame boundary as a rectangle (primarily for debugging).")
 heading3("Using $Frames$")
@@ -280,7 +280,7 @@
 #add some flowables
 story.append(Paragraph("This is a Heading",styleH))
 story.append(Paragraph("This is a paragraph in <i>Normal</i> style.",
-	styleN))
+    styleN))
 c  = Canvas('mydoc.pdf')
 f = Frame(inch, inch, 6*inch, 9*inch, showBoundary=1)
 f.addFromList(story,c)
@@ -302,17 +302,17 @@
 
 eg("""
     BaseDocTemplate(self, filename,
-					pagesize=defaultPageSize,
-					pageTemplates=[],
-					showBoundary=0,
-					leftMargin=inch,
-					rightMargin=inch,
-					topMargin=inch,
-					bottomMargin=inch,
-					allowSplitting=1,
-					title=None,
-					author=None,
-					_pageBreakQuick=1)
+                    pagesize=defaultPageSize,
+                    pageTemplates=[],
+                    showBoundary=0,
+                    leftMargin=inch,
+                    rightMargin=inch,
+                    topMargin=inch,
+                    bottomMargin=inch,
+                    allowSplitting=1,
+                    title=None,
+                    author=None,
+                    _pageBreakQuick=1)
 """)
 
 disc("""
@@ -372,8 +372,8 @@
     BaseDocTemplate.afterPage(self)
 """)
 disc("""This is called after page processing, and
-		immediately after the afterDrawPage method
-		of the current page template. A derived class could
+        immediately after the afterDrawPage method
+        of the current page template. A derived class could
 use this to do things which are dependent on information in the page
 such as the first and last word on the page of a dictionary.
 """)
@@ -393,19 +393,19 @@
 """)
 
 disc("""This is called at the beginning of page
-		processing, and immediately before the
-		beforeDrawPage method of the current page
-		template. It could be used to reset page specific
-		information holders.""")
+        processing, and immediately before the
+        beforeDrawPage method of the current page
+        template. It could be used to reset page specific
+        information holders.""")
 
 eg("""
     BaseDocTemplate.filterFlowables(self,flowables)
 """)
 
 disc("""This is called to filter flowables at the start of the main handle_flowable method.
-		Upon return if flowables[0] has been set to None it is discarded and the main
-		method returns immediately.
-		""")
+        Upon return if flowables[0] has been set to None it is discarded and the main
+        method returns immediately.
+        """)
 
 eg("""
     BaseDocTemplate.afterFlowable(self, flowable)
@@ -471,7 +471,7 @@
 #add some flowables
 story.append(Paragraph("This is a Heading",styleH))
 story.append(Paragraph("This is a paragraph in <i>Normal</i> style.",
-	styleN))
+    styleN))
 doc = SimpleDocTemplate('mydoc.pdf',pagesize = letter)
 doc.build(story)
 """)
--- a/reportlab/docs/userguide/ch6_tables.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/docs/userguide/ch6_tables.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,7 +1,7 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/docs/userguide/ch6_tables.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/docs/userguide/ch6_tables.py,v 1.2 2001/10/27 22:37:02 andy_robinson Exp $
+#$Header: /tmp/reportlab/reportlab/docs/userguide/ch6_tables.py,v 1.3 2002/07/17 22:46:22 andy_robinson Exp $
 from reportlab.tools.docco.rl_doc_utils import *
 from reportlab.platypus import Image
 
@@ -175,38 +175,38 @@
         ['30', '31', '32', '33', '34']]
 t=Table(data,style=[('GRID',(1,1),(-2,-2),1,colors.green),
                     ('BOX',(0,0),(1,-1),2,colors.red),
-					('LINEABOVE',(1,2),(-2,2),1,colors.blue),
-					('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
-					])
+                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
+                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
+                    ])
 """)
 disc("""Line commands cause problems for tables when they split; the following example
 shows a table being split in various positions""")
 EmbeddedCode("""
 data=  [['00', '01', '02', '03', '04'],
-		['10', '11', '12', '13', '14'],
-		['20', '21', '22', '23', '24'],
-		['30', '31', '32', '33', '34']]
+        ['10', '11', '12', '13', '14'],
+        ['20', '21', '22', '23', '24'],
+        ['30', '31', '32', '33', '34']]
 t=Table(data,style=[
-				('GRID',(0,0),(-1,-1),0.5,colors.grey),
-				('GRID',(1,1),(-2,-2),1,colors.green),
-				('BOX',(0,0),(1,-1),2,colors.red),
-				('BOX',(0,0),(-1,-1),2,colors.black),
-				('LINEABOVE',(1,2),(-2,2),1,colors.blue),
-				('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
-				('BACKGROUND', (0, 0), (0, 1), colors.pink),
-				('BACKGROUND', (1, 1), (1, 2), colors.lavender),
-				('BACKGROUND', (2, 2), (2, 3), colors.orange),
-				])
+                ('GRID',(0,0),(-1,-1),0.5,colors.grey),
+                ('GRID',(1,1),(-2,-2),1,colors.green),
+                ('BOX',(0,0),(1,-1),2,colors.red),
+                ('BOX',(0,0),(-1,-1),2,colors.black),
+                ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
+                ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
+                ('BACKGROUND', (0, 0), (0, 1), colors.pink),
+                ('BACKGROUND', (1, 1), (1, 2), colors.lavender),
+                ('BACKGROUND', (2, 2), (2, 3), colors.orange),
+                ])
 """)
 t=getStory()[-1]
 getStory().append(Spacer(0,6))
 for s in t.split(4*inch,30):
-	getStory().append(s)
-	getStory().append(Spacer(0,6))
+    getStory().append(s)
+    getStory().append(Spacer(0,6))
 getStory().append(Spacer(0,6))
 for s in t.split(4*inch,36):
-	getStory().append(s)
-	getStory().append(Spacer(0,6))
+    getStory().append(s)
+    getStory().append(Spacer(0,6))
 
 disc("""When unsplit and split at the first or second row.""")
 
@@ -234,27 +234,27 @@
        Image</para>''',
        styleSheet["BodyText"])
 data=  [['A',   'B', 'C',     P0, 'D'],
-		['00', '01', '02', [I,P], '04'],
-		['10', '11', '12', [P,I], '14'],
-		['20', '21', '22',  '23', '24'],
-		['30', '31', '32',  '33', '34']]
+        ['00', '01', '02', [I,P], '04'],
+        ['10', '11', '12', [P,I], '14'],
+        ['20', '21', '22',  '23', '24'],
+        ['30', '31', '32',  '33', '34']]
 
 t=Table(data,style=[('GRID',(1,1),(-2,-2),1,colors.green),
-					('BOX',(0,0),(1,-1),2,colors.red),
-					('LINEABOVE',(1,2),(-2,2),1,colors.blue),
-					('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
-					('BACKGROUND', (0, 0), (0, 1), colors.pink),
-					('BACKGROUND', (1, 1), (1, 2), colors.lavender),
-					('BACKGROUND', (2, 2), (2, 3), colors.orange),
-					('BOX',(0,0),(-1,-1),2,colors.black),
-					('GRID',(0,0),(-1,-1),0.5,colors.black),
-					('VALIGN',(3,0),(3,0),'BOTTOM'),
-					('BACKGROUND',(3,0),(3,0),colors.limegreen),
-					('BACKGROUND',(3,1),(3,1),colors.khaki),
-					('ALIGN',(3,1),(3,1),'CENTER'),
-					('BACKGROUND',(3,2),(3,2),colors.beige),
-					('ALIGN',(3,2),(3,2),'LEFT'),
-					])
+                    ('BOX',(0,0),(1,-1),2,colors.red),
+                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
+                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
+                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
+                    ('BACKGROUND', (1, 1), (1, 2), colors.lavender),
+                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
+                    ('BOX',(0,0),(-1,-1),2,colors.black),
+                    ('GRID',(0,0),(-1,-1),0.5,colors.black),
+                    ('VALIGN',(3,0),(3,0),'BOTTOM'),
+                    ('BACKGROUND',(3,0),(3,0),colors.limegreen),
+                    ('BACKGROUND',(3,1),(3,1),colors.khaki),
+                    ('ALIGN',(3,1),(3,1),'CENTER'),
+                    ('BACKGROUND',(3,2),(3,2),colors.beige),
+                    ('ALIGN',(3,2),(3,2),'LEFT'),
+                    ])
 
 t._argW[3]=1.5*inch
 """%I)
@@ -306,9 +306,9 @@
 """,after=0.1)
 disc("""will display as""")
 try:
-	getStory().append(Image(I))
+    getStory().append(Image(I))
 except:
-	disc("""An image should have appeared here.""")
+    disc("""An image should have appeared here.""")
 disc("""whereas""")
 eg("""
 im = Image("lj8100.jpg", width=2*inch, height=2*inch)
@@ -316,11 +316,11 @@
 """, after=0.1)
 disc('produces')
 try:
-	im = Image(I, width=2*inch, height=2*inch)
-	im.hAlign = 'CENTER'
-	getStory().append(Image(I, width=2*inch, height=2*inch))
+    im = Image(I, width=2*inch, height=2*inch)
+    im.hAlign = 'CENTER'
+    getStory().append(Image(I, width=2*inch, height=2*inch))
 except:
-	disc("""An image should have appeared here.""")
+    disc("""An image should have appeared here.""")
 heading2("""$Spacer(width, height)$""")
 disc("""This does exactly as would be expected; it adds a certain amount of space into the story.
 At present this only works for vertical space.
--- a/reportlab/docs/userguide/ch7_custom.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/docs/userguide/ch7_custom.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,7 +1,7 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/docs/userguide/ch7_custom.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/docs/userguide/ch7_custom.py,v 1.2 2001/10/27 22:37:02 andy_robinson Exp $
+#$Header: /tmp/reportlab/reportlab/docs/userguide/ch7_custom.py,v 1.3 2002/07/17 22:46:22 andy_robinson Exp $
 from reportlab.tools.docco.rl_doc_utils import *
 
 heading1("Writing your own $Flowable$ Objects")
@@ -71,12 +71,12 @@
 
 EmbeddedCode("""
 class RotatedImage(Image):
-	def wrap(self,availWidth,availHeight):
-		h, w = Image.wrap(self,availHeight,availWidth)
-		return w, h
-	def draw(self):
-		self.canv.rotate(90)
-		Image.draw(self)
+    def wrap(self,availWidth,availHeight):
+        h, w = Image.wrap(self,availHeight,availWidth)
+        return w, h
+    def draw(self):
+        self.canv.rotate(90)
+        Image.draw(self)
 I = RotatedImage('%s')
 I.hAlign = 'CENTER'
 """ % I,'I')
--- a/reportlab/docs/userguide/genuserguide.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/docs/userguide/genuserguide.py	Wed Jul 17 22:46:24 2002 +0000
@@ -2,9 +2,9 @@
 #copyright ReportLab Inc. 2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/docs/userguide/genuserguide.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/docs/userguide/genuserguide.py,v 1.10 2001/12/20 13:55:55 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/docs/userguide/genuserguide.py,v 1.11 2002/07/17 22:46:22 andy_robinson Exp $
 
-__version__=''' $Id: genuserguide.py,v 1.10 2001/12/20 13:55:55 rgbecker Exp $ '''
+__version__=''' $Id: genuserguide.py,v 1.11 2002/07/17 22:46:22 andy_robinson Exp $ '''
 
 __doc__ = """
 This module contains the script for building the user guide.
@@ -14,76 +14,76 @@
 
 def run(pagesize=defaultPageSize, verbose=0, outDir=None):
 
-	# copy to target
-	import reportlab
-	if not outDir: outDir = os.path.join(os.path.dirname(reportlab.__file__),'docs')
-	destfn = os.path.join(outDir,'userguide.pdf')
-	doc = RLDocTemplate(destfn,pagesize = pagesize)
+    # copy to target
+    import reportlab
+    if not outDir: outDir = os.path.join(os.path.dirname(reportlab.__file__),'docs')
+    destfn = os.path.join(outDir,'userguide.pdf')
+    doc = RLDocTemplate(destfn,pagesize = pagesize)
 
-	#this builds the story
-	#resetStory()
+    #this builds the story
+    #resetStory()
 
-	import ch1_intro
-	import ch2_graphics
-	import ch2a_fonts
-	import ch3_pdffeatures
-	import ch4_platypus_concepts
-	import ch5_paragraphs
-	import ch6_tables
-	import ch7_custom
-	import ch9_future
+    import ch1_intro
+    import ch2_graphics
+    import ch2a_fonts
+    import ch3_pdffeatures
+    import ch4_platypus_concepts
+    import ch5_paragraphs
+    import ch6_tables
+    import ch7_custom
+    import ch9_future
 
-	import app_demos
+    import app_demos
 
-	story = getStory()
-	if verbose: print 'Built story contains %d flowables...' % len(story)
-	doc.build(story)
-	if verbose: print 'Saved "%s"' % destfn
+    story = getStory()
+    if verbose: print 'Built story contains %d flowables...' % len(story)
+    doc.build(story)
+    if verbose: print 'Saved "%s"' % destfn
 
-	# remove *.pyc files
-	pat = os.path.join(os.path.dirname(sys.argv[0]), '*.pyc')
-	for file in glob.glob(pat):
-		os.remove(file)
+    # remove *.pyc files
+    pat = os.path.join(os.path.dirname(sys.argv[0]), '*.pyc')
+    for file in glob.glob(pat):
+        os.remove(file)
 
 
 def makeSuite():
-	"standard test harness support - run self as separate process"
-	from reportlab.test.utils import ScriptThatMakesFileTest
-	return ScriptThatMakesFileTest('../docs/userguide', 'genuserguide.py', 'userguide.pdf') 
+    "standard test harness support - run self as separate process"
+    from reportlab.test.utils import ScriptThatMakesFileTest
+    return ScriptThatMakesFileTest('../docs/userguide', 'genuserguide.py', 'userguide.pdf') 
 
 if __name__=="__main__":
-	outDir = filter(lambda x: x[:9]=='--outdir=',sys.argv)
-	if outDir:
-		outDir = outDir[0]
-		sys.argv.remove(outDir)
-		outDir = outDir[9:]
-	else:
-		outDir = None
-	verbose = '-s' not in sys.argv
-	if not verbose: sys.argv.remove('-s')
-	timing = '-timing' in sys.argv
-	if timing: sys.argv.remove('-timing')
-	prof = '-prof' in sys.argv
-	if prof: sys.argv.remove('-prof')
+    outDir = filter(lambda x: x[:9]=='--outdir=',sys.argv)
+    if outDir:
+        outDir = outDir[0]
+        sys.argv.remove(outDir)
+        outDir = outDir[9:]
+    else:
+        outDir = None
+    verbose = '-s' not in sys.argv
+    if not verbose: sys.argv.remove('-s')
+    timing = '-timing' in sys.argv
+    if timing: sys.argv.remove('-timing')
+    prof = '-prof' in sys.argv
+    if prof: sys.argv.remove('-prof')
 
-	if len(sys.argv) > 1:
-		try:
-			(w, h) = eval(sys.argv[1])
-		except:
-			print 'Expected page size in argument 1', sys.argv[1]
-			raise
-		if verbose:
-			print 'set page size to',sys.argv[1]
-	else:
-		(w, h) = defaultPageSize
-	if timing:
-		from time import time
-		t0 = time()
-		run((w, h), verbose,outDir)
-		if verbose:
-			print 'Generation of userguide took %.2f seconds' % (time()-t0)
-	elif prof:
-		import profile
-		profile.run('run((w, h),verbose,outDir)','genuserguide.stats')
-	else:
-		run((w, h), verbose,outDir)
+    if len(sys.argv) > 1:
+        try:
+            (w, h) = eval(sys.argv[1])
+        except:
+            print 'Expected page size in argument 1', sys.argv[1]
+            raise
+        if verbose:
+            print 'set page size to',sys.argv[1]
+    else:
+        (w, h) = defaultPageSize
+    if timing:
+        from time import time
+        t0 = time()
+        run((w, h), verbose,outDir)
+        if verbose:
+            print 'Generation of userguide took %.2f seconds' % (time()-t0)
+    elif prof:
+        import profile
+        profile.run('run((w, h),verbose,outDir)','genuserguide.stats')
+    else:
+        run((w, h), verbose,outDir)
--- a/reportlab/graphics/charts/axes.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/graphics/charts/axes.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,7 +1,7 @@
 #copyright ReportLab Inc. 2000-2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/graphics/charts/axes.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/graphics/charts/axes.py,v 1.56 2002/06/12 12:30:16 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/graphics/charts/axes.py,v 1.57 2002/07/17 22:46:22 andy_robinson Exp $
 """Collection of axes for charts.
 
 The current collection comprises axes for charts using cartesian
@@ -31,14 +31,14 @@
 at any absolute value (specified in points) or at some value of
 the former axes in its own coordinate system.
 """
-__version__=''' $Id: axes.py,v 1.56 2002/06/12 12:30:16 rgbecker Exp $ '''
+__version__=''' $Id: axes.py,v 1.57 2002/07/17 22:46:22 andy_robinson Exp $ '''
 
 import string
 from types import FunctionType, StringType, TupleType, ListType
 
-from reportlab.lib.validators import	isNumber, isNumberOrNone, isListOfStringsOrNone, isListOfNumbers, \
-										isListOfNumbersOrNone, isColorOrNone, OneOf, isBoolean, SequenceOf, \
-										isString
+from reportlab.lib.validators import    isNumber, isNumberOrNone, isListOfStringsOrNone, isListOfNumbers, \
+                                        isListOfNumbersOrNone, isColorOrNone, OneOf, isBoolean, SequenceOf, \
+                                        isString
 from reportlab.lib.attrmap import *
 from reportlab.lib import normalDate
 from reportlab.graphics.shapes import Drawing, Line, Group, STATE_DEFAULTS, _textBoxLimits, _rotatedBoxLimits
@@ -50,1773 +50,1773 @@
 # Helpers.
 
 def _findMinMaxValue(V, x, default, func):
-	if type(V[0][0]) in (TupleType,ListType):
-		V=map(lambda e,f=lambda T,x=x: T[x]: map(f,e),V)
-	V = filter(len,map(lambda x: filter(lambda x: x is not None,x),V))
-	if len(V)==0: return default
-	return func(map(func,V))
+    if type(V[0][0]) in (TupleType,ListType):
+        V=map(lambda e,f=lambda T,x=x: T[x]: map(f,e),V)
+    V = filter(len,map(lambda x: filter(lambda x: x is not None,x),V))
+    if len(V)==0: return default
+    return func(map(func,V))
 
 def _findMin(V, x, default):
-	'''find minimum over V[i][x]'''
-	return _findMinMaxValue(V,x,default,min)
+    '''find minimum over V[i][x]'''
+    return _findMinMaxValue(V,x,default,min)
 
 def _findMax(V, x, default):
-	'''find maximum over V[i][x]'''
-	return _findMinMaxValue(V,x,default,max)
+    '''find maximum over V[i][x]'''
+    return _findMinMaxValue(V,x,default,max)
 
 
 # Category axes.
 class CategoryAxis(Widget):
-	"Abstract category axis, unusable in itself."
-	_nodoc = 1
-	_attrMap = AttrMap(
-		visible = AttrMapValue(isBoolean, desc='Display entire object, if true.'),
-		visibleAxis = AttrMapValue(isBoolean, desc='Display axis line, if true.'),
-		visibleTicks = AttrMapValue(isBoolean, desc='Display axis ticks, if true.'),
-		visibleGrid = AttrMapValue(isBoolean, desc='Display axis grid, if true.'),
-		strokeWidth = AttrMapValue(isNumber, desc='Width of axis line and ticks.'),
-		strokeColor = AttrMapValue(isColorOrNone, desc='Color of axis line and ticks.'),
-		strokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for axis line.'),
-		gridStrokeWidth = AttrMapValue(isNumber, desc='Width of grid lines.'),
-		gridStrokeColor = AttrMapValue(isColorOrNone, desc='Color of grid lines.'),
-		gridStrokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for grid lines.'),
-		gridStart = AttrMapValue(isNumber, desc='Start of grid lines wrt axis origin'),
-		gridEnd = AttrMapValue(isNumber, desc='End of grid lines wrt axis origin'),
-		labels = AttrMapValue(None, desc='Handle of the axis labels.'),
-		categoryNames = AttrMapValue(isListOfStringsOrNone, desc='List of category names.'),
-		joinAxis = AttrMapValue(None, desc='Join both axes if true.'),
-		joinAxisPos = AttrMapValue(isNumberOrNone, desc='Position at which to join with other axis.'),
-		reverseDirection = AttrMapValue(isBoolean, desc='If true reverse category direction.'),
-		style = AttrMapValue(OneOf('parallel','stacked'),"How common category bars are plotted"),
-		labelAxisMode = AttrMapValue(OneOf('high','low','axis'), desc="Like joinAxisMode, but for the axis labels"),
-		)
+    "Abstract category axis, unusable in itself."
+    _nodoc = 1
+    _attrMap = AttrMap(
+        visible = AttrMapValue(isBoolean, desc='Display entire object, if true.'),
+        visibleAxis = AttrMapValue(isBoolean, desc='Display axis line, if true.'),
+        visibleTicks = AttrMapValue(isBoolean, desc='Display axis ticks, if true.'),
+        visibleGrid = AttrMapValue(isBoolean, desc='Display axis grid, if true.'),
+        strokeWidth = AttrMapValue(isNumber, desc='Width of axis line and ticks.'),
+        strokeColor = AttrMapValue(isColorOrNone, desc='Color of axis line and ticks.'),
+        strokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for axis line.'),
+        gridStrokeWidth = AttrMapValue(isNumber, desc='Width of grid lines.'),
+        gridStrokeColor = AttrMapValue(isColorOrNone, desc='Color of grid lines.'),
+        gridStrokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for grid lines.'),
+        gridStart = AttrMapValue(isNumber, desc='Start of grid lines wrt axis origin'),
+        gridEnd = AttrMapValue(isNumber, desc='End of grid lines wrt axis origin'),
+        labels = AttrMapValue(None, desc='Handle of the axis labels.'),
+        categoryNames = AttrMapValue(isListOfStringsOrNone, desc='List of category names.'),
+        joinAxis = AttrMapValue(None, desc='Join both axes if true.'),
+        joinAxisPos = AttrMapValue(isNumberOrNone, desc='Position at which to join with other axis.'),
+        reverseDirection = AttrMapValue(isBoolean, desc='If true reverse category direction.'),
+        style = AttrMapValue(OneOf('parallel','stacked'),"How common category bars are plotted"),
+        labelAxisMode = AttrMapValue(OneOf('high','low','axis'), desc="Like joinAxisMode, but for the axis labels"),
+        )
 
-	def __init__(self):
-		assert self.__class__.__name__!='CategoryAxis', "Abstract Class CategoryAxis Instantiated"
-		# private properties set by methods.  The initial values
-		# here are to make demos easy; they would always be
-		# overridden in real life.
-		self._x = 50
-		self._y = 50
-		self._length = 100
-		self._catCount = 0
+    def __init__(self):
+        assert self.__class__.__name__!='CategoryAxis', "Abstract Class CategoryAxis Instantiated"
+        # private properties set by methods.  The initial values
+        # here are to make demos easy; they would always be
+        # overridden in real life.
+        self._x = 50
+        self._y = 50
+        self._length = 100
+        self._catCount = 0
 
-		# public properties
-		self.visible = 1
-		self.visibleAxis = 1
-		self.visibleTicks = 1
-		self.visibleGrid = 0
+        # public properties
+        self.visible = 1
+        self.visibleAxis = 1
+        self.visibleTicks = 1
+        self.visibleGrid = 0
 
-		self.strokeWidth = 1
-		self.strokeColor = STATE_DEFAULTS['strokeColor']
-		self.strokeDashArray = STATE_DEFAULTS['strokeDashArray']
-		self.gridStrokeWidth = 0.25
-		self.gridStrokeColor = STATE_DEFAULTS['strokeColor']
-		self.gridStrokeDashArray = STATE_DEFAULTS['strokeDashArray']
-		self.gridStart = self.gridEnd = 0
-		self.labels = TypedPropertyCollection(Label)
-		# if None, they don't get labels. If provided,
-		# you need one name per data point and they are
-		# used for label text.
-		self.categoryNames = None
-		self.joinAxis = None
-		self.joinAxisPos = None
-		self.joinAxisMode = None
-		self.labelAxisMode = 'axis'
-		self.reverseDirection = 0
-		self.style = 'parallel'
+        self.strokeWidth = 1
+        self.strokeColor = STATE_DEFAULTS['strokeColor']
+        self.strokeDashArray = STATE_DEFAULTS['strokeDashArray']
+        self.gridStrokeWidth = 0.25
+        self.gridStrokeColor = STATE_DEFAULTS['strokeColor']
+        self.gridStrokeDashArray = STATE_DEFAULTS['strokeDashArray']
+        self.gridStart = self.gridEnd = 0
+        self.labels = TypedPropertyCollection(Label)
+        # if None, they don't get labels. If provided,
+        # you need one name per data point and they are
+        # used for label text.
+        self.categoryNames = None
+        self.joinAxis = None
+        self.joinAxisPos = None
+        self.joinAxisMode = None
+        self.labelAxisMode = 'axis'
+        self.reverseDirection = 0
+        self.style = 'parallel'
 
-	def setPosition(self, x, y, length):
-		# ensure floating point
-		self._x = x
-		self._y = y
-		self._length = length
+    def setPosition(self, x, y, length):
+        # ensure floating point
+        self._x = x
+        self._y = y
+        self._length = length
 
 
-	def configure(self, multiSeries,barWidth=None):
-		self._catCount = max(map(len,multiSeries))
-		self._barWidth = barWidth or (self._length/float(self._catCount or 1))
+    def configure(self, multiSeries,barWidth=None):
+        self._catCount = max(map(len,multiSeries))
+        self._barWidth = barWidth or (self._length/float(self._catCount or 1))
 
-	def draw(self):
-		g = Group()
+    def draw(self):
+        g = Group()
 
-		if not self.visible:
-			return g
+        if not self.visible:
+            return g
 
-		g.add(self.makeAxis())
-		g.add(self.makeTicks())
-		g.add(self.makeTickLabels())
+        g.add(self.makeAxis())
+        g.add(self.makeTicks())
+        g.add(self.makeTickLabels())
 
-		return g
+        return g
 
-	def _scale(self,idx):
-		if self.reverseDirection: idx = self._catCount-idx-1
-		return idx
+    def _scale(self,idx):
+        if self.reverseDirection: idx = self._catCount-idx-1
+        return idx
 
-	def makeGrid(self,g):
-		'''this is only called by a container object'''
-		if self.visibleGrid and (self.gridStart or self.gridEnd):
-			self._makeLines(g,self.gridStart,self.gridEnd,self.gridStrokeColor,self.gridStrokeWidth,self.gridStrokeDashArray)
+    def makeGrid(self,g):
+        '''this is only called by a container object'''
+        if self.visibleGrid and (self.gridStart or self.gridEnd):
+            self._makeLines(g,self.gridStart,self.gridEnd,self.gridStrokeColor,self.gridStrokeWidth,self.gridStrokeDashArray)
 
 
 class XCategoryAxis(CategoryAxis):
-	"X/category axis"
+    "X/category axis"
 
-	_attrMap = AttrMap(BASE=CategoryAxis,
-		tickUp = AttrMapValue(isNumber,
-			desc='Tick length up the axis.'),
-		tickDown = AttrMapValue(isNumber,
-			desc='Tick length down the axis.'),
-		joinAxisMode = AttrMapValue(OneOf('bottom', 'top', 'value', 'points', None),
-			desc="Mode used for connecting axis ('bottom', 'top', 'value', 'points', None)."),
-		)
+    _attrMap = AttrMap(BASE=CategoryAxis,
+        tickUp = AttrMapValue(isNumber,
+            desc='Tick length up the axis.'),
+        tickDown = AttrMapValue(isNumber,
+            desc='Tick length down the axis.'),
+        joinAxisMode = AttrMapValue(OneOf('bottom', 'top', 'value', 'points', None),
+            desc="Mode used for connecting axis ('bottom', 'top', 'value', 'points', None)."),
+        )
 
-	def __init__(self):
-		CategoryAxis.__init__(self)
-		self.labels.boxAnchor = 'n' #north - top edge
-		self.labels.dy = -5
-		# ultra-simple tick marks for now go between categories
-		# and have same line style as axis - need more
-		self.tickUp = 0  # how far into chart does tick go?
-		self.tickDown = 5  # how far below axis does tick go?
+    def __init__(self):
+        CategoryAxis.__init__(self)
+        self.labels.boxAnchor = 'n' #north - top edge
+        self.labels.dy = -5
+        # ultra-simple tick marks for now go between categories
+        # and have same line style as axis - need more
+        self.tickUp = 0  # how far into chart does tick go?
+        self.tickDown = 5  # how far below axis does tick go?
 
 
-	def demo(self):
-		self.setPosition(30, 70, 140)
-		self.configure([(10,20,30,40,50)])
+    def demo(self):
+        self.setPosition(30, 70, 140)
+        self.configure([(10,20,30,40,50)])
 
-		self.categoryNames = ['One','Two','Three','Four','Five']
-		# all labels top-centre aligned apart from the last
-		self.labels.boxAnchor = 'n'
-		self.labels[4].boxAnchor = 'e'
-		self.labels[4].angle = 90
+        self.categoryNames = ['One','Two','Three','Four','Five']
+        # all labels top-centre aligned apart from the last
+        self.labels.boxAnchor = 'n'
+        self.labels[4].boxAnchor = 'e'
+        self.labels[4].angle = 90
 
-		d = Drawing(200, 100)
-		d.add(self)
-		return d
+        d = Drawing(200, 100)
+        d.add(self)
+        return d
 
 
-	def joinToAxis(self, yAxis, mode='bottom', pos=None):
-		"Join with y-axis using some mode."
+    def joinToAxis(self, yAxis, mode='bottom', pos=None):
+        "Join with y-axis using some mode."
 
-		# Make sure we connect only to a y-axis.
-		axisClassName = yAxis.__class__.__name__
-		msg = "Cannot connect to other axes (%s), but Y- ones." % axisClassName
-		assert axisClassName[0] == 'Y', msg
+        # Make sure we connect only to a y-axis.
+        axisClassName = yAxis.__class__.__name__
+        msg = "Cannot connect to other axes (%s), but Y- ones." % axisClassName
+        assert axisClassName[0] == 'Y', msg
 
-		if mode == 'bottom':
-			self._x = yAxis._x
-			self._y = yAxis._y
-		elif mode == 'top':
-			self._x = yAxis._x
-			self._y = yAxis._y + yAxis._length
-		elif mode == 'value':
-			self._x = yAxis._x
-			self._y = yAxis.scale(pos)
-		elif mode == 'points':
-			self._x = yAxis._x
-			self._y = pos
+        if mode == 'bottom':
+            self._x = yAxis._x
+            self._y = yAxis._y
+        elif mode == 'top':
+            self._x = yAxis._x
+            self._y = yAxis._y + yAxis._length
+        elif mode == 'value':
+            self._x = yAxis._x
+            self._y = yAxis.scale(pos)
+        elif mode == 'points':
+            self._x = yAxis._x
+            self._y = pos
 
 
-	def scale(self, idx):
-		"""returns the x position and width in drawing units of the slice"""
-		return (self._x + self._scale(idx)*self._barWidth, self._barWidth)
+    def scale(self, idx):
+        """returns the x position and width in drawing units of the slice"""
+        return (self._x + self._scale(idx)*self._barWidth, self._barWidth)
 
 
-	def makeAxis(self):
-		g = Group()
+    def makeAxis(self):
+        g = Group()
 
 
-		ja = self.joinAxis
-		if ja:
-			jam = self.joinAxisMode
-			jap = self.joinAxisPos
-			jta = self.joinToAxis
-			if jam in ('bottom', 'top'):
-				jta(ja, mode=jam)
-			elif jam in ('value', 'points'):
-				jta(ja, mode=jam, pos=jap)
+        ja = self.joinAxis
+        if ja:
+            jam = self.joinAxisMode
+            jap = self.joinAxisPos
+            jta = self.joinToAxis
+            if jam in ('bottom', 'top'):
+                jta(ja, mode=jam)
+            elif jam in ('value', 'points'):
+                jta(ja, mode=jam, pos=jap)
 
-		if not self.visibleAxis: return g
+        if not self.visibleAxis: return g
 
-		axis = Line(self._x, self._y, self._x + self._length, self._y)
-		axis.strokeColor = self.strokeColor
-		axis.strokeWidth = self.strokeWidth
-		axis.strokeDashArray = self.strokeDashArray
-		g.add(axis)
+        axis = Line(self._x, self._y, self._x + self._length, self._y)
+        axis.strokeColor = self.strokeColor
+        axis.strokeWidth = self.strokeWidth
+        axis.strokeDashArray = self.strokeDashArray
+        g.add(axis)
 
-		return g
+        return g
 
-	def _makeLines(self,g,start,end,strokeColor,strokeWidth,strokeDashArray):
-		for i in range(self._catCount+1):
-			x = self._x + i*self._barWidth
-			L = Line(x, self._y + start, x, self._y + end)
-			L.strokeColor = strokeColor
-			L.strokeWidth = strokeWidth
-			L.strokeDashArray = strokeDashArray
-			g.add(L)
-		return g
+    def _makeLines(self,g,start,end,strokeColor,strokeWidth,strokeDashArray):
+        for i in range(self._catCount+1):
+            x = self._x + i*self._barWidth
+            L = Line(x, self._y + start, x, self._y + end)
+            L.strokeColor = strokeColor
+            L.strokeWidth = strokeWidth
+            L.strokeDashArray = strokeDashArray
+            g.add(L)
+        return g
 
-	def makeTicks(self):
-		g = Group()
-		if not self.visibleTicks: return g
-		if self.tickUp or self.tickDown:
-			self._makeLines(g,self.tickUp,-self.tickDown,self.strokeColor,self.strokeWidth,self.strokeDashArray)
-		return g
+    def makeTicks(self):
+        g = Group()
+        if not self.visibleTicks: return g
+        if self.tickUp or self.tickDown:
+            self._makeLines(g,self.tickUp,-self.tickDown,self.strokeColor,self.strokeWidth,self.strokeDashArray)
+        return g
 
-	def _labelAxisPos(self):
-		axis = self.joinAxis
-		if axis:
-			mode = self.labelAxisMode
-			if mode == 'low':
-				return axis._y
-			elif mode == 'high':
-				return axis._y + axis._length
-		return self._y
+    def _labelAxisPos(self):
+        axis = self.joinAxis
+        if axis:
+            mode = self.labelAxisMode
+            if mode == 'low':
+                return axis._y
+            elif mode == 'high':
+                return axis._y + axis._length
+        return self._y
 
-	def makeTickLabels(self):
-		g = Group()
+    def makeTickLabels(self):
+        g = Group()
 
-		if not self.visibleTicks:
-			return g
+        if not self.visibleTicks:
+            return g
 
-		if not (self.categoryNames is None):
-			catCount = self._catCount
-			assert len(self.categoryNames) == catCount, \
-				"expected %d category names but found %d in axis" % (
-				len(self.categoryNames), catCount
-				)
-			reverseDirection = self.reverseDirection
-			barWidth = self._barWidth
-			_y = self._labelAxisPos()
-			_x = self._x
+        if not (self.categoryNames is None):
+            catCount = self._catCount
+            assert len(self.categoryNames) == catCount, \
+                "expected %d category names but found %d in axis" % (
+                len(self.categoryNames), catCount
+                )
+            reverseDirection = self.reverseDirection
+            barWidth = self._barWidth
+            _y = self._labelAxisPos()
+            _x = self._x
 
-			for i in range(catCount):
-				x = _x + (i+0.5) * barWidth
-				label = self.labels[i]
-				label.setOrigin(x, _y)
-				if reverseDirection: i = catCount-i-1
-				label.setText(self.categoryNames[i])
-				g.add(label)
+            for i in range(catCount):
+                x = _x + (i+0.5) * barWidth
+                label = self.labels[i]
+                label.setOrigin(x, _y)
+                if reverseDirection: i = catCount-i-1
+                label.setText(self.categoryNames[i])
+                g.add(label)
 
-		return g
+        return g
 
 
 class YCategoryAxis(CategoryAxis):
-	"Y/category axis"
+    "Y/category axis"
 
-	_attrMap = AttrMap(BASE=CategoryAxis,
-		tickLeft = AttrMapValue(isNumber,
-			desc='Tick length left of the axis.'),
-		tickRight = AttrMapValue(isNumber,
-			desc='Tick length right of the axis.'),
-		joinAxisMode = AttrMapValue(OneOf(('left', 'right', 'value', 'points', None)),
-			desc="Mode used for connecting axis ('left', 'right', 'value', 'points', None)."),
-		)
+    _attrMap = AttrMap(BASE=CategoryAxis,
+        tickLeft = AttrMapValue(isNumber,
+            desc='Tick length left of the axis.'),
+        tickRight = AttrMapValue(isNumber,
+            desc='Tick length right of the axis.'),
+        joinAxisMode = AttrMapValue(OneOf(('left', 'right', 'value', 'points', None)),
+            desc="Mode used for connecting axis ('left', 'right', 'value', 'points', None)."),
+        )
 
 
-	def __init__(self):
-		CategoryAxis.__init__(self)
-		self.labels.boxAnchor = 'e' #east - right edge
-		self.labels.dx = -5
-		# ultra-simple tick marks for now go between categories
-		# and have same line style as axis - need more
-		self.tickLeft = 5  # how far left of axis does tick go?
-		self.tickRight = 0	# how far right of axis does tick go?
+    def __init__(self):
+        CategoryAxis.__init__(self)
+        self.labels.boxAnchor = 'e' #east - right edge
+        self.labels.dx = -5
+        # ultra-simple tick marks for now go between categories
+        # and have same line style as axis - need more
+        self.tickLeft = 5  # how far left of axis does tick go?
+        self.tickRight = 0  # how far right of axis does tick go?
 
 
-	def demo(self):
-		self.setPosition(50, 10, 80)
-		self.configure([(10,20,30)])
-		self.categoryNames = ['One','Two','Three']
-		# all labels top-centre aligned apart from the last
-		self.labels.boxAnchor = 'e'
-		self.labels[2].boxAnchor = 's'
-		self.labels[2].angle = 90
+    def demo(self):
+        self.setPosition(50, 10, 80)
+        self.configure([(10,20,30)])
+        self.categoryNames = ['One','Two','Three']
+        # all labels top-centre aligned apart from the last
+        self.labels.boxAnchor = 'e'
+        self.labels[2].boxAnchor = 's'
+        self.labels[2].angle = 90
 
-		d = Drawing(200, 100)
-		d.add(self)
-		return d
+        d = Drawing(200, 100)
+        d.add(self)
+        return d
 
 
-	def joinToAxis(self, xAxis, mode='left', pos=None):
-		"Join with x-axis using some mode."
+    def joinToAxis(self, xAxis, mode='left', pos=None):
+        "Join with x-axis using some mode."
 
-		# Make sure we connect only to a y-axis.
-		axisClassName = xAxis.__class__.__name__
-		msg = "Cannot connect to other axes (%s), but X- ones." % axisClassName
-		assert axisClassName[0] == 'X', msg
+        # Make sure we connect only to a y-axis.
+        axisClassName = xAxis.__class__.__name__
+        msg = "Cannot connect to other axes (%s), but X- ones." % axisClassName
+        assert axisClassName[0] == 'X', msg
 
-		if mode == 'left':
-			self._x = xAxis._x * 1.0
-			self._y = xAxis._y * 1.0
-		elif mode == 'right':
-			self._x = (xAxis._x + xAxis._length) * 1.0
-			self._y = xAxis._y * 1.0
-		elif mode == 'value':
-			self._x = xAxis.scale(pos) * 1.0
-			self._y = xAxis._y * 1.0
-		elif mode == 'points':
-			self._x = pos * 1.0
-			self._y = xAxis._y * 1.0
+        if mode == 'left':
+            self._x = xAxis._x * 1.0
+            self._y = xAxis._y * 1.0
+        elif mode == 'right':
+            self._x = (xAxis._x + xAxis._length) * 1.0
+            self._y = xAxis._y * 1.0
+        elif mode == 'value':
+            self._x = xAxis.scale(pos) * 1.0
+            self._y = xAxis._y * 1.0
+        elif mode == 'points':
+            self._x = pos * 1.0
+            self._y = xAxis._y * 1.0
 
 
-	def scale(self, idx):
-		"Returns the y position and width in drawing units of the slice."
-		return (self._y + self._scale(idx)*self._barWidth, self._barWidth)
+    def scale(self, idx):
+        "Returns the y position and width in drawing units of the slice."
+        return (self._y + self._scale(idx)*self._barWidth, self._barWidth)
 
 
-	def makeAxis(self):
-		g = Group()
+    def makeAxis(self):
+        g = Group()
 
-		if not self.visibleAxis:
-			return g
+        if not self.visibleAxis:
+            return g
 
-		ja = self.joinAxis
-		if ja:
-			jam = self.joinAxisMode
-			jap = self.joinAxisPos
-			jta = self.joinToAxis
-			if jam in ('left', 'right'):
-				jta(ja, mode=jam)
-			elif jam in ('value', 'points'):
-				jta(ja, mode=jam, pos=jap)
+        ja = self.joinAxis
+        if ja:
+            jam = self.joinAxisMode
+            jap = self.joinAxisPos
+            jta = self.joinToAxis
+            if jam in ('left', 'right'):
+                jta(ja, mode=jam)
+            elif jam in ('value', 'points'):
+                jta(ja, mode=jam, pos=jap)
 
-		axis = Line(self._x, self._y, self._x, self._y + self._length)
-		axis.strokeColor = self.strokeColor
-		axis.strokeWidth = self.strokeWidth
-		axis.strokeDashArray = self.strokeDashArray
-		g.add(axis)
+        axis = Line(self._x, self._y, self._x, self._y + self._length)
+        axis.strokeColor = self.strokeColor
+        axis.strokeWidth = self.strokeWidth
+        axis.strokeDashArray = self.strokeDashArray
+        g.add(axis)
 
-		return g
+        return g
 
 
-	def _makeLines(self,g,start,end,strokeColor,strokeWidth,strokeDashArray):
-		for i in range(self._catCount + 1):
-			y = self._y + i*self._barWidth
-			L = Line(self._x+start, y, self._x+end, y)
-			L.strokeColor = self.strokeColor
-			L.strokeWidth = self.strokeWidth
-			L.strokeDashArray = self.strokeDashArray
-			g.add(L)
+    def _makeLines(self,g,start,end,strokeColor,strokeWidth,strokeDashArray):
+        for i in range(self._catCount + 1):
+            y = self._y + i*self._barWidth
+            L = Line(self._x+start, y, self._x+end, y)
+            L.strokeColor = self.strokeColor
+            L.strokeWidth = self.strokeWidth
+            L.strokeDashArray = self.strokeDashArray
+            g.add(L)
 
-	def makeTicks(self):
-		g = Group()
-		if not self.visibleTicks: return g
-		if self.tickLeft or self.tickRight:
-			self._makeLines(g,-self.tickLeft,self.tickRight,self.strokeColor,self.strokeWidth,self.strokeDashArray)
-		return g
+    def makeTicks(self):
+        g = Group()
+        if not self.visibleTicks: return g
+        if self.tickLeft or self.tickRight:
+            self._makeLines(g,-self.tickLeft,self.tickRight,self.strokeColor,self.strokeWidth,self.strokeDashArray)
+        return g
 
-	def _labelAxisPos(self):
-		axis = self.joinAxis
-		if axis:
-			mode = self.labelAxisMode
-			if mode == 'low':
-				return axis._x
-			elif mode == 'high':
-				return axis._x + axis._length
-		return self._x
+    def _labelAxisPos(self):
+        axis = self.joinAxis
+        if axis:
+            mode = self.labelAxisMode
+            if mode == 'low':
+                return axis._x
+            elif mode == 'high':
+                return axis._x + axis._length
+        return self._x
 
-	def makeTickLabels(self):
-		g = Group()
+    def makeTickLabels(self):
+        g = Group()
 
-		if not self.visibleTicks:
-			return g
+        if not self.visibleTicks:
+            return g
 
-		if not (self.categoryNames is None):
-			catCount = self._catCount
-			assert len(self.categoryNames) == catCount, \
-				"expected %d category names but found %d in axis" % (
-				len(self.categoryNames), catCount
-				)
-			reverseDirection = self.reverseDirection
-			barWidth = self._barWidth
-			labels = self.labels
-			_x = self._labelAxisPos()
-			_y = self._y
-			for i in range(catCount):
-				y = _y + (i+0.5) * barWidth
-				label = labels[i]
-				label.setOrigin(_x, y)
-				if reverseDirection: i = catCount-i-1
-				label.setText(self.categoryNames[i])
-				g.add(label)
+        if not (self.categoryNames is None):
+            catCount = self._catCount
+            assert len(self.categoryNames) == catCount, \
+                "expected %d category names but found %d in axis" % (
+                len(self.categoryNames), catCount
+                )
+            reverseDirection = self.reverseDirection
+            barWidth = self._barWidth
+            labels = self.labels
+            _x = self._labelAxisPos()
+            _y = self._y
+            for i in range(catCount):
+                y = _y + (i+0.5) * barWidth
+                label = labels[i]
+                label.setOrigin(_x, y)
+                if reverseDirection: i = catCount-i-1
+                label.setText(self.categoryNames[i])
+                g.add(label)
 
-		return g
+        return g
 
 
 # Value axes.
 class ValueAxis(Widget):
-	"Abstract value axis, unusable in itself."
+    "Abstract value axis, unusable in itself."
 
-	_attrMap = AttrMap(
-		forceZero = AttrMapValue(isBoolean, desc='Ensure zero in range if true.'),
-		visible = AttrMapValue(isBoolean, desc='Display entire object, if true.'),
-		visibleAxis = AttrMapValue(isBoolean, desc='Display axis line, if true.'),
-		visibleTicks = AttrMapValue(isBoolean, desc='Display axis ticks, if true.'),
-		visibleGrid = AttrMapValue(isBoolean, desc='Display axis grid, if true.'),
-		strokeWidth = AttrMapValue(isNumber, desc='Width of axis line and ticks.'),
-		strokeColor = AttrMapValue(isColorOrNone, desc='Color of axis line and ticks.'),
-		strokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for axis line.'),
-		gridStrokeWidth = AttrMapValue(isNumber, desc='Width of grid lines.'),
-		gridStrokeColor = AttrMapValue(isColorOrNone, desc='Color of grid lines.'),
-		gridStrokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for grid lines.'),
-		gridStart = AttrMapValue(isNumber, desc='Start of grid lines wrt axis origin'),
-		gridEnd = AttrMapValue(isNumber, desc='End of grid lines wrt axis origin'),
-		minimumTickSpacing = AttrMapValue(isNumber, desc='Minimum value for distance between ticks.'),
-		maximumTicks = AttrMapValue(isNumber, desc='Maximum number of ticks.'),
-		labels = AttrMapValue(None, desc='Handle of the axis labels.'),
-		labelTextFormat = AttrMapValue(None, desc='Formatting string or function used for axis labels.'),
-		valueMin = AttrMapValue(isNumberOrNone, desc='Minimum value on axis.'),
-		valueMax = AttrMapValue(isNumberOrNone, desc='Maximum value on axis.'),
-		valueStep = AttrMapValue(isNumberOrNone, desc='Step size used between ticks.'),
-		valueSteps = AttrMapValue(isListOfNumbersOrNone, desc='List of step sizes used between ticks.'),
-		avoidBoundFrac = AttrMapValue(isNumberOrNone, desc='Fraction of interval to allow above and below.'),
-		rangeRound=AttrMapValue(OneOf('none','both','ceiling','floor'),'How to round the axis limits'),
-		)
+    _attrMap = AttrMap(
+        forceZero = AttrMapValue(isBoolean, desc='Ensure zero in range if true.'),
+        visible = AttrMapValue(isBoolean, desc='Display entire object, if true.'),
+        visibleAxis = AttrMapValue(isBoolean, desc='Display axis line, if true.'),
+        visibleTicks = AttrMapValue(isBoolean, desc='Display axis ticks, if true.'),
+        visibleGrid = AttrMapValue(isBoolean, desc='Display axis grid, if true.'),
+        strokeWidth = AttrMapValue(isNumber, desc='Width of axis line and ticks.'),
+        strokeColor = AttrMapValue(isColorOrNone, desc='Color of axis line and ticks.'),
+        strokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for axis line.'),
+        gridStrokeWidth = AttrMapValue(isNumber, desc='Width of grid lines.'),
+        gridStrokeColor = AttrMapValue(isColorOrNone, desc='Color of grid lines.'),
+        gridStrokeDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array used for grid lines.'),
+        gridStart = AttrMapValue(isNumber, desc='Start of grid lines wrt axis origin'),
+        gridEnd = AttrMapValue(isNumber, desc='End of grid lines wrt axis origin'),
+        minimumTickSpacing = AttrMapValue(isNumber, desc='Minimum value for distance between ticks.'),
+        maximumTicks = AttrMapValue(isNumber, desc='Maximum number of ticks.'),
+        labels = AttrMapValue(None, desc='Handle of the axis labels.'),
+        labelTextFormat = AttrMapValue(None, desc='Formatting string or function used for axis labels.'),
+        valueMin = AttrMapValue(isNumberOrNone, desc='Minimum value on axis.'),
+        valueMax = AttrMapValue(isNumberOrNone, desc='Maximum value on axis.'),
+        valueStep = AttrMapValue(isNumberOrNone, desc='Step size used between ticks.'),
+        valueSteps = AttrMapValue(isListOfNumbersOrNone, desc='List of step sizes used between ticks.'),
+        avoidBoundFrac = AttrMapValue(isNumberOrNone, desc='Fraction of interval to allow above and below.'),
+        rangeRound=AttrMapValue(OneOf('none','both','ceiling','floor'),'How to round the axis limits'),
+        )
 
-	def __init__(self):
-		assert self.__class__.__name__!='ValueAxis', 'Abstract Class ValueAxis Instantiated'
-		self._configured = 0
-		# private properties set by methods.  The initial values
-		# here are to make demos easy; they would always be
-		# overridden in real life.
-		self._x = 50
-		self._y = 50
-		self._length = 100
+    def __init__(self):
+        assert self.__class__.__name__!='ValueAxis', 'Abstract Class ValueAxis Instantiated'
+        self._configured = 0
+        # private properties set by methods.  The initial values
+        # here are to make demos easy; they would always be
+        # overridden in real life.
+        self._x = 50
+        self._y = 50
+        self._length = 100
 
-		# public properties
-		self.visible = 1
-		self.visibleAxis = 1
-		self.visibleTicks = 1
-		self.visibleGrid = 0
-		self.forceZero = 0
+        # public properties
+        self.visible = 1
+        self.visibleAxis = 1
+        self.visibleTicks = 1
+        self.visibleGrid = 0
+        self.forceZero = 0
 
-		self.strokeWidth = 1
-		self.strokeColor = STATE_DEFAULTS['strokeColor']
-		self.strokeDashArray = STATE_DEFAULTS['strokeDashArray']
-		self.gridStrokeWidth = 0.25
-		self.gridStrokeColor = STATE_DEFAULTS['strokeColor']
-		self.gridStrokeDashArray = STATE_DEFAULTS['strokeDashArray']
-		self.gridStart = self.gridEnd = 0
+        self.strokeWidth = 1
+        self.strokeColor = STATE_DEFAULTS['strokeColor']
+        self.strokeDashArray = STATE_DEFAULTS['strokeDashArray']
+        self.gridStrokeWidth = 0.25
+        self.gridStrokeColor = STATE_DEFAULTS['strokeColor']
+        self.gridStrokeDashArray = STATE_DEFAULTS['strokeDashArray']
+        self.gridStart = self.gridEnd = 0
 
-		self.labels = TypedPropertyCollection(Label)
-		self.labels.angle = 0
+        self.labels = TypedPropertyCollection(Label)
+        self.labels.angle = 0
 
-		# how close can the ticks be?
-		self.minimumTickSpacing = 10
-		self.maximumTicks = 7
+        # how close can the ticks be?
+        self.minimumTickSpacing = 10
+        self.maximumTicks = 7
 
-		# this may be either of (a) a format string like '%0.2f'
-		# or (b) a function which takes the value as an argument
-		# and returns a chunk of text.	So you can write a
-		# 'formatMonthEndDate' function and use that on irregular
-		# data points.
-		self.labelTextFormat = '%d'
+        # this may be either of (a) a format string like '%0.2f'
+        # or (b) a function which takes the value as an argument
+        # and returns a chunk of text.  So you can write a
+        # 'formatMonthEndDate' function and use that on irregular
+        # data points.
+        self.labelTextFormat = '%d'
 
-		# if set to None, these will be worked out for you.
-		# if you override any or all of them, your values
-		# will be used.
-		self.valueMin = None
-		self.valueMax = None
-		self.valueStep = None
-		self.avoidBoundFrac = None
-		self.rangeRound = 'none'
+        # if set to None, these will be worked out for you.
+        # if you override any or all of them, your values
+        # will be used.
+        self.valueMin = None
+        self.valueMax = None
+        self.valueStep = None
+        self.avoidBoundFrac = None
+        self.rangeRound = 'none'
 
 
-	def setPosition(self, x, y, length):
-		# ensure floating point
-		self._x = x * 1.0
-		self._y = y * 1.0
-		self._length = length * 1.0
+    def setPosition(self, x, y, length):
+        # ensure floating point
+        self._x = x * 1.0
+        self._y = y * 1.0
+        self._length = length * 1.0
 
 
-	def configure(self, dataSeries):
-		"""Let the axis configure its scale and range based on the data.
+    def configure(self, dataSeries):
+        """Let the axis configure its scale and range based on the data.
 
-		Called after setPosition. Let it look at a list of lists of
-		numbers determine the tick mark intervals.	If valueMin,
-		valueMax and valueStep are configured then it
-		will use them; if any of them are set to None it
-		will look at the data and make some sensible decision.
-		You may override this to build custom axes with
-		irregular intervals.  It creates an internal
-		variable self._values, which is a list of numbers
-		to use in plotting.
-		"""
-		self._setRange(dataSeries)
-		self._calcScaleFactor()
-		self._calcTickmarkPositions()
-		self._configured = 1
+        Called after setPosition. Let it look at a list of lists of
+        numbers determine the tick mark intervals.  If valueMin,
+        valueMax and valueStep are configured then it
+        will use them; if any of them are set to None it
+        will look at the data and make some sensible decision.
+        You may override this to build custom axes with
+        irregular intervals.  It creates an internal
+        variable self._values, which is a list of numbers
+        to use in plotting.
+        """
+        self._setRange(dataSeries)
+        self._calcScaleFactor()
+        self._calcTickmarkPositions()
+        self._configured = 1
 
 
-	def _setRange(self, dataSeries):
-		"""Set minimum and maximum axis values.
+    def _setRange(self, dataSeries):
+        """Set minimum and maximum axis values.
 
-		The dataSeries argument is assumed to be a list of data
-		vectors. Each vector is itself a list or tuple of numbers.
+        The dataSeries argument is assumed to be a list of data
+        vectors. Each vector is itself a list or tuple of numbers.
 
-		Returns a min, max tuple.
-		"""
+        Returns a min, max tuple.
+        """
 
-		valueMin, valueMax, rangeRound = self.valueMin, self.valueMax, self.rangeRound
-		if valueMin is None: self._cValueMin = valueMin = _findMin(dataSeries,self._dataIndex,0)
-		if valueMax is None: self._cValueMax = valueMax = _findMax(dataSeries,self._dataIndex,0)
-		if valueMin == valueMax:
-			if valueMax==0:
-				valueMax = 0.01
-				valueMin = -0.01
-			else:
-				a = abs(valueMax)
-				valueMax = valueMax + a
-				valueMin = valueMin - a
-		if self.forceZero:
-			if valueMax<0: valueMax=0
-			elif valueMin>0: valueMin = 0
+        valueMin, valueMax, rangeRound = self.valueMin, self.valueMax, self.rangeRound
+        if valueMin is None: self._cValueMin = valueMin = _findMin(dataSeries,self._dataIndex,0)
+        if valueMax is None: self._cValueMax = valueMax = _findMax(dataSeries,self._dataIndex,0)
+        if valueMin == valueMax:
+            if valueMax==0:
+                valueMax = 0.01
+                valueMin = -0.01
+            else:
+                a = abs(valueMax)
+                valueMax = valueMax + a
+                valueMin = valueMin - a
+        if self.forceZero:
+            if valueMax<0: valueMax=0
+            elif valueMin>0: valueMin = 0
 
-		if rangeRound is not 'neither' and not getattr(self,'valueSteps',None):
-			self._valueMin, self._valueMax = valueMin, valueMax
-			P = self._calcTickPositions()
-			if len(P)>1:
-				valueStep = P[1]-P[0]
-			else:
-				oVS = self.valueStep
-				self.valueStep = None
-				P = self._calcTickPositions()
-				self.valueStep = oVS
-				if len(P)>1:
-					valueStep = P[1]-P[0]
-				else:
-					valueStep = self._valueStep
-			fuzz = 1e-8*valueStep
-			if rangeRound in ['both','floor'] and valueMin<P[0]-fuzz: valueMin = P[0]-valueStep
-			if rangeRound in ['both','ceiling'] and valueMax>P[-1]+fuzz: valueMax = P[-1]+valueStep
+        if rangeRound is not 'neither' and not getattr(self,'valueSteps',None):
+            self._valueMin, self._valueMax = valueMin, valueMax
+            P = self._calcTickPositions()
+            if len(P)>1:
+                valueStep = P[1]-P[0]
+            else:
+                oVS = self.valueStep
+                self.valueStep = None
+                P = self._calcTickPositions()
+                self.valueStep = oVS
+                if len(P)>1:
+                    valueStep = P[1]-P[0]
+                else:
+                    valueStep = self._valueStep
+            fuzz = 1e-8*valueStep
+            if rangeRound in ['both','floor'] and valueMin<P[0]-fuzz: valueMin = P[0]-valueStep
+            if rangeRound in ['both','ceiling'] and valueMax>P[-1]+fuzz: valueMax = P[-1]+valueStep
 
-		self._valueMin, self._valueMax = valueMin, valueMax
-		self._rangeAdjust()
+        self._valueMin, self._valueMax = valueMin, valueMax
+        self._rangeAdjust()
 
 
-	def _rangeAdjust(self):
-		"""Override this if you want to alter the calculated range.
+    def _rangeAdjust(self):
+        """Override this if you want to alter the calculated range.
 
-		E.g. if want a minumamum range of 30% or don't want 100%
-		as the first point.
-		"""
+        E.g. if want a minumamum range of 30% or don't want 100%
+        as the first point.
+        """
 
-		pass
+        pass
 
-	def _adjustAxisTicks(self):
-		'''Override if you want to put slack at the ends of the axis
-		eg if you don't want the last tick to be at the bottom etc
-		'''
-		pass
+    def _adjustAxisTicks(self):
+        '''Override if you want to put slack at the ends of the axis
+        eg if you don't want the last tick to be at the bottom etc
+        '''
+        pass
 
-	def _calcScaleFactor(self):
-		"""Calculate the axis' scale factor.
+    def _calcScaleFactor(self):
+        """Calculate the axis' scale factor.
 
-		This should be called only *after* the axis' range is set.
+        This should be called only *after* the axis' range is set.
 
-		Returns a number.
-		"""
+        Returns a number.
+        """
 
-		self._scaleFactor = self._length / float(self._valueMax - self._valueMin)
-		return self._scaleFactor
+        self._scaleFactor = self._length / float(self._valueMax - self._valueMin)
+        return self._scaleFactor
 
-	def _calcTickPositions(self):
-		self._calcValueStep()
-		P = []
-		valueMin, valueMax, valueStep = self._valueMin, self._valueMax, self._valueStep
-		fuzz = 1e-8*valueStep
-		t = int((valueMin-fuzz)/valueStep) * valueStep
-		if t >= valueMin-fuzz: P.append(t)
-		t = t + valueStep
-		while t <= valueMax+fuzz:
-			P.append(t)
-			t = t + valueStep
-		return P
+    def _calcTickPositions(self):
+        self._calcValueStep()
+        P = []
+        valueMin, valueMax, valueStep = self._valueMin, self._valueMax, self._valueStep
+        fuzz = 1e-8*valueStep
+        t = int((valueMin-fuzz)/valueStep) * valueStep
+        if t >= valueMin-fuzz: P.append(t)
+        t = t + valueStep
+        while t <= valueMax+fuzz:
+            P.append(t)
+            t = t + valueStep
+        return P
 
-	def _calcTickmarkPositions(self):
-		"""Calculate a list of tick positions on the axis.
+    def _calcTickmarkPositions(self):
+        """Calculate a list of tick positions on the axis.
 
-		Returns a list of numbers.
-		"""
+        Returns a list of numbers.
+        """
 
-		self._tickValues = getattr(self,'valueSteps',None)
-		if self._tickValues: return self._tickValues
+        self._tickValues = getattr(self,'valueSteps',None)
+        if self._tickValues: return self._tickValues
 
-		self._tickValues = self._calcTickPositions()
-		self._adjustAxisTicks()
-		return self._tickValues
+        self._tickValues = self._calcTickPositions()
+        self._adjustAxisTicks()
+        return self._tickValues
 
-	def _calcValueStep(self):
-		'''Calculate _valueStep for the axis or get from valueStep.'''
+    def _calcValueStep(self):
+        '''Calculate _valueStep for the axis or get from valueStep.'''
 
-		if self.valueStep is None:
-			rawRange = self._valueMax - self._valueMin
-			rawInterval = rawRange / min(float(self.maximumTicks-1),(float(self._length)/self.minimumTickSpacing))
-			niceInterval = nextRoundNumber(rawInterval)
-			self._valueStep = niceInterval
-		else:
-			self._valueStep = self.valueStep
+        if self.valueStep is None:
+            rawRange = self._valueMax - self._valueMin
+            rawInterval = rawRange / min(float(self.maximumTicks-1),(float(self._length)/self.minimumTickSpacing))
+            niceInterval = nextRoundNumber(rawInterval)
+            self._valueStep = niceInterval
+        else:
+            self._valueStep = self.valueStep
 
 
-	def makeTickLabels(self):
-		g = Group()
+    def makeTickLabels(self):
+        g = Group()
 
-		f = self.labelTextFormat
-		pos = [self._x, self._y]
-		d = self._dataIndex
-		labels = self.labels
+        f = self.labelTextFormat
+        pos = [self._x, self._y]
+        d = self._dataIndex
+        labels = self.labels
 
-		i = 0
-		for tick in self._tickValues:
-			if f and labels[i].visible:
-				v = self.scale(tick)
-				if type(f) is StringType: txt = f % tick
-				elif type(f) in (TupleType,ListType):
-					#it's a list, use as many items as we get
-					if i < len(f):
-						txt = f[i]
-					else:
-						txt = ''
-				elif callable(f):
-					txt = f(tick)
-				else:
-					raise ValueError, 'Invalid labelTextFormat %s' % f
-				label = labels[i]
-				pos[d] = v
-				apply(label.setOrigin,pos)
-				label.setText(txt)
-				g.add(label)
-			i = i + 1
+        i = 0
+        for tick in self._tickValues:
+            if f and labels[i].visible:
+                v = self.scale(tick)
+                if type(f) is StringType: txt = f % tick
+                elif type(f) in (TupleType,ListType):
+                    #it's a list, use as many items as we get
+                    if i < len(f):
+                        txt = f[i]
+                    else:
+                        txt = ''
+                elif callable(f):
+                    txt = f(tick)
+                else:
+                    raise ValueError, 'Invalid labelTextFormat %s' % f
+                label = labels[i]
+                pos[d] = v
+                apply(label.setOrigin,pos)
+                label.setText(txt)
+                g.add(label)
+            i = i + 1
 
-		return g
+        return g
 
-	def _makeLines(self,g,start,end,strokeColor,strokeWidth,strokeDashArray):
-		i = 0
-		for tickValue in self._tickValues:
-				v = self.scale(tickValue)
-				if not self._dataIndex:
-					L = Line(v, self._y + start, v, self._y + end)
-				else:
-					L = Line(self._x + start, v, self._x + end, v)
-				L.strokeColor = strokeColor
-				L.strokeWidth = strokeWidth
-				L.strokeDashArray = strokeDashArray
-				g.add(L)
+    def _makeLines(self,g,start,end,strokeColor,strokeWidth,strokeDashArray):
+        i = 0
+        for tickValue in self._tickValues:
+                v = self.scale(tickValue)
+                if not self._dataIndex:
+                    L = Line(v, self._y + start, v, self._y + end)
+                else:
+                    L = Line(self._x + start, v, self._x + end, v)
+                L.strokeColor = strokeColor
+                L.strokeWidth = strokeWidth
+                L.strokeDashArray = strokeDashArray
+                g.add(L)
 
-	def makeGrid(self,g):
-		'''this is only called by a container object'''
-		if self.visibleGrid and (self.gridStart or self.gridEnd):
-			self._makeLines(g,self.gridStart,self.gridEnd,self.gridStrokeColor,self.gridStrokeWidth,self.gridStrokeDashArray)
+    def makeGrid(self,g):
+        '''this is only called by a container object'''
+        if self.visibleGrid and (self.gridStart or self.gridEnd):
+            self._makeLines(g,self.gridStart,self.gridEnd,self.gridStrokeColor,self.gridStrokeWidth,self.gridStrokeDashArray)
 
 
-	def draw(self):
-		g = Group()
+    def draw(self):
+        g = Group()
 
-		if not self.visible:
-			return g
+        if not self.visible:
+            return g
 
-		g.add(self.makeAxis())
-		g.add(self.makeTicks())
-		g.add(self.makeTickLabels())
+        g.add(self.makeAxis())
+        g.add(self.makeTicks())
+        g.add(self.makeTickLabels())
 
-		return g
+        return g
 
 
 class XValueAxis(ValueAxis):
-	"X/value axis"
+    "X/value axis"
 
-	_attrMap = AttrMap(BASE=ValueAxis,
-		tickUp = AttrMapValue(isNumber,
-			desc='Tick length up the axis.'),
-		tickDown = AttrMapValue(isNumber,
-			desc='Tick length down the axis.'),
-		joinAxis = AttrMapValue(None,
-			desc='Join both axes if true.'),
-		joinAxisMode = AttrMapValue(OneOf('bottom', 'top', 'value', 'points', None),
-			desc="Mode used for connecting axis ('bottom', 'top', 'value', 'points', None)."),
-		joinAxisPos = AttrMapValue(isNumberOrNone,
-			desc='Position at which to join with other axis.'),
-		)
+    _attrMap = AttrMap(BASE=ValueAxis,
+        tickUp = AttrMapValue(isNumber,
+            desc='Tick length up the axis.'),
+        tickDown = AttrMapValue(isNumber,
+            desc='Tick length down the axis.'),
+        joinAxis = AttrMapValue(None,
+            desc='Join both axes if true.'),
+        joinAxisMode = AttrMapValue(OneOf('bottom', 'top', 'value', 'points', None),
+            desc="Mode used for connecting axis ('bottom', 'top', 'value', 'points', None)."),
+        joinAxisPos = AttrMapValue(isNumberOrNone,
+            desc='Position at which to join with other axis.'),
+        )
 
-	# Indicate the dimension of the data we're interested in.
-	_dataIndex = 0
+    # Indicate the dimension of the data we're interested in.
+    _dataIndex = 0
 
-	def __init__(self):
-		ValueAxis.__init__(self)
+    def __init__(self):
+        ValueAxis.__init__(self)
 
-		self.labels.boxAnchor = 'n'
-		self.labels.dx = 0
-		self.labels.dy = -5
+        self.labels.boxAnchor = 'n'
+        self.labels.dx = 0
+        self.labels.dy = -5
 
-		self.tickUp = 0
-		self.tickDown = 5
+        self.tickUp = 0
+        self.tickDown = 5
 
-		self.joinAxis = None
-		self.joinAxisMode = None
-		self.joinAxisPos = None
+        self.joinAxis = None
+        self.joinAxisMode = None
+        self.joinAxisPos = None
 
 
-	def demo(self):
-		self.setPosition(20, 50, 150)
-		self.configure([(10,20,30,40,50)])
+    def demo(self):
+        self.setPosition(20, 50, 150)
+        self.configure([(10,20,30,40,50)])
 
-		d = Drawing(200, 100)
-		d.add(self)
-		return d
+        d = Drawing(200, 100)
+        d.add(self)
+        return d
 
 
-	def joinToAxis(self, yAxis, mode='bottom', pos=None):
-		"Join with y-axis using some mode."
+    def joinToAxis(self, yAxis, mode='bottom', pos=None):
+        "Join with y-axis using some mode."
 
-		# Make sure we connect only to a y-axis.
-		axisClassName = yAxis.__class__.__name__
-		msg = "Cannot connect to other axes (%s), but Y- ones." % axisClassName
-		assert axisClassName[0] == 'Y', msg
+        # Make sure we connect only to a y-axis.
+        axisClassName = yAxis.__class__.__name__
+        msg = "Cannot connect to other axes (%s), but Y- ones." % axisClassName
+        assert axisClassName[0] == 'Y', msg
 
-		if mode == 'bottom':
-			self._x = yAxis._x * 1.0
-			self._y = yAxis._y * 1.0
-		elif mode == 'top':
-			self._x = yAxis._x * 1.0
-			self._y = (yAxis._y + yAxis._length) * 1.0
-		elif mode == 'value':
-			self._x = yAxis._x * 1.0
-			self._y = yAxis.scale(pos) * 1.0
-		elif mode == 'points':
-			self._x = yAxis._x * 1.0
-			self._y = pos * 1.0
+        if mode == 'bottom':
+            self._x = yAxis._x * 1.0
+            self._y = yAxis._y * 1.0
+        elif mode == 'top':
+            self._x = yAxis._x * 1.0
+            self._y = (yAxis._y + yAxis._length) * 1.0
+        elif mode == 'value':
+            self._x = yAxis._x * 1.0
+            self._y = yAxis.scale(pos) * 1.0
+        elif mode == 'points':
+            self._x = yAxis._x * 1.0
+            self._y = pos * 1.0
 
 
-	def scale(self, value):
-		"""Converts a numeric value to a Y position.
+    def scale(self, value):
+        """Converts a numeric value to a Y position.
 
-		The chart first configures the axis, then asks it to
-		work out the x value for each point when plotting
-		lines or bars.	You could override this to do
-		logarithmic axes.
-		"""
+        The chart first configures the axis, then asks it to
+        work out the x value for each point when plotting
+        lines or bars.  You could override this to do
+        logarithmic axes.
+        """
 
-		msg = "Axis cannot scale numbers before it is configured"
-		assert self._configured, msg
-		if value is None:
-			value = 0
-		return self._x + self._scaleFactor * (value - self._valueMin)
+        msg = "Axis cannot scale numbers before it is configured"
+        assert self._configured, msg
+        if value is None:
+            value = 0
+        return self._x + self._scaleFactor * (value - self._valueMin)
 
 
-	def makeAxis(self):
-		g = Group()
+    def makeAxis(self):
+        g = Group()
 
-		if not self.visibleAxis:
-			return g
+        if not self.visibleAxis:
+            return g
 
-		ja = self.joinAxis
-		if ja:
-			jam = self.joinAxisMode
-			jap = self.joinAxisPos
-			jta = self.joinToAxis
-			if jam in ('bottom', 'top'):
-				jta(ja, mode=jam)
-			elif jam in ('value', 'points'):
-				jta(ja, mode=jam, pos=jap)
+        ja = self.joinAxis
+        if ja:
+            jam = self.joinAxisMode
+            jap = self.joinAxisPos
+            jta = self.joinToAxis
+            if jam in ('bottom', 'top'):
+                jta(ja, mode=jam)
+            elif jam in ('value', 'points'):
+                jta(ja, mode=jam, pos=jap)
 
-		axis = Line(self._x, self._y, self._x + self._length, self._y)
-		axis.strokeColor = self.strokeColor
-		axis.strokeWidth = self.strokeWidth
-		axis.strokeDashArray = self.strokeDashArray
-		g.add(axis)
+        axis = Line(self._x, self._y, self._x + self._length, self._y)
+        axis.strokeColor = self.strokeColor
+        axis.strokeWidth = self.strokeWidth
+        axis.strokeDashArray = self.strokeDashArray
+        g.add(axis)
 
-		return g
+        return g
 
-	def makeTicks(self):
-		g = Group()
-		if self.visibleTicks and (self.tickUp or self.tickDown):
-			self._makeLines(g,-self.tickDown,self.tickUp,self.strokeColor,self.strokeWidth,self.strokeDashArray)
-		return g
+    def makeTicks(self):
+        g = Group()
+        if self.visibleTicks and (self.tickUp or self.tickDown):
+            self._makeLines(g,-self.tickDown,self.tickUp,self.strokeColor,self.strokeWidth,self.strokeDashArray)
+        return g
 
 class NormalDateXValueAxis(XValueAxis):
-	"""An X axis applying additional rules.
+    """An X axis applying additional rules.
 
-	Depending on the data and some built-in rules, the axis
-	displays normalDate values as nicely formatted dates.
+    Depending on the data and some built-in rules, the axis
+    displays normalDate values as nicely formatted dates.
 
-	The client chart should have NormalDate X values.
-	"""
+    The client chart should have NormalDate X values.
+    """
 
-	_attrMap = AttrMap(BASE = XValueAxis,
-		bottomAxisLabelSlack = AttrMapValue(isNumber, desc="Fractional amount used to adjust label spacing"),
-		niceMonth = AttrMapValue(isBoolean, desc="Flag for displaying months 'nicely'."),
-		forceEndDate = AttrMapValue(isBoolean, desc='Flag for enforced displaying of last date value.'),
-		forceFirstDate = AttrMapValue(isBoolean, desc='Flag for enforced displaying of first date value.'),
-		xLabelFormat = AttrMapValue(None, desc="Label format string (e.g. '{mm}/{yy}') or function."),
-		dayOfWeekName = AttrMapValue(SequenceOf(isString,emptyOK=0,lo=7,hi=7), desc='Weekday names.'),
-		monthName = AttrMapValue(SequenceOf(isString,emptyOK=0,lo=12,hi=12), desc='Month names.'),
-		dailyFreq = AttrMapValue(isBoolean, desc='True if we are to assume daily data to be ticked at end of month.'),
-		)
+    _attrMap = AttrMap(BASE = XValueAxis,
+        bottomAxisLabelSlack = AttrMapValue(isNumber, desc="Fractional amount used to adjust label spacing"),
+        niceMonth = AttrMapValue(isBoolean, desc="Flag for displaying months 'nicely'."),
+        forceEndDate = AttrMapValue(isBoolean, desc='Flag for enforced displaying of last date value.'),
+        forceFirstDate = AttrMapValue(isBoolean, desc='Flag for enforced displaying of first date value.'),
+        xLabelFormat = AttrMapValue(None, desc="Label format string (e.g. '{mm}/{yy}') or function."),
+        dayOfWeekName = AttrMapValue(SequenceOf(isString,emptyOK=0,lo=7,hi=7), desc='Weekday names.'),
+        monthName = AttrMapValue(SequenceOf(isString,emptyOK=0,lo=12,hi=12), desc='Month names.'),
+        dailyFreq = AttrMapValue(isBoolean, desc='True if we are to assume daily data to be ticked at end of month.'),
+        )
 
-	_valueClass = normalDate.ND
+    _valueClass = normalDate.ND
 
-	def __init__(self, **kw):
-		apply(XValueAxis.__init__, (self,))
+    def __init__(self, **kw):
+        apply(XValueAxis.__init__, (self,))
 
-		# some global variables still used...
-		self.bottomAxisLabelSlack = 0.1
-		self.niceMonth = 1
-		self.forceEndDate = 0
-		self.forceFirstDate = 0
-		self.dailyFreq = 0
-		self.xLabelFormat = "{mm}/{yy}"
-		self.dayOfWeekName = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
-		self.monthName = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
-							'August', 'September', 'October', 'November', 'December']
-		self.valueSteps = None
+        # some global variables still used...
+        self.bottomAxisLabelSlack = 0.1
+        self.niceMonth = 1
+        self.forceEndDate = 0
+        self.forceFirstDate = 0
+        self.dailyFreq = 0
+        self.xLabelFormat = "{mm}/{yy}"
+        self.dayOfWeekName = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
+        self.monthName = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
+                            'August', 'September', 'October', 'November', 'December']
+        self.valueSteps = None
 
-	def _scalar2ND(self, x):
-		"Convert a scalar to a NormalDate value."
-		d = self._valueClass()
-		d.normalize(x)
-		return d
+    def _scalar2ND(self, x):
+        "Convert a scalar to a NormalDate value."
+        d = self._valueClass()
+        d.normalize(x)
+        return d
 
-	def _dateFormatter(self, v):
-		"Create a formatted label for some value."
-		if not isinstance(v,normalDate.NormalDate):
-			v = self._scalar2ND(v)
-		d, m = normalDate._dayOfWeekName, normalDate._monthName
-		try:
-			normalDate._dayOfWeekName, normalDate._monthName = self.dayOfWeekName, self.monthName
-			return v.formatMS(self.xLabelFormat)
-		finally:
-			normalDate._dayOfWeekName, normalDate._monthName = d, m
+    def _dateFormatter(self, v):
+        "Create a formatted label for some value."
+        if not isinstance(v,normalDate.NormalDate):
+            v = self._scalar2ND(v)
+        d, m = normalDate._dayOfWeekName, normalDate._monthName
+        try:
+            normalDate._dayOfWeekName, normalDate._monthName = self.dayOfWeekName, self.monthName
+            return v.formatMS(self.xLabelFormat)
+        finally:
+            normalDate._dayOfWeekName, normalDate._monthName = d, m
 
-	def _xAxisTicker(self, xVals):
-		"""Complex stuff...
+    def _xAxisTicker(self, xVals):
+        """Complex stuff...
 
-		Needs explanation...
-		"""
-		axisLength = self._length
-		formatter = self._dateFormatter
-		labels = self.labels
-		fontName, fontSize, leading = labels.fontName, labels.fontSize, labels.leading
-		textAnchor, boxAnchor, angle = labels.textAnchor, labels.boxAnchor, labels.angle
-		RBL = _textBoxLimits(string.split(formatter(xVals[0]),'\n'),fontName,
-					fontSize,leading or 1.2*fontSize,textAnchor,boxAnchor)
-		RBL = _rotatedBoxLimits(RBL[0],RBL[1],RBL[2],RBL[3], angle)
-		xLabelW = RBL[1]-RBL[0]
-		xLabelH = RBL[3]-RBL[2]
-		w = max(xLabelW,labels.width,self.minimumTickSpacing)
+        Needs explanation...
+        """
+        axisLength = self._length
+        formatter = self._dateFormatter
+        labels = self.labels
+        fontName, fontSize, leading = labels.fontName, labels.fontSize, labels.leading
+        textAnchor, boxAnchor, angle = labels.textAnchor, labels.boxAnchor, labels.angle
+        RBL = _textBoxLimits(string.split(formatter(xVals[0]),'\n'),fontName,
+                    fontSize,leading or 1.2*fontSize,textAnchor,boxAnchor)
+        RBL = _rotatedBoxLimits(RBL[0],RBL[1],RBL[2],RBL[3], angle)
+        xLabelW = RBL[1]-RBL[0]
+        xLabelH = RBL[3]-RBL[2]
+        w = max(xLabelW,labels.width,self.minimumTickSpacing)
 
-		W = w+w*self.bottomAxisLabelSlack
-		n = len(xVals)
-		ticks = []
-		labels = []
-		maximumTicks = self.maximumTicks
+        W = w+w*self.bottomAxisLabelSlack
+        n = len(xVals)
+        ticks = []
+        labels = []
+        maximumTicks = self.maximumTicks
 
-		def addTick(i, xVals=xVals, formatter=formatter, ticks=ticks, labels=labels):
-			ticks.insert(0,xVals[i])
-			labels.insert(0,formatter(xVals[i]))
+        def addTick(i, xVals=xVals, formatter=formatter, ticks=ticks, labels=labels):
+            ticks.insert(0,xVals[i])
+            labels.insert(0,formatter(xVals[i]))
 
-		for d in (1,2,3,6,12,24,60,120):
-			k = n/d
-			if k<=maximumTicks and k*W <= axisLength:
-				i = n-1
-				if self.niceMonth:
-					j = xVals[-1].month() % (d<=12 and d or 12)
-					if j:
-						if self.forceEndDate: addTick(i)
-						i = i - j
+        for d in (1,2,3,6,12,24,60,120):
+            k = n/d
+            if k<=maximumTicks and k*W <= axisLength:
+                i = n-1
+                if self.niceMonth:
+                    j = xVals[-1].month() % (d<=12 and d or 12)
+                    if j:
+                        if self.forceEndDate: addTick(i)
+                        i = i - j
 
-				#weird first date ie not at end of month
-				try:
-					wfd = xVals[0].month() == xVals[1].month()
-				except:
-					wfd = 0
+                #weird first date ie not at end of month
+                try:
+                    wfd = xVals[0].month() == xVals[1].month()
+                except:
+                    wfd = 0
 
-				while i>=wfd:
-					addTick(i)
-					i = i - d
+                while i>=wfd:
+                    addTick(i)
+                    i = i - d
 
-				if self.forceFirstDate and ticks[0] != xVals[0]:
-					addTick(0)
-					if (axisLength/(ticks[-1]-ticks[0]))*(ticks[1]-ticks[0])<=w:
-						del ticks[1], labels[1]
-				if self.forceEndDate and self.niceMonth and j:
-					if (axisLength/(ticks[-1]-ticks[0]))*(ticks[-1]-ticks[-2])<=w:
-						del ticks[-2], labels[-2]
-				try:
-					if labels[0]==labels[1]:
-						del ticks[1], labels[1]
-				except IndexError:
-					pass
+                if self.forceFirstDate and ticks[0] != xVals[0]:
+                    addTick(0)
+                    if (axisLength/(ticks[-1]-ticks[0]))*(ticks[1]-ticks[0])<=w:
+                        del ticks[1], labels[1]
+                if self.forceEndDate and self.niceMonth and j:
+                    if (axisLength/(ticks[-1]-ticks[0]))*(ticks[-1]-ticks[-2])<=w:
+                        del ticks[-2], labels[-2]
+                try:
+                    if labels[0]==labels[1]:
+                        del ticks[1], labels[1]
+                except IndexError:
+                    pass
 
-				return ticks, labels
+                return ticks, labels
 
-	def _convertXV(self,data):
-		'''Convert all XValues to a standard normalDate type'''
+    def _convertXV(self,data):
+        '''Convert all XValues to a standard normalDate type'''
 
-		VC = self._valueClass
-		for D in data:
-			for i in xrange(len(D)):
-				x, y = D[i]
-				if not isinstance(x,VC):
-					D[i] = (VC(x),y)
+        VC = self._valueClass
+        for D in data:
+            for i in xrange(len(D)):
+                x, y = D[i]
+                if not isinstance(x,VC):
+                    D[i] = (VC(x),y)
 
-	def configure(self, data):
-		self._convertXV(data)
-		xVals = map(lambda dv: dv[0], data[0])
-		if self.dailyFreq:
-			xEOM = []
-			pm = 0
-			px = xVals[0]
-			for x in xVals:
-				m = x.month()
-				if pm!=m:
-					if pm: xEOM.append(px)
-					pm = m
-				px = x
-			px = xVals[-1]
-			if xEOM[-1]!=x: xEOM.append(px)
-			steps, labels = self._xAxisTicker(xEOM)
-		else:
-			steps, labels = self._xAxisTicker(xVals)
-		valueMin, valueMax = self.valueMin, self.valueMax
-		if valueMin is None: valueMin = xVals[0]
-		if valueMax is None: valueMax = xVals[-1]
-		self._valueMin, self._valueMax = valueMin, valueMax
-		self.valueSteps = steps
-		self.labelTextFormat = labels
+    def configure(self, data):
+        self._convertXV(data)
+        xVals = map(lambda dv: dv[0], data[0])
+        if self.dailyFreq:
+            xEOM = []
+            pm = 0
+            px = xVals[0]
+            for x in xVals:
+                m = x.month()
+                if pm!=m:
+                    if pm: xEOM.append(px)
+                    pm = m
+                px = x
+            px = xVals[-1]
+            if xEOM[-1]!=x: xEOM.append(px)
+            steps, labels = self._xAxisTicker(xEOM)
+        else:
+            steps, labels = self._xAxisTicker(xVals)
+        valueMin, valueMax = self.valueMin, self.valueMax
+        if valueMin is None: valueMin = xVals[0]
+        if valueMax is None: valueMax = xVals[-1]
+        self._valueMin, self._valueMax = valueMin, valueMax
+        self.valueSteps = steps
+        self.labelTextFormat = labels
 
-		self._scaleFactor = self._length / float(valueMax - valueMin)
-		self._tickValues = steps
-		self._configured = 1
+        self._scaleFactor = self._length / float(valueMax - valueMin)
+        self._tickValues = steps
+        self._configured = 1
 
 
 class YValueAxis(ValueAxis):
-	"Y/value axis"
+    "Y/value axis"
 
-	_attrMap = AttrMap(BASE=ValueAxis,
-		tickLeft = AttrMapValue(isNumber,
-			desc='Tick length left of the axis.'),
-		tickRight = AttrMapValue(isNumber,
-			desc='Tick length right of the axis.'),
-		joinAxis = AttrMapValue(None,
-			desc='Join both axes if true.'),
-		joinAxisMode = AttrMapValue(OneOf(('left', 'right', 'value', 'points', None)),
-			desc="Mode used for connecting axis ('left', 'right', 'value', 'points', None)."),
-		joinAxisPos = AttrMapValue(isNumberOrNone,
-			desc='Position at which to join with other axis.'),
-		)
+    _attrMap = AttrMap(BASE=ValueAxis,
+        tickLeft = AttrMapValue(isNumber,
+            desc='Tick length left of the axis.'),
+        tickRight = AttrMapValue(isNumber,
+            desc='Tick length right of the axis.'),
+        joinAxis = AttrMapValue(None,
+            desc='Join both axes if true.'),
+        joinAxisMode = AttrMapValue(OneOf(('left', 'right', 'value', 'points', None)),
+            desc="Mode used for connecting axis ('left', 'right', 'value', 'points', None)."),
+        joinAxisPos = AttrMapValue(isNumberOrNone,
+            desc='Position at which to join with other axis.'),
+        )
 
-	# Indicate the dimension of the data we're interested in.
-	_dataIndex = 1
+    # Indicate the dimension of the data we're interested in.
+    _dataIndex = 1
 
-	def __init__(self):
-		ValueAxis.__init__(self)
+    def __init__(self):
+        ValueAxis.__init__(self)
 
-		self.labels.boxAnchor = 'e'
-		self.labels.dx = -5
-		self.labels.dy = 0
+        self.labels.boxAnchor = 'e'
+        self.labels.dx = -5
+        self.labels.dy = 0
 
-		self.tickRight = 0
-		self.tickLeft = 5
+        self.tickRight = 0
+        self.tickLeft = 5
 
-		self.joinAxis = None
-		self.joinAxisMode = None
-		self.joinAxisPos = None
+        self.joinAxis = None
+        self.joinAxisMode = None
+        self.joinAxisPos = None
 
 
-	def demo(self):
-		data = [(10, 20, 30, 42)]
-		self.setPosition(100, 10, 80)
-		self.configure(data)
+    def demo(self):
+        data = [(10, 20, 30, 42)]
+        self.setPosition(100, 10, 80)
+        self.configure(data)
 
-		drawing = Drawing(200, 100)
-		drawing.add(self)
-		return drawing
+        drawing = Drawing(200, 100)
+        drawing.add(self)
+        return drawing
 
 
 
-	def joinToAxis(self, xAxis, mode='left', pos=None):
-		"Join with x-axis using some mode."
+    def joinToAxis(self, xAxis, mode='left', pos=None):
+        "Join with x-axis using some mode."
 
-		# Make sure we connect only to a y-axis.
-		axisClassName = xAxis.__class__.__name__
-		msg = "Cannot connect to other axes (%s), but X- ones." % axisClassName
-		assert axisClassName[0] == 'X', msg
+        # Make sure we connect only to a y-axis.
+        axisClassName = xAxis.__class__.__name__
+        msg = "Cannot connect to other axes (%s), but X- ones." % axisClassName
+        assert axisClassName[0] == 'X', msg
 
-		if mode == 'left':
-			self._x = xAxis._x * 1.0
-			self._y = xAxis._y * 1.0
-		elif mode == 'right':
-			self._x = (xAxis._x + xAxis._length) * 1.0
-			self._y = xAxis._y * 1.0
-		elif mode == 'value':
-			self._x = xAxis.scale(pos) * 1.0
-			self._y = xAxis._y * 1.0
-		elif mode == 'points':
-			self._x = pos * 1.0
-			self._y = xAxis._y * 1.0
+        if mode == 'left':
+            self._x = xAxis._x * 1.0
+            self._y = xAxis._y * 1.0
+        elif mode == 'right':
+            self._x = (xAxis._x + xAxis._length) * 1.0
+            self._y = xAxis._y * 1.0
+        elif mode == 'value':
+            self._x = xAxis.scale(pos) * 1.0
+            self._y = xAxis._y * 1.0
+        elif mode == 'points':
+            self._x = pos * 1.0
+            self._y = xAxis._y * 1.0
 
 
-	def scale(self, value):
-		"""Converts a numeric value to a Y position.
+    def scale(self, value):
+        """Converts a numeric value to a Y position.
 
-		The chart first configures the axis, then asks it to
-		work out the x value for each point when plotting
-		lines or bars.	You could override this to do
-		logarithmic axes.
-		"""
+        The chart first configures the axis, then asks it to
+        work out the x value for each point when plotting
+        lines or bars.  You could override this to do
+        logarithmic axes.
+        """
 
-		msg = "Axis cannot scale numbers before it is configured"
-		assert self._configured, msg
+        msg = "Axis cannot scale numbers before it is configured"
+        assert self._configured, msg
 
-		if value is None:
-			value = 0
-		return self._y + self._scaleFactor * (value - self._valueMin)
+        if value is None:
+            value = 0
+        return self._y + self._scaleFactor * (value - self._valueMin)
 
 
-	def makeAxis(self):
-		g = Group()
+    def makeAxis(self):
+        g = Group()
 
-		if not self.visibleAxis:
-			return g
+        if not self.visibleAxis:
+            return g
 
-		ja = self.joinAxis
-		if ja:
-			jam = self.joinAxisMode
-			jap = self.joinAxisPos
-			jta = self.joinToAxis
-			if jam in ('left', 'right'):
-				jta(ja, mode=jam)
-			elif jam in ('value', 'points'):
-				jta(ja, mode=jam, pos=jap)
+        ja = self.joinAxis
+        if ja:
+            jam = self.joinAxisMode
+            jap = self.joinAxisPos
+            jta = self.joinToAxis
+            if jam in ('left', 'right'):
+                jta(ja, mode=jam)
+            elif jam in ('value', 'points'):
+                jta(ja, mode=jam, pos=jap)
 
-		axis = Line(self._x, self._y, self._x, self._y + self._length)
-		axis.strokeColor = self.strokeColor
-		axis.strokeWidth = self.strokeWidth
-		axis.strokeDashArray = self.strokeDashArray
-		g.add(axis)
+        axis = Line(self._x, self._y, self._x, self._y + self._length)
+        axis.strokeColor = self.strokeColor
+        axis.strokeWidth = self.strokeWidth
+        axis.strokeDashArray = self.strokeDashArray
+        g.add(axis)
 
-		return g
+        return g
 
-	def makeTicks(self):
-		g = Group()
-		if self.visibleTicks and (self.tickLeft or self.tickRight):
-			self._makeLines(g,-self.tickLeft,self.tickRight,self.strokeColor,self.strokeWidth,self.strokeDashArray)
-		return g
+    def makeTicks(self):
+        g = Group()
+        if self.visibleTicks and (self.tickLeft or self.tickRight):
+            self._makeLines(g,-self.tickLeft,self.tickRight,self.strokeColor,self.strokeWidth,self.strokeDashArray)
+        return g
 
 class AdjYValueAxis(YValueAxis):
-	"""A Y-axis applying additional rules.
+    """A Y-axis applying additional rules.
 
-	Depending on the data and some built-in rules, the axis
-	may choose to adjust its range and origin.
-	"""
-	_attrMap = AttrMap(BASE = YValueAxis,
-		requiredRange = AttrMapValue(isNumberOrNone, desc='Minimum required value range.'),
-		leftAxisPercent = AttrMapValue(isBoolean, desc='When true add percent sign to label values.'),
-		leftAxisOrigShiftIPC = AttrMapValue(isNumber, desc='Lowest label shift interval ratio.'),
-		leftAxisOrigShiftMin = AttrMapValue(isNumber, desc='Minimum amount to shift.'),
-		leftAxisSkipLL0 = AttrMapValue(isBoolean, desc='Skip lowest tick label when true.')
-		)
+    Depending on the data and some built-in rules, the axis
+    may choose to adjust its range and origin.
+    """
+    _attrMap = AttrMap(BASE = YValueAxis,
+        requiredRange = AttrMapValue(isNumberOrNone, desc='Minimum required value range.'),
+        leftAxisPercent = AttrMapValue(isBoolean, desc='When true add percent sign to label values.'),
+        leftAxisOrigShiftIPC = AttrMapValue(isNumber, desc='Lowest label shift interval ratio.'),
+        leftAxisOrigShiftMin = AttrMapValue(isNumber, desc='Minimum amount to shift.'),
+        leftAxisSkipLL0 = AttrMapValue(isBoolean, desc='Skip lowest tick label when true.')
+        )
 
-	def __init__(self):
-		apply(YValueAxis.__init__, (self,))
-		self.requiredRange = 30
-		self.leftAxisPercent = 1
-		self.leftAxisOrigShiftIPC = 0.15
-		self.leftAxisOrigShiftMin = 12
-		self.leftAxisSkipLL0 = 0
-		self.valueSteps = None
+    def __init__(self):
+        apply(YValueAxis.__init__, (self,))
+        self.requiredRange = 30
+        self.leftAxisPercent = 1
+        self.leftAxisOrigShiftIPC = 0.15
+        self.leftAxisOrigShiftMin = 12
+        self.leftAxisSkipLL0 = 0
+        self.valueSteps = None
 
-	def _rangeAdjust(self):
-		"Adjusts the value range of the axis."
+    def _rangeAdjust(self):
+        "Adjusts the value range of the axis."
 
-		from reportlab.graphics.charts.utils import find_good_grid, ticks
-		y_min, y_max = self._valueMin, self._valueMax
+        from reportlab.graphics.charts.utils import find_good_grid, ticks
+        y_min, y_max = self._valueMin, self._valueMax
 
-		valueStep, requiredRange = self.valueStep, self.requiredRange
-		if requiredRange and y_max - y_min < requiredRange:
-			y1, y2, None = find_good_grid(y_min, y_max,grid=valueStep)
-			if y2 - y1 < requiredRange:
-				ym = (y1+y2)*0.5
-				y1 = min(ym-requiredRange*0.5,y_min)
-				y2 = max(ym+requiredRange*0.5,y_max)
-				if y_min>=100 and y1<100:
-					y2 = y2 + 100 - y1
-					y1 = 100
-				elif y_min>=0 and y1<0:
-					y2 = y2 - y1
-					y1 = 0
-			self._valueMin, self._valueMax = y1, y2
+        valueStep, requiredRange = self.valueStep, self.requiredRange
+        if requiredRange and y_max - y_min < requiredRange:
+            y1, y2, None = find_good_grid(y_min, y_max,grid=valueStep)
+            if y2 - y1 < requiredRange:
+                ym = (y1+y2)*0.5
+                y1 = min(ym-requiredRange*0.5,y_min)
+                y2 = max(ym+requiredRange*0.5,y_max)
+                if y_min>=100 and y1<100:
+                    y2 = y2 + 100 - y1
+                    y1 = 100
+                elif y_min>=0 and y1<0:
+                    y2 = y2 - y1
+                    y1 = 0
+            self._valueMin, self._valueMax = y1, y2
 
-		T, L = ticks(self._valueMin, self._valueMax, split=1, percent=self.leftAxisPercent,grid=valueStep)
-		abf = self.avoidBoundFrac
-		if abf:
-			_n = getattr(self,'_cValueMin',T[0])
-			_x = getattr(self,'_cValueMax',T[-1])
-			i = (T[1]-T[0])*abf
-			if _n - T[0] < i: self._valueMin = self._valueMin - i
-			if T[-1]-_x < i: self._valueMax = self._valueMax + i
-			T, L = ticks(self._valueMin, self._valueMax, split=1, percent=self.leftAxisPercent,grid=valueStep)
+        T, L = ticks(self._valueMin, self._valueMax, split=1, percent=self.leftAxisPercent,grid=valueStep)
+        abf = self.avoidBoundFrac
+        if abf:
+            _n = getattr(self,'_cValueMin',T[0])
+            _x = getattr(self,'_cValueMax',T[-1])
+            i = (T[1]-T[0])*abf
+            if _n - T[0] < i: self._valueMin = self._valueMin - i
+            if T[-1]-_x < i: self._valueMax = self._valueMax + i
+            T, L = ticks(self._valueMin, self._valueMax, split=1, percent=self.leftAxisPercent,grid=valueStep)
 
-		self._valueMin = T[0]
-		self._valueMax = T[-1]
-		self.valueSteps = T
-		from reportlab.lib.formatters import DecimalFormatter
-		if not isinstance(self.labelTextFormat,DecimalFormatter): self.labelTextFormat = L
+        self._valueMin = T[0]
+        self._valueMax = T[-1]
+        self.valueSteps = T
+        from reportlab.lib.formatters import DecimalFormatter
+        if not isinstance(self.labelTextFormat,DecimalFormatter): self.labelTextFormat = L
 
-		if abs(self._valueMin-100)<1e-6:
-			self._calcValueStep()
-			vMax, vMin = self._valueMax, self._valueMin
-			m = max(self.leftAxisOrigShiftIPC*self._valueStep,
-					(vMax-vMin)*self.leftAxisOrigShiftMin/self._length)
-			self._valueMin = self._valueMin - m
+        if abs(self._valueMin-100)<1e-6:
+            self._calcValueStep()
+            vMax, vMin = self._valueMax, self._valueMin
+            m = max(self.leftAxisOrigShiftIPC*self._valueStep,
+                    (vMax-vMin)*self.leftAxisOrigShiftMin/self._length)
+            self._valueMin = self._valueMin - m
 
-		if self.leftAxisSkipLL0:
-			L[0] = ''
+        if self.leftAxisSkipLL0:
+            L[0] = ''
 
 # Sample functions.
 def sample0a():
-	"Sample drawing with one xcat axis and two buckets."
+    "Sample drawing with one xcat axis and two buckets."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20)]
+    data = [(10, 20)]
 
-	xAxis = XCategoryAxis()
-	xAxis.setPosition(75, 75, 300)
-	xAxis.configure(data)
-	xAxis.categoryNames = ['Ying', 'Yang']
-	xAxis.labels.boxAnchor = 'n'
+    xAxis = XCategoryAxis()
+    xAxis.setPosition(75, 75, 300)
+    xAxis.configure(data)
+    xAxis.categoryNames = ['Ying', 'Yang']
+    xAxis.labels.boxAnchor = 'n'
 
-	drawing.add(xAxis)
+    drawing.add(xAxis)
 
-	return drawing
+    return drawing
 
 
 def sample0b():
-	"Sample drawing with one xcat axis and one bucket only."
+    "Sample drawing with one xcat axis and one bucket only."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10,)]
+    data = [(10,)]
 
-	xAxis = XCategoryAxis()
-	xAxis.setPosition(75, 75, 300)
-	xAxis.configure(data)
-	xAxis.categoryNames = ['Ying']
-	xAxis.labels.boxAnchor = 'n'
+    xAxis = XCategoryAxis()
+    xAxis.setPosition(75, 75, 300)
+    xAxis.configure(data)
+    xAxis.categoryNames = ['Ying']
+    xAxis.labels.boxAnchor = 'n'
 
-	drawing.add(xAxis)
+    drawing.add(xAxis)
 
-	return drawing
+    return drawing
 
 
 def sample1():
-	"Sample drawing containing two unconnected axes."
+    "Sample drawing containing two unconnected axes."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XCategoryAxis()
-	xAxis.setPosition(75, 75, 300)
-	xAxis.configure(data)
-	xAxis.categoryNames = ['Beer','Wine','Meat','Cannelloni']
-	xAxis.labels.boxAnchor = 'n'
-	xAxis.labels[3].dy = -15
-	xAxis.labels[3].angle = 30
-	xAxis.labels[3].fontName = 'Times-Bold'
+    xAxis = XCategoryAxis()
+    xAxis.setPosition(75, 75, 300)
+    xAxis.configure(data)
+    xAxis.categoryNames = ['Beer','Wine','Meat','Cannelloni']
+    xAxis.labels.boxAnchor = 'n'
+    xAxis.labels[3].dy = -15
+    xAxis.labels[3].angle = 30
+    xAxis.labels[3].fontName = 'Times-Bold'
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 ##def sample2a():
-##	"Make sample drawing with two axes, x connected at top of y."
+##  "Make sample drawing with two axes, x connected at top of y."
 ##
-##	  drawing = Drawing(400, 200)
+##    drawing = Drawing(400, 200)
 ##
-##	  data = [(10, 20, 30, 42)]
+##    data = [(10, 20, 30, 42)]
 ##
-##	  yAxis = YValueAxis()
-##	  yAxis.setPosition(50, 50, 125)
-##	  yAxis.configure(data)
+##    yAxis = YValueAxis()
+##    yAxis.setPosition(50, 50, 125)
+##    yAxis.configure(data)
 ##
-##	  xAxis = XCategoryAxis()
-##	  xAxis._length = 300
-##	  xAxis.configure(data)
-##	  xAxis.joinToAxis(yAxis, mode='top')
-##	  xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-##	  xAxis.labels.boxAnchor = 'n'
+##    xAxis = XCategoryAxis()
+##    xAxis._length = 300
+##    xAxis.configure(data)
+##    xAxis.joinToAxis(yAxis, mode='top')
+##    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+##    xAxis.labels.boxAnchor = 'n'
 ##
-##	  drawing.add(xAxis)
-##	  drawing.add(yAxis)
+##    drawing.add(xAxis)
+##    drawing.add(yAxis)
 ##
-##	  return drawing
+##    return drawing
 ##
 ##
 ##def sample2b():
-##	  "Make two axes, x connected at bottom of y."
+##    "Make two axes, x connected at bottom of y."
 ##
-##	  drawing = Drawing(400, 200)
+##    drawing = Drawing(400, 200)
 ##
-##	  data = [(10, 20, 30, 42)]
+##    data = [(10, 20, 30, 42)]
 ##
-##	  yAxis = YValueAxis()
-##	  yAxis.setPosition(50, 50, 125)
-##	  yAxis.configure(data)
+##    yAxis = YValueAxis()
+##    yAxis.setPosition(50, 50, 125)
+##    yAxis.configure(data)
 ##
-##	  xAxis = XCategoryAxis()
-##	  xAxis._length = 300
-##	  xAxis.configure(data)
-##	  xAxis.joinToAxis(yAxis, mode='bottom')
-##	  xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-##	  xAxis.labels.boxAnchor = 'n'
+##    xAxis = XCategoryAxis()
+##    xAxis._length = 300
+##    xAxis.configure(data)
+##    xAxis.joinToAxis(yAxis, mode='bottom')
+##    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+##    xAxis.labels.boxAnchor = 'n'
 ##
-##	  drawing.add(xAxis)
-##	  drawing.add(yAxis)
+##    drawing.add(xAxis)
+##    drawing.add(yAxis)
 ##
-##	  return drawing
+##    return drawing
 ##
 ##
 ##def sample2c():
-##	  "Make two axes, x connected at fixed value (in points) of y."
+##    "Make two axes, x connected at fixed value (in points) of y."
 ##
-##	  drawing = Drawing(400, 200)
+##    drawing = Drawing(400, 200)
 ##
-##	  data = [(10, 20, 30, 42)]
+##    data = [(10, 20, 30, 42)]
 ##
-##	  yAxis = YValueAxis()
-##	  yAxis.setPosition(50, 50, 125)
-##	  yAxis.configure(data)
+##    yAxis = YValueAxis()
+##    yAxis.setPosition(50, 50, 125)
+##    yAxis.configure(data)
 ##
-##	  xAxis = XCategoryAxis()
-##	  xAxis._length = 300
-##	  xAxis.configure(data)
-##	  xAxis.joinToAxis(yAxis, mode='points', pos=100)
-##	  xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-##	  xAxis.labels.boxAnchor = 'n'
+##    xAxis = XCategoryAxis()
+##    xAxis._length = 300
+##    xAxis.configure(data)
+##    xAxis.joinToAxis(yAxis, mode='points', pos=100)
+##    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+##    xAxis.labels.boxAnchor = 'n'
 ##
-##	  drawing.add(xAxis)
-##	  drawing.add(yAxis)
+##    drawing.add(xAxis)
+##    drawing.add(yAxis)
 ##
-##	  return drawing
+##    return drawing
 ##
 ##
 ##def sample2d():
-##	  "Make two axes, x connected at fixed value (of y-axes) of y."
+##    "Make two axes, x connected at fixed value (of y-axes) of y."
 ##
-##	  drawing = Drawing(400, 200)
+##    drawing = Drawing(400, 200)
 ##
-##	  data = [(10, 20, 30, 42)]
+##    data = [(10, 20, 30, 42)]
 ##
-##	  yAxis = YValueAxis()
-##	  yAxis.setPosition(50, 50, 125)
-##	  yAxis.configure(data)
+##    yAxis = YValueAxis()
+##    yAxis.setPosition(50, 50, 125)
+##    yAxis.configure(data)
 ##
-##	  xAxis = XCategoryAxis()
-##	  xAxis._length = 300
-##	  xAxis.configure(data)
-##	  xAxis.joinToAxis(yAxis, mode='value', pos=20)
-##	  xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-##	  xAxis.labels.boxAnchor = 'n'
+##    xAxis = XCategoryAxis()
+##    xAxis._length = 300
+##    xAxis.configure(data)
+##    xAxis.joinToAxis(yAxis, mode='value', pos=20)
+##    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+##    xAxis.labels.boxAnchor = 'n'
 ##
-##	  drawing.add(xAxis)
-##	  drawing.add(yAxis)
+##    drawing.add(xAxis)
+##    drawing.add(yAxis)
 ##
-##	  return drawing
+##    return drawing
 ##
 ##
 ##def sample3a():
-##	  "Make sample drawing with two axes, y connected at left of x."
+##    "Make sample drawing with two axes, y connected at left of x."
 ##
-##	  drawing = Drawing(400, 200)
+##    drawing = Drawing(400, 200)
 ##
-##	  data = [(10, 20, 30, 42)]
+##    data = [(10, 20, 30, 42)]
 ##
-##	  xAxis = XCategoryAxis()
-##	  xAxis._length = 300
-##	  xAxis.configure(data)
-##	  xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-##	  xAxis.labels.boxAnchor = 'n'
+##    xAxis = XCategoryAxis()
+##    xAxis._length = 300
+##    xAxis.configure(data)
+##    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+##    xAxis.labels.boxAnchor = 'n'
 ##
-##	  yAxis = YValueAxis()
-##	  yAxis.setPosition(50, 50, 125)
-##	  yAxis.configure(data)
-##	  yAxis.joinToAxis(xAxis, mode='left')
+##    yAxis = YValueAxis()
+##    yAxis.setPosition(50, 50, 125)
+##    yAxis.configure(data)
+##    yAxis.joinToAxis(xAxis, mode='left')
 ##
-##	  drawing.add(xAxis)
-##	  drawing.add(yAxis)
+##    drawing.add(xAxis)
+##    drawing.add(yAxis)
 ##
-##	  return drawing
+##    return drawing
 ##
 ##
 ##def sample3b():
-##	  "Make sample drawing with two axes, y connected at right of x."
+##    "Make sample drawing with two axes, y connected at right of x."
 ##
-##	  drawing = Drawing(400, 200)
+##    drawing = Drawing(400, 200)
 ##
-##	  data = [(10, 20, 30, 42)]
+##    data = [(10, 20, 30, 42)]
 ##
-##	  xAxis = XCategoryAxis()
-##	  xAxis._length = 300
-##	  xAxis.configure(data)
-##	  xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-##	  xAxis.labels.boxAnchor = 'n'
+##    xAxis = XCategoryAxis()
+##    xAxis._length = 300
+##    xAxis.configure(data)
+##    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+##    xAxis.labels.boxAnchor = 'n'
 ##
-##	  yAxis = YValueAxis()
-##	  yAxis.setPosition(50, 50, 125)
-##	  yAxis.configure(data)
-##	  yAxis.joinToAxis(xAxis, mode='right')
+##    yAxis = YValueAxis()
+##    yAxis.setPosition(50, 50, 125)
+##    yAxis.configure(data)
+##    yAxis.joinToAxis(xAxis, mode='right')
 ##
-##	  drawing.add(xAxis)
-##	  drawing.add(yAxis)
+##    drawing.add(xAxis)
+##    drawing.add(yAxis)
 ##
-##	  return drawing
+##    return drawing
 ##
 ##
 ##def sample3c():
-##	  "Make two axes, y connected at fixed value (in points) of x."
+##    "Make two axes, y connected at fixed value (in points) of x."
 ##
-##	  drawing = Drawing(400, 200)
+##    drawing = Drawing(400, 200)
 ##
-##	  data = [(10, 20, 30, 42)]
+##    data = [(10, 20, 30, 42)]
 ##
-##	  yAxis = YValueAxis()
-##	  yAxis.setPosition(50, 50, 125)
-##	  yAxis.configure(data)
+##    yAxis = YValueAxis()
+##    yAxis.setPosition(50, 50, 125)
+##    yAxis.configure(data)
 ##
-##	  xAxis = XValueAxis()
-##	  xAxis._length = 300
-##	  xAxis.configure(data)
-##	  xAxis.joinToAxis(yAxis, mode='points', pos=100)
+##    xAxis = XValueAxis()
+##    xAxis._length = 300
+##    xAxis.configure(data)
+##    xAxis.joinToAxis(yAxis, mode='points', pos=100)
 ##
-##	  drawing.add(xAxis)
-##	  drawing.add(yAxis)
+##    drawing.add(xAxis)
+##    drawing.add(yAxis)
 ##
-##	  return drawing
+##    return drawing
 
 
 def sample4a():
-	"Sample drawing, xvalue/yvalue axes, y connected at 100 pts to x."
+    "Sample drawing, xvalue/yvalue axes, y connected at 100 pts to x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'points'
-	xAxis.joinAxisPos = 100
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'points'
+    xAxis.joinAxisPos = 100
+    xAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample4b():
-	"Sample drawing, xvalue/yvalue axes, y connected at value 35 of x."
+    "Sample drawing, xvalue/yvalue axes, y connected at value 35 of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'value'
-	xAxis.joinAxisPos = 35
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'value'
+    xAxis.joinAxisPos = 35
+    xAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample4c():
-	"Sample drawing, xvalue/yvalue axes, y connected to bottom of x."
+    "Sample drawing, xvalue/yvalue axes, y connected to bottom of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'bottom'
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'bottom'
+    xAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample4c1():
-	"xvalue/yvalue axes, without drawing axis lines/ticks."
+    "xvalue/yvalue axes, without drawing axis lines/ticks."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
-	yAxis.visibleAxis = 0
-	yAxis.visibleTicks = 0
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
+    yAxis.visibleAxis = 0
+    yAxis.visibleTicks = 0
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'bottom'
-	xAxis.configure(data)
-	xAxis.visibleAxis = 0
-	xAxis.visibleTicks = 0
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'bottom'
+    xAxis.configure(data)
+    xAxis.visibleAxis = 0
+    xAxis.visibleTicks = 0
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample4d():
-	"Sample drawing, xvalue/yvalue axes, y connected to top of x."
+    "Sample drawing, xvalue/yvalue axes, y connected to top of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'top'
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'top'
+    xAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample5a():
-	"Sample drawing, xvalue/yvalue axes, y connected at 100 pts to x."
+    "Sample drawing, xvalue/yvalue axes, y connected at 100 pts to x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis.setPosition(50, 50, 300)
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis.setPosition(50, 50, 300)
+    xAxis.configure(data)
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'points'
-	yAxis.joinAxisPos = 100
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'points'
+    yAxis.joinAxisPos = 100
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample5b():
-	"Sample drawing, xvalue/yvalue axes, y connected at value 35 of x."
+    "Sample drawing, xvalue/yvalue axes, y connected at value 35 of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis.setPosition(50, 50, 300)
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis.setPosition(50, 50, 300)
+    xAxis.configure(data)
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'value'
-	yAxis.joinAxisPos = 35
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'value'
+    yAxis.joinAxisPos = 35
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample5c():
-	"Sample drawing, xvalue/yvalue axes, y connected at right of x."
+    "Sample drawing, xvalue/yvalue axes, y connected at right of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis.setPosition(50, 50, 300)
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis.setPosition(50, 50, 300)
+    xAxis.configure(data)
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'right'
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'right'
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample5d():
-	"Sample drawing, xvalue/yvalue axes, y connected at left of x."
+    "Sample drawing, xvalue/yvalue axes, y connected at left of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis.setPosition(50, 50, 300)
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis.setPosition(50, 50, 300)
+    xAxis.configure(data)
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'left'
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'left'
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample6a():
-	"Sample drawing, xcat/yvalue axes, x connected at top of y."
+    "Sample drawing, xcat/yvalue axes, x connected at top of y."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XCategoryAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'top'
-	xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	xAxis.labels.boxAnchor = 'n'
+    xAxis = XCategoryAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'top'
+    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    xAxis.labels.boxAnchor = 'n'
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample6b():
-	"Sample drawing, xcat/yvalue axes, x connected at bottom of y."
+    "Sample drawing, xcat/yvalue axes, x connected at bottom of y."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XCategoryAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'bottom'
-	xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	xAxis.labels.boxAnchor = 'n'
+    xAxis = XCategoryAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'bottom'
+    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    xAxis.labels.boxAnchor = 'n'
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample6c():
-	"Sample drawing, xcat/yvalue axes, x connected at 100 pts to y."
+    "Sample drawing, xcat/yvalue axes, x connected at 100 pts to y."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XCategoryAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'points'
-	xAxis.joinAxisPos = 100
-	xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	xAxis.labels.boxAnchor = 'n'
+    xAxis = XCategoryAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'points'
+    xAxis.joinAxisPos = 100
+    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    xAxis.labels.boxAnchor = 'n'
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample6d():
-	"Sample drawing, xcat/yvalue axes, x connected at value 20 of y."
+    "Sample drawing, xcat/yvalue axes, x connected at value 20 of y."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	yAxis = YValueAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.configure(data)
+    yAxis = YValueAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.configure(data)
 
-	xAxis = XCategoryAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
-	xAxis.joinAxis = yAxis
-	xAxis.joinAxisMode = 'value'
-	xAxis.joinAxisPos = 20
-	xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	xAxis.labels.boxAnchor = 'n'
+    xAxis = XCategoryAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
+    xAxis.joinAxis = yAxis
+    xAxis.joinAxisMode = 'value'
+    xAxis.joinAxisPos = 20
+    xAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    xAxis.labels.boxAnchor = 'n'
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample7a():
-	"Sample drawing, xvalue/ycat axes, y connected at right of x."
+    "Sample drawing, xvalue/ycat axes, y connected at right of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
 
-	yAxis = YCategoryAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'right'
-	yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	yAxis.labels.boxAnchor = 'e'
-	yAxis.configure(data)
+    yAxis = YCategoryAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'right'
+    yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    yAxis.labels.boxAnchor = 'e'
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample7b():
-	"Sample drawing, xvalue/ycat axes, y connected at left of x."
+    "Sample drawing, xvalue/ycat axes, y connected at left of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
 
-	yAxis = YCategoryAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'left'
-	yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	yAxis.labels.boxAnchor = 'e'
-	yAxis.configure(data)
+    yAxis = YCategoryAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'left'
+    yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    yAxis.labels.boxAnchor = 'e'
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample7c():
-	"Sample drawing, xvalue/ycat axes, y connected at value 30 of x."
+    "Sample drawing, xvalue/ycat axes, y connected at value 30 of x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
 
-	yAxis = YCategoryAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'value'
-	yAxis.joinAxisPos = 30
-	yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	yAxis.labels.boxAnchor = 'e'
-	yAxis.configure(data)
+    yAxis = YCategoryAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'value'
+    yAxis.joinAxisPos = 30
+    yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    yAxis.labels.boxAnchor = 'e'
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
 
 
 def sample7d():
-	"Sample drawing, xvalue/ycat axes, y connected at 200 pts to x."
+    "Sample drawing, xvalue/ycat axes, y connected at 200 pts to x."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(10, 20, 30, 42)]
+    data = [(10, 20, 30, 42)]
 
-	xAxis = XValueAxis()
-	xAxis._length = 300
-	xAxis.configure(data)
+    xAxis = XValueAxis()
+    xAxis._length = 300
+    xAxis.configure(data)
 
-	yAxis = YCategoryAxis()
-	yAxis.setPosition(50, 50, 125)
-	yAxis.joinAxis = xAxis
-	yAxis.joinAxisMode = 'points'
-	yAxis.joinAxisPos = 200
-	yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
-	yAxis.labels.boxAnchor = 'e'
-	yAxis.configure(data)
+    yAxis = YCategoryAxis()
+    yAxis.setPosition(50, 50, 125)
+    yAxis.joinAxis = xAxis
+    yAxis.joinAxisMode = 'points'
+    yAxis.joinAxisPos = 200
+    yAxis.categoryNames = ['Beer', 'Wine', 'Meat', 'Cannelloni']
+    yAxis.labels.boxAnchor = 'e'
+    yAxis.configure(data)
 
-	drawing.add(xAxis)
-	drawing.add(yAxis)
+    drawing.add(xAxis)
+    drawing.add(yAxis)
 
-	return drawing
+    return drawing
--- a/reportlab/graphics/charts/barcharts.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/graphics/charts/barcharts.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,7 +1,7 @@
 #copyright ReportLab Inc. 2000-2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/graphics/charts/barcharts.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/graphics/charts/barcharts.py,v 1.62 2002/07/15 18:45:01 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/graphics/charts/barcharts.py,v 1.63 2002/07/17 22:46:22 andy_robinson Exp $
 """This module defines a variety of Bar Chart components.
 
 The basic flavors are Side-by-side, available in horizontal and
@@ -9,7 +9,7 @@
 
 Stacked and percentile bar charts to follow...
 """
-__version__=''' $Id: barcharts.py,v 1.62 2002/07/15 18:45:01 rgbecker Exp $ '''
+__version__=''' $Id: barcharts.py,v 1.63 2002/07/17 22:46:22 andy_robinson Exp $ '''
 
 import string, copy
 from types import FunctionType, StringType
@@ -27,877 +27,877 @@
 from reportlab.graphics.widgets.grids import ShadedRect
 
 class BarChartProperties(PropHolder):
-	_attrMap = AttrMap(
-		strokeColor = AttrMapValue(isColorOrNone, desc='Color of the bar border.'),
-		fillColor = AttrMapValue(isColorOrNone, desc='Color of the bar interior area.'),
-		strokeWidth = AttrMapValue(isNumber, desc='Width of the bar border.'),
-		symbol = AttrMapValue(None, desc='A widget to be used instead of a normal bar.'),
-		)
+    _attrMap = AttrMap(
+        strokeColor = AttrMapValue(isColorOrNone, desc='Color of the bar border.'),
+        fillColor = AttrMapValue(isColorOrNone, desc='Color of the bar interior area.'),
+        strokeWidth = AttrMapValue(isNumber, desc='Width of the bar border.'),
+        symbol = AttrMapValue(None, desc='A widget to be used instead of a normal bar.'),
+        )
 
-	def __init__(self):
-		self.strokeColor = None
-		self.fillColor = colors.blue
-		self.strokeWidth = 0.5
-		self.symbol = None
+    def __init__(self):
+        self.strokeColor = None
+        self.fillColor = colors.blue
+        self.strokeWidth = 0.5
+        self.symbol = None
 
 # Bar chart classes.
 class BarChart(Widget):
-	"Abstract base class, unusable by itself."
+    "Abstract base class, unusable by itself."
 
-	_attrMap = AttrMap(
-		debug = AttrMapValue(isNumber, desc='Used only for debugging.'),
-		x = AttrMapValue(isNumber, desc='X position of the lower-left corner of the chart.'),
-		y = AttrMapValue(isNumber, desc='Y position of the lower-left corner of the chart.'),
-		width = AttrMapValue(isNumber, desc='Width of the chart.'),
-		height = AttrMapValue(isNumber, desc='Height of the chart.'),
-		useAbsolute = AttrMapValue(isNumber, desc='Flag to use absolute spacing values.'),
-		barWidth = AttrMapValue(isNumber, desc='The width of an individual bar.'),
-		groupSpacing = AttrMapValue(isNumber, desc='Width between groups of bars.'),
-		barSpacing = AttrMapValue(isNumber, desc='Width between individual bars.'),
-		strokeColor = AttrMapValue(isColorOrNone, desc='Color of the plot area border.'),
-		strokeWidth = AttrMapValue(isNumber, desc='Width plot area border.'),
-		fillColor = AttrMapValue(isColorOrNone, desc='Color of the plot area interior.'),
-		bars = AttrMapValue(None, desc='Handle of the individual bars.'),
-		valueAxis = AttrMapValue(None, desc='Handle of the value axis.'),
-		categoryAxis = AttrMapValue(None, desc='Handle of the category axis.'),
-		data = AttrMapValue(None, desc='Data to be plotted, list of (lists of) numbers.'),
-		barLabels = AttrMapValue(None, desc='Handle to the list of bar labels.'),
-		barLabelFormat = AttrMapValue(None, desc='Formatting string or function used for bar labels.'),
-		reversePlotOrder = AttrMapValue(isBoolean, desc='If true, reverse common category plot order.'),
-		naLabel = AttrMapValue(NoneOrInstanceOfNA_Label, desc='Label to use for N/A values.'),
-		)
+    _attrMap = AttrMap(
+        debug = AttrMapValue(isNumber, desc='Used only for debugging.'),
+        x = AttrMapValue(isNumber, desc='X position of the lower-left corner of the chart.'),
+        y = AttrMapValue(isNumber, desc='Y position of the lower-left corner of the chart.'),
+        width = AttrMapValue(isNumber, desc='Width of the chart.'),
+        height = AttrMapValue(isNumber, desc='Height of the chart.'),
+        useAbsolute = AttrMapValue(isNumber, desc='Flag to use absolute spacing values.'),
+        barWidth = AttrMapValue(isNumber, desc='The width of an individual bar.'),
+        groupSpacing = AttrMapValue(isNumber, desc='Width between groups of bars.'),
+        barSpacing = AttrMapValue(isNumber, desc='Width between individual bars.'),
+        strokeColor = AttrMapValue(isColorOrNone, desc='Color of the plot area border.'),
+        strokeWidth = AttrMapValue(isNumber, desc='Width plot area border.'),
+        fillColor = AttrMapValue(isColorOrNone, desc='Color of the plot area interior.'),
+        bars = AttrMapValue(None, desc='Handle of the individual bars.'),
+        valueAxis = AttrMapValue(None, desc='Handle of the value axis.'),
+        categoryAxis = AttrMapValue(None, desc='Handle of the category axis.'),
+        data = AttrMapValue(None, desc='Data to be plotted, list of (lists of) numbers.'),
+        barLabels = AttrMapValue(None, desc='Handle to the list of bar labels.'),
+        barLabelFormat = AttrMapValue(None, desc='Formatting string or function used for bar labels.'),
+        reversePlotOrder = AttrMapValue(isBoolean, desc='If true, reverse common category plot order.'),
+        naLabel = AttrMapValue(NoneOrInstanceOfNA_Label, desc='Label to use for N/A values.'),
+        )
 
-	def __init__(self):
-		assert self.__class__.__name__!='BarChart', 'Abstract Class BarChart Instantiated'
-		self.debug = 0
-		self.barSpacing = 0
+    def __init__(self):
+        assert self.__class__.__name__!='BarChart', 'Abstract Class BarChart Instantiated'
+        self.debug = 0
+        self.barSpacing = 0
 
-		self.x = 0
-		self.y = 0
-		self.x = 20
-		self.y = 10
-		self.height = 85
-		self.width = 180
-		self.reversePlotOrder = 0
+        self.x = 0
+        self.y = 0
+        self.x = 20
+        self.y = 10
+        self.height = 85
+        self.width = 180
+        self.reversePlotOrder = 0
 
-		# allow for a bounding rectangle
-		self.strokeColor = None
-		self.strokeWidth = 1
-		self.fillColor = None
+        # allow for a bounding rectangle
+        self.strokeColor = None
+        self.strokeWidth = 1
+        self.fillColor = None
 
-		# this defines two series of 3 points.	Just an example.
-		self.data = [(100,110,120,130),
-					(70, 80, 85, 90)]
+        # this defines two series of 3 points.  Just an example.
+        self.data = [(100,110,120,130),
+                    (70, 80, 85, 90)]
 
-		# control bar spacing. is useAbsolute = 1 then
-		# the next parameters are in points; otherwise
-		# they are 'proportions' and are normalized to
-		# fit the available space.	Half a barSpacing
-		# is allocated at the beginning and end of the
-		# chart.
-		self.useAbsolute = 0   #- not done yet
-		self.barWidth = 10
-		self.groupSpacing = 5
-		self.barSpacing = 0
+        # control bar spacing. is useAbsolute = 1 then
+        # the next parameters are in points; otherwise
+        # they are 'proportions' and are normalized to
+        # fit the available space.  Half a barSpacing
+        # is allocated at the beginning and end of the
+        # chart.
+        self.useAbsolute = 0   #- not done yet
+        self.barWidth = 10
+        self.groupSpacing = 5
+        self.barSpacing = 0
 
-		self.barLabels = TypedPropertyCollection(BarChartLabel)
-		self.barLabels.boxAnchor = 'c'
-		self.barLabels.textAnchor = 'middle'
-		self.barLabelFormat = None
+        self.barLabels = TypedPropertyCollection(BarChartLabel)
+        self.barLabels.boxAnchor = 'c'
+        self.barLabels.textAnchor = 'middle'
+        self.barLabelFormat = None
 
-		# this says whether the origin is inside or outside
-		# the bar - +10 means put the origin ten points
-		# above the tip of the bar if value > 0, or ten
-		# points inside if bar value < 0.  This is different
-		# to label dx/dy which are not dependent on the
-		# sign of the data.
-		self.barLabels.nudge = 0
+        # this says whether the origin is inside or outside
+        # the bar - +10 means put the origin ten points
+        # above the tip of the bar if value > 0, or ten
+        # points inside if bar value < 0.  This is different
+        # to label dx/dy which are not dependent on the
+        # sign of the data.
+        self.barLabels.nudge = 0
 
-		# if you have multiple series, by default they butt
-		# together.
+        # if you have multiple series, by default they butt
+        # together.
 
-		# we really need some well-designed default lists of
-		# colors e.g. from Tufte.  These will be used in a
-		# cycle to set the fill color of each series.
-		self.bars = TypedPropertyCollection(BarChartProperties)
-##		  self.bars.symbol = None
-		self.bars.strokeWidth = 1
-		self.bars.strokeColor = colors.black
+        # we really need some well-designed default lists of
+        # colors e.g. from Tufte.  These will be used in a
+        # cycle to set the fill color of each series.
+        self.bars = TypedPropertyCollection(BarChartProperties)
+##        self.bars.symbol = None
+        self.bars.strokeWidth = 1
+        self.bars.strokeColor = colors.black
 
-		self.bars[0].fillColor = colors.red
-		self.bars[1].fillColor = colors.green
-		self.bars[2].fillColor = colors.blue
-		self.naLabel = None#NA_Label()
+        self.bars[0].fillColor = colors.red
+        self.bars[1].fillColor = colors.green
+        self.bars[2].fillColor = colors.blue
+        self.naLabel = None#NA_Label()
 
-	def makeBackground(self):
-		strokeColor,strokeWidth,fillColor=self.strokeColor, self.strokeWidth, self.fillColor
-		if (strokeWidth and strokeColor) or fillColor:
-			g = Group()
-			g.add(Rect(self.x, self.y, self.width, self.height,
-				strokeColor=strokeColor, strokeWidth=strokeWidth, fillColor=fillColor))
-			return g
-		else:
-			return None
+    def makeBackground(self):
+        strokeColor,strokeWidth,fillColor=self.strokeColor, self.strokeWidth, self.fillColor
+        if (strokeWidth and strokeColor) or fillColor:
+            g = Group()
+            g.add(Rect(self.x, self.y, self.width, self.height,
+                strokeColor=strokeColor, strokeWidth=strokeWidth, fillColor=fillColor))
+            return g
+        else:
+            return None
 
 
-	def demo(self):
-		"""Shows basic use of a bar chart"""
-		if self.__class__.__name__=='BarChart':
-			raise NotImplementedError, 'Abstract Class BarChart has no demo'
-		drawing = Drawing(200, 100)
-		bc = self.__class__()
-		drawing.add(bc)
-		return drawing
+    def demo(self):
+        """Shows basic use of a bar chart"""
+        if self.__class__.__name__=='BarChart':
+            raise NotImplementedError, 'Abstract Class BarChart has no demo'
+        drawing = Drawing(200, 100)
+        bc = self.__class__()
+        drawing.add(bc)
+        return drawing
 
-	def _getConfigureData(self):
-		cA = self.categoryAxis
-		data = self.data
-		if cA.style!='parallel':
-			_data = data
-			data = max(map(len,_data))*[0]
-			for d in _data:
-				for i in xrange(len(d)):
-					data[i] = data[i] + (d[i] or 0)
-			data = list(_data) + [data]
-		self._configureData = data
+    def _getConfigureData(self):
+        cA = self.categoryAxis
+        data = self.data
+        if cA.style!='parallel':
+            _data = data
+            data = max(map(len,_data))*[0]
+            for d in _data:
+                for i in xrange(len(d)):
+                    data[i] = data[i] + (d[i] or 0)
+            data = list(_data) + [data]
+        self._configureData = data
 
-	def _getMinMax(self):
-		'''Attempt to return the data range'''
-		self._getConfigureData()
-		self.valueAxis._setRange(self._configureData)
-		return self.valueAxis._valueMin, self.valueAxis._valueMax
+    def _getMinMax(self):
+        '''Attempt to return the data range'''
+        self._getConfigureData()
+        self.valueAxis._setRange(self._configureData)
+        return self.valueAxis._valueMin, self.valueAxis._valueMax
 
-	def _drawBegin(self,org,length):
-		'''Position and configure value axis, return crossing value'''
-		vA = self.valueAxis
-		vA.setPosition(self.x, self.y, length)
-		self._getConfigureData()
-		vA.configure(self._configureData)
+    def _drawBegin(self,org,length):
+        '''Position and configure value axis, return crossing value'''
+        vA = self.valueAxis
+        vA.setPosition(self.x, self.y, length)
+        self._getConfigureData()
+        vA.configure(self._configureData)
 
-		# if zero is in chart, put the other axis there, otherwise use low
-		crossesAt = vA.scale(0)
-		if crossesAt > org+length or crossesAt<org:
-			crossesAt = org
-		return crossesAt
+        # if zero is in chart, put the other axis there, otherwise use low
+        crossesAt = vA.scale(0)
+        if crossesAt > org+length or crossesAt<org:
+            crossesAt = org
+        return crossesAt
 
-	def _drawFinish(self):
-		'''finalize the drawing of a barchart'''
-		cA = self.categoryAxis
-		vA = self.valueAxis
-		cA.configure(self._configureData)
-		self.calcBarPositions()
-		g = Group()
-		g.add(self.makeBackground())
-		cA.makeGrid(g)
-		vA.makeGrid(g)
-		g.add(self.makeBars())
-		g.add(cA)
-		g.add(vA)
-		del self._configureData
-		return g
+    def _drawFinish(self):
+        '''finalize the drawing of a barchart'''
+        cA = self.categoryAxis
+        vA = self.valueAxis
+        cA.configure(self._configureData)
+        self.calcBarPositions()
+        g = Group()
+        g.add(self.makeBackground())
+        cA.makeGrid(g)
+        vA.makeGrid(g)
+        g.add(self.makeBars())
+        g.add(cA)
+        g.add(vA)
+        del self._configureData
+        return g
 
 
-	def calcBarPositions(self):
-		"""Works out where they go. default vertical.
+    def calcBarPositions(self):
+        """Works out where they go. default vertical.
 
-		Sets an attribute _barPositions which is a list of
-		lists of (x, y, width, height) matching the data.
-		"""
+        Sets an attribute _barPositions which is a list of
+        lists of (x, y, width, height) matching the data.
+        """
 
-		flipXY = self._flipXY
-		if flipXY:
-			org = self.y
-		else:
-			org = self.x
-		cA = self.categoryAxis
-		cScale = cA.scale
+        flipXY = self._flipXY
+        if flipXY:
+            org = self.y
+        else:
+            org = self.x
+        cA = self.categoryAxis
+        cScale = cA.scale
 
-		data = self.data
-		seriesCount = self._seriesCount = len(data)
-		self._rowLength = rowLength = max(map(len,data))
-		groupSpacing, barSpacing, barWidth = self.groupSpacing, self.barSpacing, self.barWidth
-		style = self.categoryAxis.style
-		if style=='parallel':
-			groupWidth = groupSpacing+(seriesCount*barWidth)+(seriesCount-1)*barSpacing
-			bGap = barWidth+barSpacing
-		else:
-			accum = rowLength*[0]
-			groupWidth = groupSpacing+barWidth
-			bGap = 0
-		self._groupWidth = groupWidth
-		useAbsolute = self.useAbsolute
+        data = self.data
+        seriesCount = self._seriesCount = len(data)
+        self._rowLength = rowLength = max(map(len,data))
+        groupSpacing, barSpacing, barWidth = self.groupSpacing, self.barSpacing, self.barWidth
+        style = self.categoryAxis.style
+        if style=='parallel':
+            groupWidth = groupSpacing+(seriesCount*barWidth)+(seriesCount-1)*barSpacing
+            bGap = barWidth+barSpacing
+        else:
+            accum = rowLength*[0]
+            groupWidth = groupSpacing+barWidth
+            bGap = 0
+        self._groupWidth = groupWidth
+        useAbsolute = self.useAbsolute
 
-		if useAbsolute:
-			# bar dimensions are absolute
-			normFactor = 1.0
-		else:
-			# bar dimensions are normalized to fit.  How wide
-			# notionally is one group of bars?
-			availWidth = cScale(0)[1]
-			normFactor = availWidth/float(groupWidth)
-			if self.debug:
-				print '%d series, %d points per series' % (seriesCount, self._rowLength)
-				print 'width = %d group + (%d bars * %d barWidth) + (%d gaps * %d interBar) = %d total' % (
-					groupSpacing, seriesCount, barWidth,
-					seriesCount-1, barSpacing, groupWidth)
+        if useAbsolute:
+            # bar dimensions are absolute
+            normFactor = 1.0
+        else:
+            # bar dimensions are normalized to fit.  How wide
+            # notionally is one group of bars?
+            availWidth = cScale(0)[1]
+            normFactor = availWidth/float(groupWidth)
+            if self.debug:
+                print '%d series, %d points per series' % (seriesCount, self._rowLength)
+                print 'width = %d group + (%d bars * %d barWidth) + (%d gaps * %d interBar) = %d total' % (
+                    groupSpacing, seriesCount, barWidth,
+                    seriesCount-1, barSpacing, groupWidth)
 
-		# 'Baseline' correction...
-		vA = self.valueAxis
-		vScale = vA.scale
-		vm, vM = vA._valueMin, vA._valueMax
-		if vm <= 0 <= vM:
-			baseLine = vScale(0)
-		elif 0 < vm:
-			baseLine = vScale(vm)
-		elif vM < 0:
-			baseLine = vScale(vM)
-		self._baseLine = baseLine
+        # 'Baseline' correction...
+        vA = self.valueAxis
+        vScale = vA.scale
+        vm, vM = vA._valueMin, vA._valueMax
+        if vm <= 0 <= vM:
+            baseLine = vScale(0)
+        elif 0 < vm:
+            baseLine = vScale(vm)
+        elif vM < 0:
+            baseLine = vScale(vM)
+        self._baseLine = baseLine
 
-		COLUMNS = range(max(map(len,data)))
-		if useAbsolute:
-			_cScale = cA._scale
+        COLUMNS = range(max(map(len,data)))
+        if useAbsolute:
+            _cScale = cA._scale
 
-		width = self.barWidth*normFactor
-		self._barPositions = []
-		reversePlotOrder = self.reversePlotOrder
-		for rowNo in range(seriesCount):
-			barRow = []
-			xVal = 0.5*groupSpacing+rowNo*bGap
-			if reversePlotOrder: rowNo = seriesCount-1 - rowNo
-			for colNo in COLUMNS:
-				datum = data[rowNo][colNo]
+        width = self.barWidth*normFactor
+        self._barPositions = []
+        reversePlotOrder = self.reversePlotOrder
+        for rowNo in range(seriesCount):
+            barRow = []
+            xVal = 0.5*groupSpacing+rowNo*bGap
+            if reversePlotOrder: rowNo = seriesCount-1 - rowNo
+            for colNo in COLUMNS:
+                datum = data[rowNo][colNo]
 
-				# Ufff...
-				if useAbsolute:
-					x = groupWidth*_cScale(colNo) + xVal + org
-				else:
-					(g, gW) = cScale(colNo)
-					x = g + normFactor*xVal
+                # Ufff...
+                if useAbsolute:
+                    x = groupWidth*_cScale(colNo) + xVal + org
+                else:
+                    (g, gW) = cScale(colNo)
+                    x = g + normFactor*xVal
 
-				if datum is None:
-					height = None
-					y = baseLine
-				else:
-					if style!='parallel':
-						y = vScale(accum[colNo])
-						if y<baseLine: y = baseLine
-						accum[colNo] = accum[colNo] + datum
-						datum = accum[colNo]
-					else:
-						y = baseLine
-					height = vScale(datum) - y
-					if -1e-8<height<=1e-8:
-						height = 1e-8
-						if datum<-1e-8: height = -1e-8
-				barRow.append(flipXY and (y,x,height,width) or (x, y, width, height))
+                if datum is None:
+                    height = None
+                    y = baseLine
+                else:
+                    if style!='parallel':
+                        y = vScale(accum[colNo])
+                        if y<baseLine: y = baseLine
+                        accum[colNo] = accum[colNo] + datum
+                        datum = accum[colNo]
+                    else:
+                        y = baseLine
+                    height = vScale(datum) - y
+                    if -1e-8<height<=1e-8:
+                        height = 1e-8
+                        if datum<-1e-8: height = -1e-8
+                barRow.append(flipXY and (y,x,height,width) or (x, y, width, height))
 
-			self._barPositions.append(barRow)
+            self._barPositions.append(barRow)
 
 
-	def _getLabelText(self, rowNo, colNo):
-		'''return formatted label text'''
-		labelFmt = self.barLabelFormat
-		if labelFmt is None:
-			labelText = None
-		elif type(labelFmt) is StringType:
-			labelText = labelFmt % self.data[rowNo][colNo]
-		elif type(labelFmt) is FunctionType:
-			labelText = labelFmt(self.data[rowNo][colNo])
-		elif isinstance(labelFmt, Formatter):
-			#these are callable objects
-			labelText = labelFmt(self.data[rowNo][colNo])
-		else:
-			msg = "Unknown formatter type %s, expected string or function" % labelFmt
-			raise Exception, msg
-		return labelText
+    def _getLabelText(self, rowNo, colNo):
+        '''return formatted label text'''
+        labelFmt = self.barLabelFormat
+        if labelFmt is None:
+            labelText = None
+        elif type(labelFmt) is StringType:
+            labelText = labelFmt % self.data[rowNo][colNo]
+        elif type(labelFmt) is FunctionType:
+            labelText = labelFmt(self.data[rowNo][colNo])
+        elif isinstance(labelFmt, Formatter):
+            #these are callable objects
+            labelText = labelFmt(self.data[rowNo][colNo])
+        else:
+            msg = "Unknown formatter type %s, expected string or function" % labelFmt
+            raise Exception, msg
+        return labelText
 
-	def _labelXY(self,label,x,y,width,height):
-		'Compute x, y for a label'
-		if self._flipXY:
-			return x + width + (width>=0 and 1 or -1) * label.nudge, y + 0.5*height
-		else:
-			return x + 0.5*width, y + height + (height>=0 and 1 or -1) * label.nudge
+    def _labelXY(self,label,x,y,width,height):
+        'Compute x, y for a label'
+        if self._flipXY:
+            return x + width + (width>=0 and 1 or -1) * label.nudge, y + 0.5*height
+        else:
+            return x + 0.5*width, y + height + (height>=0 and 1 or -1) * label.nudge
 
-	def _addBarLabel(self, g, rowNo, colNo, x, y, width, height):
-		text = self._getLabelText(rowNo,colNo)
-		if text:
-			self._addLabel(text, self.barLabels[(rowNo, colNo)], g, rowNo, colNo, x, y, width, height)
+    def _addBarLabel(self, g, rowNo, colNo, x, y, width, height):
+        text = self._getLabelText(rowNo,colNo)
+        if text:
+            self._addLabel(text, self.barLabels[(rowNo, colNo)], g, rowNo, colNo, x, y, width, height)
 
-	def _addNABarLabel(self, g, rowNo, colNo, x, y, width, height):
-		na = self.naLabel
-		if na and na.text:
-			na = copy.copy(na)
-			v = self.valueAxis._valueMax<=0 and -1e-8 or 1e-8
-			if width is None: width = v
-			if height is None: height = v
-			self._addLabel(na.text, na, g, rowNo, colNo, x, y, width, height)
+    def _addNABarLabel(self, g, rowNo, colNo, x, y, width, height):
+        na = self.naLabel
+        if na and na.text:
+            na = copy.copy(na)
+            v = self.valueAxis._valueMax<=0 and -1e-8 or 1e-8
+            if width is None: width = v
+            if height is None: height = v
+            self._addLabel(na.text, na, g, rowNo, colNo, x, y, width, height)
 
-	def _addLabel(self, text, label, g, rowNo, colNo, x, y, width, height):
-		if label.visible:
-			labelWidth = stringWidth(text, label.fontName, label.fontSize)
-			x0, y0 = self._labelXY(label,x,y,width,height)
-			flipXY = self._flipXY
-			if flipXY:
-				pm = width
-			else:
-				pm = height
-			label._pmv = pm	#the plus minus val
-			fixedEnd = getattr(label,'fixedEnd', None)
-			if fixedEnd is not None:
-				v = fixedEnd._getValue(self,pm)
-				x00, y00 = x0, y0
-				if flipXY:
-					x0 = v
-				else:
-					y0 = v
-			else:
-				if flipXY:
-					x00 = x0
-					y00 = y+height/2.0
-				else:
-					x00 = x+width/2.0
-					y00 = y0
-			fixedStart = getattr(label,'fixedStart', None)
-			if fixedStart is not None:
-				v = fixedStart._getValue(self,pm)
-				if flipXY:
-					x00 = v
-				else:
-					y00 = v
+    def _addLabel(self, text, label, g, rowNo, colNo, x, y, width, height):
+        if label.visible:
+            labelWidth = stringWidth(text, label.fontName, label.fontSize)
+            x0, y0 = self._labelXY(label,x,y,width,height)
+            flipXY = self._flipXY
+            if flipXY:
+                pm = width
+            else:
+                pm = height
+            label._pmv = pm #the plus minus val
+            fixedEnd = getattr(label,'fixedEnd', None)
+            if fixedEnd is not None:
+                v = fixedEnd._getValue(self,pm)
+                x00, y00 = x0, y0
+                if flipXY:
+                    x0 = v
+                else:
+                    y0 = v
+            else:
+                if flipXY:
+                    x00 = x0
+                    y00 = y+height/2.0
+                else:
+                    x00 = x+width/2.0
+                    y00 = y0
+            fixedStart = getattr(label,'fixedStart', None)
+            if fixedStart is not None:
+                v = fixedStart._getValue(self,pm)
+                if flipXY:
+                    x00 = v
+                else:
+                    y00 = v
 
-			if pm<0:
-				if flipXY:
-					dx = -2*label.dx
-					dy = 0
-				else:
-					dy = -2*label.dy
-					dx = 0
-			else:
-				dy = dx = 0
-			label.setOrigin(x0+dx, y0+dy)
-			label.setText(text)
-			sC, sW = label.lineStrokeColor, label.lineStrokeWidth
-			if sC and sW: g.insert(0,Line(x00,y00,x0,y0, strokeColor=sC, strokeWidth=sW))
-			g.add(label)
-			alx = getattr(self,'barLabelCallOut',None)
-			if alx:
-				label._callOutInfo = (self,g,rowNo,colNo,x,y,width,height,x00,y00,x0,y0)
-				alx(label)
-				del label._callOutInfo
+            if pm<0:
+                if flipXY:
+                    dx = -2*label.dx
+                    dy = 0
+                else:
+                    dy = -2*label.dy
+                    dx = 0
+            else:
+                dy = dx = 0
+            label.setOrigin(x0+dx, y0+dy)
+            label.setText(text)
+            sC, sW = label.lineStrokeColor, label.lineStrokeWidth
+            if sC and sW: g.insert(0,Line(x00,y00,x0,y0, strokeColor=sC, strokeWidth=sW))
+            g.add(label)
+            alx = getattr(self,'barLabelCallOut',None)
+            if alx:
+                label._callOutInfo = (self,g,rowNo,colNo,x,y,width,height,x00,y00,x0,y0)
+                alx(label)
+                del label._callOutInfo
 
-	def makeBars(self):
-		g = Group()
+    def makeBars(self):
+        g = Group()
 
-		lenData = len(self.data)
-		reversePlotOrder = self.reversePlotOrder
-		for rowNo in range(lenData):
-			if reversePlotOrder: rowNo = lenData-1 - rowNo
-			row = self._barPositions[rowNo]
-			styleCount = len(self.bars)
-			styleIdx = rowNo % styleCount
-			rowStyle = self.bars[styleIdx]
-			for colNo in range(len(row)):
-				barPos = row[colNo]
-				(x, y, width, height) = barPos
-				if None in (width,height):
-					self._addNABarLabel(g,rowNo,colNo,x,y,width,height)
-					continue
+        lenData = len(self.data)
+        reversePlotOrder = self.reversePlotOrder
+        for rowNo in range(lenData):
+            if reversePlotOrder: rowNo = lenData-1 - rowNo
+            row = self._barPositions[rowNo]
+            styleCount = len(self.bars)
+            styleIdx = rowNo % styleCount
+            rowStyle = self.bars[styleIdx]
+            for colNo in range(len(row)):
+                barPos = row[colNo]
+                (x, y, width, height) = barPos
+                if None in (width,height):
+                    self._addNABarLabel(g,rowNo,colNo,x,y,width,height)
+                    continue
 
-				# Draw a rectangular symbol for each data item,
-				# or a normal colored rectangle.
-				symbol = None
-				if hasattr(self.bars[styleIdx], 'symbol'):
-					symbol = copy.deepcopy(self.bars[styleIdx].symbol)
-				elif hasattr(self.bars, 'symbol'):
-					symbol = self.bars.symbol
+                # Draw a rectangular symbol for each data item,
+                # or a normal colored rectangle.
+                symbol = None
+                if hasattr(self.bars[styleIdx], 'symbol'):
+                    symbol = copy.deepcopy(self.bars[styleIdx].symbol)
+                elif hasattr(self.bars, 'symbol'):
+                    symbol = self.bars.symbol
 
-				if symbol:
-					symbol.x = x
-					symbol.y = y
-					symbol.width = width
-					symbol.height = height
-					g.add(symbol)
-				elif abs(width)>1e-7 and abs(height)>=1e-7 and (rowStyle.fillColor is not None or rowStyle.strokeColor is not None):
-					r = Rect(x, y, width, height)
-					r.strokeWidth = rowStyle.strokeWidth
-					r.fillColor = rowStyle.fillColor
-					r.strokeColor = rowStyle.strokeColor
-					g.add(r)
+                if symbol:
+                    symbol.x = x
+                    symbol.y = y
+                    symbol.width = width
+                    symbol.height = height
+                    g.add(symbol)
+                elif abs(width)>1e-7 and abs(height)>=1e-7 and (rowStyle.fillColor is not None or rowStyle.strokeColor is not None):
+                    r = Rect(x, y, width, height)
+                    r.strokeWidth = rowStyle.strokeWidth
+                    r.fillColor = rowStyle.fillColor
+                    r.strokeColor = rowStyle.strokeColor
+                    g.add(r)
 
-				self._addBarLabel(g,rowNo,colNo,x,y,width,height)
-		return g
+                self._addBarLabel(g,rowNo,colNo,x,y,width,height)
+        return g
 
-	def _desiredCategoryAxisLength(self):
-		'''for dynamically computing the desired category axis length'''
-		style = self.categoryAxis.style
-		data = self.data
-		n = len(data)
-		m = max(map(len,data))
-		if style=='parallel':
-			groupWidth = (n-1)*self.barSpacing+n*self.barWidth
-		else:
-			groupWidth = self.barWidth
-		return m*(self.groupSpacing+groupWidth)
+    def _desiredCategoryAxisLength(self):
+        '''for dynamically computing the desired category axis length'''
+        style = self.categoryAxis.style
+        data = self.data
+        n = len(data)
+        m = max(map(len,data))
+        if style=='parallel':
+            groupWidth = (n-1)*self.barSpacing+n*self.barWidth
+        else:
+            groupWidth = self.barWidth
+        return m*(self.groupSpacing+groupWidth)
 
-	def draw(self):
-		cA, vA = self.categoryAxis, self.valueAxis
-		if vA: ovAjA, vA.joinAxis = vA.joinAxis, cA
-		if cA: ocAjA, cA.joinAxis = cA.joinAxis, vA
-		if self._flipXY:
-			cA.setPosition(self._drawBegin(self.x,self.width), self.y, self.height)
-		else:
-			cA.setPosition(self.x, self._drawBegin(self.y,self.height), self.width)
-		return self._drawFinish()
+    def draw(self):
+        cA, vA = self.categoryAxis, self.valueAxis
+        if vA: ovAjA, vA.joinAxis = vA.joinAxis, cA
+        if cA: ocAjA, cA.joinAxis = cA.joinAxis, vA
+        if self._flipXY:
+            cA.setPosition(self._drawBegin(self.x,self.width), self.y, self.height)
+        else:
+            cA.setPosition(self.x, self._drawBegin(self.y,self.height), self.width)
+        return self._drawFinish()
 
 class VerticalBarChart(BarChart):
-	"Vertical bar chart with multiple side-by-side bars."
+    "Vertical bar chart with multiple side-by-side bars."
 
-	_flipXY = 0
+    _flipXY = 0
 
-	def __init__(self):
-		self.categoryAxis = XCategoryAxis()
-		self.valueAxis = YValueAxis()
-		BarChart.__init__(self)
+    def __init__(self):
+        self.categoryAxis = XCategoryAxis()
+        self.valueAxis = YValueAxis()
+        BarChart.__init__(self)
 
 class HorizontalBarChart(BarChart):
-	"Horizontal bar chart with multiple side-by-side bars."
+    "Horizontal bar chart with multiple side-by-side bars."
 
-	_flipXY = 1
+    _flipXY = 1
 
-	def __init__(self):
-		self.categoryAxis = YCategoryAxis()
-		self.valueAxis = XValueAxis()
-		BarChart.__init__(self)
+    def __init__(self):
+        self.categoryAxis = YCategoryAxis()
+        self.valueAxis = XValueAxis()
+        BarChart.__init__(self)
 
 # Vertical samples.
 
 def sampleV0a():
-	"A slightly pathologic bar chart with only TWO data items."
+    "A slightly pathologic bar chart with only TWO data items."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'ne'
-	bc.categoryAxis.labels.dx = 8
-	bc.categoryAxis.labels.dy = -2
-	bc.categoryAxis.labels.angle = 30
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'ne'
+    bc.categoryAxis.labels.dx = 8
+    bc.categoryAxis.labels.dy = -2
+    bc.categoryAxis.labels.angle = 30
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV0b():
-	"A pathologic bar chart with only ONE data item."
+    "A pathologic bar chart with only ONE data item."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(42,)]
+    data = [(42,)]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 50
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 50
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'ne'
-	bc.categoryAxis.labels.dx = 8
-	bc.categoryAxis.labels.dy = -2
-	bc.categoryAxis.labels.angle = 30
-	bc.categoryAxis.categoryNames = ['Jan-99']
+    bc.categoryAxis.labels.boxAnchor = 'ne'
+    bc.categoryAxis.labels.dx = 8
+    bc.categoryAxis.labels.dy = -2
+    bc.categoryAxis.labels.angle = 30
+    bc.categoryAxis.categoryNames = ['Jan-99']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV0c():
-	"A really pathologic bar chart with NO data items at all!"
+    "A really pathologic bar chart with NO data items at all!"
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [()]
+    data = [()]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'ne'
-	bc.categoryAxis.labels.dx = 8
-	bc.categoryAxis.labels.dy = -2
-	bc.categoryAxis.categoryNames = []
+    bc.categoryAxis.labels.boxAnchor = 'ne'
+    bc.categoryAxis.labels.dx = 8
+    bc.categoryAxis.labels.dy = -2
+    bc.categoryAxis.categoryNames = []
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV1():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [
-			(13, 5, 20, 22, 37, 45, 19, 4),
-			(14, 6, 21, 23, 38, 46, 20, 5)
-			]
+    data = [
+            (13, 5, 20, 22, 37, 45, 19, 4),
+            (14, 6, 21, 23, 38, 46, 20, 5)
+            ]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'ne'
-	bc.categoryAxis.labels.dx = 8
-	bc.categoryAxis.labels.dy = -2
-	bc.categoryAxis.labels.angle = 30
+    bc.categoryAxis.labels.boxAnchor = 'ne'
+    bc.categoryAxis.labels.dx = 8
+    bc.categoryAxis.labels.dy = -2
+    bc.categoryAxis.labels.angle = 30
 
-	catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
-	catNames = map(lambda n:n+'-99', catNames)
-	bc.categoryAxis.categoryNames = catNames
-	drawing.add(bc)
+    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
+    catNames = map(lambda n:n+'-99', catNames)
+    bc.categoryAxis.categoryNames = catNames
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV2a():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	data = [(2.4, -5.7, 2, 5, 9.2),
-			(0.6, -4.9, -3, 4, 6.8)
-			]
+    data = [(2.4, -5.7, 2, 5, 9.2),
+            (0.6, -4.9, -3, 4, 6.8)
+            ]
 
-	labels = ("Q3 2000", "Year to Date", "12 months",
-			  "Annualised\n3 years", "Since 07.10.99")
+    labels = ("Q3 2000", "Year to Date", "12 months",
+              "Annualised\n3 years", "Since 07.10.99")
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 120
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 120
+    bc.width = 300
+    bc.data = data
 
-	bc.barSpacing = 0
-	bc.groupSpacing = 10
-	bc.barWidth = 10
+    bc.barSpacing = 0
+    bc.groupSpacing = 10
+    bc.barWidth = 10
 
-	bc.valueAxis.valueMin = -15
-	bc.valueAxis.valueMax = +15
-	bc.valueAxis.valueStep = 5
-	bc.valueAxis.labels.fontName = 'Helvetica'
-	bc.valueAxis.labels.fontSize = 8
-	bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
-	bc.valueAxis.labels.textAnchor = 'middle'
+    bc.valueAxis.valueMin = -15
+    bc.valueAxis.valueMax = +15
+    bc.valueAxis.valueStep = 5
+    bc.valueAxis.labels.fontName = 'Helvetica'
+    bc.valueAxis.labels.fontSize = 8
+    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
+    bc.valueAxis.labels.textAnchor = 'middle'
 
-	bc.categoryAxis.categoryNames = labels
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 8
-	bc.categoryAxis.labels.dy = -60
+    bc.categoryAxis.categoryNames = labels
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 8
+    bc.categoryAxis.labels.dy = -60
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV2b():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	data = [(2.4, -5.7, 2, 5, 9.2),
-			(0.6, -4.9, -3, 4, 6.8)
-			]
+    data = [(2.4, -5.7, 2, 5, 9.2),
+            (0.6, -4.9, -3, 4, 6.8)
+            ]
 
-	labels = ("Q3 2000", "Year to Date", "12 months",
-			  "Annualised\n3 years", "Since 07.10.99")
+    labels = ("Q3 2000", "Year to Date", "12 months",
+              "Annualised\n3 years", "Since 07.10.99")
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 120
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 120
+    bc.width = 300
+    bc.data = data
 
-	bc.barSpacing = 5
-	bc.groupSpacing = 10
-	bc.barWidth = 10
+    bc.barSpacing = 5
+    bc.groupSpacing = 10
+    bc.barWidth = 10
 
-	bc.valueAxis.valueMin = -15
-	bc.valueAxis.valueMax = +15
-	bc.valueAxis.valueStep = 5
-	bc.valueAxis.labels.fontName = 'Helvetica'
-	bc.valueAxis.labels.fontSize = 8
-	bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
-	bc.valueAxis.labels.textAnchor = 'middle'
+    bc.valueAxis.valueMin = -15
+    bc.valueAxis.valueMax = +15
+    bc.valueAxis.valueStep = 5
+    bc.valueAxis.labels.fontName = 'Helvetica'
+    bc.valueAxis.labels.fontSize = 8
+    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
+    bc.valueAxis.labels.textAnchor = 'middle'
 
-	bc.categoryAxis.categoryNames = labels
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 8
-	bc.categoryAxis.labels.dy = -60
+    bc.categoryAxis.categoryNames = labels
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 8
+    bc.categoryAxis.labels.dy = -60
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV2c():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	data = [(2.4, -5.7, 2, 5, 9.99),
-			(0.6, -4.9, -3, 4, 9.99)
-			]
+    data = [(2.4, -5.7, 2, 5, 9.99),
+            (0.6, -4.9, -3, 4, 9.99)
+            ]
 
-	labels = ("Q3 2000", "Year to Date", "12 months",
-			  "Annualised\n3 years", "Since 07.10.99")
+    labels = ("Q3 2000", "Year to Date", "12 months",
+              "Annualised\n3 years", "Since 07.10.99")
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 120
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 120
+    bc.width = 300
+    bc.data = data
 
-	bc.barSpacing = 2
-	bc.groupSpacing = 10
-	bc.barWidth = 10
+    bc.barSpacing = 2
+    bc.groupSpacing = 10
+    bc.barWidth = 10
 
-	bc.valueAxis.valueMin = -15
-	bc.valueAxis.valueMax = +15
-	bc.valueAxis.valueStep = 5
-	bc.valueAxis.labels.fontName = 'Helvetica'
-	bc.valueAxis.labels.fontSize = 8
+    bc.valueAxis.valueMin = -15
+    bc.valueAxis.valueMax = +15
+    bc.valueAxis.valueStep = 5
+    bc.valueAxis.labels.fontName = 'Helvetica'
+    bc.valueAxis.labels.fontSize = 8
 
-	bc.categoryAxis.categoryNames = labels
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 8
-	bc.valueAxis.labels.boxAnchor = 'n'
-	bc.valueAxis.labels.textAnchor = 'middle'
-	bc.categoryAxis.labels.dy = -60
+    bc.categoryAxis.categoryNames = labels
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 8
+    bc.valueAxis.labels.boxAnchor = 'n'
+    bc.valueAxis.labels.textAnchor = 'middle'
+    bc.categoryAxis.labels.dy = -60
 
-	bc.barLabels.nudge = 10
+    bc.barLabels.nudge = 10
 
-	bc.barLabelFormat = '%0.2f'
-	bc.barLabels.dx = 0
-	bc.barLabels.dy = 0
-	bc.barLabels.boxAnchor = 'n'  # irrelevant (becomes 'c')
-	bc.barLabels.fontName = 'Helvetica'
-	bc.barLabels.fontSize = 6
+    bc.barLabelFormat = '%0.2f'
+    bc.barLabels.dx = 0
+    bc.barLabels.dy = 0
+    bc.barLabels.boxAnchor = 'n'  # irrelevant (becomes 'c')
+    bc.barLabels.fontName = 'Helvetica'
+    bc.barLabels.fontSize = 6
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV3():
-	"Faked horizontal bar chart using a vertical real one (deprecated)."
+    "Faked horizontal bar chart using a vertical real one (deprecated)."
 
-	names = ("UK Equities", "US Equities", "European Equities", "Japanese Equities",
-			  "Pacific (ex Japan) Equities", "Emerging Markets Equities",
-			  "UK Bonds", "Overseas Bonds", "UK Index-Linked", "Cash")
+    names = ("UK Equities", "US Equities", "European Equities", "Japanese Equities",
+              "Pacific (ex Japan) Equities", "Emerging Markets Equities",
+              "UK Bonds", "Overseas Bonds", "UK Index-Linked", "Cash")
 
-	series1 = (-1.5, 0.3, 0.5, 1.0, 0.8, 0.7, 0.4, 0.1, 1.0, 0.3)
-	series2 = (0.0, 0.33, 0.55, 1.1, 0.88, 0.77, 0.44, 0.11, 1.10, 0.33)
+    series1 = (-1.5, 0.3, 0.5, 1.0, 0.8, 0.7, 0.4, 0.1, 1.0, 0.3)
+    series2 = (0.0, 0.33, 0.55, 1.1, 0.88, 0.77, 0.44, 0.11, 1.10, 0.33)
 
-	assert len(names) == len(series1), "bad data"
-	assert len(names) == len(series2), "bad data"
+    assert len(names) == len(series1), "bad data"
+    assert len(names) == len(series2), "bad data"
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = VerticalBarChart()
-	bc.x = 0
-	bc.y = 0
-	bc.height = 100
-	bc.width = 150
-	bc.data = (series1,)
-	bc.bars.fillColor = colors.green
+    bc = VerticalBarChart()
+    bc.x = 0
+    bc.y = 0
+    bc.height = 100
+    bc.width = 150
+    bc.data = (series1,)
+    bc.bars.fillColor = colors.green
 
-	bc.barLabelFormat = '%0.2f'
-	bc.barLabels.dx = 0
-	bc.barLabels.dy = 0
-	bc.barLabels.boxAnchor = 'w' # irrelevant (becomes 'c')
-	bc.barLabels.angle = 90
-	bc.barLabels.fontName = 'Helvetica'
-	bc.barLabels.fontSize = 6
-	bc.barLabels.nudge = 10
+    bc.barLabelFormat = '%0.2f'
+    bc.barLabels.dx = 0
+    bc.barLabels.dy = 0
+    bc.barLabels.boxAnchor = 'w' # irrelevant (becomes 'c')
+    bc.barLabels.angle = 90
+    bc.barLabels.fontName = 'Helvetica'
+    bc.barLabels.fontSize = 6
+    bc.barLabels.nudge = 10
 
-	bc.valueAxis.visible = 0
-	bc.valueAxis.valueMin = -2
-	bc.valueAxis.valueMax = +2
-	bc.valueAxis.valueStep = 1
+    bc.valueAxis.visible = 0
+    bc.valueAxis.valueMin = -2
+    bc.valueAxis.valueMax = +2
+    bc.valueAxis.valueStep = 1
 
-	bc.categoryAxis.tickUp = 0
-	bc.categoryAxis.tickDown = 0
-	bc.categoryAxis.categoryNames = names
-	bc.categoryAxis.labels.angle = 90
-	bc.categoryAxis.labels.boxAnchor = 'w'
-	bc.categoryAxis.labels.dx = 0
-	bc.categoryAxis.labels.dy = -125
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 6
+    bc.categoryAxis.tickUp = 0
+    bc.categoryAxis.tickDown = 0
+    bc.categoryAxis.categoryNames = names
+    bc.categoryAxis.labels.angle = 90
+    bc.categoryAxis.labels.boxAnchor = 'w'
+    bc.categoryAxis.labels.dx = 0
+    bc.categoryAxis.labels.dy = -125
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 6
 
-	g = Group(bc)
-	g.translate(100, 175)
-	g.rotate(-90)
+    g = Group(bc)
+    g.translate(100, 175)
+    g.rotate(-90)
 
-	drawing.add(g)
+    drawing.add(g)
 
-	return drawing
+    return drawing
 
 
 def sampleV4a():
-	"A bar chart showing value axis region starting at *exactly* zero."
+    "A bar chart showing value axis region starting at *exactly* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV4b():
-	"A bar chart showing value axis region starting *below* zero."
+    "A bar chart showing value axis region starting *below* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = -10
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = -10
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV4c():
-	"A bar chart showing value axis region staring *above* zero."
+    "A bar chart showing value axis region staring *above* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 10
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 10
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV4d():
-	"A bar chart showing value axis region entirely *below* zero."
+    "A bar chart showing value axis region entirely *below* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(-13, -20)]
+    data = [(-13, -20)]
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = -30
-	bc.valueAxis.valueMax = -10
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = -30
+    bc.valueAxis.valueMax = -10
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 ###
@@ -907,931 +907,931 @@
 dataSample5 = [(10, 60), (20, 50), (30, 40), (40, 30)]
 
 def sampleV5a():
-	"A simple bar chart with no expressed spacing attributes."
+    "A simple bar chart with no expressed spacing attributes."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV5b():
-	"A simple bar chart with proportional spacing."
+    "A simple bar chart with proportional spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 0
-	bc.barWidth = 40
-	bc.groupSpacing = 20
-	bc.barSpacing = 10
+    bc.useAbsolute = 0
+    bc.barWidth = 40
+    bc.groupSpacing = 20
+    bc.barSpacing = 10
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV5c1():
-	"Make sampe simple bar chart but with absolute spacing."
+    "Make sampe simple bar chart but with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 40
-	bc.groupSpacing = 0
-	bc.barSpacing = 0
+    bc.useAbsolute = 1
+    bc.barWidth = 40
+    bc.groupSpacing = 0
+    bc.barSpacing = 0
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV5c2():
-	"Make sampe simple bar chart but with absolute spacing."
+    "Make sampe simple bar chart but with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 40
-	bc.groupSpacing = 20
-	bc.barSpacing = 0
+    bc.useAbsolute = 1
+    bc.barWidth = 40
+    bc.groupSpacing = 20
+    bc.barSpacing = 0
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV5c3():
-	"Make sampe simple bar chart but with absolute spacing."
+    "Make sampe simple bar chart but with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 40
-	bc.groupSpacing = 0
-	bc.barSpacing = 10
+    bc.useAbsolute = 1
+    bc.barWidth = 40
+    bc.groupSpacing = 0
+    bc.barSpacing = 10
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleV5c4():
-	"Make sampe simple bar chart but with absolute spacing."
+    "Make sampe simple bar chart but with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 40
-	bc.groupSpacing = 20
-	bc.barSpacing = 10
+    bc.useAbsolute = 1
+    bc.barWidth = 40
+    bc.groupSpacing = 20
+    bc.barSpacing = 10
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'n'
-	bc.categoryAxis.labels.dy = -5
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'n'
+    bc.categoryAxis.labels.dy = -5
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 # Horizontal samples
 
 def sampleH0a():
-	"Make a slightly pathologic bar chart with only TWO data items."
+    "Make a slightly pathologic bar chart with only TWO data items."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'se'
-	bc.categoryAxis.labels.angle = 30
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'se'
+    bc.categoryAxis.labels.angle = 30
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH0b():
-	"Make a pathologic bar chart with only ONE data item."
+    "Make a pathologic bar chart with only ONE data item."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(42,)]
+    data = [(42,)]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 50
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 50
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'se'
-	bc.categoryAxis.labels.angle = 30
-	bc.categoryAxis.categoryNames = ['Jan-99']
+    bc.categoryAxis.labels.boxAnchor = 'se'
+    bc.categoryAxis.labels.angle = 30
+    bc.categoryAxis.categoryNames = ['Jan-99']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH0c():
-	"Make a really pathologic bar chart with NO data items at all!"
+    "Make a really pathologic bar chart with NO data items at all!"
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [()]
+    data = [()]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'se'
-	bc.categoryAxis.labels.angle = 30
-	bc.categoryAxis.categoryNames = []
+    bc.categoryAxis.labels.boxAnchor = 'se'
+    bc.categoryAxis.labels.angle = 30
+    bc.categoryAxis.categoryNames = []
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH1():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [
-			(13, 5, 20, 22, 37, 45, 19, 4),
-			(14, 6, 21, 23, 38, 46, 20, 5)
-			]
+    data = [
+            (13, 5, 20, 22, 37, 45, 19, 4),
+            (14, 6, 21, 23, 38, 46, 20, 5)
+            ]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
-	catNames = map(lambda n:n+'-99', catNames)
-	bc.categoryAxis.categoryNames = catNames
-	drawing.add(bc)
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
+    catNames = map(lambda n:n+'-99', catNames)
+    bc.categoryAxis.categoryNames = catNames
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH2a():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	data = [(2.4, -5.7, 2, 5, 9.2),
-			(0.6, -4.9, -3, 4, 6.8)
-			]
+    data = [(2.4, -5.7, 2, 5, 9.2),
+            (0.6, -4.9, -3, 4, 6.8)
+            ]
 
-	labels = ("Q3 2000", "Year to Date", "12 months",
-			  "Annualised\n3 years", "Since 07.10.99")
+    labels = ("Q3 2000", "Year to Date", "12 months",
+              "Annualised\n3 years", "Since 07.10.99")
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = HorizontalBarChart()
-	bc.x = 80
-	bc.y = 50
-	bc.height = 120
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 80
+    bc.y = 50
+    bc.height = 120
+    bc.width = 300
+    bc.data = data
 
-	bc.barSpacing = 0
-	bc.groupSpacing = 10
-	bc.barWidth = 10
+    bc.barSpacing = 0
+    bc.groupSpacing = 10
+    bc.barWidth = 10
 
-	bc.valueAxis.valueMin = -15
-	bc.valueAxis.valueMax = +15
-	bc.valueAxis.valueStep = 5
-	bc.valueAxis.labels.fontName = 'Helvetica'
-	bc.valueAxis.labels.fontSize = 8
-	bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
-	bc.valueAxis.labels.textAnchor = 'middle'
-	bc.valueAxis.configure(bc.data)
+    bc.valueAxis.valueMin = -15
+    bc.valueAxis.valueMax = +15
+    bc.valueAxis.valueStep = 5
+    bc.valueAxis.labels.fontName = 'Helvetica'
+    bc.valueAxis.labels.fontSize = 8
+    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
+    bc.valueAxis.labels.textAnchor = 'middle'
+    bc.valueAxis.configure(bc.data)
 
-	bc.categoryAxis.categoryNames = labels
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 8
-	bc.categoryAxis.labels.dx = -150
+    bc.categoryAxis.categoryNames = labels
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 8
+    bc.categoryAxis.labels.dx = -150
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH2b():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	data = [(2.4, -5.7, 2, 5, 9.2),
-			(0.6, -4.9, -3, 4, 6.8)
-			]
+    data = [(2.4, -5.7, 2, 5, 9.2),
+            (0.6, -4.9, -3, 4, 6.8)
+            ]
 
-	labels = ("Q3 2000", "Year to Date", "12 months",
-			  "Annualised\n3 years", "Since 07.10.99")
+    labels = ("Q3 2000", "Year to Date", "12 months",
+              "Annualised\n3 years", "Since 07.10.99")
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = HorizontalBarChart()
-	bc.x = 80
-	bc.y = 50
-	bc.height = 120
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 80
+    bc.y = 50
+    bc.height = 120
+    bc.width = 300
+    bc.data = data
 
-	bc.barSpacing = 5
-	bc.groupSpacing = 10
-	bc.barWidth = 10
+    bc.barSpacing = 5
+    bc.groupSpacing = 10
+    bc.barWidth = 10
 
-	bc.valueAxis.valueMin = -15
-	bc.valueAxis.valueMax = +15
-	bc.valueAxis.valueStep = 5
-	bc.valueAxis.labels.fontName = 'Helvetica'
-	bc.valueAxis.labels.fontSize = 8
-	bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
-	bc.valueAxis.labels.textAnchor = 'middle'
+    bc.valueAxis.valueMin = -15
+    bc.valueAxis.valueMax = +15
+    bc.valueAxis.valueStep = 5
+    bc.valueAxis.labels.fontName = 'Helvetica'
+    bc.valueAxis.labels.fontSize = 8
+    bc.valueAxis.labels.boxAnchor = 'n'   # irrelevant (becomes 'c')
+    bc.valueAxis.labels.textAnchor = 'middle'
 
-	bc.categoryAxis.categoryNames = labels
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 8
-	bc.categoryAxis.labels.dx = -150
+    bc.categoryAxis.categoryNames = labels
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 8
+    bc.categoryAxis.labels.dx = -150
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH2c():
-	"Sample of multi-series bar chart."
+    "Sample of multi-series bar chart."
 
-	data = [(2.4, -5.7, 2, 5, 9.99),
-			(0.6, -4.9, -3, 4, 9.99)
-			]
+    data = [(2.4, -5.7, 2, 5, 9.99),
+            (0.6, -4.9, -3, 4, 9.99)
+            ]
 
-	labels = ("Q3 2000", "Year to Date", "12 months",
-			  "Annualised\n3 years", "Since 07.10.99")
+    labels = ("Q3 2000", "Year to Date", "12 months",
+              "Annualised\n3 years", "Since 07.10.99")
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = HorizontalBarChart()
-	bc.x = 80
-	bc.y = 50
-	bc.height = 120
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 80
+    bc.y = 50
+    bc.height = 120
+    bc.width = 300
+    bc.data = data
 
-	bc.barSpacing = 2
-	bc.groupSpacing = 10
-	bc.barWidth = 10
+    bc.barSpacing = 2
+    bc.groupSpacing = 10
+    bc.barWidth = 10
 
-	bc.valueAxis.valueMin = -15
-	bc.valueAxis.valueMax = +15
-	bc.valueAxis.valueStep = 5
-	bc.valueAxis.labels.fontName = 'Helvetica'
-	bc.valueAxis.labels.fontSize = 8
-	bc.valueAxis.labels.boxAnchor = 'n'
-	bc.valueAxis.labels.textAnchor = 'middle'
+    bc.valueAxis.valueMin = -15
+    bc.valueAxis.valueMax = +15
+    bc.valueAxis.valueStep = 5
+    bc.valueAxis.labels.fontName = 'Helvetica'
+    bc.valueAxis.labels.fontSize = 8
+    bc.valueAxis.labels.boxAnchor = 'n'
+    bc.valueAxis.labels.textAnchor = 'middle'
 
-	bc.categoryAxis.categoryNames = labels
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 8
-	bc.categoryAxis.labels.dx = -150
+    bc.categoryAxis.categoryNames = labels
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 8
+    bc.categoryAxis.labels.dx = -150
 
-	bc.barLabels.nudge = 10
+    bc.barLabels.nudge = 10
 
-	bc.barLabelFormat = '%0.2f'
-	bc.barLabels.dx = 0
-	bc.barLabels.dy = 0
-	bc.barLabels.boxAnchor = 'n'  # irrelevant (becomes 'c')
-	bc.barLabels.fontName = 'Helvetica'
-	bc.barLabels.fontSize = 6
+    bc.barLabelFormat = '%0.2f'
+    bc.barLabels.dx = 0
+    bc.barLabels.dy = 0
+    bc.barLabels.boxAnchor = 'n'  # irrelevant (becomes 'c')
+    bc.barLabels.fontName = 'Helvetica'
+    bc.barLabels.fontSize = 6
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH3():
-	"A really horizontal bar chart (compared to the equivalent faked one)."
+    "A really horizontal bar chart (compared to the equivalent faked one)."
 
-	names = ("UK Equities", "US Equities", "European Equities", "Japanese Equities",
-			  "Pacific (ex Japan) Equities", "Emerging Markets Equities",
-			  "UK Bonds", "Overseas Bonds", "UK Index-Linked", "Cash")
+    names = ("UK Equities", "US Equities", "European Equities", "Japanese Equities",
+              "Pacific (ex Japan) Equities", "Emerging Markets Equities",
+              "UK Bonds", "Overseas Bonds", "UK Index-Linked", "Cash")
 
-	series1 = (-1.5, 0.3, 0.5, 1.0, 0.8, 0.7, 0.4, 0.1, 1.0, 0.3)
-	series2 = (0.0, 0.33, 0.55, 1.1, 0.88, 0.77, 0.44, 0.11, 1.10, 0.33)
+    series1 = (-1.5, 0.3, 0.5, 1.0, 0.8, 0.7, 0.4, 0.1, 1.0, 0.3)
+    series2 = (0.0, 0.33, 0.55, 1.1, 0.88, 0.77, 0.44, 0.11, 1.10, 0.33)
 
-	assert len(names) == len(series1), "bad data"
-	assert len(names) == len(series2), "bad data"
+    assert len(names) == len(series1), "bad data"
+    assert len(names) == len(series2), "bad data"
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	bc = HorizontalBarChart()
-	bc.x = 100
-	bc.y = 20
-	bc.height = 150
-	bc.width = 250
-	bc.data = (series1,)
-	bc.bars.fillColor = colors.green
+    bc = HorizontalBarChart()
+    bc.x = 100
+    bc.y = 20
+    bc.height = 150
+    bc.width = 250
+    bc.data = (series1,)
+    bc.bars.fillColor = colors.green
 
-	bc.barLabelFormat = '%0.2f'
-	bc.barLabels.dx = 0
-	bc.barLabels.dy = 0
-	bc.barLabels.boxAnchor = 'w' # irrelevant (becomes 'c')
-	bc.barLabels.fontName = 'Helvetica'
-	bc.barLabels.fontSize = 6
-	bc.barLabels.nudge = 10
+    bc.barLabelFormat = '%0.2f'
+    bc.barLabels.dx = 0
+    bc.barLabels.dy = 0
+    bc.barLabels.boxAnchor = 'w' # irrelevant (becomes 'c')
+    bc.barLabels.fontName = 'Helvetica'
+    bc.barLabels.fontSize = 6
+    bc.barLabels.nudge = 10
 
-	bc.valueAxis.visible = 0
-	bc.valueAxis.valueMin = -2
-	bc.valueAxis.valueMax = +2
-	bc.valueAxis.valueStep = 1
+    bc.valueAxis.visible = 0
+    bc.valueAxis.valueMin = -2
+    bc.valueAxis.valueMax = +2
+    bc.valueAxis.valueStep = 1
 
-	bc.categoryAxis.tickLeft = 0
-	bc.categoryAxis.tickRight = 0
-	bc.categoryAxis.categoryNames = names
-	bc.categoryAxis.labels.boxAnchor = 'w'
-	bc.categoryAxis.labels.dx = -170
-	bc.categoryAxis.labels.fontName = 'Helvetica'
-	bc.categoryAxis.labels.fontSize = 6
+    bc.categoryAxis.tickLeft = 0
+    bc.categoryAxis.tickRight = 0
+    bc.categoryAxis.categoryNames = names
+    bc.categoryAxis.labels.boxAnchor = 'w'
+    bc.categoryAxis.labels.dx = -170
+    bc.categoryAxis.labels.fontName = 'Helvetica'
+    bc.categoryAxis.labels.fontSize = 6
 
-	g = Group(bc)
-	drawing.add(g)
+    g = Group(bc)
+    drawing.add(g)
 
-	return drawing
+    return drawing
 
 
 def sampleH4a():
-	"A bar chart showing value axis region starting at *exactly* zero."
+    "A bar chart showing value axis region starting at *exactly* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH4b():
-	"A bar chart showing value axis region starting *below* zero."
+    "A bar chart showing value axis region starting *below* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = -10
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = -10
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH4c():
-	"A bar chart showing value axis region starting *above* zero."
+    "A bar chart showing value axis region starting *above* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(13, 20)]
+    data = [(13, 20)]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 10
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 10
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH4d():
-	"A bar chart showing value axis region entirely *below* zero."
+    "A bar chart showing value axis region entirely *below* zero."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [(-13, -20)]
+    data = [(-13, -20)]
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
 
-	bc.strokeColor = colors.black
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = -30
-	bc.valueAxis.valueMax = -10
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = -30
+    bc.valueAxis.valueMax = -10
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 dataSample5 = [(10, 60), (20, 50), (30, 40), (40, 30)]
 
 def sampleH5a():
-	"A simple bar chart with no expressed spacing attributes."
+    "A simple bar chart with no expressed spacing attributes."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH5b():
-	"A simple bar chart with proportional spacing."
+    "A simple bar chart with proportional spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 0
-	bc.barWidth = 40
-	bc.groupSpacing = 20
-	bc.barSpacing = 10
+    bc.useAbsolute = 0
+    bc.barWidth = 40
+    bc.groupSpacing = 20
+    bc.barSpacing = 10
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH5c1():
-	"A simple bar chart with absolute spacing."
+    "A simple bar chart with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 10
-	bc.groupSpacing = 0
-	bc.barSpacing = 0
+    bc.useAbsolute = 1
+    bc.barWidth = 10
+    bc.groupSpacing = 0
+    bc.barSpacing = 0
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH5c2():
-	"Simple bar chart with absolute spacing."
+    "Simple bar chart with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 10
-	bc.groupSpacing = 20
-	bc.barSpacing = 0
+    bc.useAbsolute = 1
+    bc.barWidth = 10
+    bc.groupSpacing = 20
+    bc.barSpacing = 0
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH5c3():
-	"Simple bar chart with absolute spacing."
+    "Simple bar chart with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 20
-	bc.height = 155
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 20
+    bc.height = 155
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 10
-	bc.groupSpacing = 0
-	bc.barSpacing = 2
+    bc.useAbsolute = 1
+    bc.barWidth = 10
+    bc.groupSpacing = 0
+    bc.barSpacing = 2
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 
 def sampleH5c4():
-	"Simple bar chart with absolute spacing."
+    "Simple bar chart with absolute spacing."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = HorizontalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = HorizontalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.useAbsolute = 1
-	bc.barWidth = 10
-	bc.groupSpacing = 20
-	bc.barSpacing = 10
+    bc.useAbsolute = 1
+    bc.barWidth = 10
+    bc.groupSpacing = 20
+    bc.barSpacing = 10
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 def sampleSymbol1():
-	"Simple bar chart using symbol attribute."
+    "Simple bar chart using symbol attribute."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.barWidth = 10
-	bc.groupSpacing = 15
-	bc.barSpacing = 3
+    bc.barWidth = 10
+    bc.groupSpacing = 15
+    bc.barSpacing = 3
 
-	bc.valueAxis.valueMin = 0
-	bc.valueAxis.valueMax = 60
-	bc.valueAxis.valueStep = 15
+    bc.valueAxis.valueMin = 0
+    bc.valueAxis.valueMax = 60
+    bc.valueAxis.valueStep = 15
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	sym1 = ShadedRect()
-	sym1.fillColorStart = colors.black
-	sym1.fillColorEnd = colors.blue
-	sym1.orientation = 'horizontal'
-	sym1.strokeWidth = 0
+    sym1 = ShadedRect()
+    sym1.fillColorStart = colors.black
+    sym1.fillColorEnd = colors.blue
+    sym1.orientation = 'horizontal'
+    sym1.strokeWidth = 0
 
-	sym2 = ShadedRect()
-	sym2.fillColorStart = colors.black
-	sym2.fillColorEnd = colors.pink
-	sym2.orientation = 'horizontal'
-	sym2.strokeWidth = 0
+    sym2 = ShadedRect()
+    sym2.fillColorStart = colors.black
+    sym2.fillColorEnd = colors.pink
+    sym2.orientation = 'horizontal'
+    sym2.strokeWidth = 0
 
-	sym3 = ShadedRect()
-	sym3.fillColorStart = colors.blue
-	sym3.fillColorEnd = colors.white
-	sym3.orientation = 'vertical'
-	sym3.cylinderMode = 1
-	sym3.strokeWidth = 0
+    sym3 = ShadedRect()
+    sym3.fillColorStart = colors.blue
+    sym3.fillColorEnd = colors.white
+    sym3.orientation = 'vertical'
+    sym3.cylinderMode = 1
+    sym3.strokeWidth = 0
 
-	bc.bars.symbol = sym1
-	bc.bars[2].symbol = sym2
-	bc.bars[3].symbol = sym3
+    bc.bars.symbol = sym1
+    bc.bars[2].symbol = sym2
+    bc.bars[3].symbol = sym3
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 def sampleStacked1():
-	"Simple bar chart using symbol attribute."
+    "Simple bar chart using symbol attribute."
 
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = dataSample5
+    data = dataSample5
 
-	bc = VerticalBarChart()
-	bc.categoryAxis.style = 'stacked'
-	bc.x = 50
-	bc.y = 50
-	bc.height = 125
-	bc.width = 300
-	bc.data = data
-	bc.strokeColor = colors.black
+    bc = VerticalBarChart()
+    bc.categoryAxis.style = 'stacked'
+    bc.x = 50
+    bc.y = 50
+    bc.height = 125
+    bc.width = 300
+    bc.data = data
+    bc.strokeColor = colors.black
 
-	bc.barWidth = 10
-	bc.groupSpacing = 15
-	bc.valueAxis.valueMin = 0
+    bc.barWidth = 10
+    bc.groupSpacing = 15
+    bc.valueAxis.valueMin = 0
 
-	bc.categoryAxis.labels.boxAnchor = 'e'
-	bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+    bc.categoryAxis.labels.boxAnchor = 'e'
+    bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-	bc.bars.symbol = ShadedRect()
-	bc.bars.symbol.fillColorStart = colors.red
-	bc.bars.symbol.fillColorEnd = colors.white
-	bc.bars.symbol.orientation = 'vertical'
-	bc.bars.symbol.cylinderMode = 1
-	bc.bars.symbol.strokeWidth = 0
+    bc.bars.symbol = ShadedRect()
+    bc.bars.symbol.fillColorStart = colors.red
+    bc.bars.symbol.fillColorEnd = colors.white
+    bc.bars.symbol.orientation = 'vertical'
+    bc.bars.symbol.cylinderMode = 1
+    bc.bars.symbol.strokeWidth = 0
 
-	bc.bars[1].symbol = ShadedRect()
-	bc.bars[1].symbol.fillColorStart = colors.magenta
-	bc.bars[1].symbol.fillColorEnd = colors.white
-	bc.bars[1].symbol.orientation = 'vertical'
-	bc.bars[1].symbol.cylinderMode = 1
-	bc.bars[1].symbol.strokeWidth = 0
+    bc.bars[1].symbol = ShadedRect()
+    bc.bars[1].symbol.fillColorStart = colors.magenta
+    bc.bars[1].symbol.fillColorEnd = colors.white
+    bc.bars[1].symbol.orientation = 'vertical'
+    bc.bars[1].symbol.cylinderMode = 1
+    bc.bars[1].symbol.strokeWidth = 0
 
-	bc.bars[2].symbol = ShadedRect()
-	bc.bars[2].symbol.fillColorStart = colors.green
-	bc.bars[2].symbol.fillColorEnd = colors.white
-	bc.bars[2].symbol.orientation = 'vertical'
-	bc.bars[2].symbol.cylinderMode = 1
-	bc.bars[2].symbol.strokeWidth = 0
+    bc.bars[2].symbol = ShadedRect()
+    bc.bars[2].symbol.fillColorStart = colors.green
+    bc.bars[2].symbol.fillColorEnd = colors.white
+    bc.bars[2].symbol.orientation = 'vertical'
+    bc.bars[2].symbol.cylinderMode = 1
+    bc.bars[2].symbol.strokeWidth = 0
 
-	bc.bars[3].symbol = ShadedRect()
-	bc.bars[3].symbol.fillColorStart = colors.blue
-	bc.bars[3].symbol.fillColorEnd = colors.white
-	bc.bars[3].symbol.orientation = 'vertical'
-	bc.bars[3].symbol.cylinderMode = 1
-	bc.bars[3].symbol.strokeWidth = 0
+    bc.bars[3].symbol = ShadedRect()
+    bc.bars[3].symbol.fillColorStart = colors.blue
+    bc.bars[3].symbol.fillColorEnd = colors.white
+    bc.bars[3].symbol.orientation = 'vertical'
+    bc.bars[3].symbol.cylinderMode = 1
+    bc.bars[3].symbol.strokeWidth = 0
 
-	drawing.add(bc)
+    drawing.add(bc)
 
-	return drawing
+    return drawing
 
 #class version of function sampleH5c4 above
 class SampleH5c4(Drawing):
-	"Simple bar chart with absolute spacing."
+    "Simple bar chart with absolute spacing."
 
-	def __init__(self,width=400,height=200,*args,**kw):
-		apply(Drawing.__init__,(self,width,height)+args,kw)
-		bc = HorizontalBarChart()
-		bc.x = 50
-		bc.y = 50
-		bc.height = 125
-		bc.width = 300
-		bc.data = dataSample5
-		bc.strokeColor = colors.black
+    def __init__(self,width=400,height=200,*args,**kw):
+        apply(Drawing.__init__,(self,width,height)+args,kw)
+        bc = HorizontalBarChart()
+        bc.x = 50
+        bc.y = 50
+        bc.height = 125
+        bc.width = 300
+        bc.data = dataSample5
+        bc.strokeColor = colors.black
 
-		bc.useAbsolute = 1
-		bc.barWidth = 10
-		bc.groupSpacing = 20
-		bc.barSpacing = 10
+        bc.useAbsolute = 1
+        bc.barWidth = 10
+        bc.groupSpacing = 20
+        bc.barSpacing = 10
 
-		bc.valueAxis.valueMin = 0
-		bc.valueAxis.valueMax = 60
-		bc.valueAxis.valueStep = 15
+        bc.valueAxis.valueMin = 0
+        bc.valueAxis.valueMax = 60
+        bc.valueAxis.valueStep = 15
 
-		bc.categoryAxis.labels.boxAnchor = 'e'
-		bc.categoryAxis.categoryNames = ['Ying', 'Yang']
+        bc.categoryAxis.labels.boxAnchor = 'e'
+        bc.categoryAxis.categoryNames = ['Ying', 'Yang']
 
-		self.add(bc,name='HBC')
+        self.add(bc,name='HBC')
--- a/reportlab/graphics/charts/legends.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/graphics/charts/legends.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,10 +1,10 @@
 #copyright ReportLab Inc. 2000-2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/graphics/charts/legends.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/graphics/charts/legends.py,v 1.21 2002/07/03 10:22:29 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/graphics/charts/legends.py,v 1.22 2002/07/17 22:46:22 andy_robinson Exp $
 """This will be a collection of legends to be used with charts.
 """
-__version__=''' $Id: legends.py,v 1.21 2002/07/03 10:22:29 rgbecker Exp $ '''
+__version__=''' $Id: legends.py,v 1.22 2002/07/17 22:46:22 andy_robinson Exp $ '''
 
 import string, copy
 
@@ -17,256 +17,256 @@
 
 
 class Legend(Widget):
-	"""A simple legend containing rectangular swatches and strings.
+    """A simple legend containing rectangular swatches and strings.
 
-	The swatches are filled rectangles whenever the respective
-	color object in 'colorNamePairs' is a subclass of Color in
-	reportlab.lib.colors. Otherwise the object passed instead is
-	assumed to have 'x', 'y', 'width' and 'height' attributes.
-	A legend then tries to set them or catches any error. This
-	lets you plug-in any widget you like as a replacement for
-	the default rectangular swatches.
+    The swatches are filled rectangles whenever the respective
+    color object in 'colorNamePairs' is a subclass of Color in
+    reportlab.lib.colors. Otherwise the object passed instead is
+    assumed to have 'x', 'y', 'width' and 'height' attributes.
+    A legend then tries to set them or catches any error. This
+    lets you plug-in any widget you like as a replacement for
+    the default rectangular swatches.
 
-	Strings can be nicely aligned left or right to the swatches.
-	"""
-	
-	_attrMap = AttrMap(
-		x = AttrMapValue(isNumber, desc="x-coordinate of upper-left reference point"),
-		y = AttrMapValue(isNumber, desc="y-coordinate of upper-left reference point"),
-		deltax = AttrMapValue(isNumberOrNone, desc="x-distance between neighbouring swatches"),
-		deltay = AttrMapValue(isNumberOrNone, desc="y-distance between neighbouring swatches"),
-		dxTextSpace = AttrMapValue(isNumber, desc="Distance between swatch rectangle and text"),
-		autoXPadding = AttrMapValue(isNumber, desc="x Padding between columns if deltax=None"), 
-		autoYPadding = AttrMapValue(isNumber, desc="y Padding between rows if deltay=None"), 
-		dx = AttrMapValue(isNumber, desc="Width of swatch rectangle"),
-		dy = AttrMapValue(isNumber, desc="Height of swatch rectangle"),
-		columnMaximum = AttrMapValue(isNumber, desc="Max. number of items per column"),
-		alignment = AttrMapValue(OneOf("left", "right"), desc="Alignment of text with respect to swatches"),
-		colorNamePairs = AttrMapValue(None, desc="List of color/name tuples (color can also be widget)"),
-		fontName = AttrMapValue(isString, desc="Font name of the strings"),
-		fontSize = AttrMapValue(isNumber, desc="Font size of the strings"),
-		fillColor = AttrMapValue(isColorOrNone, desc=""),
-		strokeColor = AttrMapValue(isColorOrNone, desc="Border color of the swatches"),
-		strokeWidth = AttrMapValue(isNumber, desc="Width of the border color of the swatches"),
-		callout = AttrMapValue(None, desc="a user callout(self,g,x,y,(color,text))"),
-	   )
+    Strings can be nicely aligned left or right to the swatches.
+    """
+    
+    _attrMap = AttrMap(
+        x = AttrMapValue(isNumber, desc="x-coordinate of upper-left reference point"),
+        y = AttrMapValue(isNumber, desc="y-coordinate of upper-left reference point"),
+        deltax = AttrMapValue(isNumberOrNone, desc="x-distance between neighbouring swatches"),
+        deltay = AttrMapValue(isNumberOrNone, desc="y-distance between neighbouring swatches"),
+        dxTextSpace = AttrMapValue(isNumber, desc="Distance between swatch rectangle and text"),
+        autoXPadding = AttrMapValue(isNumber, desc="x Padding between columns if deltax=None"), 
+        autoYPadding = AttrMapValue(isNumber, desc="y Padding between rows if deltay=None"), 
+        dx = AttrMapValue(isNumber, desc="Width of swatch rectangle"),
+        dy = AttrMapValue(isNumber, desc="Height of swatch rectangle"),
+        columnMaximum = AttrMapValue(isNumber, desc="Max. number of items per column"),
+        alignment = AttrMapValue(OneOf("left", "right"), desc="Alignment of text with respect to swatches"),
+        colorNamePairs = AttrMapValue(None, desc="List of color/name tuples (color can also be widget)"),
+        fontName = AttrMapValue(isString, desc="Font name of the strings"),
+        fontSize = AttrMapValue(isNumber, desc="Font size of the strings"),
+        fillColor = AttrMapValue(isColorOrNone, desc=""),
+        strokeColor = AttrMapValue(isColorOrNone, desc="Border color of the swatches"),
+        strokeWidth = AttrMapValue(isNumber, desc="Width of the border color of the swatches"),
+        callout = AttrMapValue(None, desc="a user callout(self,g,x,y,(color,text))"),
+       )
 
-	def __init__(self):
-		# Upper-left reference point.
-		self.x = 0
-		self.y = 0
+    def __init__(self):
+        # Upper-left reference point.
+        self.x = 0
+        self.y = 0
 
-		# Alginment of text with respect to swatches.
-		self.alignment = "left"
+        # Alginment of text with respect to swatches.
+        self.alignment = "left"
 
-		# x- and y-distances between neighbouring swatches.
-		self.deltax = 75
-		self.deltay = 20
-		self.autoXPadding = 5
-		self.autoYPadding = 2
+        # x- and y-distances between neighbouring swatches.
+        self.deltax = 75
+        self.deltay = 20
+        self.autoXPadding = 5
+        self.autoYPadding = 2
 
-		# Size of swatch rectangle.
-		self.dx = 10
-		self.dy = 10
+        # Size of swatch rectangle.
+        self.dx = 10
+        self.dy = 10
 
-		# Distance between swatch rectangle and text.
-		self.dxTextSpace = 10
+        # Distance between swatch rectangle and text.
+        self.dxTextSpace = 10
 
-		# Max. number of items per column.
-		self.columnMaximum = 3
+        # Max. number of items per column.
+        self.columnMaximum = 3
 
-		# Color/name pairs.
-		self.colorNamePairs = [ (colors.red, "red"),
-								(colors.blue, "blue"),
-								(colors.green, "green"),
-								(colors.pink, "pink"),
-								(colors.yellow, "yellow") ]
+        # Color/name pairs.
+        self.colorNamePairs = [ (colors.red, "red"),
+                                (colors.blue, "blue"),
+                                (colors.green, "green"),
+                                (colors.pink, "pink"),
+                                (colors.yellow, "yellow") ]
 
-		# Font name and size of the labels.
-		self.fontName = STATE_DEFAULTS['fontName']
-		self.fontSize = STATE_DEFAULTS['fontSize']
-		self.fillColor = STATE_DEFAULTS['fillColor']
-		self.strokeColor = STATE_DEFAULTS['strokeColor']
-		self.strokeWidth = STATE_DEFAULTS['strokeWidth']
+        # Font name and size of the labels.
+        self.fontName = STATE_DEFAULTS['fontName']
+        self.fontSize = STATE_DEFAULTS['fontSize']
+        self.fillColor = STATE_DEFAULTS['fillColor']
+        self.strokeColor = STATE_DEFAULTS['strokeColor']
+        self.strokeWidth = STATE_DEFAULTS['strokeWidth']
 
-	def _calculateMaxWidth(self, colorNamePairs):
-		"Calculate the maximum width of some given strings."
-		m = 0
-		for t in map(lambda p:str(p[1]),colorNamePairs):
-			if t:
-				for s in string.split(t,'\n'):
-					m = max(m,stringWidth(s, self.fontName, self.fontSize))
-		return m
+    def _calculateMaxWidth(self, colorNamePairs):
+        "Calculate the maximum width of some given strings."
+        m = 0
+        for t in map(lambda p:str(p[1]),colorNamePairs):
+            if t:
+                for s in string.split(t,'\n'):
+                    m = max(m,stringWidth(s, self.fontName, self.fontSize))
+        return m
 
 
-	def _calcHeight(self):
-		deltay = self.deltay
-		dy = self.dy
-		thisy = upperlefty = self.y - dy
-		ascent=getFont(self.fontName).face.ascent/1000.
-		if ascent==0: ascent=0.718 # default (from helvetica)
-		leading = self.fontSize*1.2
-		columnCount = 0
-		count = 0
-		lowy = upperlefty
-		for None, name in colorNamePairs:
-			T = string.split(name and str(name) or '','\n')
-			S = []
-			# thisy+dy/2 = y+leading/2
-			y = thisy+(dy-ascent)*0.5-leading
-			newy = thisy-max(deltay,len(S)*leading)
-			lowy = min(y,newy)
-			if count == columnMaximum-1:
-				count = 0
-				thisy = upperlefty
-				columnCount = columnCount + 1
-			else:
-				thisy = newy
-				count = count+1
-		return upperlefty - lowy
+    def _calcHeight(self):
+        deltay = self.deltay
+        dy = self.dy
+        thisy = upperlefty = self.y - dy
+        ascent=getFont(self.fontName).face.ascent/1000.
+        if ascent==0: ascent=0.718 # default (from helvetica)
+        leading = self.fontSize*1.2
+        columnCount = 0
+        count = 0
+        lowy = upperlefty
+        for None, name in colorNamePairs:
+            T = string.split(name and str(name) or '','\n')
+            S = []
+            # thisy+dy/2 = y+leading/2
+            y = thisy+(dy-ascent)*0.5-leading
+            newy = thisy-max(deltay,len(S)*leading)
+            lowy = min(y,newy)
+            if count == columnMaximum-1:
+                count = 0
+                thisy = upperlefty
+                columnCount = columnCount + 1
+            else:
+                thisy = newy
+                count = count+1
+        return upperlefty - lowy
 
-	def draw(self):
-		g = Group()
-		colorNamePairs = self.colorNamePairs
-		thisx = upperleftx = self.x
-		thisy = upperlefty = self.y - self.dy
-		dx, dy, alignment, columnMaximum = self.dx, self.dy, self.alignment, self.columnMaximum
-		deltax, deltay, dxTextSpace = self.deltax, self.deltay, self.dxTextSpace
-		fontName, fontSize, fillColor = self.fontName, self.fontSize, self.fillColor
-		strokeWidth, strokeColor = self.strokeWidth, self.strokeColor
-		leading = fontSize*1.2
-		if not deltay:
-			deltay = max(dy,leading)+self.autoYPadding
-		if not deltax:
-			maxWidth = self._calculateMaxWidth(colorNamePairs)
-			deltax = maxWidth+dx+dxTextSpace+self.autoXPadding
-		else:
-			if alignment=='left': maxWidth = self._calculateMaxWidth(colorNamePairs)
+    def draw(self):
+        g = Group()
+        colorNamePairs = self.colorNamePairs
+        thisx = upperleftx = self.x
+        thisy = upperlefty = self.y - self.dy
+        dx, dy, alignment, columnMaximum = self.dx, self.dy, self.alignment, self.columnMaximum
+        deltax, deltay, dxTextSpace = self.deltax, self.deltay, self.dxTextSpace
+        fontName, fontSize, fillColor = self.fontName, self.fontSize, self.fillColor
+        strokeWidth, strokeColor = self.strokeWidth, self.strokeColor
+        leading = fontSize*1.2
+        if not deltay:
+            deltay = max(dy,leading)+self.autoYPadding
+        if not deltax:
+            maxWidth = self._calculateMaxWidth(colorNamePairs)
+            deltax = maxWidth+dx+dxTextSpace+self.autoXPadding
+        else:
+            if alignment=='left': maxWidth = self._calculateMaxWidth(colorNamePairs)
 
-		def gAdd(t,g=g,fontName=fontName,fontSize=fontSize,fillColor=fillColor):
-			t.fontName = fontName
-			t.fontSize = fontSize
-			t.fillColor = fillColor
-			return g.add(t)
+        def gAdd(t,g=g,fontName=fontName,fontSize=fontSize,fillColor=fillColor):
+            t.fontName = fontName
+            t.fontSize = fontSize
+            t.fillColor = fillColor
+            return g.add(t)
 
-		ascent=getFont(fontName).face.ascent/1000.
-		if ascent==0: ascent=0.718 # default (from helvetica)
-		ascent=ascent*fontSize # normalize
+        ascent=getFont(fontName).face.ascent/1000.
+        if ascent==0: ascent=0.718 # default (from helvetica)
+        ascent=ascent*fontSize # normalize
 
-		columnCount = 0
-		count = 0
-		callout = getattr(self,'callout',None)
-		for col, name in colorNamePairs:
-			T = string.split(name and str(name) or '','\n')
-			S = []
-			# thisy+dy/2 = y+leading/2
-			y = thisy+(dy-ascent)*0.5
-			if callout: callout(self,g,thisx,y,colorNamePairs[count])
-			if alignment == "left":
-				for t in T:
-					# align text to left
-					s = String(thisx+maxWidth,y,t)
-					s.textAnchor = "end"
-					S.append(s)
-					y = y-leading
-				x = thisx+maxWidth+dxTextSpace
-			elif alignment == "right":
-				for t in T:
-					# align text to right
-					s = String(thisx+dx+dxTextSpace, y, t)
-					s.textAnchor = "start"
-					S.append(s)
-					y = y-leading
-				x = thisx
-			else:
-				raise ValueError, "bad alignment"
+        columnCount = 0
+        count = 0
+        callout = getattr(self,'callout',None)
+        for col, name in colorNamePairs:
+            T = string.split(name and str(name) or '','\n')
+            S = []
+            # thisy+dy/2 = y+leading/2
+            y = thisy+(dy-ascent)*0.5
+            if callout: callout(self,g,thisx,y,colorNamePairs[count])
+            if alignment == "left":
+                for t in T:
+                    # align text to left
+                    s = String(thisx+maxWidth,y,t)
+                    s.textAnchor = "end"
+                    S.append(s)
+                    y = y-leading
+                x = thisx+maxWidth+dxTextSpace
+            elif alignment == "right":
+                for t in T:
+                    # align text to right
+                    s = String(thisx+dx+dxTextSpace, y, t)
+                    s.textAnchor = "start"
+                    S.append(s)
+                    y = y-leading
+                x = thisx
+            else:
+                raise ValueError, "bad alignment"
 
-			# Make a 'normal' color swatch...
-			if isinstance(col, colors.Color):
-				r = Rect(x, thisy, dx, dy)
-				r.fillColor = col
-				r.strokeColor = strokeColor
-				r.strokeWidth = strokeWidth
-				g.add(r)
-			else:
-				#try and see if we should do better.
-				try:
-					c = copy.deepcopy(col)
-					c.x = x
-					c.y = thisy
-					c.width = dx
-					c.height = dy
-					g.add(c)
-				except:
-					pass
+            # Make a 'normal' color swatch...
+            if isinstance(col, colors.Color):
+                r = Rect(x, thisy, dx, dy)
+                r.fillColor = col
+                r.strokeColor = strokeColor
+                r.strokeWidth = strokeWidth
+                g.add(r)
+            else:
+                #try and see if we should do better.
+                try:
+                    c = copy.deepcopy(col)
+                    c.x = x
+                    c.y = thisy
+                    c.width = dx
+                    c.height = dy
+                    g.add(c)
+                except:
+                    pass
 
-			map(gAdd,S)
+            map(gAdd,S)
 
-			if count%columnMaximum == columnMaximum-1:
-				thisx = thisx+deltax
-				thisy = upperlefty
-				columnCount = columnCount + 1
-			else:
-				thisy = thisy-max(deltay,len(S)*leading)
-			count = count+1
+            if count%columnMaximum == columnMaximum-1:
+                thisx = thisx+deltax
+                thisy = upperlefty
+                columnCount = columnCount + 1
+            else:
+                thisy = thisy-max(deltay,len(S)*leading)
+            count = count+1
 
-		return g
+        return g
 
 
-	def demo(self):
-		"Make sample legend."
+    def demo(self):
+        "Make sample legend."
 
-		d = Drawing(200, 100)
-		
-		legend = Legend()
-		legend.alignment = 'left'
-		legend.x = 0
-		legend.y = 100
-		legend.dxTextSpace = 5
-		items = string.split('red green blue yellow pink black white', ' ')
-		items = map(lambda i:(getattr(colors, i), i), items)
-		legend.colorNamePairs = items
+        d = Drawing(200, 100)
+        
+        legend = Legend()
+        legend.alignment = 'left'
+        legend.x = 0
+        legend.y = 100
+        legend.dxTextSpace = 5
+        items = string.split('red green blue yellow pink black white', ' ')
+        items = map(lambda i:(getattr(colors, i), i), items)
+        legend.colorNamePairs = items
 
-		d.add(legend, 'legend')
+        d.add(legend, 'legend')
 
-		return d
+        return d
 
 
 def sample1c():
-	"Make sample legend."
-	
-	d = Drawing(200, 100)
-	
-	legend = Legend()
-	legend.alignment = 'right'
-	legend.x = 0
-	legend.y = 100
-	legend.dxTextSpace = 5
-	items = string.split('red green blue yellow pink black white', ' ')
-	items = map(lambda i:(getattr(colors, i), i), items)
-	legend.colorNamePairs = items
+    "Make sample legend."
+    
+    d = Drawing(200, 100)
+    
+    legend = Legend()
+    legend.alignment = 'right'
+    legend.x = 0
+    legend.y = 100
+    legend.dxTextSpace = 5
+    items = string.split('red green blue yellow pink black white', ' ')
+    items = map(lambda i:(getattr(colors, i), i), items)
+    legend.colorNamePairs = items
 
-	d.add(legend, 'legend')
+    d.add(legend, 'legend')
 
-	return d
+    return d
 
 
 def sample2c():
-	"Make sample legend."
+    "Make sample legend."
 
-	d = Drawing(200, 100)
-	
-	legend = Legend()
-	legend.alignment = 'right'
-	legend.x = 20
-	legend.y = 90
-	legend.deltax = 60
-	legend.dxTextSpace = 10
-	legend.columnMaximum = 4
-	items = string.split('red green blue yellow pink black white', ' ')
-	items = map(lambda i:(getattr(colors, i), i), items)
-	legend.colorNamePairs = items
+    d = Drawing(200, 100)
+    
+    legend = Legend()
+    legend.alignment = 'right'
+    legend.x = 20
+    legend.y = 90
+    legend.deltax = 60
+    legend.dxTextSpace = 10
+    legend.columnMaximum = 4
+    items = string.split('red green blue yellow pink black white', ' ')
+    items = map(lambda i:(getattr(colors, i), i), items)
+    legend.colorNamePairs = items
 
-	d.add(legend, 'legend')
+    d.add(legend, 'legend')
 
-	return d
+    return d
--- a/reportlab/graphics/charts/linecharts.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/graphics/charts/linecharts.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,18 +1,18 @@
 #copyright ReportLab Inc. 2000-2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/graphics/charts/linecharts.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/graphics/charts/linecharts.py,v 1.22 2002/04/11 13:35:47 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/graphics/charts/linecharts.py,v 1.23 2002/07/17 22:46:22 andy_robinson Exp $
 """
 This modules defines a very preliminary Line Chart example.
 """
-__version__=''' $Id: linecharts.py,v 1.22 2002/04/11 13:35:47 rgbecker Exp $ '''
+__version__=''' $Id: linecharts.py,v 1.23 2002/07/17 22:46:22 andy_robinson Exp $ '''
 
 import string
 from types import FunctionType, StringType
 
 from reportlab.lib import colors
 from reportlab.lib.validators import isNumber, isColor, isColorOrNone, isListOfStrings, \
-									isListOfStringsOrNone, SequenceOf
+                                    isListOfStringsOrNone, SequenceOf
 from reportlab.lib.attrmap import *
 from reportlab.lib.formatters import Formatter
 from reportlab.graphics.widgetbase import Widget, TypedPropertyCollection, PropHolder
@@ -24,507 +24,507 @@
 
 
 class LineChartProperties(PropHolder):
-	_attrMap = AttrMap(
-		strokeWidth = AttrMapValue(isNumber, desc='Width of a line.'),
-		strokeColor = AttrMapValue(isColorOrNone, desc='Color of a line.'),
-		symbol = AttrMapValue(isSymbol, desc='Widget placed at data points.'),
-		)
+    _attrMap = AttrMap(
+        strokeWidth = AttrMapValue(isNumber, desc='Width of a line.'),
+        strokeColor = AttrMapValue(isColorOrNone, desc='Color of a line.'),
+        symbol = AttrMapValue(isSymbol, desc='Widget placed at data points.'),
+        )
 
 class LineChart(Widget):
-	pass
+    pass
 
 
 # This is conceptually similar to the VerticalBarChart.
 # Still it is better named HorizontalLineChart... :-/
 
 class HorizontalLineChart(LineChart):
-	"""Line chart with multiple lines.
+    """Line chart with multiple lines.
 
-	A line chart is assumed to have one category and one value axis.
-	Despite its generic name this particular line chart class has
-	a vertical value axis and a horizontal category one. It may
-	evolve into individual horizontal and vertical variants (like
-	with the existing bar charts).
+    A line chart is assumed to have one category and one value axis.
+    Despite its generic name this particular line chart class has
+    a vertical value axis and a horizontal category one. It may
+    evolve into individual horizontal and vertical variants (like
+    with the existing bar charts).
 
-	Available attributes are:
+    Available attributes are:
 
-		x: x-position of lower-left chart origin
-		y: y-position of lower-left chart origin
-		width: chart width
-		height: chart height
+        x: x-position of lower-left chart origin
+        y: y-position of lower-left chart origin
+        width: chart width
+        height: chart height
 
-		useAbsolute: disables auto-scaling of chart elements (?)
-		lineLabelNudge: distance of data labels to data points
-		lineLabels: labels associated with data values
-		lineLabelFormat: format string or callback function
-		groupSpacing: space between categories
+        useAbsolute: disables auto-scaling of chart elements (?)
+        lineLabelNudge: distance of data labels to data points
+        lineLabels: labels associated with data values
+        lineLabelFormat: format string or callback function
+        groupSpacing: space between categories
 
-		joinedLines: enables drawing of lines
+        joinedLines: enables drawing of lines
 
-		strokeColor: color of chart lines (?)
-		fillColor: color for chart background (?)
-		lines: style list, used cyclically for data series
+        strokeColor: color of chart lines (?)
+        fillColor: color for chart background (?)
+        lines: style list, used cyclically for data series
 
-		valueAxis: value axis object
-		categoryAxis: category axis object
-		categoryNames: category names
+        valueAxis: value axis object
+        categoryAxis: category axis object
+        categoryNames: category names
 
-		data: chart data, a list of data series of equal length
-	"""
+        data: chart data, a list of data series of equal length
+    """
 
-	_attrMap = AttrMap(
-		x = AttrMapValue(isNumber,
-			desc='X position of the lower-left corner of the chart.'),
-		y = AttrMapValue(isNumber,
-			desc='Y position of the lower-left corner of the chart.'),
-		width = AttrMapValue(isNumber,
-			desc='Width of the chart.'),
-		height = AttrMapValue(isNumber,
-			desc='Height of the chart.'),
+    _attrMap = AttrMap(
+        x = AttrMapValue(isNumber,
+            desc='X position of the lower-left corner of the chart.'),
+        y = AttrMapValue(isNumber,
+            desc='Y position of the lower-left corner of the chart.'),
+        width = AttrMapValue(isNumber,
+            desc='Width of the chart.'),
+        height = AttrMapValue(isNumber,
+            desc='Height of the chart.'),
 
-		useAbsolute = AttrMapValue(isNumber,
-			desc='Flag to use absolute spacing values.'),
-		lineLabelNudge = AttrMapValue(isNumber,
-			desc='Distance between a data point and its label.'),
-		lineLabels = AttrMapValue(None,
-			desc='Handle to the list of data point labels.'),
-		lineLabelFormat = AttrMapValue(None,
-			desc='Formatting string or function used for data point labels.'),
-		groupSpacing = AttrMapValue(isNumber,
-			desc='? - Likely to disappear.'),
+        useAbsolute = AttrMapValue(isNumber,
+            desc='Flag to use absolute spacing values.'),
+        lineLabelNudge = AttrMapValue(isNumber,
+            desc='Distance between a data point and its label.'),
+        lineLabels = AttrMapValue(None,
+            desc='Handle to the list of data point labels.'),
+        lineLabelFormat = AttrMapValue(None,
+            desc='Formatting string or function used for data point labels.'),
+        groupSpacing = AttrMapValue(isNumber,
+            desc='? - Likely to disappear.'),
 
-		joinedLines = AttrMapValue(isNumber,
-			desc='Display data points joined with lines if true.'),
+        joinedLines = AttrMapValue(isNumber,
+            desc='Display data points joined with lines if true.'),
 
-		strokeColor = AttrMapValue(isColorOrNone,
-			desc='Color used for background border of plot area.'),
-		fillColor = AttrMapValue(isColorOrNone,
-			desc='Color used for background interior of plot area.'),
+        strokeColor = AttrMapValue(isColorOrNone,
+            desc='Color used for background border of plot area.'),
+        fillColor = AttrMapValue(isColorOrNone,
+            desc='Color used for background interior of plot area.'),
 
-		lines = AttrMapValue(None,
-			desc='Handle of the lines.'),
+        lines = AttrMapValue(None,
+            desc='Handle of the lines.'),
 
-		valueAxis = AttrMapValue(None,
-			desc='Handle of the value axis.'),
-		categoryAxis = AttrMapValue(None,
-			desc='Handle of the category axis.'),
-		categoryNames = AttrMapValue(isListOfStringsOrNone,
-			desc='List of category names.'),
-		data = AttrMapValue(None,
-			desc='Data to be plotted, list of (lists of) numbers.'),
-		)
+        valueAxis = AttrMapValue(None,
+            desc='Handle of the value axis.'),
+        categoryAxis = AttrMapValue(None,
+            desc='Handle of the category axis.'),
+        categoryNames = AttrMapValue(isListOfStringsOrNone,
+            desc='List of category names.'),
+        data = AttrMapValue(None,
+            desc='Data to be plotted, list of (lists of) numbers.'),
+        )
 
-	def __init__(self):
-		self.x = 0
-		self.y = 0
-		self.width = 200
-		self.height = 100
+    def __init__(self):
+        self.x = 0
+        self.y = 0
+        self.width = 200
+        self.height = 100
 
-		# Allow for a bounding rectangle.
-		self.strokeColor = None
-		self.fillColor = None
+        # Allow for a bounding rectangle.
+        self.strokeColor = None
+        self.fillColor = None
 
-		# Named so we have less recoding for the horizontal one :-)
-		self.categoryAxis = XCategoryAxis()
-		self.valueAxis = YValueAxis()
+        # Named so we have less recoding for the horizontal one :-)
+        self.categoryAxis = XCategoryAxis()
+        self.valueAxis = YValueAxis()
 
-		# This defines two series of 3 points.	Just an example.
-		self.data = [(100,110,120,130),
-					 (70, 80, 80, 90)]
-		self.categoryNames = ('North','South','East','West')
+        # This defines two series of 3 points.  Just an example.
+        self.data = [(100,110,120,130),
+                     (70, 80, 80, 90)]
+        self.categoryNames = ('North','South','East','West')
 
-		self.lines = TypedPropertyCollection(LineChartProperties)
-		self.lines.strokeWidth = 1
-		self.lines[0].strokeColor = colors.red
-		self.lines[1].strokeColor = colors.green
-		self.lines[2].strokeColor = colors.blue
+        self.lines = TypedPropertyCollection(LineChartProperties)
+        self.lines.strokeWidth = 1
+        self.lines[0].strokeColor = colors.red
+        self.lines[1].strokeColor = colors.green
+        self.lines[2].strokeColor = colors.blue
 
-		# control spacing. if useAbsolute = 1 then
-		# the next parameters are in points; otherwise
-		# they are 'proportions' and are normalized to
-		# fit the available space.
-		self.useAbsolute = 0   #- not done yet
-		self.groupSpacing = 1 #5
+        # control spacing. if useAbsolute = 1 then
+        # the next parameters are in points; otherwise
+        # they are 'proportions' and are normalized to
+        # fit the available space.
+        self.useAbsolute = 0   #- not done yet
+        self.groupSpacing = 1 #5
 
-		self.lineLabels = TypedPropertyCollection(Label)
-		self.lineLabelFormat = None
+        self.lineLabels = TypedPropertyCollection(Label)
+        self.lineLabelFormat = None
 
-		# This says whether the origin is above or below
-		# the data point. +10 means put the origin ten points
-		# above the data point if value > 0, or ten
-		# points below if data value < 0.  This is different
-		# to label dx/dy which are not dependent on the
-		# sign of the data.
-		self.lineLabelNudge = 10
-		# If you have multiple series, by default they butt
-		# together.
+        # This says whether the origin is above or below
+        # the data point. +10 means put the origin ten points
+        # above the data point if value > 0, or ten
+        # points below if data value < 0.  This is different
+        # to label dx/dy which are not dependent on the
+        # sign of the data.
+        self.lineLabelNudge = 10
+        # If you have multiple series, by default they butt
+        # together.
 
-		# New line chart attributes.
-		self.joinedLines = 1 # Connect items with straight lines.
+        # New line chart attributes.
+        self.joinedLines = 1 # Connect items with straight lines.
 
 
-	def demo(self):
-		"""Shows basic use of a line chart."""
+    def demo(self):
+        """Shows basic use of a line chart."""
 
-		drawing = Drawing(200, 100)
+        drawing = Drawing(200, 100)
 
-		data = [
-				(13, 5, 20, 22, 37, 45, 19, 4),
-				(14, 10, 21, 28, 38, 46, 25, 5)
-				]
+        data = [
+                (13, 5, 20, 22, 37, 45, 19, 4),
+                (14, 10, 21, 28, 38, 46, 25, 5)
+                ]
 
-		lc = HorizontalLineChart()
+        lc = HorizontalLineChart()
 
-		lc.x = 20
-		lc.y = 10
-		lc.height = 85
-		lc.width = 170
-		lc.data = data
-		lc.lines.symbol = makeMarker('Circle')
+        lc.x = 20
+        lc.y = 10
+        lc.height = 85
+        lc.width = 170
+        lc.data = data
+        lc.lines.symbol = makeMarker('Circle')
 
-		drawing.add(lc)
+        drawing.add(lc)
 
-		return drawing
+        return drawing
 
 
-	def calcPositions(self):
-		"""Works out where they go.
+    def calcPositions(self):
+        """Works out where they go.
 
-		Sets an attribute _positions which is a list of
-		lists of (x, y) matching the data.
-		"""
+        Sets an attribute _positions which is a list of
+        lists of (x, y) matching the data.
+        """
 
-		self._seriesCount = len(self.data)
-		self._rowLength = max(map(len,self.data))
+        self._seriesCount = len(self.data)
+        self._rowLength = max(map(len,self.data))
 
-		if self.useAbsolute:
-			# Dimensions are absolute.
-			normFactor = 1.0
-		else:
-			# Dimensions are normalized to fit.
-			normWidth = self.groupSpacing
-			availWidth = self.categoryAxis.scale(0)[1]
-			normFactor = availWidth / normWidth
+        if self.useAbsolute:
+            # Dimensions are absolute.
+            normFactor = 1.0
+        else:
+            # Dimensions are normalized to fit.
+            normWidth = self.groupSpacing
+            availWidth = self.categoryAxis.scale(0)[1]
+            normFactor = availWidth / normWidth
 
-		self._positions = []
-		for rowNo in range(len(self.data)):
-			lineRow = []
-			for colNo in range(len(self.data[rowNo])):
-				datum = self.data[rowNo][colNo]
-				(groupX, groupWidth) = self.categoryAxis.scale(colNo)
-				x = groupX + (0.5 * self.groupSpacing * normFactor)
-				y = self.valueAxis.scale(0)
-				height = self.valueAxis.scale(datum) - y
-				lineRow.append((x, y+height))
-			self._positions.append(lineRow)
+        self._positions = []
+        for rowNo in range(len(self.data)):
+            lineRow = []
+            for colNo in range(len(self.data[rowNo])):
+                datum = self.data[rowNo][colNo]
+                (groupX, groupWidth) = self.categoryAxis.scale(colNo)
+                x = groupX + (0.5 * self.groupSpacing * normFactor)
+                y = self.valueAxis.scale(0)
+                height = self.valueAxis.scale(datum) - y
+                lineRow.append((x, y+height))
+            self._positions.append(lineRow)
 
 
-	def drawLabel(self, group, rowNo, colNo, x, y):
-		"Draw a label for a given item in the list."
+    def drawLabel(self, group, rowNo, colNo, x, y):
+        "Draw a label for a given item in the list."
 
-		labelFmt = self.lineLabelFormat
-		labelValue = self.data[rowNo][colNo]
+        labelFmt = self.lineLabelFormat
+        labelValue = self.data[rowNo][colNo]
 
-		if labelFmt is None:
-			labelText = None
-		elif type(labelFmt) is StringType:
-			labelText = labelFmt % labelValue
-		elif type(labelFmt) is FunctionType:
-			labelText = labelFmt(labelValue)
-		elif isinstance(labelFmt, Formatter):
-			labelText = labelFmt(labelValue)
-		else:
-			msg = "Unknown formatter type %s, expected string or function"
-			raise Exception, msg % labelFmt
+        if labelFmt is None:
+            labelText = None
+        elif type(labelFmt) is StringType:
+            labelText = labelFmt % labelValue
+        elif type(labelFmt) is FunctionType:
+            labelText = labelFmt(labelValue)
+        elif isinstance(labelFmt, Formatter):
+            labelText = labelFmt(labelValue)
+        else:
+            msg = "Unknown formatter type %s, expected string or function"
+            raise Exception, msg % labelFmt
 
-		if labelText:
-			label = self.lineLabels[(rowNo, colNo)]
-			# Make sure labels are some distance off the data point.
-			if y > 0:
-				label.setOrigin(x, y + self.lineLabelNudge)
-			else:
-				label.setOrigin(x, y - self.lineLabelNudge)
-			label.setText(labelText)
+        if labelText:
+            label = self.lineLabels[(rowNo, colNo)]
+            # Make sure labels are some distance off the data point.
+            if y > 0:
+                label.setOrigin(x, y + self.lineLabelNudge)
+            else:
+                label.setOrigin(x, y - self.lineLabelNudge)
+            label.setText(labelText)
 
-			group.add(label)
+            group.add(label)
 
 
-	def makeBackground(self):
-		g = Group()
+    def makeBackground(self):
+        g = Group()
 
-		g.add(Rect(self.x, self.y,
-				   self.width, self.height,
-				   strokeColor = self.strokeColor,
-				   fillColor= self.fillColor))
+        g.add(Rect(self.x, self.y,
+                   self.width, self.height,
+                   strokeColor = self.strokeColor,
+                   fillColor= self.fillColor))
 
-		return g
+        return g
 
 
-	def makeLines(self):
-		g = Group()
+    def makeLines(self):
+        g = Group()
 
-		labelFmt = self.lineLabelFormat
+        labelFmt = self.lineLabelFormat
 
-		# Iterate over data rows.
-		for rowNo in range(len(self._positions)):
-			row = self._positions[rowNo]
-			styleCount = len(self.lines)
-			styleIdx = rowNo % styleCount
-			rowStyle = self.lines[styleIdx]
+        # Iterate over data rows.
+        for rowNo in range(len(self._positions)):
+            row = self._positions[rowNo]
+            styleCount = len(self.lines)
+            styleIdx = rowNo % styleCount
+            rowStyle = self.lines[styleIdx]
 
-			if hasattr(self.lines[styleIdx], 'strokeWidth'):
-				strokeWidth = self.lines[styleIdx].strokeWidth
-			elif hasattr(self.lines, 'strokeWidth'):
-				strokeWidth = self.lines.strokeWidth
-			else:
-				strokeWidth = None
+            if hasattr(self.lines[styleIdx], 'strokeWidth'):
+                strokeWidth = self.lines[styleIdx].strokeWidth
+            elif hasattr(self.lines, 'strokeWidth'):
+                strokeWidth = self.lines.strokeWidth
+            else:
+                strokeWidth = None
 
-			# Iterate over data columns.
-			for colNo in range(len(row)):
-				x1, y1 = row[colNo]
-				if self.joinedLines == 1:
-					if colNo > 0:
-						# Draw lines between adjacent items.
-						x2, y2 = row[colNo-1]
-						line = Line(x1, y1, x2, y2)
-						line.strokeColor = rowStyle.strokeColor
-						line.strokeWidth = rowStyle.strokeWidth
-						g.add(line)
+            # Iterate over data columns.
+            for colNo in range(len(row)):
+                x1, y1 = row[colNo]
+                if self.joinedLines == 1:
+                    if colNo > 0:
+                        # Draw lines between adjacent items.
+                        x2, y2 = row[colNo-1]
+                        line = Line(x1, y1, x2, y2)
+                        line.strokeColor = rowStyle.strokeColor
+                        line.strokeWidth = rowStyle.strokeWidth
+                        g.add(line)
 
-			if hasattr(self.lines[styleIdx], 'symbol'):
-				uSymbol = self.lines[styleIdx].symbol
-			elif hasattr(self.lines, 'symbol'):
-				uSymbol = self.lines.symbol
-			else:
-				uSymbol = None
+            if hasattr(self.lines[styleIdx], 'symbol'):
+                uSymbol = self.lines[styleIdx].symbol
+            elif hasattr(self.lines, 'symbol'):
+                uSymbol = self.lines.symbol
+            else:
+                uSymbol = None
 
-			if uSymbol:
-				for colNo in range(len(row)):
-					x1, y1 = row[colNo]
-					symbol = uSymbol2Symbol(uSymbol,x1,y1,rowStyle.strokeColor)
-					if symbol: g.add(symbol)
+            if uSymbol:
+                for colNo in range(len(row)):
+                    x1, y1 = row[colNo]
+                    symbol = uSymbol2Symbol(uSymbol,x1,y1,rowStyle.strokeColor)
+                    if symbol: g.add(symbol)
 
-			# Draw item labels.
-			for colNo in range(len(row)):
-				x1, y1 = row[colNo]
-				self.drawLabel(g, rowNo, colNo, x1, y1)
+            # Draw item labels.
+            for colNo in range(len(row)):
+                x1, y1 = row[colNo]
+                self.drawLabel(g, rowNo, colNo, x1, y1)
 
-		return g
+        return g
 
 
-	def draw(self):
-		"Draws itself."
+    def draw(self):
+        "Draws itself."
 
-		vA, cA = self.valueAxis, self.categoryAxis
-		vA.setPosition(self.x, self.y, self.height)
-		vA.configure(self.data)
+        vA, cA = self.valueAxis, self.categoryAxis
+        vA.setPosition(self.x, self.y, self.height)
+        vA.configure(self.data)
 
-		# If zero is in chart, put x axis there, otherwise
-		# use bottom.
-		xAxisCrossesAt = vA.scale(0)
-		if ((xAxisCrossesAt > self.y + self.height) or (xAxisCrossesAt < self.y)):
-			y = self.y
-		else:
-			y = xAxisCrossesAt
+        # If zero is in chart, put x axis there, otherwise
+        # use bottom.
+        xAxisCrossesAt = vA.scale(0)
+        if ((xAxisCrossesAt > self.y + self.height) or (xAxisCrossesAt < self.y)):
+            y = self.y
+        else:
+            y = xAxisCrossesAt
 
-		cA.setPosition(self.x, y, self.width)
-		cA.configure(self.data)
+        cA.setPosition(self.x, y, self.width)
+        cA.configure(self.data)
 
-		self.calcPositions()
+        self.calcPositions()
 
-		g = Group()
+        g = Group()
 
-		g.add(cA)
-		g.add(vA)
-		g.add(self.makeBackground())
-		cA.makeGrid(g)
-		vA.makeGrid(g)
-		g.add(self.makeLines())
+        g.add(cA)
+        g.add(vA)
+        g.add(self.makeBackground())
+        cA.makeGrid(g)
+        vA.makeGrid(g)
+        g.add(self.makeLines())
 
-		return g
+        return g
 
 
 class VerticalLineChart(LineChart):
-	pass
+    pass
 
 
 def sample1():
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [
-			(13, 5, 20, 22, 37, 45, 19, 4),
-			(5, 20, 46, 38, 23, 21, 6, 14)
-			]
+    data = [
+            (13, 5, 20, 22, 37, 45, 19, 4),
+            (5, 20, 46, 38, 23, 21, 6, 14)
+            ]
 
-	lc = HorizontalLineChart()
+    lc = HorizontalLineChart()
 
-	lc.x = 50
-	lc.y = 50
-	lc.height = 125
-	lc.width = 300
-	lc.data = data
-	lc.joinedLines = 1
-	lc.lines.symbol = makeMarker('FilledDiamond')
-	lc.lineLabelFormat = '%2.0f'
+    lc.x = 50
+    lc.y = 50
+    lc.height = 125
+    lc.width = 300
+    lc.data = data
+    lc.joinedLines = 1
+    lc.lines.symbol = makeMarker('FilledDiamond')
+    lc.lineLabelFormat = '%2.0f'
 
-	catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
-	lc.categoryAxis.categoryNames = catNames
-	lc.categoryAxis.labels.boxAnchor = 'n'
+    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
+    lc.categoryAxis.categoryNames = catNames
+    lc.categoryAxis.labels.boxAnchor = 'n'
 
-	lc.valueAxis.valueMin = 0
-	lc.valueAxis.valueMax = 60
-	lc.valueAxis.valueStep = 15
+    lc.valueAxis.valueMin = 0
+    lc.valueAxis.valueMax = 60
+    lc.valueAxis.valueStep = 15
 
-	drawing.add(lc)
+    drawing.add(lc)
 
-	return drawing
+    return drawing
 
 
 class SampleHorizontalLineChart(HorizontalLineChart):
-	"Sample class overwriting one method to draw additional horizontal lines."
+    "Sample class overwriting one method to draw additional horizontal lines."
 
-	def demo(self):
-		"""Shows basic use of a line chart."""
+    def demo(self):
+        """Shows basic use of a line chart."""
 
-		drawing = Drawing(200, 100)
+        drawing = Drawing(200, 100)
 
-		data = [
-				(13, 5, 20, 22, 37, 45, 19, 4),
-				(14, 10, 21, 28, 38, 46, 25, 5)
-				]
+        data = [
+                (13, 5, 20, 22, 37, 45, 19, 4),
+                (14, 10, 21, 28, 38, 46, 25, 5)
+                ]
 
-		lc = SampleHorizontalLineChart()
+        lc = SampleHorizontalLineChart()
 
-		lc.x = 20
-		lc.y = 10
-		lc.height = 85
-		lc.width = 170
-		lc.data = data
-		lc.strokeColor = colors.white
-		lc.fillColor = colors.HexColor(0xCCCCCC)
+        lc.x = 20
+        lc.y = 10
+        lc.height = 85
+        lc.width = 170
+        lc.data = data
+        lc.strokeColor = colors.white
+        lc.fillColor = colors.HexColor(0xCCCCCC)
 
-		drawing.add(lc)
+        drawing.add(lc)
 
-		return drawing
+        return drawing
 
 
-	def makeBackground(self):
-		g = Group()
+    def makeBackground(self):
+        g = Group()
 
-		g.add(HorizontalLineChart.makeBackground(self))
+        g.add(HorizontalLineChart.makeBackground(self))
 
-		valAxis = self.valueAxis
-		valTickPositions = valAxis._tickValues
+        valAxis = self.valueAxis
+        valTickPositions = valAxis._tickValues
 
-		for y in valTickPositions:
-			y = valAxis.scale(y)
-			g.add(Line(self.x, y, self.x+self.width, y,
-					   strokeColor = self.strokeColor))
+        for y in valTickPositions:
+            y = valAxis.scale(y)
+            g.add(Line(self.x, y, self.x+self.width, y,
+                       strokeColor = self.strokeColor))
 
-		return g
+        return g
 
 
 
 def sample1a():
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [
-			(13, 5, 20, 22, 37, 45, 19, 4),
-			(5, 20, 46, 38, 23, 21, 6, 14)
-			]
+    data = [
+            (13, 5, 20, 22, 37, 45, 19, 4),
+            (5, 20, 46, 38, 23, 21, 6, 14)
+            ]
 
-	lc = SampleHorizontalLineChart()
+    lc = SampleHorizontalLineChart()
 
-	lc.x = 50
-	lc.y = 50
-	lc.height = 125
-	lc.width = 300
-	lc.data = data
-	lc.joinedLines = 1
-	lc.strokeColor = colors.white
-	lc.fillColor = colors.HexColor(0xCCCCCC)
-	lc.lines.symbol = makeMarker('FilledDiamond')
-	lc.lineLabelFormat = '%2.0f'
+    lc.x = 50
+    lc.y = 50
+    lc.height = 125
+    lc.width = 300
+    lc.data = data
+    lc.joinedLines = 1
+    lc.strokeColor = colors.white
+    lc.fillColor = colors.HexColor(0xCCCCCC)
+    lc.lines.symbol = makeMarker('FilledDiamond')
+    lc.lineLabelFormat = '%2.0f'
 
-	catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
-	lc.categoryAxis.categoryNames = catNames
-	lc.categoryAxis.labels.boxAnchor = 'n'
+    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
+    lc.categoryAxis.categoryNames = catNames
+    lc.categoryAxis.labels.boxAnchor = 'n'
 
-	lc.valueAxis.valueMin = 0
-	lc.valueAxis.valueMax = 60
-	lc.valueAxis.valueStep = 15
+    lc.valueAxis.valueMin = 0
+    lc.valueAxis.valueMax = 60
+    lc.valueAxis.valueStep = 15
 
-	drawing.add(lc)
+    drawing.add(lc)
 
-	return drawing
+    return drawing
 
 
 def sample2():
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [
-			(13, 5, 20, 22, 37, 45, 19, 4),
-			(5, 20, 46, 38, 23, 21, 6, 14)
-			]
+    data = [
+            (13, 5, 20, 22, 37, 45, 19, 4),
+            (5, 20, 46, 38, 23, 21, 6, 14)
+            ]
 
-	lc = HorizontalLineChart()
+    lc = HorizontalLineChart()
 
-	lc.x = 50
-	lc.y = 50
-	lc.height = 125
-	lc.width = 300
-	lc.data = data
-	lc.joinedLines = 1
-	lc.lines.symbol = makeMarker('Smiley')
-	lc.lineLabelFormat = '%2.0f'
-	lc.strokeColor = colors.black
-	lc.fillColor = colors.lightblue
+    lc.x = 50
+    lc.y = 50
+    lc.height = 125
+    lc.width = 300
+    lc.data = data
+    lc.joinedLines = 1
+    lc.lines.symbol = makeMarker('Smiley')
+    lc.lineLabelFormat = '%2.0f'
+    lc.strokeColor = colors.black
+    lc.fillColor = colors.lightblue
 
-	catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
-	lc.categoryAxis.categoryNames = catNames
-	lc.categoryAxis.labels.boxAnchor = 'n'
+    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
+    lc.categoryAxis.categoryNames = catNames
+    lc.categoryAxis.labels.boxAnchor = 'n'
 
-	lc.valueAxis.valueMin = 0
-	lc.valueAxis.valueMax = 60
-	lc.valueAxis.valueStep = 15
+    lc.valueAxis.valueMin = 0
+    lc.valueAxis.valueMax = 60
+    lc.valueAxis.valueStep = 15
 
-	drawing.add(lc)
+    drawing.add(lc)
 
-	return drawing
+    return drawing
 
 
 def sample3():
-	drawing = Drawing(400, 200)
+    drawing = Drawing(400, 200)
 
-	data = [
-			(13, 5, 20, 22, 37, 45, 19, 4),
-			(5, 20, 46, 38, 23, 21, 6, 14)
-			]
+    data = [
+            (13, 5, 20, 22, 37, 45, 19, 4),
+            (5, 20, 46, 38, 23, 21, 6, 14)
+            ]
 
-	lc = HorizontalLineChart()
+    lc = HorizontalLineChart()
 
-	lc.x = 50
-	lc.y = 50
-	lc.height = 125
-	lc.width = 300
-	lc.data = data
-	lc.joinedLines = 1
-	lc.lineLabelFormat = '%2.0f'
-	lc.strokeColor = colors.black
+    lc.x = 50
+    lc.y = 50
+    lc.height = 125
+    lc.width = 300
+    lc.data = data
+    lc.joinedLines = 1
+    lc.lineLabelFormat = '%2.0f'
+    lc.strokeColor = colors.black
 
-	lc.lines[0].symbol = makeMarker('Smiley')
-	lc.lines[1].symbol = NoEntry
-	lc.lines[0].strokeWidth = 2
-	lc.lines[1].strokeWidth = 4
+    lc.lines[0].symbol = makeMarker('Smiley')
+    lc.lines[1].symbol = NoEntry
+    lc.lines[0].strokeWidth = 2
+    lc.lines[1].strokeWidth = 4
 
-	catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
-	lc.categoryAxis.categoryNames = catNames
-	lc.categoryAxis.labels.boxAnchor = 'n'
+    catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
+    lc.categoryAxis.categoryNames = catNames
+    lc.categoryAxis.labels.boxAnchor = 'n'
 
-	lc.valueAxis.valueMin = 0
-	lc.valueAxis.valueMax = 60
-	lc.valueAxis.valueStep = 15
+    lc.valueAxis.valueMin = 0
+    lc.valueAxis.valueMax = 60
+    lc.valueAxis.valueStep = 15
 
-	drawing.add(lc)
+    drawing.add(lc)
 
-	return drawing
+    return drawing
--- a/reportlab/graphics/charts/lineplots.py	Wed Jul 17 22:12:13 2002 +0000
+++ b/reportlab/graphics/charts/lineplots.py	Wed Jul 17 22:46:24 2002 +0000
@@ -1,10 +1,10 @@
 #copyright ReportLab Inc. 2000-2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/graphics/charts/lineplots.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/graphics/charts/lineplots.py,v 1.31 2002/05/24 15:47:19 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/graphics/charts/lineplots.py,v 1.32 2002/07/17 22:46:22 andy_robinson Exp $
 """This module defines a very preliminary Line Plot example.
 """
-__version__=''' $Id: lineplots.py,v 1.31 2002/05/24 15:47:19 rgbecker Exp $ '''
+__version__=''' $Id: lineplots.py,v 1.32 2002/07/17 22:46:22 andy_robinson Exp $ '''
 
 import string, time
 from types import FunctionType
@@ -23,298 +23,298 @@
 
 # This might be moved again from here...
 class LinePlotProperties(PropHolder):
-	_attrMap = AttrMap(
-		strokeWidth = AttrMapValue(isNumber,
-			desc='Width of a line.'),
-		strokeColor = AttrMapValue(isColorOrNone,
-			desc='Color of a line.'),
-		strokeDashArray = AttrMapValue(isListOfNumbersOrNone,
-			desc='Dash array of a line.'),
-		symbol = AttrMapValue(None,
-			desc='Widget placed at data points.'),
-		)
+    _attrMap = AttrMap(
+        strokeWidth = AttrMapValue(isNumber,
+            desc='Width of a line.'),
+        strokeColor = AttrMapValue(isColorOrNone,
+            desc='Color of a line.'),
+        strokeDashArray = AttrMapValue(isListOfNumbersOrNone,
+            desc='Dash array of a line.'),
+        symbol = AttrMapValue(None,
+            desc='Widget placed at data points.'),
+        )
 
 
 class LinePlot(Widget):
-	"""Line plot with multiple lines.
+    """Line plot with multiple lines.
 
-	Both x- and y-axis are value axis (so there are no seperate
-	X and Y versions of this class).
-	"""
+    Both x- and y-axis are value axis (so there are no seperate
+    X and Y versions of this class).
+    """
 
-	_attrMap = AttrMap(
-		debug = AttrMapValue(isNumber,
-			desc='Used only for debugging.'),
-		x = AttrMapValue(isNumber, desc='X position of the lower-left corner of the chart.'),
-		y = AttrMapValue(isNumber, desc='Y position of the lower-left corner of the chart.'),
-		reversePlotOrder = AttrMapValue(isBoolean, desc='If true reverse plot order.'),
-		width = AttrMapValue(isNumber, desc='Width of the chart.'),
-		height = AttrMapValue(isNumber, desc='Height of the chart.'),
-		lineLabelNudge = AttrMapValue(isNumber,
-			desc='Distance between a data point and its label.'),
-		lineLabels = AttrMapValue(None,
-			desc='Handle to the list of data point labels.'),
-		lineLabelFormat = AttrMapValue(None,
-			desc='Formatting string or function used for data point labels.'),
-		joinedLines = AttrMapValue(isNumber,
-			desc='Display data points joined with lines if true.'),
-		strokeColor = AttrMapValue(isColorOrNone,
-			desc='Color used for background border of plot area.'),
-		fillColor = AttrMapValue(isColorOrNone,
-			desc='Color used for background interior of plot area.'),
-		lines = AttrMapValue(None,
-			desc='Handle of the lines.'),
-		xValueAxis = AttrMapValue(None,
-			desc='Handle of the x axis.'),
-		yValueAxis = AttrMapValue(None,
-			desc='Handle of the y axis.'),
-		data = AttrMapValue(None,
-			desc='Data to be plotted, list of (lists of) x/y tuples.'),
-		)
+    _attrMap = AttrMap(
+        debug = AttrMapValue(isNumber,
+            desc='Used only for debugging.'),
+        x = AttrMapValue(isNumber, desc='X position of the lower-left corner of the chart.'),
+        y = AttrMapValue(isNumber, desc='Y position of the lower-left corner of the chart.'),
+        reversePlotOrder = AttrMapValue(isBoolean, desc='If true reverse plot order.'),
+        width = AttrMapValue(isNumber, desc='Width of the chart.'),
+        height = AttrMapValue(isNumber, desc='Height of the chart.'),
+        lineLabelNudge = AttrMapValue(isNumber,
+            desc='Distance between a data point and its label.'),
+        lineLabels = AttrMapValue(None,
+            desc='Handle to the list of data point labels.'),
+        lineLabelFormat = AttrMapValue(None,
+            desc='Formatting string or function used for data point labels.'),
+        joinedLines = AttrMapValue(isNumber,
+            desc='Display data points joined with lines if true.'),
+        strokeColor = AttrMapValue(isColorOrNone,
+            desc='Color used for background border of plot area.'),
+        fillColor = AttrMapValue(isColorOrNone,
+            desc='Color used for background interior of plot area.'),
+        lines = AttrMapValue(None,
+            desc='Handle of the lines.'),
+        xValueAxis = AttrMapValue(None,
+            desc='Handle of the x axis.'),
+        yValueAxis = AttrMapValue(None,
+            desc='Handle of the y axis.'),
+        data = AttrMapValue(None,
+            desc='Data to be plotted, list of (lists of) x/y tuples.'),
+        )
 
-	def __init__(self):
-		self.debug = 0
+    def __init__(self):
+        self.debug = 0
 
-		self.x = 0
-		self.y = 0
-		self.reversePlotOrder = 0
-		self.width = 200
-		self.height = 100
+        self.x = 0
+        self.y = 0
+        self.reversePlotOrder = 0
+        self.width = 200
+        self.height = 100
 
-		# allow for a bounding rectangle
-		self.strokeColor = None
-		self.fillColor = None
+        # allow for a bounding rectangle
+        self.strokeColor = None
+        self.fillColor = None
 
-		self.xValueAxis = XValueAxis()
-		self.yValueAxis = YValueAxis()
+        self.xValueAxis = XValueAxis()
+        self.yValueAxis = YValueAxis()
 
-		# this defines two series of 3 points.	Just an example.
-		self.data = [
-			((1,1), (2,2), (2.5,1), (3,3), (4,5)),
-			((1,2), (2,3), (2.5,2), (3,4), (4,6))
-			]
+        # this defines two series of 3 points.  Just an example.
+        self.data = [
+            ((1,1), (2,2), (2.5,1), (3,3), (4,5)),
+            ((1,2), (2,3), (2.5,2), (3,4), (4,6))
+            ]
 
-		self.lines = TypedPropertyCollection(LinePlotProperties)
-		self.lines.strokeWidth = 1
-		self.lines[0].strokeColor = colors.red
-		self.lines[1].strokeColor = colors.blue
+        self.lines = TypedPropertyCollection(LinePlotProperties)
+        self.lines.strokeWidth = 1
+        self.lines[0].strokeColor = colors.red
+        self.lines[1].strokeColor = colors.blue
 
-		self.lineLabels = TypedPropertyCollection(Label)
-		self.lineLabelFormat = None
+        self.lineLabels = TypedPropertyCollection(Label)
+        self.lineLabelFormat = None
 
-		# this says whether the origin is inside or outside
-		# the bar - +10 means put the origin ten points
-		# above the tip of the bar if value > 0, or ten
-		# points inside if bar value < 0.  This is different
-		# to label dx/dy which are not dependent on the
-		# sign of the data.
-		self.lineLabelNudge = 10
-		# if you have multiple series, by default they butt
-		# together.
+        # this says whether the origin is inside or outside
+        # the bar - +10 means put the origin ten points
+        # above the tip of the bar if value > 0, or ten
+        # points inside if bar value < 0.  This is different
+        # to label dx/dy which are not dependent on the
+        # sign of the data.
+        self.lineLabelNudge = 10
+        # if you have multiple series, by default they butt
+        # together.
 
-		# New line chart attributes.
-		self.joinedLines = 1 # Connect items with straight lines.
+        # New line chart attributes.
+        self.joinedLines = 1 # Connect items with straight lines.
 
-	def demo(self):
-		"""Shows basic use of a line chart."""
+    def demo(self):
+        """Shows basic use of a line chart."""
 
-		drawing = Drawing(400, 200)
+        drawing = Drawing(400, 200)
 
-		data = [
-			((1,1), (2,2), (2.5,1), (3,3), (4,5)),
-			((1,2), (2,3), (2.5,2), (3.5,5), (4,6))
-			]
+        data = [
+            ((1,1), (2,2), (2.5,1), (3,3), (4,5)),
+            ((1,2), (2,3), (2.5,2), (3.5,5), (4,6))
+            ]
 
-		lp = LinePlot()
+        lp = LinePlot()
 
-		lp.x = 50
-		lp.y = 50
-		lp.height = 125
-		lp.width = 300
-		lp.data = data
-		lp.joinedLines = 1
-		lp.lineLabelFormat = '%2.0f'
-		lp.strokeColor = colors.black
+        lp.x = 50
+        lp.y = 50
+        lp.height = 125
+        lp.width = 300
+        lp.data = data
+        lp.joinedLines = 1
+        lp.lineLabelFormat = '%2.0f'
+        lp.strokeColor = colors.black
 
-		lp.lines[0].strokeColor = colors.red
-		lp.lines[0].symbol = makeMarker('FilledCircle')
-		lp.lines[1].strokeColor = colors.blue
-		lp.lines[1].symbol = makeMarker('FilledDiamond')
+        lp.lines[0].strokeColor = colors.red
+        lp.lines[0].symbol = makeMarker('FilledCircle')
+        lp.lines[1].strokeColor = colors.blue
+        lp.lines[1].symbol = makeMarker('FilledDiamond')
 
-		lp.xValueAxis.valueMin = 0
-		lp.xValueAxis.valueMax = 5
-		lp.xValueAxis.valueStep = 1
+        lp.xValueAxis.valueMin = 0
+        lp.xValueAxis.valueMax = 5
+        lp.xValueAxis.valueStep = 1
 
-		lp.yValueAxis.valueMin = 0
-		lp.yValueAxis.valueMax = 7
-		lp.yValueAxis.valueStep = 1
+        lp.yValueAxis.valueMin = 0
+        lp.yValueAxis.valueMax = 7
+        lp.yValueAxis.valueStep = 1
 
-		drawing.add(lp)
+        drawing.add(lp)
 
-		return drawing
+        return drawing
 
 
-	def calcPositions(self):
-		"""Works out where they go.
+    def calcPositions(self):
+        """Works out where they go.
 
-		Sets an attribute _positions which is a list of
-		lists of (x, y) matching the data.
-		"""
+        Sets an attribute _positions which is a list of
+        lists of (x, y) matching the data.
+        """
 
-		self._seriesCount = len(self.data)
-		self._rowLength = max(map(len,self.data))
+        self._seriesCount = len(self.data)
+        self._rowLength = max(map(len,self.data))
 
-		self._positions = []
-		for rowNo in range(len(self.data)):
-			line = []
-			for colNo in range(len(self.data[rowNo])):
-				datum = self.data[rowNo][colNo] # x,y value
-				if type(datum[0]) == type(''):
-					x = self.xValueAxis.scale(mktime(mkTimeTuple(datum[0])))
-				else:
-					x = self.xValueAxis.scale(datum[0])
-				y = self.yValueAxis.scale(datum[1])
-				line.append((x, y))
-			self._positions.append(line)
+        self._positions = []
+        for rowNo in range(len(self.data)):
+            line = []
+            for colNo in range(len(self.data[rowNo])):
+                datum = self.data[rowNo][colNo] # x,y value
+                if type(datum[0]) == type(''):
+                    x = self.xValueAxis.scale(mktime(mkTimeTuple(datum[0])))
+                else:
+                    x = self.xValueAxis.scale(datum[0])
+                y = self.yValueAxis.scale(datum[1])
+                line.append((x, y))
+            self._positions.append(line)
 
 
-	def makeBackground(self):
-		g = Group()
+    def makeBackground(self):
+        g = Group()
 
-		g.add(Rect(self.x, self.y,
-				   self.width, self.height,
-				   strokeColor = self.strokeColor,
-				   fillColor= self.fillColor))
+        g.add(Rect(self.x, self.y,
+                   self.width, self.height,
+                   strokeColor = self.strokeColor,
+                   fillColor= self.fillColor))
 
-		return g
+        return g
 
 
-	def drawLabel(self, group, rowNo, colNo, x, y):
-		"Draw a label for a given item in the list."
+    def drawLabel(self, group, rowNo, colNo, x, y):
+        "Draw a label for a given item in the list."
 
-		labelFmt = self.lineLabelFormat
-		labelValue = self.data[rowNo][colNo][1] ###
+        labelFmt = self.lineLabelFormat
+        labelValue = self.data[rowNo][colNo][1] ###
 
-		if labelFmt is None:
-			labelText = None
-		elif type(labelFmt) is StringType:
-			labelText = labelFmt % labelValue
-		elif type(labelFmt) is FunctionType:
-			labelText = labelFmt(labelValue)
-		elif isinstance(labelFmt, Formatter):
-			labelText = labelFmt(labelValue)
-		else:
-			msg = "Unknown formatter type %s, expected string or function"
-			raise Exception, msg % labelFmt
+        if labelFmt is None:
+            labelText = None
+        elif type(labelFmt) is StringType:
+            labelText = labelFmt % labelValue
+        elif type(labelFmt) is FunctionType:
+            labelText = labelFmt(labelValue)
+        elif isinstance(labelFmt, Formatter):
+            labelText = labelFmt(labelValue)
+        else:
+            msg = "Unknown formatter type %s, expected string or function"
+            raise Exception, msg % labelFmt
 
-		if labelText:
-			label = self.lineLabels[(rowNo, colNo)]
-			#hack to make sure labels are outside the bar
-			if y > 0:
-				label.setOrigin(x, y + self.lineLabelNudge)
-			else:
-				label.setOrigin(x, y - self.lineLabelNudge)
-			label.setText(labelText)
-			group.add(label)
+        if labelText:
+            label = self.lineLabels[(rowNo, colNo)]
+            #hack to make sure labels are outside the bar
+            if y > 0:
+                label.setOrigin(x, y + self.lineLabelNudge)
+            else:
+                label.setOrigin(x, y - self.lineLabelNudge)
+            label.setText(labelText)
+            group.add(label)
 
 
-	def makeLines(self):
-		g = Group()
+    def makeLines(self):
+        g = Group()
 
-		labelFmt = self.lineLabelFormat
+        labelFmt = self.lineLabelFormat
 
-		P = range(len(self._positions))
-		if self.reversePlotOrder: P.reverse()
-		# Iterate over data rows.
-		for rowNo in P:
-			row = self._positions[rowNo]
+        P = range(len(self._positions))
+        if self.reversePlotOrder: P.reverse()
+        # Iterate over data rows.
+        for rowNo in P:
+            row = self._positions[rowNo]
 
-			styleCount = len(self.lines)
-			styleIdx = rowNo % styleCount
-			rowColor = self.lines[styleIdx].strokeColor
-			dash = getattr(self.lines[styleIdx], 'strokeDashArray', None)
+            styleCount = len(self.lines)
+            styleIdx = rowNo % styleCount
+            rowColor = self.lines[styleIdx].strokeColor
+            dash = getattr(self.lines[styleIdx], 'strokeDashArray', None)
 
-			# width = getattr(self.lines[styleIdx], 'strokeWidth', None)
-			if hasattr(self.lines[styleIdx], 'strokeWidth'):
-				width = self.lines[styleIdx].strokeWidth
-			elif hasattr(self.lines, 'strokeWidth'):
-				width = self.lines.strokeWidth
-			else:
-				width = None
+            # width = getattr(self.lines[styleIdx], 'strokeWidth', None)
+            if hasattr(self.lines[styleIdx], 'strokeWidth'):
+                width = self.lines[styleIdx].strokeWidth
+            elif hasattr(self.lines, 'strokeWidth'):
+                width = self.lines.strokeWidth
+            else:
+                width = None
 
-			# Iterate over data columns.
-			if self.joinedLines:
-				points = []
-				for xy in row:
-					points = points + [xy[0], xy[1]]
-				line = PolyLine(points,strokeColor=rowColor,strokeLineCap=0,strokeLineJoin=1)
-				if width:
-					line.strokeWidth = width
-				if dash:
-					line.strokeDashArray = dash
-				g.add(line)
-			else:
-				for colNo in range(len(row)):
-					x1, y1 = row[colNo]
-					if self.joinedLines == 1:
-						if colNo > 0:
-							# Draw lines between adjacent items.
-							x2, y2 = row[colNo-1]
-							line = Line(x1, y1, x2, y2,
-										strokeColor=rowColor,
-										strokeLineCap=1)
-							if width:
-								line.strokeWidth = width
-							if dash:
-								line.strokeDashArray = dash
-							g.add(line)
+            # Iterate over data columns.
+            if self.joinedLines:
+                points = []
+                for xy in row:
+                    points = points + [xy[0], xy[1]]
+                line = PolyLine(points,strokeColor=rowColor,strokeLineCap=0,strokeLineJoin=1)
+                if width:
+                    line.strokeWidth = width
+                if dash:
+                    line.strokeDashArray = dash
+                g.add(line)
+            else:
+                for colNo in range(len(row)):
+                    x1, y1 = row[colNo]
+                    if self.joinedLines == 1:
+                        if colNo > 0:
+                            # Draw lines between adjacent items.
+                            x2, y2 = row[colNo-1]
+                            line = Line(x1, y1, x2, y2,
+                                        strokeColor=rowColor,
+                                        strokeLineCap=1)
+                            if width:
+                                line.strokeWidth = width
+                            if dash:
+                                line.strokeDashArray = dash
+                            g.add(line)
 
-			if hasattr(self.lines[styleIdx], 'symbol'):
-				uSymbol = self.lines[styleIdx].symbol
-			elif hasattr(self.lines, 'symbol'):
-				uSymbol = self.lines.symbol
-			else:
-				uSymbol = None
+            if hasattr(self.lines[styleIdx], 'symbol'):
+                uSymbol = self.lines[styleIdx].symbol
+            elif hasattr(self.lines, 'symbol'):
+                uSymbol = self.lines.symbol
+            else:
+                uSymbol = None
 
-			if uSymbol:
-				for colNo in range(len(row)):
-					x1, y1 = row[colNo]
-					symbol = uSymbol2Symbol(uSymbol,x1,y1,rowColor)
-					if symbol: g.add(symbol)
+            if uSymbol:
+                for colNo in range(len(row)):
+                    x1, y1 = row[colNo]
+                    symbol = uSymbol2Symbol(uSymbol,x1,y1,rowColor)
+                    if symbol: g.add(symbol)
 
-			# Draw item (bar) labels.
-			for colNo in range(len(row)):
-				x1, y1 = row[colNo]
-				self.drawLabel(g, rowNo, colNo, x1, y1)
+            # Draw item (bar) labels.
+            for colNo in range(len(row)):
+                x1, y1 = row[colNo]
+                self.drawLabel(g, rowNo, colNo, x1, y1)
 
-		return g
+        return g
 
 
-	def draw(self):
-		self.yValueAxis.setPosition(self.x, self.y, self.height)
-		self.yValueAxis.configure(self.data)
+    def draw(self):
+        self.yValueAxis.setPosition(self.x, self.y, self.height)
+        self.yValueAxis.configure(self.data)
 
-		# if zero is in chart, put x axis there, otherwise
-		# use bottom.
-		xAxisCrossesAt = self.yValueAxis.scale(0)
-		if ((xAxisCrossesAt > self.y + self.height) or (xAxisCrossesAt < self.y)):
-			y = self.y
-		else:
-			y = xAxisCrossesAt
+        # if zero is in chart, put x axis there, otherwise
+        # use bottom.
+        xAxisCrossesAt = self.yValueAxis.scale(0)
+        if ((xAxisCrossesAt > self.y + self.height) or (xAxisCrossesAt < self.y)):
+            y = self.y
+        else:
+            y = xAxisCrossesAt
 
-		self.xValueAxis.setPosition(self.x, y, self.width)
-		self.xValueAxis.configure(self.data)
+        self.xValueAxis.setPosition(self.x, y, self.width)
+        self.xValueAxis.configure(self.data)
 
-		self.calcPositions()
+        self.calcPositions()
 
-		g = Group()
+        g = Group()
 
-		g.add(self.makeBackground())
-		g.add(self.xValueAxis)
-		g.add(self.yValueAxis)
-		g.add(self.makeLines())
+        g.add(self.makeBackground())
+        g.add(self.xValueAxis)
+        g.add(self.yValueAxis)
+        g.add(self.makeLines())
 
-		return g
+        return g
 
 _monthlyIndexData = [[(19971202, 100.0),
   (19971231, 100.1704367),
@@ -382,501 +382,501 @@
   (20000630, 114.6)]]
 
 class GridLinePlot(LinePlot):
-	"""A customized version of LinePlot.
-	It uses NormalDateXValueAxis() and AdjYValueAxis() for the X and Y axes.
-	The chart has a default grid background with thin horizontal lines
-	aligned with the tickmarks (and labels). You can change the back-
-	ground to be any Grid or ShadedRect, or scale the whole chart.
-	If you do provide a background, you can specify the colours of the
-	stripes with 'background.stripeColors'.
-	"""
+    """A customized version of LinePlot.
+    It uses NormalDateXValueAxis() and AdjYValueAxis() for the X and Y axes.
+    The chart has a default grid background with thin horizontal lines
+    aligned with the tickmarks (and labels). You can change the back-
+    ground to be any Grid or ShadedRect, or scale the whole chart.
+    If you do provide a background, you can specify the colours of the
+    stripes with 'background.stripeColors'.
+    """
 
-	_attrMap = AttrMap(BASE=LinePlot,
-		background = AttrMapValue(None, desc='Background for chart area (now Grid or ShadedRect).'),
-		scaleFactor = AttrMapValue(isNumberOrNone, desc='Scalefactor to apply to whole drawing.'),
-		)
+    _attrMap = AttrMap(BASE=LinePlot,
+        background = AttrMapValue(None, desc='Background for chart area (now Grid or ShadedRect).'),
+        scaleFactor = AttrMapValue(isNumberOrNone, desc='Scalefactor to apply to whole drawing.'),
+        )
 
-	def __init__(self):
-		from reportlab.lib import colors
-		LinePlot.__init__(self)
-		self.xValueAxis = NormalDateXValueAxis()
-		self.yValueAxis = AdjYValueAxis()
-		self.scaleFactor = None
-		self.background = Grid()
-		self.background.orientation = 'horizontal'
-		self.background.useRects = 0
-		self.background.useLines = 1
-		self.background.strokeWidth = 0.5
-		self.background.strokeColor = colors.black
-		self.data = _monthlyIndexData
+    def __init__(self):
+        from reportlab.lib import colors
+        LinePlot.__init__(self)
+        self.xValueAxis = NormalDateXValueAxis()
+        self.yValueAxis = AdjYValueAxis()
+        self.scaleFactor = None
+        self.background = Grid()
+        self.background.orientation = 'horizontal'
+        self.background.useRects = 0
+        self.background.useLines = 1
+        self.background.strokeWidth = 0.5
+        self.background.strokeColor = colors.black
+        self.data = _monthlyIndexData
 
-	def demo(self,drawing=None):
-		from reportlab.lib import colors
-		if not drawing:
-			drawing = Drawing(400, 200)
-		lp = AdjLinePlot()
-		lp.x = 50
-		lp.y = 50
-		lp.height = 125
-		lp.width = 300
-		lp.data = _monthlyIndexData
-		lp.joinedLines = 1
-		lp.strokeColor = colors.black
-		c0 = colors.PCMYKColor(100,65,0,30, spotName='PANTONE 288 CV', density=100)
-		lp.lines[0].strokeColor = c0
-		lp.lines[0].strokeWidth = 2
-		lp.lines[0].strokeDashArray = None
-		c1 = colors.PCMYKColor(0,79,91,0, spotName='PANTONE Wm Red CV', density=100)
-		lp.lines[1].strokeColor = c1
-		lp.lines[1].strokeWidth = 1
-		lp.lines[1].strokeDashArray = [3,1]
-		lp.xValueAxis.labels.fontSize = 10
-		lp.xValueAxis.labels.textAnchor = 'start'
-		lp.xValueAxis.labels.boxAnchor = 'w'
-		lp.xValueAxis.labels.angle = -45
-		lp.xValueAxis.labels.dx = 0
-		lp.xValueAxis.labels.dy = -8
-		lp.xValueAxis.xLabelFormat = '{mm}/{yy}'
-		lp.yValueAxis.labelTextFormat = '%5d%% '
-		lp.yValueAxis.tickLeft = 5
-		lp.yValueAxis.labels.fontSize = 10
-		lp.background = Grid()
-		lp.background.stripeColors = [colors.pink, colors.lightblue]
-		lp.background.orientation = 'vertical'
-		drawing.add(lp,'plot')
-		return drawing
+    def demo(self,drawing=None):
+        from reportlab.lib import colors
+        if not drawing:
+            drawing = Drawing(400, 200)
+        lp = AdjLinePlot()
+        lp.x = 50
+        lp.y = 50
+        lp.height = 125
+        lp.width = 300
+        lp.data = _monthlyIndexData
+        lp.joinedLines = 1
+        lp.strokeColor = colors.black
+        c0 = colors.PCMYKColor(100,65,0,30, spotName='PANTONE 288 CV', density=100)
+        lp.lines[0].strokeColor = c0
+        lp.lines[0].strokeWidth = 2
+        lp.lines[0].strokeDashArray = None
+        c1 = colors.PCMYKColor(0,79,91,0, spotName='PANTONE Wm Red CV', density=100)
+        lp.lines[1].strokeColor = c1
+        lp.lines[1].strokeWidth = 1
+        lp.lines[1].strokeDashArray = [3,1]
+        lp.xValueAxis.labels.fontSize = 10
+        lp.xValueAxis.labels.textAnchor = 'start'
+        lp.xValueAxis.labels.boxAnchor = 'w'
+        lp.xValueAxis.labels.angle = -45
+        lp.xValueAxis.labels.dx = 0
+        lp.xValueAxis.labels.dy = -8
+        lp.xValueAxis.xLabelFormat = '{mm}/{yy}'
+        lp.yValueAxis.labelTextFormat = '%5d%% '
+        lp.yValueAxis.tickLeft = 5
+        lp.yValueAxis.labels.fontSize = 10
+        lp.background = Grid()
+        lp.background.stripeColors = [colors.pink, colors.lightblue]
+        lp.background.orientation = 'vertical'
+        drawing.add(lp,'plot')
+        return drawing
 
-	def makeBackground(self):
-		"Make a background grid or fall back on chart's default."
+    def makeBackground(self):
+        "Make a background grid or fall back on chart's default."
 
-		# If no background set, fall back to default behaviour.
-		if not self.background:
-			return LinePlot.makeBackground(self)
+        # If no background set, fall back to default behaviour.
+        if not self.background:
+            return LinePlot.makeBackground(self)
 
-		g = Group()
+        g = Group()
 
-		back = self.background
-		back.x = self.x
-		back.y = self.y
-		back.width = self.width
-		back.height = self.height
+        back = self.background
+        back.x = self.x
+        back.y = self.y
+        back.width = self.width
+        back.height = self.height
 
-		g.add(self.background)
+        g.add(self.background)
 
-		return g
+        return g
 
-	def draw(self):
-		xva, yva = self.xValueAxis, self.yValueAxis
+    def draw(self):
+        xva, yva = self.xValueAxis, self.yValueAxis
 
-		yva.setPosition(self.x, self.y, self.height)
-		yva.configure(self.data)
+        yva.setPosition(self.x, self.y, self.height)
+        yva.configure(self.data)
 
-		# if zero is in chart, put x axis there, otherwise
-		# use bottom.
-		xAxisCrossesAt = yva.scale(0)
-		if ((xAxisCrossesAt > self.y + self.height) or (xAxisCrossesAt < self.y)):
-			y = self.y
-		else:
-			y = xAxisCrossesAt
+        # if zero is in chart, put x axis there, otherwise
+        # use bottom.
+        xAxisCrossesAt = yva.scale(0)
+        if ((xAxisCrossesAt > self.y + self.height) or (xAxisCrossesAt < self.y)):
+            y = self.y
+        else:
+            y = xAxisCrossesAt
 
-		xva.setPosition(self.x, y, self.width)
-		xva.configure(self.data)
+        xva.setPosition(self.x, y, self.width)
+        xva.configure(self.data)
 
-		back = self.background
-		if isinstance(back, Grid):
-			if back.orientation == 'vertical' and xva.valueSteps:
-				xpos = map(xva.scale, [xva._valueMin] + xva.valueSteps)
-				steps = []
-				for i in range(len(xpos)-1):
-					steps.append(xpos[i+1] - xpos[i])
-				back.deltaSteps = steps
-			elif back.orientation == 'horizontal' and yva.valueSteps:
-				ypos = map(yva.scale, [yva._valueMin] + yva.valueSteps)
-				steps = []
-				for i in range(len(ypos)-1):
-					steps.append(ypos[i+1] - ypos[i])
-				back.deltaSteps = steps
-		elif isinstance(back, DoubleGrid):
-			# Ideally, these lines would not be needed...
-			back.grid0.x = self.x
-			back.grid0.y = self.y
-			back.grid0.width = self.width
-			back.grid0.height = self.height
-			back.grid1.x = self.x
-			back.grid1.y = self.y
-			back.grid1.width = self.width
-			back.grid1.height = self.height
+        back = self.background
+        if isinstance(back, Grid):
+            if back.orientation == 'vertical' and xva.valueSteps:
+                xpos = map(xva.scale, [xva._valueMin] + xva.valueSteps)
+                steps = []
+                for i in range(len(xpos)-1):
+                    steps.append(xpos[i+1] - xpos[i])
+                back.deltaSteps = steps
+            elif back.orientation == 'horizontal' and yva.valueSteps:
+                ypos = map(yva.scale, [yva._valueMin] + yva.valueSteps)
+                steps = []
+                for i in range(len(ypos)-1):
+                    steps.append(ypos[i+1] - ypos[i])
+                back.deltaSteps = steps
+        elif isinstance(back, DoubleGrid):
+            # Ideally, these lines would not be needed...
+            back.grid0.x = self.x
+            back.grid0.y = self.y
+            back.grid0.width = self.width
+            back.grid0.height = self.height
+            back.grid1.x = self.x
+            back.grid1.y = self.y
+            back.grid1.width = self.width
+            back.grid1.height = self.height
 
-			# some room left for optimization...
-			if back.grid0.orientation == 'vertical' and xva.valueSteps:
-				xpos = map(xva.scale, [xva._valueMin] + xva.valueSteps)
-				steps = []
-				for i in range(len(xpos)-1):
-					steps.append(xpos[i+1] - xpos[i])
-				back.grid0.deltaSteps = steps
-			elif back.grid0.orientation == 'horizontal' and yva.valueSteps:
-				ypos = map(yva.scale, [yva._valueMin] + yva.valueSteps)
-				steps = []
-				for i in range(len(ypos)-1):
-					steps.append(ypos[i+1] - ypos[i])
-				back.grid0.deltaSteps = steps
-			if back.grid1.orientation == 'vertical' and xva.valueSteps:
-				xpos = map(xva.scale, [xva._valueMin] + xva.valueSteps)
-				steps = []
-				for i in range(len(xpos)-1):
-					steps.append(xpos[i+1] - xpos[i])
-				back.grid1.deltaSteps = steps
-			elif back.grid1.orientation == 'horizontal' and yva.valueSteps:
-				ypos = map(yva.scale, [yva._valueMin] + yva.valueSteps)
-				steps = []
-				for i in range(len(ypos)-1):
-					steps.append(ypos[i+1] - ypos[i])
-				back.grid1.deltaSteps = steps
+            # some room left for optimization...
+            if back.grid0.orientation == 'vertical' and xva.valueSteps:
+                xpos = map(xva.scale, [xva._valueMin] + xva.valueSteps)
+                steps = []
+                for i in range(len(xpos)-1):
+                    steps.append(xpos[i+1] - xpos[i])
+                back.grid0.deltaSteps = steps
+            elif back.grid0.orientation == 'horizontal' and yva.valueSteps:
+                ypos = map(yva.scale, [yva._valueMin] + yva.valueSteps)
+                steps = []
+                for i in range(len(ypos)-1):
+                    steps.append(ypos[i+1] - ypos[i])
+                back.grid0.deltaSteps = steps
+            if back.grid1.orientation == 'vertical' and xva.valueSteps:
+                xpos = map(xva.scale, [xva._valueMin] + xva.valueSteps)
+                steps = []
+                for i in range(len(xpos)-1):
+                    steps.append(xpos[i+1] - xpos[i])
+                back.grid1.deltaSteps = steps
+            elif back.grid1.orientation == 'horizontal' and yva.valueSteps:
+                ypos = map(yva.scale, [yva._valueMin] + yva.valueSteps)
+                steps = []
+                for i in range(len(ypos)-1):
+                    steps.append(ypos[i+1] - ypos[i])
+                back.grid1.deltaSteps = steps
 
-		self.calcPositions()
+        self.calcPositions()
 
-		width, height, scaleFactor = self.width, self.height, self.scaleFactor
-		if scaleFactor and scaleFactor!=1:
-			#g = Drawing(scaleFactor*width, scaleFactor*height)
-			g.transform = (scaleFactor, 0, 0, scaleFactor,0,0)
-		else: