1

I need to place text in an array based on the content in the array. For example

<?php   $stuff = array (5, 15, 50, 55, 90);
for ($i=0; $i<5; $i++) {
echo "<div style=position:absolute; top:$i"."px> $stuff[$i] </div>"; 
}

will output

5

15




50
55





90

Which is what I want, however the issue is the elements in the array may be close together, like 51 instead of 55 instead:

$stuff = array (5,15,50,51,90);

which would output

5

15




overlapping 50
and 51 here





90

since the font size of the text is larger than a single pixel.

Is there a way to position the elements as close to their natural spot without overlapping -- in the example 50 would go up just a hair and 51 would go down just a hair so they dont overlap.

  • What does "just a hair higher" mean in programming?? You need to know the font size, line size and then it's just mathematics... I somewhat doubt there is a premade library for you to use. – walther Nov 15 '14 at 15:33

3 Answers3

0

Do something like this:

$stuff = array (5, 15, 50, 55, 90);
$limit = 5;

for ($i=0; $i < 5; $i++) {
    for($j=0; $j < $i; $j++) {
        if (abs($stuff[$j] - $stuff[$i]) <= $limit) $stuff[$i] += $limit;
    }

    echo "<div style=position:absolute; top:" . $i . "px> " . $stuff[$i] . " </div>";
}

This checks the distance with all previous values.

Hassan Ahmed
  • 405
  • 3
  • 9
  • 1
    Thanks Hassan -- this actually changes $stuff[$i], which I do not want to do -- but I think I'll code some logic like this in place – Neville Aga Nov 16 '14 at 04:45
0

You could use position: relative like this:

<?php

    $stuff = array (5, 15, 50, 51, 90);

    foreach($stuff as $k => $v)
        echo "<div style='position: relative; top:" . $v . "px;'>$stuff[$k]</div>"; 

?>

Update:

This should work for you:

<?php

    $stuff = array (5, 15, 50, 51, 90);

    foreach($stuff as $k => $v)
        echo "<div style='position: absolute; top:" . (($k >= 1) ? (($stuff[$k]-$stuff[$k-1] < 15) ? ($v+10) : "$v") : "$v") . "px;'>$stuff[$k]</div>";

    $stuff = array (5, 15, 50, 55, 90);

    foreach($stuff as $k => $v)
        echo "<div style='position: absolute; top:" . (($k >= 1) ? (($stuff[$k]-$stuff[$k-1] < 15) ? ($v+10) : "$v") : "$v") . "px; left: 30px'>$stuff[$k]</div>"; 

?>
Rizier123
  • 58,877
  • 16
  • 101
  • 156
  • Thanks Rizer -- the relative works great for non-overlapping, but I don't get the placement I need -- specifically I put out 2 columns side by side and if possible I want the same number to appear at the same position in the 2 columns. If one array contains 5,10,15,20,50 and the other contains 10,50 then the 50 in the 1st column would go down an extra 4 positions because of the relative tag. – Neville Aga Nov 16 '14 at 04:48
  • @NevilleAga updated my answer so that it is absolute an you can have 2 columns! Also i check if that the min. difference between the number is 15 if not im add 10 to the value – Rizier123 Nov 16 '14 at 05:18
0

So I ended up using a while loop and a incrementing an offset until the space was no longer occupied.

$stuff = array (5, 15, 50, 51, 90);
$z = array ();
for ($i=0; $i<5; $i++) {

$offset=0;
while  ( (in_array($stuff + $offset,$z)) || (in_array($stuff[1] + 1 + $offset,$z))    ) {  #this place already taken - assumes the text needs 2 px to display - adjust your math for your needs (I needed 8)
$offset++;
}

$i = $i + $offset;


#mark the spots as taken
$z[] = $stuff + $offset;
$z[] = $stuff + 1 + $offset;    


echo "<div style=position:absolute; top:$stuff[$i]"."px> $stuff[$i] </div>"; 
}