用于设置表格宽度的可变列宽计算算法 [英] Algorithm for calculating variable column widths for set table width
问题描述
我需要找出一种算法,该算法将在以下条件下计算列宽的优化大小:
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:
推荐答案
一个简单的解决方案是将属性分配给您的列.例如,您的Notes
列可能是flexible
.然后,您可以计算所有行上每一列的最大宽度,为所有非柔性列设置该宽度,然后将剩余空间均匀分配(或可能由其最大宽度加权)到柔性列.
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
这篇关于用于设置表格宽度的可变列宽计算算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!