Ignore:
Timestamp:
Apr 13, 2019, 8:05:15 PM (5 years ago)
Author:
roby
Message:
 
File:
1 edited

Legend:

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

    r2 r265  
    11<?php
    22/*=======================================================================
    3 // File:        JPGRAPH_LINE.PHP
    4 // Description: Line plot extension for JpGraph
    5 // Created:     2001-01-08
    6 // Ver:         $Id: jpgraph_line.php 981 2008-03-24 11:51:12Z ljp $
    7 //
    8 // Copyright (c) Aditus Consulting. All rights reserved.
    9 //========================================================================
    10 */
     3 // File:                JPGRAPH_LINE.PHP
     4 // Description: Line plot extension for JpGraph
     5 // Created:     2001-01-08
     6 // Ver:                 $Id: jpgraph_line.php 1921 2009-12-11 11:46:39Z ljp $
     7 //
     8 // Copyright (c) Asial Corporation. All rights reserved.
     9 //========================================================================
     10 */
    1111
    1212require_once ('jpgraph_plotmark.inc.php');
     
    2020//===================================================
    2121// CLASS LinePlot
    22 // Description: 
     22// Description:
    2323//===================================================
    2424class LinePlot extends Plot{
     
    2727    protected $fill_color='blue';
    2828    protected $step_style=false, $center=false;
    29     protected $line_style=1;    // Default to solid
     29    protected $line_style=1; // Default to solid
    3030    protected $filledAreas = array(); // array of arrays(with min,max,col,filled in them)
    3131    public $barcenter=false;  // When we mix line and bar. Should we center the line in the bar.
    32     protected $fillFromMin = false ;
     32    protected $fillFromMin = false, $fillFromMax = false;
    3333    protected $fillgrad=false,$fillgrad_fromcolor='navy',$fillgrad_tocolor='silver',$fillgrad_numcolors=100;
    3434    protected $iFastStroke=false;
    3535
    36 //---------------
    37 // CONSTRUCTOR
    38     function LinePlot($datay,$datax=false) {
    39         $this->Plot($datay,$datax);
    40         $this->mark = new PlotMark() ;
    41     }
    42 //---------------
    43 // PUBLIC METHODS       
    44 
    45     // Set style, filled or open
    46     function SetFilled($aFlag=true) {
    47         JpGraphError::RaiseL(10001);//('LinePlot::SetFilled() is deprecated. Use SetFillColor()');
    48     }
    49        
     36    //---------------
     37    // CONSTRUCTOR
     38    function __construct($datay,$datax=false) {
     39        parent::__construct($datay,$datax);
     40        $this->mark = new PlotMark() ;
     41        $this->color = ColorFactory::getColor();
     42        $this->fill_color = $this->color;
     43    }
     44    //---------------
     45    // PUBLIC METHODS
     46
     47    function SetFilled($aFlg=true) {
     48                $this->filled = $aFlg;
     49    }
     50
    5051    function SetBarCenter($aFlag=true) {
    51         $this->barcenter=$aFlag;
     52        $this->barcenter=$aFlag;
    5253    }
    5354
    5455    function SetStyle($aStyle) {
    55         $this->line_style=$aStyle;
    56     }
    57        
     56        $this->line_style=$aStyle;
     57    }
     58
    5859    function SetStepStyle($aFlag=true) {
    59         $this->step_style = $aFlag;
    60     }
    61        
     60        $this->step_style = $aFlag;
     61    }
     62
    6263    function SetColor($aColor) {
    63         parent::SetColor($aColor);
    64     }
    65        
     64        parent::SetColor($aColor);
     65    }
     66
    6667    function SetFillFromYMin($f=true) {
    67         $this->fillFromMin = $f ;
    68     }
    69    
     68        $this->fillFromMin = $f ;
     69    }
     70
     71    function SetFillFromYMax($f=true) {
     72        $this->fillFromMax = $f ;
     73    }
     74
    7075    function SetFillColor($aColor,$aFilled=true) {
    71         $this->fill_color=$aColor;
    72         $this->filled=$aFilled;
     76        //$this->color = $aColor;
     77        $this->fill_color=$aColor;
     78        $this->filled=$aFilled;
    7379    }
    7480
    7581    function SetFillGradient($aFromColor,$aToColor,$aNumColors=100,$aFilled=true) {
    76         $this->fillgrad_fromcolor = $aFromColor;
    77         $this->fillgrad_tocolor   = $aToColor;
    78         $this->fillgrad_numcolors = $aNumColors;
    79         $this->filled = $aFilled;
    80         $this->fillgrad = true;
    81     }
    82        
     82        $this->fillgrad_fromcolor = $aFromColor;
     83        $this->fillgrad_tocolor   = $aToColor;
     84        $this->fillgrad_numcolors = $aNumColors;
     85        $this->filled = $aFilled;
     86        $this->fillgrad = true;
     87    }
     88
    8389    function Legend($graph) {
    84         if( $this->legend!="" ) {
    85             if( $this->filled && !$this->fillgrad ) {
    86                 $graph->legend->Add($this->legend,
    87                                     $this->fill_color,$this->mark,0,
    88                                     $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
    89             }
    90             elseif( $this->fillgrad ) {
    91                 $color=array($this->fillgrad_fromcolor,$this->fillgrad_tocolor);
    92                 // In order to differentiate between gradients and cooors specified as an RGB triple
    93                 $graph->legend->Add($this->legend,$color,"",-2 /* -GRAD_HOR */,
    94                                     $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
    95             } else {
    96                 $graph->legend->Add($this->legend,
    97                                     $this->color,$this->mark,$this->line_style,
    98                                     $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
    99             }
    100         }       
     90        if( $this->legend!="" ) {
     91            if( $this->filled && !$this->fillgrad ) {
     92                $graph->legend->Add($this->legend,
     93                $this->fill_color,$this->mark,0,
     94                $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
     95            }
     96            elseif( $this->fillgrad ) {
     97                $color=array($this->fillgrad_fromcolor,$this->fillgrad_tocolor);
     98                // In order to differentiate between gradients and cooors specified as an RGB triple
     99                $graph->legend->Add($this->legend,$color,"",-2 /* -GRAD_HOR */,
     100                $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
     101            } else {
     102                $graph->legend->Add($this->legend,
     103                $this->color,$this->mark,$this->line_style,
     104                $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget);
     105            }
     106        }
    101107    }
    102108
    103109    function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) {
    104         if($aMin > $aMax) {
    105             // swap
    106             $tmp = $aMin;
    107             $aMin = $aMax;
    108             $aMax = $tmp;
    109         }
    110         $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder);
    111     }
    112        
     110        if($aMin > $aMax) {
     111            // swap
     112            $tmp = $aMin;
     113            $aMin = $aMax;
     114            $aMax = $tmp;
     115        }
     116        $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder);
     117    }
     118
    113119    // Gets called before any axis are stroked
    114120    function PreStrokeAdjust($graph) {
    115121
    116         // If another plot type have already adjusted the
    117         // offset we don't touch it.
    118         // (We check for empty in case the scale is  a log scale
    119         // and hence doesn't contain any xlabel_offset)
    120         if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
    121             $graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
    122             if( $this->center ) {
    123                 ++$this->numpoints;
    124                 $a=0.5; $b=0.5;
    125             } else {
    126                 $a=0; $b=0;
    127             }
    128             $graph->xaxis->scale->ticks->SetXLabelOffset($a);
    129             $graph->SetTextScaleOff($b);                                               
    130             //$graph->xaxis->scale->ticks->SupressMinorTickMarks();
    131         }
    132     }
    133    
     122        // If another plot type have already adjusted the
     123        // offset we don't touch it.
     124        // (We check for empty in case the scale is  a log scale
     125        // and hence doesn't contain any xlabel_offset)
     126        if( empty($graph->xaxis->scale->ticks->xlabel_offset) || $graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
     127            if( $this->center ) {
     128                ++$this->numpoints;
     129                $a=0.5; $b=0.5;
     130            } else {
     131                $a=0; $b=0;
     132            }
     133            $graph->xaxis->scale->ticks->SetXLabelOffset($a);
     134            $graph->SetTextScaleOff($b);
     135            //$graph->xaxis->scale->ticks->SupressMinorTickMarks();
     136        }
     137    }
     138
    134139    function SetFastStroke($aFlg=true) {
    135         $this->iFastStroke = $aFlg;
     140        $this->iFastStroke = $aFlg;
    136141    }
    137142
    138143    function FastStroke($img,$xscale,$yscale,$aStartPoint=0,$exist_x=true) {
    139         // An optimized stroke for many data points with no extra
    140         // features but 60% faster. You can't have values or line styles, or null
    141         // values in plots.
    142         $numpoints=count($this->coords[0]);
    143         if( $this->barcenter )
    144             $textadj = 0.5-$xscale->text_scale_off;
    145         else
    146             $textadj = 0;
    147 
    148         $img->SetColor($this->color);
    149         $img->SetLineWeight($this->weight);
    150         $pnts=$aStartPoint;
    151         while( $pnts < $numpoints ) {       
    152             if( $exist_x ) $x=$this->coords[1][$pnts];
    153             else $x=$pnts+$textadj;
    154             $xt = $xscale->Translate($x);
    155             $y=$this->coords[0][$pnts];
    156             $yt = $yscale->Translate($y);   
    157             if( is_numeric($y) ) {
    158                 $cord[] = $xt;
    159                 $cord[] = $yt;
    160             }
    161             elseif( $y == '-' && $pnts > 0 ) {
    162                 // Just ignore
    163             }
    164             else {
    165                 JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()');
    166             }
    167             ++$pnts;
    168         } // WHILE
    169 
    170         $img->Polygon($cord,false,true);
    171     }
    172        
     144        // An optimized stroke for many data points with no extra
     145        // features but 60% faster. You can't have values or line styles, or null
     146        // values in plots.
     147        $numpoints=count($this->coords[0]);
     148        if( $this->barcenter ) {
     149            $textadj = 0.5-$xscale->text_scale_off;
     150        }
     151        else {
     152            $textadj = 0;
     153        }
     154
     155        $img->SetColor($this->color);
     156        $img->SetLineWeight($this->weight);
     157        $pnts=$aStartPoint;
     158        while( $pnts < $numpoints ) {
     159            if( $exist_x ) {
     160                $x=$this->coords[1][$pnts];
     161            }
     162            else {
     163                $x=$pnts+$textadj;
     164            }
     165            $xt = $xscale->Translate($x);
     166            $y=$this->coords[0][$pnts];
     167            $yt = $yscale->Translate($y);
     168            if( is_numeric($y) ) {
     169                $cord[] = $xt;
     170                $cord[] = $yt;
     171            }
     172            elseif( $y == '-' && $pnts > 0 ) {
     173                // Just ignore
     174            }
     175            else {
     176                JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()');
     177            }
     178            ++$pnts;
     179        } // WHILE
     180
     181        $img->Polygon($cord,false,true);
     182    }
     183
    173184    function Stroke($img,$xscale,$yscale) {
    174         $idx=0;
    175         $numpoints=count($this->coords[0]);
    176         if( isset($this->coords[1]) ) {
    177             if( count($this->coords[1])!=$numpoints )
    178                 JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints);
    179 //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");
    180             else
    181                 $exist_x = true;
    182         }
    183         else
    184             $exist_x = false;
    185 
    186         if( $this->barcenter )
    187             $textadj = 0.5-$xscale->text_scale_off;
    188         else
    189             $textadj = 0;
    190 
    191         // Find the first numeric data point
    192         $startpoint=0;
    193         while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) )
    194             ++$startpoint;
    195 
    196         // Bail out if no data points
    197         if( $startpoint == $numpoints )
    198             return;
    199 
    200         if( $this->iFastStroke ) {
    201             $this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x);
    202             return;
    203         }
    204 
    205         if( $exist_x )
    206             $xs=$this->coords[1][$startpoint];
    207         else
    208             $xs= $textadj+$startpoint;
    209 
    210         $img->SetStartPoint($xscale->Translate($xs),
    211                             $yscale->Translate($this->coords[0][$startpoint]));
    212 
    213                
    214         if( $this->filled ) {
    215             $min = $yscale->GetMinVal();
    216             if( $min > 0 || $this->fillFromMin )
    217                 $fillmin = $yscale->scale_abs[0];//Translate($min);
    218             else
    219                 $fillmin = $yscale->Translate(0);
    220 
    221             $cord[$idx++] = $xscale->Translate($xs);
    222             $cord[$idx++] = $fillmin;
    223         }
    224         $xt = $xscale->Translate($xs);
    225         $yt = $yscale->Translate($this->coords[0][$startpoint]);
    226         $cord[$idx++] = $xt;
    227         $cord[$idx++] = $yt;
    228         $yt_old = $yt;
    229         $xt_old = $xt;
    230         $y_old = $this->coords[0][$startpoint];
    231 
    232         $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt);
    233 
    234         $img->SetColor($this->color);
    235         $img->SetLineWeight($this->weight);
    236         $img->SetLineStyle($this->line_style);
    237         $pnts=$startpoint+1;
    238         $firstnonumeric = false;
    239 
    240 
    241         while( $pnts < $numpoints ) {
    242            
    243             if( $exist_x ) $x=$this->coords[1][$pnts];
    244             else $x=$pnts+$textadj;
    245             $xt = $xscale->Translate($x);
    246             $yt = $yscale->Translate($this->coords[0][$pnts]);
    247            
    248             $y=$this->coords[0][$pnts];
    249             if( $this->step_style ) {
    250                 // To handle null values within step style we need to record the
    251                 // first non numeric value so we know from where to start if the
    252                 // non value is '-'.
    253                 if( is_numeric($y) ) {
    254                     $firstnonumeric = false;
    255                     if( is_numeric($y_old) ) {
    256                         $img->StyleLine($xt_old,$yt_old,$xt,$yt_old);
    257                         $img->StyleLine($xt,$yt_old,$xt,$yt);
    258                     }
    259                     elseif( $y_old == '-' ) {
    260                         $img->StyleLine($xt_first,$yt_first,$xt,$yt_first);
    261                         $img->StyleLine($xt,$yt_first,$xt,$yt);                 
    262                     }
    263                     else {
    264                         $yt_old = $yt;
    265                         $xt_old = $xt;
    266                     }
    267                     $cord[$idx++] = $xt;
    268                     $cord[$idx++] = $yt_old;
    269                     $cord[$idx++] = $xt;
    270                     $cord[$idx++] = $yt;
    271                 }
    272                 elseif( $firstnonumeric==false ) {
    273                     $firstnonumeric = true;
    274                     $yt_first = $yt_old;
    275                     $xt_first = $xt_old;
    276                 }
    277             }
    278             else {
    279                 $tmp1=$y;
    280                 $prev=$this->coords[0][$pnts-1];                                       
    281                 if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x';
    282                 if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x';
    283 
    284                 if( is_numeric($y) || (is_string($y) && $y != '-') ) {
    285                     if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) {
    286                         $img->StyleLineTo($xt,$yt);
    287                     }
    288                     else {
    289                         $img->SetStartPoint($xt,$yt);
    290                     }
    291                 }
    292                 if( $this->filled && $tmp1 !== '-' ) {
    293                     if( $tmp1 === 'x' ) {
    294                         $cord[$idx++] = $cord[$idx-3];
    295                         $cord[$idx++] = $fillmin;
    296                     }
    297                     elseif( $prev === 'x' ) {
    298                         $cord[$idx++] = $xt;
    299                         $cord[$idx++] = $fillmin;
    300                         $cord[$idx++] = $xt;
    301                         $cord[$idx++] = $yt;                       
    302                     }
    303                     else {
    304                         $cord[$idx++] = $xt;
    305                         $cord[$idx++] = $yt;
    306                     }
    307                 }
    308                 else {
    309                     if( is_numeric($tmp1)  && (is_numeric($prev) || $prev === '-' ) ) {
    310                         $cord[$idx++] = $xt;
    311                         $cord[$idx++] = $yt;
    312                     }
    313                 }
    314             }
    315             $yt_old = $yt;
    316             $xt_old = $xt;
    317             $y_old = $y;
    318 
    319             $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
    320 
    321             ++$pnts;
    322         }       
    323 
    324         if( $this->filled  ) {
    325             $cord[$idx++] = $xt;
    326             if( $min > 0 || $this->fillFromMin )
    327                 $cord[$idx++] = $yscale->Translate($min);
    328             else
    329                 $cord[$idx++] = $yscale->Translate(0);
    330             if( $this->fillgrad ) {
    331                 $img->SetLineWeight(1);
    332                 $grad = new Gradient($img);
    333                 $grad->SetNumColors($this->fillgrad_numcolors);
    334                 $grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor);
    335                 $img->SetLineWeight($this->weight);
    336             }
    337             else {
    338                 $img->SetColor($this->fill_color);     
    339                 $img->FilledPolygon($cord);
    340             }
    341             if( $this->line_weight > 0 ) {
    342                 $img->SetColor($this->color);
    343                 $img->Polygon($cord);
    344             }
    345         }
    346 
    347         if(!empty($this->filledAreas)) {
    348 
    349             $minY = $yscale->Translate($yscale->GetMinVal());
    350             $factor = ($this->step_style ? 4 : 2);
    351 
    352             for($i = 0; $i < sizeof($this->filledAreas); ++$i) {
    353                 // go through all filled area elements ordered by insertion
    354                 // fill polygon array
    355                 $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor];
    356                 $areaCoords[] = $minY;
    357 
    358                 $areaCoords =
    359                     array_merge($areaCoords,
    360                                 array_slice($cord,
    361                                             $this->filledAreas[$i][0] * $factor,
    362                                             ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1))  * $factor));
    363                 $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x
    364                 $areaCoords[] = $minY; // last y
    365            
    366                 if($this->filledAreas[$i][3]) {
    367                     $img->SetColor($this->filledAreas[$i][2]);
    368                     $img->FilledPolygon($areaCoords);
    369                     $img->SetColor($this->color);
    370                 }
    371                 // Check if we should draw the frame.
    372                 // If not we still re-draw the line since it might have been
    373                 // partially overwritten by the filled area and it doesn't look
    374                 // very good.
    375                 // TODO: The behaviour is undefined if the line does not have
    376                 // any line at the position of the area.
    377                 if( $this->filledAreas[$i][4] )
    378                     $img->Polygon($areaCoords);
    379                 else
    380                     $img->Polygon($cord);
    381 
    382                 $areaCoords = array();
    383             }
    384         }       
    385 
    386         if( $this->mark->type == -1 || $this->mark->show == false )
    387             return;
    388 
    389         for( $pnts=0; $pnts<$numpoints; ++$pnts) {
    390 
    391             if( $exist_x ) $x=$this->coords[1][$pnts];
    392             else $x=$pnts+$textadj;
    393             $xt = $xscale->Translate($x);
    394             $yt = $yscale->Translate($this->coords[0][$pnts]);
    395 
    396             if( is_numeric($this->coords[0][$pnts]) ) {
    397                 if( !empty($this->csimtargets[$pnts]) ) {
    398                     if( !empty($this->csimwintargets[$pnts]) ) {
    399                         $this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]);
    400                     }
    401                     else {
    402                         $this->mark->SetCSIMTarget($this->csimtargets[$pnts]);
    403                     }
    404                     $this->mark->SetCSIMAlt($this->csimalts[$pnts]);
    405                 }
    406                 if( $exist_x )
    407                     $x=$this->coords[1][$pnts];
    408                 else
    409                     $x=$pnts;
    410                 $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x);
    411                 $this->mark->Stroke($img,$xt,$yt);     
    412                 $this->csimareas .= $this->mark->GetCSIMAreas();
    413             }
    414         }
     185        $idx=0;
     186        $numpoints=count($this->coords[0]);
     187        if( isset($this->coords[1]) ) {
     188            if( count($this->coords[1])!=$numpoints ) {
     189                JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints);
     190            //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");
     191            }
     192            else {
     193                $exist_x = true;
     194            }
     195        }
     196        else {
     197            $exist_x = false;
     198        }
     199
     200        if( $this->barcenter ) {
     201            $textadj = 0.5-$xscale->text_scale_off;
     202        }
     203        else {
     204            $textadj = 0;
     205        }
     206
     207        // Find the first numeric data point
     208        $startpoint=0;
     209        while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) ) {
     210            ++$startpoint;
     211        }
     212
     213        // Bail out if no data points
     214        if( $startpoint == $numpoints ) return;
     215
     216        if( $this->iFastStroke ) {
     217            $this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x);
     218            return;
     219        }
     220
     221        if( $exist_x ) {
     222            $xs=$this->coords[1][$startpoint];
     223        }
     224        else {
     225            $xs= $textadj+$startpoint;
     226        }
     227
     228        $img->SetStartPoint($xscale->Translate($xs),
     229        $yscale->Translate($this->coords[0][$startpoint]));
     230
     231        if( $this->filled ) {
     232            if( $this->fillFromMax ) {
     233                //$max = $yscale->GetMaxVal();
     234                $cord[$idx++] = $xscale->Translate($xs);
     235                $cord[$idx++] = $yscale->scale_abs[1];
     236            }
     237            else {
     238                $min = $yscale->GetMinVal();
     239                if( $min > 0 || $this->fillFromMin ) {
     240                    $fillmin = $yscale->scale_abs[0];//Translate($min);
     241                }
     242                else {
     243                    $fillmin = $yscale->Translate(0);
     244                }
     245
     246                $cord[$idx++] = $xscale->Translate($xs);
     247                $cord[$idx++] = $fillmin;
     248            }
     249        }
     250        $xt = $xscale->Translate($xs);
     251        $yt = $yscale->Translate($this->coords[0][$startpoint]);
     252        $cord[$idx++] = $xt;
     253        $cord[$idx++] = $yt;
     254        $yt_old = $yt;
     255        $xt_old = $xt;
     256        $y_old = $this->coords[0][$startpoint];
     257
     258        $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt);
     259
     260        $img->SetColor($this->color);
     261        $img->SetLineWeight($this->weight);
     262        $img->SetLineStyle($this->line_style);
     263        $pnts=$startpoint+1;
     264        $firstnonumeric = false;
     265
     266
     267        while( $pnts < $numpoints ) {
     268
     269            if( $exist_x ) {
     270                $x=$this->coords[1][$pnts];
     271            }
     272            else {
     273                $x=$pnts+$textadj;
     274            }
     275            $xt = $xscale->Translate($x);
     276            $yt = $yscale->Translate($this->coords[0][$pnts]);
     277
     278            $y=$this->coords[0][$pnts];
     279            if( $this->step_style ) {
     280                // To handle null values within step style we need to record the
     281                // first non numeric value so we know from where to start if the
     282                // non value is '-'.
     283                if( is_numeric($y) ) {
     284                    $firstnonumeric = false;
     285                    if( is_numeric($y_old) ) {
     286                        $img->StyleLine($xt_old,$yt_old,$xt,$yt_old);
     287                        $img->StyleLine($xt,$yt_old,$xt,$yt);
     288                    }
     289                    elseif( $y_old == '-' ) {
     290                        $img->StyleLine($xt_first,$yt_first,$xt,$yt_first);
     291                        $img->StyleLine($xt,$yt_first,$xt,$yt);
     292                    }
     293                    else {
     294                        $yt_old = $yt;
     295                        $xt_old = $xt;
     296                    }
     297                    $cord[$idx++] = $xt;
     298                    $cord[$idx++] = $yt_old;
     299                    $cord[$idx++] = $xt;
     300                    $cord[$idx++] = $yt;
     301                }
     302                elseif( $firstnonumeric==false ) {
     303                    $firstnonumeric = true;
     304                    $yt_first = $yt_old;
     305                    $xt_first = $xt_old;
     306                }
     307            }
     308            else {
     309                $tmp1=$y;
     310                $prev=$this->coords[0][$pnts-1];
     311                if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x';
     312                if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x';
     313
     314                if( is_numeric($y) || (is_string($y) && $y != '-') ) {
     315                    if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) {
     316                        $img->StyleLineTo($xt,$yt);
     317                    }
     318                    else {
     319                        $img->SetStartPoint($xt,$yt);
     320                    }
     321                }
     322                if( $this->filled && $tmp1 !== '-' ) {
     323                    if( $tmp1 === 'x' ) {
     324                        $cord[$idx++] = $cord[$idx-3];
     325                        $cord[$idx++] = $fillmin;
     326                    }
     327                    elseif( $prev === 'x' ) {
     328                        $cord[$idx++] = $xt;
     329                        $cord[$idx++] = $fillmin;
     330                        $cord[$idx++] = $xt;
     331                        $cord[$idx++] = $yt;
     332                    }
     333                    else {
     334                        $cord[$idx++] = $xt;
     335                        $cord[$idx++] = $yt;
     336                    }
     337                }
     338                else {
     339                    if( is_numeric($tmp1)  && (is_numeric($prev) || $prev === '-' ) ) {
     340                        $cord[$idx++] = $xt;
     341                        $cord[$idx++] = $yt;
     342                    }
     343                }
     344            }
     345            $yt_old = $yt;
     346            $xt_old = $xt;
     347            $y_old = $y;
     348
     349            $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
     350
     351            ++$pnts;
     352        }
     353
     354        if( $this->filled  ) {
     355            $cord[$idx++] = $xt;
     356            if( $this->fillFromMax ) {
     357                $cord[$idx++] = $yscale->scale_abs[1];
     358            }
     359            else {
     360                if( $min > 0 || $this->fillFromMin ) {
     361                    $cord[$idx++] = $yscale->Translate($min);
     362                }
     363                else {
     364                    $cord[$idx++] = $yscale->Translate(0);
     365                }
     366            }
     367            if( $this->fillgrad ) {
     368                $img->SetLineWeight(1);
     369                $grad = new Gradient($img);
     370                $grad->SetNumColors($this->fillgrad_numcolors);
     371                $grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor);
     372                $img->SetLineWeight($this->weight);
     373            }
     374            else {
     375                $img->SetColor($this->fill_color);
     376                $img->FilledPolygon($cord);
     377            }
     378            if( $this->weight > 0 ) {
     379                $img->SetLineWeight($this->weight);
     380                $img->SetColor($this->color);
     381                // Remove first and last coordinate before drawing the line
     382                // sine we otherwise get the vertical start and end lines which
     383                // doesn't look appropriate
     384                $img->Polygon(array_slice($cord,2,count($cord)-4));
     385            }
     386        }
     387
     388        if(!empty($this->filledAreas)) {
     389
     390            $minY = $yscale->Translate($yscale->GetMinVal());
     391            $factor = ($this->step_style ? 4 : 2);
     392
     393            for($i = 0; $i < sizeof($this->filledAreas); ++$i) {
     394                // go through all filled area elements ordered by insertion
     395                // fill polygon array
     396                $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor];
     397                $areaCoords[] = $minY;
     398
     399                $areaCoords =
     400                array_merge($areaCoords,
     401                array_slice($cord,
     402                $this->filledAreas[$i][0] * $factor,
     403                ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1))  * $factor));
     404                $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x
     405                $areaCoords[] = $minY; // last y
     406
     407                if($this->filledAreas[$i][3]) {
     408                    $img->SetColor($this->filledAreas[$i][2]);
     409                    $img->FilledPolygon($areaCoords);
     410                    $img->SetColor($this->color);
     411                }
     412                // Check if we should draw the frame.
     413                // If not we still re-draw the line since it might have been
     414                // partially overwritten by the filled area and it doesn't look
     415                // very good.
     416                if( $this->filledAreas[$i][4] ) {
     417                    $img->Polygon($areaCoords);
     418                }
     419                else {
     420                    $img->Polygon($cord);
     421                }
     422
     423                $areaCoords = array();
     424            }
     425        }
     426
     427        if( $this->mark->type == -1 || $this->mark->show == false )
     428        return;
     429
     430        for( $pnts=0; $pnts<$numpoints; ++$pnts) {
     431
     432            if( $exist_x ) {
     433                $x=$this->coords[1][$pnts];
     434            }
     435            else {
     436                $x=$pnts+$textadj;
     437            }
     438            $xt = $xscale->Translate($x);
     439            $yt = $yscale->Translate($this->coords[0][$pnts]);
     440
     441            if( is_numeric($this->coords[0][$pnts]) ) {
     442                if( !empty($this->csimtargets[$pnts]) ) {
     443                    if( !empty($this->csimwintargets[$pnts]) ) {
     444                        $this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]);
     445                    }
     446                    else {
     447                        $this->mark->SetCSIMTarget($this->csimtargets[$pnts]);
     448                    }
     449                    $this->mark->SetCSIMAlt($this->csimalts[$pnts]);
     450                }
     451                if( $exist_x ) {
     452                    $x=$this->coords[1][$pnts];
     453                }
     454                else {
     455                    $x=$pnts;
     456                }
     457                $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x);
     458                $this->mark->Stroke($img,$xt,$yt);
     459                $this->csimareas .= $this->mark->GetCSIMAreas();
     460            }
     461        }
    415462    }
    416463} // Class
     
    419466//===================================================
    420467// CLASS AccLinePlot
    421 // Description: 
     468// Description:
    422469//===================================================
    423470class AccLinePlot extends Plot {
    424471    protected $plots=null,$nbrplots=0;
    425472    private $iStartEndZero=true;
    426 //---------------
    427 // CONSTRUCTOR
    428     function AccLinePlot($plots) {
     473    //---------------
     474    // CONSTRUCTOR
     475    function __construct($plots) {
    429476        $this->plots = $plots;
    430         $this->nbrplots = count($plots);
    431         $this->numpoints = $plots[0]->numpoints;
    432 
    433         // Verify that all plots have the same number of data points
    434         for( $i=1; $i < $this->nbrplots; ++$i ) {
    435             if( $plots[$i]->numpoints != $this->numpoints ) {
    436                 JpGraphError::RaiseL(10003);//('Each plot in an accumulated lineplot must have the same number of data points',0)
    437             }
    438         }
    439 
    440         for($i=0; $i < $this->nbrplots; ++$i ) {
    441             $this->LineInterpolate($this->plots[$i]->coords[0]);
    442         }       
    443     }
    444 
    445 //---------------
    446 // PUBLIC METHODS       
     477        $this->nbrplots = count($plots);
     478        $this->numpoints = $plots[0]->numpoints;
     479
     480        // Verify that all plots have the same number of data points
     481        for( $i=1; $i < $this->nbrplots; ++$i ) {
     482            if( $plots[$i]->numpoints != $this->numpoints ) {
     483                JpGraphError::RaiseL(10003);//('Each plot in an accumulated lineplot must have the same number of data points',0)
     484            }
     485        }
     486
     487        for($i=0; $i < $this->nbrplots; ++$i ) {
     488            $this->LineInterpolate($this->plots[$i]->coords[0]);
     489        }
     490    }
     491
     492    //---------------
     493    // PUBLIC METHODS
    447494    function Legend($graph) {
    448         foreach( $this->plots as $p )
    449             $p->DoLegend($graph);
    450     }
    451        
     495        foreach( $this->plots as $p ) {
     496            $p->DoLegend($graph);
     497        }
     498    }
     499
    452500    function Max() {
    453         list($xmax) = $this->plots[0]->Max();
    454         $nmax=0;
    455         $n = count($this->plots);
    456         for($i=0; $i < $n; ++$i) {
    457             $nc = count($this->plots[$i]->coords[0]);
    458             $nmax = max($nmax,$nc);
    459             list($x) = $this->plots[$i]->Max();
    460             $xmax = Max($xmax,$x);
    461         }
    462         for( $i = 0; $i < $nmax; $i++ ) {
    463             // Get y-value for line $i by adding the
    464             // individual bars from all the plots added.
    465             // It would be wrong to just add the
    466             // individual plots max y-value since that
    467             // would in most cases give to large y-value.
    468             $y=$this->plots[0]->coords[0][$i];
    469             for( $j = 1; $j < $this->nbrplots; $j++ ) {
    470                 $y += $this->plots[ $j ]->coords[0][$i];
    471             }
    472             $ymax[$i] = $y;
    473         }
    474         $ymax = max($ymax);
    475         return array($xmax,$ymax);
    476     }   
     501        list($xmax) = $this->plots[0]->Max();
     502        $nmax=0;
     503        $n = count($this->plots);
     504        for($i=0; $i < $n; ++$i) {
     505            $nc = count($this->plots[$i]->coords[0]);
     506            $nmax = max($nmax,$nc);
     507            list($x) = $this->plots[$i]->Max();
     508            $xmax = Max($xmax,$x);
     509        }
     510        for( $i = 0; $i < $nmax; $i++ ) {
     511            // Get y-value for line $i by adding the
     512            // individual bars from all the plots added.
     513            // It would be wrong to just add the
     514            // individual plots max y-value since that
     515            // would in most cases give to large y-value.
     516            $y=$this->plots[0]->coords[0][$i];
     517            for( $j = 1; $j < $this->nbrplots; $j++ ) {
     518                $y += $this->plots[ $j ]->coords[0][$i];
     519            }
     520            $ymax[$i] = $y;
     521        }
     522        $ymax = max($ymax);
     523        return array($xmax,$ymax);
     524    }
    477525
    478526    function Min() {
    479         $nmax=0;
    480         list($xmin,$ysetmin) = $this->plots[0]->Min();
    481         $n = count($this->plots);
    482         for($i=0; $i < $n; ++$i) {
    483             $nc = count($this->plots[$i]->coords[0]);
    484             $nmax = max($nmax,$nc);
    485             list($x,$y) = $this->plots[$i]->Min();
    486             $xmin = Min($xmin,$x);
    487             $ysetmin = Min($y,$ysetmin);
    488         }
    489         for( $i = 0; $i < $nmax; $i++ ) {
    490             // Get y-value for line $i by adding the
    491             // individual bars from all the plots added.
    492             // It would be wrong to just add the
    493             // individual plots min y-value since that
    494             // would in most cases give to small y-value.
    495             $y=$this->plots[0]->coords[0][$i];
    496             for( $j = 1; $j < $this->nbrplots; $j++ ) {
    497                 $y += $this->plots[ $j ]->coords[0][$i];
    498             }
    499             $ymin[$i] = $y;
    500         }
    501         $ymin = Min($ysetmin,Min($ymin));
    502         return array($xmin,$ymin);
     527        $nmax=0;
     528        list($xmin,$ysetmin) = $this->plots[0]->Min();
     529        $n = count($this->plots);
     530        for($i=0; $i < $n; ++$i) {
     531            $nc = count($this->plots[$i]->coords[0]);
     532            $nmax = max($nmax,$nc);
     533            list($x,$y) = $this->plots[$i]->Min();
     534            $xmin = Min($xmin,$x);
     535            $ysetmin = Min($y,$ysetmin);
     536        }
     537        for( $i = 0; $i < $nmax; $i++ ) {
     538            // Get y-value for line $i by adding the
     539            // individual bars from all the plots added.
     540            // It would be wrong to just add the
     541            // individual plots min y-value since that
     542            // would in most cases give to small y-value.
     543            $y=$this->plots[0]->coords[0][$i];
     544            for( $j = 1; $j < $this->nbrplots; $j++ ) {
     545                $y += $this->plots[ $j ]->coords[0][$i];
     546            }
     547            $ymin[$i] = $y;
     548        }
     549        $ymin = Min($ysetmin,Min($ymin));
     550        return array($xmin,$ymin);
    503551    }
    504552
     
    506554    function PreStrokeAdjust($graph) {
    507555
    508         // If another plot type have already adjusted the
    509         // offset we don't touch it.
    510         // (We check for empty in case the scale is  a log scale
    511         // and hence doesn't contain any xlabel_offset)
    512        
    513         if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
    514             $graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
    515             if( $this->center ) {
    516                 ++$this->numpoints;
    517                 $a=0.5; $b=0.5;
    518             } else {
    519                 $a=0; $b=0;
    520             }
    521             $graph->xaxis->scale->ticks->SetXLabelOffset($a);
    522             $graph->SetTextScaleOff($b);                                               
    523             $graph->xaxis->scale->ticks->SupressMinorTickMarks();
    524         }
    525        
     556        // If another plot type have already adjusted the
     557        // offset we don't touch it.
     558        // (We check for empty in case the scale is  a log scale
     559        // and hence doesn't contain any xlabel_offset)
     560
     561        if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
     562        $graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
     563            if( $this->center ) {
     564                ++$this->numpoints;
     565                $a=0.5; $b=0.5;
     566            } else {
     567                $a=0; $b=0;
     568            }
     569            $graph->xaxis->scale->ticks->SetXLabelOffset($a);
     570            $graph->SetTextScaleOff($b);
     571            $graph->xaxis->scale->ticks->SupressMinorTickMarks();
     572        }
     573
    526574    }
    527575
    528576    function SetInterpolateMode($aIntMode) {
    529         $this->iStartEndZero=$aIntMode;
     577        $this->iStartEndZero=$aIntMode;
    530578    }
    531579
     
    535583    function LineInterpolate(&$aData) {
    536584
    537         $n=count($aData);
    538         $i=0;
    539    
    540         // If first point is undefined we will set it to the same as the first
    541         // valid data
    542         if( $aData[$i]==='-' ) {
    543             // Find the first valid data
    544             while( $i < $n && $aData[$i]==='-' ) {
    545                 ++$i;
    546             }
    547             if( $i < $n ) {
    548                 for($j=0; $j < $i; ++$j ) {
    549                     if( $this->iStartEndZero )
    550                         $aData[$i] = 0;
    551                     else
    552                         $aData[$j] = $aData[$i];
    553                 }
    554             }
    555             else {
    556                 // All '-' => Error
    557                 return false;
    558             }
    559         }
    560 
    561         while($i < $n) {
    562             while( $i < $n && $aData[$i] !== '-' ) {
    563                 ++$i;
    564             }
    565             if( $i < $n ) {
    566                 $pstart=$i-1;
    567 
    568                 // Now see how long this segment of '-' are
    569                 while( $i < $n && $aData[$i] === '-' )
    570                     ++$i;
    571                 if( $i < $n ) {
    572                     $pend=$i;
    573                     $size=$pend-$pstart;
    574                     $k=($aData[$pend]-$aData[$pstart])/$size;
    575                     // Replace the segment of '-' with a linear interpolated value.
    576                     for($j=1; $j < $size; ++$j ) {
    577                         $aData[$pstart+$j] = $aData[$pstart] + $j*$k ;
    578                     }
    579                 }
    580                 else {
    581                     // There are no valid end point. The '-' goes all the way to the end
    582                     // In that case we just set all the remaining values the the same as the
    583                     // last valid data point.
    584                     for( $j=$pstart+1; $j < $n; ++$j )
    585                         if( $this->iStartEndZero )
    586                             $aData[$j] = 0;
    587                         else
    588                             $aData[$j] = $aData[$pstart] ;             
    589                 }
    590             }
    591         }
    592         return true;
    593     }
    594 
    595 
     585        $n=count($aData);
     586        $i=0;
     587
     588        // If first point is undefined we will set it to the same as the first
     589        // valid data
     590        if( $aData[$i]==='-' ) {
     591            // Find the first valid data
     592            while( $i < $n && $aData[$i]==='-' ) {
     593                ++$i;
     594            }
     595            if( $i < $n ) {
     596                for($j=0; $j < $i; ++$j ) {
     597                    if( $this->iStartEndZero )
     598                    $aData[$i] = 0;
     599                    else
     600                    $aData[$j] = $aData[$i];
     601                }
     602            }
     603            else {
     604                // All '-' => Error
     605                return false;
     606            }
     607        }
     608
     609        while($i < $n) {
     610            while( $i < $n && $aData[$i] !== '-' ) {
     611                ++$i;
     612            }
     613            if( $i < $n ) {
     614                $pstart=$i-1;
     615
     616                // Now see how long this segment of '-' are
     617                while( $i < $n && $aData[$i] === '-' ) {
     618                    ++$i;
     619                }
     620                if( $i < $n ) {
     621                    $pend=$i;
     622                    $size=$pend-$pstart;
     623                    $k=($aData[$pend]-$aData[$pstart])/$size;
     624                    // Replace the segment of '-' with a linear interpolated value.
     625                    for($j=1; $j < $size; ++$j ) {
     626                        $aData[$pstart+$j] = $aData[$pstart] + $j*$k ;
     627                    }
     628                }
     629                else {
     630                    // There are no valid end point. The '-' goes all the way to the end
     631                    // In that case we just set all the remaining values the the same as the
     632                    // last valid data point.
     633                    for( $j=$pstart+1; $j < $n; ++$j )
     634                    if( $this->iStartEndZero ) {
     635                        $aData[$j] = 0;
     636                    }
     637                    else {
     638                        $aData[$j] = $aData[$pstart] ;
     639                    }
     640                }
     641            }
     642        }
     643        return true;
     644    }
    596645
    597646    // To avoid duplicate of line drawing code here we just
     
    602651    // since this method would have a side effect.
    603652    function Stroke($img,$xscale,$yscale) {
    604         $img->SetLineWeight($this->weight);
    605         $this->numpoints = count($this->plots[0]->coords[0]);
    606         // Allocate array
    607         $coords[$this->nbrplots][$this->numpoints]=0;
    608         for($i=0; $i<$this->numpoints; $i++) {
    609             $coords[0][$i]=$this->plots[0]->coords[0][$i];
    610             $accy=$coords[0][$i];
    611             for($j=1; $j<$this->nbrplots; ++$j ) {
    612                 $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy;
    613                 $accy = $coords[$j][$i];
    614             }
    615         }
    616         for($j=$this->nbrplots-1; $j>=0; --$j) {
    617             $p=$this->plots[$j];
    618             for( $i=0; $i<$this->numpoints; ++$i) {
    619                 $tmp[$i]=$p->coords[0][$i];
    620                 $p->coords[0][$i]=$coords[$j][$i];
    621             }
    622             $p->Stroke($img,$xscale,$yscale);
    623             for( $i=0; $i<$this->numpoints; ++$i)
    624                 $p->coords[0][$i]=$tmp[$i];
    625             $p->coords[0][]=$tmp;
    626         }
     653        $img->SetLineWeight($this->weight);
     654        $this->numpoints = count($this->plots[0]->coords[0]);
     655        // Allocate array
     656        $coords[$this->nbrplots][$this->numpoints]=0;
     657        for($i=0; $i<$this->numpoints; $i++) {
     658            $coords[0][$i]=$this->plots[0]->coords[0][$i];
     659            $accy=$coords[0][$i];
     660            for($j=1; $j<$this->nbrplots; ++$j ) {
     661                $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy;
     662                $accy = $coords[$j][$i];
     663            }
     664        }
     665        for($j=$this->nbrplots-1; $j>=0; --$j) {
     666            $p=$this->plots[$j];
     667            for( $i=0; $i<$this->numpoints; ++$i) {
     668                $tmp[$i]=$p->coords[0][$i];
     669                $p->coords[0][$i]=$coords[$j][$i];
     670            }
     671            $p->Stroke($img,$xscale,$yscale);
     672            for( $i=0; $i<$this->numpoints; ++$i) {
     673                $p->coords[0][$i]=$tmp[$i];
     674            }
     675            $p->coords[0][]=$tmp;
     676        }
    627677    }
    628678} // Class
Note: See TracChangeset for help on using the changeset viewer.