public function Create($aPattern, $aColor, $aWeight = 1) { switch ($aPattern) { case BAND_RDIAG: $obj = new RectPatternRDiag($aColor, $aWeight); break; case BAND_LDIAG: $obj = new RectPatternLDiag($aColor, $aWeight); break; case BAND_SOLID: $obj = new RectPatternSolid($aColor, $aWeight); break; case BAND_VLINE: $obj = new RectPatternVert($aColor, $aWeight); break; case BAND_HLINE: $obj = new RectPatternHor($aColor, $aWeight); break; case BAND_3DPLANE: $obj = new RectPattern3DPlane($aColor, $aWeight); break; case BAND_HVCROSS: $obj = new RectPatternCross($aColor, $aWeight); break; case BAND_DIAGCROSS: $obj = new RectPatternDiagCross($aColor, $aWeight); break; default: Util\JpGraphError::RaiseL(16003, $aPattern); //(" Unknown pattern specification ($aPattern)"); } return $obj; }
public function GetImg($aIdx) { if ($aIdx < 0 || $aIdx >= $this->iLen) { Util\JpGraphError::RaiseL(6010, $aIdx); //('Illegal icon index for Gantt builtin icon ['.$aIdx.']'); } return Image::CreateFromString(base64_decode($this->iBuiltinIcon[$aIdx][1])); }
public function Set($aProg) { if ($aProg < 0.0 || $aProg > 1.0) { Util\JpGraphError::RaiseL(6027); //("Progress value must in range [0, 1]"); } $this->iProgress = $aProg; }
public function Set($aMajStep, $aMinStep = false) { if ($aMinStep == false) { $aMinStep = $aMajStep; } if ($aMajStep <= 0 || $aMinStep <= 0) { Util\JpGraphError::RaiseL(25064); //Util\JpGraphError::Raise(" Minor or major step size is 0. Check that you haven't got an accidental SetTextTicks(0) in your code. 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; }
public function SetScale($aScale, $rmax = 0, $dummy1 = 1, $dummy2 = 1, $dummy3 = 1) { if ($aScale == 'lin') { $this->scale = new PolarScale($rmax, $this, $this->iClockwise); } elseif ($aScale == 'log') { $this->scale = new PolarLogScale($rmax, $this, $this->iClockwise); } else { Util\JpGraphError::RaiseL(17004); //('Unknown scale type for polar graph. Must be "lin" or "log"'); } $this->axis = new PolarAxis($this->img, $this->scale); $this->SetMargin(40, 40, 50, 40); }
public function __construct($aDir, $aPattern, $aMin, $aMax, $aColor = "black", $aWeight = 1, $aDepth = DEPTH_BACK) { $f = new RectPatternFactory(); $this->prect = $f->Create($aPattern, $aColor, $aWeight); if (is_numeric($aMin) && is_numeric($aMax) && $aMin > $aMax) { Util\JpGraphError::RaiseL(16004); } //('Min value for plotband is larger than specified max value. Please correct.'); $this->dir = $aDir; $this->min = $aMin; $this->max = $aMax; $this->depth = $aDepth; }
public function __construct($aIcon, $aScale = 1) { global $_gPredefIcons; if (is_string($aIcon)) { $this->iGDImage = Graph::LoadBkgImage('', $aIcon); } elseif (is_integer($aIcon)) { // Builtin image $this->iGDImage = $_gPredefIcons->GetImg($aIcon); } else { Util\JpGraphError::RaiseL(6011); //('Argument to IconImage must be string or integer'); } $this->iScale = $aScale; $this->iWidth = Image::GetWidth($this->iGDImage); $this->iHeight = Image::GetHeight($this->iGDImage); }
public function GetImg($aMark, $aIdx) { $n = $this->an[$aMark]; if (is_string($aIdx)) { if (!in_array($aIdx, $this->colors)) { Util\JpGraphError::RaiseL(23001, $this->name, $aIdx); //('This marker "'.($this->name).'" does not exist in color: '.$aIdx); } $idx = $this->index[$aIdx]; } elseif (!is_integer($aIdx) || is_integer($aIdx) && $aIdx > $this->maxidx) { Util\JpGraphError::RaiseL(23002, $this->name); //('Mark color index too large for marker "'.($this->name).'"'); } else { $idx = $aIdx; } return Image::CreateFromString(base64_decode($this->{$n}[$idx][1])); }
public function Add($aObj) { if (is_array($aObj) && count($aObj) > 0) { $cl = $aObj[0]; } else { $cl = $aObj; } if ($cl instanceof Text) { $this->AddText($aObj); } elseif ($cl instanceof IconPlot) { $this->AddIcon($aObj); } elseif ($cl instanceof WindrosePlot || $cl instanceof LayoutRect || $cl instanceof LayoutHor) { $this->plots[] = $aObj; } else { Util\JpGraphError::RaiseL(22021); } }
public function File($family, $style = FS_NORMAL) { $fam = @$this->font_files[$family]; if (!$fam) { Util\JpGraphError::RaiseL(25046, $family); //("Specified TTF font family (id=$family) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/"); } $ff = @$fam[$style]; // There are several optional file names. They are tried in order // and the first one found is used if (!is_array($ff)) { $ff = array($ff); } $jpgraph_font_dir = dirname(dirname(__FILE__)) . '/fonts/'; foreach ($ff as $font_file) { // All font families are guaranteed to have the normal style if ($font_file === '') { Util\JpGraphError::RaiseL(25047, $this->style_names[$style], $this->font_files[$family][FS_NORMAL]); } //('Style "'.$this->style_names[$style].'" is not available for font family '.$this->font_files[$family][FS_NORMAL].'.'); if (!$font_file) { Util\JpGraphError::RaiseL(25048, $fam); //("Unknown font style specification [$fam]."); } // check jpgraph/src/fonts dir $jpgraph_font_file = $jpgraph_font_dir . $font_file; if (file_exists($jpgraph_font_file) === true && is_readable($jpgraph_font_file) === true) { $font_file = $jpgraph_font_file; break; } // check OS font dir if ($family >= FF_MINCHO && $family <= FF_PGOTHIC) { $font_file = MBTTF_DIR . $font_file; } else { $font_file = TTF_DIR . $font_file; } if (file_exists($font_file) === true && is_readable($font_file) === true) { break; } } if (!file_exists($font_file)) { //Util\JpGraphError::RaiseL(25049, $font_file); //("Font file \"$font_file\" is not readable or does not exist."); return $this->File(FF_DV_SANSSERIF, $style); } return $font_file; }
/** * */ public function ApplyGraph($graph) { $this->graph = $graph; $method_name = ''; $graphClass = explode('\\', get_class($graph)); $classname = end($graphClass); if ($classname == 'Graph') { $method_name = 'SetupGraph'; } else { $method_name = 'Setup' . $classname; } if (method_exists($this, $method_name)) { $this->{$method_name}($graph); } else { Util\JpGraphError::RaiseL(30001, $method_name, $method_name); //Theme::%s() is not defined. \nPlease make %s(\$graph) function in your theme classs. } }
public function Stroke($aImg) { if ($this->rect == null) { Util\JpGraphError::RaiseL(16002); } //(" No positions specified for pattern."); if (!(is_numeric($this->iBackgroundColor) && $this->iBackgroundColor == -1)) { $aImg->SetColor($this->iBackgroundColor); $aImg->FilledRectangle($this->rect->x, $this->rect->y, $this->rect->xe, $this->rect->ye); } $aImg->SetColor($this->color); $aImg->SetLineWeight($this->weight); // Virtual function implemented by subclass $this->DoPattern($aImg); // Frame around the pattern area if ($this->doframe) { $aImg->Rectangle($this->rect->x, $this->rect->y, $this->rect->xe, $this->rect->ye); } }
public function Stroke($aImg) { list($dx, $dy) = $this->isizespec[$this->iSize]; $x = $this->ix; $y = $this->iy; switch ($this->iDirection) { case ARROW_DOWN: $c = array($x, $y, $x - $dx, $y - $dy, $x + $dx, $y - $dy, $x, $y); break; case ARROW_UP: $c = array($x, $y, $x - $dx, $y + $dy, $x + $dx, $y + $dy, $x, $y); break; case ARROW_LEFT: $c = array($x, $y, $x + $dy, $y - $dx, $x + $dy, $y + $dx, $x, $y); break; case ARROW_RIGHT: $c = array($x, $y, $x - $dy, $y - $dx, $x - $dy, $y + $dx, $x, $y); break; default: Util\JpGraphError::RaiseL(6030); //('Unknown arrow direction for link.'); die; break; } $aImg->SetColor($this->iColor); switch ($this->iType) { case ARROWT_SOLID: $aImg->FilledPolygon($c); break; case ARROWT_OPEN: $aImg->Polygon($c); break; default: Util\JpGraphError::RaiseL(6031); //('Unknown arrow type for link.'); die; break; } }
public function Stroke($img, $xscale, $yscale) { $idx = 0; $numpoints = count($this->coords[0]); if (isset($this->coords[1])) { if (count($this->coords[1]) != $numpoints) { Util\JpGraphError::RaiseL(2003, count($this->coords[1]), $numpoints); //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); } else { $exist_x = true; } } else { $exist_x = false; } if ($this->barcenter) { $textadj = 0.5 - $xscale->text_scale_off; } else { $textadj = 0; } // Find the first numeric data point $startpoint = 0; while ($startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint])) { ++$startpoint; } // Bail out if no data points if ($startpoint == $numpoints) { return; } if ($this->iFastStroke) { $this->FastStroke($img, $xscale, $yscale, $startpoint, $exist_x); return; } if ($exist_x) { $xs = $this->coords[1][$startpoint]; } else { $xs = $textadj + $startpoint; } $img->SetStartPoint($xscale->Translate($xs), $yscale->Translate($this->coords[0][$startpoint])); if ($this->filled) { if ($this->fillFromMax) { //$max = $yscale->GetMaxVal(); $cord[$idx++] = $xscale->Translate($xs); $cord[$idx++] = $yscale->scale_abs[1]; } else { $min = $yscale->GetMinVal(); if ($min > 0 || $this->fillFromMin) { $fillmin = $yscale->scale_abs[0]; //Translate($min); } else { $fillmin = $yscale->Translate(0); } $cord[$idx++] = $xscale->Translate($xs); $cord[$idx++] = $fillmin; } } $xt = $xscale->Translate($xs); $yt = $yscale->Translate($this->coords[0][$startpoint]); $cord[$idx++] = $xt; $cord[$idx++] = $yt; $yt_old = $yt; $xt_old = $xt; $y_old = $this->coords[0][$startpoint]; $this->value->Stroke($img, $this->coords[0][$startpoint], $xt, $yt); $img->SetColor($this->color); $img->SetLineWeight($this->weight); $img->SetLineStyle($this->line_style); $pnts = $startpoint + 1; $firstnonumeric = false; while ($pnts < $numpoints) { if ($exist_x) { $x = $this->coords[1][$pnts]; } else { $x = $pnts + $textadj; } $xt = $xscale->Translate($x); $yt = $yscale->Translate($this->coords[0][$pnts]); $y = $this->coords[0][$pnts]; if ($this->step_style) { // To handle null values within step style we need to record the // first non numeric value so we know from where to start if the // non value is '-'. if (is_numeric($y)) { $firstnonumeric = false; if (is_numeric($y_old)) { $img->StyleLine($xt_old, $yt_old, $xt, $yt_old); $img->StyleLine($xt, $yt_old, $xt, $yt); } elseif ($y_old == '-') { $img->StyleLine($xt_first, $yt_first, $xt, $yt_first); $img->StyleLine($xt, $yt_first, $xt, $yt); } else { $yt_old = $yt; $xt_old = $xt; } $cord[$idx++] = $xt; $cord[$idx++] = $yt_old; $cord[$idx++] = $xt; $cord[$idx++] = $yt; } elseif ($firstnonumeric == false) { $firstnonumeric = true; $yt_first = $yt_old; $xt_first = $xt_old; } } else { $tmp1 = $y; $prev = $this->coords[0][$pnts - 1]; if ($tmp1 === '' || $tmp1 === null || $tmp1 === 'X') { $tmp1 = 'x'; } if ($prev === '' || $prev === null || $prev === 'X') { $prev = 'x'; } if (is_numeric($y) || is_string($y) && $y != '-') { if (is_numeric($y) && (is_numeric($prev) || $prev === '-')) { $img->StyleLineTo($xt, $yt); } else { $img->SetStartPoint($xt, $yt); } } if ($this->filled && $tmp1 !== '-') { if ($tmp1 === 'x') { $cord[$idx++] = $cord[$idx - 3]; $cord[$idx++] = $fillmin; } elseif ($prev === 'x') { $cord[$idx++] = $xt; $cord[$idx++] = $fillmin; $cord[$idx++] = $xt; $cord[$idx++] = $yt; } else { $cord[$idx++] = $xt; $cord[$idx++] = $yt; } } else { if (is_numeric($tmp1) && (is_numeric($prev) || $prev === '-')) { $cord[$idx++] = $xt; $cord[$idx++] = $yt; } } } $yt_old = $yt; $xt_old = $xt; $y_old = $y; $this->StrokeDataValue($img, $this->coords[0][$pnts], $xt, $yt); ++$pnts; } if ($this->filled) { $cord[$idx++] = $xt; if ($this->fillFromMax) { $cord[$idx++] = $yscale->scale_abs[1]; } else { if ($min > 0 || $this->fillFromMin) { $cord[$idx++] = $yscale->Translate($min); } else { $cord[$idx++] = $yscale->Translate(0); } } if ($this->fillgrad) { $img->SetLineWeight(1); $grad = new Gradient($img); $grad->SetNumColors($this->fillgrad_numcolors); $grad->FilledFlatPolygon($cord, $this->fillgrad_fromcolor, $this->fillgrad_tocolor); $img->SetLineWeight($this->weight); } else { $img->SetColor($this->fill_color); $img->FilledPolygon($cord); } if ($this->weight > 0) { $img->SetLineWeight($this->weight); $img->SetColor($this->color); // Remove first and last coordinate before drawing the line // sine we otherwise get the vertical start and end lines which // doesn't look appropriate $img->Polygon(array_slice($cord, 2, count($cord) - 4)); } } if (!empty($this->filledAreas)) { $minY = $yscale->Translate($yscale->GetMinVal()); $factor = $this->step_style ? 4 : 2; for ($i = 0; $i < sizeof($this->filledAreas); ++$i) { // go through all filled area elements ordered by insertion // fill polygon array $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor]; $areaCoords[] = $minY; $areaCoords = array_merge($areaCoords, array_slice($cord, $this->filledAreas[$i][0] * $factor, ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor)); $areaCoords[] = $areaCoords[sizeof($areaCoords) - 2]; // last x $areaCoords[] = $minY; // last y if ($this->filledAreas[$i][3]) { $img->SetColor($this->filledAreas[$i][2]); $img->FilledPolygon($areaCoords); $img->SetColor($this->color); } // Check if we should draw the frame. // If not we still re-draw the line since it might have been // partially overwritten by the filled area and it doesn't look // very good. if ($this->filledAreas[$i][4]) { $img->Polygon($areaCoords); } else { $img->Polygon($cord); } $areaCoords = array(); } } if (!is_object($this->mark) || $this->mark->type == -1 || $this->mark->show == false) { return; } for ($pnts = 0; $pnts < $numpoints; ++$pnts) { if ($exist_x) { $x = $this->coords[1][$pnts]; } else { $x = $pnts + $textadj; } $xt = $xscale->Translate($x); $yt = $yscale->Translate($this->coords[0][$pnts]); if (is_numeric($this->coords[0][$pnts])) { if (!empty($this->csimtargets[$pnts])) { if (!empty($this->csimwintargets[$pnts])) { $this->mark->SetCSIMTarget($this->csimtargets[$pnts], $this->csimwintargets[$pnts]); } else { $this->mark->SetCSIMTarget($this->csimtargets[$pnts]); } $this->mark->SetCSIMAlt($this->csimalts[$pnts]); } if ($exist_x) { $x = $this->coords[1][$pnts]; } else { $x = $pnts; } $this->mark->SetCSIMAltVal($this->coords[0][$pnts], $x); $this->mark->Stroke($img, $xt, $yt); $this->csimareas .= $this->mark->GetCSIMAreas(); } } }
public function StrokeConstrains() { $n = count($this->iObj); // Stroke all constrains for ($i = 0; $i < $n; ++$i) { // Some gantt objects may not have constraints associated with them // for example we can add IconPlots which doesn't have this property. if (empty($this->iObj[$i]->constraints)) { continue; } $numConstrains = count($this->iObj[$i]->constraints); for ($k = 0; $k < $numConstrains; $k++) { $vpos = $this->iObj[$i]->constraints[$k]->iConstrainRow; if ($vpos >= 0) { $c1 = $this->iObj[$i]->iConstrainPos; // Find out which object is on the target row $targetobj = -1; for ($j = 0; $j < $n && $targetobj == -1; ++$j) { if ($this->iObj[$j]->iVPos == $vpos) { $targetobj = $j; } } if ($targetobj == -1) { Util\JpGraphError::RaiseL(6008, $this->iObj[$i]->iVPos, $vpos); //('You have specifed a constrain from row='.$this->iObj[$i]->iVPos.' to row='.$vpos.' which does not have any activity.'); } $c2 = $this->iObj[$targetobj]->iConstrainPos; if (count($c1) == 4 && count($c2) == 4) { switch ($this->iObj[$i]->constraints[$k]->iConstrainType) { case CONSTRAIN_ENDSTART: if ($c1[1] < $c2[1]) { $link = new GanttLink($c1[2], $c1[3], $c2[0], $c2[1]); } else { $link = new GanttLink($c1[2], $c1[1], $c2[0], $c2[3]); } $link->SetPath(3); break; case CONSTRAIN_STARTEND: if ($c1[1] < $c2[1]) { $link = new GanttLink($c1[0], $c1[3], $c2[2], $c2[1]); } else { $link = new GanttLink($c1[0], $c1[1], $c2[2], $c2[3]); } $link->SetPath(0); break; case CONSTRAIN_ENDEND: if ($c1[1] < $c2[1]) { $link = new GanttLink($c1[2], $c1[3], $c2[2], $c2[1]); } else { $link = new GanttLink($c1[2], $c1[1], $c2[2], $c2[3]); } $link->SetPath(1); break; case CONSTRAIN_STARTSTART: if ($c1[1] < $c2[1]) { $link = new GanttLink($c1[0], $c1[3], $c2[0], $c2[1]); } else { $link = new GanttLink($c1[0], $c1[1], $c2[0], $c2[3]); } $link->SetPath(3); break; default: Util\JpGraphError::RaiseL(6009, $this->iObj[$i]->iVPos, $vpos); //('Unknown constrain type specified from row='.$this->iObj[$i]->iVPos.' to row='.$vpos); break; } $link->SetColor($this->iObj[$i]->constraints[$k]->iConstrainColor); $link->SetArrow($this->iObj[$i]->constraints[$k]->iConstrainArrowSize, $this->iObj[$i]->constraints[$k]->iConstrainArrowType); $link->Stroke($this->img); } } } } }
public function SetTextLabelInterval($aStep) { if ($aStep < 1) { Util\JpGraphError::RaiseL(25058); //(" Text label interval must be specified >= 1."); } $this->label_step = $aStep; }
public function _gdImgHandle($agdCanvas, $x, $y, $fx = 0, $fy = 0, $w = 0, $h = 0, $mix = 100) { if ($w == 0) { $w = @imagesx($agdCanvas); } if ($w === null) { Util\JpGraphError::RaiseL(12007); //('Argument to MGraph::Add() is not a valid GD image handle.'); return; } if ($h == 0) { $h = @imagesy($agdCanvas); } $this->iGraphs[$this->iCnt++] = array($agdCanvas, $x, $y, $fx, $fy, $w, $h, $mix); }
public function Stroke($img, $aaoption = 0) { // aaoption is used to handle antialias // aaoption == 0 a normal pie // aaoption == 1 just the body // aaoption == 2 just the values // Explode scaling. If anti alias we scale the image // twice and we also need to scale the exploding distance $expscale = $aaoption === 1 ? 2 : 1; if ($this->labeltype == 2) { // Adjust the data so that it will add up to 100% $this->adjusted_data = $this->AdjPercentage($this->data); } if ($this->use_plot_theme_colors) { $this->setslicecolors = null; } $colors = array_keys($img->rgb->rgb_table); sort($colors); $ta = $this->themearr[$this->theme]; $n = count($this->data); if ($this->setslicecolors == null) { $numcolors = count($ta); } else { // We need to create an array of colors as long as the data // since we need to reverse it to get the colors in the right order $numcolors = count($this->setslicecolors); $i = 2 * $numcolors; while ($n > $i) { $this->setslicecolors = array_merge($this->setslicecolors, $this->setslicecolors); $i += $n; } $tt = array_slice($this->setslicecolors, 0, $n % $numcolors); $this->setslicecolors = array_merge($this->setslicecolors, $tt); $this->setslicecolors = array_reverse($this->setslicecolors); } // Draw the slices $sum = 0; for ($i = 0; $i < $n; ++$i) { $sum += $this->data[$i]; } // Bail out with error if the sum is 0 if ($sum == 0) { Util\JpGraphError::RaiseL(15009); //("Sum of all data is 0 for Pie."); } // Set up the pie-circle if ($this->radius <= 1) { $radius = floor($this->radius * min($img->width, $img->height)); } else { $radius = $aaoption === 1 ? $this->radius * 2 : $this->radius; } if ($this->posx <= 1 && $this->posx > 0) { $xc = round($this->posx * $img->width); } else { $xc = $this->posx; } if ($this->posy <= 1 && $this->posy > 0) { $yc = round($this->posy * $img->height); } else { $yc = $this->posy; } $n = count($this->data); if ($this->explode_all) { for ($i = 0; $i < $n; ++$i) { $this->explode_radius[$i] = $this->explode_r; } } // If we have a shadow and not just drawing the labels if ($this->ishadowcolor != "" && $aaoption !== 2) { $accsum = 0; $angle2 = $this->startangle; $img->SetColor($this->ishadowcolor); for ($i = 0; $sum > 0 && $i < $n; ++$i) { $j = $n - $i - 1; $d = $this->data[$i]; $angle1 = $angle2; $accsum += $d; $angle2 = $this->startangle + 2 * M_PI * $accsum / $sum; if (empty($this->explode_radius[$j])) { $this->explode_radius[$j] = 0; } if ($d < 1.0E-5) { continue; } $la = 2 * M_PI - (abs($angle2 - $angle1) / 2.0 + $angle1); $xcm = $xc + $this->explode_radius[$j] * cos($la) * $expscale; $ycm = $yc - $this->explode_radius[$j] * sin($la) * $expscale; $xcm += $this->ishadowdrop * $expscale; $ycm += $this->ishadowdrop * $expscale; $_sa = round($angle1 * 180 / M_PI); $_ea = round($angle2 * 180 / M_PI); // The CakeSlice method draws a full circle in case of start angle = end angle // for pie slices we don't want this behaviour unless we only have one // slice in the pie in case it is the wanted behaviour if ($_ea - $_sa > 0.1 || $n == 1) { $img->CakeSlice($xcm, $ycm, $radius - 1, $radius - 1, $angle1 * 180 / M_PI, $angle2 * 180 / M_PI, $this->ishadowcolor); } } } //-------------------------------------------------------------------------------- // This is the main loop to draw each cake slice //-------------------------------------------------------------------------------- // Set up the accumulated sum, start angle for first slice and border color $accsum = 0; $angle2 = $this->startangle; $img->SetColor($this->color); // Loop though all the slices if there is a pie to draw (sum>0) // There are n slices in total for ($i = 0; $sum > 0 && $i < $n; ++$i) { // $j is the actual index used for the slice $j = $n - $i - 1; // Make sure we havea valid distance to explode the slice if (empty($this->explode_radius[$j])) { $this->explode_radius[$j] = 0; } // The actual numeric value for the slice $d = $this->data[$i]; $angle1 = $angle2; // Accumlate the sum $accsum += $d; // The new angle when we add the "size" of this slice // angle1 is then the start and angle2 the end of this slice $angle2 = $this->NormAngle($this->startangle + 2 * M_PI * $accsum / $sum); // We avoid some trouble by not allowing end angle to be 0, in that case // we translate to 360 // la is used to hold the label angle, which is centered on the slice if ($angle2 < 0.0001 && $angle1 > 0.0001) { $this->la[$i] = 2 * M_PI - (abs(2 * M_PI - $angle1) / 2.0 + $angle1); } elseif ($angle1 > $angle2) { // The case where the slice crosses the 3 a'clock line // Remember that the slices are counted clockwise and // labels are counted counter clockwise so we need to revert with 2 PI $this->la[$i] = 2 * M_PI - $this->NormAngle($angle1 + (2 * M_PI - $angle1 + $angle2) / 2); } else { $this->la[$i] = 2 * M_PI - (abs($angle2 - $angle1) / 2.0 + $angle1); } // Too avoid rounding problems we skip the slice if it is too small if ($d < 1.0E-5) { continue; } // If the user has specified an array of colors for each slice then use // that a color otherwise use the theme array (ta) of colors if ($this->setslicecolors == null) { $slicecolor = $colors[$ta[$i % $numcolors]]; } else { $slicecolor = $this->setslicecolors[$i % $numcolors]; } // $_sa = round($angle1*180/M_PI); // $_ea = round($angle2*180/M_PI); // $_la = round($this->la[$i]*180/M_PI); // echo "Slice#$i: ang1=$_sa , ang2=$_ea, la=$_la, color=$slicecolor<br>"; // If we have enabled antialias then we don't draw any border so // make the bordedr color the same as the slice color if ($this->pie_interior_border && $aaoption === 0) { $img->SetColor($this->color); } else { $img->SetColor($slicecolor); } $arccolor = $this->pie_border && $aaoption === 0 ? $this->color : ""; // Calculate the x,y coordinates for the base of this slice taking // the exploded distance into account. Here we use the mid angle as the // ray of extension and we have the mid angle handy as it is also the // label angle $xcm = $xc + $this->explode_radius[$j] * cos($this->la[$i]) * $expscale; $ycm = $yc - $this->explode_radius[$j] * sin($this->la[$i]) * $expscale; // If we are not just drawing the labels then draw this cake slice if ($aaoption !== 2) { $_sa = round($angle1 * 180 / M_PI); $_ea = round($angle2 * 180 / M_PI); $_la = round($this->la[$i] * 180 / M_PI); //echo "[$i] sa=$_sa, ea=$_ea, la[$i]=$_la, (color=$slicecolor)<br>"; // The CakeSlice method draws a full circle in case of start angle = end angle // for pie slices we want this in case the slice have a value larger than 99% of the // total sum if (abs($_ea - $_sa) >= 1 || $d == $sum) { $img->CakeSlice($xcm, $ycm, $radius - 1, $radius - 1, $_sa, $_ea, $slicecolor, $arccolor); } } // If the CSIM is used then make sure we register a CSIM area for this slice as well if ($this->csimtargets && $aaoption !== 1) { $this->AddSliceToCSIM($i, $xcm, $ycm, $radius, $angle1, $angle2); } } // Format the titles for each slice if ($aaoption !== 2) { for ($i = 0; $i < $n; ++$i) { if ($this->labeltype == 0) { if ($sum != 0) { $l = 100.0 * $this->data[$i] / $sum; } else { $l = 0.0; } } elseif ($this->labeltype == 1) { $l = $this->data[$i] * 1.0; } else { $l = $this->adjusted_data[$i]; } if (isset($this->labels[$i]) && is_string($this->labels[$i])) { $this->labels[$i] = sprintf($this->labels[$i], $l); } else { $this->labels[$i] = $l; } } } if ($this->value->show && $aaoption !== 1) { $this->StrokeAllLabels($img, $xc, $yc, $radius); } // Adjust title position if ($aaoption !== 1) { $this->title->SetPos($xc, $yc - $this->title->GetFontHeight($img) - $radius - $this->title->margin, "center", "bottom"); $this->title->Stroke($img); } }
public function __get($name) { if (strpos($name, 'raw_') !== false) { // if $name == 'raw_left_margin' , return $this->_left_margin; $variable_name = '_' . str_replace('raw_', '', $name); return $this->{$variable_name}; } $variable_name = '_' . $name; if (isset($this->{$variable_name})) { return $this->{$variable_name} * SUPERSAMPLING_SCALE; } else { Util\JpGraphError::RaiseL('25132', $name); } }
public function Allocate($aColor, $aAlpha = 0.0) { list($r, $g, $b, $a) = $this->color($aColor); // If alpha is specified in the color string then this // takes precedence over the second argument if ($a > 0) { $aAlpha = $a; } if ($aAlpha < 0 || $aAlpha > 1) { Util\JpGraphError::RaiseL(25080); //('Alpha parameter for color must be between 0.0 and 1.0'); } return imagecolorresolvealpha($this->img, $r, $g, $b, round($aAlpha * 127)); }
public function GetIdxByName($aName, &$outFullName) { if (is_integer($aName)) { $idx = $this->GetIdxByOrdinal($aName, $outFullName); return $idx; } $found = false; $aName = strtolower($aName); $nlen = strlen($aName); reset($this->iCountryNameMap); // Start by trying to match exact index name while (list($key, $val) = each($this->iCountryNameMap)) { if ($nlen == strlen($val) && $val == $aName) { $found = true; break; } } if (!$found) { reset($this->iCountryNameMap); // If the exact index doesn't work try a (partial) full name while (list($key, $val) = each($this->iCountryNameMap)) { if (strpos(strtolower($key), $aName) !== false) { $found = true; break; } } } if ($found) { $outFullName = $key; return $val; } else { Util\JpGraphError::RaiseL(5004, $aName); //("The (partial) country name \"$aName\" does not have a cooresponding flag image. The flag may still exist but under another name, e.g. insted of \"usa\" try \"united states\"."); } }
public function _doAutoTickPos($aScale) { $maj_step_abs = $aScale->scale_factor * $this->major_step; $min_step_abs = $aScale->scale_factor * $this->minor_step; if ($min_step_abs == 0 || $maj_step_abs == 0) { Util\JpGraphError::RaiseL(25068); //("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 that the plot area is too small. It could also be that no input data value is numeric (perhaps only '-' or 'x')"); } // We need to make this an int since comparing it below // with the result from round() can give wrong result, such that // (40 < 40) == TRUE !!! $limit = (int) $aScale->scale_abs[1]; if ($aScale->textscale) { // This can only be true for a X-scale (horizontal) // Define ticks for a text scale. This is slightly different from a // normal linear type of scale since the position might be adjusted // and the labels start at on $label = (double) $aScale->GetMinVal() + $this->text_label_start + $this->label_offset; $start_abs = $aScale->scale_factor * $this->text_label_start; $nbrmajticks = round(($aScale->GetMaxVal() - $aScale->GetMinVal() - $this->text_label_start) / $this->major_step) + 1; $x = $aScale->scale_abs[0] + $start_abs + $this->xlabel_offset * $min_step_abs; for ($i = 0; $label <= $aScale->GetMaxVal() + $this->label_offset; ++$i) { // Apply format to label $this->maj_ticks_label[$i] = $this->_doLabelFormat($label, $i, $nbrmajticks); $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 = $aScale->scale_abs[0] + $start_abs + $this->xtick_offset * $min_step_abs + $i * $maj_step_abs; $this->maj_ticks_pos[$i] = $xtick; $this->maj_ticklabels_pos[$i] = round($x); $x += $maj_step_abs; } } else { $label = $aScale->GetMinVal(); $abs_pos = $aScale->scale_abs[0]; $j = 0; $i = 0; $step = round($maj_step_abs / $min_step_abs); if ($aScale->type == "x") { // For a normal linear type of scale the major ticks will always be multiples // of the minor ticks. In order to avoid any rounding issues the major ticks are // defined as every "step" minor ticks and not calculated separately $nbrmajticks = round(($aScale->GetMaxVal() - $aScale->GetMinVal() - $this->text_label_start) / $this->major_step) + 1; while (round($abs_pos) <= $limit) { $this->ticks_pos[] = round($abs_pos); $this->ticks_label[] = $label; if ($step == 0 || $i % $step == 0 && $j < $nbrmajticks) { $this->maj_ticks_pos[$j] = round($abs_pos); $this->maj_ticklabels_pos[$j] = round($abs_pos); $this->maj_ticks_label[$j] = $this->_doLabelFormat($label, $j, $nbrmajticks); ++$j; } ++$i; $abs_pos += $min_step_abs; $label += $this->minor_step; } } elseif ($aScale->type == "y") { //@todo s=2:20,12 s=1:50,6 $this->major_step:$nbr // abs_point,limit s=1:270,80 s=2:540,160 // $this->major_step = 50; $nbrmajticks = round(($aScale->GetMaxVal() - $aScale->GetMinVal()) / $this->major_step) + 1; // $step = 5; while (round($abs_pos) >= $limit) { $this->ticks_pos[$i] = round($abs_pos); $this->ticks_label[$i] = $label; if ($step == 0 || $i % $step == 0 && $j < $nbrmajticks) { $this->maj_ticks_pos[$j] = round($abs_pos); $this->maj_ticklabels_pos[$j] = round($abs_pos); $this->maj_ticks_label[$j] = $this->_doLabelFormat($label, $j, $nbrmajticks); ++$j; } ++$i; $abs_pos += $min_step_abs; $label += $this->minor_step; } } } }
public function __get($name) { $variable_name = '_' . $name; if (isset($this->{$variable_name})) { return $this->{$variable_name} * SUPERSAMPLING_SCALE; } else { Util\JpGraphError::RaiseL('25132', $name); } }
public function SetTextLabelStart($aStart) { Util\JpGraphError::RaiseL(11005); //('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.'); }
public function _TransVert3D($aGdImg, $aHorizon = 100, $aSkewDist = 120, $aDir = SKEW3D_DOWN, $aMinSize = true, $aFillColor = '#FFFFFF', $aQuality = false, $aBorder = false, $aHorizonPos = 0.5) { // Parameter check if ($aHorizonPos < 0 || $aHorizonPos > 1.0) { Util\JpGraphError::RaiseL(9001); //("Value for image transformation out of bounds.\nVanishing point on horizon must be specified as a value between 0 and 1."); } $w = imagesx($aGdImg); $h = imagesy($aGdImg); // Create new image $ww = $w; if ($aMinSize) { $hh = ceil($h * $aHorizon / ($aSkewDist + $h)); } else { $hh = $h; } $newgdh = imagecreatetruecolor($ww, $hh); $crgb = new RGB($newgdh); $fillColor = $crgb->Allocate($aFillColor); imagefilledrectangle($newgdh, 0, 0, $ww - 1, $hh - 1, $fillColor); if ($aBorder) { $colidx = $crgb->Allocate($aBorder); imagerectangle($newgdh, 0, 0, $ww - 1, $hh - 1, $colidx); } $mid = round($w * $aHorizonPos); $last = $h; for ($y = 0; $y < $h; ++$y) { $yp = $h - $y - 1; $yt = floor($yp * $aHorizon / ($aSkewDist + $yp)); if (!$aQuality) { if ($last <= $yt) { continue; } $last = $yt; } for ($x = 0; $x < $w; ++$x) { $xt = ($x - $mid) * $aSkewDist / ($aSkewDist + $yp); if ($aDir == SKEW3D_UP) { $rgb = imagecolorat($aGdImg, $x, $h - $y - 1); } else { $rgb = imagecolorat($aGdImg, $x, $y); } $r = $rgb >> 16 & 0xff; $g = $rgb >> 8 & 0xff; $b = $rgb & 0xff; $colidx = imagecolorallocate($newgdh, $r, $g, $b); $xt = round($xt + $mid); if ($aDir == SKEW3D_UP) { $syt = $yt; } else { $syt = $hh - $yt - 1; } if (!empty($set[$yt])) { $nrgb = imagecolorat($newgdh, $xt, $syt); $nr = $nrgb >> 16 & 0xff; $ng = $nrgb >> 8 & 0xff; $nb = $nrgb & 0xff; $colidx = imagecolorallocate($newgdh, floor(($r + $nr) / 2), floor(($g + $ng) / 2), floor(($b + $nb) / 2)); } imagesetpixel($newgdh, $xt, $syt, $colidx); } $set[$yt] = true; } return $newgdh; }
public function Stroke() { if (!$this->IsRangeSet()) { Util\JpGraphError::RaiseL(6022); //("Gantt scale has not been specified."); } $img = $this->iImg; // If minutes are displayed then hour interval must be 1 if ($this->IsDisplayMinute() && $this->hour->GetIntervall() > 1) { Util\JpGraphError::RaiseL(6023); //('If you display both hour and minutes the hour intervall must be 1 (Otherwise it doesn\' make sense to display minutes).'); } // Stroke all headers. As argument we supply the offset from the // top which depends on any previous headers // First find out the height of each header $offy = $this->StrokeYears(0, true); $offm = $this->StrokeMonths($offy, true); $offw = $this->StrokeWeeks($offm, true); $offd = $this->StrokeDays($offw, true); $offh = $this->StrokeHours($offd, true); $offmin = $this->StrokeMinutes($offh, true); // ... then we can stroke them in the "backwards order to ensure that // the larger scale gridlines is stroked over the smaller scale gridline $this->StrokeMinutes($offh); $this->StrokeHours($offd); $this->StrokeDays($offw); $this->StrokeWeeks($offm); $this->StrokeMonths($offy); $this->StrokeYears(0); // Now when we now the oaverall size of the scale headers // we can stroke the overall table headers $this->StrokeTableHeaders($offmin); // Now we can calculate the correct scaling factor for each vertical position $this->iAvailableHeight = $img->height - $img->top_margin - $img->bottom_margin - $offd; $this->iVertHeaderSize = $offmin; if ($this->iVertSpacing == -1) { $this->iVertSpacing = $this->iAvailableHeight / $this->iVertLines; } }
public function MakeDirs($aFile) { $dirs = array(); // In order to better work when open_basedir is enabled // we do not create directories in the root path while ($aFile != '/' && !file_exists($aFile)) { $dirs[] = $aFile . '/'; $aFile = dirname($aFile); } for ($i = sizeof($dirs) - 1; $i >= 0; $i--) { if (!@mkdir($dirs[$i], 0777)) { Util\JpGraphError::RaiseL(25118, $aFile); //(" Can't create directory $aFile. Make sure PHP has write permission to this directory."); } // We also specify mode here after we have changed group. // This is necessary if Apache user doesn't belong the // default group and hence can't specify group permission // in the previous mkdir() call if (CACHE_FILE_GROUP != "") { $res = true; $res = @chgrp($dirs[$i], CACHE_FILE_GROUP); $res = @chmod($dirs[$i], 0777); if (!$res) { Util\JpGraphError::RaiseL(25119, $aFile); //(" Can't set permissions for $aFile. Permission problems?"); } } } return true; }
public function Stroke($aOtherAxisScale, $aStrokeLabels = true) { if ($this->hide) { return; } if (is_numeric($this->pos)) { $pos = $aOtherAxisScale->Translate($this->pos); } else { // Default to minimum of other scale if pos not set if ($aOtherAxisScale->GetMinVal() >= 0 && $this->pos == false || $this->pos == 'min') { $pos = $aOtherAxisScale->scale_abs[0]; } elseif ($this->pos == "max") { $pos = $aOtherAxisScale->scale_abs[1]; } else { // If negative set x-axis at 0 $this->pos = 0; $pos = $aOtherAxisScale->Translate(0); } } $pos += $this->iDeltaAbsPos; $this->img->SetLineWeight($this->weight); $this->img->SetColor($this->color); $this->img->SetFont($this->font_family, $this->font_style, $this->font_size); if ($this->scale->type == "x") { if (!$this->hide_line) { // Stroke X-axis $this->img->FilledRectangle($this->img->left_margin, $pos, $this->img->width - $this->img->right_margin, $pos + $this->weight - 1); } if ($this->title_side == SIDE_DOWN) { $y = $pos + $this->img->GetFontHeight() + $this->title_margin + $this->title->margin; $yalign = 'top'; } else { $y = $pos - $this->img->GetFontHeight() - $this->title_margin - $this->title->margin; $yalign = 'bottom'; } if ($this->title_adjust == 'high') { $this->title->SetPos($this->img->width - $this->img->right_margin, $y, 'right', $yalign); } elseif ($this->title_adjust == 'middle' || $this->title_adjust == 'center') { $this->title->SetPos(($this->img->width - $this->img->left_margin - $this->img->right_margin) / 2 + $this->img->left_margin, $y, 'center', $yalign); } elseif ($this->title_adjust == 'low') { $this->title->SetPos($this->img->left_margin, $y, 'left', $yalign); } else { Util\JpGraphError::RaiseL(25060, $this->title_adjust); //('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')'); } } 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. if (!$this->hide_line) { // Stroke Y-axis $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; $x -= $this->title->margin; $halign = 'right'; } else { $x += $this->title_margin; $x += $this->title->margin; $halign = 'left'; } // If the user has manually specified an hor. align // then we override the automatic settings with this // specifed setting. Since default is 'left' we compare // with that. (This means a manually set 'left' align // will have no effect.) if ($this->title->halign != 'left') { $halign = $this->title->halign; } if ($this->title_adjust == 'high') { $this->title->SetPos($x, $this->img->top_margin, $halign, 'top'); } elseif ($this->title_adjust == 'middle' || $this->title_adjust == 'center') { $this->title->SetPos($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->SetPos($x, $this->img->height - $this->img->bottom_margin, $halign, 'bottom'); } else { Util\JpGraphError::RaiseL(25061, $this->title_adjust); //('Unknown alignment specified for Y-axis title. ('.$this->title_adjust.')'); } } $this->scale->ticks->Stroke($this->img, $this->scale, $pos); if ($aStrokeLabels) { if (!$this->hide_labels) { $this->StrokeLabels($pos); } $this->title->Stroke($this->img); } }
public function AutoScale($img, $aStartTime, $aEndTime, $aNumSteps, $_adummy = false) { // We need to have one dummy argument to make the signature of AutoScale() // identical to LinearScale::AutoScale if ($aStartTime == $aEndTime) { // Special case when we only have one data point. // Create a small artifical intervall to do the autoscaling $aStartTime -= 10; $aEndTime += 10; } $done = false; $i = 0; while (!$done && $i < 5) { list($adjstart, $adjend, $maj, $min, $format) = $this->DoDateAutoScale($aStartTime, $aEndTime, $i); $n = floor(($adjend - $adjstart) / $maj); if ($n * 1.7 > $aNumSteps) { $done = true; } $i++; } /* if( 0 ) { // DEBUG echo " Start =".date("Y-m-d H:i:s",$aStartTime)."<br>"; echo " End =".date("Y-m-d H:i:s",$aEndTime)."<br>"; echo "Adj Start =".date("Y-m-d H:i:s",$adjstart)."<br>"; echo "Adj End =".date("Y-m-d H:i:s",$adjend)."<p>"; echo "Major = $maj s, ".floor($maj/60)."min, ".floor($maj/3600)."h, ".floor($maj/86400)."day<br>"; echo "Min = $min s, ".floor($min/60)."min, ".floor($min/3600)."h, ".floor($min/86400)."day<br>"; echo "Format=$format<p>"; } */ if ($this->iStartTimeAlign !== false && $this->iStartAlign !== false) { Util\JpGraphError::RaiseL(3001); //('It is only possible to use either SetDateAlign() or SetTimeAlign() but not both'); } if ($this->iStartTimeAlign !== false) { if ($this->iStartTimeAlign >= 30) { $adjstart = $this->AdjStartTime($aStartTime, $this->iStartTimeAlign - 30); } elseif ($this->iStartTimeAlign >= 20) { $adjstart = $this->AdjStartTime($aStartTime, false, $this->iStartTimeAlign - 20); } else { $adjstart = $this->AdjStartTime($aStartTime, false, false, $this->iStartTimeAlign); } } if ($this->iEndTimeAlign !== false) { if ($this->iEndTimeAlign >= 30) { $adjend = $this->AdjEndTime($aEndTime, $this->iEndTimeAlign - 30); } elseif ($this->iEndTimeAlign >= 20) { $adjend = $this->AdjEndTime($aEndTime, false, $this->iEndTimeAlign - 20); } else { $adjend = $this->AdjEndTime($aEndTime, false, false, $this->iEndTimeAlign); } } if ($this->iStartAlign !== false) { if ($this->iStartAlign >= 30) { $adjstart = $this->AdjStartDate($aStartTime, $this->iStartAlign - 30); } elseif ($this->iStartAlign >= 20) { $adjstart = $this->AdjStartDate($aStartTime, false, $this->iStartAlign - 20); } else { $adjstart = $this->AdjStartDate($aStartTime, false, false, $this->iStartAlign); } } if ($this->iEndAlign !== false) { if ($this->iEndAlign >= 30) { $adjend = $this->AdjEndDate($aEndTime, $this->iEndAlign - 30); } elseif ($this->iEndAlign >= 20) { $adjend = $this->AdjEndDate($aEndTime, false, $this->iEndAlign - 20); } else { $adjend = $this->AdjEndDate($aEndTime, false, false, $this->iEndAlign); } } $this->Update($img, $adjstart, $adjend); if (!$this->ticks->IsSpecified()) { $this->ticks->Set($maj, $min); } if ($this->date_format == '') { $this->ticks->SetLabelDateFormat($format); } else { $this->ticks->SetLabelDateFormat($this->date_format); } }
public function SetTheme($graph_theme) { if (!$this instanceof PieGraph) { if (!$this->isAfterSetScale) { Util\JpGraphError::RaiseL(25133); //('Use Graph::SetTheme() after Graph::SetScale().'); } } if ($this->graph_theme) { $this->ClearTheme(); } $this->graph_theme = $graph_theme; $this->graph_theme->ApplyGraph($this); }