计算表格宽度的可变列宽的算法

Chu*_*ess 8 algorithm math

我需要找出一个算法来计算列宽的优化大小,给出以下内容:

  • 表的宽度固定为页面的大小
  • 列内的数据将是可变的,因此列的宽度是可变的
  • 必须优化宽度以知道何时包装列以及何时不包括

所以给出以下数据:

'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.'
Run Code Online (Sandbox Code Playgroud)

如何计算最佳色谱柱宽度,以便"音符"列不会将其他宽度压缩到小于可接受的宽度?

问题的样本

更新:我目前知道页面的宽度和字体的宽度,所以我可以计算每列的最大宽度要求.它应该填充页面上的可用空间.但是,除非必要,否则我希望列不包装.像这样:

在此输入图像描述

M O*_*ehm 7

一个简单的解决方案是为您的列分配属性; 例如,您的Notes列可能是flexible.然后,您可以计算所有行上每列的最大宽度,为所有非灵活列设置该宽度,然后将剩余空间均匀分布(或者可能按其最大宽度加权)到灵活列.

但您也可以尝试使用一些简单的条件找出属性:

  • 如果列中的任何条目中包含空格,则列可以是自动换行的.在您的示例中,无法包装日期以及可能的状态和类型条目.该名称不应在正常情况下包装,但如果名称很长或者给出了多个名称,则可以包装.notes列应该被包装.
  • 如果列的最大宽度超过,例如,如果所有尺寸均匀分布,则单元格的宽度应该是灵活的.

然后按照上述说明:计算所有非柔性列的宽度.检查是否有足够的空间; 如果没有,也可以使可包装的柱子变得灵活.然后计算柔性单元格的宽度,按其最大宽度加权.

可能的伪代码算法如下.它可以自由地使用各种启发式方法,所以你应该把它当作一粒盐.您可以根据用例调整这些条件,但很难满足所有可能的情况.

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
Run Code Online (Sandbox Code Playgroud)

  • 是的,但这也是我提出的伪代码的目的.(你觉得好像我没有理解这个问题.我想我已经.)我实际上已经在Python中实现了算法(输出到具有固定宽度字符的终端,其中文本宽度只是字符串长度然后将其改装成伪代码,因为我不知道你使用的语言是什么.结果看起来还不错,但我当然可以将其与结果的屏幕截图进行比较. (3认同)