Next / Previous / Contents / TCC Help System / NM Tech homepage

10.21. hist.cgi: outputAllRows(): Build the body of the table

In the current version, the maximum number of physical columns into which we fold each logical row is determined by the constant defined in Section 13.7.1, “MAX_PHYS_COLS. This is only a maximum; if the number of logical columns plus the number of suffix columns is less than this value, that will be the number of physical columns.


An earlier version of this application allowed the user to select a value; this would not be a difficult feature to add, represented by a text entry field on the regional index form.

Conceptually, the table consists of two heading rows (represented internally by KeyRow and PartyHoursRow instances) followed by the census rows generated by the CbcHist.genCensusRows().

However, usability requires that we repeat the first heading row periodically, so that in a Web rendering the user of a reasonable-sized screen will be able to tell which year or effort is associated with any cell of a census row.

In practice, we maintain a running count (rowsSinceHeading) of the number of physical rows rendered since the last heading. When this number exceeds the constant defined in Section 13.8.3, “HEADING_REPEAT, another KeyRow is added as XHTML before the census row, and the count is reset.

# - - -   o u t p u t A l l R o w s

def outputAllRows(sox, cbcHist):
    '''Generate the Web rendering of the detail table.

      [ (sox is a sox.Sox instance) and
        (cbcHist is a CbcHist instance) ->
          sox  +:=  headings and all census rows from cbcHist ]

The detail table will be fully ruled inside and out. Quite modest amounts of cell padding are added to keep it from being completely illegible, but space may be at a premium in some cases.

    #-- 1
    # [ sox  +:=  a new table
    #   table  :=  that table element ]
    table = sox.start("table", lib.CLASS_CENSUS_TABLE)

We always start with the two different kinds of heading rows.

    #-- 2
    # [ sox  +:=  (cbcHist.keyRow as XHTML) +
    #       (cbcHist.partyHoursRow as XHTML)
    #   rowsSinceHeading  :=  0
    #   nPhysRows  :=  number of physical rows necessary to represent
    #       cbcHist.keyRow using no more than lib.MAX_PHYS_COLS
    #       physical columns
    cbcHist.keyRow.html(sox, lib.MAX_PHYS_COLS)
    cbcHist.partyHoursRow.html(sox, lib.MAX_PHYS_COLS)
    rowsSinceHeading = 0
    nPhysRows = cbcHist.keyRow.nPhysRows(lib.MAX_PHYS_COLS)

Here we generate the body of the table using the census rows generated by cbcHist, sprinkling key rows in as needed.

    #-- 3
    # [ sox  +:=  (census rows from cbcHist, with additional key
    #       rows from cbcHist interspersed no oftener than every
    #       lib.HEADING_REPEAT physical rows) ]
    for censusRow in cbcHist.genCensusRows():
        #-- 3 body
        # [ if rowsSinceHeading > lib.HEADING_REPEAT ->
        #     sox  +:=  (cbcHist.keyRow as XHTML) + (censusRow as
        #                 XHTML)
        #     rowsSinceHeading  :=  nPhysRows
        #   else ->
        #     table  +:=  censusRow as XHTML
        #     rowsSinceHeading  +:=  nPhysRows ]
        if rowsSinceHeading > lib.HEADING_REPEAT:
            cbcHist.keyRow.html(sox, lib.MAX_PHYS_COLS)
            rowsSinceHeading = 0

        censusRow.html(sox, lib.MAX_PHYS_COLS)
        rowsSinceHeading += nPhysRows

    #-- 4