public function Stroke($img, $xscale, $yscale) { $numpoints = count($this->coords[0]) / 2; $img->SetColor($this->color); $img->SetLineWeight($this->weight); if (isset($this->coords[1])) { if (count($this->coords[1]) != $numpoints) { Util\JpGraphError::RaiseL(2003, count($this->coords[1]), $numpoints); } else { $exist_x = true; } } else { $exist_x = false; } for ($i = 0; $i < $numpoints; ++$i) { if ($exist_x) { $x = $this->coords[1][$i]; } else { $x = $i; } if (!is_numeric($x) || !is_numeric($this->coords[0][$i * 2]) || !is_numeric($this->coords[0][$i * 2 + 1])) { continue; } $xt = $xscale->Translate($x); $yt1 = $yscale->Translate($this->coords[0][$i * 2]); $yt2 = $yscale->Translate($this->coords[0][$i * 2 + 1]); $img->Line($xt, $yt1, $xt, $yt2); $img->Line($xt - $this->errwidth, $yt1, $xt + $this->errwidth, $yt1); $img->Line($xt - $this->errwidth, $yt2, $xt + $this->errwidth, $yt2); } return true; }
public function SetDayOffset($aOff = 0.5) { if ($aOff < 0.0 || $aOff > 1.0) { Util\JpGraphError::RaiseL(6029); //("Offset for vertical line must be in range [0,1]"); } $this->iDayOffset = $aOff; }
public function SetCSIMAlt($aAlt) { if (!is_string($aAlt)) { $tv = substr(var_export($aAlt, true), 0, 40); Util\JpGraphError::RaiseL(6025, $tv); //('CSIM Alt text must be specified as a string.'."\nStart of alt text is:\n$tv"); } $this->csimalt = $aAlt; }
public function SetType($aType, $aFileName = '', $aScale = 1.0) { $this->type = $aType; if ($aType == MARK_IMG && $aFileName == '') { Util\JpGraphError::RaiseL(23003); //('A filename must be specified if you set the mark type to MARK_IMG.'); } $this->iFileName = $aFileName; $this->iScale = $aScale; }
public function Legend($graph) { $n = count($this->plots); for ($i = 0; $i < $n; ++$i) { $c = get_class($this->plots[$i]); if (!$this->plots[$i] instanceof BarPlot) { Util\JpGraphError::RaiseL(2009, $c); //('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')'); } $this->plots[$i]->DoLegend($graph); } }
public function __construct($datay, $datax = false) { if (count($datax) != count($datay) && is_array($datax)) { Util\JpGraphError::RaiseL(20003); //("Scatterplot must have equal number of X and Y points."); } parent::__construct($datay, $datax); $this->mark = new PlotMark(); $this->mark->SetType(MARK_SQUARE); $this->mark->SetColor($this->color); $this->value->SetAlign('center', 'center'); $this->value->SetMargin(0); $this->link = new Graph\LineProperty(1, 'black', 'solid'); $this->link->iShow = false; }
public function __construct($datay, $datax, $angles) { if (count($datax) != count($datay)) { Util\JpGraphError::RaiseL(20001); } //("Fieldplots must have equal number of X and Y points."); if (count($datax) != count($angles)) { Util\JpGraphError::RaiseL(20002); } //("Fieldplots must have an angle specified for each X and Y points."); $this->iAngles = $angles; parent::__construct($datay, $datax); $this->value->SetAlign('center', 'center'); $this->value->SetMargin(15); $this->arrow = new FieldArrow(); }
public function __construct($plots) { $this->plots = $plots; $this->nbrplots = count($plots); $this->numpoints = $plots[0]->numpoints; // Verify that all plots have the same number of data points for ($i = 1; $i < $this->nbrplots; ++$i) { if ($plots[$i]->numpoints != $this->numpoints) { Util\JpGraphError::RaiseL(10003); //('Each plot in an accumulated lineplot must have the same number of data points',0) } } for ($i = 0; $i < $this->nbrplots; ++$i) { $this->LineInterpolate($this->plots[$i]->coords[0]); } }
public function __construct($datay, $datax = false) { $ly = array(); $ey = array(); $n = count($datay); if ($n % 3 != 0) { Util\JpGraphError::RaiseL(4002); //('Error in input data to LineErrorPlot. Number of data points must be a multiple of 3'); } for ($i = 0; $i < $n; $i += 3) { $ly[] = $datay[$i]; $ey[] = $datay[$i] + $datay[$i + 1]; $ey[] = $datay[$i] + $datay[$i + 2]; } parent::__construct($ey, $datax); $this->line = new LinePlot($ly, $datax); }
public function _Stroke($aImg, $x = null, $y = null, $aReturnWidthHeight = false) { if ($this->iFile != '' && $this->iCountryFlag != '') { Util\JpGraphError::RaiseL(8003); //('It is not possible to specify both an image file and a country flag for the same icon.'); } if ($this->iFile != '') { $gdimg = Graph::LoadBkgImage('', $this->iFile); } elseif ($this->iImgString != '') { $gdimg = Image::CreateFromString($this->iImgString); } else { if (!class_exists('FlagImages', false)) { Util\JpGraphError::RaiseL(8004); //('In order to use Country flags as icons you must include the "jpgraph_flags.php" file.'); } $fobj = new FlagImages($this->iCountryStdSize); $dummy = ''; $gdimg = $fobj->GetImgByName($this->iCountryFlag, $dummy); } $iconw = imagesx($gdimg); $iconh = imagesy($gdimg); if ($aReturnWidthHeight) { return array(round($iconw * $this->iScale), round($iconh * $this->iScale)); } if ($x !== null && $y !== null) { $this->iX = $x; $this->iY = $y; } if ($this->iX >= 0 && $this->iX <= 1.0) { $w = imagesx($aImg->img); $this->iX = round($w * $this->iX); } if ($this->iY >= 0 && $this->iY <= 1.0) { $h = imagesy($aImg->img); $this->iY = round($h * $this->iY); } if ($this->iHorAnchor == 'center') { $this->iX -= round($iconw * $this->iScale / 2); } if ($this->iHorAnchor == 'right') { $this->iX -= round($iconw * $this->iScale); } if ($this->iVertAnchor == 'center') { $this->iY -= round($iconh * $this->iScale / 2); } if ($this->iVertAnchor == 'bottom') { $this->iY -= round($iconh * $this->iScale); } $aImg->CopyMerge($gdimg, $this->iX, $this->iY, 0, 0, round($iconw * $this->iScale), round($iconh * $this->iScale), $iconw, $iconh, $this->iMix); }
public function Stroke($aGraph) { $aImg = $aGraph->img; if ($this->iX > 0 && $this->iX < 1) { $this->iX = round($aImg->width * $this->iX); } if ($this->iY > 0 && $this->iY < 1) { $this->iY = round($aImg->height * $this->iY); } if ($this->iSize > 0 && $this->iSize < 1) { $this->iSize *= min($aImg->width, $aImg->height); } if ($this->iCenterSize > 0 && $this->iCenterSize < 1) { $this->iCenterSize *= $this->iSize; } $this->scale->AutoScale(($this->iSize - $this->iCenterSize) / 2, round(2.5 * $this->scale->iFontSize)); $scaling = $this->iAntiAlias ? 2 : 1; $value = new Text\Text(); $value->SetFont($this->iFontFamily, $this->iFontStyle, $this->iFontSize * $scaling); $value->SetColor($this->iFontColor); $legendheight = round($this->legend->iShow ? 1 : 0); $legendheight *= max($this->legend->iCircleRadius * 2, $this->legend->iTxtFontSize * 2) + $this->legend->iMargin + $this->legend->iBottomMargin + 2; $legendheight *= $scaling; $w = $scaling * $this->getWidth($aImg); $h = $scaling * $this->getHeight($aImg); // Copy back the double buffered image to the proper canvas $ww = $w / $scaling; $hh = $h / $scaling; // Create the double buffer if ($this->iAntiAlias) { $dblImg = new RotImage($w, $h); // Set the background color $dblImg->SetColor($this->iColor); $dblImg->FilledRectangle(0, 0, $w, $h); } else { $dblImg = $aImg; // Make sure the ix and it coordinates correpond to the new top left center $dblImg->SetTranslation($this->iX - $w / 2, $this->iY - $h / 2); } if (__DEBUG) { $dblImg->SetColor('red'); $dblImg->Rectangle(0, 0, $w - 1, $h - 1); } $dblImg->SetColor('black'); if ($this->iShowBox) { $dblImg->SetColor($this->iBoxColor); $old = $dblImg->SetLineWeight($this->iBoxWeight); $dblImg->SetLineStyle($this->iBoxStyle); $dblImg->Rectangle(0, 0, $w - 1, $h - 1); $dblImg->SetLineWeight($old); } $xc = round($w / 2); $yc = round(($h - $legendheight) / 2); if (__DEBUG) { $dblImg->SetColor('red'); $old = $dblImg->SetLineWeight(2); $dblImg->Line($xc - 5, $yc - 5, $xc + 5, $yc + 5); $dblImg->Line($xc + 5, $yc - 5, $xc - 5, $yc + 5); $dblImg->SetLineWeight($old); } $this->iSize *= $scaling; // Inner circle size $ri = $this->iCenterSize / 2; // Full circle radius $r = round($this->iSize / 2); // Get number of grid circles $n = $this->scale->GetNumCirc(); // Plot circle grids $ri *= $scaling; $rr = round(($r - $ri) / $n); for ($i = 1; $i <= $n; ++$i) { $this->_ThickCircle($dblImg, $xc, $yc, $rr * $i + $ri, $this->iCircGridWeight, $this->iGridColor1); } $num = 0; if ($this->iType == WINDROSE_TYPEFREE) { $this->_StrokeFreeRose($dblImg, $value, $scaling, $xc, $yc, $r, $ri); } else { // Check if we need to re-code the interpretation of the ordinal // number in the data. Internally ordinal value 0 is East and then // counted anti-clockwise. The user might choose an encoding // that have 0 being the first axis to the right of the "N" axis and then // counted clock-wise if ($this->iOrdinalEncoding == KEYENCODING_CLOCKWISE) { if ($this->iType == WINDROSE_TYPE16) { $const1 = 19; $const2 = 16; } elseif ($this->iType == WINDROSE_TYPE8) { $const1 = 9; $const2 = 8; } else { $const1 = 4; $const2 = 4; } $tmp = []; $n = count($this->iData); foreach ($this->iData as $key => $val) { if (is_numeric($key)) { $key = ($const1 - $key) % $const2; } $tmp[$key] = $val; } $this->iData = $tmp; } $this->_StrokeRegularRose($dblImg, $value, $scaling, $xc, $yc, $r, $ri); } // Stroke the labels $this->scale->iFontSize *= $scaling; $this->scale->iZFontSize *= $scaling; $this->scale->StrokeLabels($dblImg, $xc, $yc, $ri, $rr); // Stroke the inner circle again since the legs // might have written over it $this->_ThickCircle($dblImg, $xc, $yc, $ri, $this->iCircGridWeight, $this->iGridColor1); if ($ww > $aImg->width) { Util\JpGraphError::RaiseL(22020); //('Windrose plot is too large to fit the specified Graph size. Please use WindrosePlot::SetSize() to make the plot smaller or increase the size of the Graph in the initial WindroseGraph() call.'); } $x = $xc; $y = $h; $this->_StrokeLegend($dblImg, $x, $y, $scaling); if ($this->iAntiAlias) { $aImg->Copy($dblImg->img, $this->iX - $ww / 2, $this->iY - $hh / 2, 0, 0, $ww, $hh, $w, $h); } // We need to restore the translation matrix $aImg->SetTranslation(0, 0); }
public function PreStrokeAdjust($aGraph) { if (substr($aGraph->axtype, 0, 4) == "text" && isset($this->coords[1])) { Util\JpGraphError::RaiseL(25123); //("JpGraph: You can't use a text X-scale with specified X-coords. Use a \"int\" or \"lin\" scale instead."); } return true; }
public function Stroke($aImg, $aScale) { $factory = new RectPatternFactory(); $prect = $factory->Create($this->iPattern, $this->iPatternColor); $prect->SetDensity($this->iPatternDensity); // If height factor is specified as a float between 0,1 then we take it as meaning // percetage of the scale width between horizontal line. // If it is an integer > 1 we take it to mean the absolute height in pixels if ($this->iHeightFactor > -0.0 && $this->iHeightFactor <= 1.1) { $vs = $aScale->GetVertSpacing() * $this->iHeightFactor; } elseif (is_int($this->iHeightFactor) && $this->iHeightFactor > 2 && $this->iHeightFactor < 200) { $vs = $this->iHeightFactor; } else { Util\JpGraphError::RaiseL(6028, $this->iHeightFactor); // ("Specified height (".$this->iHeightFactor.") for gantt bar is out of range."); } // Clip date to min max dates to show $st = $aScale->NormalizeDate($this->iStart); $en = $aScale->NormalizeDate($this->iEnd); $limst = max($st, $aScale->iStartDate); $limen = min($en, $aScale->iEndDate); $xt = round($aScale->TranslateDate($limst)); $xb = round($aScale->TranslateDate($limen)); $yt = round($aScale->TranslateVertPos($this->iVPos) - $vs - ($aScale->GetVertSpacing() / 2 - $vs / 2)); $yb = round($aScale->TranslateVertPos($this->iVPos) - ($aScale->GetVertSpacing() / 2 - $vs / 2)); $middle = round($yt + ($yb - $yt) / 2); $this->StrokeActInfo($aImg, $aScale, $middle); // CSIM for title if (!empty($this->title->csimtarget)) { $colwidth = $this->title->GetColWidth($aImg); $colstarts = array(); $aScale->actinfo->GetColStart($aImg, $colstarts, true); $n = min(count($colwidth), count($this->title->csimtarget)); for ($i = 0; $i < $n; ++$i) { $title_xt = $colstarts[$i]; $title_xb = $title_xt + $colwidth[$i]; $coords = "{$title_xt},{$yt},{$title_xb},{$yt},{$title_xb},{$yb},{$title_xt},{$yb}"; if (!empty($this->title->csimtarget[$i])) { $this->csimarea .= "<area shape=\"poly\" coords=\"{$coords}\" href=\"" . $this->title->csimtarget[$i] . "\""; if (!empty($this->title->csimwintarget[$i])) { $this->csimarea .= "target=\"" . $this->title->csimwintarget[$i] . "\" "; } if (!empty($this->title->csimalt[$i])) { $tmp = $this->title->csimalt[$i]; $this->csimarea .= " title=\"{$tmp}\" alt=\"{$tmp}\" "; } $this->csimarea .= " />\n"; } } } // Check if the bar is totally outside the current scale range if ($en < $aScale->iStartDate || $st > $aScale->iEndDate) { return; } // Remember the positions for the bar $this->SetConstrainPos($xt, $yt, $xb, $yb); $prect->ShowFrame(false); $prect->SetBackground($this->iFillColor); if ($this->iBreakStyle) { $aImg->SetColor($this->iFrameColor); $olds = $aImg->SetLineStyle($this->iBreakLineStyle); $oldw = $aImg->SetLineWeight($this->iBreakLineWeight); $aImg->StyleLine($xt, $yt, $xb, $yt); $aImg->StyleLine($xt, $yb, $xb, $yb); $aImg->SetLineStyle($olds); $aImg->SetLineWeight($oldw); } else { if ($this->iShadow) { $aImg->SetColor($this->iFrameColor); $aImg->ShadowRectangle($xt, $yt, $xb, $yb, $this->iFillColor, $this->iShadowWidth, $this->iShadowColor); $prect->SetPos(new Rectangle($xt + 1, $yt + 1, $xb - $xt - $this->iShadowWidth - 2, $yb - $yt - $this->iShadowWidth - 2)); $prect->Stroke($aImg); } else { $prect->SetPos(new Rectangle($xt, $yt, $xb - $xt + 1, $yb - $yt + 1)); $prect->Stroke($aImg); $aImg->SetColor($this->iFrameColor); $aImg->Rectangle($xt, $yt, $xb, $yb); } } // CSIM for bar if (!empty($this->csimtarget)) { $coords = "{$xt},{$yt},{$xb},{$yt},{$xb},{$yb},{$xt},{$yb}"; $this->csimarea .= "<area shape=\"poly\" coords=\"{$coords}\" href=\"" . $this->csimtarget . "\""; if (!empty($this->csimwintarget)) { $this->csimarea .= " target=\"" . $this->csimwintarget . "\" "; } if ($this->csimalt != '') { $tmp = $this->csimalt; $this->csimarea .= " title=\"{$tmp}\" alt=\"{$tmp}\" "; } $this->csimarea .= " />\n"; } // Draw progress bar inside activity bar if ($this->progress->iProgress > 0) { $xtp = $aScale->TranslateDate($st); $xbp = $aScale->TranslateDate($en); $len = ($xbp - $xtp) * $this->progress->iProgress; $endpos = $xtp + $len; if ($endpos > $xt) { // Take away the length of the progress that is not visible (before the start date) $len -= $xt - $xtp; // Is the the progress bar visible after the start date? if ($xtp < $xt) { $xtp = $xt; } // Make sure that the progess bar doesn't extend over the end date if ($xtp + $len - 1 > $xb) { $len = $xb - $xtp; } $prog = $factory->Create($this->progress->iPattern, $this->progress->iColor); $prog->SetDensity($this->progress->iDensity); $prog->SetBackground($this->progress->iFillColor); $barheight = $yb - $yt + 1; if ($this->iShadow) { $barheight -= $this->iShadowWidth; } $progressheight = floor($barheight * $this->progress->iHeight); $marg = ceil(($barheight - $progressheight) / 2); $pos = new Rectangle($xtp, $yt + $marg, $len, $barheight - 2 * $marg); $prog->SetPos($pos); $prog->Stroke($aImg); } } // We don't plot the end mark if the bar has been capped if ($limst == $st) { $y = $middle; // We treat the RIGHT and LEFT triangle mark a little bi // special so that these marks are placed right under the // bar. if ($this->leftMark->GetType() == MARK_LEFTTRIANGLE) { $y = $yb; } $this->leftMark->Stroke($aImg, $xt, $y); } if ($limen == $en) { $y = $middle; // We treat the RIGHT and LEFT triangle mark a little bi // special so that these marks are placed right under the // bar. if ($this->rightMark->GetType() == MARK_RIGHTTRIANGLE) { $y = $yb; } $this->rightMark->Stroke($aImg, $xb, $y); $margin = $this->iCaptionMargin; if ($this->rightMark->show) { $margin += $this->rightMark->GetWidth(); } $this->caption->Stroke($aImg, $xb + $margin, $middle); } }
/** * Internal method. Stroke the contour plot to the graph * * @param $img Image handler * @param $xscale Instance of the xscale to use * @param $yscale Instance of the yscale to use */ public function Stroke($img, $xscale, $yscale) { if (count($this->manualIsobarColors) > 0) { $this->contourColor = $this->manualIsobarColors; if (count($this->manualIsobarColors) != $this->nbrContours) { Util\JpGraphError::RaiseL(28002); } } $img->SetLineWeight($this->line_weight); for ($c = 0; $c < $this->nbrContours; $c++) { $img->SetColor($this->contourColor[$c]); $n = count($this->contourCoord[$c]); $i = 0; while ($i < $n) { list($x1, $y1) = $this->contourCoord[$c][$i][0]; $x1t = $xscale->Translate($x1); $y1t = $yscale->Translate($y1); list($x2, $y2) = $this->contourCoord[$c][$i++][1]; $x2t = $xscale->Translate($x2); $y2t = $yscale->Translate($y2); $img->Line($x1t, $y1t, $x2t, $y2t); } } }
public function Stroke($img, $xscale, $yscale) { $pattern = null; $img->SetLineWeight($this->weight); $grad = null; for ($i = 0; $i < $this->numpoints - 1; $i++) { $accy = 0; $accy_neg = 0; for ($j = 0; $j < $this->nbrplots; ++$j) { $img->SetColor($this->plots[$j]->color); if ($this->plots[$j]->coords[0][$i] >= 0) { $yt = $yscale->Translate($this->plots[$j]->coords[0][$i] + $accy); $accyt = $yscale->Translate($accy); $accy += $this->plots[$j]->coords[0][$i]; } else { //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { $yt = $yscale->Translate($this->plots[$j]->coords[0][$i] + $accy_neg); $accyt = $yscale->Translate($accy_neg); $accy_neg += $this->plots[$j]->coords[0][$i]; } $xt = $xscale->Translate($i); if ($this->abswidth > -1) { $abswidth = $this->abswidth; } else { $abswidth = round($this->width * $xscale->scale_factor, 0); } $pts = array($xt, $accyt, $xt, $yt, $xt + $abswidth, $yt, $xt + $abswidth, $accyt); if ($this->bar_shadow) { $ssh = $this->bar_shadow_hsize; $ssv = $this->bar_shadow_vsize; // We must also differ if we are a positive or negative bar. if ($j === 0) { // This gets extra complicated since we have to // see all plots to see if we are negative. It could // for example be that all plots are 0 until the very // last one. We therefore need to save the initial setup // for both the negative and positive case // In case the final bar is positive $sp[0] = $pts[6] + 1; $sp[1] = $pts[7]; $sp[2] = $pts[6] + $ssh; $sp[3] = $pts[7] - $ssv; // In case the final bar is negative $nsp[0] = $pts[0]; $nsp[1] = $pts[1]; $nsp[2] = $pts[0] + $ssh; $nsp[3] = $pts[1] - $ssv; $nsp[4] = $pts[6] + $ssh; $nsp[5] = $pts[7] - $ssv; $nsp[10] = $pts[6] + 1; $nsp[11] = $pts[7]; } if ($j === $this->nbrplots - 1) { // If this is the last plot of the bar and // the total value is larger than 0 then we // add the shadow. if (is_array($this->bar_shadow_color)) { $numcolors = count($this->bar_shadow_color); if ($numcolors == 0) { Util\JpGraphError::RaiseL(2013); //('You have specified an empty array for shadow colors in the bar plot.'); } $img->PushColor($this->bar_shadow_color[$i % $numcolors]); } else { $img->PushColor($this->bar_shadow_color); } if ($accy > 0) { $sp[4] = $pts[4] + $ssh; $sp[5] = $pts[5] - $ssv; $sp[6] = $pts[2] + $ssh; $sp[7] = $pts[3] - $ssv; $sp[8] = $pts[2]; $sp[9] = $pts[3] - 1; $sp[10] = $pts[4] + 1; $sp[11] = $pts[5]; $img->FilledPolygon($sp, 4); } elseif ($accy_neg < 0) { $nsp[6] = $pts[4] + $ssh; $nsp[7] = $pts[5] - $ssv; $nsp[8] = $pts[4] + 1; $nsp[9] = $pts[5]; $img->FilledPolygon($nsp, 4); } $img->PopColor(); } } // If value is NULL or 0, then don't draw a bar at all if ($this->plots[$j]->coords[0][$i] == 0) { continue; } if ($this->plots[$j]->grad) { if ($grad === null) { $grad = new Gradient($img); } if (is_array($this->plots[$j]->grad_fromcolor)) { // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be // an array to specify both (from, to style) for each individual bar. The way to know the difference is // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB // triple. $ng = count($this->plots[$j]->grad_fromcolor); if ($ng === 3) { if (is_numeric($this->plots[$j]->grad_fromcolor[0]) && $this->plots[$j]->grad_fromcolor[0] > 0 && $this->plots[$j]->grad_fromcolor[0] < 256) { // RGB Triple $fromcolor = $this->plots[$j]->grad_fromcolor; $tocolor = $this->plots[$j]->grad_tocolor; $style = $this->plots[$j]->grad_style; } else { $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; } } else { $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; } $grad->FilledRectangle($pts[2], $pts[3], $pts[6], $pts[7], $fromcolor, $tocolor, $style); } else { $grad->FilledRectangle($pts[2], $pts[3], $pts[6], $pts[7], $this->plots[$j]->grad_fromcolor, $this->plots[$j]->grad_tocolor, $this->plots[$j]->grad_style); } } else { if (is_array($this->plots[$j]->fill_color)) { $numcolors = count($this->plots[$j]->fill_color); $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors]; // If the bar is specified to be non filled then the fill color is false if ($fillcolor !== false) { $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); } } else { $fillcolor = $this->plots[$j]->fill_color; if ($fillcolor !== false) { $img->SetColor($this->plots[$j]->fill_color); } } if ($fillcolor !== false) { $img->FilledPolygon($pts); } } $img->SetColor($this->plots[$j]->color); // Stroke the pattern if ($this->plots[$j]->iPattern > -1) { if ($pattern === null) { $pattern = new RectPatternFactory(); } $prect = $pattern->Create($this->plots[$j]->iPattern, $this->plots[$j]->iPatternColor, 1); $prect->SetDensity($this->plots[$j]->iPatternDensity); if ($this->plots[$j]->coords[0][$i] < 0) { $rx = $pts[0]; $ry = $pts[1]; } else { $rx = $pts[2]; $ry = $pts[3]; } $width = abs($pts[4] - $pts[0]) + 1; $height = abs($pts[1] - $pts[3]) + 1; $prect->SetPos(new Rectangle($rx, $ry, $width, $height)); $prect->Stroke($img); } // CSIM array if ($i < count($this->plots[$j]->csimtargets)) { // Create the client side image map $rpts = $img->ArrRotate($pts); $csimcoord = round($rpts[0]) . ", " . round($rpts[1]); for ($k = 1; $k < 4; ++$k) { $csimcoord .= ", " . round($rpts[2 * $k]) . ", " . round($rpts[2 * $k + 1]); } if (!empty($this->plots[$j]->csimtargets[$i])) { $this->csimareas .= '<area shape="poly" coords="' . $csimcoord . '" '; $this->csimareas .= " href=\"" . $this->plots[$j]->csimtargets[$i] . "\" "; if (!empty($this->plots[$j]->csimwintargets[$i])) { $this->csimareas .= " target=\"" . $this->plots[$j]->csimwintargets[$i] . "\" "; } $sval = ''; if (!empty($this->plots[$j]->csimalts[$i])) { $sval = sprintf($this->plots[$j]->csimalts[$i], $this->plots[$j]->coords[0][$i]); $this->csimareas .= " title=\"{$sval}\" "; } $this->csimareas .= " alt=\"{$sval}\" />\n"; } } $pts[] = $pts[0]; $pts[] = $pts[1]; $img->SetLineWeight($this->plots[$j]->weight); $img->Polygon($pts); $img->SetLineWeight(1); } // Daw potential bar around the entire accbar bar if ($this->weight > 0) { $y = $yscale->Translate(0); $img->SetColor($this->color); $img->SetLineWeight($this->weight); $img->Rectangle($pts[0], $y, $pts[6], $pts[5]); } // Draw labels for each acc.bar $x = $pts[2] + ($pts[4] - $pts[2]) / 2; if ($this->bar_shadow) { $x += $ssh; } // First stroke the accumulated value for the entire bar // This value is always placed at the top/bottom of the bars if ($accy_neg < 0) { $y = $yscale->Translate($accy_neg); $this->value->Stroke($img, $accy_neg, $x, $y); } else { $y = $yscale->Translate($accy); $this->value->Stroke($img, $accy, $x, $y); } $accy = 0; $accy_neg = 0; for ($j = 0; $j < $this->nbrplots; ++$j) { // We don't print 0 values in an accumulated bar plot if ($this->plots[$j]->coords[0][$i] == 0) { continue; } if ($this->plots[$j]->coords[0][$i] > 0) { $yt = $yscale->Translate($this->plots[$j]->coords[0][$i] + $accy); $accyt = $yscale->Translate($accy); if ($this->plots[$j]->valuepos == 'center') { $y = $accyt - ($accyt - $yt) / 2; } elseif ($this->plots[$j]->valuepos == 'bottom') { $y = $accyt; } else { // top or max $y = $accyt - ($accyt - $yt); } $accy += $this->plots[$j]->coords[0][$i]; if ($this->plots[$j]->valuepos == 'center') { $this->plots[$j]->value->SetAlign("center", "center"); $this->plots[$j]->value->SetMargin(0); } elseif ($this->plots[$j]->valuepos == 'bottom') { $this->plots[$j]->value->SetAlign('center', 'bottom'); $this->plots[$j]->value->SetMargin(2); } else { $this->plots[$j]->value->SetAlign('center', 'top'); $this->plots[$j]->value->SetMargin(1); } } else { $yt = $yscale->Translate($this->plots[$j]->coords[0][$i] + $accy_neg); $accyt = $yscale->Translate($accy_neg); $accy_neg += $this->plots[$j]->coords[0][$i]; if ($this->plots[$j]->valuepos == 'center') { $y = $accyt - ($accyt - $yt) / 2; } elseif ($this->plots[$j]->valuepos == 'bottom') { $y = $accyt; } else { $y = $accyt - ($accyt - $yt); } if ($this->plots[$j]->valuepos == 'center') { $this->plots[$j]->value->SetAlign("center", "center"); $this->plots[$j]->value->SetMargin(0); } elseif ($this->plots[$j]->valuepos == 'bottom') { $this->plots[$j]->value->SetAlign('center', $j == 0 ? 'bottom' : 'top'); $this->plots[$j]->value->SetMargin(-2); } else { $this->plots[$j]->value->SetAlign('center', 'bottom'); $this->plots[$j]->value->SetMargin(-1); } } $this->plots[$j]->value->Stroke($img, $this->plots[$j]->coords[0][$i], $x, $y); } } return true; }
/** * Determine if the specified isobar crosses the vertical edge specified by its row and column * * @param $aRow Row index of edge to be checked * @param $aCol Col index of edge to be checked * @param $aIsobar Isobar value * @return true if the isobar is crossing this edge */ public function isobarVCrossing($aRow, $aCol, $aIsobar) { if ($aRow >= $this->nbrRows - 1) { Util\JpGraphError::RaiseL(28005, $aRow); //'isobarVCrossing: Row index too large } if ($aCol >= $this->nbrCols) { Util\JpGraphError::RaiseL(28006, $aCol); //'isobarVCrossing: Col index too large } $v1 = $this->dataPoints[$aRow][$aCol]; $v2 = $this->dataPoints[$aRow + 1][$aCol]; return ($aIsobar - $v1) * ($aIsobar - $v2) < 0; }
public function Stroke($img, $xscale, $yscale) { $n = $this->numpoints; if ($this->center) { $n--; } if (isset($this->coords[1])) { if (count($this->coords[1]) != $n) { Util\JpGraphError::RaiseL(2003, count($this->coords[1]), $n); // ("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 ($exist_x) { $xs = $this->coords[1][0]; } else { $xs = 0; } $ts = $this->iTupleSize; $this->csimareas = ''; for ($i = 0; $i < $n; ++$i) { //If value is NULL, then don't draw a bar at all if ($this->coords[0][$i * $ts] === null) { continue; } if ($exist_x) { $x = $this->coords[1][$i]; if ($x === null) { continue; } } else { $x = $i; } $xt = $xscale->Translate($x); $neg = $this->coords[0][$i * $ts] > $this->coords[0][$i * $ts + 1]; $yopen = $yscale->Translate($this->coords[0][$i * $ts]); $yclose = $yscale->Translate($this->coords[0][$i * $ts + 1]); $ymin = $yscale->Translate($this->coords[0][$i * $ts + 2]); $ymax = $yscale->Translate($this->coords[0][$i * $ts + 3]); $dx = floor($this->iWidth / 2); $xl = $xt - $dx; $xr = $xt + $dx; if ($neg) { $img->SetColor($this->iStockColor3); } else { $img->SetColor($this->iStockColor1); } $img->FilledRectangle($xl, $yopen, $xr, $yclose); $img->SetLineWeight($this->weight); if ($neg) { $img->SetColor($this->iStockColor2); } else { $img->SetColor($this->color); } $img->Rectangle($xl, $yopen, $xr, $yclose); if ($yopen < $yclose) { $ytop = $yopen; $ybottom = $yclose; } else { $ytop = $yclose; $ybottom = $yopen; } $img->SetColor($this->color); $img->Line($xt, $ytop, $xt, $ymax); $img->Line($xt, $ybottom, $xt, $ymin); if ($this->iEndLines) { $img->Line($xl, $ymax, $xr, $ymax); $img->Line($xl, $ymin, $xr, $ymin); } // A chance for subclasses to add things to the bar // for data point i $this->ModBox($img, $xscale, $yscale, $i, $xl, $xr, $neg); // Setup image maps if (!empty($this->csimtargets[$i])) { $this->csimareas .= '<area shape="rect" coords="' . round($xl) . ',' . round($ytop) . ',' . round($xr) . ',' . round($ybottom) . '" '; $this->csimareas .= ' href="' . $this->csimtargets[$i] . '"'; if (!empty($this->csimalts[$i])) { $sval = $this->csimalts[$i]; $this->csimareas .= " title=\"{$sval}\" alt=\"{$sval}\" "; } $this->csimareas .= " />\n"; } } return true; }
public function _Stroke($aImg, $aMinX, $aMinY, $aMaxX, $aMaxY, $aXPos, $aYPos) { $aImg->SetColor($this->color); $aImg->SetLineWeight($this->weight); $oldStyle = $aImg->SetLineStyle($this->iLineStyle); if ($this->direction == VERTICAL) { $ymin_abs = $aMinY; $ymax_abs = $aMaxY; $xpos_abs = $aXPos; $aImg->StyleLine($xpos_abs, $ymin_abs, $xpos_abs, $ymax_abs); } elseif ($this->direction == HORIZONTAL) { $xmin_abs = $aMinX; $xmax_abs = $aMaxX; $ypos_abs = $aYPos; $aImg->StyleLine($xmin_abs, $ypos_abs, $xmax_abs, $ypos_abs); } else { Util\JpGraphError::RaiseL(25125); //(" Illegal direction for static line"); } $aImg->SetLineStyle($oldStyle); }
public function Stroke($img, $xscale, $yscale) { $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; } $numbars = count($this->coords[0]); // Use GetMinVal() instead of scale[0] directly since in the case // of log scale we get a correct value. Log scales will have negative // values for values < 1 while still not representing negative numbers. if ($yscale->GetMinVal() >= 0) { $zp = $yscale->scale_abs[0]; } else { $zp = $yscale->Translate(0); } if ($this->abswidth > -1) { $abswidth = $this->abswidth; } else { $abswidth = round($this->width * $xscale->scale_factor, 0); } // Count pontetial pattern array to avoid doing the count for each iteration if (is_array($this->iPattern)) { $np = count($this->iPattern); } $grad = null; for ($i = 0; $i < $numbars; ++$i) { // If value is NULL, or 0 then don't draw a bar at all if ($this->coords[0][$i] === null || $this->coords[0][$i] === '') { continue; } if ($exist_x) { $x = $this->coords[1][$i]; } else { $x = $i; } $x = $xscale->Translate($x); // Comment Note: This confuses the positioning when using acc together with // grouped bars. Workaround for fixing #191 /* if( !$xscale->textscale ) { if($this->align=="center") $x -= $abswidth/2; elseif($this->align=="right") $x -= $abswidth; } */ // Stroke fill color and fill gradient $pts = array($x, $zp, $x, $yscale->Translate($this->coords[0][$i]), $x + $abswidth, $yscale->Translate($this->coords[0][$i]), $x + $abswidth, $zp); if ($this->grad) { if ($grad === null) { $grad = new Gradient($img); } if (is_array($this->grad_fromcolor)) { // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be // an array to specify both (from, to style) for each individual bar. The way to know the difference is // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB // triple. $ng = count($this->grad_fromcolor); if ($ng === 3) { if (is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256) { // RGB Triple $fromcolor = $this->grad_fromcolor; $tocolor = $this->grad_tocolor; $style = $this->grad_style; } else { $fromcolor = $this->grad_fromcolor[$i % $ng][0]; $tocolor = $this->grad_fromcolor[$i % $ng][1]; $style = $this->grad_fromcolor[$i % $ng][2]; } } else { $fromcolor = $this->grad_fromcolor[$i % $ng][0]; $tocolor = $this->grad_fromcolor[$i % $ng][1]; $style = $this->grad_fromcolor[$i % $ng][2]; } $grad->FilledRectangle($pts[2], $pts[3], $pts[6], $pts[7], $fromcolor, $tocolor, $style); } else { $grad->FilledRectangle($pts[2], $pts[3], $pts[6], $pts[7], $this->grad_fromcolor, $this->grad_tocolor, $this->grad_style); } } elseif (!empty($this->fill_color)) { if (is_array($this->fill_color)) { $img->PushColor($this->fill_color[$i % count($this->fill_color)]); } else { $img->PushColor($this->fill_color); } $img->FilledPolygon($pts); $img->PopColor(); } /////////////////////////kokorahen rectangle polygon////////////////////// // Remember value of this bar $val = $this->coords[0][$i]; if (!empty($val) && !is_numeric($val)) { Util\JpGraphError::RaiseL(2004, $i, $val); //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); } // Determine the shadow if ($this->bar_shadow && $val != 0) { $ssh = $this->bar_shadow_hsize; $ssv = $this->bar_shadow_vsize; // Create points to create a "upper-right" shadow if ($val > 0) { $sp[0] = $pts[6]; $sp[1] = $pts[7]; $sp[2] = $pts[4]; $sp[3] = $pts[5]; $sp[4] = $pts[2]; $sp[5] = $pts[3]; $sp[6] = $pts[2] + $ssh; $sp[7] = $pts[3] - $ssv; $sp[8] = $pts[4] + $ssh; $sp[9] = $pts[5] - $ssv; $sp[10] = $pts[6] + $ssh; $sp[11] = $pts[7] - $ssv; } elseif ($val < 0) { $sp[0] = $pts[4]; $sp[1] = $pts[5]; $sp[2] = $pts[6]; $sp[3] = $pts[7]; $sp[4] = $pts[0]; $sp[5] = $pts[1]; $sp[6] = $pts[0] + $ssh; $sp[7] = $pts[1] - $ssv; $sp[8] = $pts[6] + $ssh; $sp[9] = $pts[7] - $ssv; $sp[10] = $pts[4] + $ssh; $sp[11] = $pts[5] - $ssv; } if (is_array($this->bar_shadow_color)) { $numcolors = count($this->bar_shadow_color); if ($numcolors == 0) { Util\JpGraphError::RaiseL(2005); //('You have specified an empty array for shadow colors in the bar plot.'); } $img->PushColor($this->bar_shadow_color[$i % $numcolors]); } else { $img->PushColor($this->bar_shadow_color); } $img->FilledPolygon($sp); $img->PopColor(); } elseif ($this->bar_3d && $val != 0) { // Determine the 3D $ssh = $this->bar_3d_hsize; $ssv = $this->bar_3d_vsize; // Create points to create a "upper-right" shadow if ($val > 0) { $sp1[0] = $pts[6]; $sp1[1] = $pts[7]; $sp1[2] = $pts[4]; $sp1[3] = $pts[5]; $sp1[4] = $pts[4] + $ssh; $sp1[5] = $pts[5] - $ssv; $sp1[6] = $pts[6] + $ssh; $sp1[7] = $pts[7] - $ssv; $sp2[0] = $pts[4]; $sp2[1] = $pts[5]; $sp2[2] = $pts[2]; $sp2[3] = $pts[3]; $sp2[4] = $pts[2] + $ssh; $sp2[5] = $pts[3] - $ssv; $sp2[6] = $pts[4] + $ssh; $sp2[7] = $pts[5] - $ssv; } elseif ($val < 0) { $sp1[0] = $pts[4]; $sp1[1] = $pts[5]; $sp1[2] = $pts[6]; $sp1[3] = $pts[7]; $sp1[4] = $pts[6] + $ssh; $sp1[5] = $pts[7] - $ssv; $sp1[6] = $pts[4] + $ssh; $sp1[7] = $pts[5] - $ssv; $sp2[0] = $pts[6]; $sp2[1] = $pts[7]; $sp2[2] = $pts[0]; $sp2[3] = $pts[1]; $sp2[4] = $pts[0] + $ssh; $sp2[5] = $pts[1] - $ssv; $sp2[6] = $pts[6] + $ssh; $sp2[7] = $pts[7] - $ssv; } $base_color = $this->fill_color; $img->PushColor($base_color . ':0.7'); $img->FilledPolygon($sp1); $img->PopColor(); $img->PushColor($base_color . ':1.1'); $img->FilledPolygon($sp2); $img->PopColor(); } // Stroke the pattern if (is_array($this->iPattern)) { $f = new RectPatternFactory(); if (is_array($this->iPatternColor)) { $pcolor = $this->iPatternColor[$i % $np]; } else { $pcolor = $this->iPatternColor; } $prect = $f->Create($this->iPattern[$i % $np], $pcolor, 1); $prect->SetDensity($this->iPatternDensity[$i % $np]); if ($val < 0) { $rx = $pts[0]; $ry = $pts[1]; } else { $rx = $pts[2]; $ry = $pts[3]; } $width = abs($pts[4] - $pts[0]) + 1; $height = abs($pts[1] - $pts[3]) + 1; $prect->SetPos(new Rectangle($rx, $ry, $width, $height)); $prect->Stroke($img); } else { if ($this->iPattern > -1) { $f = new RectPatternFactory(); $prect = $f->Create($this->iPattern, $this->iPatternColor, 1); $prect->SetDensity($this->iPatternDensity); if ($val < 0) { $rx = $pts[0]; $ry = $pts[1]; } else { $rx = $pts[2]; $ry = $pts[3]; } $width = abs($pts[4] - $pts[0]) + 1; $height = abs($pts[1] - $pts[3]) + 1; $prect->SetPos(new Rectangle($rx, $ry, $width, $height)); $prect->Stroke($img); } } // Stroke the outline of the bar if (is_array($this->color)) { $img->SetColor($this->color[$i % count($this->color)]); } else { $img->SetColor($this->color); } $pts[] = $pts[0]; $pts[] = $pts[1]; if ($this->weight > 0) { $img->SetLineWeight($this->weight); $img->Polygon($pts); } // Determine how to best position the values of the individual bars $x = $pts[2] + ($pts[4] - $pts[2]) / 2; $this->value->SetMargin(5); if ($this->valuepos == 'top') { $y = $pts[3]; if ($img->a === 90) { if ($val < 0) { $this->value->SetAlign('right', 'center'); } else { $this->value->SetAlign('left', 'center'); } } else { if ($val < 0) { $this->value->SetMargin(-5); $y = $pts[1]; $this->value->SetAlign('center', 'bottom'); } else { $this->value->SetAlign('center', 'bottom'); } } $this->value->Stroke($img, $val, $x, $y); } elseif ($this->valuepos == 'max') { $y = $pts[3]; if ($img->a === 90) { if ($val < 0) { $this->value->SetAlign('left', 'center'); } else { $this->value->SetAlign('right', 'center'); } } else { if ($val < 0) { $this->value->SetAlign('center', 'bottom'); } else { $this->value->SetAlign('center', 'top'); } } $this->value->SetMargin(-5); $this->value->Stroke($img, $val, $x, $y); } elseif ($this->valuepos == 'center') { $y = ($pts[3] + $pts[1]) / 2; $this->value->SetAlign('center', 'center'); $this->value->SetMargin(0); $this->value->Stroke($img, $val, $x, $y); } elseif ($this->valuepos == 'bottom' || $this->valuepos == 'min') { $y = $pts[1]; if ($img->a === 90) { if ($val < 0) { $this->value->SetAlign('right', 'center'); } else { $this->value->SetAlign('left', 'center'); } } $this->value->SetMargin(3); $this->value->Stroke($img, $val, $x, $y); } else { Util\JpGraphError::RaiseL(2006, $this->valuepos); //'Unknown position for values on bars :'.$this->valuepos); } // Create the client side image map $rpts = $img->ArrRotate($pts); $csimcoord = round($rpts[0]) . ", " . round($rpts[1]); for ($j = 1; $j < 4; ++$j) { $csimcoord .= ", " . round($rpts[2 * $j]) . ", " . round($rpts[2 * $j + 1]); } if (!empty($this->csimtargets[$i])) { $this->csimareas .= '<area shape="poly" coords="' . $csimcoord . '" '; $this->csimareas .= " href=\"" . htmlentities($this->csimtargets[$i]) . "\""; if (!empty($this->csimwintargets[$i])) { $this->csimareas .= " target=\"" . $this->csimwintargets[$i] . "\" "; } $sval = ''; if (!empty($this->csimalts[$i])) { $sval = sprintf($this->csimalts[$i], $this->coords[0][$i]); $this->csimareas .= " title=\"{$sval}\" alt=\"{$sval}\" "; } $this->csimareas .= " />\n"; } } return true; }
public function Stroke($img, $aaoption = 0) { $n = count($this->data); // If user hasn't set the colors use the theme array if ($this->setslicecolors == null) { $colors = array_keys($img->rgb->rgb_table); sort($colors); $idx_a = $this->themearr[$this->theme]; $ca = array(); $m = count($idx_a); for ($i = 0; $i < $m; ++$i) { $ca[$i] = $colors[$idx_a[$i]]; } $ca = array_reverse(array_slice($ca, 0, $n)); } else { $ca = $this->setslicecolors; } 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; } if ($this->radius <= 1) { $width = floor($this->radius * min($img->width, $img->height)); // Make sure that the pie doesn't overflow the image border // The 0.9 factor is simply an extra margin to leave some space // between the pie an the border of the image. $width = min($width, min($xc * 0.9, ($yc * 90 / $this->angle - $width / 4) * 0.9)); } else { $width = $this->radius * ($aaoption === 1 ? 2 : 1); } // Add a sanity check for width if ($width < 1) { Util\JpGraphError::RaiseL(14007); //("Width for 3D Pie is 0. Specify a size > 0"); } // Establish a thickness. By default the thickness is a fifth of the // pie slice width (=pie radius) but since the perspective depends // on the inclination angle we use some heuristics to make the edge // slightly thicker the less the angle. // Has user specified an absolute thickness? In that case use // that instead if ($this->iThickness) { $thick = $this->iThickness; $thick *= $aaoption === 1 ? 2 : 1; } else { $thick = $width / 12; } $a = $this->angle; if ($a <= 30) { $thick *= 1.6; } elseif ($a <= 40) { $thick *= 1.4; } elseif ($a <= 50) { $thick *= 1.2; } elseif ($a <= 60) { $thick *= 1.0; } elseif ($a <= 70) { $thick *= 0.8; } elseif ($a <= 80) { $thick *= 0.7; } else { $thick *= 0.6; } $thick = floor($thick); if ($this->explode_all) { for ($i = 0; $i < $n; ++$i) { $this->explode_radius[$i] = $this->explode_r; } } $this->Pie3D($aaoption, $img, $this->data, $ca, $xc, $yc, $width, $this->angle, $thick, 0.65, $this->startangle, $this->edgecolor, $this->edgeweight); // Adjust title position if ($aaoption != 1) { $this->title->SetPos($xc, $yc - $this->title->GetFontHeight($img) - $width / 2 - $this->title->margin, "center", "bottom"); $this->title->Stroke($img); } }