Drawing a bar chart

Our site has several PHP scripts that draw bar and line charts automatically from climate data. With one chart, the swing in the data is dramatic, so the script needs to account for the Y axis having different scales on different days. I want the script to automatically calculate “intuitive” tick marks on the Y axis, with no more than about 10 such marks. If the maximum Y value is, say, 42, I want an equation that automatically determines that 5 is the best interval. Or if the maximum value is something like 9,211, I want the equation to come up with 1,500 as the interval. Any suggestions?

Have you thought about using Google Charts? It makes this type of stuff pretty easy. :slight_smile:

Hi,
just came across this fantastic dynamic graph for a page i was working on.

I ran the query off my database but you can just specify values straight into the array part.

this is the article i used http://www.qualitycodes.com/tutorial.php?articleid=20&title=How-to-create-bar-graph-in-PHP-with-dynamic-scaling


<?php 
// connect to database
$mysql_link = mysql_connect("localhost", "usernamne","password"); 
mysql_select_db('yourdb', $mysql_link); 
	
$nid = mysql_real_escape_string($_GET['nid']);						 	
			   // Query for time of day    
				$sql_address_time = mysql_query("SELECT * FROM your_table WHERE nid = '$nid' ") 
			   or die (mysql_error()); 
			   
			   //count the rows returned
			   $totalRows_row_time = mysql_num_rows($sql_address_time); 
			   if($totalRows_row_time ==''){ 
			   	
					//no results returned so we'll just put 0 for everthing so it doesn't mess up the graph.
//need at least one value so i put 1 in the first one.
					$morning = 1;
					$afternoon = 0;
					$evening = 0;
			   
			   }
			   else{
			   
			   //$track =0;
			   $morning =0;
			   $afternoon =0;
			   $evening =0;
				while($results_time = mysql_fetch_array($sql_address_time)){
				
//sorry a bit messsy as i was extracting part of a date that is returned.
					$cleanedstr = substr_replace($results_time['atime'], "", 0, 11);
					$cleanedstr2 = substr_replace($cleanedstr, "", -3, 3);
					$cleanedstr3 = substr_replace($cleanedstr2, "", 2, 1);
					//echo $cleanedstr3;
					//echo '<br>';
					
					if($cleanedstr3 <=1200){ ++$morning ;}
					elseif($cleanedstr3 >1200 && $cleanedstr3 <=1800){ ++$afternoon ;}
					elseif($cleanedstr3 >=1801 && $cleanedstr3 <=2359){ ++$evening ;}
					
					//$track = ++$track;
				
				}
			}
				//echo '<p>Opened between 00:00-12:00 - <strong>'.$morning.'</strong></p>';
				//echo '<p>Opened between 12:00-18:00 - <strong>'.$afternoon.'</strong></p>';
				//echo '<p>Opened between 18:00-00:00 - <strong>'.$evening.'</strong></p>';
				//echo 'tracked - '.$track;	


///if you want you can get rid of the above code  and just put values directly into the array below just replace $morning etc 

	# ------- The graph values in the form of associative array
	$values=array(
		"Morning" => "$morning",
		"Afternoon" => "$afternoon",
		"Evening" => "$evening"
	);

 
	$img_width=250;
	$img_height=200; 
	$margins=20;

 
	# ---- Find the size of graph by substracting the size of borders
	$graph_width=$img_width - $margins * 2;
	$graph_height=$img_height - $margins * 2; 
	$img=imagecreate($img_width,$img_height);

 
	$bar_width=20;
	$total_bars=count($values);
	$gap= ($graph_width- $total_bars * $bar_width ) / ($total_bars +1);

 
	# -------  Define Colors ----------------
	$bar_color=imagecolorallocate($img,0,64,128);
	$background_color=imagecolorallocate($img,240,240,255);
	$border_color=imagecolorallocate($img,200,200,200);
	$line_color=imagecolorallocate($img,220,220,220);
 
	# ------ Create the border around the graph ------

	imagefilledrectangle($img,1,1,$img_width-2,$img_height-2,$border_color);
	imagefilledrectangle($img,$margins,$margins,$img_width-1-$margins,$img_height-1-$margins,$background_color);

 
	# ------- Max value is required to adjust the scale	-------
	$max_value=max($values);
	$ratio= $graph_height/$max_value;

 
	# -------- Create scale and draw horizontal lines  --------
	$horizontal_lines=10;
	$horizontal_gap=$graph_height/$horizontal_lines;

	for($i=1;$i<=$horizontal_lines;$i++){
		$y=$img_height - $margins - $horizontal_gap * $i ;
		imageline($img,$margins,$y,$img_width-$margins,$y,$line_color);
		$v=intval($horizontal_gap * $i /$ratio);
		imagestring($img,0,5,$y-5,$v,$bar_color);

	}
 
 
	# ----------- Draw the bars here ------
	for($i=0;$i< $total_bars; $i++){ 
		# ------ Extract key and value pair from the current pointer position
		list($key,$value)=each($values); 
		$x1= $margins + $gap + $i * ($gap+$bar_width) ;
		$x2= $x1 + $bar_width; 
		$y1=$margins +$graph_height- intval($value * $ratio) ;
		$y2=$img_height-$margins;
		imagestring($img,0,$x1+3,$y1-10,$value,$bar_color);
		imagestring($img,0,$x1+3,$img_height-15,$key,$bar_color);		
		imagefilledrectangle($img,$x1,$y1,$x2,$y2,$bar_color);
	}
	header("Content-type:image/png");
	imagepng($img);

?>

I’ve found pChart really nice.

Thanks for the suggestions. Although I already have the charts created, I can use the suggestions to refine the look. (I’m currently looking for a way to fill a polygon with a gradient.) My question was aimed at the making the Y axis user friendly. I could simply divide the axis into 10 parts, but the numbers produced wouldn’t be “neat” ones since the scale is based on the maximum Y value.

The charts I created are based on CSV files that are updated every hour. I looked through the Google Chart documentation and, at first glance, I didn’t see a way to have the charts pull CSV data automatically.