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 + -
显示快捷键?