SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question 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?

  2. #2
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Have you thought about using Google Charts? It makes this type of stuff pretty easy.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  3. #3
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    Hiding from the world
    Posts
    357
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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...ynamic-scaling

    Code:
    <?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);
    
    ?>
    If i am a product of your imagination you should try harder!

  4. #4

  5. #5
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •