Line graph

Add-On Line graph

Informations

Author:Anthony Master
License: 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 used
maxVal: maximum ordinate; if 0 or not given, it is automatically computed
nbDiv: 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();
?>
View the result here.

Download

ZIP | TGZ
An Error Occurred:Internal Server Error

Oops! An Error Occurred

The server returned a "500Internal Server Error".

Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.