I am rewriting my company's web reporting framework at the moment. We have opted to use Google's charts API. So here is the issue: the chart API requires that you specify the range for each axis, based on the input data. So if you had 3 data points with values 1, 6 and 16, your "Y" axis range might be 0 and 16. However in order to draw axis labels with even, sensible values you might want to make the range 0-20 and have labels for 5, 10 and 15. So the problem is write a routine which calculates the nearest "sensible" number given any number. 16 gives 20, 465 gives 500, 67,584 gives 68,000 and so forth.

Here are my efforts, neither of which seem like the "right way":

function math_rndup( $num )
{
	$magn = $num / 10;
	$last = round( $magn );
	$mult = 1;
	while( $magn / 10 > 0.1 )
	{
		$last = round( $magn );
		$magn /= 10;
		$mult *= 10;
	}
	$max = $last * $mult;
	return $max;
}
function string_rndup( $val )
{
	return substr( $val, 0, 1 ) +1 . str_repeat( '0', strlen( substr( $val, 1 )));
}

Incidentally doing the string cast and manipulating it performs just as well as using math operators.

    Hi Shrike,

    Will this help. You can pass the tick size as well.

    function math_rndup( $num , $tickSize)
    {
    	if($num < $tickSize)
    		return $tickSize;
    
       $x = floor($num / $tickSize);
       $y = $num % $tickSize;	
    
       $z = $y == 0 ? $num : (($x+1) * $tickSize); 
    
       return $z;
    
    }
    
    print math_rndup(16, 5);
    

    Regards,
    niroshan

      Hi Niroshan, thanks for the post. I think its awkward to pass the tick size since you don't really know that until you have calculated the upper limit. So if you wanted to always show 10 ticks, and your upper range was 100 the ticksize would be 10. But if the upper limit was 200 the ticksize would be 20.

      Here's a real world example: The largest data point is 26 so the upper range is calculated to be 30. Number of ticks is 10 so tick size is 3.

      http://chart.apis.google.com/chart?cht=bvs&chds=0,30&chxr=0,0,30,3&chbh=a&chd=t:25,4,1,2,6,8,2,5,1,2,3,1&chl=2|3|7|8|11|12|16|17|22|23|25|26&chs=600x400&chxt=y&chtt=

        Hi Shrike,

        Your welcome. so if i understood you correctly you want to keep the no of ticks static (ex: 10) and calculate the max Yaxis dynamically keeping exact tick sizes is it? 😕 🙂

        regards,
        Niroshan

          Hi Shrike,

          function math_rndup( $num )
          {
          	$noOfTicks = 10;
          
          $w= floor($num / $noOfTicks);
          $x = $num % $noOfTicks;
          
          if($x > 0)
          {
          	$y = $w * $noOfTicks;
          	$z = $y + $noOfTicks;		
          }
          
          $tSize = $z / $noOfTicks;		
          $a = array('tick_size' => $tSize, 'Yaxis' => $z);
          
          return $a;
          }
          
          
          print '<pre>';
          print_r(math_rndup(67584));
          print '</pre>';
          
          

          Will This work? 🙂

          Regards,
          niroshan

            From your code I infer that "sensible" is rounded up to one significant figure?

            function sensible_bound($n)
            {
            	$size = pow(10, ceil(log10($val)) - 1);
            	return ceil($val / $size) * $size;
            }
            
              Weedpacket;10949169 wrote:

              From your code I infer that "sensible" is rounded up to one significant figure?

              Yep that's correct, and your example is certainly the most elegant. Thanks.

                Weedpacket;10949169 wrote:

                From your code I infer that "sensible" is rounded up to one significant figure?

                function sensible_bound($n)
                {
                	$size = pow(10, ceil(log10($val)) - 1);
                	return ceil($val / $size) * $size;
                }
                

                Tiny change ...

                function sensible_bound($n)
                
                //should be..
                
                function sensible_bound($val)
                
                

                Thanks,
                regards,
                niroshan

                  10 days later
                  Shrike;10949137 wrote:

                  I am rewriting my company's web reporting framework at the moment. We have opted to use Google's charts API.

                  I am not trying to sway your company decision but nowadays calling Google Chart API or even Google Maps API require registration for which we will be given a key and this key is needed as part of the argument we pass to Google when we call their API. I presume Google need that key to uniquely identify who make the API call and after cross certain limit start to bill your company ? E.g free for first 30,000 API calls per day and the rest cost monies ?

                  Someone recommend me JFreeChart (Java-based) API which is better as it is free and you will have more control over the formatting of the charts. For your next project you may want to consider using that instead. Of cuz, it implies you may need to use Java at your back-end instead of PHP.

                  Maybe someone can approach JFreeChart to check if they intend to release a PHP version of JFreeChart ?

                    The Google Charts API does not require an API key in the same way as Google Maps (in fact Google are doing away with that key too). The Chart API also has a 50,000 requests per day limit (after which they ask you to "get in touch with them"). 50k per day is beyond our traffic level at the moment.

                    I would not dismiss the idea of using a Java charting tool, but for now Google's service does all we need.

                      Write a Reply...