Add-On Line graph
Informations
Author:Anthony MasterLicense: FPDF
Description
This script allows to create line-based charts. The method to use is the following:LineGraph(float w, float h, array data [, string options [, array colors [, int maxVal [, int nbDiv]]]])
w: graph width
h: graph height
data: multidimensional array containing series of data
options: string containing display options
colors: multidimensional array containing line colors; if
null
or not given, some random colors are usedmaxVal: maximum ordinate; if
0
or not given, it is automatically computednbDiv: number of vertical divisions (default value:
4
)
Source
<?php
/***********************************************************************************************************
This line graph function was developed by Anthony Master
***********************************************************************************************************/
require('fpdf.php');
class PDF_LineGraph extends FPDF {
function LineGraph($w, $h, $data, $options='', $colors=null, $maxVal=0, $nbDiv=4){
/*******************************************
Explain the variables:
$w = the width of the diagram
$h = the height of the diagram
$data = the data for the diagram in the form of a multidimensional array
$options = the possible formatting options which include:
'V' = Print Vertical Divider lines
'H' = Print Horizontal Divider Lines
'kB' = Print bounding box around the Key (legend)
'vB' = Print bounding box around the values under the graph
'gB' = Print bounding box around the graph
'dB' = Print bounding box around the entire diagram
$colors = A multidimensional array containing RGB values
$maxVal = The Maximum Value for the graph vertically
$nbDiv = The number of vertical Divisions
*******************************************/
$this->SetDrawColor(0, 0, 0);
$this->SetLineWidth(0.2);
$keys = array_keys($data);
$ordinateWidth = 10;
$w -= $ordinateWidth;
$valX = $this->getX()+$ordinateWidth;
$valY = $this->getY();
$margin = 1;
$titleH = 8;
$titleW = $w;
$lineh = 5;
$keyH = count($data)*$lineh;
$keyW = $w/5;
$graphValH = 5;
$graphValW = $w-$keyW-3*$margin;
$graphH = $h-(3*$margin)-$graphValH;
$graphW = $w-(2*$margin)-($keyW+$margin);
$graphX = $valX+$margin;
$graphY = $valY+$margin;
$graphValX = $valX+$margin;
$graphValY = $valY+2*$margin+$graphH;
$keyX = $valX+(2*$margin)+$graphW;
$keyY = $valY+$margin+.5*($h-(2*$margin))-.5*($keyH);
//draw graph frame border
if(strstr($options, 'gB')){
$this->Rect($valX, $valY, $w, $h);
}
//draw graph diagram border
if(strstr($options, 'dB')){
$this->Rect($valX+$margin, $valY+$margin, $graphW, $graphH);
}
//draw key legend border
if(strstr($options, 'kB')){
$this->Rect($keyX, $keyY, $keyW, $keyH);
}
//draw graph value box
if(strstr($options, 'vB')){
$this->Rect($graphValX, $graphValY, $graphValW, $graphValH);
}
//define colors
if($colors===null){
$safeColors = array(0, 51, 102, 153, 204, 225);
for($i=0;$i<count($data);$i++){
$colors[$keys[$i]] = array($safeColors[array_rand($safeColors)], $safeColors[array_rand($safeColors)], $safeColors[array_rand($safeColors)]);
}
}
//form an array with all data values from the multi-demensional $data array
$ValArray = array();
foreach($data as $key => $value){
foreach($data[$key] as $val){
$ValArray[]=$val;
}
}
//define max value
if($maxVal<ceil(max($ValArray))){
$maxVal = ceil(max($ValArray));
}
//draw horizontal lines
$vertDivH = $graphH/$nbDiv;
if(strstr($options, 'H')){
for($i=0;$i<=$nbDiv;$i++){
if($i<$nbDiv){
$this->Line($graphX, $graphY+$i*$vertDivH, $graphX+$graphW, $graphY+$i*$vertDivH);
} else{
$this->Line($graphX, $graphY+$graphH, $graphX+$graphW, $graphY+$graphH);
}
}
}
//draw vertical lines
$horiDivW = floor($graphW/(count($data[$keys[0]])-1));
if(strstr($options, 'V')){
for($i=0;$i<=(count($data[$keys[0]])-1);$i++){
if($i<(count($data[$keys[0]])-1)){
$this->Line($graphX+$i*$horiDivW, $graphY, $graphX+$i*$horiDivW, $graphY+$graphH);
} else {
$this->Line($graphX+$graphW, $graphY, $graphX+$graphW, $graphY+$graphH);
}
}
}
//draw graph lines
foreach($data as $key => $value){
$this->setDrawColor($colors[$key][0], $colors[$key][1], $colors[$key][2]);
$this->SetLineWidth(0.8);
$valueKeys = array_keys($value);
for($i=0;$i<count($value);$i++){
if($i==count($value)-2){
$this->Line(
$graphX+($i*$horiDivW),
$graphY+$graphH-($value[$valueKeys[$i]]/$maxVal*$graphH),
$graphX+$graphW,
$graphY+$graphH-($value[$valueKeys[$i+1]]/$maxVal*$graphH)
);
} else if($i<(count($value)-1)) {
$this->Line(
$graphX+($i*$horiDivW),
$graphY+$graphH-($value[$valueKeys[$i]]/$maxVal*$graphH),
$graphX+($i+1)*$horiDivW,
$graphY+$graphH-($value[$valueKeys[$i+1]]/$maxVal*$graphH)
);
}
}
//Set the Key (legend)
$this->SetFont('Courier', '', 10);
if(!isset($n))$n=0;
$this->Line($keyX+1, $keyY+$lineh/2+$n*$lineh, $keyX+8, $keyY+$lineh/2+$n*$lineh);
$this->SetXY($keyX+8, $keyY+$n*$lineh);
$this->Cell($keyW, $lineh, $key, 0, 1, 'L');
$n++;
}
//print the abscissa values
foreach($valueKeys as $key => $value){
if($key==0){
$this->SetXY($graphValX, $graphValY);
$this->Cell(30, $lineh, $value, 0, 0, 'L');
} else if($key==count($valueKeys)-1){
$this->SetXY($graphValX+$graphValW-30, $graphValY);
$this->Cell(30, $lineh, $value, 0, 0, 'R');
} else {
$this->SetXY($graphValX+$key*$horiDivW-15, $graphValY);
$this->Cell(30, $lineh, $value, 0, 0, 'C');
}
}
//print the ordinate values
for($i=0;$i<=$nbDiv;$i++){
$this->SetXY($graphValX-10, $graphY+($nbDiv-$i)*$vertDivH-3);
$this->Cell(8, 6, sprintf('%.1f', $maxVal/$nbDiv*$i), 0, 0, 'R');
}
$this->SetDrawColor(0, 0, 0);
$this->SetLineWidth(0.2);
}
}
?>
Example
This example displays the same chart in 4 different ways:<?php
require('linegraph.php');
$pdf = new PDF_LineGraph();
$pdf->SetFont('Arial', '', 10);
$data = array(
'Group 1' => array(
'08-02' => 2.7,
'08-23' => 3.0,
'09-13' => 3.3928571,
'10-04' => 3.2903226,
'10-25' => 3.1
),
'Group 2' => array(
'08-02' => 2.5,
'08-23' => 2.0,
'09-13' => 3.1785714,
'10-04' => 2.9677419,
'10-25' => 3.33333
)
);
$colors = array(
'Group 1' => array(114, 171, 237),
'Group 2' => array(163, 36, 153)
);
$pdf->AddPage();
// Display options: all (horizontal and vertical lines, 4 bounding boxes)
// Colors: fixed
// Max ordinate: 6
// Number of divisions: 3
$pdf->LineGraph(190, 100, $data, 'VHkBvBgBdB', $colors, 6, 3);
$pdf->AddPage();
// Display options: horizontal lines, bounding box around the abscissa values
// Colors: random
// Max ordinate: auto
// Number of divisions: default
$pdf->LineGraph(190, 100, $data, 'HvB');
$pdf->AddPage();
// Display options: vertical lines, bounding box around the legend
// Colors: random
// Max ordinate: auto
// Number of divisions: default
$pdf->LineGraph(190, 100, $data, 'VkB');
$pdf->AddPage();
// Display options: horizontal lines, bounding boxes around the plotting area and the entire area
// Colors: random
// Max ordinate: 20
// Number of divisions: 10
$pdf->LineGraph(190, 100, $data, 'HgBdB', null, 20, 10);
$pdf->Output();
?>