7

I cant get around on how to express this is PHP.

I have 100 and 420 as my min and max value that I wish to obtain.

Than lets suppose I have:

1000
4534
34566
123145
12312265

Now, how can I say:

Take 4534 and knowing that 1000 = 420 and 12312265 = 100 determine 4534 value.

To make it more clear, Im trying to represent web page ranks with squares, so if the rank is 1 it should be translated into my maximum value/size 420, however if the page ranks low on popularity, say 13000 then its size should be close to the minimum 100. I know all the values.

Thank you.

Im still having trouble figuring this out.

So far using the code from the first answer I have:

$srcmin=1185;
$srcmax=25791525;

$destmin=100;
$destmax=420;

$pos = (($RANK - $srcmin) / ($srcmax-$srcmin)) ;
$rescaled = ($pos * ($destmax-$destmin)) + $destmin;*/

$percentage = (($RANK - $MIN) * 100) / $MAX;
$SIZE = (($percentage / 320) * 100) + 100

Being $RANK my values for the ranks of web pages and $SIZE the value that I need to size them accordingly. This does not work (my mistake no doubt) all I get from $SIZE is 100.

Marvin
  • 503
  • 2
  • 7
  • 17
  • 1
    How exactly is 1000 = 420 and 12312265 = 100? That doesn't make sense? – Daniel Egeberg Jun 28 '10 at 23:06
  • I want the more higher the value the smaller it will turn out. This is for a page rank and square representing it, if google rank is 1 then it size should be my biggest thus 420, but if the page is some other with a rank of 13000 then it shpuld be smaller thus aproaching my minimum size of 100. – Marvin Jun 28 '10 at 23:07

4 Answers4

7

This should illustrate....

$values=array(1000, 4534, 34566, 123145, 12312265);
$srcmin=$values[0];
$srcmax=$values[count($values)-1];

$destmin=420;
$destmax=100;

foreach($values as $x)
{
     //how far in the source range is $x (0..1)
     $pos = (($x - $srcmin) / ($srcmax-$srcmin)) 

     //figure out where that puts us in the destination range
     $rescaled = ($pos * ($destmax-$destmin)) + $destmin;
}

You want to know how far through the source range each number is, that's what the $pos value gives you. Given that, you can translate that into how far through the destination range you are.

Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
  • Thank you, but i cant use an array, can you explain it as im looping the values from a DB? – Marvin Jun 28 '10 at 23:11
  • 1
    ignore the array, replace with whatever will give you a value you want to translate – Paul Dixon Jun 28 '10 at 23:12
  • 2
    Loop through the values from the DB and store them into an array, then do this. – Austin Fitzpatrick Jun 28 '10 at 23:15
  • is $x the value form the item I want to determine the size correct? – Marvin Jun 28 '10 at 23:17
  • yes - you simply need to know what the min and max values in your source range are also ($srcmin and $srcmax in the example) – Paul Dixon Jun 28 '10 at 23:19
  • so is this correct? *$srcmin=1185; $srcmax=25791525; $destmin=100; $destmax=420; $pos = (($RANK - $srcmin) / ($srcmax-$srcmin)) ; $rescaled = ($pos * ($destmax-$destmin)) + $destmin; Sorry dont know how to format comments. – Marvin Jun 28 '10 at 23:32
1

I think you mean

$min=100;
$max=420;
$range = $max - $min;
$nums = [10,15,20,25,30]; // Edit this as you please
$relMin = min($nums);
$relMax = max($nums);
$relRange = $relMax - $relMin;
foreach($nums as $num)
{
  $pct = ($num - $relMin)/$relRange;
  echo "$num is %$pct between $relMin and $relMax";
  $val = $pct*$range + $min;
  echo "$pct of the range between $min and $max is $val";
}
linked
  • 1,258
  • 1
  • 14
  • 25
1

What you need to do is

(1) find [0..1] position of each value in the range of values, 1000 meaning x=0 and 123145 meaning x=1;

(2) invert it, because you want the smallest number to have the greatest width (x=1-x)

(3) translate that number [0..1] to the width range you wanted.

$values = array(1000, 4534, 34566, 123145);
$minV = min($values);
$maxV = max($values);
$minW = 100;
$maxW = 420;
foreach($values as $v)
{
    $width = $minW + ($maxW - $minW) * (1 - (($v - $minV) / ($maxV - $minV)));
    echo "<div style='width:".$width."px;background-color:red;padding:5px;'></div>";
}

or you could generalize it in a function:

function invTranslate($value)
{
    $min1 = 1000;
    $max1 = 123145;
    $min2 = 100;
    $max2 = 420;
    return $min2 + ($max2 - $min2) * (1 - (($value - $min1) / ($max1 - $min1)));
}

and use it like:

<div style="width:<?=invTranslate(5000)?>px"></div>
<div style="width:<?=invTranslate(100000)?>px"></div>
<div style="width:<?=invTranslate(90000)?>px"></div>
Gorkem Pacaci
  • 1,741
  • 1
  • 11
  • 9
  • Thank you, please can you rewrite it letting go the array and just passing it a number between the minV and maxV? I cant remove the array and make it work. Like I know the maxV and minV and also know what value ill pass to it. – Marvin Jun 28 '10 at 23:47
  • I wrote it as a function with constants inside, hoping that's what you wanted. – Gorkem Pacaci Jun 29 '10 at 00:30
  • Thank you for your example I already solved it but your approach is also interesting. – Marvin Jun 29 '10 at 00:38
0

First, determine your minimum and maximum values of the data you have. Then, your question is equivalent to this one --

We'll call MIN your target minimum, and MAX your target max. We'll call val_min the minimum of your values and val_max the maximum of your values.

Then you need to find both ranges -- RANGE = MAX-MIN, val_range = val_max - val_min

Now, you can start the conversion.

First, turn your to-be-converted value into a number between 0 and 1, with val_min mapping to 0 and val_max mapping to 1:

normed_value = (value - val_min) / val_range

Then, map that 0 to 1 value to your final range:

final_scaled_value = MIN + (normed_value * RANGE)
Community
  • 1
  • 1
Justin L.
  • 13,510
  • 5
  • 48
  • 83
  • How do I do this: First, turn your to-be-converted value into a number between 0 and 1, with val_min mapping to 0 and val_max mapping to 1:" ? – Marvin Jun 28 '10 at 23:56
  • the code right after it, "normed value", is the number between 0 and 1. – Justin L. Jun 29 '10 at 00:10