Add-On Tree
Informations
Author:InterWorld.SDNLicense: FPDF
Description
This extension allows to draw a tree from an array structure. It uses MultiCell() to display the nodes and offers several rendering options.Source
<?php
////////////////////////////////////////////////////
// PDF Tree
//
// Extension for the FPDF Class (http://www.fpdf.org) to print a tree based on an array structure
// where each internal array represents a node and its elements the children
//
// Copyright (C) 2004 InterWorld Srl (ITALY)
// http://www.webjam.it
//-------------------------------------------------------------------
// VERSIONS:
// 1.0 : Initial release
// BUGS:
// 1) Does not support multipage
// 2) Problems when the text of each line in the nodes is bigger then the width given.
////////////////////////////////////////////////////
/**
* PDF Tree
* @package PDF
* @authors:
* - Simone Cosci <simone@webarts.it>
* - Raffaele Montagnani <raffaele@webarts.it>
* @copyright 2004 InterWorld Srl
* @return double (height of the tree)
* @desc Print a Tree from an Array Structure
* @param $data array // Data in Array format
* @param $x int // Starting X position (units from lMargin) default=0
* @param $nodeFormat string // Format of a node, where %k is the Key of element; default='+%k'
* @param $childFormat string // Format of a terminal child (leaf), where %k is the key of element and %v is the value; default='-%k: %v'
* @param $w int // Width of the nodes; default=20
* @param $h int // Height of the nodes; default=5
* @param $border int // Border of the nodes; default=1 (0=N, 1=Y)
* @param $fill boolean // Fill the nodes; default=false
* @param $align string // Align of the text in the nodes; default=''
* @param $indent int // Units of indentation of the children; default=1
* @param $vspacing int // Vertical nodes spacing; default=1
* @param $drawlines boolean // Draw also the lines of the tree structure; default=true
* @param $level int // Reserved (recursive use)
* @param $hcell array // Reserved (recursive use)
* @param $treeHeight double // Reserved (recursive use)
**/
require_once('fpdf.php');
class PDF_Tree extends FPDF {
function MakeTree($data, $x=0, $nodeFormat='+%k', $childFormat='-%k: %v', $w=20, $h=5, $border=1, $fill=false, $align='', $indent=1, $vspacing=1, $drawlines=true, $level=0, $hcell=array(), $treeHeight=0.00){
if(is_array($data)){
$countData = count($data); $c=0; $hcell[$level]=array();
foreach($data as $key=>$value){
$this->SetXY($x+$this->lMargin+($indent*$level), $this->GetY()+$vspacing);
if(is_array($value)){
$pStr = str_replace('%k', $key, $nodeFormat);
}else{
$pStr = str_replace('%k', $key, $childFormat);
$pStr = str_replace('%v', $value, $pStr);
}
$pStr = str_replace("\r", '', $pStr);
$pStr = str_replace("\t", '', $pStr);
while(ord(substr($pStr, -1, 1))==10)
$pStr = substr($pStr, 0, (strlen($pStr)-1));
$line = explode("\n", $pStr);
$rows = 0; $addLines = 0;
foreach ($line as $l){
$widthLine = (int)ceil($this->GetStringWidth($l));
$rows = $widthLine/$w;
if($rows>1)
$addLines+=($widthLine%$w==0) ? $rows-1 : $rows;
}
$hcell[$level][$c]=intval(count($line)+$addLines)*$h;
$this->MultiCell($w, $h, $pStr, $border, $align, $fill);
$x1 = $x+$this->lMargin+($indent*$level);
$y1 = $this->GetY()-($hcell[$level][$c]/2);
if($drawlines)
$this->Line($x1, $y1, $x1-$indent, $y1);
if($c==$countData-1){
$x1 = $x+$this->lMargin+($indent*$level)-$indent;
$halfHeight = 0;
if(isset($hcell[$level-1])){
$lastKeys = array_keys($hcell[$level-1]);
$lastKey = $lastKeys[count($lastKeys)-1];
$halfHeight = $hcell[$level-1][$lastKey]/2;
}
$y2 = $y1-$treeHeight-($hcell[$level][$c]/2)-$halfHeight-$vspacing;
if($drawlines)
$this->Line($x1, $this->GetY()-($hcell[$level][$c]/2), $x1, $y2);
}
if(is_array($value))
$treeHeight += $this->MakeTree($value, $x, $nodeFormat, $childFormat, $w, $h, $border, $fill, $align, $indent, $vspacing, $drawlines, $level+1, $hcell);
$treeHeight += $hcell[$level][$c]+$vspacing;
$c++;
}
return $treeHeight;
}
}
}
?>
Example
<?php
require('pdf_tree.php');
// LOAD DATA INTO AN ARRAY
$data = array(
'Operating Systems'=>array(
'Microsoft Windows'=>array(
'3.1'=>'NotAvailable',
'NT'=>'$120.00',
'95'=>'$120.00',
'98'=>'$120.00',
'2000'=>array(
'Home'=>'$120.00',
'Professional'=>'$320.00',
'Server'=>'$1200.00'
),
'ME'=>'NotAvailable',
'XP'=>'NotAvailable'
),
'Linux'=>array(
'Red Hat',
'Debian',
'Mandrake'
),
'FreeBSD',
'AS400',
'OS/2'
),
'Food'=>array(
'Fruits'=>array(
'Apple',
'Pear'
),
'Vegetables'=>array(
'Carot',
'Salad',
'Bean'
),
'Chicken',
'Hamburger'
)
);
// CREATE PDF
$pdf=new PDF_Tree();
$pdf->SetMargins(5, 0, 5);
$pdf->SetAutoPageBreak(true, 0);
$pdf->AddPage();
$pdf->SetFont('Arial', '', 5);
$pdf->SetFillColor(150, 150, 150);
$pdf->SetDrawColor(20, 20, 20);
$pdf->SetTextColor(0, 0, 0);
$pdf->Cell(0, 6, 'My Tree Example', 0, '', 'R');
$pdf->Ln(6);
// TREE 1
$pdf->SetY(6);
$pdf->MakeTree($data);
// TREE 2
$startX = 30;
$nodeFormat = '[Node: %k]';
$childFormat = '[Child: %k = <%v>]';
$w = 40;
$h = 5;
$border = 0;
$fill = 0;
$align = 'L';
$indent = 2;
$vspacing = 1;
$pdf->SetY(6);
$pdf->MakeTree($data, $startX, $nodeFormat, $childFormat, $w, $h, $border, $fill, $align, $indent, $vspacing);
// TREE 3
$startX = 75;
$nodeFormat = '+%k';
$childFormat = "%k:\n%v";
$w = 20;
$h = 3;
$border = 0;
$fill = 1;
$align = 'C';
$indent = 5;
$vspacing = 3;
$pdf->SetY(6);
$pdf->MakeTree($data, $startX, $nodeFormat, $childFormat, $w, $h, $border, $fill, $align, $indent, $vspacing);
// TREE 4
$startX = 140;
$nodeFormat = '<%k>';
$childFormat = '<%k> = [%v]';
$w = 20;
$h = 3;
$border = 1;
$fill = 1;
$align = 'R';
$indent = 8;
$vspacing = 0;
$pdf->SetY(6);
$pdf->MakeTree($data, $startX, $nodeFormat, $childFormat, $w, $h, $border, $fill, $align, $indent, $vspacing);
// TREE 5
$startX = 115;
$nodeFormat = '%k';
$childFormat = '%k = [%v]';
$w = 25;
$h = 3;
$border = 0;
$fill = 1;
$align = 'J';
$indent = 18;
$vspacing = 1;
$drawlines = false;
$pdf->SetY(120);
$pdf->MakeTree($data, $startX, $nodeFormat, $childFormat, $w, $h, $border, $fill, $align, $indent, $vspacing, $drawlines);
$pdf->Output();
?>