Keyword:  
Category:
  Advance Search >>  
   Home  :  New Codes  :  Tutorials  :  Submit Material  :  Login About Us  :  Contact Us
PHP

How to create bar graph in PHP with dynamic scaling
By Junaid Shabbir
06-Aug-08
Views: 3976

Hi everyone, this tutorial will help you in creating a bar graph from PHP with the ability to adjus
 
How to create bar graph with dynamic scaling (Page 1 of 1)
Hi everyone, this tutorial will help you in creating a bar graph from PHP with the ability to adjust the scale depending upon the values provided. The technique used is smart enough to handle the number and range of values. A preview of the graph is shown below

All you need to understand this tutorial is the knowledge of following PHP image functions in addition the following PHP functions are also used and offcourse some mathematics as well If you have a good understanding of all these function, its good to go otherwise you should click on function which is new to you to consult the documentation and get back after learning all these functions

Lets get started
First of all declare an array of values for the graph. Declare these values in the form of associative array (i.e key and value pairs). Keys will be shown at the bottom as the graph legend and the values will be used to draw bars.

 $values=array(
	"Jan" => 110,
	"Feb" => 130,
	"Mar" => 215,
	"Apr" => 81,
	"May" => 310,
	"Jun" => 110,
	"Jul" => 190,
	"Aug" => 175,
	"Sep" => 390,
	"Oct" => 286,
	"Nov" => 150,
	"Dec" => 196
); 

Now define the size of image, i have used an image of size 600x400 for this tutorial.

 $img_width=600;
 $img_height=400; 

The graph we are going to create has a border around it, i have declared a variable $margins to create that border around the four sides.

 $margins=20;

Now find the size of graph by subtracting the size of borders.

 $graph_width=$img_width - $margins * 2;
 $graph_height=$img_height - $margins * 2; 

Create an image of the size defined above

 $img=imagecreate($img_width,$img_height);

Define the width of bar. Gap between the bars will depend upon the width and number of bars and the gaps will be one more than the total number of bars as there is gap on the right and left of the graph. You can see in our example, we have 12 bars but 13 gaps, thats why you see ($total_bars+1) in the denominator.

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

Define colors to be used in the graph

 $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 a border around the graph by filling in rectangle

 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); 

Now the maximum value is required to adjust the scale. Ratio is calculated by dividing graph height by maximum graph value. Each value will be multiplied with ratio, so that no bar goes beyond the graph height.

 $max_value=max($values);
 $ratio= $graph_height/$max_value; 

Drawing horizontal lines is optional, note that the margin variable is subtracted from image height so that first line is positioned inside the graph area (Discarding the margins). If you have trouble understanding this code, use a paper and pencil to manually find the values of variable at each repitition of the loop

 $horizontal_lines=20;
 $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);
 }

Here comes the most crucial part of our graph, drawing the bars. Each of the 8 lines in the for loop are individually explained below
  1. Extract key and value pair from the current pointer position, each iteration of loop moves the internal pointer of array to the next entry
  2. The x1 value (i.e. left) of each bar gets and increment by $gap+$bar_width with each iteration of loop
  3. The x2 value (i.e. right) is calculated by adding bar width with x1
  4. y1 is the top of each bar. ratio is multiplied with individual values to mare sure that bars remain inside the graph boundries.
  5. y2 (i.e bottom) is fix for all bars. Can also be placed outside the loop
  6. Draw the graph with calculated left, top, right and bottom positions
  7. The numeric value of each bar is shown at the top. Some plus or minus will be required to center align the displayed value with the bar
  8. Display the legend i.e. Month names

 for($i=0;$i< $total_bars; $i++){
	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;
	imagefilledrectangle($img,$x1,$y1,$x2,$y2,$bar_color);
	imagestring($img,0,$x1+3,$y1-10,$value,$bar_color);
	imagestring($img,0,$x1+3,$img_height-15,$key,$bar_color);
} 

Show the graph as a png image

 header("Content-type:image/png");
 imagepng($img); 

The whole script is givenbelow, just copy and enjoy your own php graphs

<?
	# ------- The graph values in the form of associative array
	$values=array(
		"Jan" => 110,
		"Feb" => 130,
		"Mar" => 215,
		"Apr" => 81,
		"May" => 310,
		"Jun" => 110,
		"Jul" => 190,
		"Aug" => 175,
		"Sep" => 390,
		"Oct" => 286,
		"Nov" => 150,
		"Dec" => 196
	);

 
	$img_width=450;
	$img_height=300; 
	$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=20;
	$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);
	$_REQUEST['asdfad']=234234;

?>

Comments

Chris
On 02-Sep-2008

Very nice example, thanks a lot.

Ranjini
On 27-Aug-2008

superb,i was searching for this for a very long period, the code helped me to complete the task, good work

Tejas Mehta
On 16-Sep-2008

This awesome. i thank Junaid Shabbir for this

eijaz sheikh
On 26-Sep-2008

Salaam Alaikum & Ramadan Mubarak. Its an Awesome tutorial! Thnx :) BTW, i am trying to get hold of a 3D horizontal stack graph script inorder to include it into my php code. I have an 3 Associative arrays : (where Key is Empcode & Value is the value). 1 for BudgetHours 1 for CompletedHours 1 for AvailableHours (i.e. BudgetHours - CompletedHours) So i need a 3D Horizontal Stack Bar graph to display per Empcode. Is this possible & if so have u written somewhat similar code for it? Please reply ASAP. Allah Haafiz. Eijaz Sheikh

Unreal Media
On 30-Sep-2008

Excellent. I might use this for my hit counter script.

fauzi
On 14-Oct-2008

I'm not having a successfull trial, there's an error on the script line 82, which is header("Content-type:image/png"); and the output ar weard symbols.thank you very much sir

Hafiz
On 08-Oct-2008

Nice Tutorial. but there is a drawback. every thing will be the image and as it will be rendered through the php so this will take a little more time too. It is good for programmers but I suggest that just do the calculation and database relative thing from php but use CSS for making images. Use PHP where you need some sort of curves.

shree Rijal
On 18-Oct-2008

its awesome working gr8 Thanks! shree

Mujie
On 20-Oct-2008

Thumbs up, great article. Its make me clear.

UMAKANT
On 21-Oct-2008

totorial of graph

Vesko Ivanov
On 21-Oct-2008

The script is very helpful. Thanks.

rano
On 16-Dec-2008

Thanks a lot... It's more easy script

Name:


Email (Required, will not be shown)


Website (Optional, starting with http://)


Comments


Are you human ?




Enter the code shown in the image