📄 jpgraph.php
字号:
if( $this->ynaxis[$i] != null) { foreach( $this->ynplots[$i] as $p ) { list($xmin,$ymin) = $p->Min(); list($xmax,$ymax) = $p->Max(); $min = Min($xmin,$min); $max = Max($xmax,$max); } } } return array($min,$max); } function AdjustMarginsForTitles() { $totrequired = ($this->title->t != '' ? $this->title->GetTextHeight($this->img) + $this->title->margin + 5 : 0 ) + ($this->subtitle->t != '' ? $this->subtitle->GetTextHeight($this->img) + $this->subtitle->margin + 5 : 0 ) + ($this->subsubtitle->t != '' ? $this->subsubtitle->GetTextHeight($this->img) + $this->subsubtitle->margin + 5 : 0 ) ; $btotrequired = 0; if($this->xaxis != null && !$this->xaxis->hide && !$this->xaxis->hide_labels ) { // Minimum bottom margin if( $this->xaxis->title->t != '' ) { if( $this->img->a == 90 ) $btotrequired = $this->yaxis->title->GetTextHeight($this->img) + 5 ; else $btotrequired = $this->xaxis->title->GetTextHeight($this->img) + 5 ; } else $btotrequired = 0; if( $this->img->a == 90 ) { $this->img->SetFont($this->yaxis->font_family,$this->yaxis->font_style, $this->yaxis->font_size); $lh = $this->img->GetTextHeight('Mg',$this->yaxis->label_angle); } else { $this->img->SetFont($this->xaxis->font_family,$this->xaxis->font_style, $this->xaxis->font_size); $lh = $this->img->GetTextHeight('Mg',$this->xaxis->label_angle); } $btotrequired += $lh + 5; } if( $this->img->a == 90 ) { // DO Nothing. It gets too messy to do this properly for 90 deg... } else{ if( $this->img->top_margin < $totrequired ) { $this->SetMargin($this->img->left_margin,$this->img->right_margin, $totrequired,$this->img->bottom_margin); } if( $this->img->bottom_margin < $btotrequired ) { $this->SetMargin($this->img->left_margin,$this->img->right_margin, $this->img->top_margin,$btotrequired); } } } // Stroke the graph // $aStrokeFileName If != "" the image will be written to this file and NOT // streamed back to the browser function Stroke($aStrokeFileName="") { // Fist make a sanity check that user has specified a scale if( empty($this->yscale) ) { JpGraphError::RaiseL(25031);//('You must specify what scale to use with a call to Graph::SetScale().'); } // Start by adjusting the margin so that potential titles will fit. $this->AdjustMarginsForTitles(); // Setup scale constants if( $this->yscale ) $this->yscale->InitConstants($this->img); if( $this->xscale ) $this->xscale->InitConstants($this->img); if( $this->y2scale ) $this->y2scale->InitConstants($this->img); $n=count($this->ynscale); for($i=0; $i < $n; ++$i) { if( $this->ynscale[$i] ) $this->ynscale[$i]->InitConstants($this->img); } // If the filename is the predefined value = '_csim_special_' // we assume that the call to stroke only needs to do enough // to correctly generate the CSIM maps. // We use this variable to skip things we don't strictly need // to do to generate the image map to improve performance // a best we can. Therefor you will see a lot of tests !$_csim in the // code below. $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); // We need to know if we have stroked the plot in the // GetCSIMareas. Otherwise the CSIM hasn't been generated // and in the case of GetCSIM called before stroke to generate // CSIM without storing an image to disk GetCSIM must call Stroke. $this->iHasStroked = true; // 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]->DoLegend($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]->DoLegend($this); } } // Any plots on the extra Y axises? $n = count($this->ynaxis); for($i=0; $i<$n ; ++$i ) { if( $this->ynplots == null || $this->ynplots[$i] == null) { JpGraphError::RaiseL(25032,$i);//("No plots for Y-axis nbr:$i"); } $m = count($this->ynplots[$i]); for($j=0; $j < $m; ++$j ) { $this->ynplots[$i][$j]->PreStrokeAdjust($this); $this->ynplots[$i][$j]->DoLegend($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) ) { //$e = "n=".count($this->y2plots)."\n"; // $e = "Can't draw unspecified Y-scale.<br>\nYou have either:<br>\n"; // $e .= "1. Specified an Y axis for autoscaling but have not supplied any plots<br>\n"; // $e .= "2. Specified a scale manually but have forgot to specify the tick steps"; JpGraphError::RaiseL(25026); } // Bail out if no plots and no specified X-scale if( (!$this->xscale->IsSpecified() && count($this->plots)==0 && count($this->y2plots)==0) ) JpGraphError::RaiseL(25034);//("<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); $lres = $this->GetLinesYMinMax($this->lines); if( is_array($lres) ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $tres = $this->GetTextsYMinMax(); if( is_array($tres) ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $this->yscale->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor); } elseif( $this->yscale->IsSpecified() && ( $this->yscale->auto_ticks || !$this->yscale->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->yscale->scale[0]; $max = $this->yscale->scale[1]; $this->yscale->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor, $this->yscale->auto_ticks); } if( $this->y2scale != null) { if( !$this->y2scale->IsSpecified() && count($this->y2plots)>0 ) { list($min,$max) = $this->GetPlotsYMinMax($this->y2plots); $lres = $this->GetLinesYMinMax($this->y2lines); if( is_array($lres) ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $tres = $this->GetTextsYMinMax(true); if( is_array($tres) ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $this->y2scale->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); } elseif( $this->y2scale->IsSpecified() && ( $this->y2scale->auto_ticks || !$this->y2scale->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->y2scale->scale[0]; $max = $this->y2scale->scale[1]; $this->y2scale->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor, $this->y2scale->auto_ticks); } } // // Autoscale the multiple Y-axis // $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { if( $this->ynscale[$i] != null) { if( !$this->ynscale[$i]->IsSpecified() && count($this->ynplots[$i])>0 ) { list($min,$max) = $this->GetPlotsYMinMax($this->ynplots[$i]); $this->ynscale[$i]->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); } elseif( $this->ynscale[$i]->IsSpecified() && ( $this->ynscale[$i]->auto_ticks || !$this->ynscale[$i]->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->ynscale[$i]->scale[0]; $max = $this->ynscale[$i]->scale[1]; $this->ynscale[$i]->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor, $this->ynscale[$i]->auto_ticks); } } } //Check if we should autoscale x-axis if( !$this->xscale->IsSpecified() ) { if( substr($this->axtype,0,4) == "text" ) { $max=0; $n = count($this->plots); for($i=0; $i < $n; ++$i ) { $p = $this->plots[$i]; // We need some unfortunate sub class knowledge here in order // to increase number of data points in case it is a line plot // which has the barcenter set. If not it could mean that the // last point of the data is outside the scale since the barcenter // settings means that we will shift the entire plot half a tick step // to the right in oder to align with the center of the bars. if( is_a($p,'BarPlot') || empty($p->barcenter)) { $max=max($max,$p->numpoints-1); } else { $max=max($max,$p->numpoints); } } $min=0; if( $this->y2axis != null ) { foreach( $this->y2plots as $p ) { $max=max($max,$p->numpoints-1); } } $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { if( $this->ynaxis[$i] != null) { foreach( $this->ynplots[$i] as $p ) { $max=max($max,$p->numpoints-1); } } } $this->xscale->Update($this->img,$min,$max); $this->xscale->ticks->Set($this->xaxis->tick_step,1); $this->xscale->ticks->SupressMinorTickMarks(); } else { list($min,$max) = $this->GetXMinMax(); $lres = $this->GetLinesXMinMax($this->lines); if( $lres ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $lres = $this->GetLinesXMinMax($this->y2lines); if( $lres ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $tres = $this->GetTextsXMinMax(); if( $tres ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $tres = $this->GetTextsXMinMax(true); if( $tres ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $this->xscale->AutoScale($this->img,$min,$max,round($this->img->plotwidth/$this->xtick_factor)); } //Adjust position of y-axis and y2-axis to minimum/maximum of x-scale if( !is_numeric($this->yaxis->pos) && !is_string($this->yaxis->pos) ) $this->yaxis->SetPos($this->xscale->GetMinVal()); if( $this->y2axis != null ) { if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) ) $this->y2axis->SetPos($this->xscale->GetMaxVal()); $this->y2axis->SetTitleSide(SIDE_RIGHT); } $n = count($this->ynaxis); $nY2adj = $this->y2axis != null ? $this->iYAxisDeltaPos : 0; for( $i=0; $i < $n; ++$i ) { if( $this->ynaxis[$i] != null ) { if( !is_numeric($this->ynaxis[$i]->pos) && !is_string($this->ynaxis[$i]->pos) ) { $this->ynaxis[$i]->SetPos($this->xscale->GetMaxVal()); $this->ynaxis[$i]->SetPosAbsDelta($i*$this->iYAxisDeltaPos + $nY2adj); } $this->ynaxis[$i]->SetTitleSide(SIDE_RIGHT); } } } elseif( $this->xscale->IsSpecified() && ( $this->xscale->auto_ticks || !$this->xscale->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->xscale->scale[0]; $max = $this->xscale->scale[1]; $this->xscale->AutoScale($this->img,$min,$max, $this->img->plotwidth/$this->xtick_factor, false); if( $this->y2axis != null ) { if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) ) $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. // For X-text scale we ignore all this since the tick are usually // much further in and not close to the Y-axis. Hence the test // for 'text' if( ($this->yaxis->pos==$this->xscale->GetMinVal() || (is_string($this->yaxis->pos) && $this->yaxis->pos=='min')) && !is_numeric($this->xaxis->pos) && $this->yscale->GetMinVal() < 0 && substr($this->axtype,0,4) != 'text' && $this->xaxis->pos!="min" ) { //$this->yscale->ticks->SupressZeroLabel(false); $this->xscale->ticks->SupressFirst(); if( $this->y2axis != null ) { $this->xscale->ticks->SupressLast(); } } elseif( !is_numeric($this->yaxis->pos) && $this->yaxis->pos=='max' ) { $this->xscale->ticks->SupressLast(); } if( !$_csim ) { $this->StrokePlotArea(); if( $this->iIconDepth == DEPTH_BACK ) { $this->StrokeIcons(); } } $this->StrokeAxis(); // Stroke bands if( $this->bands != null && !$_csim) 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->y2bands != null && $this->y2scale != null && !$_csim ) for($i=0; $i < count($this->y2bands); ++$i) { // Stroke all bands that asks to be in the foreground if( $this->y2bands[$i]->depth == DEPTH_BACK ) $this->y2bands[$i]->Stroke($this->img,$this->xscale,$this->y2scale); } if( $this->grid_depth == DEPTH_BACK && !$_csim) { $this->ygrid->Stroke(); $this->xgrid->Stroke(); } // Stroke Y2-axis if( $this->y2axis != null && !$_csim) { $this->y2axis->Stroke($this->xscale); $this->y2grid->Stroke(); } // Stroke yn-axis $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { $this->ynaxis[$i]->Stroke($this->xscale); } $oldoff=$this->xscale->off; if(substr($this->axtype
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -