Jump to content

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
https://forums.phpfreaks.com/topic/284456-determining-available-table-area/
Share on other sites

there's a MySQL query on the back-end and PHP loops through it all to create an array. Once the Array is built, PHP loops through it to build the table.

 

The table is a basic events calendar by location. columns are days of the week (for only seven days), rows are locations.

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.

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.

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.

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);
    
}


?>

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);
    
}


?>

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.

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.