I need to figure out an algorithm that will calculate the optimized size of the column widths given the following:
So given the following data:
'From' => '03/06/2014',
'To' => '03/06/2014',
'First Name' => 'John Doe',
'Status' => 'approved',
'Type' => 'PTO',
'Amount' => '8 Hours',
'Notes' => 'Oops! Who knew I would need one more day. This should be all I need over the next week to support my trip.'
How can I calculate the optimal column widths so that the 'notes' column does not squeeze the other widths down to a less than acceptable width?
UPDATE: I currently know the width of the page & the width of the font so I can calculate the max width requirements for each column. It should fill the available space on the page. However, I would prefer the columns not wrap unless necessary. Like this:
An easy solution is to assign attributes to your colums; for example your Notes
columns could be flexible
. Then you could calculate the maximum width of each column over all rows, set that width for all non-flexible columns and then distribute the remaining space evenly (or possibly weighted by their max width) to the flexible columns.
But you could also try to find out the attributes with some simple conditions:
Then go about as described above: Calculate all non-flexible columns width. Check if there is enough space; if not, make the wrappable columns flexible, too. Then calculate the width of the flexible cells, weighted by their maximum widths.
A possible pseudocode algorithm is below. It makes liberal use of various heuristics, so you should probably take it with a grain of salt. You can adjust these conditions according to your use case, but it will be difficult to cater for all possible cases.
function layout(table[], width, gutter, col[])
var maxw[col.length] # max. text width over all rows
var maxl[col.length] # max. width of longest word
var flex[col.length] # is column flexible?
var wrap[col.length] # can column be wrapped?
var colw[col.length] # final width of columns
foreach row in table:
for i = 0 to col.length:
cell = row[i]
maxw[i] = max(maxw[i], textwidth(cell))
if cell.find(" "):
maxl[i] = max(maxl[i], wordwidth(cell))
var left = width - (col.length - 1) * gutter
var avg = left / col.length
var nflex = 0
# determine whether columns should be flexible and assign
# width of non-flexible cells
for i = 0 to col.length:
flex[i] = (maxw[i] > 2 * avg) # ???
if flex[i]:
nflex++
else:
colw[i] = maxw[i]
left -= colw[i]
# if there is not enough space, make columns that could
# be word-wrapped flexible, too
if left < nflex * avg:
for i = 0 to col.length:
if !flex[i] and wrap[i]:
left += width[i]
colw[i] = 0
flex[i] = true
nflex += 1
# Calculate weights for flexible columns. The max width
# is capped at the page width to treat columns that have to
# be wrapped more or less equal
var tot = 0
for i = 0 to col.length:
if flex[i]:
maxw[i] = min(maxw[i], width) # ???
tot += maxw[i]
# Now assign the actual width for flexible columns. Make
# sure that it is at least as long as the longest word length
for i = 0 to col.length:
if flex[i]:
colw[i] = left * maxw[i] / tot
colw[i] = max(colw[i], maxl[i])
left -= colw[i]
return colw
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With