src/reportlab/graphics/widgets/table.py
author rptlab
Tue, 30 Apr 2013 14:28:14 +0100
branchpy33
changeset 3723 99aa837b6703
parent 3721 0c93dd8ff567
child 4045 623b741fa779
permissions -rw-r--r--
second stage of port to Python 3.3; working hello world
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3228
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     1
#!/usr/bin/env python
3617
ae5744e97c42 reportlab: copyright date changes
robin
parents: 3228
diff changeset
     2
#Copyright ReportLab Europe Ltd. 2000-2012
3228
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     3
#see license.txt for license details
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     4
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/graphics/widgets/grids.py
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     5
__version__=''' $Id$ '''
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     6
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     7
from reportlab.graphics.widgetbase import Widget
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     8
from reportlab.graphics.charts.textlabels import Label
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
     9
from reportlab.graphics import shapes
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    10
from reportlab.lib import colors
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    11
from reportlab.lib.validators import *
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    12
from reportlab.lib.attrmap import *
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    13
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    14
from reportlab.graphics.shapes import Drawing
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    15
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    16
class TableWidget(Widget):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    17
    """A two dimensions table of labels
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    18
    """
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    19
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    20
    _attrMap = AttrMap(
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    21
        x = AttrMapValue(isNumber, desc="x position of left edge of table"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    22
        y = AttrMapValue(isNumber, desc="y position of bottom edge of table"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    23
        width = AttrMapValue(isNumber, desc="table width"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    24
        height = AttrMapValue(isNumber, desc="table height"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    25
        borderStrokeColor = AttrMapValue(isColorOrNone, desc="table border color"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    26
        fillColor = AttrMapValue(isColorOrNone, desc="table fill color"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    27
        borderStrokeWidth = AttrMapValue(isNumber, desc="border line width"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    28
        horizontalDividerStrokeColor = AttrMapValue(isColorOrNone, desc="table inner horizontal lines color"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    29
        verticalDividerStrokeColor = AttrMapValue(isColorOrNone, desc="table inner vertical lines color"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    30
        horizontalDividerStrokeWidth = AttrMapValue(isNumber, desc="table inner horizontal lines width"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    31
        verticalDividerStrokeWidth = AttrMapValue(isNumber, desc="table inner vertical lines width"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    32
        dividerDashArray = AttrMapValue(isListOfNumbersOrNone, desc='Dash array for dividerLines.'),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    33
        data = AttrMapValue(None, desc="a list of list of strings to be displayed in the cells"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    34
        boxAnchor = AttrMapValue(isBoxAnchor, desc="location of the table anchoring point"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    35
        fontName = AttrMapValue(isString, desc="text font in the table"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    36
        fontSize = AttrMapValue(isNumber, desc="font size of the table"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    37
        fontColor = AttrMapValue(isColorOrNone, desc="font color"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    38
        alignment = AttrMapValue(OneOf("left", "right"), desc="Alignment of text within cells"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    39
        textAnchor = AttrMapValue(OneOf('start','middle','end','numeric'), desc="Alignment of text within cells"),
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    40
    )
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    41
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    42
    def __init__(self, x=10, y=10, **kw):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    43
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    44
        self.x = x
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    45
        self.y = y
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    46
        self.width = 200
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    47
        self.height = 100
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    48
        self.borderStrokeColor = colors.black
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    49
        self.fillColor = None
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    50
        self.borderStrokeWidth = 0.5
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    51
        self.horizontalDividerStrokeColor = colors.black
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    52
        self.verticalDividerStrokeColor = colors.black
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    53
        self.horizontalDividerStrokeWidth = 0.5
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    54
        self.verticalDividerStrokeWidth = 0.25
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    55
        self.dividerDashArray = None
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    56
        self.data = [['North','South','East','West'],[100,110,120,130],['A','B','C','D']] # list of rows each row is a list of columns
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    57
        self.boxAnchor = 'nw'
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    58
        #self.fontName = None
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    59
        self.fontSize = 8
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    60
        self.fontColor = colors.black
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    61
        self.alignment = 'right'
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    62
        self.textAnchor = 'start'
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    63
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    64
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    65
        for k, v in kw.items():
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
    66
            if k in list(self.__class__._attrMap.keys()):
3228
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    67
                setattr(self, k, v)
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
    68
                print('setting %s = %s'%(k, v))
3228
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    69
            else:
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    70
                raise ValueError('invalid argument supplied for class %s'%self.__class__)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    71
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    72
    def demo(self):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    73
        """ returns a sample of this widget with data
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    74
        """
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    75
        d = Drawing(400, 200)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    76
        t = TableWidget()
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    77
        d.add(t, name='table')
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    78
        d.table.dividerDashArray = (1, 3, 2)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    79
        d.table.verticalDividerStrokeColor = None
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    80
        d.table.borderStrokeWidth = 0
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    81
        d.table.borderStrokeColor = colors.red
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    82
        return d
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    83
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    84
    def draw(self):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    85
        """ returns a group of shapes
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    86
        """
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    87
        g = shapes.Group()
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    88
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    89
        #overall border and fill
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    90
        if self.borderStrokeColor or self.fillColor: # adds border and filling color
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    91
            rect = shapes.Rect(self.x, self.y, self.width, self.height)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    92
            rect.fillColor = self.fillColor
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    93
            rect.strokeColor = self.borderStrokeColor
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    94
            rect.strokeWidth = self.borderStrokeWidth
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    95
            g.add(rect)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    96
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    97
        #special case - for an empty table we want to avoid divide-by-zero
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    98
        data = self.preProcessData(self.data)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
    99
        rows = len(self.data)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   100
        cols = len(self.data[0])
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   101
        #print "(rows,cols)=(%s, %s)"%(rows,cols)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   102
        row_step = self.height / float(rows)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   103
        col_step = self.width / float(cols)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   104
        #print "(row_step,col_step)=(%s, %s)"%(row_step,col_step)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   105
        # draw the grid
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   106
        if self.horizontalDividerStrokeColor:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   107
            for i in range(rows): # make horizontal lines
3228
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   108
                x1 = self.x
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   109
                x2 = self.x + self.width
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   110
                y = self.y + row_step*i
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   111
                #print 'line (%s, %s), (%s, %s)'%(x1, y, x2, y)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   112
                line = shapes.Line(x1, y, x2, y)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   113
                line.strokeDashArray = self.dividerDashArray
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   114
                line.strokeWidth = self.horizontalDividerStrokeWidth
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   115
                line.strokeColor = self.horizontalDividerStrokeColor
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   116
                g.add(line)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   117
        if self.verticalDividerStrokeColor:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   118
            for i in range(cols): # make vertical lines
3228
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   119
                x = self.x+col_step*i
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   120
                y1 = self.y
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   121
                y2 = self.y + self.height
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   122
                #print 'line (%s, %s), (%s, %s)'%(x, y1, x, y2)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   123
                line = shapes.Line(x, y1, x, y2)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   124
                line.strokeDashArray = self.dividerDashArray
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   125
                line.strokeWidth = self.verticalDividerStrokeWidth
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   126
                line.strokeColor = self.verticalDividerStrokeColor
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   127
                g.add(line)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   128
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   129
        # since we plot data from down up, we reverse the list
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   130
        self.data.reverse()
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   131
        for (j, row) in enumerate(self.data):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   132
            y = self.y + j*row_step + 0.5*row_step - 0.5 * self.fontSize
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   133
            for (i, datum) in enumerate(row):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   134
                if datum:
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   135
                    x = self.x + i*col_step + 0.5*col_step
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   136
                    s = shapes.String(x, y, str(datum), textAnchor=self.textAnchor)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   137
                    s.fontName = self.fontName
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   138
                    s.fontSize = self.fontSize
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   139
                    s.fillColor = self.fontColor
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   140
                    g.add(s)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   141
        return g
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   142
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   143
    def preProcessData(self, data):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   144
        """preprocess and return a new array with at least one row
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   145
        and column (use a None) if needed, and all rows the same
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   146
        length (adding Nones if needed)
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   147
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   148
        """
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   149
        if not data:
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   150
            return [[None]]
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   151
        #make all rows have similar number of cells, append None when needed
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   152
        max_row = max( [len(x) for x in data] )
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   153
        for rowNo, row in enumerate(data):
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   154
            if len(row) < max_row:
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   155
                row.extend([None]*(max_row-len(row)))
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   156
        return data
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   157
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   158
#test
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   159
if __name__ == '__main__':
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   160
    d = TableWidget().demo()
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   161
    import os
60250a3b480d a new table widget has been added
meitham
parents:
diff changeset
   162
    d.save(formats=['pdf'],outDir=os.getcwd(),fnRoot=None)