Example #1
0
 /**
  * @param array $coefficients
  * @param array $features
  * @param float $outcome
  * @return array
  */
 public function gradient(array $coefficients, array $features, float $outcome) : array
 {
     $gradient = [];
     $baseGradient = $this->gradient->gradient($coefficients, $features, $outcome);
     for ($i = 0; $i < count($baseGradient); $i++) {
         $penalty = $i || !$this->ignoreFirst ? $this->lambda * pow(abs($coefficients[$i]), $this->level - 1) : 0.0;
         $gradient[] = $baseGradient[$i] + $penalty;
     }
     return $gradient;
 }
/**
 * Creates a gradient in the form of a background image.
 *
 * @author Anthony Short
 * @param $param
 * @return string The properties
 */
function Scaffold_background_gradient($params)
{
    if (preg_match_all('/\\([^)]*?,[^)]*?\\)/', $params, $matches)) {
        foreach ($matches as $key => $original) {
            $new = str_replace(',', '#COMMA#', $original);
            $params = str_replace($original, $new, $params);
        }
    }
    $params = explode(',', $params);
    foreach (array('dir', 'size', 'from', 'to') as $key => $name) {
        ${$name} = trim(str_replace('#COMMA#', ',', array_shift($params)));
    }
    $stops = array();
    foreach ($params as $stop) {
        $stop = preg_replace('/color\\-stop\\(|\\)/', '', $stop);
        $stop = explode('#COMMA#', $stop);
        $stops[] = array('position' => trim($stop[0]), 'color' => trim($stop[1]));
    }
    $from = preg_replace('/from\\s*\\(|\\)/', '', $from);
    $to = preg_replace('/to\\s*\\(|\\)/', '', $to);
    $size = str_replace('px', '', $size);
    return Gradient::create_gradient($dir, $size, $from, $to, $stops);
}
Example #3
0
 function Stroke(&$img, &$xscale, &$yscale)
 {
     $img->SetLineWeight($this->weight);
     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 {
                 $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);
             //echo "$i => $xt<br>";
             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->plots[$j]->grad) {
                 $grad = new Gradient($img);
                 $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);
             } elseif ($this->plots[$j]->fill_color) {
                 $img->SetColor($this->plots[$j]->fill_color);
                 $img->FilledPolygon($pts);
                 $img->SetColor($this->plots[$j]->color);
             }
             if ($this->bar_shadow) {
                 $ssh = $this->bar_shadow_hsize;
                 $ssv = $this->bar_shadow_vsize;
                 // Create points to create a "upper-right" shadow
                 $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;
                 $img->SetColor($this->bar_shadow_color);
                 $img->FilledPolygon($sp, 4);
             }
             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]);
                 }
                 $this->csimareas .= '<area shape="poly" coords="' . $csimcoord . '" ';
                 $this->csimareas .= " href=\"" . $this->plots[$j]->csimtargets[$i] . "\"";
                 if (!empty($this->plots[$j]->csimalts[$i])) {
                     $sval = sprintf($this->plots[$j]->csimalts[$i], $this->plots[$j]->coords[0][$i]);
                     $this->csimareas .= " alt=\"{$sval}\" title=\"{$sval}\" ";
                 }
                 $this->csimareas .= ">\n";
             }
             $pts[] = $pts[0];
             $pts[] = $pts[1];
             $img->Polygon($pts);
         }
         $x = $pts[2] + ($pts[4] - $pts[2]) / 2;
         $y = $yscale->Translate($accy);
         if ($this->bar_shadow) {
             $x += $ssh;
         }
         $this->value->Stroke($img, $accy, $x, $y);
         $accy = 0;
         $accy_neg = 0;
         for ($j = 0; $j < $this->nbrplots; ++$j) {
             if ($this->plots[$j]->coords[0][$i] > 0) {
                 $yt = $yscale->Translate($this->plots[$j]->coords[0][$i] + $accy);
                 $accyt = $yscale->Translate($accy);
                 $y = $accyt - ($accyt - $yt) / 2;
                 $accy += $this->plots[$j]->coords[0][$i];
             } else {
                 $yt = $yscale->Translate($this->plots[$j]->coords[0][$i] + $accy_neg);
                 $accyt = $yscale->Translate($accy_neg);
                 $y = 0;
                 $accy_neg += $this->plots[$j]->coords[0][$i];
             }
             $this->plots[$j]->value->SetAlign("center", "center");
             $this->plots[$j]->value->SetMargin(0);
             $this->plots[$j]->value->Stroke($img, $this->plots[$j]->coords[0][$i], $x, $y);
         }
     }
     return true;
 }
Example #4
0
 function Stroke($img, $xscale, $yscale)
 {
     $idx = 0;
     $numpoints = count($this->coords[0]);
     if (isset($this->coords[1])) {
         if (count($this->coords[1]) != $numpoints) {
             JpGraphError::RaiseL(2003, count($this->coords[1]), $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) {
         $min = $yscale->GetMinVal();
         if ($min > 0 || $this->fillFromMin) {
             $fillmin = $yscale->scale_abs[0];
         } 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 ($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->line_weight > 0) {
             $img->SetColor($this->color);
             $img->Polygon($cord);
         }
     }
     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.
             // TODO: The behaviour is undefined if the line does not have
             // any line at the position of the area.
             if ($this->filledAreas[$i][4]) {
                 $img->Polygon($areaCoords);
             } else {
                 $img->Polygon($cord);
             }
             $areaCoords = array();
         }
     }
     if ($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();
         }
     }
 }
Example #5
0
 function Stroke(&$aImg)
 {
     // Constant
     $fillBoxFrameWeight = 1;
     if ($this->hide) {
         return;
     }
     $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
     if ($this->reverse) {
         $this->txtcol = array_reverse($this->txtcol);
     }
     $n = count($this->txtcol);
     if ($n == 0) {
         return;
     }
     // Find out the max width and height of each column to be able
     // to size the legend box.
     $numcolumns = $n > $this->layout_n ? $this->layout_n : $n;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_hsize;
         $colheight[$i] = 0;
     }
     // Find our maximum height in each row
     $rows = 0;
     $rowheight[0] = 0;
     for ($i = 0; $i < $n; ++$i) {
         $h = max($this->mark_abs_vsize, $aImg->GetTextHeight($this->txtcol[$i][0])) + $this->ymargin;
         if ($i % $numcolumns == 0) {
             $rows++;
             $rowheight[$rows - 1] = 0;
         }
         $rowheight[$rows - 1] = max($rowheight[$rows - 1], $h);
     }
     $abs_height = 0;
     for ($i = 0; $i < $rows; ++$i) {
         $abs_height += $rowheight[$i];
     }
     // Make sure that the height is at least as high as mark size + ymargin
     $abs_height = max($abs_height, $this->mark_abs_vsize);
     // We add 3 extra pixels height to compensate for the difficult in
     // calculating font height
     $abs_height += $this->ymargin + 3;
     // Find out the maximum width in each column
     for ($i = $numcolumns; $i < $n; ++$i) {
         $colwidth[$i % $numcolumns] = max($aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_hsize, $colwidth[$i % $numcolumns]);
     }
     // Get the total width
     $mtw = 0;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $mtw += $colwidth[$i];
     }
     // Find out maximum width we need for legend box
     $abs_width = $mtw + $this->xlmargin;
     if ($this->xabspos === -1 && $this->yabspos === -1) {
         $this->xabspos = $this->xpos * $aImg->width;
         $this->yabspos = $this->ypos * $aImg->height;
     }
     // Positioning of the legend box
     if ($this->halign == 'left') {
         $xp = $this->xabspos;
     } elseif ($this->halign == 'center') {
         $xp = $this->xabspos - $abs_width / 2;
     } else {
         $xp = $aImg->width - $this->xabspos - $abs_width;
     }
     $yp = $this->yabspos;
     if ($this->valign == 'center') {
         $yp -= $abs_height / 2;
     } elseif ($this->valign == 'bottom') {
         $yp -= $abs_height;
     }
     // Stroke legend box
     $aImg->SetColor($this->color);
     $aImg->SetLineWeight($this->frameweight);
     $aImg->SetLineStyle('solid');
     if ($this->shadow) {
         $aImg->ShadowRectangle($xp, $yp, $xp + $abs_width + $this->shadow_width, $yp + $abs_height + $this->shadow_width, $this->fill_color, $this->shadow_width, $this->shadow_color);
     } else {
         $aImg->SetColor($this->fill_color);
         $aImg->FilledRectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
         $aImg->SetColor($this->color);
         $aImg->Rectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
     }
     // x1,y1 is the position for the legend mark
     $x1 = $xp + $this->mark_abs_hsize + $this->xlmargin;
     $y1 = $yp + $this->ymargin;
     $f2 = round($aImg->GetTextHeight('X') / 2);
     $grad = new Gradient($aImg);
     $patternFactory = null;
     // Now stroke each legend in turn
     // Each plot has added the following information to  the legend
     // p[0] = Legend text
     // p[1] = Color,
     // p[2] = For markers a reference to the PlotMark object
     // p[3] = For lines the line style, for gradient the negative gradient style
     // p[4] = CSIM target
     // p[5] = CSIM Alt text
     $i = 1;
     $row = 0;
     foreach ($this->txtcol as $p) {
         // STROKE DEBUG BOX
         if (_JPG_DEBUG) {
             $aImg->SetLineWeight(1);
             $aImg->SetColor('red');
             $aImg->SetLineStyle('solid');
             $aImg->Rectangle($xp, $y1, $xp + $abs_width, $y1 + $rowheight[$row]);
         }
         $aImg->SetLineWeight($this->weight);
         $x1 = round($x1);
         $y1 = round($y1);
         if (!empty($p[2]) && $p[2]->GetType() > -1) {
             // Make a plot mark legend
             $aImg->SetColor($p[1]);
             if (is_string($p[3]) || $p[3] > 0) {
                 $aImg->SetLineStyle($p[3]);
                 $aImg->StyleLine($x1 - $this->mark_abs_hsize, $y1 + $f2, $x1 + $this->mark_abs_hsize, $y1 + $f2);
             }
             // Stroke a mark with the standard size
             // (As long as it is not an image mark )
             if ($p[2]->GetType() != MARK_IMG) {
                 // Clear any user callbacks since we ont want them called for
                 // the legend marks
                 $p[2]->iFormatCallback = '';
                 $p[2]->iFormatCallback2 = '';
                 // Since size for circles is specified as the radius
                 // this means that we must half the size to make the total
                 // width behave as the other marks
                 if ($p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE) {
                     $p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize) / 2);
                     $p[2]->Stroke($aImg, $x1, $y1 + $f2);
                 } else {
                     $p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize));
                     $p[2]->Stroke($aImg, $x1, $y1 + $f2);
                 }
             }
         } elseif (!empty($p[2]) && (is_string($p[3]) || $p[3] > 0)) {
             // Draw a styled line
             $aImg->SetColor($p[1]);
             $aImg->SetLineStyle($p[3]);
             $aImg->StyleLine($x1 - 1, $y1 + $f2, $x1 + $this->mark_abs_hsize, $y1 + $f2);
             $aImg->StyleLine($x1 - 1, $y1 + $f2 + 1, $x1 + $this->mark_abs_hsize, $y1 + $f2 + 1);
         } else {
             // Draw a colored box
             $color = $p[1];
             // We make boxes slightly larger to better show
             $boxsize = min($this->mark_abs_vsize, $this->mark_abs_hsize) + 2;
             $ym = round($y1 + $f2 - $boxsize / 2);
             // We either need to plot a gradient or a
             // pattern. To differentiate we use a kludge.
             // Patterns have a p[3] value of < -100
             if ($p[3] < -100) {
                 // p[1][0] == iPattern, p[1][1] == iPatternColor, p[1][2] == iPatternDensity
                 if ($patternFactory == null) {
                     $patternFactory = new RectPatternFactory();
                 }
                 $prect = $patternFactory->Create($p[1][0], $p[1][1], 1);
                 $prect->SetBackground($p[1][3]);
                 $prect->SetDensity($p[1][2] + 1);
                 $prect->SetPos(new Rectangle($x1, $ym, $boxsize, $boxsize));
                 $prect->Stroke($aImg);
                 $prect = null;
             } else {
                 if (is_array($color) && count($color) == 2) {
                     // The client want a gradient color
                     $grad->FilledRectangle($x1, $ym, $x1 + $boxsize, $ym + $boxsize, $color[0], $color[1], -$p[3]);
                 } else {
                     $aImg->SetColor($p[1]);
                     $aImg->FilledRectangle($x1, $ym, $x1 + $boxsize, $ym + $boxsize);
                 }
                 $aImg->SetColor($this->color);
                 $aImg->SetLineWeight($fillBoxFrameWeight);
                 $aImg->Rectangle($x1, $ym, $x1 + $boxsize, $ym + $boxsize);
             }
         }
         $aImg->SetColor($this->font_color);
         $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
         $aImg->SetTextAlign("left", "top");
         $aImg->StrokeText(round($x1 + $this->mark_abs_hsize + $this->xmargin), $y1, $p[0]);
         // Add CSIM for Legend if defined
         if (!empty($p[4])) {
             $xe = $x1 + $this->xmargin + $this->mark_abs_hsize + $aImg->GetTextWidth($p[0]);
             $ye = $y1 + max($this->mark_abs_vsize, $aImg->GetTextHeight($p[0]));
             $coords = "{$x1},{$y1},{$xe},{$y1},{$xe},{$ye},{$x1},{$ye}";
             if (!empty($p[4])) {
                 $this->csimareas .= "<area shape=\"poly\" coords=\"{$coords}\" href=\"" . atk_htmlentities($p[4]) . "\"";
                 if (!empty($p[6])) {
                     $this->csimareas .= " target=\"" . $p[6] . "\"";
                 }
                 if (!empty($p[5])) {
                     $tmp = sprintf($p[5], $p[0]);
                     $this->csimareas .= " title=\"{$tmp}\" alt=\"{$tmp}\" ";
                 }
                 $this->csimareas .= " />\n";
             }
         }
         if ($i >= $this->layout_n) {
             $x1 = $xp + $this->mark_abs_hsize + $this->xlmargin;
             $y1 += $rowheight[$row++];
             $i = 1;
         } else {
             $x1 += $colwidth[($i - 1) % $numcolumns];
             ++$i;
         }
     }
 }
Example #6
0
 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) {
                             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;
 }
Example #7
0
 function Stroke(&$img, &$xscale, &$yscale)
 {
     $pattern = NULL;
     $img->SetLineWeight($this->weight);
     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) {
                             JpGraphError::Raise('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) {
                 $grad = new Gradient($img);
                 $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);
                     $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]);
                 } else {
                     $img->SetColor($this->plots[$j]->fill_color);
                 }
                 $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);
                 $prect->SetPos(new Rectangle($pts[2], $pts[3], $pts[4] - $pts[0] + 1, $pts[1] - $pts[3] + 1));
                 $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]->csimalts[$i])) {
                         $sval = sprintf($this->plots[$j]->csimalts[$i], $this->plots[$j]->coords[0][$i]);
                         $this->csimareas .= " alt=\"{$sval}\" title=\"{$sval}\" ";
                     }
                     $this->csimareas .= ">\n";
                 }
             }
             $pts[] = $pts[0];
             $pts[] = $pts[1];
             $img->Polygon($pts);
         }
         // Draw labels for each acc.bar
         $x = $pts[2] + ($pts[4] - $pts[2]) / 2;
         $y = $yscale->Translate($accy);
         if ($this->bar_shadow) {
             $x += $ssh;
         }
         $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);
                 $y = $accyt - ($accyt - $yt) / 2;
                 $accy += $this->plots[$j]->coords[0][$i];
             } else {
                 $yt = $yscale->Translate($this->plots[$j]->coords[0][$i] + $accy_neg);
                 $accyt = $yscale->Translate($accy_neg);
                 //$y=0;
                 $accy_neg += $this->plots[$j]->coords[0][$i];
                 $y = $accyt - ($accyt - $yt) / 2;
                 // TODO : Check this fix
             }
             $this->plots[$j]->value->SetAlign("center", "center");
             $this->plots[$j]->value->SetMargin(0);
             $this->plots[$j]->value->Stroke($img, $this->plots[$j]->coords[0][$i], $x, $y);
         }
     }
     return true;
 }
Example #8
0
 function Stroke($aImg)
 {
     // Constant
     $fillBoxFrameWeight = 1;
     if ($this->hide) {
         return;
     }
     $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
     if ($this->reverse) {
         $this->txtcol = array_reverse($this->txtcol);
     }
     $n = count($this->txtcol);
     if ($n == 0) {
         return;
     }
     // Find out the max width and height of each column to be able
     // to size the legend box.
     $numcolumns = $n > $this->layout_n ? $this->layout_n : $n;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_hsize;
         $colheight[$i] = 0;
     }
     // Find our maximum height in each row
     $rows = 0;
     $rowheight[0] = 0;
     for ($i = 0; $i < $n; ++$i) {
         $h = max($this->mark_abs_vsize, $aImg->GetTextHeight($this->txtcol[$i][0])) + $this->ylinespacing;
         // Makes sure we always have a minimum of 1/4 (1/2 on each side) of the mark as space
         // between two vertical legend entries
         //$h = round(max($h,$this->mark_abs_vsize+$this->ymargin));
         //echo "Textheight #$i: tetxheight=".$aImg->GetTextHeight($this->txtcol[$i][0]).', ';
         //echo "h=$h ({$this->mark_abs_vsize},{$this->ymargin})<br>";
         if ($i % $numcolumns == 0) {
             $rows++;
             $rowheight[$rows - 1] = 0;
         }
         $rowheight[$rows - 1] = max($rowheight[$rows - 1], $h) + 1;
     }
     $abs_height = 0;
     for ($i = 0; $i < $rows; ++$i) {
         $abs_height += $rowheight[$i];
     }
     // Make sure that the height is at least as high as mark size + ymargin
     $abs_height = max($abs_height, $this->mark_abs_vsize);
     $abs_height += $this->ybottom_margin;
     // Find out the maximum width in each column
     for ($i = $numcolumns; $i < $n; ++$i) {
         $colwidth[$i % $numcolumns] = max($aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_hsize, $colwidth[$i % $numcolumns]);
     }
     // Get the total width
     $mtw = 0;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $mtw += $colwidth[$i];
     }
     // remove the last rows interpace margin (since there is no next row)
     $abs_height -= $this->ylinespacing;
     // Find out maximum width we need for legend box
     $abs_width = $mtw + $this->xlmargin + ($numcolumns - 1) * $this->mark_abs_hsize;
     if ($this->xabspos === -1 && $this->yabspos === -1) {
         $this->xabspos = $this->xpos * $aImg->width;
         $this->yabspos = $this->ypos * $aImg->height;
     }
     // Positioning of the legend box
     if ($this->halign == 'left') {
         $xp = $this->xabspos;
     } elseif ($this->halign == 'center') {
         $xp = $this->xabspos - $abs_width / 2;
     } else {
         $xp = $aImg->width - $this->xabspos - $abs_width;
     }
     $yp = $this->yabspos;
     if ($this->valign == 'center') {
         $yp -= $abs_height / 2;
     } elseif ($this->valign == 'bottom') {
         $yp -= $abs_height;
     }
     // Stroke legend box
     $aImg->SetColor($this->color);
     $aImg->SetLineWeight($this->frameweight);
     $aImg->SetLineStyle('solid');
     if ($this->shadow) {
         $aImg->ShadowRectangle($xp, $yp, $xp + $abs_width + $this->shadow_width + 2, $yp + $abs_height + $this->shadow_width + 2, $this->fill_color, $this->shadow_width + 2, $this->shadow_color);
     } else {
         $aImg->SetColor($this->fill_color);
         $aImg->FilledRectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
         $aImg->SetColor($this->color);
         $aImg->Rectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
     }
     if ($this->bkg_gradtype >= 0) {
         $grad = new Gradient($aImg);
         $grad->FilledRectangle($xp + 1, $yp + 1, $xp + $abs_width - 3, $yp + $abs_height - 3, $this->bkg_gradfrom, $this->bkg_gradto, $this->bkg_gradtype);
     }
     // x1,y1 is the position for the legend marker + text
     // The vertical position is the baseline position for the text
     // and every marker is adjusted acording to that.
     // For multiline texts this get more complicated.
     $x1 = $xp + $this->xlmargin;
     $y1 = $yp + $rowheight[0] - $this->ylinespacing + 2;
     // The ymargin is included in rowheight
     // Now, y1 is the bottom vertical position of the first legend, i.e if
     // the legend has multiple lines it is the bottom line.
     $grad = new Gradient($aImg);
     $patternFactory = null;
     // Now stroke each legend in turn
     // Each plot has added the following information to  the legend
     // p[0] = Legend text
     // p[1] = Color,
     // p[2] = For markers a reference to the PlotMark object
     // p[3] = For lines the line style, for gradient the negative gradient style
     // p[4] = CSIM target
     // p[5] = CSIM Alt text
     $i = 1;
     $row = 0;
     foreach ($this->txtcol as $p) {
         // STROKE DEBUG BOX
         if (_JPG_DEBUG) {
             $aImg->SetLineWeight(1);
             $aImg->SetColor('red');
             $aImg->SetLineStyle('solid');
             $aImg->Rectangle($x1, $y1, $xp + $abs_width - 1, $y1 - $rowheight[$row]);
         }
         $aImg->SetLineWeight($this->weight);
         $x1 = round($x1) + 1;
         // We add one to not collide with the border
         $y1 = round($y1);
         // This is the center offset up from the baseline which is
         // considered the "center" of the marks. This gets slightly complicated since
         // we need to consider if the text is a multiline paragraph or if it is only
         // a single line. The reason is that for single line the y1 corresponds to the baseline
         // and that is fine. However for a multiline paragraph there is no single baseline
         // and in that case the y1 corresponds to the lowest y for the bounding box. In that
         // case we center the mark in the middle of the paragraph
         if (!preg_match('/\\n/', $p[0])) {
             // Single line
             $marky = ceil($y1 - $this->mark_abs_vsize / 2) - 1;
         } else {
             // Paragraph
             $marky = $y1 - $aImg->GetTextHeight($p[0]) / 2;
             //  echo "y1=$y1, p[o]={$p[0]}, marky=$marky<br>";
         }
         //echo "<br>Mark #$i: marky=$marky<br>";
         $x1 += $this->mark_abs_hsize;
         if (!empty($p[2]) && $p[2]->GetType() > -1) {
             // Make a plot mark legend. This is constructed with a mark which
             // is run through with a line
             // First construct a bit of the line that looks exactly like the
             // line in the plot
             $aImg->SetColor($p[1]);
             if (is_string($p[3]) || $p[3] > 0) {
                 $aImg->SetLineStyle($p[3]);
                 $aImg->StyleLine($x1 - $this->mark_abs_hsize, $marky, $x1 + $this->mark_abs_hsize, $marky);
             }
             // Stroke a mark using image
             if ($p[2]->GetType() == MARK_IMG) {
                 $p[2]->Stroke($aImg, $x1, $marky);
             }
             // Stroke a mark with the standard size
             // (As long as it is not an image mark )
             if ($p[2]->GetType() != MARK_IMG) {
                 // Clear any user callbacks since we ont want them called for
                 // the legend marks
                 $p[2]->iFormatCallback = '';
                 $p[2]->iFormatCallback2 = '';
                 // Since size for circles is specified as the radius
                 // this means that we must half the size to make the total
                 // width behave as the other marks
                 if ($p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE) {
                     $p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize) / 2);
                     $p[2]->Stroke($aImg, $x1, $marky);
                 } else {
                     $p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize));
                     $p[2]->Stroke($aImg, $x1, $marky);
                 }
             }
         } elseif (!empty($p[2]) && (is_string($p[3]) || $p[3] > 0)) {
             // Draw a styled line
             $aImg->SetColor($p[1]);
             $aImg->SetLineStyle($p[3]);
             $aImg->StyleLine($x1 - $this->mark_abs_hsize, $marky, $x1 + $this->mark_abs_hsize, $marky);
             $aImg->StyleLine($x1 - $this->mark_abs_hsize, $marky + 1, $x1 + $this->mark_abs_hsize, $marky + 1);
         } else {
             // Draw a colored box
             $color = $p[1];
             // We make boxes slightly larger to better show
             $boxsize = max($this->mark_abs_vsize, $this->mark_abs_hsize) + 2;
             $ym = $marky - ceil($boxsize / 2);
             // Marker y-coordinate
             // We either need to plot a gradient or a
             // pattern. To differentiate we use a kludge.
             // Patterns have a p[3] value of < -100
             if ($p[3] < -100) {
                 // p[1][0] == iPattern, p[1][1] == iPatternColor, p[1][2] == iPatternDensity
                 if ($patternFactory == null) {
                     $patternFactory = new RectPatternFactory();
                 }
                 $prect = $patternFactory->Create($p[1][0], $p[1][1], 1);
                 $prect->SetBackground($p[1][3]);
                 $prect->SetDensity($p[1][2] + 1);
                 $prect->SetPos(new Rectangle($x1, $ym, $boxsize, $boxsize));
                 $prect->Stroke($aImg);
                 $prect = null;
             } else {
                 if (is_array($color) && count($color) == 2) {
                     // The client want a gradient color
                     $grad->FilledRectangle($x1 - $boxsize / 2, $ym, $x1 + $boxsize / 2, $ym + $boxsize, $color[0], $color[1], -$p[3]);
                 } else {
                     $aImg->SetColor($p[1]);
                     $aImg->FilledRectangle($x1 - $boxsize / 2, $ym, $x1 + $boxsize / 2, $ym + $boxsize);
                 }
                 // Draw a plot frame line
                 $aImg->SetColor($this->color);
                 $aImg->SetLineWeight($fillBoxFrameWeight);
                 $aImg->Rectangle($x1 - $boxsize / 2, $ym, $x1 + $boxsize / 2, $ym + $boxsize);
             }
         }
         $aImg->SetColor($this->font_color);
         $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
         $aImg->SetTextAlign('left', 'baseline');
         $debug = false;
         $aImg->StrokeText($x1 + $this->mark_abs_hsize + $this->xmargin, $y1, $p[0], 0, 'left', $debug);
         // Add CSIM for Legend if defined
         if (!empty($p[4])) {
             $xs = $x1 - $this->mark_abs_hsize;
             $ys = $y1 + 1;
             $xe = $x1 + $aImg->GetTextWidth($p[0]) + $this->mark_abs_hsize + $this->xmargin;
             $ye = $y1 - $rowheight[$row] + 1;
             $coords = "{$xs},{$ys},{$xe},{$y1},{$xe},{$ye},{$xs},{$ye}";
             if (!empty($p[4])) {
                 $this->csimareas .= "<area shape=\"poly\" coords=\"{$coords}\" href=\"" . htmlentities($p[4]) . "\"";
                 if (!empty($p[6])) {
                     $this->csimareas .= " target=\"" . $p[6] . "\"";
                 }
                 if (!empty($p[5])) {
                     $tmp = sprintf($p[5], $p[0]);
                     $this->csimareas .= " title=\"{$tmp}\" alt=\"{$tmp}\" ";
                 }
                 $this->csimareas .= " />\n";
             }
         }
         if ($i >= $this->layout_n) {
             $x1 = $xp + $this->xlmargin;
             $row++;
             if (!empty($rowheight[$row])) {
                 $y1 += $rowheight[$row];
             }
             $i = 1;
         } else {
             $x1 += $colwidth[($i - 1) % $numcolumns];
             ++$i;
         }
     }
 }
Example #9
0
 function Stroke(&$img, &$xscale, &$yscale)
 {
     $img->SetColor($this->color);
     $img->SetLineWeight($this->weight);
     $numbars = count($this->coords[0]);
     if ($yscale->scale[0] >= 0) {
         $zp = $yscale->scale_abs[0];
     } else {
         $zp = $yscale->Translate(0.0);
     }
     $abswidth = round($this->width * $xscale->scale_factor, 0);
     for ($i = 0; $i < $numbars; $i++) {
         $x = $xscale->Translate($i + 1);
         $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) {
             $grad = new Gradient($img);
             $grad->FilledRectangle($pts[2], $pts[3], $pts[6], $pts[7], $this->grad_fromcolor, $this->grad_tocolor, $this->grad_style);
         } elseif ($this->fill_color) {
             $img->SetColor($this->fill_color);
             $img->FilledPolygon($pts, 4);
             $img->SetColor($this->color);
         }
         $img->Polygon($pts, 4);
     }
     return true;
 }
Example #10
0
 function Stroke(&$img, &$xscale, &$yscale)
 {
     $img->SetLineWeight($this->weight);
     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 {
                 $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);
             $abswidth = round($this->width * $xscale->scale_factor, 0);
             $pts = array($xt, $accyt, $xt, $yt, $xt + $abswidth, $yt, $xt + $abswidth, $accyt);
             if ($this->plots[$j]->grad) {
                 $grad = new Gradient($img);
                 $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);
             } elseif ($this->plots[$j]->fill_color) {
                 $img->SetColor($this->plots[$j]->fill_color);
                 $img->FilledPolygon($pts, 4);
                 $img->SetColor($this->plots[$j]->color);
             }
             if ($this->bar_shadow) {
                 $ssh = $this->bar_shadow_hsize;
                 $ssv = $this->bar_shadow_vsize;
                 // Create points to create a "upper-right" shadow
                 $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;
                 $img->SetColor($this->bar_shadow_color);
                 $img->FilledPolygon($sp, 4);
             }
             if ($i < count($this->plots[$j]->csimtargets)) {
                 $this->csimareas .= "<area shape=\"rect\" coords=\"";
                 // Hmmm, this is fishy.  Fixes a bug in Opera whereby if Y2<Y1 or X2<X1 the csim doesn't work
                 // This means that the area MUST specify top left and bottom right corners
                 if ($pts[3] < $pts[7]) {
                     if ($pts[2] < $pts[6]) {
                         $this->csimareas .= "{$pts['2']}, {$pts['3']}, {$pts['6']}, {$pts['7']}\"";
                     } else {
                         $this->csimareas .= "{$pts['6']}, {$pts['3']}, {$pts['2']}, {$pts['7']}\"";
                     }
                 } else {
                     if ($pts[2] < $pts[6]) {
                         $this->csimareas .= "{$pts['2']}, {$pts['7']}, {$pts['6']}, {$pts['3']}\"";
                     } else {
                         $this->csimareas .= "{$pts['6']}, {$pts['7']}, {$pts['2']}, {$pts['3']}\"";
                     }
                 }
                 $this->csimareas .= " href=\"" . $this->plots[$j]->csimtargets[$i] . "\"";
                 if (!empty($this->plots[$j]->csimalts[$i])) {
                     $sval = sprintf($this->plots[$j]->csimalts[$i], $this->plots[$j]->coords[0][$i]);
                     $this->csimareas .= " alt=\"{$sval}\"";
                 }
                 $this->csimareas .= ">\r\n";
             }
             $img->Polygon($pts, 4);
         }
         $yt = $yscale->Translate($accy);
         if ($this->show_value) {
             $sval = sprintf($this->show_value_format, $accy);
             $txt = new Text($sval);
             $txt->SetFont($this->show_value_ff, $this->show_value_fs, $this->show_value_fsize);
             $txt->SetColor($this->show_value_color);
             $x = $pts[2] + ($pts[4] - $pts[2]) / 2;
             if ($this->bar_shadow) {
                 $x += $ssh;
             }
             $txt->Pos($x, $yt - $this->show_value_margin);
             $txt->Align("center", "bottom");
             $txt->SetOrientation($this->show_value_angle);
             $txt->Stroke($img);
         }
     }
     return true;
 }
Example #11
0
 function Stroke(&$img, &$xscale, &$yscale)
 {
     $idx = 0;
     $numpoints = count($this->coords[0]);
     if (isset($this->coords[1])) {
         if (count($this->coords[1]) != $numpoints) {
             JpGraphError::RaiseL(2003, count($this->coords[1]), $numpoints);
         } else {
             $exist_x = true;
         }
     } else {
         $exist_x = false;
     }
     if ($this->barcenter) {
         $textadj = 0.5 - $xscale->text_scale_off;
     } else {
         $textadj = 0;
     }
     $startpoint = 0;
     while ($startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint])) {
         ++$startpoint;
     }
     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) {
         $min = $yscale->GetMinVal();
         if ($min > 0 || $this->fillFromMin) {
             $fillmin = $yscale->scale_abs[0];
         } 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) {
             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 ($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->line_weight > 0) {
             $img->SetColor($this->color);
             $img->Polygon($cord);
         }
     }
     if (!empty($this->filledAreas)) {
         $minY = $yscale->Translate($yscale->GetMinVal());
         $factor = $this->step_style ? 4 : 2;
         for ($i = 0; $i < sizeof($this->filledAreas); ++$i) {
             $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];
             $areaCoords[] = $minY;
             if ($this->filledAreas[$i][3]) {
                 $img->SetColor($this->filledAreas[$i][2]);
                 $img->FilledPolygon($areaCoords);
                 $img->SetColor($this->color);
             }
             if ($this->filledAreas[$i][4]) {
                 $img->Polygon($areaCoords);
             } else {
                 $img->Polygon($cord);
             }
             $areaCoords = array();
         }
     }
     if ($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();
         }
     }
 }
Example #12
0
 function Stroke(&$img, &$xscale, &$yscale)
 {
     $pattern = NULL;
     $img->SetLineWeight($this->weight);
     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 {
                 $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;
                 if ($j === 0) {
                     $sp[0] = $pts[6] + 1;
                     $sp[1] = $pts[7];
                     $sp[2] = $pts[6] + $ssh;
                     $sp[3] = $pts[7] - $ssv;
                     $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 (is_array($this->bar_shadow_color)) {
                         $numcolors = count($this->bar_shadow_color);
                         if ($numcolors == 0) {
                             JpGraphError::RaiseL(2013);
                         }
                         $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 ($this->plots[$j]->coords[0][$i] == 0) {
                 continue;
             }
             if ($this->plots[$j]->grad) {
                 $grad = new Gradient($img);
                 $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 ($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);
             }
             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);
             }
             if ($i < count($this->plots[$j]->csimtargets)) {
                 $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]->line_weight);
             $img->Polygon($pts);
             $img->SetLineWeight(1);
         }
         $x = $pts[2] + ($pts[4] - $pts[2]) / 2;
         if ($this->bar_shadow) {
             $x += $ssh;
         }
         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) {
             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 {
                     $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;
 }
Example #13
0
 function Stroke(&$aImg)
 {
     $fillBoxFrameWeight = 1;
     if ($this->hide) {
         return;
     }
     $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
     if ($this->reverse) {
         $this->txtcol = array_reverse($this->txtcol);
     }
     $n = count($this->txtcol);
     if ($n == 0) {
         return;
     }
     $numcolumns = $n > $this->layout_n ? $this->layout_n : $n;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_hsize;
         $colheight[$i] = 0;
     }
     $rows = 0;
     $rowheight[0] = 0;
     for ($i = 0; $i < $n; ++$i) {
         $h = max($this->mark_abs_vsize, $aImg->GetTextHeight($this->txtcol[$i][0])) + $this->ymargin;
         if ($i % $numcolumns == 0) {
             $rows++;
             $rowheight[$rows - 1] = 0;
         }
         $rowheight[$rows - 1] = max($rowheight[$rows - 1], $h);
     }
     $abs_height = 0;
     for ($i = 0; $i < $rows; ++$i) {
         $abs_height += $rowheight[$i];
     }
     $abs_height = max($abs_height, $this->mark_abs_vsize);
     $abs_height += $this->ymargin + 3;
     for ($i = $numcolumns; $i < $n; ++$i) {
         $colwidth[$i % $numcolumns] = max($aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_hsize, $colwidth[$i % $numcolumns]);
     }
     $mtw = 0;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $mtw += $colwidth[$i];
     }
     $abs_width = $mtw + $this->xlmargin;
     if ($this->xabspos === -1 && $this->yabspos === -1) {
         $this->xabspos = $this->xpos * $aImg->width;
         $this->yabspos = $this->ypos * $aImg->height;
     }
     if ($this->halign == "left") {
         $xp = $this->xabspos;
     } elseif ($this->halign == "center") {
         $xp = $this->xabspos - $abs_width / 2;
     } else {
         $xp = $aImg->width - $this->xabspos - $abs_width;
     }
     $yp = $this->yabspos;
     if ($this->valign == "center") {
         $yp -= $abs_height / 2;
     } elseif ($this->valign == "bottom") {
         $yp -= $abs_height;
     }
     $aImg->SetColor($this->color);
     $aImg->SetLineWeight($this->frameweight);
     $aImg->SetLineStyle('solid');
     if ($this->shadow) {
         $aImg->ShadowRectangle($xp, $yp, $xp + $abs_width + $this->shadow_width, $yp + $abs_height + $this->shadow_width, $this->fill_color, $this->shadow_width, $this->shadow_color);
     } else {
         $aImg->SetColor($this->fill_color);
         $aImg->FilledRectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
         $aImg->SetColor($this->color);
         $aImg->Rectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
     }
     $x1 = $xp + $this->mark_abs_hsize + $this->xlmargin;
     $y1 = $yp + $this->ymargin;
     $f2 = round($aImg->GetTextHeight('X') / 2);
     $grad = new Gradient($aImg);
     $patternFactory = null;
     $i = 1;
     $row = 0;
     foreach ($this->txtcol as $p) {
         if (_JPG_DEBUG) {
             $aImg->SetLineWeight(1);
             $aImg->SetColor('red');
             $aImg->SetLineStyle('solid');
             $aImg->Rectangle($xp, $y1, $xp + $abs_width, $y1 + $rowheight[$row]);
         }
         $aImg->SetLineWeight($this->weight);
         $x1 = round($x1);
         $y1 = round($y1);
         if ($p[2] && $p[2]->GetType() > -1) {
             $aImg->SetColor($p[1]);
             if (is_string($p[3]) || $p[3] > 0) {
                 $aImg->SetLineStyle($p[3]);
                 $aImg->StyleLine($x1 - $this->mark_abs_hsize, $y1 + $f2, $x1 + $this->mark_abs_hsize, $y1 + $f2);
             }
             if ($p[2]->GetType() != MARK_IMG) {
                 $p[2]->iFormatCallback = '';
                 $p[2]->iFormatCallback2 = '';
                 if ($p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE) {
                     $p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize) / 2);
                     $p[2]->Stroke($aImg, $x1, $y1 + $f2);
                 } else {
                     $p[2]->SetSize(min($this->mark_abs_vsize, $this->mark_abs_hsize));
                     $p[2]->Stroke($aImg, $x1, $y1 + $f2);
                 }
             }
         } elseif ($p[2] && (is_string($p[3]) || $p[3] > 0)) {
             $aImg->SetColor($p[1]);
             $aImg->SetLineStyle($p[3]);
             $aImg->StyleLine($x1 - 1, $y1 + $f2, $x1 + $this->mark_abs_hsize, $y1 + $f2);
             $aImg->StyleLine($x1 - 1, $y1 + $f2 + 1, $x1 + $this->mark_abs_hsize, $y1 + $f2 + 1);
         } else {
             $color = $p[1];
             $boxsize = min($this->mark_abs_vsize, $this->mark_abs_hsize) + 2;
             $ym = round($y1 + $f2 - $boxsize / 2);
             if ($p[3] < -100) {
                 if ($patternFactory == null) {
                     $patternFactory = new RectPatternFactory();
                 }
                 $prect = $patternFactory->Create($p[1][0], $p[1][1], 1);
                 $prect->SetBackground($p[1][3]);
                 $prect->SetDensity($p[1][2] + 1);
                 $prect->SetPos(new Rectangle($x1, $ym, $boxsize, $boxsize));
                 $prect->Stroke($aImg);
                 $prect = null;
             } else {
                 if (is_array($color) && count($color) == 2) {
                     $grad->FilledRectangle($x1, $ym, $x1 + $boxsize, $ym + $boxsize, $color[0], $color[1], -$p[3]);
                 } else {
                     $aImg->SetColor($p[1]);
                     $aImg->FilledRectangle($x1, $ym, $x1 + $boxsize, $ym + $boxsize);
                 }
                 $aImg->SetColor($this->color);
                 $aImg->SetLineWeight($fillBoxFrameWeight);
                 $aImg->Rectangle($x1, $ym, $x1 + $boxsize, $ym + $boxsize);
             }
         }
         $aImg->SetColor($this->font_color);
         $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
         $aImg->SetTextAlign("left", "top");
         $aImg->StrokeText(round($x1 + $this->mark_abs_hsize + $this->xmargin), $y1, $p[0]);
         if ($p[4] != "") {
             $xe = $x1 + $this->xmargin + $this->mark_abs_hsize + $aImg->GetTextWidth($p[0]);
             $ye = $y1 + max($this->mark_abs_vsize, $aImg->GetTextHeight($p[0]));
             $coords = "{$x1},{$y1},{$xe},{$y1},{$xe},{$ye},{$x1},{$ye}";
             if (!empty($p[4])) {
                 $this->csimareas .= "<area shape=\"poly\" coords=\"{$coords}\" href=\"" . htmlentities($p[4]) . "\"";
                 if (!empty($p[6])) {
                     $this->csimareas .= " target=\"" . $p[6] . "\"";
                 }
                 if (!empty($p[5])) {
                     $tmp = sprintf($p[5], $p[0]);
                     $this->csimareas .= " title=\"{$tmp}\" alt=\"{$tmp}\" ";
                 }
                 $this->csimareas .= " />\n";
             }
         }
         if ($i >= $this->layout_n) {
             $x1 = $xp + $this->mark_abs_hsize + $this->xlmargin;
             $y1 += $rowheight[$row++];
             $i = 1;
         } else {
             $x1 += $colwidth[($i - 1) % $numcolumns];
             ++$i;
         }
     }
 }
Example #14
0
 function Stroke($img, $xscale, $yscale)
 {
     $numpoints = count($this->coords[0]);
     if (isset($this->coords[1])) {
         if (count($this->coords[1]) != $numpoints) {
             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)) {
             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) {
                     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 {
             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;
 }
Example #15
0
 function StrokeBackgroundGrad()
 {
     if ($this->bkg_gradtype < 0) {
         return;
     }
     $grad = new Gradient($this->img);
     if ($this->bkg_gradstyle == BGRAD_PLOT) {
         $xl = $this->img->left_margin;
         $yt = $this->img->top_margin;
         $xr = $xl + $this->img->plotwidth + 1;
         $yb = $yt + $this->img->plotheight;
         $grad->FilledRectangle($xl, $yt, $xr, $yb, $this->bkg_gradfrom, $this->bkg_gradto, $this->bkg_gradtype);
     } else {
         $xl = 0;
         $yt = 0;
         $xr = $xl + $this->img->width - 1;
         $yb = $yt + $this->img->height - 1;
         if ($this->doshadow) {
             $xr -= $this->shadow_width;
             $yb -= $this->shadow_width;
         }
         if ($this->doframe) {
             $yt += $this->frame_weight;
             $yb -= $this->frame_weight;
             $xl += $this->frame_weight;
             $xr -= $this->frame_weight;
         }
         $aa = $this->img->SetAngle(0);
         $grad->FilledRectangle($xl, $yt, $xr, $yb, $this->bkg_gradfrom, $this->bkg_gradto, $this->bkg_gradtype);
         $aa = $this->img->SetAngle($aa);
     }
 }
Example #16
0
 function Stroke(&$img, &$xscale, &$yscale)
 {
     $numpoints = count($this->coords[0]);
     if (isset($this->coords[1])) {
         if (count($this->coords[1]) != $numpoints) {
             JpGraphError::Raise("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 ($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) {
         $cord[] = $xscale->Translate($xs);
         $min = $yscale->GetMinVal();
         if ($min > 0 || $this->fillFromMin) {
             $cord[] = $yscale->Translate($min);
         } else {
             $cord[] = $yscale->Translate(0);
         }
     }
     $xt = $xscale->Translate($xs);
     $yt = $yscale->Translate($this->coords[0][$startpoint]);
     $cord[] = $xt;
     $cord[] = $yt;
     $yt_old = $yt;
     $this->value->Stroke($img, $this->coords[0][$startpoint], $xt, $yt);
     $img->SetColor($this->color);
     $img->SetLineWeight($this->weight);
     $img->SetLineStyle($this->line_style);
     for ($pnts = $startpoint + 1; $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]);
         $y = $this->coords[0][$pnts];
         if ($this->step_style && is_numeric($y)) {
             $img->StyleLineTo($xt, $yt_old);
             $img->StyleLineTo($xt, $yt);
             $cord[] = $xt;
             $cord[] = $yt_old;
             $cord[] = $xt;
             $cord[] = $yt;
         } else {
             if (is_numeric($y) || is_string($y) && $y != "-") {
                 $tmp1 = $this->coords[0][$pnts];
                 $tmp2 = $this->coords[0][$pnts - 1];
                 if (is_numeric($tmp1) && (is_numeric($tmp2) || $tmp2 == "-")) {
                     $img->StyleLineTo($xt, $yt);
                 } else {
                     $img->SetStartPoint($xt, $yt);
                 }
                 if (is_numeric($tmp1) && (is_numeric($tmp2) || $tmp2 == "-" || $this->filled && $tmp2 == '')) {
                     $cord[] = $xt;
                     $cord[] = $yt;
                 }
             }
         }
         $yt_old = $yt;
         $this->StrokeDataValue($img, $this->coords[0][$pnts], $xt, $yt);
     }
     if ($this->filled) {
         $cord[] = $xt;
         if ($min > 0 || $this->fillFromMin) {
             $cord[] = $yscale->Translate($min);
         } else {
             $cord[] = $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->line_weight > 0) {
             $img->SetColor($this->color);
             $img->Polygon($cord);
         }
     }
     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.
             // TODO: The behaviour is undefined if the line does not have
             // any line at the position of the area.
             if ($this->filledAreas[$i][4]) {
                 $img->Polygon($areaCoords);
             } else {
                 $img->Polygon($cord);
             }
             $areaCoords = array();
         }
     }
     if ($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])) {
                 $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();
             $this->StrokeDataValue($img, $this->coords[0][$pnts], $xt, $yt);
         }
     }
 }
Example #17
0
 function Stroke(&$aImg)
 {
     if ($this->hide) {
         return;
     }
     $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
     if ($this->reverse) {
         $this->txtcol = array_reverse($this->txtcol);
     }
     $n = count($this->txtcol);
     if ($n == 0) {
         return;
     }
     // Find out the max width and height of each column to be able
     // to size the legend box.
     $numcolumns = $n > $this->layout_n ? $this->layout_n : $n;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_size;
         $colheight[$i] = 0;
     }
     // Find our maximum height in each row
     $rows = -1;
     for ($i = 0; $i < $n; ++$i) {
         $h = max($this->mark_abs_size, $aImg->GetTextHeight($this->txtcol[$i][0])) + $this->ymargin;
         if ($i % $numcolumns == 0) {
             $rows++;
             $rowheight[$rows] = 0;
         }
         $rowheight[$rows] = max($rowheight[$rows], $h);
     }
     $abs_height = 0;
     for ($i = 0; $i <= $rows; ++$i) {
         $abs_height += $rowheight[$i];
     }
     // Make sure that the height is at least as high as mark size + ymargin
     $abs_height = max($abs_height, $this->mark_abs_size + $this->ymargin);
     $abs_height += 2 * $this->ymargin + $this->mark_abs_size / 2;
     // Find out the maximum width in each column
     for ($i = $numcolumns; $i < $n; ++$i) {
         $colwidth[$i % $numcolumns] = max($aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_size, $colwidth[$i % $numcolumns]);
     }
     // Get the total width
     $mtw = 0;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $mtw += $colwidth[$i];
     }
     // Find out maximum width we need for legend box
     $abs_width = $mtw + $this->xlmargin;
     if ($this->xabspos === -1 && $this->yabspos === -1) {
         $this->xabspos = $this->xpos * $aImg->width;
         $this->yabspos = $this->ypos * $aImg->height;
     }
     // Positioning of the legend box
     if ($this->halign == "left") {
         $xp = $this->xabspos;
     } elseif ($this->halign == "center") {
         $xp = $this->xabspos - $abs_width / 2;
     } else {
         $xp = $aImg->width - $this->xabspos - $abs_width;
     }
     $yp = $this->yabspos;
     if ($this->valign == "center") {
         $yp -= $abs_height / 2;
     } elseif ($this->valign == "bottom") {
         $yp -= $abs_height;
     }
     // Stroke legend box
     $aImg->SetColor($this->color);
     $aImg->SetLineWeight($this->frameweight);
     $aImg->SetLineStyle('solid');
     if ($this->shadow) {
         $aImg->ShadowRectangle($xp, $yp, $xp + $abs_width + $this->shadow_width, $yp + $abs_height + $this->shadow_width, $this->fill_color, $this->shadow_width, $this->shadow_color);
     } else {
         $aImg->SetColor($this->fill_color);
         $aImg->FilledRectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
         $aImg->SetColor($this->color);
         $aImg->Rectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
     }
     // x1,y1 is the position for the legend mark
     $aImg->SetLineWeight($this->weight);
     $x1 = $xp + $this->mark_abs_size + $this->xlmargin;
     $y1 = $yp + $this->mark_abs_size / 2 + $this->ymargin / 3;
     $f2 = round($aImg->GetTextHeight('X') / 2);
     $grad = new Gradient($aImg);
     // Now stroke each legend in turn
     // Each plot has added the following information to  the legend
     // p[0] = Legend text
     // p[1] = Color,
     // p[2] = For markers a reference to the PlotMark object
     // p[3] = For lines the line style, for gradient the negative gradient style
     // p[4] = CSIM target
     // p[5] = CSIM Alt text
     $i = 1;
     $row = 0;
     foreach ($this->txtcol as $p) {
         $x1 = round($x1);
         $y1 = round($y1);
         if ($p[2] != "" && $p[2]->GetType() > -1) {
             // Make a plot mark legend
             $aImg->SetColor($p[1]);
             if (is_string($p[3]) || $p[3] > 0) {
                 $aImg->SetLineStyle($p[3]);
                 $aImg->StyleLine($x1 - $this->mark_abs_size, $y1 + $f2, $x1 + $this->mark_abs_size, $y1 + $f2);
             }
             // Stroke a mark with the standard size
             // (As long as it is not an image mark )
             if ($p[2]->GetType() != MARK_IMG) {
                 $p[2]->iFormatCallback = '';
                 // Since size for circles is specified as the radius
                 // this means that we must half the size to make the total
                 // width behave as the other marks
                 if ($p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE) {
                     $p[2]->SetSize($this->mark_abs_size / 2);
                     $p[2]->Stroke($aImg, $x1, $y1 + $f2);
                 } else {
                     $p[2]->SetSize($this->mark_abs_size);
                     $p[2]->Stroke($aImg, $x1, $y1 + $f2);
                 }
             }
         } elseif ($p[2] != "" && (is_string($p[3]) || $p[3] > 0)) {
             // Draw a styled line
             $aImg->SetColor($p[1]);
             $aImg->SetLineStyle($p[3]);
             $aImg->StyleLine($x1 - 1, $y1 + $f2, $x1 + $this->mark_abs_size, $y1 + $f2);
             $aImg->StyleLine($x1 - 1, $y1 + $f2 + 1, $x1 + $this->mark_abs_size, $y1 + $f2 + 1);
         } else {
             // Draw a colored box
             $color = $p[1];
             $ym = round($y1 + $f2 - $this->mark_abs_size / 2);
             if (is_array($color) && count($color) == 2) {
                 // The client want a gradient color
                 $grad->FilledRectangle($x1, $ym, $x1 + $this->mark_abs_size, $ym + $this->mark_abs_size, $color[0], $color[1], -$p[3]);
             } else {
                 $aImg->SetColor($p[1]);
                 $aImg->FilledRectangle($x1, $ym, $x1 + $this->mark_abs_size, $ym + $this->mark_abs_size);
             }
             $aImg->SetColor($this->color);
             $aImg->SetLineWeight($this->weight);
             $aImg->Rectangle($x1, $ym, $x1 + $this->mark_abs_size, $ym + $this->mark_abs_size);
         }
         $aImg->SetColor($this->font_color);
         $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
         $aImg->SetTextAlign("left", "top");
         $aImg->StrokeText(round($x1 + $this->mark_abs_size + $this->xmargin), $y1, $p[0]);
         // Add CSIM for Legend if defined
         if ($p[4] != "") {
             $xe = $x1 + $this->xmargin + $this->mark_abs_size + $aImg->GetTextWidth($p[0]);
             $ye = $y1 + max($this->mark_abs_size, $aImg->GetTextHeight($p[0]));
             $coords = "{$x1},{$y1},{$xe},{$y1},{$xe},{$ye},{$x1},{$ye}";
             if (!empty($p[4])) {
                 $this->csimareas .= "<area shape=\"poly\" coords=\"{$coords}\" href=\"" . $p[4] . "\"";
                 if (!empty($p[5])) {
                     $tmp = sprintf($p[5], $p[0]);
                     $this->csimareas .= " alt=\"{$tmp}\" title=\"{$tmp}\"";
                 }
                 $this->csimareas .= ">\n";
             }
         }
         if ($i >= $this->layout_n) {
             $x1 = $xp + $this->mark_abs_size + $this->xlmargin;
             //$y1 += max($aImg->GetTextHeight($p[0]),$this->mark_abs_size)+$this->ymargin;
             $y1 += $rowheight[$row++];
             $i = 1;
         } else {
             $x1 += $colwidth[($i - 1) % $numcolumns];
             ++$i;
         }
     }
 }
Example #18
0
 function Stroke(&$aImg)
 {
     if ($this->hide) {
         return;
     }
     $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
     $n = count($this->txtcol);
     if ($n == 0) {
         return;
     }
     // Find out the max width and height of each column to be able
     // to size the legend box.
     $numcolumns = $n > $this->layout_n ? $this->layout_n : $n;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_size;
         $colheight[$i] = 0;
     }
     // Find our maximum height in each row
     $rows = -1;
     for ($i = 0; $i < $n; ++$i) {
         $h = max($this->mark_abs_size, $aImg->GetTextHeight($this->txtcol[$i][0])) + $this->ymargin;
         if ($i % $numcolumns == 0) {
             $rows++;
             $rowheight[$rows] = 0;
         }
         $rowheight[$rows] = max($rowheight[$rows], $h);
     }
     $abs_height = 0;
     for ($i = 0; $i <= $rows; ++$i) {
         $abs_height += $rowheight[$i];
     }
     // Make damn sure that the height is at least as high as mark size + ymargin
     $abs_height = max($abs_height, $this->mark_abs_size + $this->ymargin);
     $abs_height += 2 * $this->ymargin;
     // Find out the maximum width in each column
     for ($i = $numcolumns; $i < $n; ++$i) {
         $colwidth[$i % $numcolumns] = max($aImg->GetTextWidth($this->txtcol[$i][0]) + 2 * $this->xmargin + 2 * $this->mark_abs_size, $colwidth[$i % $numcolumns]);
     }
     // Get the total width
     $mtw = 0;
     for ($i = 0; $i < $numcolumns; ++$i) {
         $mtw += $colwidth[$i];
     }
     // Find out maximum width we need for legend box
     $abs_width = $mtw + $this->xmargin;
     if ($this->xabspos === -1 && $this->yabspos === -1) {
         $this->xabspos = $this->xpos * $aImg->width;
         $this->yabspos = $this->ypos * $aImg->height;
     }
     // Positioning of the legend box
     if ($this->halign == "left") {
         $xp = $this->xabspos;
     } elseif ($this->halign == "center") {
         $xp = $this->xabspos - $abs_width / 2;
     } else {
         $xp = $aImg->width - $this->xabspos - $abs_width;
     }
     $yp = $this->yabspos;
     if ($this->valign == "center") {
         $yp -= $abs_height / 2;
     } elseif ($this->valign == "bottom") {
         $yp -= $abs_height;
     }
     // Stroke legend box
     $aImg->SetColor($this->color);
     $aImg->SetLineWeight($this->frameweight);
     if ($this->shadow) {
         $aImg->ShadowRectangle($xp, $yp, $xp + $abs_width + $this->shadow_width, $yp + $abs_height + $this->shadow_width, $this->fill_color, $this->shadow_width, $this->shadow_color);
     } else {
         $aImg->SetColor($this->fill_color);
         $aImg->FilledRectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
         $aImg->SetColor($this->color);
         $aImg->Rectangle($xp, $yp, $xp + $abs_width, $yp + $abs_height);
     }
     // x1,y1 is the position for the legend mark
     $aImg->SetLineWeight($this->weight);
     $x1 = $xp + $this->mark_abs_size / 2 + 3;
     $y1 = $yp + $this->mark_abs_size / 2 + $this->ymargin / 2;
     $f2 = round($aImg->GetTextHeight('X') / 2);
     $grad = new Gradient($aImg);
     // Now stroke each legend in turn
     $i = 1;
     $row = 0;
     foreach ($this->txtcol as $p) {
         $x1 = round($x1);
         $y1 = round($y1);
         if ($p[2] != "" && $p[2]->GetType() > -1) {
             // Make a plot mark legend
             $aImg->SetColor($p[1]);
             if ($p[3] > 0) {
                 $aImg->SetLineStyle($p[3]);
                 $aImg->StyleLine($x1 - 3, $y1 + $f2, $x1 + $this->mark_abs_size + 3, $y1 + $f2);
             }
             // Stroke a mark with the standard size
             // (As long as it is not an image mark )
             if ($p[2]->GetType() != MARK_IMG) {
                 $p[2]->iFormatCallback = '';
                 if ($this->mark_abs_size === _DEFAULT_LPM_SIZE) {
                     $p[2]->SetDefaultWidth();
                 } else {
                     $p[2]->SetSize($this->mark_abs_size);
                 }
                 $p[2]->Stroke($aImg, $x1 + $this->mark_abs_size / 2, $y1 + $f2);
             }
         } elseif ($p[2] != "" && (is_string($p[3]) || $p[3] > 0)) {
             // Draw a styled line
             $aImg->SetColor($p[1]);
             $aImg->SetLineStyle($p[3]);
             $aImg->StyleLine($x1, $y1 + $f2, $x1 + $this->mark_abs_size, $y1 + $f2);
             $aImg->StyleLine($x1, $y1 + $f2 + 1, $x1 + $this->mark_abs_size, $y1 + $f2 + 1);
         } else {
             // Draw a colored box
             $color = $p[1];
             $ym = round($y1 + $f2 - $this->mark_abs_size / 2);
             if (is_array($color) && count($color) == 3) {
                 // The client want a gradient color
                 $grad->FilledRectangle($x1, $ym, $x1 + $this->mark_abs_size, $ym + $this->mark_abs_size, $color[0], $color[1], $color[2]);
             } else {
                 $aImg->SetColor($p[1]);
                 $aImg->FilledRectangle($x1, $ym, $x1 + $this->mark_abs_size, $ym + $this->mark_abs_size);
             }
             $aImg->SetColor($this->color);
             $aImg->SetLineWeight($this->weight);
             $aImg->Rectangle($x1, $ym, $x1 + $this->mark_abs_size, $ym + $this->mark_abs_size);
         }
         $aImg->SetColor($this->font_color);
         $aImg->SetFont($this->font_family, $this->font_style, $this->font_size);
         $aImg->SetTextAlign("left", "top");
         $aImg->StrokeText(round($x1 + $this->mark_abs_size + $this->xmargin * 1.5), $y1, $p[0]);
         // Add CSIM for Legend if defined
         if ($p[4] != "") {
             $xe = $x1 + $this->xmargin + 2 * $this->mark_abs_size + $aImg->GetTextWidth($p[0]);
             $ye = $y1 + max($this->mark_abs_size, $aImg->GetTextHeight($p[0]));
             $coords = "{$x1},{$y1},{$xe},{$y1},{$xe},{$ye},{$x1},{$ye}";
             $this->csimareas .= "<area shape=\"poly\" coords=\"{$coords}\" href=\"" . $p[4] . "\"";
             if (!empty($p[5])) {
                 $tmp = sprintf($p[5], $p[0]);
                 $this->csimareas .= " alt=\"{$tmp}\" title=\"{$tmp}\"";
             }
             $this->csimareas .= ">\n";
         }
         if ($i >= $this->layout_n) {
             $x1 = $xp + $this->mark_abs_size / 2 + 3;
             //$y1 += max($aImg->GetTextHeight($p[0]),$this->mark_abs_size)+$this->ymargin;
             $y1 += $rowheight[$row++];
             $i = 1;
         } else {
             $x1 += $colwidth[($i - 1) % $numcolumns];
             ++$i;
         }
     }
 }