SharpLeaf Tutorials > Table Tutorials > Splitting Blocks of Columns

Splitting Blocks of Columns

There are several strategies to scale or split a table when it is larger than the available frame width.

Target Width and Column Widths

In the table sizing tutorial we’ve seen that relative-sized columns (negative column widths) share the width that’s left from the fixed-size (positive column widths) and auto-fit (zero column widths), once we’ve substracted them from the target width (which defaults to the available frame width).

   table = new string[][] {new string[]{"Sales","Jan","Feb","Mar","Apr","May","Jun",
            "Jul","Aug","Sep","Oct","Nov","Dec","Notes"},new string[]{"Suspenders",
            "36","59","20","45","63","50","26","10","50","64","60","68",""},new 
            string[]{"Pillows","78","66","72","27","74","44","21","46","62","48","39",
            "90",""},new string[]{"Garden gnomes","13","15","10","14","14","19","18",
            "16","12","12","11","11","Febrile activity"},new string[]{"Hair curlers",
            "49","25","40","31","61","64","58","32","66","28","33","48",""},new 
            string[]{"Pop corn","56","96","N/A","35","46","85","56","65","86","56",
            "84","39","Temporary closure in March"},new string[]{"Door mats","70","67",
            "57","55","42","71","78","56","78","63","56","77",""},new 
            string[]{"Firecrackers","86","51","12","23","41","44","81","47","22","47",
            "51","90","Seasonal activity"},new string[]{"Lemon squeezers","23","27",
            "28","43","12","33","47","48","34","17","19","26",""}};

   tb = new Table();
   tb.SetTitles(1,1);
  // Auto-fit first column, fixed-size widths for data, last column takes remaining width
   tb.SetColumnWidths(new int[] {0,30,30,30,30,30,30,30,30,30,30,30,30,-1});
   tb.AddRows(table);

   lf.IncludeTable(tb);  // Target frame width with no scaling

A couple of things to observe in this example:

  • The table doesn’t fit the default target width (which is the frame width) so it is split into two blocks of columns
  • Titles are repeated on all blocks
  • Last column was down-sized to its minimum width because other columns already have eaten more than the target width.

At that point we could try and force the fit, using the fourth argument of the SharpLeaf.IncludeTable method:

   lf.IncludeTable(tb,BoxFlow.Paragraph,-1,true);  // Force table to fit one frame width

Scaling to fit the target width doesn’t solve the problem of the last column width – because the other columns still overflow the target width. What we really need a bigger target width

   lf.IncludeTable(tb,BoxFlow.Paragraph,-2);  // Target width of two frames, not forcing the fit

There is no guarantee that table fits the target width without some scaling (see the SharpLeaf.IncludeTable documentation). In this case, it’s because column widths do not exactly add up to block width, and because the table is not scaled down to fit the width.

Forcing the fit to the target width

   lf.IncludeTable(tb,BoxFlow.Paragraph,-2,true);  // Force table to fit two frame widths

This is becoming nice – two-frame width allows the relative-sized column to have enough width, and the table is slightly scaled down for the columns to fit exactly on two frames. Notice that in some cases, the blocks may have un-even widths, for example column widths of {50,-1,50} with a blockwidth of 100 and a targetwidth of 200.

But now that our table is split into blocks, we want to repeat the notes column on all blocks.

   tb = new Table();
   tb.SetTitles(1,1);
  // Auto-fit first column, fixed-size widths for data, last column takes remaining width
   tb.SetColumnWidths(new int[] {0,30,30,30,30,30,30,30,30,30,30,30,30,-1});
   tb.AddRows(table);
   tb.SetColumnRetain(-1);  // Retain last column (on top of first which is a title)

   lf.Style.SpaceAfter=12; // add 12 points between table block (thanks to BoxFlow.Paragraph);
   lf.IncludeTable(tb,BoxFlow.Paragraph,-2,true);

Since the un-repeated columns have the same width, they split more nicely into blocks, but again, in the general case, columns may not always divide blocks evenly.

Scaling the Table

In some cases, we may prefer to force scaling down the table so that relative-sized columns have enough width AND the whole table fit the target width. This is achieved by the scaling factor argument of the IncludeTable method:

  // Another strategy to fit one frame width is to scale by a factor of 0.5
   lf.IncludeTable(tb,BoxFlow.Paragraph,-1,true,-1,0.5);
  // We can then split it into two blocks using half the frame width
   lf.IncludeTable(tb,BoxFlow.Right,-1,true,-0.5,0.5);
   lf.AddParagraphs("Scaling the table should be done with care because the table "+
            "fonts may become much smaller than the paragraph font…");

See also ...

Table Tutorials | SharpLeaf.IncludeTable Method | Table Members


Send comments on this topic
© Dyalog Ltd 2021