~launchpad-p-s/sofastatistics/main

« back to all changes in this revision

Viewing changes to demotables.py

  • Committer: Grant Paton-Simpson
  • Date: 2009-05-19 04:21:43 UTC
  • Revision ID: g@ubuntu-20090519042143-p561mbokz3inefvd
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
import random
 
3
 
 
4
import tabreports
 
5
import getdata
 
6
import rawtables
 
7
import make_table
 
8
import util
 
9
import dimtables
 
10
 
 
11
 
 
12
num_data_seq = ("1.0", "1.5", "2.0", "2.5", "3.0", "3.5", "12.0", "35.0")
 
13
str_data_seq = ("Lorem", "ipsum", "dolor", "sit", "amet")
 
14
dtm_data_seq = ("1 Feb 2009", "23 Aug 1994", "16 Sep 2001", "7 Nov 1986")
 
15
 
 
16
class DemoTable(object):
 
17
    """
 
18
    All demo tables, whether dim tables or raw tables, derive from this class.
 
19
    """
 
20
    
 
21
    def getDemoHTMLIfOK(self):
 
22
        "Get HTML to display if enough data to display"
 
23
        assert 0, "getDemoHTMLIfOK must be defined by subclass"
 
24
 
 
25
    def getHTMLParts(self):
 
26
        "Returns (hdr_html, body_html)"
 
27
        assert 0, "getHTMLParts must be defined by subclass"
 
28
 
 
29
    def getDemoHTML(self):
 
30
        "Get demo HTML for table"
 
31
        # sort titles out first
 
32
        if self.txtTitles.GetValue():
 
33
            self.titles = ["%s" % x for x \
 
34
                      in self.txtTitles.GetValue().split("\n")]
 
35
        else:
 
36
            self.titles = []
 
37
        if self.txtSubtitles.GetValue():
 
38
            self.subtitles = ["%s" % x for x \
 
39
                         in self.txtSubtitles.GetValue().split("\n")]
 
40
        else:
 
41
            self.subtitles = []
 
42
        if self.titles:
 
43
            self.titles[0] += " (random demo data only)"        
 
44
        html = tabreports.getHtmlHdr(hdr_title="Report(s)", 
 
45
                                     fil_css=self.fil_css)
 
46
        html += "<table cellspacing='0'>\n" # IE6 doesn't support CSS borderspacing
 
47
        (hdr_html, body_html) = self.getHTMLParts()
 
48
        html += hdr_html
 
49
        html += body_html
 
50
        html += "\n</table>"
 
51
        html += "\n</body>\n</html>"
 
52
        #print html
 
53
        return html
 
54
 
 
55
class DemoRawTable(rawtables.RawTable, DemoTable):
 
56
    """
 
57
    Demo display raw table (uses demo data only for illustrative purposes)
 
58
    """
 
59
    
 
60
    def __init__(self, txtTitles, txtSubtitles, colRoot, coltree, 
 
61
                 flds, var_labels, val_dics, fil_css, chkTotalsRow, 
 
62
                 chkFirstAsLabel):
 
63
        self.txtTitles = txtTitles
 
64
        self.txtSubtitles = txtSubtitles
 
65
        self.colRoot = colRoot
 
66
        self.coltree = coltree
 
67
        self.flds = flds
 
68
        self.var_labels = var_labels
 
69
        self.val_dics = val_dics
 
70
        self.fil_css=fil_css
 
71
        self.chkTotalsRow = chkTotalsRow
 
72
        self.chkFirstAsLabel = chkFirstAsLabel
 
73
        
 
74
    def getDemoHTMLIfOK(self):
 
75
        "Show demo table if sufficient data to do so"
 
76
        has_cols = util.getTreeCtrlChildren(tree=self.coltree, 
 
77
                                    parent=self.colRoot)
 
78
        return self.getDemoHTML() if has_cols else ""
 
79
      
 
80
    def getHTMLParts(self):
 
81
        """
 
82
        Returns (hdr_html, body_html).
 
83
        If value labels available, use these rather than random numbers.
 
84
        """
 
85
        col_names, col_labels = make_table.GetColDets(self.coltree, 
 
86
                                                      self.colRoot, 
 
87
                                                      self.var_labels)
 
88
        cols_n = len(col_names)        
 
89
        bolhas_totals_row = self.chkTotalsRow.IsChecked()
 
90
        bolfirst_col_as_label = self.chkFirstAsLabel.IsChecked()
 
91
        hdr_html = self.getHdrDets(col_labels)
 
92
        body_html = "\n<tbody>"        
 
93
        # pre-store val dics for each column where possible
 
94
        col_val_dics = []
 
95
        for col_name in col_names:
 
96
            if self.val_dics.get(col_name):
 
97
                col_val_dic = self.val_dics[col_name]
 
98
                col_val_dics.append(col_val_dic)
 
99
            else:
 
100
                col_val_dics.append(None)
 
101
        # pre-store css class(es) for each column
 
102
        col_class_lsts = [[] for x in col_names]
 
103
        if bolfirst_col_as_label:
 
104
            col_class_lsts[0] = [tabreports.CSS_LBL]
 
105
        for i, col_name in enumerate(col_names):
 
106
            if self.flds[col_name][getdata.FLD_BOLNUMERIC] \
 
107
                    and not col_val_dics[i]:
 
108
                col_class_lsts[i].append(tabreports.CSS_ALIGN_RIGHT)
 
109
        for i in range(4): # four rows enough for demo purposes
 
110
            row_tds = []
 
111
            # process cells within row
 
112
            for j in range(cols_n):
 
113
                # cell contents
 
114
                if col_val_dics[j]: # choose a random value label
 
115
                    random_key = random.choice(col_val_dics[j].keys())
 
116
                    row_val = col_val_dics[j][random_key]
 
117
                elif self.flds[col_names[j]][getdata.FLD_BOLNUMERIC]: # choose a random number
 
118
                    row_val = str(random.choice(num_data_seq))
 
119
                elif self.flds[col_names[j]][getdata.FLD_BOLDATETIME]: # choose a random date
 
120
                    row_val = str(random.choice(dtm_data_seq))
 
121
                else:
 
122
                    row_val = str(random.choice(str_data_seq))
 
123
                # cell format
 
124
                col_class_names = "\"" + ", ".join(col_class_lsts[j]) + "\""
 
125
                col_classes = "class = %s" % col_class_names if col_class_names else ""
 
126
                row_tds.append("<td %s>%s</td>" % (col_classes, row_val))
 
127
            body_html += "\n<tr>" + "".join(row_tds) + "</td></tr>"
 
128
        if bolhas_totals_row:
 
129
            if bolfirst_col_as_label:
 
130
                tot_cell = "<td class='%s'>TOTAL</td>" % tabreports.CSS_LBL
 
131
                start_idx = 1
 
132
            else:
 
133
                tot_cell = ""
 
134
                start_idx = 0
 
135
            # get demo data
 
136
            demo_row_data_lst = []
 
137
            for i in range(start_idx, cols_n):
 
138
                # if has value dic OR not numeric (e.g. date or string), 
 
139
                # show empty cell as total
 
140
                if col_val_dics[i] or \
 
141
                    not self.flds[col_names[i]][getdata.FLD_BOLNUMERIC]: 
 
142
                    demo_row_data_lst.append("&nbsp;&nbsp;")
 
143
                else:
 
144
                    demo_row_data_lst.append(str(random.choice(num_data_seq)))
 
145
            # never a displayed total for strings (whether orig data or labels)
 
146
            joiner = "</td><td class=\"%s\">" % tabreports.CSS_ALIGN_RIGHT
 
147
            body_html += "\n<tr class='total-row'>" + \
 
148
                tot_cell + "<td class=\"%s\">"  % tabreports.CSS_ALIGN_RIGHT + \
 
149
                joiner.join(demo_row_data_lst) + "</td></tr>"
 
150
        body_html += "\n</tbody>"
 
151
        return (hdr_html, body_html)
 
152
 
 
153
    
 
154
class DemoDimTable(dimtables.DimTable, DemoTable):
 
155
    "A demo table only - no real data inside"
 
156
    
 
157
    def __init__(self, txtTitles, txtSubtitles, colRoot, rowRoot, rowtree, 
 
158
                 coltree, col_no_vars_item, var_labels, val_dics, fil_css):
 
159
        self.txtTitles = txtTitles
 
160
        self.txtSubtitles = txtSubtitles
 
161
        self.colRoot = colRoot
 
162
        self.rowRoot = rowRoot
 
163
        self.rowtree = rowtree
 
164
        self.coltree = coltree
 
165
        self.col_no_vars_item = col_no_vars_item
 
166
        self.var_labels = var_labels
 
167
        self.val_dics = val_dics
 
168
        self.fil_css=fil_css
 
169
    
 
170
    def getHTMLParts(self):
 
171
        "Returns (hdr_html, body_html)"
 
172
        (row_label_rows_lst, tree_row_labels, row_label_cols_n) = \
 
173
            self.getRowDets()
 
174
        (tree_col_dets, hdr_html) = self.getHdrDets(row_label_cols_n)
 
175
        #print row_label_rows_lst #debug
 
176
        row_label_rows_lst = self.getBodyHtmlRows(row_label_rows_lst,
 
177
                                                  tree_row_labels, 
 
178
                                                  tree_col_dets)        
 
179
        body_html = "\n\n<tbody>"
 
180
        for row in row_label_rows_lst:
 
181
            # flatten row list
 
182
            body_html += "\n" + "".join(row) + "</tr>"
 
183
        body_html += "\n</tbody>"
 
184
        return (hdr_html, body_html)
 
185
    
 
186
    def getRowDets(self):
 
187
        """
 
188
        Return row_label_rows_lst - need combination of row and col filters
 
189
            to add the data cells to the table body rows.
 
190
        tree_row_labels - not needed here - only with display of 
 
191
            actual data
 
192
        row_label_cols_n - needed to set up header (need to span the 
 
193
            row labels).
 
194
        """
 
195
        tree_row_labels = dimtables.LabelNodeTree()
 
196
        for row_child_item in util.getTreeCtrlChildren(tree=self.rowtree, 
 
197
                                                    parent=self.rowRoot):
 
198
            self.addSubtreeToLabelTree(tree_dims_item=row_child_item, 
 
199
                              tree_labels_node=tree_row_labels.root_node, 
 
200
                              dim=dimtables.ROWDIM)
 
201
        return self.processRowTree(tree_row_labels)
 
202
 
 
203
    def addSubtreeToLabelTree(self, tree_dims_item, tree_labels_node, dim):
 
204
        """
 
205
        NB tree_dims_item is a wxPython TreeCtrl item.
 
206
        If the tree_dims_item is the special col_no_vars_item
 
207
          just add the measures underneath the label node.
 
208
        Otherwise, for each dim item, e.g. gender, add node to the 
 
209
          labels tree,
 
210
          then the first two values underneath (and total if relevant).
 
211
        If the variable node is terminal, then add the measures underneath 
 
212
        the new value label nodes.
 
213
        If not terminal, add a node for each var underneath 
 
214
          (e.g. Ethnicity and Age Gp) under each value node and 
 
215
          send through again.
 
216
        dim - dimtables.ROWDIM or dimtables.COLDIM
 
217
        """
 
218
        if dim == dimtables.COLDIM:
 
219
            item_conf = self.coltree.GetItemPyData(tree_dims_item)
 
220
        elif dim == dimtables.ROWDIM:
 
221
            item_conf = self.rowtree.GetItemPyData(tree_dims_item)        
 
222
        if item_conf == None:
 
223
            item_conf = make_table.ItemConfig()
 
224
        if tree_dims_item == self.col_no_vars_item:
 
225
            # add measures only
 
226
            if item_conf:
 
227
                measures = item_conf.measures_lst
 
228
            else:
 
229
                measures = [self.default_measure]
 
230
            for measure in measures:
 
231
                tree_labels_node.addChild(dimtables.LabelNode(label=measure, 
 
232
                                                        measure=measure))
 
233
        else:
 
234
            # add var e.g. gender then values below e.g. Male, Female
 
235
            var_name, var_label = make_table.extractVarDets(\
 
236
                self.coltree.GetItemText(tree_dims_item))
 
237
            #print var_name #debug
 
238
            var_label = self.var_labels.get(var_name, var_name.title())
 
239
            new_var_node = tree_labels_node.addChild(\
 
240
                                            dimtables.LabelNode(label=var_label))
 
241
            # terminal tree_dim_item (got any children)?
 
242
            item, cookie = self.coltree.GetFirstChild(tree_dims_item)
 
243
            is_terminal = not item #i.e. if there is only the root there
 
244
            if dim==dimtables.ROWDIM and self.has_row_measures:
 
245
                # add measure label nodes
 
246
                if item_conf:
 
247
                    measures = item_conf.measures_lst
 
248
                else:
 
249
                    measures = [self.default_measure]
 
250
                for measure in measures:
 
251
                    new_var_node.addChild(dimtables.LabelNode(\
 
252
                                        label=measure,
 
253
                                        measure=measure))
 
254
            else: # no row_measures 
 
255
                # add values (as labels if available, as placeholders 
 
256
                # otherwise) and possibly a total
 
257
                labels_dic = self.val_dics.get(var_name, {})
 
258
                subitems_lst = [] # build subitems list
 
259
                for (i, (key, val_label)) in enumerate(labels_dic.items()):
 
260
                    if i > 1:
 
261
                        break
 
262
                    subitems_lst.append(val_label)
 
263
                if item_conf.sort_order == dimtables.SORT_LABEL:
 
264
                    subitems_lst.sort()
 
265
                i=len(subitems_lst) + 1 # so first filler is Val 2 if first 
 
266
                # value already filled
 
267
                while len(subitems_lst) < 2:
 
268
                    subitems_lst.append("Value %s" % i)
 
269
                    i=i+1
 
270
                if item_conf.has_tot:
 
271
                    subitems_lst.append(make_table.HAS_TOTAL)
 
272
                for subitem in subitems_lst:
 
273
                    # make val node e.g. Male
 
274
                    subitem_node = dimtables.LabelNode(label=subitem)
 
275
                    new_var_node.addChild(subitem_node)                
 
276
                    if is_terminal and dim==dimtables.COLDIM and \
 
277
                        self.has_col_measures:
 
278
                        # add measure label nodes
 
279
                        measures = item_conf.measures_lst
 
280
                        if not measures:
 
281
                            measures = [self.default_measure]
 
282
                        for measure in measures:
 
283
                            subitem_node.addChild(dimtables.LabelNode(\
 
284
                                                label=measure,
 
285
                                                measure=measure))
 
286
                    else:
 
287
                        # for each child of tree_dims_item e.g. Eth and Age Gp
 
288
                        if dim == dimtables.COLDIM:
 
289
                            tree = self.coltree
 
290
                        elif dim == dimtables.ROWDIM:
 
291
                            tree = self.rowtree
 
292
                        child_items = util.getTreeCtrlChildren(tree=tree, 
 
293
                                                        parent=tree_dims_item)
 
294
                        #print util.getSubTreeItems(tree=tree, parent=tree_dims_item) #debug
 
295
                        for child_item in child_items:
 
296
                            self.addSubtreeToLabelTree(tree_dims_item=\
 
297
                                   child_item, tree_labels_node=subitem_node, 
 
298
                                   dim=dim)
 
299
    
 
300
    def addSubtreesToColLabelTree(self, tree_col_labels):
 
301
        """
 
302
        Add subtrees to column label tree.
 
303
        If coltree has no children, (not even the col no vars item)
 
304
        do not add one hee (unlike Live Tables).  It will be handled
 
305
        by the calling class e.g. by adding measures or raising an
 
306
        exception.
 
307
        """
 
308
        col_children = util.getTreeCtrlChildren(tree=self.coltree, 
 
309
                                                parent=self.colRoot)
 
310
        for col_child_item in col_children:
 
311
            self.addSubtreeToLabelTree(tree_dims_item=col_child_item, 
 
312
                          tree_labels_node=tree_col_labels.root_node, 
 
313
                          dim=dimtables.COLDIM)
 
314
        return tree_col_labels
 
315
    
 
316
 
 
317
class GenDemoTable(DemoDimTable):
 
318
    "A general demo table"
 
319
    
 
320
    has_row_measures = False
 
321
    has_row_vals = True
 
322
    has_col_measures = True
 
323
    default_measure = make_table.get_default_measure(make_table.COL_MEASURES)
 
324
    
 
325
    def __init__(self, txtTitles, txtSubtitles, colRoot, rowRoot, rowtree, 
 
326
                 coltree, col_no_vars_item, var_labels, val_dics, fil_css):
 
327
        DemoDimTable.__init__(self, txtTitles, txtSubtitles, colRoot, rowRoot, 
 
328
                           rowtree, coltree, col_no_vars_item, var_labels, 
 
329
                           val_dics, fil_css)
 
330
        
 
331
    def getDemoHTMLIfOK(self):
 
332
        "Show demo table if sufficient data to do so"
 
333
        has_rows = util.getTreeCtrlChildren(tree=self.rowtree, 
 
334
                                    parent=self.rowRoot)
 
335
        has_cols = util.getTreeCtrlChildren(tree=self.coltree, 
 
336
                                         parent=self.colRoot)
 
337
        if has_rows and has_cols:
 
338
            return self.getDemoHTML()
 
339
        else:
 
340
            return ""
 
341
    
 
342
    def getHdrDets(self, row_label_cols_n):
 
343
        """
 
344
        Return tree_col_labels and the table header HTML.
 
345
        For HTML provide everything from <thead> to </thead>.
 
346
        """
 
347
        tree_col_labels = dimtables.LabelNodeTree()
 
348
        tree_col_labels = self.addSubtreesToColLabelTree(tree_col_labels)
 
349
        if tree_col_labels.getDepth() == 1:
 
350
            raise Exception, "There must always be a column item " + \
 
351
                "even if only the col no vars item"
 
352
        return self.processHdrTree(tree_col_labels, row_label_cols_n)    
 
353
 
 
354
    def getBodyHtmlRows(self, row_label_rows_lst, tree_row_labels,
 
355
                        tree_col_labels):
 
356
        """
 
357
        Make table body rows based on contents of row_label_rows_lst:
 
358
        e.g. [["<tr>", "<td class='firstrowvar' rowspan='8'>Gender</td>" ...],
 
359
        ...]
 
360
        It already contains row label data - we need to add the data cells 
 
361
        into the appropriate row list within row_label_rows_lst before
 
362
        concatenating and appending "</tr>".
 
363
        """
 
364
        #print row_label_rows_lst #debug
 
365
        col_term_nodes = tree_col_labels.getTerminalNodes()
 
366
        row_term_nodes = tree_row_labels.getTerminalNodes()
 
367
        col_filters_lst = [x.filts for x in col_term_nodes]
 
368
        col_filt_flds_lst = [x.filt_flds for x in col_term_nodes]
 
369
        col_tots_lst = [x.is_coltot for x in col_term_nodes]
 
370
        col_measures_lst = [x.measure for x in col_term_nodes]
 
371
        row_filters_lst = [x.filts for x in row_term_nodes]
 
372
        row_filt_flds_lst = [x.filt_flds for x in row_term_nodes]
 
373
        data_cells_n = len(row_term_nodes) * len(col_term_nodes)
 
374
        #print "%s data cells in table" % data_cells_n
 
375
        row_label_rows_lst = self.getRowLabelsRowLst(row_filters_lst, 
 
376
            row_filt_flds_lst, col_measures_lst, col_filters_lst, 
 
377
            col_tots_lst, col_filt_flds_lst, row_label_rows_lst, 
 
378
            data_cells_n, col_term_nodes)
 
379
        return row_label_rows_lst
 
380
                
 
381
    def getRowLabelsRowLst(self, row_filters_lst, row_filt_flds_lst, 
 
382
                           col_measures_lst, col_filters_lst, 
 
383
                           col_tots_lst, col_filt_flds_lst, 
 
384
                           row_label_rows_lst, data_cells_n,
 
385
                           col_term_nodes):
 
386
        """
 
387
        Get list of row data.  Each row in the list is represented
 
388
        by a row of strings to concatenate, one per data point.
 
389
        """
 
390
        i=0
 
391
        data_item_presn_lst = []
 
392
        for (row_filter, row_filt_flds) in zip(row_filters_lst,
 
393
                                               row_filt_flds_lst):
 
394
            first = True
 
395
            for (colmeasure, col_filter, coltot, col_filt_flds) in \
 
396
                        zip(col_measures_lst, col_filters_lst, 
 
397
                            col_tots_lst, col_filt_flds_lst):
 
398
                if first:
 
399
                    cellclass = "firstdatacell"
 
400
                    first = False
 
401
                else:
 
402
                    cellclass = "datacell"
 
403
                #build data row list
 
404
                data_val = random.choice(num_data_seq)
 
405
                if colmeasure in [dimtables.ROWPCT, dimtables.COLPCT]:
 
406
                    val = "%s%%" % data_val
 
407
                else:
 
408
                    val = data_val
 
409
                data_item_presn_lst.append("<td class='%s'>%s</td>" % \
 
410
                                           (cellclass, val))
 
411
                i=i+1
 
412
        i=0
 
413
        # put the cell data (inc html) into the right places
 
414
        for row in row_label_rows_lst:
 
415
            for j in range(len(col_term_nodes)):
 
416
                row.append(data_item_presn_lst[i])
 
417
                i=i+1
 
418
        return row_label_rows_lst
 
419
    
 
420
    
 
421
class SummDemoTable(DemoDimTable):
 
422
    "A summary demo table"
 
423
 
 
424
    has_row_measures = True
 
425
    has_row_vals = False
 
426
    has_col_measures = False
 
427
    default_measure = make_table.get_default_measure(make_table.ROW_SUMM)
 
428
    
 
429
    def __init__(self, txtTitles, txtSubtitles, colRoot, rowRoot, rowtree, 
 
430
                 coltree, col_no_vars_item, var_labels, val_dics, fil_css):
 
431
        DemoDimTable.__init__(self, txtTitles, txtSubtitles, colRoot, rowRoot, 
 
432
                           rowtree, coltree, col_no_vars_item, var_labels, 
 
433
                           val_dics, fil_css)
 
434
 
 
435
    def getDemoHTMLIfOK(self):
 
436
        "Show demo table if sufficient data to do so"
 
437
        has_rows = util.getTreeCtrlChildren(tree=self.rowtree, 
 
438
                                    parent=self.rowRoot)
 
439
        return self.getDemoHTML() if has_rows else ""
 
440
            
 
441
    def getHdrDets(self, row_label_cols_n):
 
442
        """
 
443
        Return tree_col_labels and the table header HTML.
 
444
        For HTML provide everything from <thead> to </thead>.
 
445
        If no column variables, make a special column node.
 
446
        """
 
447
        tree_col_labels = dimtables.LabelNodeTree()
 
448
        tree_col_labels = self.addSubtreesToColLabelTree(tree_col_labels)
 
449
        if tree_col_labels.getDepth() == 1:
 
450
            tree_col_labels.addChild(dimtables.LabelNode(label="Measures"))
 
451
        return self.processHdrTree(tree_col_labels, row_label_cols_n)
 
452
 
 
453
    def getBodyHtmlRows(self, row_label_rows_lst, tree_row_labels,
 
454
                        tree_col_labels):
 
455
        """
 
456
        Make table body rows based on contents of row_label_rows_lst:
 
457
        e.g. [["<tr>", "<td class='firstrowvar' rowspan='8'>Gender</td>" ...],
 
458
        ...]
 
459
        It already contains row label data - we need to add the data cells 
 
460
        into the appropriate row list within row_label_rows_lst before
 
461
        concatenating and appending "</tr>".
 
462
        """
 
463
        col_term_nodes = tree_col_labels.getTerminalNodes()
 
464
        row_term_nodes = tree_row_labels.getTerminalNodes()
 
465
        row_measures_lst = [x.measure for x in row_term_nodes]
 
466
        col_filters_lst = [x.filts for x in col_term_nodes] #can be [[],[],[], ...]
 
467
        row_filt_flds_lst = [x.filt_flds for x in row_term_nodes]
 
468
        col_filt_flds_lst = [x.filt_flds for x in col_term_nodes]
 
469
        col_tots_lst = [x.is_coltot for x in col_term_nodes]
 
470
        data_cells_n = len(row_term_nodes) * len(col_term_nodes)
 
471
        #print "%s data cells in table" % data_cells_n
 
472
        row_label_rows_lst = self.getRowLabelsRowLst(row_filt_flds_lst, 
 
473
                                row_measures_lst, col_filters_lst, 
 
474
                                row_label_rows_lst, col_term_nodes)
 
475
        return row_label_rows_lst
 
476
    
 
477
    def getRowLabelsRowLst(self, row_flds_lst,  
 
478
                           row_measures_lst, col_filters_lst, 
 
479
                           row_label_rows_lst, col_term_nodes):
 
480
        """
 
481
        Get list of row data.  Each row in the list is represented
 
482
        by a row of strings to concatenate, one per data point.
 
483
        Get data values one at a time (no batches unlike Gen Tables).
 
484
        """
 
485
        data_item_lst = []
 
486
        for (rowmeasure, row_fld_lst) in zip(row_measures_lst, 
 
487
                                             row_flds_lst):
 
488
            first = True
 
489
            for col_filter_lst in col_filters_lst:
 
490
                #styling
 
491
                if first:
 
492
                    cellclass = "firstdatacell"
 
493
                    first = False
 
494
                else:
 
495
                    cellclass = "datacell"
 
496
                data_val = random.choice(num_data_seq)
 
497
                if rowmeasure == dimtables.SUMM_N:
 
498
                    val = "N=%s" % data_val
 
499
                else:
 
500
                    val = data_val
 
501
                data_item_lst.append("<td class='%s'>%s</td>" % \
 
502
                                     (cellclass, val))
 
503
        i=0
 
504
        for row in row_label_rows_lst:
 
505
            for j in range(len(col_term_nodes)):
 
506
                row.append(data_item_lst[i])
 
507
                i=i+1
 
508
        return row_label_rows_lst
 
 
b'\\ No newline at end of file'