Ignore:
Timestamp:
Apr 14, 2019, 2:31:40 PM (5 years ago)
Author:
roby
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/client/modules/Elezioni/grafici/jpgraph_bar.php

    r265 r267  
    11<?php
    22/*=======================================================================
    3  // File:        JPGRAPH_BAR.PHP
    4  // Description: Bar plot extension for JpGraph
    5  // Created:     2001-01-08
    6  // Ver:         $Id: jpgraph_bar.php 1905 2009-10-06 18:00:21Z ljp $
    7  //
    8  // Copyright (c) Asial Corporation. All rights reserved.
    9  //========================================================================
    10  */
     3// File:        JPGRAPH_BAR.PHP
     4// Description: Bar plot extension for JpGraph
     5// Created:     2001-01-08
     6// Ver:         $Id: jpgraph_bar.php 1017 2008-07-08 06:09:28Z ljp $
     7//
     8// Copyright (c) Aditus Consulting. All rights reserved.
     9//========================================================================
     10*/
    1111
    1212require_once('jpgraph_plotband.php');
     
    2626//===================================================
    2727// CLASS BarPlot
    28 // Description: Main code to produce a bar plot
     28// Description: Main code to produce a bar plot 
    2929//===================================================
    3030class BarPlot extends Plot {
     
    3737    protected $width=0.4; // in percent of major ticks
    3838    protected $abswidth=-1; // Width in absolute pixels
    39     protected $ybase=0; // Bars start at 0
     39    protected $ybase=0; // Bars start at 0 
    4040    protected $align="center";
    4141    protected $bar_shadow=false;
    4242    protected $bar_shadow_color="black";
    43     protected $bar_shadow_hsize=3,$bar_shadow_vsize=3;
    44     protected $bar_3d=false;
    45     protected $bar_3d_hsize=3,$bar_3d_vsize=3;
    46 
    47     //---------------
    48     // CONSTRUCTOR
    49     function __construct($datay,$datax=false) {
    50         parent::__construct($datay,$datax);
    51         ++$this->numpoints;
    52     }
    53 
    54     //---------------
    55     // PUBLIC METHODS
    56 
     43    protected $bar_shadow_hsize=3,$bar_shadow_vsize=3; 
     44       
     45//---------------
     46// CONSTRUCTOR
     47    function BarPlot($datay,$datax=false) {
     48        $this->Plot($datay,$datax);             
     49        ++$this->numpoints;
     50    }
     51
     52//---------------
     53// PUBLIC METHODS       
     54       
    5755    // Set a drop shadow for the bar (or rather an "up-right" shadow)
    58     function SetShadow($aColor="black",$aHSize=3,$aVSize=3,$aShow=true) {
    59         $this->bar_shadow=$aShow;
    60         $this->bar_shadow_color=$aColor;
    61         $this->bar_shadow_vsize=$aVSize;
    62         $this->bar_shadow_hsize=$aHSize;
    63 
    64         // Adjust the value margin to compensate for shadow
    65         $this->value->margin += $aVSize;
    66     }
    67 
    68     function Set3D($aHSize=3,$aVSize=3,$aShow=true) {
    69         $this->bar_3d=$aShow;
    70         $this->bar_3d_vsize=$aVSize;
    71         $this->bar_3d_hsize=$aHSize;
    72 
    73         $this->value->margin += $aVSize;
    74     }
    75 
     56    function SetShadow($color="black",$hsize=3,$vsize=3,$show=true) {
     57        $this->bar_shadow=$show;
     58        $this->bar_shadow_color=$color;
     59        $this->bar_shadow_vsize=$vsize;
     60        $this->bar_shadow_hsize=$hsize;
     61               
     62        // Adjust the value margin to compensate for shadow
     63        $this->value->margin += $vsize;
     64    }
     65               
    7666    // DEPRECATED use SetYBase instead
    7767    function SetYMin($aYStartValue) {
    78         //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead.");
    79         $this->ybase=$aYStartValue;
     68        //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead.");           
     69        $this->ybase=$aYStartValue;
    8070    }
    8171
    8272    // Specify the base value for the bars
    8373    function SetYBase($aYStartValue) {
    84         $this->ybase=$aYStartValue;
    85     }
    86 
    87     // The method will take the specified pattern anre
    88     // return a pattern index that corresponds to the original
    89     // patterm being rotated 90 degreees. This is needed when plottin
    90     // Horizontal bars
    91     function RotatePattern($aPat,$aRotate=true) {
    92         $rotate = array(1 => 2, 2 => 1, 3 => 3, 4 => 5, 5 => 4, 6 => 6, 7 => 7, 8 => 8);
    93         if( $aRotate ) {
    94             return $rotate[$aPat];
    95         }
    96         else {
    97             return $aPat;
    98         }
    99     }
    100 
     74        $this->ybase=$aYStartValue;
     75    }
     76       
    10177    function Legend($graph) {
    102         if( $this->grad && $this->legend!="" && !$this->fill ) {
    103             $color=array($this->grad_fromcolor,$this->grad_tocolor);
    104             // In order to differentiate between gradients and cooors specified as an RGB triple
    105             $graph->legend->Add($this->legend,$color,"",-$this->grad_style,
    106             $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
    107         }
    108         elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) {
    109             if( is_array($this->iPattern) ) {
    110                 $p1 = $this->RotatePattern( $this->iPattern[0], $graph->img->a == 90 );
    111                 $p2 = $this->iPatternColor[0];
    112                 $p3 = $this->iPatternDensity[0];
    113             }
    114             else {
    115                 $p1 = $this->RotatePattern( $this->iPattern, $graph->img->a == 90 );
    116                 $p2 = $this->iPatternColor;
    117                 $p3 = $this->iPatternDensity;
    118             }
    119             if( $p3 < 90 ) $p3 += 5;
    120             $color = array($p1,$p2,$p3,$this->fill_color);
    121             // A kludge: Too mark that we add a pattern we use a type value of < 100
    122             $graph->legend->Add($this->legend,$color,"",-101,
    123                                 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
    124         }
    125         elseif( $this->fill_color && $this->legend!="" ) {
    126             if( is_array($this->fill_color) ) {
    127                 $graph->legend->Add($this->legend,$this->fill_color[0],"",0,
    128                 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
    129             }
    130             else {
    131                 $graph->legend->Add($this->legend,$this->fill_color,"",0,
    132                 $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
    133             }
    134         }
     78        if( $this->grad && $this->legend!="" && !$this->fill ) {
     79            $color=array($this->grad_fromcolor,$this->grad_tocolor);
     80            // In order to differentiate between gradients and cooors specified as an RGB triple
     81            $graph->legend->Add($this->legend,$color,"",-$this->grad_style,
     82                                $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
     83        }
     84        elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) {
     85            if( is_array($this->iPattern) ) {
     86                $p1 = $this->iPattern[0];
     87                $p2 = $this->iPatternColor[0];
     88                $p3 = $this->iPatternDensity[0];
     89            }
     90            else {
     91                $p1 = $this->iPattern;
     92                $p2 = $this->iPatternColor;
     93                $p3 = $this->iPatternDensity;
     94            }
     95            $color = array($p1,$p2,$p3,$this->fill_color);
     96            // A kludge: Too mark that we add a pattern we use a type value of < 100
     97            $graph->legend->Add($this->legend,$color,"",-101,
     98                                $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
     99        }
     100        elseif( $this->fill_color && $this->legend!="" ) {
     101            if( is_array($this->fill_color) ) {
     102                $graph->legend->Add($this->legend,$this->fill_color[0],"",0,
     103                                    $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
     104            }
     105            else {
     106                $graph->legend->Add($this->legend,$this->fill_color,"",0,
     107                                    $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);   
     108            }
     109        }
    135110    }
    136111
    137112    // Gets called before any axis are stroked
    138113    function PreStrokeAdjust($graph) {
    139         parent::PreStrokeAdjust($graph);
    140 
    141         // If we are using a log Y-scale we want the base to be at the
    142         // minimum Y-value unless the user have specifically set some other
    143         // value than the default.
    144         if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 )
    145         $this->ybase = $graph->yaxis->scale->GetMinVal();
    146 
    147         // For a "text" X-axis scale we will adjust the
    148         // display of the bars a little bit.
    149         if( substr($graph->axtype,0,3)=="tex" ) {
    150             // Position the ticks between the bars
    151             $graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0);
    152 
    153             // Center the bars
    154             if( $this->abswidth > -1 ) {
    155                 $graph->SetTextScaleAbsCenterOff($this->abswidth);
    156             }
    157             else {
    158                 if( $this->align == "center" )
    159                 $graph->SetTextScaleOff(0.5-$this->width/2);
    160                 elseif( $this->align == "right" )
    161                 $graph->SetTextScaleOff(1-$this->width);
    162             }
    163         }
    164         elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) {
    165             // We only set an absolute width for linear and int scale
    166             // for text scale the width will be set to a fraction of
    167             // the majstep width.
    168             if( $this->abswidth == -1 ) {
     114        parent::PreStrokeAdjust($graph);
     115
     116        // If we are using a log Y-scale we want the base to be at the
     117        // minimum Y-value unless the user have specifically set some other
     118        // value than the default.
     119        if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 )
     120            $this->ybase = $graph->yaxis->scale->GetMinVal();
     121               
     122        // For a "text" X-axis scale we will adjust the
     123        // display of the bars a little bit.
     124        if( substr($graph->axtype,0,3)=="tex" ) {
     125            // Position the ticks between the bars
     126            $graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0);
     127
     128            // Center the bars
     129            if( $this->abswidth > -1 ) {
     130                $graph->SetTextScaleAbsCenterOff($this->abswidth);
     131            }
     132            else {
     133                if( $this->align == "center" )
     134                    $graph->SetTextScaleOff(0.5-$this->width/2);
     135                elseif( $this->align == "right" )
     136                    $graph->SetTextScaleOff(1-$this->width);                   
     137            }
     138        }
     139        elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) {
     140            // We only set an absolute width for linear and int scale
     141            // for text scale the width will be set to a fraction of
     142            // the majstep width.
     143            if( $this->abswidth == -1 ) {
    169144                // Not set
    170                 // set width to a visuable sensible default
    171                 $this->abswidth = $graph->img->plotwidth/(2*$this->numpoints);
    172             }
    173         }
     145                // set width to a visuable sensible default
     146                $this->abswidth = $graph->img->plotwidth/(2*$this->numpoints);
     147            }
     148        }
    174149    }
    175150
    176151    function Min() {
    177         $m = parent::Min();
    178         if( $m[1] >= $this->ybase ) $m[1] = $this->ybase;
    179         return $m;
     152        $m = parent::Min();
     153        if( $m[1] >= $this->ybase )
     154            $m[1] = $this->ybase;
     155        return $m;     
    180156    }
    181157
    182158    function Max() {
    183         $m = parent::Max();
    184         if( $m[1] <= $this->ybase ) $m[1] = $this->ybase;
    185         return $m;
    186     }
    187 
     159        $m = parent::Max();
     160        if( $m[1] <= $this->ybase )
     161            $m[1] = $this->ybase;
     162        return $m;     
     163    }   
     164       
    188165    // Specify width as fractions of the major stepo size
    189166    function SetWidth($aWidth) {
    190         if( $aWidth > 1 ) {
    191             // Interpret this as absolute width
    192             $this->abswidth=$aWidth;
    193         }
    194         else {
    195             $this->width=$aWidth;
    196         }
    197     }
    198 
     167        if( $aWidth > 1 ) {
     168            // Interpret this as absolute width
     169            $this->abswidth=$aWidth;
     170        }
     171        else
     172            $this->width=$aWidth;
     173    }
     174       
    199175    // Specify width in absolute pixels. If specified this
    200176    // overrides SetWidth()
    201177    function SetAbsWidth($aWidth) {
    202         $this->abswidth=$aWidth;
    203     }
    204 
     178        $this->abswidth=$aWidth;
     179    }
     180               
    205181    function SetAlign($aAlign) {
    206         $this->align=$aAlign;
    207     }
    208 
     182        $this->align=$aAlign;
     183    }
     184       
    209185    function SetNoFill() {
    210         $this->grad = false;
    211         $this->fill_color=false;
    212         $this->fill=false;
    213     }
    214 
     186        $this->grad = false;
     187        $this->fill_color=false;
     188        $this->fill=false;
     189    }
     190               
    215191    function SetFillColor($aColor) {
    216         // Do an extra error check if the color is specified as an RGB array triple
    217         // In that case convert it to a hex string since it will otherwise be
    218         // interpretated as an array of colors for each individual bar.
    219 
    220         $aColor = RGB::tryHexConversion($aColor);
    221         $this->fill = true ;
    222         $this->fill_color=$aColor;
    223 
    224     }
    225 
     192        $this->fill = true ;
     193        $this->fill_color=$aColor;
     194    }
     195       
    226196    function SetFillGradient($aFromColor,$aToColor=null,$aStyle=null) {
    227         $this->grad = true;
    228         $this->grad_fromcolor = $aFromColor;
    229         $this->grad_tocolor   = $aToColor;
    230         $this->grad_style     = $aStyle;
    231     }
    232 
     197        $this->grad = true;
     198        $this->grad_fromcolor = $aFromColor;
     199        $this->grad_tocolor   = $aToColor;
     200        $this->grad_style     = $aStyle;
     201    }
     202       
    233203    function SetValuePos($aPos) {
    234         $this->valuepos = $aPos;
     204        $this->valuepos = $aPos;
    235205    }
    236206
    237207    function SetPattern($aPattern, $aColor='black'){
    238         if( is_array($aPattern) ) {
    239             $n = count($aPattern);
    240             $this->iPattern = array();
    241             $this->iPatternDensity = array();
    242             if( is_array($aColor) ) {
    243                 $this->iPatternColor = array();
    244                 if( count($aColor) != $n ) {
    245                     JpGraphError::RaiseL(2001);//('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()');
    246                 }
    247             }
    248             else {
    249                 $this->iPatternColor = $aColor;
    250             }
    251             for( $i=0; $i < $n; ++$i ) {
    252                 $this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]);
    253                 if( is_array($aColor) ) {
    254                     $this->iPatternColor[$i] = $aColor[$i];
    255                 }
    256             }
    257         }
    258         else {
    259             $this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity);
    260             $this->iPatternColor = $aColor;
    261         }
     208        if( is_array($aPattern) ) {
     209            $n = count($aPattern);
     210            $this->iPattern = array();
     211            $this->iPatternDensity = array();
     212            if( is_array($aColor) ) {
     213                $this->iPatternColor = array();
     214                if( count($aColor) != $n ) {
     215                    JpGraphError::RaiseL(2001);//('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()');
     216                }
     217            }
     218            else
     219                $this->iPatternColor = $aColor;
     220            for( $i=0; $i < $n; ++$i ) {
     221                $this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]);
     222                if( is_array($aColor) ) {
     223                    $this->iPatternColor[$i] = $aColor[$i];
     224                }
     225            }
     226        }
     227        else {
     228            $this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity);
     229            $this->iPatternColor = $aColor;
     230        }
    262231    }
    263232
    264233    function _SetPatternHelper($aPattern, &$aPatternValue, &$aDensity){
    265         switch( $aPattern ) {
    266             case PATTERN_DIAG1:
    267                 $aPatternValue= 1;
    268                 $aDensity = 92;
    269                 break;
    270             case PATTERN_DIAG2:
    271                 $aPatternValue= 1;
    272                 $aDensity = 78;
    273                 break;
    274             case PATTERN_DIAG3:
    275                 $aPatternValue= 2;
    276                 $aDensity = 92;
    277                 break;
    278             case PATTERN_DIAG4:
    279                 $aPatternValue= 2;
    280                 $aDensity = 78;
    281                 break;
    282             case PATTERN_CROSS1:
    283                 $aPatternValue= 8;
    284                 $aDensity = 90;
    285                 break;
    286             case PATTERN_CROSS2:
    287                 $aPatternValue= 8;
    288                 $aDensity = 78;
    289                 break;
    290             case PATTERN_CROSS3:
    291                 $aPatternValue= 8;
    292                 $aDensity = 65;
    293                 break;
    294             case PATTERN_CROSS4:
    295                 $aPatternValue= 7;
    296                 $aDensity = 90;
    297                 break;
    298             case PATTERN_STRIPE1:
    299                 $aPatternValue= 5;
    300                 $aDensity = 94;
    301                 break;
    302             case PATTERN_STRIPE2:
    303                 $aPatternValue= 5;
    304                 $aDensity = 85;
    305                 break;
    306             default:
    307                 JpGraphError::RaiseL(2002);
    308                 //('Unknown pattern specified in call to BarPlot::SetPattern()');
    309         }
    310     }
    311 
    312     function Stroke($img,$xscale,$yscale) {
    313 
    314         $numpoints = count($this->coords[0]);
    315         if( isset($this->coords[1]) ) {
    316             if( count($this->coords[1])!=$numpoints ) {
    317                 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints);
    318             //"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints");
    319             }
    320             else {
    321                 $exist_x = true;
    322             }
    323         }
    324         else {
    325             $exist_x = false;
    326         }
    327 
    328 
    329         $numbars=count($this->coords[0]);
    330 
    331         // Use GetMinVal() instead of scale[0] directly since in the case
    332         // of log scale we get a correct value. Log scales will have negative
    333         // values for values < 1 while still not representing negative numbers.
    334         if( $yscale->GetMinVal() >= 0 )
    335         $zp=$yscale->scale_abs[0];
    336         else {
    337             $zp=$yscale->Translate(0);
    338         }
    339 
    340         if( $this->abswidth > -1 ) {
    341             $abswidth=$this->abswidth;
    342         }
    343         else {
    344             $abswidth=round($this->width*$xscale->scale_factor,0);
    345         }
    346 
    347         // Count pontetial pattern array to avoid doing the count for each iteration
    348         if( is_array($this->iPattern) ) {
    349             $np = count($this->iPattern);
    350         }
    351 
    352         $grad = null;
    353         for($i=0; $i < $numbars; ++$i) {
    354 
    355             // If value is NULL, or 0 then don't draw a bar at all
    356             if ($this->coords[0][$i] === null || $this->coords[0][$i] === '' )
    357             continue;
    358 
    359             if( $exist_x ) {
    360                 $x=$this->coords[1][$i];
    361             }
    362             else {
    363                 $x=$i;
    364             }
    365 
    366             $x=$xscale->Translate($x);
    367 
    368             // Comment Note: This confuses the positioning when using acc together with
    369             // grouped bars. Workaround for fixing #191
    370             /*
    371             if( !$xscale->textscale ) {
    372             if($this->align=="center")
    373             $x -= $abswidth/2;
    374             elseif($this->align=="right")
    375             $x -= $abswidth;
    376             }
    377             */
    378             // Stroke fill color and fill gradient
    379             $pts=array(
    380             $x,$zp,
    381             $x,$yscale->Translate($this->coords[0][$i]),
    382             $x+$abswidth,$yscale->Translate($this->coords[0][$i]),
    383             $x+$abswidth,$zp);
    384             if( $this->grad ) {
    385                 if( $grad === null ) {
    386                     $grad = new Gradient($img);
    387                 }
    388                 if( is_array($this->grad_fromcolor) ) {
    389                     // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array
    390                     // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be
    391                     // an array to specify both (from, to style) for each individual bar. The way to know the difference is
    392                     // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB
    393                     // triple.
    394                     $ng = count($this->grad_fromcolor);
    395                     if( $ng === 3 ) {
    396                         if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) {
    397                             // RGB Triple
    398                             $fromcolor = $this->grad_fromcolor;
    399                             $tocolor = $this->grad_tocolor;
    400                             $style = $this->grad_style;
    401                         }
    402                         else {
    403                             $fromcolor = $this->grad_fromcolor[$i % $ng][0];
    404                             $tocolor = $this->grad_fromcolor[$i % $ng][1];
    405                             $style = $this->grad_fromcolor[$i % $ng][2];
    406                         }
    407                     }
    408                     else {
    409                         $fromcolor = $this->grad_fromcolor[$i % $ng][0];
    410                         $tocolor = $this->grad_fromcolor[$i % $ng][1];
    411                         $style = $this->grad_fromcolor[$i % $ng][2];
    412                     }
    413                     $grad->FilledRectangle($pts[2],$pts[3],
    414                                            $pts[6],$pts[7],
    415                                            $fromcolor,$tocolor,$style);
    416                 }
    417                 else {
    418                     $grad->FilledRectangle($pts[2],$pts[3],
    419                     $pts[6],$pts[7],
    420                     $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style);
    421                 }
    422             }
    423             elseif( !empty($this->fill_color) ) {
    424                 if(is_array($this->fill_color)) {
    425                     $img->PushColor($this->fill_color[$i % count($this->fill_color)]);
    426                 } else {
    427                     $img->PushColor($this->fill_color);
    428                 }
    429                 $img->FilledPolygon($pts);
    430                 $img->PopColor();
    431             }
    432 
    433 /////////////////////////kokorahen rectangle polygon//////////////////////
    434 
    435             // Remember value of this bar
    436             $val=$this->coords[0][$i];
    437 
    438             if( !empty($val) && !is_numeric($val) ) {
    439                 JpGraphError::RaiseL(2004,$i,$val);
    440                 //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\'');
    441             }
    442 
    443             // Determine the shadow
    444             if( $this->bar_shadow && $val != 0) {
    445 
    446                 $ssh = $this->bar_shadow_hsize;
    447                 $ssv = $this->bar_shadow_vsize;
    448                 // Create points to create a "upper-right" shadow
    449                 if( $val > 0 ) {
    450                     $sp[0]=$pts[6];  $sp[1]=$pts[7];
    451                     $sp[2]=$pts[4];  $sp[3]=$pts[5];
    452                     $sp[4]=$pts[2];  $sp[5]=$pts[3];
    453                     $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv;
    454                     $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv;
    455                     $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv;
    456                 }
    457                 elseif( $val < 0 ) {
    458                     $sp[0]=$pts[4];  $sp[1]=$pts[5];
    459                     $sp[2]=$pts[6];  $sp[3]=$pts[7];
    460                     $sp[4]=$pts[0];  $sp[5]=$pts[1];
    461                     $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv;
    462                     $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv;
    463                     $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv;
    464                 }
    465                 if( is_array($this->bar_shadow_color) ) {
    466                     $numcolors = count($this->bar_shadow_color);
    467                     if( $numcolors == 0 ) {
    468                         JpGraphError::RaiseL(2005);//('You have specified an empty array for shadow colors in the bar plot.');
    469                     }
    470                     $img->PushColor($this->bar_shadow_color[$i % $numcolors]);
    471                 }
    472                 else {
    473                     $img->PushColor($this->bar_shadow_color);
    474                 }
    475                 $img->FilledPolygon($sp);
    476                 $img->PopColor();
    477 
    478             } elseif( $this->bar_3d && $val != 0) {
    479               // Determine the 3D
    480 
    481                 $ssh = $this->bar_3d_hsize;
    482                 $ssv = $this->bar_3d_vsize;
    483 
    484                 // Create points to create a "upper-right" shadow
    485                 if( $val > 0 ) {
    486                     $sp1[0]=$pts[6];  $sp1[1]=$pts[7];
    487                     $sp1[2]=$pts[4];  $sp1[3]=$pts[5];
    488                     $sp1[4]=$pts[4]+$ssh; $sp1[5]=$pts[5]-$ssv;
    489                     $sp1[6]=$pts[6]+$ssh; $sp1[7]=$pts[7]-$ssv;
    490 
    491                     $sp2[0]=$pts[4];  $sp2[1]=$pts[5];
    492                     $sp2[2]=$pts[2];  $sp2[3]=$pts[3];
    493                     $sp2[4]=$pts[2]+$ssh; $sp2[5]=$pts[3]-$ssv;
    494                     $sp2[6]=$pts[4]+$ssh; $sp2[7]=$pts[5]-$ssv;
    495 
    496                 }
    497                 elseif( $val < 0 ) {
    498                     $sp1[0]=$pts[4];  $sp1[1]=$pts[5];
    499                     $sp1[2]=$pts[6];  $sp1[3]=$pts[7];
    500                     $sp1[4]=$pts[6]+$ssh; $sp1[5]=$pts[7]-$ssv;
    501                     $sp1[6]=$pts[4]+$ssh; $sp1[7]=$pts[5]-$ssv;
    502 
    503                     $sp2[0]=$pts[6];  $sp2[1]=$pts[7];
    504                     $sp2[2]=$pts[0];  $sp2[3]=$pts[1];
    505                     $sp2[4]=$pts[0]+$ssh; $sp2[5]=$pts[1]-$ssv;
    506                     $sp2[6]=$pts[6]+$ssh; $sp2[7]=$pts[7]-$ssv;
    507                 }
    508 
    509                 $base_color = $this->fill_color;
    510 
    511                 $img->PushColor($base_color . ':0.7');
    512                 $img->FilledPolygon($sp1);
    513                 $img->PopColor();
    514 
    515                 $img->PushColor($base_color . ':1.1');
    516                 $img->FilledPolygon($sp2);
    517                 $img->PopColor();
    518             }
    519 
    520             // Stroke the pattern
    521             if( is_array($this->iPattern) ) {
    522                 $f = new RectPatternFactory();
    523                 if( is_array($this->iPatternColor) ) {
    524                     $pcolor = $this->iPatternColor[$i % $np];
    525                 }
    526                 else {
    527                     $pcolor = $this->iPatternColor;
    528                 }
    529                 $prect = $f->Create($this->iPattern[$i % $np],$pcolor,1);
    530                 $prect->SetDensity($this->iPatternDensity[$i % $np]);
    531 
    532                 if( $val < 0 ) {
    533                     $rx = $pts[0];
    534                     $ry = $pts[1];
    535                 }
    536                 else {
    537                     $rx = $pts[2];
    538                     $ry = $pts[3];
    539                 }
    540                 $width = abs($pts[4]-$pts[0])+1;
    541                 $height = abs($pts[1]-$pts[3])+1;
    542                 $prect->SetPos(new Rectangle($rx,$ry,$width,$height));
    543                 $prect->Stroke($img);
    544             }
    545             else {
    546                 if( $this->iPattern > -1 ) {
    547                     $f = new RectPatternFactory();
    548                     $prect = $f->Create($this->iPattern,$this->iPatternColor,1);
    549                     $prect->SetDensity($this->iPatternDensity);
    550                     if( $val < 0 ) {
    551                         $rx = $pts[0];
    552                         $ry = $pts[1];
    553                     }
    554                     else {
    555                         $rx = $pts[2];
    556                         $ry = $pts[3];
    557                     }
    558                     $width = abs($pts[4]-$pts[0])+1;
    559                     $height = abs($pts[1]-$pts[3])+1;
    560                     $prect->SetPos(new Rectangle($rx,$ry,$width,$height));
    561                     $prect->Stroke($img);
    562                 }
    563             }
    564 
    565             // Stroke the outline of the bar
    566             if( is_array($this->color) ) {
    567                 $img->SetColor($this->color[$i % count($this->color)]);
    568             }
    569             else {
    570                 $img->SetColor($this->color);
    571             }
    572 
    573             $pts[] = $pts[0];
    574             $pts[] = $pts[1];
    575 
    576             if( $this->weight > 0 ) {
    577                 $img->SetLineWeight($this->weight);
    578                 $img->Polygon($pts);
    579             }
    580 
    581             // Determine how to best position the values of the individual bars
    582             $x=$pts[2]+($pts[4]-$pts[2])/2;
    583             $this->value->SetMargin(5);
    584 
    585             if( $this->valuepos=='top' ) {
    586                 $y=$pts[3];
    587                 if( $img->a === 90 ) {
    588                     if( $val < 0 ) {
    589                         $this->value->SetAlign('right','center');
    590                     }
    591                     else {
    592                         $this->value->SetAlign('left','center');
    593                     }
    594 
    595                 }
    596                 else {
    597                     if( $val < 0 ) {
    598                         $this->value->SetMargin(-5);
    599                         $y=$pts[1];
    600                         $this->value->SetAlign('center','bottom');
    601                     }
    602                     else {
    603                         $this->value->SetAlign('center','bottom');
    604                     }
    605 
    606                 }
    607                 $this->value->Stroke($img,$val,$x,$y);
    608             }
    609             elseif( $this->valuepos=='max' ) {
    610                 $y=$pts[3];
    611                 if( $img->a === 90 ) {
    612                     if( $val < 0 )
    613                     $this->value->SetAlign('left','center');
    614                     else
    615                     $this->value->SetAlign('right','center');
    616                 }
    617                 else {
    618                     if( $val < 0 ) {
    619                         $this->value->SetAlign('center','bottom');
    620                     }
    621                     else {
    622                         $this->value->SetAlign('center','top');
    623                     }
    624                 }
    625                 $this->value->SetMargin(-5);
    626                 $this->value->Stroke($img,$val,$x,$y);
    627             }
    628             elseif( $this->valuepos=='center' ) {
    629                 $y = ($pts[3] + $pts[1])/2;
    630                 $this->value->SetAlign('center','center');
    631                 $this->value->SetMargin(0);
    632                 $this->value->Stroke($img,$val,$x,$y);
    633             }
    634             elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) {
    635                 $y=$pts[1];
    636                 if( $img->a === 90 ) {
    637                     if( $val < 0 )
    638                     $this->value->SetAlign('right','center');
    639                     else
    640                     $this->value->SetAlign('left','center');
    641                 }
    642                 $this->value->SetMargin(3);
    643                 $this->value->Stroke($img,$val,$x,$y);
    644             }
    645             else {
    646                 JpGraphError::RaiseL(2006,$this->valuepos);
    647                 //'Unknown position for values on bars :'.$this->valuepos);
    648             }
    649             // Create the client side image map
    650             $rpts = $img->ArrRotate($pts);
    651             $csimcoord=round($rpts[0]).", ".round($rpts[1]);
    652             for( $j=1; $j < 4; ++$j){
    653                 $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]);
    654             }
    655             if( !empty($this->csimtargets[$i]) ) {
    656                 $this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" ';
    657                 $this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\"";
    658 
    659                 if( !empty($this->csimwintargets[$i]) ) {
    660                     $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" ";
    661                 }
    662 
    663                 $sval='';
    664                 if( !empty($this->csimalts[$i]) ) {
    665                     $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]);
    666                     $this->csimareas .= " title=\"$sval\" alt=\"$sval\" ";
    667                 }
    668                 $this->csimareas .= " />\n";
    669             }
    670         }
    671         return true;
     234        switch( $aPattern ) {
     235            case PATTERN_DIAG1:
     236                $aPatternValue= 1;
     237                $aDensity = 90;
     238                break;
     239            case PATTERN_DIAG2:
     240                $aPatternValue= 1;
     241                $aDensity = 75;
     242                break;
     243            case PATTERN_DIAG3:
     244                $aPatternValue= 2;
     245                $aDensity = 90;
     246                break;
     247            case PATTERN_DIAG4:
     248                $aPatternValue= 2;
     249                $aDensity = 75;
     250                break;
     251            case PATTERN_CROSS1:
     252                $aPatternValue= 8;
     253                $aDensity = 90;
     254                break;
     255            case PATTERN_CROSS2:
     256                $aPatternValue= 8;
     257                $aDensity = 78;
     258                break;
     259            case PATTERN_CROSS3:
     260                $aPatternValue= 8;
     261                $aDensity = 65;
     262                break;
     263            case PATTERN_CROSS4:
     264                $aPatternValue= 7;
     265                $aDensity = 90;
     266                break;
     267            case PATTERN_STRIPE1:
     268                $aPatternValue= 5;
     269                $aDensity = 90;
     270                break;
     271            case PATTERN_STRIPE2:
     272                $aPatternValue= 5;
     273                $aDensity = 75;
     274                break;
     275            default:
     276                JpGraphError::RaiseL(2002);
     277//('Unknown pattern specified in call to BarPlot::SetPattern()');
     278        }
     279    }
     280
     281    function Stroke($img,$xscale,$yscale) {
     282               
     283        $numpoints = count($this->coords[0]);
     284        if( isset($this->coords[1]) ) {
     285            if( count($this->coords[1])!=$numpoints )
     286                JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints);
     287//"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints");
     288            else
     289                $exist_x = true;
     290        }
     291        else
     292            $exist_x = false;
     293               
     294               
     295        $numbars=count($this->coords[0]);
     296
     297        // Use GetMinVal() instead of scale[0] directly since in the case
     298        // of log scale we get a correct value. Log scales will have negative
     299        // values for values < 1 while still not representing negative numbers.
     300        if( $yscale->GetMinVal() >= 0 )
     301            $zp=$yscale->scale_abs[0];
     302        else {
     303            $zp=$yscale->Translate(0);
     304        }
     305
     306        if( $this->abswidth > -1 ) {
     307            $abswidth=$this->abswidth;
     308        }
     309        else
     310            $abswidth=round($this->width*$xscale->scale_factor,0);
     311
     312        // Count pontetial pattern array to avoid doing the count for each iteration
     313        if( is_array($this->iPattern) ) {
     314            $np = count($this->iPattern);
     315        }
     316                       
     317        $grad = null;
     318        for($i=0; $i < $numbars; ++$i) {
     319
     320            // If value is NULL, or 0 then don't draw a bar at all
     321            if ($this->coords[0][$i] === null || $this->coords[0][$i] === '' )
     322                continue;   
     323
     324            if( $exist_x ) $x=$this->coords[1][$i];
     325            else $x=$i;
     326                       
     327            $x=$xscale->Translate($x);
     328
     329// Comment Note: This confuses the positioning when using acc together with
     330// grouped bars. Workaround for fixing #191
     331/*
     332            if( !$xscale->textscale ) {
     333                if($this->align=="center")
     334                    $x -= $abswidth/2;
     335                elseif($this->align=="right")
     336                    $x -= $abswidth;                   
     337            }
     338*/
     339            // Stroke fill color and fill gradient
     340            $pts=array(
     341                $x,$zp,
     342                $x,$yscale->Translate($this->coords[0][$i]),
     343                $x+$abswidth,$yscale->Translate($this->coords[0][$i]),
     344                $x+$abswidth,$zp);
     345            if( $this->grad ) {
     346                if( $grad === null )
     347                    $grad = new Gradient($img);
     348                if( is_array($this->grad_fromcolor) ) {
     349                    // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array
     350                    // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be
     351                    // an array to specify both (from, to style) for each individual bar. The way to know the difference is
     352                    // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB
     353                    // triple.
     354                    $ng = count($this->grad_fromcolor);
     355                    if( $ng === 3 ) {
     356                        if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) {
     357                            // RGB Triple
     358                            $fromcolor = $this->grad_fromcolor;
     359                            $tocolor = $this->grad_tocolor;
     360                            $style = $this->grad_style;
     361                        }
     362                    }
     363                    else {
     364                        $fromcolor = $this->grad_fromcolor[$i % $ng][0];
     365                        $tocolor = $this->grad_fromcolor[$i % $ng][1];
     366                        $style = $this->grad_fromcolor[$i % $ng][2];
     367                    }
     368                    $grad->FilledRectangle($pts[2],$pts[3],
     369                                           $pts[6],$pts[7],
     370                                           $fromcolor,$tocolor,$style);
     371                }
     372                else {
     373                    $grad->FilledRectangle($pts[2],$pts[3],
     374                                           $pts[6],$pts[7],
     375                                           $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style);
     376                }
     377            }
     378            elseif( !empty($this->fill_color) ) {
     379                if(is_array($this->fill_color)) {
     380                    $img->PushColor($this->fill_color[$i % count($this->fill_color)]);
     381                } else {
     382                    $img->PushColor($this->fill_color);
     383                }
     384                $img->FilledPolygon($pts);
     385                $img->PopColor();
     386            }
     387 
     388                       
     389            // Remember value of this bar
     390            $val=$this->coords[0][$i];
     391
     392            if( !empty($val) && !is_numeric($val) ) {
     393                JpGraphError::RaiseL(2004,$i,$val);
     394                //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\'');
     395            }
     396
     397            // Determine the shadow
     398            if( $this->bar_shadow && $val != 0) {
     399
     400                $ssh = $this->bar_shadow_hsize;
     401                $ssv = $this->bar_shadow_vsize;
     402                // Create points to create a "upper-right" shadow
     403                if( $val > 0 ) {
     404                    $sp[0]=$pts[6];             $sp[1]=$pts[7];
     405                    $sp[2]=$pts[4];             $sp[3]=$pts[5];
     406                    $sp[4]=$pts[2];             $sp[5]=$pts[3];
     407                    $sp[6]=$pts[2]+$ssh;        $sp[7]=$pts[3]-$ssv;
     408                    $sp[8]=$pts[4]+$ssh;        $sp[9]=$pts[5]-$ssv;
     409                    $sp[10]=$pts[6]+$ssh;       $sp[11]=$pts[7]-$ssv;
     410                }
     411                elseif( $val < 0 ) {
     412                    $sp[0]=$pts[4];             $sp[1]=$pts[5];
     413                    $sp[2]=$pts[6];             $sp[3]=$pts[7];
     414                    $sp[4]=$pts[0];             $sp[5]=$pts[1];
     415                    $sp[6]=$pts[0]+$ssh;        $sp[7]=$pts[1]-$ssv;
     416                    $sp[8]=$pts[6]+$ssh;        $sp[9]=$pts[7]-$ssv;
     417                    $sp[10]=$pts[4]+$ssh;       $sp[11]=$pts[5]-$ssv;
     418                }
     419                if( is_array($this->bar_shadow_color) ) {
     420                    $numcolors = count($this->bar_shadow_color);
     421                    if( $numcolors == 0 ) {
     422                        JpGraphError::RaiseL(2005);//('You have specified an empty array for shadow colors in the bar plot.');
     423                    }
     424                    $img->PushColor($this->bar_shadow_color[$i % $numcolors]);
     425                }
     426                else {
     427                    $img->PushColor($this->bar_shadow_color);
     428                }
     429                $img->FilledPolygon($sp);
     430                $img->PopColor();
     431            }
     432                       
     433            // Stroke the pattern
     434            if( is_array($this->iPattern) ) {
     435                $f = new RectPatternFactory();
     436                if( is_array($this->iPatternColor) ) {
     437                    $pcolor = $this->iPatternColor[$i % $np];
     438                }
     439                else
     440                    $pcolor = $this->iPatternColor;
     441                $prect = $f->Create($this->iPattern[$i % $np],$pcolor,1);
     442                $prect->SetDensity($this->iPatternDensity[$i % $np]);
     443
     444                if( $val < 0 ) {
     445                    $rx = $pts[0];
     446                    $ry = $pts[1];
     447                }
     448                else {
     449                    $rx = $pts[2];
     450                    $ry = $pts[3];
     451                }
     452                $width = abs($pts[4]-$pts[0])+1;
     453                $height = abs($pts[1]-$pts[3])+1;
     454                $prect->SetPos(new Rectangle($rx,$ry,$width,$height));
     455                $prect->Stroke($img);
     456            }
     457            else {
     458                if( $this->iPattern > -1 ) {
     459                    $f = new RectPatternFactory();
     460                    $prect = $f->Create($this->iPattern,$this->iPatternColor,1);
     461                    $prect->SetDensity($this->iPatternDensity);
     462                    if( $val < 0 ) {
     463                        $rx = $pts[0];
     464                        $ry = $pts[1];
     465                    }
     466                    else {
     467                        $rx = $pts[2];
     468                        $ry = $pts[3];
     469                    }
     470                    $width = abs($pts[4]-$pts[0])+1;
     471                    $height = abs($pts[1]-$pts[3])+1;
     472                    $prect->SetPos(new Rectangle($rx,$ry,$width,$height));
     473                    $prect->Stroke($img);
     474                }
     475            }
     476            // Stroke the outline of the bar
     477            if( is_array($this->color) )
     478                $img->SetColor($this->color[$i % count($this->color)]);
     479            else
     480                $img->SetColor($this->color);
     481
     482            $pts[] = $pts[0];
     483            $pts[] = $pts[1];
     484
     485            if( $this->weight > 0 ) {
     486                $img->SetLineWeight($this->weight);
     487                $img->Polygon($pts);
     488            }
     489                       
     490            // Determine how to best position the values of the individual bars
     491            $x=$pts[2]+($pts[4]-$pts[2])/2;
     492            $this->value->SetMargin(5);
     493
     494            if( $this->valuepos=='top' ) {
     495                $y=$pts[3];
     496                if( $img->a === 90 ) {
     497                    if( $val < 0 )
     498                        $this->value->SetAlign('right','center');                       
     499                    else
     500                        $this->value->SetAlign('left','center');
     501                       
     502                }
     503                else {
     504                    if( $val < 0 ) {
     505                        $this->value->SetMargin(-5);
     506                        $y=$pts[1];
     507                        $this->value->SetAlign('center','bottom');
     508                    }
     509                    else {
     510                        $this->value->SetAlign('center','bottom');                     
     511                    }
     512
     513                }
     514                $this->value->Stroke($img,$val,$x,$y);
     515            }
     516            elseif( $this->valuepos=='max' ) {
     517                $y=$pts[3];
     518                if( $img->a === 90 ) {
     519                    if( $val < 0 )
     520                        $this->value->SetAlign('left','center');
     521                    else
     522                        $this->value->SetAlign('right','center');                   
     523                }
     524                else {
     525                    if( $val < 0 ) {
     526                        $this->value->SetAlign('center','bottom');
     527                    }
     528                    else {
     529                        $this->value->SetAlign('center','top');
     530                    }
     531                }
     532                $this->value->SetMargin(-5);
     533                $this->value->Stroke($img,$val,$x,$y);
     534            }
     535            elseif( $this->valuepos=='center' ) {
     536                $y = ($pts[3] + $pts[1])/2;
     537                $this->value->SetAlign('center','center');
     538                $this->value->SetMargin(0);
     539                $this->value->Stroke($img,$val,$x,$y);
     540            }
     541            elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) {
     542                $y=$pts[1];
     543                if( $img->a === 90 ) {
     544                    if( $val < 0 )
     545                        $this->value->SetAlign('right','center');
     546                    else
     547                        $this->value->SetAlign('left','center');                                   
     548                }
     549                $this->value->SetMargin(3);
     550                $this->value->Stroke($img,$val,$x,$y);
     551            }
     552            else {
     553                JpGraphError::RaiseL(2006,$this->valuepos);
     554                //'Unknown position for values on bars :'.$this->valuepos);
     555            }
     556            // Create the client side image map
     557            $rpts = $img->ArrRotate($pts);             
     558            $csimcoord=round($rpts[0]).", ".round($rpts[1]);
     559            for( $j=1; $j < 4; ++$j){
     560                $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]);
     561            }               
     562            if( !empty($this->csimtargets[$i]) ) {
     563                $this->csimareas .= '<area shape="poly" coords="'.$csimcoord.'" ';         
     564                $this->csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\"";
     565
     566                if( !empty($this->csimwintargets[$i]) ) {
     567                    $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" ";
     568                }
     569
     570                $sval='';
     571                if( !empty($this->csimalts[$i]) ) {
     572                    $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]);
     573                    $this->csimareas .= " title=\"$sval\" alt=\"$sval\" ";
     574                }
     575                $this->csimareas .= " />\n";
     576            }
     577        }
     578        return true;
    672579    }
    673580} // Class
     
    678585//===================================================
    679586class GroupBarPlot extends BarPlot {
    680     public $plots;
    681     private $nbrplots=0;
    682     //---------------
    683     // CONSTRUCTOR
    684     function __construct($plots) {
    685         $this->width=0.7;
    686         $this->plots = $plots;
    687         $this->nbrplots = count($plots);
    688         if( $this->nbrplots < 1 ) {
    689             JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.');
    690         }
    691         for($i=0; $i < $this->nbrplots; ++$i ) {
    692             if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
    693                 JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty.");
    694             }
    695         }
    696         $this->numpoints = $plots[0]->numpoints;
    697         $this->width=0.7;
    698     }
    699 
    700     //---------------
    701     // PUBLIC METHODS
     587    private $plots, $nbrplots=0;
     588//---------------
     589// CONSTRUCTOR
     590    function GroupBarPlot($plots) {
     591        $this->width=0.7;
     592        $this->plots = $plots;
     593        $this->nbrplots = count($plots);
     594        if( $this->nbrplots < 1 ) {
     595            JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.');
     596        }
     597        for($i=0; $i < $this->nbrplots; ++$i ) {
     598            if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
     599                JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty.");
     600            }
     601        }
     602        $this->numpoints = $plots[0]->numpoints;
     603        $this->width=0.7;
     604    }
     605
     606//---------------
     607// PUBLIC METHODS       
    702608    function Legend($graph) {
    703         $n = count($this->plots);
    704         for($i=0; $i < $n; ++$i) {
    705             $c = get_class($this->plots[$i]);
    706             if( !($this->plots[$i] instanceof BarPlot) ) {
    707                 JpGraphError::RaiseL(2009,$c);
    708                 //('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')');
    709             }
    710             $this->plots[$i]->DoLegend($graph);
    711         }
    712     }
    713 
     609        $n = count($this->plots);
     610        for($i=0; $i < $n; ++$i) {
     611            $c = get_class($this->plots[$i]);
     612            if( !($this->plots[$i] instanceof BarPlot) ) {
     613                JpGraphError::RaiseL(2009,$c);
     614//('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')');
     615            }
     616            $this->plots[$i]->DoLegend($graph);
     617        }
     618    }
     619       
    714620    function Min() {
    715         list($xmin,$ymin) = $this->plots[0]->Min();
    716         $n = count($this->plots);
    717         for($i=0; $i < $n; ++$i) {
    718             list($xm,$ym) = $this->plots[$i]->Min();
    719             $xmin = max($xmin,$xm);
    720             $ymin = min($ymin,$ym);
    721         }
    722         return array($xmin,$ymin);
    723     }
    724 
     621        list($xmin,$ymin) = $this->plots[0]->Min();
     622        $n = count($this->plots);
     623        for($i=0; $i < $n; ++$i) {
     624            list($xm,$ym) = $this->plots[$i]->Min();
     625            $xmin = max($xmin,$xm);
     626            $ymin = min($ymin,$ym);
     627        }
     628        return array($xmin,$ymin);             
     629    }
     630       
    725631    function Max() {
    726         list($xmax,$ymax) = $this->plots[0]->Max();
    727         $n = count($this->plots);
    728         for($i=0; $i < $n; ++$i) {
    729             list($xm,$ym) = $this->plots[$i]->Max();
    730             $xmax = max($xmax,$xm);
    731             $ymax = max($ymax,$ym);
    732         }
    733         return array($xmax,$ymax);
    734     }
    735 
     632        list($xmax,$ymax) = $this->plots[0]->Max();
     633        $n = count($this->plots);
     634        for($i=0; $i < $n; ++$i) {
     635            list($xm,$ym) = $this->plots[$i]->Max();
     636            $xmax = max($xmax,$xm);
     637            $ymax = max($ymax,$ym);
     638        }
     639        return array($xmax,$ymax);
     640    }
     641       
    736642    function GetCSIMareas() {
    737         $n = count($this->plots);
    738         $csimareas='';
    739         for($i=0; $i < $n; ++$i) {
    740             $csimareas .= $this->plots[$i]->csimareas;
    741         }
    742         return $csimareas;
    743     }
    744 
     643        $n = count($this->plots);
     644        $csimareas='';
     645        for($i=0; $i < $n; ++$i) {
     646            $csimareas .= $this->plots[$i]->csimareas;
     647        }
     648        return $csimareas;
     649    }
     650       
    745651    // Stroke all the bars next to each other
    746     function Stroke($img,$xscale,$yscale) {
    747         $tmp=$xscale->off;
    748         $n = count($this->plots);
    749         $subwidth = $this->width/$this->nbrplots ;
    750 
    751         for( $i=0; $i < $n; ++$i ) {
    752             $this->plots[$i]->ymin=$this->ybase;
    753             $this->plots[$i]->SetWidth($subwidth);
    754 
    755             // If the client have used SetTextTickInterval() then
    756             // major_step will be > 1 and the positioning will fail.
    757             // If we assume it is always one the positioning will work
    758             // fine with a text scale but this will not work with
    759             // arbitrary linear scale
    760             $xscale->off = $tmp+$i*round($xscale->scale_factor* $subwidth);
    761             $this->plots[$i]->Stroke($img,$xscale,$yscale);
    762         }
    763         $xscale->off=$tmp;
     652    function Stroke($img,$xscale,$yscale) { 
     653        $tmp=$xscale->off;
     654        $n = count($this->plots);
     655        $subwidth = $this->width/$this->nbrplots ;
     656
     657        for( $i=0; $i < $n; ++$i ) {
     658            $this->plots[$i]->ymin=$this->ybase;
     659            $this->plots[$i]->SetWidth($subwidth);
     660           
     661            // If the client have used SetTextTickInterval() then
     662            // major_step will be > 1 and the positioning will fail.
     663            // If we assume it is always one the positioning will work
     664            // fine with a text scale but this will not work with
     665            // arbitrary linear scale
     666            $xscale->off = $tmp+$i*round($xscale->scale_factor* $subwidth);
     667            $this->plots[$i]->Stroke($img,$xscale,$yscale);
     668        }
     669        $xscale->off=$tmp;
    764670    }
    765671} // Class
     
    770676//===================================================
    771677class AccBarPlot extends BarPlot {
    772     public $plots=null;
    773     private $nbrplots=0;
    774     //---------------
    775     // CONSTRUCTOR
    776     function __construct($plots) {
    777         $this->plots = $plots;
    778         $this->nbrplots = count($plots);
    779         if( $this->nbrplots < 1 ) {
    780             JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.');
    781         }
    782         for($i=0; $i < $this->nbrplots; ++$i ) {
    783             if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
    784                 JpGraphError::RaiseL(2011,$i);//("Acc bar plot element nbr $i is undefined or empty.");
    785             }
    786         }
    787 
    788         // We can only allow individual plost which do not have specified X-positions
    789         for($i=0; $i < $this->nbrplots; ++$i ) {
    790             if( !empty($this->plots[$i]->coords[1]) ) {
    791                 JpGraphError::RaiseL(2015);
    792                 //'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.');
    793             }
    794         }
    795 
    796         // Use 0 weight by default which means that the individual bar
    797         // weights will be used per part n the accumulated bar
    798         $this->SetWeight(0);
    799 
    800         $this->numpoints = $plots[0]->numpoints;
    801         $this->value = new DisplayValue();
    802     }
    803 
    804     //---------------
    805     // PUBLIC METHODS
     678    private $plots=null,$nbrplots=0;
     679//---------------
     680// CONSTRUCTOR
     681    function AccBarPlot($plots) {
     682        $this->plots = $plots;
     683        $this->nbrplots = count($plots);
     684        if( $this->nbrplots < 1 ) {
     685            JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.');
     686        }
     687        for($i=0; $i < $this->nbrplots; ++$i ) {
     688            if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) {
     689                JpGraphError::RaiseL(2011,$i);//("Acc bar plot element nbr $i is undefined or empty.");
     690            }
     691        }
     692
     693// We can only allow individual plost which do not have specified X-positions
     694        for($i=0; $i < $this->nbrplots; ++$i ) {
     695            if( !empty($this->plots[$i]->coords[1]) ) {
     696                JpGraphError::RaiseL(2015);
     697                //'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.');
     698            }
     699        }
     700       
     701        $this->numpoints = $plots[0]->numpoints;               
     702        $this->value = new DisplayValue();
     703    }
     704
     705//---------------
     706// PUBLIC METHODS       
    806707    function Legend($graph) {
    807         $n = count($this->plots);
    808         for( $i=$n-1; $i >= 0; --$i ) {
    809             $c = get_class($this->plots[$i]);
    810             if( !($this->plots[$i] instanceof BarPlot) ) {
    811                 JpGraphError::RaiseL(2012,$c);
    812                 //('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')');
    813             }
    814             $this->plots[$i]->DoLegend($graph);
    815         }
     708        $n = count($this->plots);
     709        for( $i=$n-1; $i >= 0; --$i ) {
     710            $c = get_class($this->plots[$i]);
     711            if( !($this->plots[$i] instanceof BarPlot) ) {
     712                JpGraphError::RaiseL(2012,$c);
     713//('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')');
     714            }       
     715            $this->plots[$i]->DoLegend($graph);
     716        }
    816717    }
    817718
    818719    function Max() {
    819         list($xmax) = $this->plots[0]->Max();
    820         $nmax=0;
    821         for($i=0; $i < count($this->plots); ++$i) {
    822             $n = count($this->plots[$i]->coords[0]);
    823             $nmax = max($nmax,$n);
    824             list($x) = $this->plots[$i]->Max();
    825             $xmax = max($xmax,$x);
    826         }
    827         for( $i = 0; $i < $nmax; $i++ ) {
    828             // Get y-value for bar $i by adding the
    829             // individual bars from all the plots added.
    830             // It would be wrong to just add the
    831             // individual plots max y-value since that
    832             // would in most cases give to large y-value.
    833             $y=0;
    834             if( !isset($this->plots[0]->coords[0][$i]) ) {
    835                 JpGraphError::RaiseL(2014);
    836             }
    837             if( $this->plots[0]->coords[0][$i] > 0 )
    838             $y=$this->plots[0]->coords[0][$i];
    839             for( $j = 1; $j < $this->nbrplots; $j++ ) {
    840                 if( !isset($this->plots[$j]->coords[0][$i]) ) {
    841                     JpGraphError::RaiseL(2014);
    842                 }
    843                 if( $this->plots[$j]->coords[0][$i] > 0 )
    844                 $y += $this->plots[$j]->coords[0][$i];
    845             }
    846             $ymax[$i] = $y;
    847         }
    848         $ymax = max($ymax);
    849 
    850         // Bar always start at baseline
    851         if( $ymax <= $this->ybase )
    852         $ymax = $this->ybase;
    853         return array($xmax,$ymax);
     720        list($xmax) = $this->plots[0]->Max();
     721        $nmax=0;
     722        for($i=0; $i < count($this->plots); ++$i) {
     723            $n = count($this->plots[$i]->coords[0]);
     724            $nmax = max($nmax,$n);
     725            list($x) = $this->plots[$i]->Max();
     726            $xmax = max($xmax,$x);
     727        }
     728        for( $i = 0; $i < $nmax; $i++ ) {
     729            // Get y-value for bar $i by adding the
     730            // individual bars from all the plots added.
     731            // It would be wrong to just add the
     732            // individual plots max y-value since that
     733            // would in most cases give to large y-value.
     734            $y=0;
     735            if( !isset($this->plots[0]->coords[0][$i]) ) {
     736                JpGraphError::RaiseL(2014);
     737            }
     738            if( $this->plots[0]->coords[0][$i] > 0 )
     739                $y=$this->plots[0]->coords[0][$i];
     740            for( $j = 1; $j < $this->nbrplots; $j++ ) {
     741                if( !isset($this->plots[$j]->coords[0][$i]) ) {
     742                    JpGraphError::RaiseL(2014);
     743                }
     744                if( $this->plots[$j]->coords[0][$i] > 0 )
     745                    $y += $this->plots[$j]->coords[0][$i];
     746            }
     747            $ymax[$i] = $y;
     748        }
     749        $ymax = max($ymax);
     750
     751        // Bar always start at baseline
     752        if( $ymax <= $this->ybase )
     753            $ymax = $this->ybase;
     754        return array($xmax,$ymax);
    854755    }
    855756
    856757    function Min() {
    857         $nmax=0;
    858         list($xmin,$ysetmin) = $this->plots[0]->Min();
    859         for($i=0; $i < count($this->plots); ++$i) {
    860             $n = count($this->plots[$i]->coords[0]);
    861             $nmax = max($nmax,$n);
    862             list($x,$y) = $this->plots[$i]->Min();
    863             $xmin = Min($xmin,$x);
    864             $ysetmin = Min($y,$ysetmin);
    865         }
    866         for( $i = 0; $i < $nmax; $i++ ) {
    867             // Get y-value for bar $i by adding the
    868             // individual bars from all the plots added.
    869             // It would be wrong to just add the
    870             // individual plots max y-value since that
    871             // would in most cases give to large y-value.
    872             $y=0;
    873             if( $this->plots[0]->coords[0][$i] < 0 )
    874             $y=$this->plots[0]->coords[0][$i];
    875             for( $j = 1; $j < $this->nbrplots; $j++ ) {
    876                 if( $this->plots[$j]->coords[0][$i] < 0 )
    877                 $y += $this->plots[ $j ]->coords[0][$i];
    878             }
    879             $ymin[$i] = $y;
    880         }
    881         $ymin = Min($ysetmin,Min($ymin));
    882         // Bar always start at baseline
    883         if( $ymin >= $this->ybase )
    884         $ymin = $this->ybase;
    885         return array($xmin,$ymin);
     758        $nmax=0;
     759        list($xmin,$ysetmin) = $this->plots[0]->Min();
     760        for($i=0; $i < count($this->plots); ++$i) {
     761            $n = count($this->plots[$i]->coords[0]);
     762            $nmax = max($nmax,$n);
     763            list($x,$y) = $this->plots[$i]->Min();
     764            $xmin = Min($xmin,$x);
     765            $ysetmin = Min($y,$ysetmin);
     766        }
     767        for( $i = 0; $i < $nmax; $i++ ) {
     768            // Get y-value for bar $i by adding the
     769            // individual bars from all the plots added.
     770            // It would be wrong to just add the
     771            // individual plots max y-value since that
     772            // would in most cases give to large y-value.
     773            $y=0;
     774            if( $this->plots[0]->coords[0][$i] < 0 )
     775                $y=$this->plots[0]->coords[0][$i];
     776            for( $j = 1; $j < $this->nbrplots; $j++ ) {
     777                if( $this->plots[$j]->coords[0][$i] < 0 )
     778                    $y += $this->plots[ $j ]->coords[0][$i];
     779            }
     780            $ymin[$i] = $y;
     781        }
     782        $ymin = Min($ysetmin,Min($ymin));
     783        // Bar always start at baseline
     784        if( $ymin >= $this->ybase )
     785            $ymin = $this->ybase;
     786        return array($xmin,$ymin);
    886787    }
    887788
    888789    // Stroke acc bar plot
    889790    function Stroke($img,$xscale,$yscale) {
    890         $pattern=NULL;
    891         $img->SetLineWeight($this->weight);
    892         $grad=null;
    893         for($i=0; $i < $this->numpoints-1; $i++) {
    894             $accy = 0;
    895             $accy_neg = 0;
    896             for($j=0; $j < $this->nbrplots; ++$j ) {
    897                 $img->SetColor($this->plots[$j]->color);
    898 
    899                 if ( $this->plots[$j]->coords[0][$i] >= 0) {
    900                     $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy);
    901                     $accyt=$yscale->Translate($accy);
    902                     $accy+=$this->plots[$j]->coords[0][$i];
    903                 }
    904                 else {
    905                     //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) {
    906                     $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg);
    907                     $accyt=$yscale->Translate($accy_neg);
    908                     $accy_neg+=$this->plots[$j]->coords[0][$i];
    909                 }
    910 
    911                 $xt=$xscale->Translate($i);
    912 
    913                 if( $this->abswidth > -1 ) {
    914                     $abswidth=$this->abswidth;
    915                 }
    916                 else {
    917                     $abswidth=round($this->width*$xscale->scale_factor,0);
    918                 }
    919 
    920                 $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt);
    921 
    922                 if( $this->bar_shadow ) {
    923                     $ssh = $this->bar_shadow_hsize;
    924                     $ssv = $this->bar_shadow_vsize;
    925 
    926                     // We must also differ if we are a positive or negative bar.
    927                     if( $j === 0 ) {
    928                         // This gets extra complicated since we have to
    929                         // see all plots to see if we are negative. It could
    930                         // for example be that all plots are 0 until the very
    931                         // last one. We therefore need to save the initial setup
    932                         // for both the negative and positive case
    933 
    934                         // In case the final bar is positive
    935                         $sp[0]=$pts[6]+1; $sp[1]=$pts[7];
    936                         $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv;
    937 
    938                         // In case the final bar is negative
    939                         $nsp[0]=$pts[0]; $nsp[1]=$pts[1];
    940                         $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv;
    941                         $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv;
    942                         $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7];
    943                     }
    944 
    945                     if( $j === $this->nbrplots-1 ) {
    946                         // If this is the last plot of the bar and
    947                         // the total value is larger than 0 then we
    948                         // add the shadow.
    949                         if( is_array($this->bar_shadow_color) ) {
    950                             $numcolors = count($this->bar_shadow_color);
    951                             if( $numcolors == 0 ) {
    952                                 JpGraphError::RaiseL(2013);//('You have specified an empty array for shadow colors in the bar plot.');
    953                             }
    954                             $img->PushColor($this->bar_shadow_color[$i % $numcolors]);
    955                         }
    956                         else {
    957                             $img->PushColor($this->bar_shadow_color);
    958                         }
    959 
    960                         if( $accy > 0 ) {
    961                             $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv;
    962                             $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv;
    963                             $sp[8]=$pts[2]; $sp[9]=$pts[3]-1;
    964                             $sp[10]=$pts[4]+1; $sp[11]=$pts[5];
    965                             $img->FilledPolygon($sp,4);
    966                         }
    967                         elseif( $accy_neg < 0 ) {
    968                             $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv;
    969                             $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5];
    970                             $img->FilledPolygon($nsp,4);
    971                         }
    972                         $img->PopColor();
    973                     }
    974                 }
    975 
    976 
    977                 // If value is NULL or 0, then don't draw a bar at all
    978                 if ($this->plots[$j]->coords[0][$i] == 0 ) continue;
    979 
    980                 if( $this->plots[$j]->grad ) {
    981                     if( $grad === null ) {
    982                         $grad = new Gradient($img);
    983                     }
    984                     if( is_array($this->plots[$j]->grad_fromcolor) ) {
    985                         // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array
    986                         // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be
    987                         // an array to specify both (from, to style) for each individual bar. The way to know the difference is
    988                         // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB
    989                         // triple.
    990                         $ng = count($this->plots[$j]->grad_fromcolor);
    991                         if( $ng === 3 ) {
    992                             if( is_numeric($this->plots[$j]->grad_fromcolor[0]) && $this->plots[$j]->grad_fromcolor[0] > 0 &&
    993                                  $this->plots[$j]->grad_fromcolor[0] < 256 ) {
    994                                 // RGB Triple
    995                                 $fromcolor = $this->plots[$j]->grad_fromcolor;
    996                                 $tocolor = $this->plots[$j]->grad_tocolor;
    997                                 $style = $this->plots[$j]->grad_style;
    998                             }
    999                             else {
    1000                                 $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0];
    1001                                 $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1];
    1002                                 $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2];
    1003                             }
    1004                         }
    1005                         else {
    1006                             $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0];
    1007                             $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1];
    1008                             $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2];
    1009                         }
    1010                         $grad->FilledRectangle($pts[2],$pts[3],
    1011                                                $pts[6],$pts[7],
    1012                                                $fromcolor,$tocolor,$style);
    1013                     }
    1014                     else {
    1015                         $grad->FilledRectangle($pts[2],$pts[3],
    1016                                                $pts[6],$pts[7],
    1017                                                $this->plots[$j]->grad_fromcolor,
    1018                                                $this->plots[$j]->grad_tocolor,
    1019                                                $this->plots[$j]->grad_style);
    1020                     }
    1021                 } else {
    1022                     if (is_array($this->plots[$j]->fill_color) ) {
    1023                         $numcolors = count($this->plots[$j]->fill_color);
    1024                         $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors];
    1025                         // If the bar is specified to be non filled then the fill color is false
    1026                         if( $fillcolor !== false ) {
    1027                             $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]);
    1028                         }
    1029                     }
    1030                     else {
    1031                         $fillcolor = $this->plots[$j]->fill_color;
    1032                         if( $fillcolor !== false ) {
    1033                             $img->SetColor($this->plots[$j]->fill_color);
    1034                         }
    1035                     }
    1036                     if( $fillcolor !== false ) {
    1037                         $img->FilledPolygon($pts);
    1038                     }
    1039                 }
    1040 
    1041                 $img->SetColor($this->plots[$j]->color);
    1042 
    1043                 // Stroke the pattern
    1044                 if( $this->plots[$j]->iPattern > -1 ) {
    1045                     if( $pattern===NULL ) {
    1046                         $pattern = new RectPatternFactory();
    1047                     }
    1048 
    1049                     $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1);
    1050                     $prect->SetDensity($this->plots[$j]->iPatternDensity);
    1051                     if( $this->plots[$j]->coords[0][$i] < 0 ) {
    1052                         $rx = $pts[0];
    1053                         $ry = $pts[1];
    1054                     }
    1055                     else {
    1056                         $rx = $pts[2];
    1057                         $ry = $pts[3];
    1058                     }
    1059                     $width = abs($pts[4]-$pts[0])+1;
    1060                     $height = abs($pts[1]-$pts[3])+1;
    1061                     $prect->SetPos(new Rectangle($rx,$ry,$width,$height));
    1062                     $prect->Stroke($img);
    1063                 }
    1064 
    1065 
    1066                 // CSIM array
    1067 
    1068                 if( $i < count($this->plots[$j]->csimtargets) ) {
    1069                     // Create the client side image map
    1070                     $rpts = $img->ArrRotate($pts);
    1071                     $csimcoord=round($rpts[0]).", ".round($rpts[1]);
    1072                     for( $k=1; $k < 4; ++$k){
    1073                         $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]);
    1074                     }
    1075                     if( ! empty($this->plots[$j]->csimtargets[$i]) ) {
    1076                         $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" ';
    1077                         $this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\" ";
    1078 
    1079                         if( ! empty($this->plots[$j]->csimwintargets[$i]) ) {
    1080                             $this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$i]."\" ";
    1081                         }
    1082 
    1083                         $sval='';
    1084                         if( !empty($this->plots[$j]->csimalts[$i]) ) {
    1085                             $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]);
    1086                             $this->csimareas .= " title=\"$sval\" ";
    1087                         }
    1088                         $this->csimareas .= " alt=\"$sval\" />\n";
    1089                     }
    1090                 }
    1091 
    1092                 $pts[] = $pts[0];
    1093                 $pts[] = $pts[1];
    1094                 $img->SetLineWeight($this->plots[$j]->weight);
    1095                 $img->Polygon($pts);
    1096                 $img->SetLineWeight(1);
    1097             }
    1098 
    1099             // Daw potential bar around the entire accbar bar
    1100             if( $this->weight > 0 ) {
    1101                 $y=$yscale->Translate(0);
    1102                 $img->SetColor($this->color);
    1103                 $img->SetLineWeight($this->weight);
    1104                 $img->Rectangle($pts[0],$y,$pts[6],$pts[5]);
    1105             }
    1106 
    1107             // Draw labels for each acc.bar
    1108 
    1109             $x=$pts[2]+($pts[4]-$pts[2])/2;
    1110             if($this->bar_shadow) $x += $ssh;
    1111 
    1112             // First stroke the accumulated value for the entire bar
    1113             // This value is always placed at the top/bottom of the bars
    1114             if( $accy + $accy_neg < 0 ) {
    1115                 $y=$yscale->Translate($accy_neg);
    1116             }
    1117             else {
    1118                 $y=$yscale->Translate($accy);
    1119             }
    1120             $this->value->Stroke($img,$accy + $accy_neg,$x,$y);
    1121 
    1122             $accy = 0;
    1123             $accy_neg = 0;
    1124             for($j=0; $j < $this->nbrplots; ++$j ) {
    1125 
    1126                 // We don't print 0 values in an accumulated bar plot
    1127                 if( $this->plots[$j]->coords[0][$i] == 0 ) continue;
    1128 
    1129                 if ($this->plots[$j]->coords[0][$i] > 0) {
    1130                     $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy);
    1131                     $accyt=$yscale->Translate($accy);
    1132                     if(  $this->plots[$j]->valuepos=='center' ) {
    1133                         $y = $accyt-($accyt-$yt)/2;
    1134                     }
    1135                     elseif( $this->plots[$j]->valuepos=='bottom' ) {
    1136                         $y = $accyt;
    1137                     }
    1138                     else { // top or max
    1139                         $y = $accyt-($accyt-$yt);
    1140                     }
    1141                     $accy+=$this->plots[$j]->coords[0][$i];
    1142                     if(  $this->plots[$j]->valuepos=='center' ) {
    1143                         $this->plots[$j]->value->SetAlign("center","center");
    1144                         $this->plots[$j]->value->SetMargin(0);
    1145                     }
    1146                     elseif( $this->plots[$j]->valuepos=='bottom' ) {
    1147                         $this->plots[$j]->value->SetAlign('center','bottom');
    1148                         $this->plots[$j]->value->SetMargin(2);
    1149                     }
    1150                     else {
    1151                         $this->plots[$j]->value->SetAlign('center','top');
    1152                         $this->plots[$j]->value->SetMargin(1);
    1153                     }
    1154                 } else {
    1155                     $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg);
    1156                     $accyt=$yscale->Translate($accy_neg);
    1157                     $accy_neg+=$this->plots[$j]->coords[0][$i];
    1158                     if(  $this->plots[$j]->valuepos=='center' ) {
    1159                         $y = $accyt-($accyt-$yt)/2;
    1160                     }
    1161                     elseif( $this->plots[$j]->valuepos=='bottom' ) {
    1162                         $y = $accyt;
    1163                     }
    1164                     else {
    1165                         $y = $accyt-($accyt-$yt);
    1166                     }
    1167                     if(  $this->plots[$j]->valuepos=='center' ) {
    1168                         $this->plots[$j]->value->SetAlign("center","center");
    1169                         $this->plots[$j]->value->SetMargin(0);
    1170                     }
    1171                     elseif( $this->plots[$j]->valuepos=='bottom' ) {
    1172                         $this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top');
    1173                         $this->plots[$j]->value->SetMargin(-2);
    1174                     }
    1175                     else {
    1176                         $this->plots[$j]->value->SetAlign('center','bottom');
    1177                         $this->plots[$j]->value->SetMargin(-1);
    1178                     }
    1179                 }
    1180                 $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],round($x),round($y));
    1181             }
    1182 
    1183         }
    1184         return true;
     791        $pattern=NULL;
     792        $img->SetLineWeight($this->weight);
     793        for($i=0; $i < $this->numpoints-1; $i++) {
     794            $accy = 0;
     795            $accy_neg = 0;
     796            for($j=0; $j < $this->nbrplots; ++$j ) {                           
     797                $img->SetColor($this->plots[$j]->color);
     798
     799                if ( $this->plots[$j]->coords[0][$i] >= 0) {
     800                    $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy);
     801                    $accyt=$yscale->Translate($accy);
     802                    $accy+=$this->plots[$j]->coords[0][$i];
     803                }
     804                else {
     805                    //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) {
     806                    $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg);
     807                    $accyt=$yscale->Translate($accy_neg);
     808                    $accy_neg+=$this->plots[$j]->coords[0][$i];
     809                }                               
     810                               
     811                $xt=$xscale->Translate($i);
     812
     813                if( $this->abswidth > -1 )
     814                    $abswidth=$this->abswidth;
     815                else
     816                    $abswidth=round($this->width*$xscale->scale_factor,0);
     817               
     818                $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt);
     819
     820                if( $this->bar_shadow ) {
     821                    $ssh = $this->bar_shadow_hsize;
     822                    $ssv = $this->bar_shadow_vsize;
     823                   
     824                    // We must also differ if we are a positive or negative bar.
     825                    if( $j === 0 ) {
     826                        // This gets extra complicated since we have to
     827                        // see all plots to see if we are negative. It could
     828                        // for example be that all plots are 0 until the very
     829                        // last one. We therefore need to save the initial setup
     830                        // for both the negative and positive case
     831
     832                        // In case the final bar is positive
     833                        $sp[0]=$pts[6]+1; $sp[1]=$pts[7];
     834                        $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv;
     835
     836                        // In case the final bar is negative
     837                        $nsp[0]=$pts[0]; $nsp[1]=$pts[1];
     838                        $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv;
     839                        $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv;
     840                        $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7];
     841                    }
     842
     843                    if( $j === $this->nbrplots-1 ) {
     844                        // If this is the last plot of the bar and
     845                        // the total value is larger than 0 then we
     846                        // add the shadow.
     847                        if( is_array($this->bar_shadow_color) ) {
     848                            $numcolors = count($this->bar_shadow_color);
     849                            if( $numcolors == 0 ) {
     850                                JpGraphError::RaiseL(2013);//('You have specified an empty array for shadow colors in the bar plot.');
     851                            }
     852                            $img->PushColor($this->bar_shadow_color[$i % $numcolors]);
     853                        }
     854                        else {
     855                            $img->PushColor($this->bar_shadow_color);
     856                        }
     857
     858                        if( $accy > 0 ) {
     859                            $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv;
     860                            $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv;
     861                            $sp[8]=$pts[2]; $sp[9]=$pts[3]-1;
     862                            $sp[10]=$pts[4]+1; $sp[11]=$pts[5];
     863                            $img->FilledPolygon($sp,4);
     864                        }
     865                        elseif( $accy_neg < 0 ) {
     866                            $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv;
     867                            $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5];
     868                            $img->FilledPolygon($nsp,4);
     869                        }
     870                        $img->PopColor();
     871                    }
     872                }
     873
     874
     875                // If value is NULL or 0, then don't draw a bar at all
     876                if ($this->plots[$j]->coords[0][$i] == 0 ) continue;
     877
     878                if( $this->plots[$j]->grad ) {
     879                    $grad = new Gradient($img);
     880                    $grad->FilledRectangle(
     881                        $pts[2],$pts[3],
     882                        $pts[6],$pts[7],
     883                        $this->plots[$j]->grad_fromcolor,
     884                        $this->plots[$j]->grad_tocolor,
     885                        $this->plots[$j]->grad_style);                         
     886                } else {
     887                    if (is_array($this->plots[$j]->fill_color) ) {
     888                        $numcolors = count($this->plots[$j]->fill_color);
     889                        $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors];
     890                        // If the bar is specified to be non filled then the fill color is false
     891                        if( $fillcolor !== false )
     892                            $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]);
     893                    }
     894                    else {
     895                        $fillcolor = $this->plots[$j]->fill_color;
     896                        if( $fillcolor !== false )
     897                            $img->SetColor($this->plots[$j]->fill_color);
     898                    }
     899                    if( $fillcolor !== false )
     900                        $img->FilledPolygon($pts);
     901                    $img->SetColor($this->plots[$j]->color);
     902                }                                 
     903
     904                // Stroke the pattern
     905                if( $this->plots[$j]->iPattern > -1 ) {
     906                    if( $pattern===NULL )
     907                        $pattern = new RectPatternFactory();
     908               
     909                    $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1);
     910                    $prect->SetDensity($this->plots[$j]->iPatternDensity);
     911                    if( $this->plots[$j]->coords[0][$i] < 0 ) {
     912                        $rx = $pts[0];
     913                        $ry = $pts[1];
     914                    }
     915                    else {
     916                        $rx = $pts[2];
     917                        $ry = $pts[3];
     918                    }
     919                    $width = abs($pts[4]-$pts[0])+1;
     920                    $height = abs($pts[1]-$pts[3])+1;
     921                    $prect->SetPos(new Rectangle($rx,$ry,$width,$height));
     922                    $prect->Stroke($img);
     923                }
     924
     925
     926                // CSIM array
     927
     928                if( $i < count($this->plots[$j]->csimtargets) ) {
     929                    // Create the client side image map
     930                    $rpts = $img->ArrRotate($pts);             
     931                    $csimcoord=round($rpts[0]).", ".round($rpts[1]);
     932                    for( $k=1; $k < 4; ++$k){
     933                        $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]);
     934                    }               
     935                    if( ! empty($this->plots[$j]->csimtargets[$i]) ) {
     936                        $this->csimareas.= '<area shape="poly" coords="'.$csimcoord.'" ';
     937                        $this->csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\" ";
     938
     939                        if( ! empty($this->plots[$j]->csimwintargets[$i]) ) {
     940                            $this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$i]."\" ";
     941                        }
     942
     943                        $sval='';
     944                        if( !empty($this->plots[$j]->csimalts[$i]) ) {
     945                            $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]);
     946                            $this->csimareas .= " title=\"$sval\" ";
     947                        }
     948                        $this->csimareas .= " alt=\"$sval\" />\n";                             
     949                    }
     950                }
     951
     952                $pts[] = $pts[0];
     953                $pts[] = $pts[1];
     954                $img->SetLineWeight($this->plots[$j]->line_weight);
     955                $img->Polygon($pts);
     956                $img->SetLineWeight(1);
     957            }
     958               
     959            // Draw labels for each acc.bar
     960       
     961            $x=$pts[2]+($pts[4]-$pts[2])/2;
     962            if($this->bar_shadow) $x += $ssh;
     963
     964            // First stroke the accumulated value for the entire bar
     965            // This value is always placed at the top/bottom of the bars
     966            if( $accy_neg < 0 ) {
     967                $y=$yscale->Translate($accy_neg);                       
     968                $this->value->Stroke($img,$accy_neg,$x,$y);
     969            }
     970            else {
     971                $y=$yscale->Translate($accy);                   
     972                $this->value->Stroke($img,$accy,$x,$y);
     973            }
     974
     975            $accy = 0;
     976            $accy_neg = 0;
     977            for($j=0; $j < $this->nbrplots; ++$j ) {   
     978
     979                // We don't print 0 values in an accumulated bar plot
     980                if( $this->plots[$j]->coords[0][$i] == 0 ) continue;
     981                       
     982                if ($this->plots[$j]->coords[0][$i] > 0) {
     983                    $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy);
     984                    $accyt=$yscale->Translate($accy);
     985                    if(  $this->plots[$j]->valuepos=='center' ) {
     986                        $y = $accyt-($accyt-$yt)/2;
     987                    }
     988                    elseif( $this->plots[$j]->valuepos=='bottom' ) {
     989                        $y = $accyt;
     990                    }
     991                    else { // top or max
     992                        $y = $accyt-($accyt-$yt);
     993                    }
     994                    $accy+=$this->plots[$j]->coords[0][$i];
     995                    if(  $this->plots[$j]->valuepos=='center' ) {
     996                        $this->plots[$j]->value->SetAlign("center","center");
     997                        $this->plots[$j]->value->SetMargin(0);
     998                    }
     999                    elseif( $this->plots[$j]->valuepos=='bottom' ) {
     1000                        $this->plots[$j]->value->SetAlign('center','bottom');
     1001                        $this->plots[$j]->value->SetMargin(2);
     1002                    }
     1003                    else {
     1004                        $this->plots[$j]->value->SetAlign('center','top');
     1005                        $this->plots[$j]->value->SetMargin(1);
     1006                    }
     1007                } else {
     1008                    $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg);
     1009                    $accyt=$yscale->Translate($accy_neg);
     1010                    $accy_neg+=$this->plots[$j]->coords[0][$i];
     1011                    if(  $this->plots[$j]->valuepos=='center' ) {
     1012                        $y = $accyt-($accyt-$yt)/2;
     1013                    }
     1014                    elseif( $this->plots[$j]->valuepos=='bottom' ) {
     1015                        $y = $accyt;
     1016                    }
     1017                    else {
     1018                        $y = $accyt-($accyt-$yt);
     1019                    }
     1020                    if(  $this->plots[$j]->valuepos=='center' ) {
     1021                        $this->plots[$j]->value->SetAlign("center","center");
     1022                        $this->plots[$j]->value->SetMargin(0);
     1023                    }
     1024                    elseif( $this->plots[$j]->valuepos=='bottom' ) {
     1025                        $this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top');
     1026                        $this->plots[$j]->value->SetMargin(-2);
     1027                    }
     1028                    else {
     1029                        $this->plots[$j]->value->SetAlign('center','bottom');
     1030                        $this->plots[$j]->value->SetMargin(-1);
     1031                    }
     1032                }       
     1033                $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y);
     1034            }
     1035
     1036        }
     1037        return true;
    11851038    }
    11861039} // Class
Note: See TracChangeset for help on using the changeset viewer.