jpgraph.php

来自「eGroupWare is a multi-user, web-based gr」· PHP 代码 · 共 1,955 行 · 第 1/5 页

PHP
1,955
字号
    //             If false the image is just created in the cache
    function Graph($aWidth=300,$aHeight=200,$aCachedName="",$aTimeOut=0,$aInline=true) {
		
	// If timing is used create a new timing object
	if( BRAND_TIMING ) {
	    global $tim;
	    $tim = new JpgTimer();
	    $tim->Push();
	}
		
	// Automtically generate the image file name based on the name of the script that
	// generates the graph
	if( $aCachedName=="auto" )
	    $aCachedName=GenImgName();
			
	// Should the image be streamed back to the browser or only to the cache?
	$this->inline=$aInline;
		
	$this->img 		=  new RotImage($aWidth,$aHeight);
	$this->cache 	=  new ImgStreamCache($this->img);
	$this->cache->SetTimeOut($aTimeOut);
	$this->title 	=  new Text();
	$this->subtitle =  new Text();
	$this->legend 	=  new Legend();
		
	// If the cached version exist just read it directly from the
	// cache, stream it back to browser and exit
	if( $aCachedName!="" && READ_CACHE && $aInline )
	    if( $this->cache->GetAndStream($aCachedName) ) {
		exit();
	    }
				
	$this->cache_name = $aCachedName;
	$this->SetTickDensity(); // Normal density
    }
//---------------
// PUBLIC METHODS	

    // Should the grid be in front or back of the plot?
    function SetGridDepth($aDepth) {
	$this->grid_depth=$aDepth;
    }
	
    // Specify graph angle 0-360 degrees.
    function SetAngle($aAngle) {
	$this->img->SetAngle($aAngle);
    }
	
    // Add a plot object to the graph
    function Add(&$aPlot) {
	if( $aPlot == null )
	    JpGraphError::Raise("<b><b>JpGraph Error:</b></b> Graph::Add() You tried to add a null plot to the graph.");				
	$this->plots[] = &$aPlot;
    }
	
    // Add plot to second Y-scale
    function AddY2(&$aPlot) {
	if( $aPlot == null )
	    JpGraphError::Raise("<b><b>JpGraph Error:</b></b> Graph::AddY2() You tried to add a null plot to the graph.");				
	$this->y2plots[] = &$aPlot;
    }
	
    // Add text object to the graph
    function AddText(&$aTxt) {
	if( $aTxt == null )
	    JpGraphError::Raise("<b><b>JpGraph Error:</b></b> Graph::AddText() You tried to add a null text to the graph.");		
	if( is_array($aTxt) ) {
	    for($i=0; $i<count($aTxt); ++$i )
		$this->texts[]=&$aTxt[$i];
	}
	else
	    $this->texts[] = &$aTxt;
    }
	
    // Add a line object (class PlotLine) to the graph
    function AddLine(&$aLine) {
	if( $aLine == null )
	    JpGraphError::Raise("<b><b>JpGraph Error:</b></b> Graph::AddLine() You tried to add a null line to the graph.");		
	if( is_array($aLine) ) {
	    for($i=0; $i<count($aLine); ++$i )
		$this->lines[]=&$aLine[$i];
	}
	else
	    $this->lines[] = &$aLine;
    }

    // Add vertical or horizontal band
    function AddBand(&$aBand) {
	if( $aBand == null )
	    JpGraphError::Raise("<b>JpGraph Error:</b> Graph::AddBand() You tried to add a null band to the graph.");
	if( is_array($aBand) ) {
	    for($i=0; $i<count($aBand); ++$i )
		$this->bands[] = &$aBand[$i];
	}
	else
	    $this->bands[] = &$aBand;
    }

	
    // Specify a background image
    function SetBackgroundImage($aFileName,$aBgType=BKIMG_FILLPLOT,$aImgFormat="png") {

	if( $GLOBALS["gd2"] && !USE_TRUECOLOR ) {
	    JpGraphError::Raise("<b>JpGraph Error:</b>You are using GD 2.x and are 
trying to use a background images on a non truecolor image. <br>
To use
background images with GD 2.x you <b>must</b> enable truecolor by setting the
USE_TRUECOLOR constant to TRUE. <br>
<b>Note:</b> Due to a bug in GD 2.0.1 
using any truetype fonts with truecolor images will result in very
poor quality fonts.");
	}

	$this->background_image = $aFileName;
	$this->background_image_type=$aBgType;
	$this->background_image_format=$aImgFormat;
    }
	
    // Adjust brightness and constrast for background image
    function AdjBackgroundImage($aBright,$aContr=0,$aSat=0) {
	$this->background_image_bright=$aBright;
	$this->background_image_contr=$aContr;
	$this->background_image_sat=$aSat;
    }
	
    // Adjust brightness and constrast for image
    function AdjImage($aBright,$aContr=0,$aSat=0) {
	$this->image_bright=$aBright;
	$this->image_contr=$aContr;
	$this->image_sat=$aSat;
    }
	
    // Set a frame around the plot area
    function SetBox($aDrawPlotFrame=true,$aPlotFrameColor=array(0,0,0),$aPlotFrameWeight=1) {
	$this->boxed = $aDrawPlotFrame;
	$this->box_weight = $aPlotFrameWeight;
	$this->box_color = $aPlotFrameColor;
    }
	
    // Specify color for the plotarea (not the margins)
    function SetColor($aColor) {
	$this->plotarea_color=$aColor;
    }
	
    // Specify color for the margins (all areas outside the plotarea)
    function SetMarginColor($aColor) {
	$this->margin_color=$aColor;
    }
	
    // Set a frame around the entire image
    function SetFrame($aDrawImgFrame=true,$aImgFrameColor=array(0,0,0),$aImgFrameWeight=1) {
	$this->doframe = $aDrawImgFrame;
	$this->frame_color = $aImgFrameColor;
	$this->frame_weight = $aImgFrameWeight;
    }
		
    // Set the shadow around the whole image
    function SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor=array(102,102,102)) {
	$this->doshadow = $aShowShadow;
	$this->shadow_color = $aShadowColor;
	$this->shadow_width = $aShadowWidth;
    }

    // Specify x,y scale. Note that if you manually specify the scale
    // you must also specify the tick distance with a call to Ticks::Set()
    function SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1) {
	$this->axtype = $aAxisType;

	$yt=substr($aAxisType,-3,3);
	if( $yt=="lin" )
	    $this->yscale = new LinearScale($aYMin,$aYMax);
	elseif( $yt == "int" ) {
	    $this->yscale = new LinearScale($aYMin,$aYMax);
	    $this->yscale->SetIntScale();
	}
	elseif( $yt=="log" )
	    $this->yscale = new LogScale($aYMin,$aYMax);
	else
	    JpGraphError::Raise("<b>JpGraph Error:</b> Unknown scale specification for Y-scale. ($axtype)");
			
	$xt=substr($aAxisType,0,3);
	if( $xt == "lin" || $xt == "tex" )
	    $this->xscale = new LinearScale($aXMin,$aXMax,"x");
	elseif( $xt == "int" ) {
	    $this->xscale = new LinearScale($aXMin,$aXMax,"x");
	    $this->xscale->SetIntScale();
	}
	elseif( $xt == "log" )
	    $this->xscale = new LogScale($aXMin,$aXMax,"x");
	else
	    JpGraphError::Raise("<b>JpGraph Error:</b> Unknown scale specification for X-scale. ($aAxisType)");

	$this->xscale->Init($this->img);
	$this->yscale->Init($this->img);						
					
	$this->xaxis = new Axis($this->img,$this->xscale);
	$this->yaxis = new Axis($this->img,$this->yscale);
	$this->xgrid = new Grid($this->xaxis);
	$this->ygrid = new Grid($this->yaxis);	
	$this->ygrid->Show();			
    }
	
    // Specify secondary Y scale
    function SetY2Scale($aAxisType="lin",$aY2Min=1,$aY2Max=1) {
	if( $aAxisType=="lin" ) 
	    $this->y2scale = new LinearScale($aY2Min,$aY2Max);
	elseif( $aAxisType=="log" ) {
	    $this->y2scale = new LogScale($aY2Min,$aY2Max);
	}
	else JpGraphError::Raise("JpGraph: Unsupported Y2 axis type: $axtype<br>");
			
	$this->y2scale->Init($this->img);	
	$this->y2axis = new Axis($this->img,$this->y2scale);
	$this->y2axis->scale->ticks->SetDirection(SIDE_LEFT); 
	$this->y2axis->SetLabelPos(SIDE_RIGHT); 
		
	// Deafult position is the max x-value
	$this->y2axis->SetPos($this->xscale->GetMaxVal());
	$this->y2grid = new Grid($this->y2axis);							
    }
	
    // Specify density of ticks when autoscaling 'normal', 'dense', 'sparse', 'verysparse'
    // The dividing factor have been determined heuristically according to my aesthetic 
    // sense (or lack off) y.m.m.v !
    function SetTickDensity($aYDensity=TICKD_NORMAL,$aXDensity=TICKD_NORMAL) {
	$this->xtick_factor=30;
	$this->ytick_factor=25;		
	switch( $aYDensity ) {
	    case TICKD_DENSE:
		$this->ytick_factor=12;			
	    break;
	    case TICKD_NORMAL:
		$this->ytick_factor=25;			
	    break;
	    case TICKD_SPARSE:
		$this->ytick_factor=40;			
	    break;
	    case TICKD_VERYSPARSE:
		$this->ytick_factor=100;			
	    break;		
	    default:
		JpGraphError::Raise("JpGraph: Unsupported Tick density: $densy");
	}
	switch( $aXDensity ) {
	    case TICKD_DENSE:
		$this->xtick_factor=18;							
	    break;
	    case TICKD_NORMAL:
		$this->xtick_factor=30;			
	    break;
	    case TICKD_SPARSE:
		$this->xtick_factor=45;					
	    break;
	    case TICKD_VERYSPARSE:
		$this->xtick_factor=60;								
	    break;		
	    default:
		JpGraphError::Raise("JpGraph: Unsupported Tick density: $densx");
	}		
    }
	
    // Get a string of all image map areas	
    function GetCSIMareas() {
	$csim="";
	foreach ($this->plots as $p) {
	    $csim.= $p->GetCSIMareas();
	}		
	return $csim;
    }
	
    // Get a complete <MAP>..</MAP> tag for the final image map
    function GetHTMLImageMap($aMapName) {
	$im = "<MAP NAME=\"$aMapName\">\n";
	$im .= $this->GetCSIMareas();
	$im .= "</MAP>"; 
	return $im;
    }

    // Stroke the graph
    // $aStrokeFileName	If != "" the image will be written to this file and NOT
    // streamed back to the browser
    function Stroke($aStrokeFileName="") {		
		
	// Do any pre-stroke adjustment that is needed by the different plot types
	// (i.e bar plots want's to add an offset to the x-labels etc)
	for($i=0; $i<count($this->plots)	; ++$i ) {
	    $this->plots[$i]->PreStrokeAdjust($this);
	    $this->plots[$i]->Legend($this);
	}
		
	// Any plots on the second Y scale?
	if( $this->y2scale != null ) {
	    for($i=0; $i<count($this->y2plots)	; ++$i ) {
		$this->y2plots[$i]->PreStrokeAdjust($this);
		$this->y2plots[$i]->Legend($this);
	    }
	}
		
	// Bail out if any of the Y-axis not been specified and
	// has no plots. (This means it is impossible to do autoscaling and
	// no other scale was given so we can't possible draw anything). If you use manual
	// scaling you also have to supply the tick steps as well.
	if( (!$this->yscale->IsSpecified() && count($this->plots)==0) ||
	    ($this->y2scale!=null && !$this->y2scale->IsSpecified() && count($this->y2plots)==0) ) {
	    JpGraphError::Raise("<strong>JpGraph: Can't draw unspecified Y-scale.</strong><br>
				You have either:
				<br>* Specified an Y axis for autoscaling but have not supplied any plots
				<br>* Specified a scale manually but have forgot to specify the tick steps");
	}
		
	// Bail out if no plots and no specified X-scale
	if( (!$this->xscale->IsSpecified() && count($this->plots)==0 && count($this->y2plots)==0) )
	    JpGraphError::Raise("<strong>JpGraph: Can't draw unspecified X-scale.</strong><br>No plots.<br>");

	//Check if we should autoscale y-axis
	if( !$this->yscale->IsSpecified() && count($this->plots)>0 ) {
	    list($min,$max) = $this->GetPlotsYMinMax($this->plots);
	    $this->yscale->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor);
	}

	if( $this->y2scale != null) 
	    if( !$this->y2scale->IsSpecified() && count($this->y2plots)>0 ) {
		list($min,$max) = $this->GetPlotsYMinMax($this->y2plots);
		$this->y2scale->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor);
	    }			
				
	//Check if we should autoscale x-axis
	if( !$this->xscale->IsSpecified() ) {
	    if( substr($this->axtype,0,4) == "text" ) {
		$max=0;
		foreach( $this->plots as $p ) 
		    $max=max($max,$p->numpoints-1);
		$min=0;
		$this->xscale->Update($this->img,$min,$max);
		$this->xscale->ticks->Set($this->xaxis->tick_step,1);
		$this->xscale->ticks->SupressMinorTickMarks();
	    }
	    else {
		list($min,$ymin) = $this->plots[0]->Min();
		list($max,$ymax) = $this->plots[0]->Max();
		foreach( $this->plots as $p ) {
		    list($xmin,$ymin) = $p->Min();
		    list($xmax,$ymax) = $p->Max();			
		    $min = Min($xmin,$min);
		    $max = Max($xmax,$max);
		}
		$this->xscale->AutoScale($this->img,$min,$max,$this->img->plotwidth/$this->xtick_factor);
	    }
			
	    //Adjust position of y-axis and y2-axis to minimum/maximum of x-scale
	    $this->yaxis->SetPos($this->xscale->GetMinVal());
	    if( $this->y2axis != null ) {
		$this->y2axis->SetPos($this->xscale->GetMaxVal());
		$this->y2axis->SetTitleSide(SIDE_RIGHT);
	    }
	}		
		
	// If we have a negative values and x-axis position is at 0
	// we need to supress the first and possible the last tick since
	// they will be drawn on top of the y-axis (and possible y2 axis)
	// The test below might seem strange the reasone being that if
	// the user hasn't specified a value for position this will not
	// be set until we do the stroke for the axis so as of now it
	// is undefined.
		
	if( !$this->xaxis->pos && $this->yscale->GetMinVal() < 0 ) {
	    $this->yscale->ticks->SupressZeroLabel(false);
	    $this->xscale->ticks->SupressFirst();
	    if( $this->y2axis != null ) {
		$this->xscale->ticks->SupressLast();
	    }
	}
		
	$this->StrokePlotArea();
		
	// Stroke axis
	$this->xaxis->Stroke($this->yscale);
	$this->yaxis->Stroke($this->xscale);		

	// Stroke bands
	if( $this->bands != null ) 
	    for($i=0; $i<count($this->bands); ++$i) {
				// Stroke all bands that asks to be in the background
		if( $this->bands[$i]->depth == DEPTH_BACK )
		    $this->bands[$i]->Stroke($this->img,$this->xscale,$this->yscale);
	    }

	if( $this->grid_depth == DEPTH_BACK ) {
	    $this->ygrid->Stroke();
	    $this->xgrid->Stroke();
	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?