jpgraph.php
来自「eGroupWare is a multi-user, web-based gr」· PHP 代码 · 共 1,955 行 · 第 1/5 页
PHP
1,955 行
if( $this->title_adjust=="high" )
$this->title->Pos($this->img->width-$this->img->right_margin,$y,"right","top");
elseif($this->title_adjust=="middle")
$this->title->Pos(($this->img->width-$this->img->left_margin-$this->img->right_margin)/2+$this->img->left_margin,$y,"center","top");
elseif($this->title_adjust=="low")
$this->title->Pos($this->img->left_margin,$y,"left","top");
}
elseif( $this->scale->type == "y" ) {
// Add line weight to the height of the axis since
// the x-axis could have a width>1 and we want the axis to fit nicely together.
$this->img->FilledRectangle($pos-$this->weight+1,$this->img->top_margin,
$pos,$this->img->height-$this->img->bottom_margin+$this->weight-1);
$x=$pos ;
if( $this->title_side == SIDE_LEFT ) {
$x -= $this->title_margin;
$halign="right";
}
else {
$x += $this->title_margin;
$halign="left";
}
if( $this->title_adjust=="high" )
$this->title->Pos($x,$this->img->top_margin,$halign,"top");
elseif($this->title_adjust=="middle" || $this->title_adjust=="center")
$this->title->Pos($x,($this->img->height-$this->img->top_margin-$this->img->bottom_margin)/2+$this->img->top_margin,$halign,"center");
elseif($this->title_adjust=="low")
$this->title->Pos($x,$this->img->height-$this->img->bottom_margin,$halign,"bottom");
}
$this->scale->ticks->Stroke($this->img,$this->scale,$pos);
$this->StrokeLabels($pos);
$this->title->Stroke($this->img);
}
// Position for axis line on the "other" scale
function SetPos($aPosOnOtherScale) {
$this->pos=$aPosOnOtherScale;
}
// Specify the angle for the tick labels
function SetLabelAngle($aAngle) {
$this->label_angle = $aAngle;
}
//---------------
// PRIVATE METHODS
// Draw all the tick labels on major tick marks
function StrokeLabels($aPos,$aMinor=false) {
$this->img->SetColor($this->label_color);
$this->img->SetFont($this->font_family,$this->font_style,$this->font_size);
$yoff=$this->img->GetFontHeight()/2;
// Only draw labels at major tick marks
$nbr = count($this->scale->ticks->maj_ticks_label);
// We have the option to not-display the very first mark
// (Usefull when the first label might interfere with another
// axis.)
if( $this->show_first_label ) $start=0;
else $start=1;
// Note. the $limit is only used for the x axis since we
// might otherwise overshoot if the scale has been centered
// This is due to us "loosing" the last tick mark if we center.
//if( $this->scale->type=="x" )
// $limit=$this->img->width-$this->img->right_margin;
//else
// $limit=$this->img->height;
// $i holds the current index for the label
$i=$start;
// Now run through all labels making sure we don't overshoot the end
// of the scale.
while( $i<$nbr ) {
// $tpos holds the absolute text position for the label
$tpos=$this->scale->ticks->maj_ticklabels_pos[$i];
// we only draw every $label_step label
if( ($i % $this->label_step)==0 ) {
// If the label has been specified use that and in other case
// just label the mark with the actual scale value
$m=$this->scale->ticks->GetMajor();
// ticks_label has an entry for each data point
if( isset($this->ticks_label[$i*$m]) )
$label=$this->ticks_label[$i*$m];
else
$label=$this->scale->ticks->maj_ticks_label[$i];
if( $this->scale->type == "x" ) {
if( $this->label_angle==0 || $this->label_angle==90 )
$this->img->SetTextAlign("center","top");
else
$this->img->SetTextAlign("topanchor","top");
$this->img->StrokeText($tpos,$aPos+$this->tick_label_margin,$label,$this->label_angle);
}
else {
// scale->type == "y"
if( $this->label_angle!=0 )
JpGraphError::Raise("<b>JpGraph Error:</b> Labels at an angle are not supported on Y-axis");
if( $this->labelPos == 0 ) { // To the left of y-axis
$this->img->SetTextAlign("right","center");
$this->img->StrokeText($aPos-$this->tick_label_margin,$tpos,$label);
}
else { // To the right of the y-axis
$this->img->SetTextAlign("left","center");
$this->img->StrokeText($aPos+$this->tick_label_margin,$tpos,$label);
}
}
}
++$i;
}
}
} // Class
//===================================================
// CLASS Ticks
// Description: Abstract base class for drawing linear and logarithmic
// tick marks on axis
//===================================================
class Ticks {
var $minor_abs_size=3, $major_abs_size=5;
var $direction=1; // Should ticks be in(=1) the plot area or outside (=-1)?
var $scale;
var $is_set=false;
var $precision=-1;
var $supress_zerolabel=false,$supress_first=false;
var $supress_last=false,$supress_tickmarks=false,$supress_minor_tickmarks=false;
var $mincolor="",$majcolor="";
var $weight=1;
var $label_formatstr=""; // C-style format string to use for labels
var $label_formfunc="";
//---------------
// CONSTRUCTOR
function Ticks(&$aScale) {
$this->scale=&$aScale;
}
//---------------
// PUBLIC METHODS
// Set format string for automatic labels
function SetLabelFormat($aFormatString) {
$this->label_formatstr=$aFormatString;
}
function SetFormatCallback($aCallbackFuncName) {
$this->label_formfunc = $aCallbackFuncName;
}
// Don't display the first zero label
function SupressZeroLabel($aFlag=true) {
$this->supress_zerolabel=$aFlag;
}
// Don't display minor tick marks
function SupressMinorTickMarks($aHide=true) {
$this->supress_minor_tickmarks=$aHide;
}
// Don't display major tick marks
function SupressTickMarks($aHide=true) {
$this->supress_tickmarks=$aHide;
}
// Hide the first tick mark
function SupressFirst($aHide=true) {
$this->supress_first=$aHide;
}
// Hide the last tick mark
function SupressLast($aHide=true) {
$this->supress_last=$aHide;
}
// Size (in pixels) of minor tick marks
function GetMinTickAbsSize() {
return $this->minor_abs_size;
}
// Size (in pixels) of major tick marks
function GetMajTickAbsSize() {
return $this->major_abs_size;
}
// Have the ticks been specified
function IsSpecified() {
return $this->is_set;
}
// Set the distance between major and minor tick marks
function Set($aMaj,$aMin) {
// "Virtual method"
// Should be implemented by the concrete subclass
// if any action is wanted.
}
// Specify number of decimals in automtic labels
// Deprecated from 1.4. Use SetFormatString() instead
function SetPrecision($aPrecision) {
$this->precision=$aPrecision;
}
// Which side of the axis should the ticks be on
function SetDirection($aSide=SIDE_RIGHT) {
$this->direction=$aSide;
}
// Set colors for major and minor tick marks
function SetMarkColor($aMajorColor,$aMinorColor="") {
$this->majcolor=$aMajorColor;
// If not specified use same as major
if( $aMinorColor=="" )
$this->mincolor=$aMajorColor;
else
$this->mincolor=$aMinorColor;
}
function SetWeight($aWeight) {
$this->weight=$aWeight;
}
} // Class
//===================================================
// CLASS LinearTicks
// Description: Draw linear ticks on axis
//===================================================
class LinearTicks extends Ticks {
var $minor_step=1, $major_step=2;
var $xlabel_offset=0,$xtick_offset=0;
var $label_offset=0; // What offset should the displayed label have
// i.e should we display 0,1,2 or 1,2,3,4 or 2,3,4 etc
var $text_label_start=0;
//---------------
// CONSTRUCTOR
function LinearTicks() {
// Empty
}
//---------------
// PUBLIC METHODS
// Return major step size in world coordinates
function GetMajor() {
return $this->major_step;
}
// Return minor step size in world coordinates
function GetMinor() {
return $this->minor_step;
}
// Set Minor and Major ticks (in world coordinates)
function Set($aMajStep,$aMinStep) {
if( $aMajStep <= 0 || $aMinStep <= 0 ) {
JpGraphError::Raise("<b>JpGraph Error:</b> Minor or major step size is 0. Check that you haven't
got an accidental SetTextTicks(0) in your code.<p>
If this is not the case you might have stumbled upon a bug in JpGraph.
Please report this and if possible include the data that caused the
problem.");
}
$this->major_step=$aMajStep;
$this->minor_step=$aMinStep;
$this->is_set = true;
}
// Draw linear ticks
function Stroke(&$img,&$scale,$pos) {
$maj_step_abs = $scale->scale_factor*$this->major_step;
$min_step_abs = $scale->scale_factor*$this->minor_step;
if( $min_step_abs==0 || $maj_step_abs==0 )
JpGraphError::Raise("<b>JpGraph Error:</b> A plot has an illegal scale. This could for example be
that you are trying to use text autoscaling to draw a line plot with only one point
or similair abnormality (a line needs two points!).");
$limit = $scale->scale_abs[1];
$nbrmajticks=floor(1.000001*(($scale->GetMaxVal()-$scale->GetMinVal())/$this->major_step))+1;
$first=0;
// If precision hasn't been specified set it to a sensible value
if( $this->precision==-1 ) {
$t = log10($this->minor_step);
if( $t > 0 )
$precision = 0;
else
$precision = -floor($t);
}
else
$precision = $this->precision;
$img->SetLineWeight($this->weight);
// Handle ticks on X-axis
if( $scale->type == "x" ) {
// Draw the major tick marks
$yu = $pos - $this->direction*$this->GetMajTickAbsSize();
// TODO: Add logic to set label_offset for text labels
$label = (float)$scale->GetMinVal()+$this->text_label_start+$this->label_offset;
$start_abs=$scale->scale_factor*$this->text_label_start;
$nbrmajticks=ceil(($scale->GetMaxVal()-$scale->GetMinVal()-$this->text_label_start )/$this->major_step)+1;
for( $i=0; $label<=$scale->GetMaxVal()+$this->label_offset; ++$i ) {
$x=$scale->scale_abs[0]+$start_abs+$i*$maj_step_abs+$this->xlabel_offset*$min_step_abs;
$this->maj_ticklabels_pos[$i]=ceil($x);
// Apply format
if( $this->label_formfunc != "" ) {
$f=$this->label_formfunc;
$l = $f($label);
}
elseif( $this->label_formatstr != "" )
$l = sprintf($this->label_formatstr,$label);
else
$l = sprintf("%01.".$precision."f",round($label,$precision));
if( ($this->supress_zerolabel && ($l + 0)==0) ||
($this->supress_first && $i==0) ||
($this->supress_last && $i==$nbrmajticks-1) )
$l="";
$this->maj_ticks_label[$i]=$l;
$label+=$this->major_step;
// The x-position of the tick marks can be different from the labels.
// Note that we record the tick position (not the label) so that the grid
// happen upon tick marks and not labels.
$xtick=$scale->scale_abs[0]+$start_abs+$i*$maj_step_abs+$this->xtick_offset*$min_step_abs;
$this->maj_ticks_pos[$i]=ceil($xtick);
if(!($this->xtick_offset > 0 && $i==$nbrmajticks-1) && !$this->supress_tickmarks) {
if( $this->majcolor!="" ) $img->PushColor($this->majcolor);
$img->Line($xtick,$pos,$xtick,$yu);
if( $this->majcolor!="" ) $img->PopColor();
}
}
// Draw the minor tick marks
$yu = $pos - $this->direction*$this->GetMinTickAbsSize();
$label = $scale->GetMinVal();
for( $i=0,$x=$scale->scale_abs[0]; $x<$limit; ++$i ) {
$x=$scale->scale_abs[0]+$i*$min_step_abs;
$this->ticks_pos[]=$x;
$this->ticks_label[]=$label;
$label+=$this->minor_step;
if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
if( $this->mincolor!="" ) $img->PushColor($this->mincolor);
$img->Line($x,$pos,$x,$yu);
if( $this->mincolor!="" ) $img->PopColor();
}
}
}
elseif( $scale->type == "y" ) {
// Draw the major tick marks
$xr = $pos + $this->direction*$this->GetMajTickAbsSize();
$label = $scale->GetMinVal();
for( $i=0; $i<$nbrmajticks; ++$i) {
$y=$scale->scale_abs[0]+$i*$maj_step_abs;
// THe following two lines might seem to be unecessary but they are not!
// The reason being that for X-axis we separate the position of the labels
// and the tick marks which we don't do for the Y-axis.
// We therefore need to make sure both arrays are corcectly filled
// since Axis::StrokeLabels() uses the label positions and Grid::Stroke() uses
// the tick positions.
$this->maj_ticklabels_pos[$i]=$y;
$this->maj_ticks_pos[$i]=$y;
if( $this->label_formfunc != "" ) {
$f=$this->label_formfunc;
$l = $f($label);
}
elseif( $this->label_formatstr != "" )
$l = sprintf($this->label_formatstr,$label);
else
$l = sprintf("%01.".$precision."f",round($label,$precision));
if( ($this->supress_zerolabel && ($l + 0)==0) ||
($this->supress_first && $i==0) ||
($this->supress_last && $i==$nbrmajticks-1) )
$l="";
$this->maj_ticks_label[$i]=$l;
$label+=$this->major_step;
if( !$this->supress_tickmarks ) {
if( $this->majcolor!
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?