graphics: start on run time callback support
authorrgbecker
Thu, 27 May 2010 15:51:47 +0000
changeset 3385 e45ca0b2053c
parent 3384 4c9c0dcf0995
child 3386 2bfeb67b4d9d
graphics: start on run time callback support
src/reportlab/graphics/charts/barcharts.py
src/reportlab/graphics/charts/utils.py
src/reportlab/graphics/renderbase.py
--- a/src/reportlab/graphics/charts/barcharts.py	Thu May 27 14:22:25 2010 +0000
+++ b/src/reportlab/graphics/charts/barcharts.py	Thu May 27 15:51:47 2010 +0000
@@ -66,6 +66,7 @@
         annotations = AttrMapValue(None, desc='list of callables, will be called with self, xscale, yscale.'),
         categoryLabelBarSize = AttrMapValue(isNumber, desc='width to leave for a category label to go between categories.'),
         categoryLabelBarOrder = AttrMapValue(OneOf('first','last','auto'), desc='where any label bar should appear first/last'),
+        barRecord = AttrMapValue(None, desc='callable(bar,label=labelText,value=value,**kwds) to record bar information', advancedUsage=1),
         )
 
     def makeSwatchSample(self, rowNo, x, y, width, height):
@@ -469,6 +470,7 @@
     def _makeBars(self,g,lg):
         lenData = len(self.data)
         bars = self.bars
+        br = getattr(self,'barRecord',None)
         for rowNo in range(lenData):
             row = self._barPositions[rowNo]
             styleCount = len(bars)
@@ -498,6 +500,7 @@
                     g.add(symbol)
                 elif abs(width)>1e-7 and abs(height)>=1e-7 and (style.fillColor is not None or style.strokeColor is not None):
                     self._makeBar(g,x,y,width,height,rowNo,style)
+                    if br: br(g.contents[-1],label=self._getLabelText(rowNo,colNo),value=self.data[rowNo][colNo],rowNo=rowNo,colNo=colNo)
 
                 self._addBarLabel(lg,rowNo,colNo,x,y,width,height)
 
--- a/src/reportlab/graphics/charts/utils.py	Thu May 27 14:22:25 2010 +0000
+++ b/src/reportlab/graphics/charts/utils.py	Thu May 27 15:51:47 2010 +0000
@@ -4,10 +4,7 @@
 
 __version__=''' $Id$ '''
 __doc__="Utilities used here and there."
-
 from time import mktime, gmtime, strftime
-import string
-
 
 ### Dinu's stuff used in some line plots (likely to vansih).
 
@@ -15,7 +12,7 @@
     "Convert a 'dd/mm/yyyy' formatted string to a tuple for use in the time module."
 
     list = [0] * 9
-    dd, mm, yyyy = map(int, string.split(timeString, '/'))
+    dd, mm, yyyy = map(int, timeString.split('/'))
     list[:3] = [yyyy, mm, dd]
 
     return tuple(list)
@@ -225,3 +222,44 @@
 
 def pairMaverage(data,n=6):
     return [(x[0],s) for x,s in zip(data, maverage([x[1] for x in data],n))]
+
+import weakref
+from reportlab.graphics.shapes import transformPoint, inverse
+class DrawTimeCollector:
+    '''
+    generic mechanism for collecting information about nodes at the time they are about to be drawn
+    '''
+    def __init__(self):
+        self._nodes = weakref.WeakKeyDictionary()
+        self.clear()
+
+    def clear(self):
+        self._info = []
+        self._info_append = self._info.append
+
+    def record(self,func,node,*args,**kwds):
+        self._nodes[node] = (func,args,kwds)
+        node.__dict__['_drawTimeCallback'] = self
+
+    def __call__(self,node,canvas,renderer):
+        func = self._nodes.get(node,None)
+        if func:
+            func, args, kwds = func
+            i = func(node,canvas,renderer, *args, **kwds)
+            if i is not None: self._info_append(i)
+
+    @staticmethod
+    def rectDrawTimeCallback(node,canvas,renderer,**kwds):
+        A = getattr(canvas,'ctm',None)
+        if not A: return
+        x1 = node.x
+        y1 = node.y
+        x2 = x1 + node.width
+        y2 = y1 + node.height
+
+        iA = inverse(A)
+        x1,y1 = transformPoint(iA,(x1,y1))
+        x2,y2 = transformPoint(iA,(x2,y2))
+        D = kwds.copy()
+        D['rect']=(x1,y1,x2,y2)
+        return D
--- a/src/reportlab/graphics/renderbase.py	Thu May 27 14:22:25 2010 +0000
+++ b/src/reportlab/graphics/renderbase.py	Thu May 27 15:51:47 2010 +0000
@@ -254,6 +254,9 @@
                 ocanvas = None
 
             self.fillDerivedValues(node)
+            dtcb = getattr(node,'_drawTimeCallback',None)
+            if dtcb:
+                dtcb(node,canvas=canvas,renderer=self)
             #draw the object, or recurse
             if isinstance(node, Line):
                 self.drawLine(node)