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_line.php

    r265 r267  
    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 1921 2009-12-11 11:46:39Z ljp $
    7  //
    8  // Copyright (c) Asial Corporation. 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 981 2008-03-24 11:51:12Z ljp $
     7//
     8// Copyright (c) Aditus Consulting. 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, $fillFromMax = false;
     32    protected $fillFromMin = false ;
    3333    protected $fillgrad=false,$fillgrad_fromcolor='navy',$fillgrad_tocolor='silver',$fillgrad_numcolors=100;
    3434    protected $iFastStroke=false;
    3535
    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 
     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       
    5150    function SetBarCenter($aFlag=true) {
    52         $this->barcenter=$aFlag;
     51        $this->barcenter=$aFlag;
    5352    }
    5453
    5554    function SetStyle($aStyle) {
    56         $this->line_style=$aStyle;
    57     }
    58 
     55        $this->line_style=$aStyle;
     56    }
     57       
    5958    function SetStepStyle($aFlag=true) {
    60         $this->step_style = $aFlag;
    61     }
    62 
     59        $this->step_style = $aFlag;
     60    }
     61       
    6362    function SetColor($aColor) {
    64         parent::SetColor($aColor);
    65     }
    66 
     63        parent::SetColor($aColor);
     64    }
     65       
    6766    function SetFillFromYMin($f=true) {
    68         $this->fillFromMin = $f ;
    69     }
    70 
    71     function SetFillFromYMax($f=true) {
    72         $this->fillFromMax = $f ;
    73     }
    74 
     67        $this->fillFromMin = $f ;
     68    }
     69   
    7570    function SetFillColor($aColor,$aFilled=true) {
    76         //$this->color = $aColor;
    77         $this->fill_color=$aColor;
    78         $this->filled=$aFilled;
     71        $this->fill_color=$aColor;
     72        $this->filled=$aFilled;
    7973    }
    8074
    8175    function SetFillGradient($aFromColor,$aToColor,$aNumColors=100,$aFilled=true) {
    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 
     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       
    8983    function Legend($graph) {
    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         }
     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        }       
    107101    }
    108102
    109103    function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) {
    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 
     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       
    119113    // Gets called before any axis are stroked
    120114    function PreStrokeAdjust($graph) {
    121115
    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 
     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   
    139134    function SetFastStroke($aFlg=true) {
    140         $this->iFastStroke = $aFlg;
     135        $this->iFastStroke = $aFlg;
    141136    }
    142137
    143138    function FastStroke($img,$xscale,$yscale,$aStartPoint=0,$exist_x=true) {
    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 
     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       
    184173    function Stroke($img,$xscale,$yscale) {
    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         }
     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        }
    462415    }
    463416} // Class
     
    466419//===================================================
    467420// CLASS AccLinePlot
    468 // Description:
     421// Description: 
    469422//===================================================
    470423class AccLinePlot extends Plot {
    471424    protected $plots=null,$nbrplots=0;
    472425    private $iStartEndZero=true;
    473     //---------------
    474     // CONSTRUCTOR
    475     function __construct($plots) {
     426//---------------
     427// CONSTRUCTOR
     428    function AccLinePlot($plots) {
    476429        $this->plots = $plots;
    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
     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       
    494447    function Legend($graph) {
    495         foreach( $this->plots as $p ) {
    496             $p->DoLegend($graph);
    497         }
    498     }
    499 
     448        foreach( $this->plots as $p )
     449            $p->DoLegend($graph);
     450    }
     451       
    500452    function Max() {
    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     }
     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    }   
    525477
    526478    function Min() {
    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);
     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);
    551503    }
    552504
     
    554506    function PreStrokeAdjust($graph) {
    555507
    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 
     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       
    574526    }
    575527
    576528    function SetInterpolateMode($aIntMode) {
    577         $this->iStartEndZero=$aIntMode;
     529        $this->iStartEndZero=$aIntMode;
    578530    }
    579531
     
    583535    function LineInterpolate(&$aData) {
    584536
    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     }
     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
    645596
    646597    // To avoid duplicate of line drawing code here we just
     
    651602    // since this method would have a side effect.
    652603    function Stroke($img,$xscale,$yscale) {
    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         }
     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        }
    677627    }
    678628} // Class
Note: See TracChangeset for help on using the changeset viewer.