home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / dotproject / lib / jpgraph / src / jpgraph_line.php < prev    next >
Encoding:
PHP Script  |  2002-12-11  |  10.3 KB  |  375 lines

  1. <?php
  2. /*=======================================================================
  3. // File:     JPGRAPH_LINE.PHP
  4. // Description:    Line plot extension for JpGraph
  5. // Created:     2001-01-08
  6. // Author:    Johan Persson (johanp@aditus.nu)
  7. // Ver:        $Id: jpgraph_line.php,v 1.1 2002/12/11 09:41:58 kripper Exp $
  8. //
  9. // License:    This code is released under QPL
  10. // Copyright (C) 2001,2002 Johan Persson
  11. //========================================================================
  12. */
  13.  
  14. // constants for the (filled) area
  15. DEFINE("LP_AREA_FILLED", true);
  16. DEFINE("LP_AREA_NOT_FILLED", false);
  17. DEFINE("LP_AREA_BORDER",false);
  18. DEFINE("LP_AREA_NO_BORDER",true);
  19.  
  20. //===================================================
  21. // CLASS LinePlot
  22. // Description: 
  23. //===================================================
  24. class LinePlot extends Plot{
  25.     var $filled=false;
  26.     var $fill_color='blue';
  27.     var $mark=null;
  28.     var $step_style=false, $center=false;
  29.     var $line_style=1;    // Default to solid
  30.     var $filledAreas = array(); // array of arrays(with min,max,col,filled in them)
  31.     var $barcenter=false;  // When we mix line and bar. Should we center the line in the bar.
  32.  
  33. //---------------
  34. // CONSTRUCTOR
  35.     function LinePlot(&$datay,$datax=false) {
  36.     $this->Plot($datay,$datax);
  37.     $this->mark = new PlotMark();
  38.     }
  39. //---------------
  40. // PUBLIC METHODS    
  41.  
  42.     // Set style, filled or open
  43.     function SetFilled($aFlag=true) {
  44.         JpGraphError::Raise('LinePlot::SetFilled() is deprecated. Use SetFillColor()');
  45.     }
  46.     
  47.     function SetBarCenter($aFlag=true) {
  48.     $this->barcenter=$aFlag;
  49.     }
  50.  
  51.     function SetStyle($aStyle) {
  52.     $this->line_style=$aStyle;
  53.     }
  54.     
  55.     function SetStepStyle($aFlag=true) {
  56.     $this->step_style = $aFlag;
  57.     }
  58.     
  59.     function SetColor($aColor) {
  60.     parent::SetColor($aColor);
  61.     }
  62.     
  63.     function SetFillColor($aColor,$aFilled=true) {
  64.     $this->fill_color=$aColor;
  65.     $this->filled=$aFilled;
  66.     }
  67.     
  68.     function Legend(&$graph) {
  69.     if( $this->legend!="" ) {
  70.         if( $this->filled ) {
  71.         $graph->legend->Add($this->legend,
  72.                     $this->fill_color,$this->mark,0,
  73.                     $this->legendcsimtarget,$this->legendcsimalt);
  74.         } else {
  75.         $graph->legend->Add($this->legend,
  76.                     $this->color,$this->mark,$this->line_style,
  77.                     $this->legendcsimtarget,$this->legendcsimalt);
  78.         }
  79.     }    
  80.     }
  81.  
  82.     function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) {
  83.     if($aMin > $aMax) {
  84.         // swap
  85.         $tmp = $aMin;
  86.         $aMin = $aMax;
  87.         $aMax = $tmp;
  88.     } 
  89.     $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder);
  90.     }
  91.     
  92.     // Gets called before any axis are stroked
  93.     function PreStrokeAdjust(&$graph) {
  94.  
  95.     // If another plot type have already adjusted the
  96.     // offset we don't touch it.
  97.     // (We check for empty in case the scale is  a log scale 
  98.     // and hence doesn't contain any xlabel_offset)
  99.     if( empty($graph->xaxis->scale->ticks->xlabel_offset) ||
  100.         $graph->xaxis->scale->ticks->xlabel_offset == 0 ) {
  101.         if( $this->center ) {
  102.         ++$this->numpoints;
  103.         $a=0.5; $b=0.5;
  104.         } else {
  105.         $a=0; $b=0;
  106.         }
  107.         $graph->xaxis->scale->ticks->SetXLabelOffset($a);
  108.         $graph->SetTextScaleOff($b);                        
  109.         $graph->xaxis->scale->ticks->SupressMinorTickMarks();
  110.     }
  111.     }
  112.     
  113.     function Stroke(&$img,&$xscale,&$yscale) {
  114.     $numpoints=count($this->coords[0]);
  115.     if( isset($this->coords[1]) ) {
  116.         if( count($this->coords[1])!=$numpoints )
  117.         JpGraphError::Raise("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints");
  118.         else
  119.         $exist_x = true;
  120.     }
  121.     else 
  122.         $exist_x = false;
  123.  
  124.     if( $this->barcenter ) 
  125.         $textadj = 0.5-$xscale->text_scale_off;
  126.     else
  127.         $textadj = 0;
  128.  
  129.     if( $exist_x )
  130.         $xs=$this->coords[1][0];
  131.     else
  132.         $xs= $textadj;
  133.  
  134.     $img->SetStartPoint($xscale->Translate($xs),
  135.                         $yscale->Translate($this->coords[0][0]));
  136.         
  137.     if( $this->filled ) {
  138.         $cord[] = $xscale->Translate($xs);
  139.         $min = $yscale->GetMinVal();
  140.         if( $min > 0 )
  141.         $cord[] = $yscale->Translate($min);
  142.         else
  143.         $cord[] = $yscale->Translate(0);
  144.     }
  145.     $xt = $xscale->Translate($xs);
  146.     $yt = $yscale->Translate($this->coords[0][0]);
  147.     $cord[] = $xt;
  148.     $cord[] = $yt;
  149.     $yt_old = $yt;
  150.  
  151.     $this->value->Stroke($img,$this->coords[0][0],$xt,$yt);
  152.  
  153.     $img->SetColor($this->color);
  154.     $img->SetLineWeight($this->weight);
  155.     $img->SetLineStyle($this->line_style);
  156.     for( $pnts=1; $pnts<$numpoints; ++$pnts) {
  157.         
  158.         if( $exist_x ) $x=$this->coords[1][$pnts];
  159.         else $x=$pnts+$textadj;
  160.         $xt = $xscale->Translate($x);
  161.         $yt = $yscale->Translate($this->coords[0][$pnts]);
  162.         
  163.         if( $this->step_style ) {
  164.         $img->StyleLineTo($xt,$yt_old);
  165.         $img->StyleLineTo($xt,$yt);
  166.  
  167.         $cord[] = $xt;
  168.         $cord[] = $yt_old;
  169.     
  170.         $cord[] = $xt;
  171.         $cord[] = $yt;
  172.  
  173.         }
  174.         else {
  175.         $y=$this->coords[0][$pnts];
  176.         if( is_numeric($y) || (is_string($y) && $y != "-") ) {
  177.             $tmp1=$this->coords[0][$pnts];
  178.             $tmp2=$this->coords[0][$pnts-1];                      
  179.             if( is_numeric($tmp1)  && (is_numeric($tmp2) || $tmp2=="-" ) ) { 
  180.             $img->StyleLineTo($xt,$yt);
  181.             } 
  182.             else {
  183.             $img->SetStartPoint($xt,$yt);
  184.             }
  185.  
  186.             if( is_numeric($tmp1)  && 
  187.             (is_numeric($tmp2) || $tmp2=="-" || ($this->filled && $tmp2=='') ) ) { 
  188.             $cord[] = $xt;
  189.             $cord[] = $yt;
  190.             } 
  191.         }
  192.         }
  193.         $yt_old = $yt;
  194.  
  195.         $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
  196.  
  197.     }    
  198.  
  199.     if( $this->filled ) {
  200.         $cord[] = $xt;
  201.         if( $min > 0 )
  202.         $cord[] = $yscale->Translate($min);
  203.         else
  204.         $cord[] = $yscale->Translate(0);
  205.         $img->SetColor($this->fill_color);    
  206.         $img->FilledPolygon($cord);
  207.         $img->SetColor($this->color);
  208.         $img->Polygon($cord);
  209.     }
  210.     if(!empty($this->filledAreas)) {
  211.  
  212.         $minY = $yscale->Translate($yscale->GetMinVal());
  213.         $factor = ($this->step_style ? 4 : 2);
  214.  
  215.         for($i = 0; $i < sizeof($this->filledAreas); ++$i) {
  216.         // go through all filled area elements ordered by insertion
  217.         // fill polygon array
  218.         $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor];
  219.         $areaCoords[] = $minY;
  220.  
  221.         $areaCoords =
  222.             array_merge($areaCoords,
  223.                 array_slice($cord,
  224.                         $this->filledAreas[$i][0] * $factor,
  225.                         ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1))  * $factor));
  226.         $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x
  227.         $areaCoords[] = $minY; // last y
  228.         
  229.         if($this->filledAreas[$i][3]) {
  230.             $img->SetColor($this->filledAreas[$i][2]);
  231.             $img->FilledPolygon($areaCoords);
  232.             $img->SetColor($this->color);
  233.         }
  234.         
  235.         $img->Polygon($areaCoords);
  236.         $areaCoords = array();
  237.         }
  238.     }    
  239.  
  240.     if( $this->mark->type == -1 || $this->mark->show == false )
  241.         return;
  242.  
  243.     for( $pnts=0; $pnts<$numpoints; ++$pnts) {
  244.  
  245.         if( $exist_x ) $x=$this->coords[1][$pnts];
  246.         else $x=$pnts+$textadj;
  247.         $xt = $xscale->Translate($x);
  248.         $yt = $yscale->Translate($this->coords[0][$pnts]);
  249.  
  250.         if( is_numeric($this->coords[0][$pnts]) ) {
  251.         if( !empty($this->csimtargets[$pnts]) ) {
  252.             $this->mark->SetCSIMTarget($this->csimtargets[$pnts]);
  253.             $this->mark->SetCSIMAlt($this->csimalts[$pnts]);
  254.         }
  255.         $this->mark->SetCSIMAltVal($this->coords[0][$pnts]);
  256.         $this->mark->Stroke($img,$xt,$yt);    
  257.         $this->csimareas .= $this->mark->GetCSIMAreas();
  258.         $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt);
  259.         }
  260.     }
  261.  
  262.  
  263.     }
  264. } // Class
  265.  
  266.  
  267. //===================================================
  268. // CLASS AccLinePlot
  269. // Description: 
  270. //===================================================
  271. class AccLinePlot extends Plot {
  272.     var $plots=null,$nbrplots=0,$numpoints=0;
  273. //---------------
  274. // CONSTRUCTOR
  275.     function AccLinePlot($plots) {
  276.         $this->plots = $plots;
  277.     $this->nbrplots = count($plots);
  278.     $this->numpoints = $plots[0]->numpoints;        
  279.     }
  280.  
  281. //---------------
  282. // PUBLIC METHODS    
  283.     function Legend(&$graph) {
  284.     foreach( $this->plots as $p )
  285.         $p->Legend($graph);
  286.     }
  287.     
  288.     function Max() {
  289.     list($xmax) = $this->plots[0]->Max();
  290.     $nmax=0;
  291.     for($i=0; $i<count($this->plots); ++$i) {
  292.         $n = count($this->plots[$i]->coords[0]);
  293.         $nmax = max($nmax,$n);
  294.         list($x) = $this->plots[$i]->Max();
  295.         $xmax = Max($xmax,$x);
  296.     }
  297.     for( $i = 0; $i < $nmax; $i++ ) {
  298.         // Get y-value for line $i by adding the
  299.         // individual bars from all the plots added.
  300.         // It would be wrong to just add the
  301.         // individual plots max y-value since that
  302.         // would in most cases give to large y-value.
  303.         $y=$this->plots[0]->coords[0][$i];
  304.         for( $j = 1; $j < $this->nbrplots; $j++ ) {
  305.         $y += $this->plots[ $j ]->coords[0][$i];
  306.         }
  307.         $ymax[$i] = $y;
  308.     }
  309.     $ymax = max($ymax);
  310.     return array($xmax,$ymax);
  311.     }    
  312.  
  313.     function Min() {
  314.     $nmax=0;
  315.     list($xmin,$ysetmin) = $this->plots[0]->Min();
  316.     for($i=0; $i<count($this->plots); ++$i) {
  317.         $n = count($this->plots[$i]->coords[0]);
  318.         $nmax = max($nmax,$n);
  319.         list($x,$y) = $this->plots[$i]->Min();
  320.         $xmin = Min($xmin,$x);
  321.         $ysetmin = Min($y,$ysetmin);
  322.     }
  323.     for( $i = 0; $i < $nmax; $i++ ) {
  324.         // Get y-value for line $i by adding the
  325.         // individual bars from all the plots added.
  326.         // It would be wrong to just add the
  327.         // individual plots min y-value since that
  328.         // would in most cases give to small y-value.
  329.         $y=$this->plots[0]->coords[0][$i];
  330.         for( $j = 1; $j < $this->nbrplots; $j++ ) {
  331.         $y += $this->plots[ $j ]->coords[0][$i];
  332.         }
  333.         $ymin[$i] = $y;
  334.     }
  335.     $ymin = Min($ysetmin,Min($ymin));
  336.     return array($xmin,$ymin);
  337.     }
  338.  
  339.  
  340.     // To avoid duplicate of line drawing code here we just
  341.     // change the y-values for each plot and then restore it
  342.     // after we have made the stroke. We must do this copy since
  343.     // it wouldn't be possible to create an acc line plot
  344.     // with the same graphs, i.e AccLinePlot(array($pl,$pl,$pl));
  345.     // since this method would have a side effect.
  346.     function Stroke(&$img,&$xscale,&$yscale) {
  347.     $img->SetLineWeight($this->weight);
  348.     // Allocate array
  349.     $coords[$this->nbrplots][$this->numpoints]=0;
  350.     for($i=0; $i<$this->numpoints; $i++) {
  351.         $coords[0][$i]=$this->plots[0]->coords[0][$i]; 
  352.         $accy=$coords[0][$i];
  353.         for($j=1; $j<$this->nbrplots; ++$j ) {
  354.         $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy; 
  355.         $accy = $coords[$j][$i];
  356.         }
  357.     }
  358.     for($j=$this->nbrplots-1; $j>=0; --$j) {
  359.         $p=$this->plots[$j];
  360.         for( $i=0; $i<$this->numpoints; ++$i) {
  361.         $tmp[$i]=$p->coords[0][$i];
  362.         $p->coords[0][$i]=$coords[$j][$i];
  363.         }
  364.         $p->Stroke($img,$xscale,$yscale);
  365.         for( $i=0; $i<$this->numpoints; ++$i) 
  366.         $p->coords[0][$i]=$tmp[$i];
  367.         $p->coords[0][]=$tmp;
  368.     }
  369.     }
  370. } // Class
  371.  
  372.  
  373. /* EOF */
  374. ?>
  375.