PHP


Creating a Bar Graph using CSS and PHP
By Richard Clark
17-Jul-09
Views: 25921

The technique used to create this type of bar is to use <div>s of different height and color. Each <div> has its height and top margin.
 
The CSS and PHP Bar Graph (Page 1 of 1)
A graph using CSS and PHP is not very common but creating a graph like this is not that difficult. This technique has the following 2 advantages:
  • No graphics library is required on the server.
  • This technique doesn't require much of calculation (because options like padding and margins are built into css), thats why it is easy to understand.
mon
tue
wed
thu
fri
sat
sun

The Technique

The technique used to create this type of bar is to use <div>s of different height and color. Each <div> has its height and top margin. For every bar (<div>) in this example the following equation holds

Height of Graph = Top Margin + Height of Bar

The whole code is given below, enjoy your own css graphs

<?
	$graph_height=200;
	$days=7;	//total number of groups
 
	// define each group as an array
	$stats['visits']=array();
	$stats['unique']=array();
	$stats['direct']=array();
	$stats['external']=array();	
	$stats['page']=array();
 
 
	$bar_width=5;		//width of bar in pixels
	$bar_gap=2;			//gap between adjacent bars
	$interval_gap=40;	//gap between groups
 
	$total_bars=5;		// Will be equal to number of bars in each group
	$interval_width=($bar_width * $total_bars)+($bar_gap * ($total_bars-1));
 
	//width of the graph will be calculated dynamically
	$graph_width=($interval_width+$interval_gap)*$days + $interval_gap ;
 
	// these values will be displayed at the bottom as the graph legend
	$week_days=array('mon','tue','wed','thu','fri','sat','sun');
 ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHP CSS Graph</title>
<style>
.bar1{
	width:<?=$bar_width ?>px;
	background-color:#A55541;
	float:left;
}
.bar2{
	width:<?=$bar_width ?>px;
	background-color:#CA804F;
	float:left;
}
.bar3{
	width:<?=$bar_width ?>px;
	background-color:#CCB426;
	float:left;
}
.bar4{
	width:<?=$bar_width ?>px;
	background-color:#8EA439;
	float:left;
}
.bar5{
	width:<?=$bar_width ?>px;
	background-color:#70883E;
	float:left;
}
.gap{
	width:<?=$bar_gap ?>px;
	float:left;
}
.space{
	width:<?=$interval_gap ?>px;
	float:left;
}
</style>
</head>

<body>
	<div style="border:solid 1px #e1e1e1; background-color:#fafafa; height:<?=$graph_height ?>px; width:<?=$graph_width ?>px; padding-top:20px;">
        <div style="height:<?=$graph_height ?>px;" class="space"></div>    
<?
 
	for($i=0;$i<$days;$i++){
		// randomly assign values to each array 
		$stats['visits'][]=200 + rand(1,100);
		$stats['unique'][]=100 + rand(1,100);
		$stats['direct'][]=50 + rand(1,50);
		$stats['external'][]=50 + rand(1,50);
		$stats['page'][]=200 + rand(1,50);
 
	}
 
	$max_visits=max($stats['visits']);
	$max_unique=max($stats['unique']);
	$max_direct=max($stats['direct']);
	$max_external=max($stats['external']);
	$max_page=max($stats['page']);	
 
 
 
	$max=max($max_visits,$max_unique,$max_direct,$max_external,$max_page);
	$ratio=$graph_height/$max;	//ratio will be used to make sure that bars never go beyond graph height
 
	for($i=0;$i<$days;$i++){
 
		$visits=$stats['visits'][$i];
		$unique=$stats['unique'][$i];
		$direct=$stats['direct'][$i];
		$external=$stats['external'][$i];
		$page=$stats['page'][$i];
 
		$visits_height=intval($visits*$ratio);	// adjust the bar height according to the bar height
		$unique_height=intval($unique*$ratio);
		$direct_height=intval($direct*$ratio);
		$external_height=intval($external*$ratio);
		$page_height=intval($page*$ratio);
 
		$visits_margin=$graph_height-$visits_height;	// as Height of Graph = Top Margin + Height of Bar
		$unique_margin=$graph_height-$unique_height;
		$direct_margin=$graph_height-$direct_height;
		$external_margin=$graph_height-$external_height;
		$page_margin=$graph_height-$page_height;
 
 ?>
		<div style="height:<?=$visits_height ?>px; margin-top:<?=$visits_margin ?>px;" class="bar1"></div>
        <div style="height:<?=$graph_height ?>px;" class="gap"></div>

		<div style="height:<?=$unique_height ?>px; margin-top:<?=$unique_margin ?>px;" class="bar2"></div>
        <div style="height:<?=$graph_height ?>px;" class="gap"></div>

		<div style="height:<?=$direct_height ?>px; margin-top:<?=$direct_margin ?>px;" class="bar3"></div>
        <div style="height:<?=$graph_height ?>px;" class="gap"></div>

		<div style="height:<?=$external_height ?>px; margin-top:<?=$external_margin ?>px;" class="bar4"></div>
        <div style="height:<?=$graph_height ?>px;" class="gap"></div>

		<div style="height:<?=$page_height ?>px; margin-top:<?=$page_margin ?>px;" class="bar5"></div>

        <div style="height:<?=$graph_height ?>px;" class="space"></div>
        
<?	} ?>
		<div style="clear:both;"></div>
	</div>
	<div style="height:15px; background-color:#8c8c8c; width:<?=$graph_width ?>px; color:#FFF; border:solid 1px #666;">
		<div style="height:<?=$graph_height ?>px;" class="space"></div>
		<?	for($i=0;$i<$days;$i++){ ?>
			<div style="width:<?=$interval_width ?>px; text-align:center; float:left; font-size:9px; font-family:Verdana, Geneva, sans-serif;"><?=$week_days[$i] ?></div>
			<div style="height:<?=$graph_height ?>px;" class="space"></div>
		<? } ?>
		</div>
	</div>
</body>
</html>

This tutorial is about creating buttons which look similar to Facebook buttons. . Read More Facebook Button CSS

Comments
Pedro Silva
[06-Jan-2010]
#1

Fantastic...and simple!

Mihir Jha
[28-May-2010]
#2

Hi,

Thanks a lot for this wonderful script.

I was trying to use it to make graphical presentation of my project which has data in Mysql table. I tweaked it as much as possible and even though i m succesful to get most of the things automated still the height of the graph that i put on y-axis and 10 intervals in which i divide it is not reflecting exactly in accordance with the bars height that represent my data from mysql table. I m putting in the script as well as the table dump here. Please see if u can help. I am really clueless and it might cost me heavily on my job as well

The Script:

=================================================================

include "db.php";

//    $graph_height=400;
    $months=12;    //total number of groups
    $bar_width=10;        //width of bar in pixels
    $bar_gap=2;            //gap between adjacent bars
    $interval_gap=10;    //gap between groups

    $total_bars=5;        // Will be equal to number of bars in each group
    $interval_width=($bar_width * $total_bars)+($bar_gap * ($total_bars-1));
 
    //width of the graph will be calculated dynamically
    $graph_width=($interval_width+$interval_gap)*$months + 5*$interval_gap ;
    // these values will be displayed at the bottom as the graph legend


 
  $qt=mysql_query("select * from gd_graph");
  while($row = mysql_fetch_array($qt))
  {
  $a[]= "$row[0]";
  $b[]= "$row[1]";
  $c[]= "$row[2]";
  $d[]= "$row[3]";
  $e[]= "$row[4]";
  $f[]= "$row[5]";
  }
  
   foreach ( $a as $key => $value)
  {    
    $week_days=array("$a[0]", "$a[1]", "$a[2]", "$a[3]", "$a[4]", "$a[5]", "$a[6]","$a[7]", "$a[8]", "$a[9]", "$a[10]","$a[11]");
  }
  
   foreach ( $b as $key => $value)
  {
     $week_dayz=array("$b[0]", "$b[1]", "$b[2]", "$b[3]", "$b[4]", "$b[5]", "$b[6]","$b[7]", "$b[8]", "$b[9]", "$b[10]","$b[11]");
  }
     foreach ( $c as $key => $value)
  {
     $field1=array("$c[0]", "$c[1]", "$c[2]", "$c[3]", "$c[4]", "$c[5]", "$c[6]","$c[7]", "$c[8]", "$c[9]", "$c[10]","$c[11]");
  }
     foreach ( $d as $key => $value)
  {
     $field2=array("$d[0]", "$d[1]", "$d[2]", "$d[3]", "$d[4]", "$d[5]", "$d[6]","$d[7]", "$d[8]", "$d[9]", "$d[10]","$d[11]");
  }
     foreach ( $e as $key => $value)
  {
     $field3=array("$e[0]", "$e[1]", "$e[2]", "$e[3]", "$e[4]", "$e[5]", "$e[6]","$e[7]", "$e[8]", "$e[9]", "$e[10]","$e[11]");
  }
      foreach ( $f as $key => $value)
  {
     $field4=array("$f[0]", "$f[1]", "$f[2]", "$f[3]", "$f[4]", "$f[5]", "$f[6]","$f[7]", "$f[8]", "$f[9]", "$f[10]","$f[11]");
   
  }
 
  $maximum_week_dayz=max($week_dayz);
  $maximum_field1=max($field1);
  $maximum_field2=max($field2);
  $maximum_field3=max($field3);
  $maximum_field4=max($field4);
  $maximum=max($maximum_week_dayz,$maximum_field1,$maximum_field2,$maximum_field3,$maximum_field4);
  $top=(ceil($maximum/100))*100;
  $line_height=($top/10)+4;
  echo "line height=$line_height";
  $padding=ceil(($line_height/3+$line_height/2))/2;
  echo "Mihirjha . $padding  ";
  $graph_height=$top;
  $division=$top/10;
  $top=$top+$division;
    $misc=$division+ceil(ceil($top/100));
  //echo "$misc . Mihir";
  for($i=0;$i<11;$i++)
  {
  $top=$top-$division;
  $z[$i].=$top;
  //echo "$z[$i]";
  } 
   ?>
  
  
  


Graph Reports



PHP CSS Graph






   

       

       
       

          {
  echo "$z[$i]". "
";
  }?>

       
       
       


   

           
 
    for($i=0;$i<$months;$i++){
        // randomly assign values to each array
        // randomly assign values to each array
        $stats['visits'][]=$week_dayz[$i];
        $stats['unique'][]=$field1[$i];
        $stats['direct'][]=$field2[$i];
        $stats['external'][]=$field3[$i];
        $stats['page'][]=$field4[$i];
    }
   
    $max_visits=max($stats['visits']);
    $max_unique=max($stats['unique']);
    $max_direct=max($stats['direct']);
    $max_external=max($stats['external']);
    $max_page=max($stats['page']);   
 
    $max=max($max_visits,$max_unique,$max_direct,$max_external,$max_page);       
    $max1=(ceil($max/100))*100;
    $ratio=$graph_height/$max;
    //echo "ratio is $ratio";    //ratio will be used to make sure that bars never go beyond graph height
    $c=$max1/10;
    for($i=0;$i<11;$i++)
    {
    $max1=$max1-$c;
    $z[$i].=$max1;
   
    }
    echo $z[$i];

    for($i=0;$i<$months;$i++){
 
        $visits=$stats['visits'][$i];
        $unique=$stats['unique'][$i];
        $direct=$stats['direct'][$i];
        $external=$stats['external'][$i];
        $page=$stats['page'][$i];
 
        $visits_height=intval($visits*$ratio);    // adjust the bar height according to the bar height
        $unique_height=intval($unique*$ratio);
        $direct_height=intval($direct*$ratio);
        $external_height=intval($external*$ratio);
        $page_height=intval($page*$ratio);

 
        $visits_margin=$graph_height-$visits_height;    // as Height of Graph = Top Margin + Height of Bar
        $unique_margin=$graph_height-$unique_height;
        $direct_margin=$graph_height-$direct_height;
        $external_margin=$graph_height-$external_height;
        $page_margin=$graph_height-$page_height;

 
 ?>
       
       

       
       

       
       

       
       

       

       
       
       

       
   

   

       
       
           
           
           
       
   


=================================================================

 

The Table Dump:

CREATE TABLE `gd_graph` (
  `month` char(3) NOT NULL default '',
  `sales` int(3) NOT NULL default '0',
  `field1` varchar(6) NOT NULL,
  `field2` varchar(4) NOT NULL,
  `field3` varchar(4) NOT NULL,
  `field4` varchar(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `gd_graph`
--

INSERT INTO `gd_graph` (`month`, `sales`, `field1`, `field2`, `field3`, `field4`) VALUES
('Jan', 100, '560', '100', '100', '100'),
('Feb', 130, '20', '110', '220', '330'),
('Mar', 140, '30', '100', '200', '300'),
('Apr', 110, '40', '90', '180', '270'),
('May', 100, '50', '80', '160', '240'),
('Jun', 115, '50', '70', '140', '210'),
('Jul', 125, '60', '60', '120', '180'),
('Aug', 120, '70', '50', '100', '150'),
('Sep', 150, '80', '40', '80', '120'),
('Oct', 140, '90', '30', '60', '90'),
('Nov', 145, '100', '20', '40', '60'),
('Dec', 150, '120', '10', '20', '30');

============================================================

if u increase the maximum values in table intervals on y-axis shall automatically divide as per new max value and graph heights shall also increase but damn bars dont reflect exactly the same value as in table and also wen i reduce all values  in less than 100 or 200 it's even more pathetic. If anyone can help, please.

 

 

 

 

Posting comments has been disabled temporarily