function drawBasicPieGraph(&$Data, &$DataDescription, $XPos, $YPos, $Radius = 100, $DrawLabels = PIE_NOLABEL, $R = 255, $G = 255, $B = 255, $Decimals = 0) { /* Validate the Data and DataDescription array */ $this->validateDataDescription("drawBasicPieGraph", $DataDescription, FALSE); $this->validateData("drawBasicPieGraph", $Data); /* Determine pie sum */ $Series = 0; $PieSum = 0; foreach ($DataDescription["Values"] as $Key2 => $ColName) { if ($ColName != $DataDescription["Position"]) { $Series++; foreach ($Data as $Key => $Values) { if (isset($Data[$Key][$ColName])) { $PieSum = $PieSum + $Data[$Key][$ColName]; } $iValues[] = $Data[$Key][$ColName]; $iLabels[] = $Data[$Key][$DataDescription["Position"]]; } } } /* Validate serie */ if ($Series != 1) { RaiseFatal("Pie chart can only accept one serie of data."); } if ($PieSum == 0) { $PieSum = 0.1; } $SpliceRatio = 360 / $PieSum; $SplicePercent = 100 / $PieSum; /* Calculate all polygons */ $Angle = 0; $TopPlots = ""; foreach ($iValues as $Key => $Value) { $TopPlots[$Key][] = $XPos; $TopPlots[$Key][] = $YPos; /* Process labels position & size */ if (!($DrawLabels == PIE_NOLABEL)) { $TAngle = $Angle + $Value * $SpliceRatio / 2; if ($DrawLabels == PIE_PERCENTAGE) { $Caption = floor($Value * pow(10, $Decimals) * $SplicePercent) / pow(10, $Decimals) . "%"; } elseif ($DrawLabels == PIE_LABELS) { $Caption = $iLabels[$Key]; } $TX = cos($TAngle * 3.1418 / 180) * ($Radius + 10) + $XPos; $TY = sin($TAngle * 3.1418 / 180) * ($Radius + 10) + $YPos + 4; if ($TAngle > 90 && $TAngle < 270) { $Position = imageftbbox($this->FontSize, 0, $this->FontName, $Caption); $TextWidth = $Position[2] - $Position[0]; $TX = $TX - $TextWidth; } $C_TextColor = imagecolorallocate($this->Picture, 70, 70, 70); imagettftext($this->Picture, $this->FontSize, 0, $TX, $TY, $C_TextColor, $this->FontName, $Caption); } /* Process pie slices */ for ($iAngle = $Angle; $iAngle <= $Angle + $Value * $SpliceRatio; $iAngle = $iAngle + 0.5) { $TopX = cos($iAngle * 3.1418 / 180) * $Radius + $XPos; $TopY = sin($iAngle * 3.1418 / 180) * $Radius + $YPos; $TopPlots[$Key][] = $TopX; $TopPlots[$Key][] = $TopY; } $TopPlots[$Key][] = $XPos; $TopPlots[$Key][] = $YPos; $Angle = $iAngle; } $PolyPlots = $TopPlots; /* Set array values type to float --- PHP Bug with imagefilledpolygon casting to integer */ foreach ($TopPlots as $Key => $Value) { foreach ($TopPlots[$Key] as $Key2 => $Value2) { settype($TopPlots[$Key][$Key2], "float"); } } /* Draw Top polygons */ foreach ($PolyPlots as $Key => $Value) { $C_GraphLo = imagecolorallocate($this->Picture, $this->Palette[$Key]["R"], $this->Palette[$Key]["G"], $this->Palette[$Key]["B"]); imagefilledpolygon($this->Picture, $PolyPlots[$Key], (count($PolyPlots[$Key]) + 1) / 2, $C_GraphLo); } $this->drawCircle($XPos - 0.5, $YPos - 0.5, $Radius, $R, $G, $B); $this->drawCircle($XPos - 0.5, $YPos - 0.5, $Radius + 0.5, $R, $G, $B); /* Draw Top polygons */ foreach ($TopPlots as $Key => $Value) { for ($j = 0; $j <= count($TopPlots[$Key]) - 4; $j = $j + 2) { $this->drawLine($TopPlots[$Key][$j], $TopPlots[$Key][$j + 1], $TopPlots[$Key][$j + 2], $TopPlots[$Key][$j + 3], $R, $G, $B); } } }
function drawPieGraph(&$Data, &$DataDescription, $XPos, $YPos, $Radius = 100, $DrawLabels = PIE_NOLABEL, $EnhanceColors = TRUE, $Skew = 60, $SpliceHeight = 20, $SpliceDistance = 0, $Decimals = 0) { /* Validate the Data and DataDescription array */ $this->validateDataDescription("drawPieGraph", $DataDescription, FALSE); $this->validateData("drawPieGraph", $Data); /* Determine pie sum */ $Series = 0; $PieSum = 0; $rPieSum = 0; foreach ($DataDescription["Values"] as $Key2 => $ColName) { if ($ColName != $DataDescription["Position"]) { $Series++; foreach ($Data as $Key => $Values) { if (isset($Data[$Key][$ColName])) { if ($Data[$Key][$ColName] == 0) { $PieSum++; $iValues[] = 1; $rValues[] = 0; } else { $PieSum += $Data[$Key][$ColName]; $iValues[] = $Data[$Key][$ColName]; $iLabels[] = $Data[$Key][$DataDescription["Position"]]; $rValues[] = $Data[$Key][$ColName]; $rPieSum += $Data[$Key][$ColName]; } } } } } /* Validate serie */ if ($Series != 1) { RaiseFatal("Pie chart can only accept one serie of data."); } $SpliceDistanceRatio = $SpliceDistance; $SkewHeight = $Radius * $Skew / 100; $SpliceRatio = (360 - $SpliceDistanceRatio * count($iValues)) / $PieSum; $SplicePercent = 100 / $PieSum; $rSplicePercent = 100 / $rPieSum; /* Calculate all polygons */ $Angle = 0; $TopPlots = ""; $BotPlots = ""; $CDev = 5; foreach ($iValues as $Key => $Value) { $XCenterPos = cos(($Angle - $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $XPos; $YCenterPos = sin(($Angle - $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $YPos; $XCenterPos2 = cos(($Angle + $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $XPos; $YCenterPos2 = sin(($Angle + $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $YPos; $TopPlots[$Key][] = $XCenterPos; $BotPlots[$Key][] = $XCenterPos; $TopPlots[$Key][] = $YCenterPos; $BotPlots[$Key][] = $YCenterPos + $SpliceHeight; /* Process labels position & size */ if (!($DrawLabels == PIE_NOLABEL)) { $TAngle = $Angle + $Value * $SpliceRatio / 2; if ($DrawLabels == PIE_PERCENTAGE) { $Caption = floor($rValues[$Key] * pow(10, $Decimals) * $rSplicePercent) / pow(10, $Decimals) . "%"; } elseif ($DrawLabels == PIE_LABELS) { $Caption = $iLabels[$Key]; } $TX = cos($TAngle * 3.1418 / 180) * ($Radius + 10) + $XPos; if ($TAngle > 0 && $TAngle < 180) { $TY = sin($TAngle * 3.1418 / 180) * ($SkewHeight + 10) + $YPos + $SpliceHeight + 4; } else { $TY = sin($TAngle * 3.1418 / 180) * ($SkewHeight + 10) + $YPos + 4; } if ($TAngle > 90 && $TAngle < 270) { $Position = imageftbbox($this->FontSize, 0, $this->FontName, $Caption); $TextWidth = $Position[2] - $Position[0]; $TX = $TX - $TextWidth; } $C_TextColor = imagecolorallocate($this->Picture, 70, 70, 70); imagettftext($this->Picture, $this->FontSize, 0, $TX, $TY, $C_TextColor, $this->FontName, $Caption); } /* Process pie slices */ for ($iAngle = $Angle; $iAngle <= $Angle + $Value * $SpliceRatio; $iAngle = $iAngle + 0.5) { $TopX = cos($iAngle * 3.1418 / 180) * $Radius + $XPos; $TopY = sin($iAngle * 3.1418 / 180) * $SkewHeight + $YPos; $TopPlots[$Key][] = $TopX; $BotPlots[$Key][] = $TopX; $TopPlots[$Key][] = $TopY; $BotPlots[$Key][] = $TopY + $SpliceHeight; } $TopPlots[$Key][] = $XCenterPos2; $BotPlots[$Key][] = $XCenterPos2; $TopPlots[$Key][] = $YCenterPos2; $BotPlots[$Key][] = $YCenterPos2 + $SpliceHeight; $Angle = $iAngle + $SpliceDistanceRatio; } /* Draw Bottom polygons */ foreach ($iValues as $Key => $Value) { $C_GraphLo = $this->AllocateColor($this->Picture, $this->Palette[$Key]["R"], $this->Palette[$Key]["G"], $this->Palette[$Key]["B"], -20); imagefilledpolygon($this->Picture, $BotPlots[$Key], (count($BotPlots[$Key]) + 1) / 2, $C_GraphLo); for ($j = 0; $j <= count($BotPlots[$Key]) - 4; $j = $j + 2) { $this->drawLine($BotPlots[$Key][$j], $BotPlots[$Key][$j + 1], $BotPlots[$Key][$j + 2], $BotPlots[$Key][$j + 3], $this->Palette[$Key]["R"] - 20, $this->Palette[$Key]["G"] - 20, $this->Palette[$Key]["B"] - 20); } } /* Draw pie layers */ if ($EnhanceColors) { $ColorRatio = 30 / $SpliceHeight; } else { $ColorRatio = 25 / $SpliceHeight; } for ($i = $SpliceHeight - 1; $i >= 1; $i--) { foreach ($iValues as $Key => $Value) { $C_GraphLo = $this->AllocateColor($this->Picture, $this->Palette[$Key]["R"], $this->Palette[$Key]["G"], $this->Palette[$Key]["B"], -10); $Plots = ""; $Plot = 0; foreach ($TopPlots[$Key] as $Key2 => $Value2) { $Plot++; if ($Plot % 2 == 1) { $Plots[] = $Value2; } else { $Plots[] = $Value2 + $i; } } imagefilledpolygon($this->Picture, $Plots, (count($Plots) + 1) / 2, $C_GraphLo); $Index = count($Plots); $ColorFactor = -20 + ($SpliceHeight - $i) * $ColorRatio; $this->drawAntialiasPixel($Plots[0], $Plots[1], $this->Palette[$Key]["R"] + $ColorFactor, $this->Palette[$Key]["G"] + $ColorFactor, $this->Palette[$Key]["B"] + $ColorFactor); $this->drawAntialiasPixel($Plots[2], $Plots[3], $this->Palette[$Key]["R"] + $ColorFactor, $this->Palette[$Key]["G"] + $ColorFactor, $this->Palette[$Key]["B"] + $ColorFactor); $this->drawAntialiasPixel($Plots[$Index - 4], $Plots[$Index - 3], $this->Palette[$Key]["R"] + $ColorFactor, $this->Palette[$Key]["G"] + $ColorFactor, $this->Palette[$Key]["B"] + $ColorFactor); } } /* Draw Top polygons */ for ($Key = count($iValues) - 1; $Key >= 0; $Key--) { $C_GraphLo = $this->AllocateColor($this->Picture, $this->Palette[$Key]["R"], $this->Palette[$Key]["G"], $this->Palette[$Key]["B"]); imagefilledpolygon($this->Picture, $TopPlots[$Key], (count($TopPlots[$Key]) + 1) / 2, $C_GraphLo); if ($EnhanceColors) { $En = 10; } else { $En = 5; } for ($j = 0; $j <= count($TopPlots[$Key]) - 4; $j = $j + 2) { $this->drawLine($TopPlots[$Key][$j], $TopPlots[$Key][$j + 1], $TopPlots[$Key][$j + 2], $TopPlots[$Key][$j + 3], $this->Palette[$Key]["R"] + $En, $this->Palette[$Key]["G"] + $En, $this->Palette[$Key]["B"] + $En); } } }
/** * This function draw a pseudo-3D pie chart */ function drawPieGraph($Data, $DataDescription, $XPos, $YPos, $Radius = 100, $DrawLabels = PIE_NOLABEL, $EnhanceColors = TRUE, $Skew = 60, $SpliceHeight = 20, $SpliceDistance = 0, $Decimals = 0) { /* Validate the Data and DataDescription array */ $this->validateDataDescription("drawPieGraph", $DataDescription, FALSE); $this->validateData("drawPieGraph", $Data); /* Determine pie sum */ $Series = 0; $PieSum = 0; $rPieSum = 0; foreach ($DataDescription["Values"] as $Key2 => $ColName) { if ($ColName != $DataDescription["Position"]) { $Series++; foreach ($Data as $Key => $Values) { if (isset($Data[$Key][$ColName])) { if ($Data[$Key][$ColName] == 0) { $iValues[] = 0; $rValues[] = 0; $iLabels[] = $Data[$Key][$DataDescription["Position"]]; } else { $PieSum += $Data[$Key][$ColName]; $iValues[] = $Data[$Key][$ColName]; $iLabels[] = $Data[$Key][$DataDescription["Position"]]; $rValues[] = $Data[$Key][$ColName]; $rPieSum += $Data[$Key][$ColName]; } } } } } /* Validate serie */ if ($Series != 1) { RaiseFatal("Pie chart can only accept one serie of data."); } $SpliceDistanceRatio = $SpliceDistance; $SkewHeight = $Radius * $Skew / 100; $SpliceRatio = (360 - $SpliceDistanceRatio * count($iValues)) / $PieSum; $SplicePercent = 100 / $PieSum; $rSplicePercent = 100 / $rPieSum; /* Calculate all polygons */ $Angle = 0; $CDev = 5; $TopPlots = ""; $BotPlots = ""; $aTopPlots = ""; $aBotPlots = ""; foreach ($iValues as $Key => $Value) { $XCenterPos = cos(($Angle - $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $XPos; $YCenterPos = sin(($Angle - $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $YPos; $XCenterPos2 = cos(($Angle + $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $XPos; $YCenterPos2 = sin(($Angle + $CDev + ($Value * $SpliceRatio + $SpliceDistanceRatio) / 2) * 3.1418 / 180) * $SpliceDistance + $YPos; $TopPlots[$Key][] = round($XCenterPos); $BotPlots[$Key][] = round($XCenterPos); $TopPlots[$Key][] = round($YCenterPos); $BotPlots[$Key][] = round($YCenterPos + $SpliceHeight); $aTopPlots[$Key][] = $XCenterPos; $aBotPlots[$Key][] = $XCenterPos; $aTopPlots[$Key][] = $YCenterPos; $aBotPlots[$Key][] = $YCenterPos + $SpliceHeight; /* Process labels position & size */ $Caption = ""; if (!($DrawLabels == PIE_NOLABEL)) { $TAngle = $Angle + $Value * $SpliceRatio / 2; if ($DrawLabels == PIE_PERCENTAGE) { $Caption = round($rValues[$Key] * pow(10, $Decimals) * $rSplicePercent) / pow(10, $Decimals) . "%"; } elseif ($DrawLabels == PIE_LABELS) { $Caption = $iLabels[$Key]; } elseif ($DrawLabels == PIE_PERCENTAGE_LABEL) { $Caption = $iLabels[$Key] . "\r\n" . round($Value * pow(10, $Decimals) * $SplicePercent) / pow(10, $Decimals) . "%"; } $Position = imageftbbox($this->FontSize, 0, $this->FontName, $Caption); $TextWidth = $Position[2] - $Position[0]; $TextHeight = abs($Position[1]) + abs($Position[3]); $TX = cos($TAngle * 3.1418 / 180) * ($Radius + 10) + $XPos; if ($TAngle > 0 && $TAngle < 180) { $TY = sin($TAngle * 3.1418 / 180) * ($SkewHeight + 10) + $YPos + $SpliceHeight + 4; } else { $TY = sin($TAngle * 3.1418 / 180) * ($SkewHeight + 4) + $YPos - $TextHeight / 2; } if ($TAngle > 90 && $TAngle < 270) { $TX = $TX - $TextWidth; } $C_TextColor = $this->AllocateColor($this->Picture, 70, 70, 70); imagettftext($this->Picture, $this->FontSize, 0, $TX, $TY, $C_TextColor, $this->FontName, $Caption); } /* Process pie slices */ for ($iAngle = $Angle; $iAngle <= $Angle + $Value * $SpliceRatio; $iAngle = $iAngle + 0.5) { $TopX = cos($iAngle * 3.1418 / 180) * $Radius + $XPos; $TopY = sin($iAngle * 3.1418 / 180) * $SkewHeight + $YPos; $TopPlots[$Key][] = round($TopX); $BotPlots[$Key][] = round($TopX); $TopPlots[$Key][] = round($TopY); $BotPlots[$Key][] = round($TopY + $SpliceHeight); $aTopPlots[$Key][] = $TopX; $aBotPlots[$Key][] = $TopX; $aTopPlots[$Key][] = $TopY; $aBotPlots[$Key][] = $TopY + $SpliceHeight; } $TopPlots[$Key][] = round($XCenterPos2); $BotPlots[$Key][] = round($XCenterPos2); $TopPlots[$Key][] = round($YCenterPos2); $BotPlots[$Key][] = round($YCenterPos2 + $SpliceHeight); $aTopPlots[$Key][] = $XCenterPos2; $aBotPlots[$Key][] = $XCenterPos2; $aTopPlots[$Key][] = $YCenterPos2; $aBotPlots[$Key][] = $YCenterPos2 + $SpliceHeight; $Angle = $iAngle + $SpliceDistanceRatio; } $this->drawPieGraphBottomPolygons($iValues, $BotPlots, $EnhanceColors, $aBotPlots); $this->drawPieGraphLayers($iValues, $TopPlots, $EnhanceColors, $SpliceHeight, $this->Palette); $this->drawPieGraphTopPolygons($iValues, $TopPlots, $EnhanceColors, $aTopPlots); }