Jump to content

determining available table area


michaellunsford

Recommended Posts

In a dynamically built table, what might be a way to identify large groups of empty cells that are clustered together? The goal is to combine them with rowspan and colspan attributes and drop an image in the empty space.

 

There will be some guesswork involved in calculating actual area -- but the big challenge to overcome first is identifying and combining blank cells across rows. Any ideas?

Link to comment
Share on other sites

By "large" I mean three or more empty rows and two or more empty columns clustered together in an HTML table. If all the columns in any particular location (displayed in rows) is completely empty for the entire week, it won't be displayed. So, each row has at least one column populated.

 

The events and vacancies tend to cluster. The tough part is identifying clusters of empty cells in that HTML table (that the script is building from an array), so it can combine them using colspan and rowspan attributes. These areas will be populated with an image.

Link to comment
Share on other sites

Off hand I would say you'd probably want to first load all your data for the tables into an array, either multi-dimensional (row/column) or serial. Once you have that array you can loop through it checking for empty elements and handle them accordingly. Searching for consecutive empty cells would be relatively easy, when you find an empty cell just keep checking the next until you find a non-empty one.

 

If you want to check other surrounding empty cells (above, below, diagonal) that would increase the difficulty some. If you could post some examples of the table you have and how you'd like it to appear instead that may help in devising a solution.

Link to comment
Share on other sites

is this image just a pattern to style the empty cells/region or is it a specific image that conveys some information, such as a picture of something?

 

for the first case, set the cellspacing of the table to zero and use a css class to set the background-image of the empty cells to be the url of your pattern image.

Link to comment
Share on other sites

This might help

<?php
$xr = 10;
$xc = 7;

//
// generate array of cells
// X if data, ' ' if blank
//
$cells = array();
for ($r = 0; $r < $xr; $r++) {
    for ($c = 0; $c < $xc; $c++) {
        $cells[$r][$c] = rand(0,2)<1 ? 'X' : ' ';
    }
}

$gaps = array();
for ($r = 0; $r < $xr-1; $r++) {
    for ($c = 0; $c < $xc-1; $c++) {
        if ($cells[$r][$c]==' ') {
            $gs = gapsize($cells, $r, $c, $xr, $xc);
            if ($gs[3]>=3) { // accept 3 or more rows only
                $gaps[] = $gs;
            }
        }
    }
}

if (count($gaps) > 0) {
    rsort($gaps);
    vprintf("Largest suitable area is %d cells at row %d, col %d (%d rows x %d cols)<br>", $gaps[0]);
}
else echo "No suitable area found<br>";


// output the array
echo '<table border="1" style="border-collapse:collapse">';
echo "<tr><th></th>";
for ($i=0; $i<$xc; $i++) echo "<th>$i</th>";
echo "</tr>";
for ($r = 0; $r < $xr; $r++) {
    echo "<tr><th>$r</th>";
    echo '<td>' . join('</td><td>', $cells[$r]) . '</td>';
    echo '<tr>';
}
echo '</table>';

function gapsize(&$cells, $r, $c, $xr, $xc) 
{
    if (($cells[$r][$c+1]!=' ')||($cells[$r+1][$c]!=' ')||($cells[$r+1][$c+1]!=' ')) {
        return array (1, $r, $c, 1, 1);
    }
    $arr = array();
    $ccount=0;
    $c1 = $c;
    while ($c1 < $xc) {
        if ($cells[$r][$c1]==' ') {
            $arr[]=$c1;
            ++$ccount;
            ++$c1;
        }
        else break;
    }
    $depths = array_fill_keys($arr, 1);
    foreach ($arr as $k=>$c2) {
        $r1 = $r+1;
        if ($cells[$r1][$c2] != ' ') {
            #$arr = array_slice($arr, 0, $k);
            $ccount = $k;
        } else {
            while ($r1 < $xr) {
                if ($cells[$r1][$c2]== ' ') {
                    $depths[$c2]++;
                }
                else {
                    break;
                }
                $r1++;
            }
            if ($k > 0 && $depths[$c2] < 3) $ccount = $k;
        }
    }
    $depths = array_slice($depths,0,$ccount);
    $arr = array_slice($arr,0,$ccount);
    $rcount = min($depths);
    return array($rcount*$ccount,$r,$c,$rcount,$ccount);
    
}


?>

Link to comment
Share on other sites

OK, sprayed it with a can of "Datakill" to get rid of a couple of bugs and gave it a coat of varnish

<?php
$xr = 10;
$xc = 7;

//
// generate array of cells
// X if data, ' ' if blank
//
$cells = array();
for ($r = 0; $r < $xr; $r++) {
    for ($c = 0; $c < $xc; $c++) {
        $cells[$r][$c] = rand(0,2)<1 ? 'X' : ' ';
    }
}

$gaps = array();
for ($r = 0; $r < $xr-1; $r++) {
    for ($c = 0; $c < $xc-1; $c++) {
        if ($cells[$r][$c]==' ') {
            $gs = gapsize($cells, $r, $c, $xr, $xc);
            if ($gs[3]>=3  && $gs[4]>=2) { // accept 3+ rows x 2+ cols only
                $gaps[] = $gs;
            }
        }
    }
}

if (count($gaps) > 0) {
    rsort($gaps);
    vprintf("Largest suitable area is %d cells at row %d, col %d (%d rows x %d cols)<br>", $gaps[0]);
}
else echo "No suitable area found<br>";

// set boundary vars for output
if (isset($gaps[0])) {
    list ($count, $row, $col, $rowcount, $colcount) = $gaps[0];
    $rend = $row + $rowcount - 1;
    $cend = $col + $colcount - 1;
}
else {
    $row = $col = $rend = $cend = 999;
    $rowcount = $colcount = 0;
}
// output the array
echo '<table border="1" style="border-collapse:collapse">';
echo "<tr><th></th>";
for ($i=0; $i<$xc; $i++) echo "<th>$i</th>";
echo "</tr>\n";
foreach ($cells as $r => $rowdata) {
    echo "<tr><th>$r</th>";
    if ($r < $row || $r > $rend) {
        echo "<td>" . join('</td><td>', $rowdata) . "</td></tr>\n";
    } else {
        foreach ($rowdata as $c => $cell) {
            if ($r==$row && $c==$col) {
                echo "<td rowspan='$rowcount' colspan='$colcount' style='background-color:#ccc'> </td>";
            }
            else {
                if ($c < $col || $c > $cend)
                    echo "<td>$cell</td>";
            }
        }
        echo "</tr>\n";
    }
}
echo '</table>';

function gapsize(&$cells, $r, $c, $xr, $xc) 
{
    if (($cells[$r][$c+1]!=' ')||($cells[$r+1][$c]!=' ')||($cells[$r+1][$c+1]!=' ')) {
        return array (1, $r, $c, 1, 1);
    }
    $arr = array();
    $ccount=0;
    $c1 = $c;
    while ($c1 < $xc) {
        if ($cells[$r][$c1]==' ') {
            $arr[]=$c1;
            ++$ccount;
            ++$c1;
        }
        else break;
    }
    $depths = array_fill_keys($arr, 1);
    foreach ($arr as $k=>$c2) {
        $r1 = $r+1;
        if ($cells[$r1][$c2] != ' ') {
            #$arr = array_slice($arr, 0, $k);
            $ccount = $k;
        } else {
            while ($r1 < $xr) {
                if ($cells[$r1][$c2]== ' ') {
                    $depths[$c2]++;
                }
                else {
                    break;
                }
                $r1++;
            }
            if ($k > 0 && $depths[$c2] < 3) {
                $ccount = $k;
                break;
            }
        }
    }
    $depths = array_slice($depths,0,$ccount);
    $arr = array_slice($arr,0,$ccount);
    $rcount = min($depths);
    return array($rcount*$ccount,$r,$c,$rcount,$ccount);
    
}


?>

Link to comment
Share on other sites

Woah, Sen, that's just awesome! Hopefully with a few tweaks it'll find more than just the one space (if more than one exists, that is).

 

To answer mac_gyver's question -- it's a photograph of one of the events listed in the table. I'll probably end up putting an in-line style in the spanned cell with a centered (and roughly scaled) background image so it doesn't push the table out of shape.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.