setMargin(5); $this->setLabelMarginLeft(30); $this->setLabelMarginRight(30); $this->setLabelMarginTop(50); $this->setLabelMarginBottom(30); $this->setLabelMarginCenter(20); $this->setPieRatio(0.55); $this->labelBoxWidth = 15; $this->labelBoxHeight = 15; } /** * Set the ratio of the pie image over the legend * * @access public * @param double ratio (value between 0 and 1) */ function setPieRatio($pieRatio) { $this->pieRatio = $pieRatio; } /** * Compare two sampling point values, order from biggest to lowest value * * @access private * @param double first value * @param double second value * @return integer result of the comparison */ function sortPie($v1, $v2) { return $v1[0] == $v2[0] ? 0 : $v1[0] > $v2[0] ? -1 : 1; } /** * Compute pie values in percentage and sort them * * @access private */ function computePercent() { $this->total = 0; $this->percent = array(); foreach($this->point as $point) $this->total += $point->getY(); // TODO assert (total != 0) foreach($this->point as $point) { $percent = 100 * $point->getY() / $this->total; array_push($this->percent, array($percent, $point)); } usort($this->percent, array("PieChart", "sortPie")); } /** * Set the margin between the pie image and the legend * * @access public * @param integer margin value in pixels */ function setLabelMarginCenter($labelMarginCenter) { $this->labelMarginCenter = $labelMarginCenter; } /** * Draw a gray box with nice borders * * @access private * @param integer top left coordinate (x) * @param integer top left coordinate (y) * @param integer bottom right coordinate (x) * @param integer bottom right coordinate (y) */ function outlinedBox($x1, $y1, $x2, $y2) { imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->axisColor1); imagerectangle($this->img, $x1, $y1, $x1 + 1, $y1 + 1, $this->axisColor2); imagerectangle($this->img, $x2 - 1, $y1, $x2, $y1 + 1, $this->axisColor2); imagerectangle($this->img, $x1, $y2 - 1, $x1 + 1, $y2, $this->axisColor2); imagerectangle($this->img, $x2 - 1, $y2 - 1, $x2, $y2, $this->axisColor2); } /** * Compute image layout * * @access private */ function computeLabelMargin() { $graphWidth = $this->width - $this->margin * 2 - $this->labelMarginLeft - $this->labelMarginCenter - $this->labelMarginRight; $this->pieTLX = $this->margin + $this->labelMarginLeft; $this->pieTLY = $this->margin + $this->labelMarginTop; $this->pieBRX = $this->pieTLX + $graphWidth * $this->pieRatio; $this->pieBRY = $this->height - $this->margin - $this->labelMarginBottom; $this->pieCenterX = $this->pieTLX + ($this->pieBRX - $this->pieTLX) / 2; $this->pieCenterY = $this->pieTLY + ($this->pieBRY - $this->pieTLY) / 2; $this->pieWidth = round(($this->pieBRX - $this->pieTLX) * 4 / 5); $this->pieHeight = round(($this->pieBRY - $this->pieTLY) * 3.7 / 5); $this->pieDepth = round($this->pieWidth * 0.05); $this->labelTLX = $this->pieBRX + $this->labelMarginCenter; $this->labelTLY = $this->pieTLY; $this->labelBRX = $this->pieTLX + $this->labelMarginCenter + $graphWidth; $this->labelBRY = $this->pieBRY; } /** * Creates the pie chart image * * @access private */ function createImage() { parent::createImage(); $pieColors = array( array(2, 78, 0), array(148, 170, 36), array(233, 191, 49), array(240, 127, 41), array(243, 63, 34), array(190, 71, 47), array(135, 81, 60), array(128, 78, 162), array(121, 75, 255), array(142, 165, 250), array(162, 254, 239), array(137, 240, 166), array(104, 221, 71), array(98, 174, 35), array(93, 129, 1) ); $this->pieColor = array(); $this->pieShadowColor = array(); $shadowFactor = 0.5; foreach($pieColors as $colorRGB) { list($red, $green, $blue) = $colorRGB; $color = imagecolorallocate($this->img, $red, $green, $blue); $shadowColor = imagecolorallocate($this->img, $red * $shadowFactor, $green * $shadowFactor, $blue * $shadowFactor); array_push($this->pieColor, $color); array_push($this->pieShadowColor, $shadowColor); } $this->axisColor1 = imagecolorallocate($this->img, 201, 201, 201); $this->axisColor2 = imagecolorallocate($this->img, 158, 158, 158); $this->aquaColor1 = imagecolorallocate($this->img, 242, 242, 242); $this->aquaColor2 = imagecolorallocate($this->img, 231, 231, 231); $this->aquaColor3 = imagecolorallocate($this->img, 239, 239, 239); $this->aquaColor4 = imagecolorallocate($this->img, 253, 253, 253); // Legend box $this->outlinedBox($this->pieTLX, $this->pieTLY, $this->pieBRX, $this->pieBRY); // Aqua-like background $aquaColor = Array($this->aquaColor1, $this->aquaColor2, $this->aquaColor3, $this->aquaColor4); for($i = $this->pieTLY + 2; $i < $this->pieBRY - 1; $i++) imageline($this->img, $this->pieTLX + 2, $i, $this->pieBRX - 2, $i, $aquaColor[($i + 3) % 4]); } /** * Print legend * * @access private */ function printLabel() { $i = 0; $boxX1 = $this->labelTLX + $this->margin; $boxX2 = $boxX1 + $this->labelBoxWidth; foreach($this->percent as $a) { list($percent, $point) = $a; $legend = $point->getX(); $color = $this->pieColor[$i % count($this->pieColor)]; $boxY1 = $this->labelTLY + $this->margin + $i * ($this->labelBoxHeight + $this->margin); $boxY2 = $boxY1 + $this->labelBoxHeight; $this->outlinedBox($boxX1, $boxY1, $boxX2, $boxY2); imagefilledrectangle($this->img, $boxX1 + 2, $boxY1 + 2, $boxX2 - 2, $boxY2 - 2, $color); $this->text->printText($this->img, $boxX2 + $this->margin, $boxY1 + $this->labelBoxHeight / 2, $this->textColor, $legend, $this->text->fontCondensed, $this->text->VERTICAL_CENTER_ALIGN); $i++; } } /** * Draw a 2D disc * * @access private * @param integer center coordinate (y) * @param array colors for each portion * @param bitfield drawing mode */ function drawDisc($cy, $colorArray, $mode) { $i = 0; $angle1 = 0; $percentTotal = 0; foreach($this->percent as $a) { list($percent, $point) = $a; $color = $colorArray[$i % count($colorArray)]; $percentTotal += $percent; $angle2 = $percentTotal * 360 / 100; imagefilledarc($this->img, $this->pieCenterX, $cy, $this->pieWidth, $this->pieHeight, $angle1, $angle2, $color, $mode); $angle1 = $angle2; $i++; } } /** * Print the percentage text * * @access private */ function drawPercent() { $angle1 = 0; $percentTotal = 0; foreach($this->percent as $a) { list($percent, $point) = $a; $percentTotal += $percent; $angle2 = $percentTotal * 2 * M_PI / 100; $angle = $angle1 + ($angle2 - $angle1) / 2; $text = number_format($percent) . "%"; $x = cos($angle) * ($this->pieWidth + 35) / 2 + $this->pieCenterX; $y = sin($angle) * ($this->pieHeight + 35) / 2 + $this->pieCenterY; $this->text->printText($this->img, $x, $y, $this->textColor, $text, $this->text->fontCondensed, $this->text->HORIZONTAL_CENTER_ALIGN | $this->text->VERTICAL_CENTER_ALIGN); $angle1 = $angle2; } } /** * Print the pie chart * * @access private */ function printPie() { // Silhouette for ($cy = $this->pieCenterY + $this->pieDepth / 2; $cy >= $this->pieCenterY - $this->pieDepth / 2; $cy--) $this->drawDisc($cy, $this->pieShadowColor, IMG_ARC_EDGED | IMG_ARC_NOFILL); // Top $this->drawDisc($this->pieCenterY - $this->pieDepth / 2, $this->pieColor, IMG_ARC_FILL); // Top Outline $this->drawPercent(); } /** * Render the chart image * * @access public * @param string name of the file to render the image to (optional) */ function render($fileName = null) { $this->computeLabelMargin(); $this->computePercent(); $this->createImage(); $this->printLogo(); $this->printTitle(); $this->printPie(); $this->printLabel(); if(isset($fileName)) imagepng($this->img, $fileName); else imagepng($this->img); } } ?>