Login   Register  
PHP Classes
elePHPant
Icontem

File: simplemultibar.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of LogaMurugan  >  Simple Multibar  >  simplemultibar.php  >  Download  
File: simplemultibar.php
Role: Class source
Content type: text/plain
Description: simple multi bar
Class: Simple Multibar
Render images with multiple types of bar chart
Author: By
Last change: Usage commented
Date: 3 years ago
Size: 11,360 bytes
 

Contents

Class file image Download
<?php

class simplemultibar
{
    private $_yMaxPoints;
    private $_stackBar;
    private $_lineNeeded;
    private $_pointsToIncrease;
    public function __construct($height=600, $width=800)
    {
        $this->_yMaxPoints                = 10;
        $this->height                    = $height;
        $this->width                     = $width;
        $this->padding_width_percentage  = 0.10;
        $this->padding_height_percentage = 0.10;
        
        $this->font        = './verdanab.ttf';
        $this->_initImage();

        $this->bgColor     = imagecolorallocate($this->image, 255, 255, 255);
        $this->lineColor   = imagecolorallocate($this->image, 128, 128, 128);
        $this->yLabelColor = imagecolorallocate($this->image, 128, 0, 0);
        $this->xLabelColor = imagecolorallocate($this->image, 130, 130, 130);
        $this->barColor    = imagecolorallocate($this->image, 0, 128, 0);
        
        $this->_lineNeeded  = true;
        $this->multiData   = false; /* to decide the data array is multi dimensional / not */
        $this->showTotal   = true;
        $this->_stackBar   = true;
        $this->maxValue    = 0;
        $this->_pointsToIncrease = 0;
        $this->barBgColorArr = array();
    }
    
    public function renderChart($dataArr=array(), $colorArr=array(), $title='')
    {
        $this->_setData($dataArr, $colorArr);
        $this->_initPlotArea(); 
        
        $this->_renderLines();
        $this->_renderBars();
        if ($this->multiData) {
            $this->_renderLegends();
        }
        if ($title) {
            $this->_renderTitle($title);
        }
    }
    public function setStackBar($opt=false)
    {
        $this->_stackBar = $opt;
    }
    public function setLineNeeded($needed=true)
    {
        $this->_lineNeeded = $needed;
    }
    public function setPointsIncrements($points)
    {
        $this->_pointsToIncrease = $points;
    }
    public function setMaxPoints($point=20)
    {
        $this->_yMaxPoints = $point;
    }
    private function _initImage()
    {
        $this->image = imagecreatetruecolor($this->width, $this->height);
        imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $this->bgColor);
    }

    private function _initPlotArea()
    {
        $width  = $this->width;
        if ($this->multiData) {
            $width  = ($this->width * 0.75);
        }
        $this->plotX1 = ($width * $this->padding_width_percentage);
        $this->plotY1 = ($this->height * $this->padding_height_percentage);
        $this->plotX2 = $width;
        if (!$this->multiData) {
            $this->plotX2 = ($width  - $this->plotX1);
        }
        $this->plotY2 = ($this->height - $this->plotY1);
        $this->graphHeight = $this->plotY2 - $this->plotY1;
        $this->graphWidth = $this->plotX2 - $this->plotX1;
        imageline($this->image, $this->plotX1, $this->plotY1, $this->plotX1, $this->plotY2, $this->lineColor);
        imageline($this->image, $this->plotX1, $this->plotY2, $this->plotX2, $this->plotY2, $this->lineColor);
    }
    private function _renderTitle($title)
    {
        imagettftext($this->image, 10, 0, $this->plotX1, ($this->plotY1/2), $this->xLabelColor, $this->font, $title);      
    }
    private function _renderLegends()
    {
        $availLegends = array();
        foreach ($this->dataArr as $xlabel=>$xValue) {
            $availLegends  = array_merge($availLegends, array_diff(array_keys($xValue), $availLegends));
        }
        $x1 = $this->plotX2+10;
        $y1 = $this->plotY1;
        $x2 = $x1+15;
        $y2 = $y1+20;
        foreach ($availLegends as $legend) {
            $color = isset($this->barBgColorArr[$legend])?$this->barBgColorArr[$legend]:$this->xLabelColor;
            imagefilledrectangle($this->image, $x1, $y1, $x2, $y2, $color);
            imagettftext($this->image, 8, 0, $x2+3, $y2-10, $this->xLabelColor, $this->font, $legend);      
            
            $y1 = $y2+2;
            $y2 = $y2+20;
        }
        
    }
    
    
    
    private function _setData($dataArr=array(), $colorArr=array())
    {
        $this->dataArr = $dataArr;
        $this->setColorData($colorArr);
        if (count($dataArr) == count($dataArr,1)) {
            $this->maxValue = max($dataArr);
            
        } else {
            $this->multiData = true;
            if ($this->_stackBar) {
                foreach ($dataArr as $data) {
                    if ($this->maxValue < array_sum($data)) {
                        $this->maxValue = array_sum($data);
                    }
                }
            } else {
                foreach ($dataArr as $data) {
                    if ($this->maxValue < max($data)) {
                        $this->maxValue = max($data);
                    }
                }
            }
            
        }
        
    }
    
    function getBarColor($hex='#FFFFFF')
    {
        $color = str_replace('#','',$hex);
        return imagecolorallocate($this->image, hexdec(substr($color,0,2)), hexdec(substr($color,2,2)), hexdec(substr($color,4,2)));
    }
    
    function setColorData($colorArr=array())
    {
        foreach ($colorArr as $index=>$colorValue) {
            $this->barBgColorArr[$index] = $this->getBarColor($colorValue);
        }
    }
    
    function _renderBars()
    {
        $barGap    = ($this->graphWidth * 0.04); //4% 
        $barCount  = count($this->dataArr);
        //$barGap      = 10; //gap between the bars 10px 
        $comboBarGap = 2; //2px;
        $barGapWidth = ($barGap * count($this->dataArr));
        if ($this->multiData && !$this->_stackBar) {
            $barGapWidth += $comboBarGap * (count($this->dataArr, 1) - count($this->dataArr));
        }
        $availWidth  = ($this->graphWidth - $barGapWidth);
        $barWidth    = ($availWidth / $barCount);
        
        $x1 = $this->plotX1;     
        $x2 = $this->plotX1;    
        if ($this->multiData) {
            if ($this->_stackBar) { /** stack bar */
                foreach ($this->dataArr as $xlabel=>$xValue) {
                    $x1 = $x2+$barGap;
                    $x2 = $x1+$barWidth;
                    $this->drawBarLabel($x1, $barWidth, $xlabel);
                    $y1 = false;
                    $subValue1 = 0;
                    foreach ($xValue as $xSubLabel=>$xSubValue) {
                        $subValue1 += $xSubValue;
                        $y1 = $this->drawBar($x1, $x2, $barWidth, $subValue1, $xSubLabel, $x2+2, $y1, $xSubValue, 7);
                    }
                }
            } else { /** combo bar */
                foreach ($this->dataArr as $xlabel=>$xValue) {
                    $x1+=$barGap;           
                    $width = ($barWidth / count($xValue));
                    $this->drawBarLabel($x1, $barWidth, $xlabel);
                    foreach ($xValue as $xSubLabel=>$xSubValue) {
                        $x2 = $x1+$comboBarGap;
                        $x1 = $x2+$width; 
                        $this->drawBar($x1, $x2, $width, $xSubValue, $xSubLabel, $x2);
                    }
                }
            }
        } else { /** simple bar */
            foreach ($this->dataArr as $xlabel=>$xValue) {
                $x1 = $x2+$barGap;
                $x2 = $x1+$barWidth;
                $this->drawBar($x1, $x2, $barWidth, $xValue, $xlabel, $x1);
                
                $this->drawBarLabel($x1, $barWidth, $xlabel);
            }
        }
    }
    
    function drawBarLabel($x1, $barWidth, $xlabel)
    {
        imagettftext($this->image, 9, 270, ($x1+($barWidth/2)), $this->plotY2+3, $this->xLabelColor, $this->font, $xlabel);      
    }
    
    
    private function drawBar($x1, $x2, $barWidth, $xValue, $xlabel, $xTotal, $y1=false, $total=0, $totalPos=false)
    {
        $color = isset($this->barBgColorArr[$xlabel])?$this->barBgColorArr[$xlabel]:$this->xLabelColor;
        $y1    = ($y1)?$y1:$this->plotY2;
        $y1    -= 1;
        $y2    = $this->plotY1 + ($this->graphHeight - $this->pointsToPixels($xValue, $this->maxValue, $this->graphHeight)); 
        imagefilledrectangle($this->image, $x1, $y1, $x2, $y2, $color);
        if ($this->showTotal) {
            $total = ($total)?$total:$xValue;
            $totalPos = $totalPos?($y2+$totalPos):$y2-3;
            imagettftext($this->image, 7, 0, ($xTotal), $totalPos, $this->xLabelColor, $this->font, $total);
        }
        return $y2;
    }
    
    
    
    private function _renderLines()
    {
        
        if ($this->_pointsToIncrease <= 0) { /** Not yet set. so set it */
            if ($this->maxValue > ($this->_yMaxPoints)) {
                $this->_pointsToIncrease = ($this->maxValue/$this->_yMaxPoints);
            } else {
                $this->_pointsToIncrease = 1;
                $this->_yMaxPoints = $this->maxValue;
            }
        }
        
        if ($this->_lineNeeded) {
            $pointYIncrementor = round($this->graphHeight / $this->_yMaxPoints);
            $y  = $this->plotY2;
            $labelXPosition = round($this->plotX1 / 3); /* dividing the padding space into 3 divisions and starting the text at first division */
            for($i=0; $i < $this->maxValue; $i+=$this->_pointsToIncrease) {
                imagettftext($this->image, 9, 0, $labelXPosition, $y, $this->yLabelColor, $this->font, $i);
                imageline($this->image, $this->plotX1-5, $y, $this->plotX2, $y, $this->lineColor);
                $y -= $pointYIncrementor;
            }
        }
    }
    
    function pointsToPixels($numamount, $numtotal, $for=100) 
    {
        $barCount1 = $numamount / $numtotal;
        $barCount2 = $barCount1 * $for;
        return number_format($barCount2, 0);
    }
    
    public function renderImage()
    {
        header("content-type:image/png");
        imagepng($this->image);
    }
}

/*
$dataArr['2006']=array('sachin'=>3, 'Lara'=>1, 'Ponting'=>2, 'Jacques Kallis'=>1);
$dataArr['2007']=array('sachin'=>1, 'Lara'=>1, 'Ponting'=>1, 'Jacques Kallis'=>3);
$dataArr['2008']=array('sachin'=>4, 'Lara'=>5, 'Ponting'=>2, 'Jacques Kallis'=>5);
$dataArr['2009']=array('sachin'=>9, 'Lara'=>5, 'Ponting'=>2, 'Jacques Kallis'=>8, 'Rahul Dravid'=>7, 'Sourav Ganguly'=>7);
$dataArr['2010']=array('sachin'=>7, 'Lara'=>3, 'Ponting'=>3);
$dataArr['2011']=array('sachin'=>6, 'Lara'=>2, 'Ponting'=>1);

$colorArr['sachin']='#5CB3FF';
$colorArr['Lara']='#F6358A';
$colorArr['Ponting']='#7D1B7E';
$colorArr['Jacques Kallis']='#FBB917';
$colorArr['Rahul Dravid']='#F87217';
$colorArr['Sourav Ganguly']='#009417';


$bar = new simplemultibar(728, 1200);
$bar->setStackBar(true); /** Combo chart */

//$bar->setStackBar(true); /** Stack chart */
$bar->renderChart($dataArr, $colorArr, 'Batsmen & Centuries (2008-2010)'); /** Combo / Stack chart */


//$simpleDataArr=array_combine(range(2001, 2010), range(100, 1000, 100));
//$bar->setMaxPoints(1010)
//$bar->renderChart($simpleDataArr, $colorArr=array(), 'Total Sales report'); /** Simple chart chart */

$bar->renderImage();
*/