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
Es ist ein Fehler aufgetreten

Es ist ein Fehler aufgetreten

Was ist das Problem?

Bei der Ausführung des Skriptes ist ein Fehler aufgetreten. Irgendetwas funktioniert nicht richtig.

Wie kann ich das Problem lösen?

Öffnen Sie die aktuelle Log-Datei im Ordner var/logs bzw. app/logs und suchen Sie die zugehörige Fehlermeldung (normalerweise die letzte).

Weitere Informationen

Die Skriptausführung wurde gestoppt, weil irgendetwas nicht korrekt funktioniert. Die eigentliche Fehlermeldung wird aus Sicherheitsgründen hinter dieser Meldung verborgen und findet sich in der aktuellen Log-Datei (siehe oben). Wenn Sie die Fehlermeldung nicht verstehen oder nicht wissen, wie das Problem zu beheben ist, durchsuchen Sie die Contao-FAQs oder besuchen Sie die Contao-Supportseite.