function pPie::draw3DRing in Visitors 7.2
Same name and namespace in other branches
- 7 pChart/class/pPie.class.php \pPie::draw3DRing()
File
- pChart/
class/ pPie.class.php, line 1094
Class
Code
function draw3DRing($X, $Y, $Format = "") {
$OuterRadius = isset($Format["OuterRadius"]) ? $Format["OuterRadius"] : 100;
$Precision = isset($Format["Precision"]) ? $Format["Precision"] : 0;
$InnerRadius = isset($Format["InnerRadius"]) ? $Format["InnerRadius"] : 30;
$SkewFactor = isset($Format["SkewFactor"]) ? $Format["SkewFactor"] : 0.6;
$SliceHeight = isset($Format["SliceHeight"]) ? $Format["SliceHeight"] : 10;
$DataGapAngle = isset($Format["DataGapAngle"]) ? $Format["DataGapAngle"] : 10;
$DataGapRadius = isset($Format["DataGapRadius"]) ? $Format["DataGapRadius"] : 10;
$Border = isset($Format["Border"]) ? $Format["Border"] : FALSE;
$Shadow = isset($Format["Shadow"]) ? $Format["Shadow"] : FALSE;
$DrawLabels = isset($Format["DrawLabels"]) ? $Format["DrawLabels"] : FALSE;
$LabelStacked = isset($Format["LabelStacked"]) ? $Format["LabelStacked"] : FALSE;
$LabelColor = isset($Format["LabelColor"]) ? $Format["LabelColor"] : PIE_LABEL_COLOR_MANUAL;
$LabelR = isset($Format["LabelR"]) ? $Format["LabelR"] : 0;
$LabelG = isset($Format["LabelG"]) ? $Format["LabelG"] : 0;
$LabelB = isset($Format["LabelB"]) ? $Format["LabelB"] : 0;
$LabelAlpha = isset($Format["LabelAlpha"]) ? $Format["LabelAlpha"] : 100;
$Cf = isset($Format["Cf"]) ? $Format["Cf"] : 20;
$WriteValues = isset($Format["WriteValues"]) ? $Format["WriteValues"] : PIE_VALUE_NATURAL;
$ValuePadding = isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : $SliceHeight + 15;
$ValuePosition = isset($Format["ValuePosition"]) ? $Format["ValuePosition"] : PIE_VALUE_OUTSIDE;
$ValueSuffix = isset($Format["ValueSuffix"]) ? $Format["ValueSuffix"] : "";
$ValueR = isset($Format["ValueR"]) ? $Format["ValueR"] : 255;
$ValueG = isset($Format["ValueG"]) ? $Format["ValueG"] : 255;
$ValueB = isset($Format["ValueB"]) ? $Format["ValueB"] : 255;
$ValueAlpha = isset($Format["ValueAlpha"]) ? $Format["ValueAlpha"] : 100;
$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
/* Error correction for overlaying rounded corners */
if ($SkewFactor < 0.5) {
$SkewFactor = 0.5;
}
/* Data Processing */
$Data = $this->pDataObject
->getData();
$Palette = $this->pDataObject
->getPalette();
/* Do we have an abscissa serie defined? */
if ($Data["Abscissa"] == "") {
return PIE_NO_ABSCISSA;
}
/* Try to find the data serie */
$DataSerie = "";
foreach ($Data["Series"] as $SerieName => $SerieData) {
if ($SerieName != $Data["Abscissa"]) {
$DataSerie = $SerieName;
}
}
/* Do we have data to compute? */
if ($DataSerie == "") {
return PIE_NO_DATASERIE;
}
/* Remove unused data */
list($Data, $Palette) = $this
->clean0Values($Data, $Palette, $DataSerie, $Data["Abscissa"]);
/* Compute the pie sum */
$SerieSum = $this->pDataObject
->getSum($DataSerie);
/* Do we have data to draw? */
if ($SerieSum == 0) {
return PIE_SUMISNULL;
}
/* Dump the real number of data to draw */
$Values = "";
foreach ($Data["Series"][$DataSerie]["Data"] as $Key => $Value) {
if ($Value != 0) {
$Values[] = $Value;
}
}
/* Compute the wasted angular space between series */
if (count($Values) == 1) {
$WastedAngular = 0;
}
else {
$WastedAngular = count($Values) * $DataGapAngle;
}
/* Compute the scale */
$ScaleFactor = (360 - $WastedAngular) / $SerieSum;
$RestoreShadow = $this->pChartObject->Shadow;
if ($this->pChartObject->Shadow) {
$this->pChartObject->Shadow = FALSE;
}
/* Draw the polygon ring elements */
$Offset = 360;
$ID = count($Values) - 1;
$Values = array_reverse($Values);
$Slice = 0;
$Slices = "";
$SliceColors = "";
$Visible = "";
$SliceAngle = "";
foreach ($Values as $Key => $Value) {
if (!isset($Palette[$ID]["R"])) {
$Color = $this->pChartObject
->getRandomColor();
$Palette[$ID] = $Color;
$this->pDataObject
->savePalette($ID, $Color);
}
$Settings = array(
"R" => $Palette[$ID]["R"],
"G" => $Palette[$ID]["G"],
"B" => $Palette[$ID]["B"],
"Alpha" => $Palette[$ID]["Alpha"],
);
$SliceColors[$Slice] = $Settings;
$StartAngle = $Offset;
$EndAngle = $Offset - $Value * $ScaleFactor;
if ($EndAngle < 0) {
$EndAngle = 0;
}
if ($StartAngle > 180) {
$Visible[$Slice]["Start"] = TRUE;
}
else {
$Visible[$Slice]["Start"] = TRUE;
}
if ($EndAngle < 180) {
$Visible[$Slice]["End"] = FALSE;
}
else {
$Visible[$Slice]["End"] = TRUE;
}
$Step = 360 / (2 * PI * $OuterRadius) / 2;
$OutX1 = VOID;
$OutY1 = VOID;
for ($i = $Offset; $i >= $EndAngle; $i = $i - $Step) {
$Xc = cos(($i - 90) * PI / 180) * ($OuterRadius + $DataGapRadius - 2) + $X;
$Yc = sin(($i - 90) * PI / 180) * ($OuterRadius + $DataGapRadius - 2) * $SkewFactor + $Y;
$Slices[$Slice]["AA"][] = array(
$Xc,
$Yc,
);
$Xc = cos(($i - 90) * PI / 180) * ($OuterRadius + $DataGapRadius - 1) + $X;
$Yc = sin(($i - 90) * PI / 180) * ($OuterRadius + $DataGapRadius - 1) * $SkewFactor + $Y;
$Slices[$Slice]["AA"][] = array(
$Xc,
$Yc,
);
$Xc = cos(($i - 90) * PI / 180) * ($OuterRadius + $DataGapRadius) + $X;
$Yc = sin(($i - 90) * PI / 180) * ($OuterRadius + $DataGapRadius) * $SkewFactor + $Y;
$this->pChartObject
->drawAntialiasPixel($Xc, $Yc, $Settings);
if ($OutX1 == VOID) {
$OutX1 = $Xc;
$OutY1 = $Yc;
}
if ($i < 90) {
$Yc++;
}
if ($i > 90 && $i < 180) {
$Xc++;
}
if ($i > 180 && $i < 270) {
$Xc++;
}
if ($i >= 270) {
$Xc++;
$Yc++;
}
$Slices[$Slice]["BottomPoly"][] = floor($Xc);
$Slices[$Slice]["BottomPoly"][] = floor($Yc);
$Slices[$Slice]["TopPoly"][] = floor($Xc);
$Slices[$Slice]["TopPoly"][] = floor($Yc) - $SliceHeight;
$Slices[$Slice]["Angle"][] = $i;
}
$OutX2 = $Xc;
$OutY2 = $Yc;
$Slices[$Slice]["Angle"][] = VOID;
$Lasti = $i;
$Step = 360 / (2 * PI * $InnerRadius) / 2;
$InX1 = VOID;
$InY1 = VOID;
for ($i = $EndAngle; $i <= $Offset; $i = $i + $Step) {
$Xc = cos(($i - 90) * PI / 180) * ($InnerRadius + $DataGapRadius - 1) + $X;
$Yc = sin(($i - 90) * PI / 180) * ($InnerRadius + $DataGapRadius - 1) * $SkewFactor + $Y;
$Slices[$Slice]["AA"][] = array(
$Xc,
$Yc,
);
$Xc = cos(($i - 90) * PI / 180) * ($InnerRadius + $DataGapRadius) + $X;
$Yc = sin(($i - 90) * PI / 180) * ($InnerRadius + $DataGapRadius) * $SkewFactor + $Y;
$Slices[$Slice]["AA"][] = array(
$Xc,
$Yc,
);
if ($InX1 == VOID) {
$InX1 = $Xc;
$InY1 = $Yc;
}
if ($i < 90) {
$Yc++;
}
if ($i > 90 && $i < 180) {
$Xc++;
}
if ($i > 180 && $i < 270) {
$Xc++;
}
if ($i >= 270) {
$Xc++;
$Yc++;
}
$Slices[$Slice]["BottomPoly"][] = floor($Xc);
$Slices[$Slice]["BottomPoly"][] = floor($Yc);
$Slices[$Slice]["TopPoly"][] = floor($Xc);
$Slices[$Slice]["TopPoly"][] = floor($Yc) - $SliceHeight;
$Slices[$Slice]["Angle"][] = $i;
}
$InX2 = $Xc;
$InY2 = $Yc;
$Slices[$Slice]["InX1"] = $InX1;
$Slices[$Slice]["InY1"] = $InY1;
$Slices[$Slice]["InX2"] = $InX2;
$Slices[$Slice]["InY2"] = $InY2;
$Slices[$Slice]["OutX1"] = $OutX1;
$Slices[$Slice]["OutY1"] = $OutY1;
$Slices[$Slice]["OutX2"] = $OutX2;
$Slices[$Slice]["OutY2"] = $OutY2;
$Offset = $Lasti - $DataGapAngle;
$ID--;
$Slice++;
}
/* Draw the bottom pie splice */
foreach ($Slices as $SliceID => $Plots) {
$Settings = $SliceColors[$SliceID];
$Settings["NoBorder"] = TRUE;
$this->pChartObject
->drawPolygon($Plots["BottomPoly"], $Settings);
foreach ($Plots["AA"] as $Key => $Pos) {
$this->pChartObject
->drawAntialiasPixel($Pos[0], $Pos[1], $Settings);
}
$this->pChartObject
->drawLine($Plots["InX1"], $Plots["InY1"], $Plots["OutX2"], $Plots["OutY2"], $Settings);
$this->pChartObject
->drawLine($Plots["InX2"], $Plots["InY2"], $Plots["OutX1"], $Plots["OutY1"], $Settings);
}
$Slices = array_reverse($Slices);
$SliceColors = array_reverse($SliceColors);
/* Draw the vertical edges (semi-visible) */
foreach ($Slices as $SliceID => $Plots) {
$Settings = $SliceColors[$SliceID];
$Settings["NoBorder"] = TRUE;
$Settings["R"] = $Settings["R"] + $Cf;
$Settings["G"] = $Settings["G"] + $Cf;
$Settings["B"] = $Settings["B"] + $Cf;
$StartAngle = $Plots["Angle"][0];
foreach ($Plots["Angle"] as $Key => $Angle) {
if ($Angle == VOID) {
$EndAngle = $Plots["Angle"][$Key - 1];
}
}
if ($StartAngle >= 270 || $StartAngle <= 90) {
$this->pChartObject
->drawLine($Plots["OutX1"], $Plots["OutY1"], $Plots["OutX1"], $Plots["OutY1"] - $SliceHeight, $Settings);
}
if ($StartAngle >= 270 || $StartAngle <= 90) {
$this->pChartObject
->drawLine($Plots["OutX2"], $Plots["OutY2"], $Plots["OutX2"], $Plots["OutY2"] - $SliceHeight, $Settings);
}
$this->pChartObject
->drawLine($Plots["InX1"], $Plots["InY1"], $Plots["InX1"], $Plots["InY1"] - $SliceHeight, $Settings);
$this->pChartObject
->drawLine($Plots["InX2"], $Plots["InY2"], $Plots["InX2"], $Plots["InY2"] - $SliceHeight, $Settings);
}
/* Draw the inner vertical slices */
foreach ($Slices as $SliceID => $Plots) {
$Settings = $SliceColors[$SliceID];
$Settings["NoBorder"] = TRUE;
$Settings["R"] = $Settings["R"] + $Cf;
$Settings["G"] = $Settings["G"] + $Cf;
$Settings["B"] = $Settings["B"] + $Cf;
$Outer = TRUE;
$Inner = FALSE;
$InnerPlotsA = "";
$InnerPlotsB = "";
foreach ($Plots["Angle"] as $ID => $Angle) {
if ($Angle == VOID) {
$Outer = FALSE;
$Inner = TRUE;
}
elseif ($Inner) {
if (($Angle < 90 || $Angle > 270) && isset($Plots["BottomPoly"][$ID * 2])) {
$Xo = $Plots["BottomPoly"][$ID * 2];
$Yo = $Plots["BottomPoly"][$ID * 2 + 1];
$InnerPlotsA[] = $Xo;
$InnerPlotsA[] = $Yo;
$InnerPlotsB[] = $Xo;
$InnerPlotsB[] = $Yo - $SliceHeight;
}
}
}
if ($InnerPlotsA != "") {
$InnerPlots = array_merge($InnerPlotsA, $this
->arrayReverse($InnerPlotsB));
$this->pChartObject
->drawPolygon($InnerPlots, $Settings);
}
}
/* Draw the splice top and left poly */
foreach ($Slices as $SliceID => $Plots) {
$Settings = $SliceColors[$SliceID];
$Settings["NoBorder"] = TRUE;
$Settings["R"] = $Settings["R"] + $Cf * 1.5;
$Settings["G"] = $Settings["G"] + $Cf * 1.5;
$Settings["B"] = $Settings["B"] + $Cf * 1.5;
$StartAngle = $Plots["Angle"][0];
foreach ($Plots["Angle"] as $Key => $Angle) {
if ($Angle == VOID) {
$EndAngle = $Plots["Angle"][$Key - 1];
}
}
if ($StartAngle < 180) {
$Points = "";
$Points[] = $Plots["InX2"];
$Points[] = $Plots["InY2"];
$Points[] = $Plots["InX2"];
$Points[] = $Plots["InY2"] - $SliceHeight;
$Points[] = $Plots["OutX1"];
$Points[] = $Plots["OutY1"] - $SliceHeight;
$Points[] = $Plots["OutX1"];
$Points[] = $Plots["OutY1"];
$this->pChartObject
->drawPolygon($Points, $Settings);
}
if ($EndAngle > 180) {
$Points = "";
$Points[] = $Plots["InX1"];
$Points[] = $Plots["InY1"];
$Points[] = $Plots["InX1"];
$Points[] = $Plots["InY1"] - $SliceHeight;
$Points[] = $Plots["OutX2"];
$Points[] = $Plots["OutY2"] - $SliceHeight;
$Points[] = $Plots["OutX2"];
$Points[] = $Plots["OutY2"];
$this->pChartObject
->drawPolygon($Points, $Settings);
}
}
/* Draw the vertical edges (visible) */
foreach ($Slices as $SliceID => $Plots) {
$Settings = $SliceColors[$SliceID];
$Settings["NoBorder"] = TRUE;
$Settings["R"] = $Settings["R"] + $Cf;
$Settings["G"] = $Settings["G"] + $Cf;
$Settings["B"] = $Settings["B"] + $Cf;
$StartAngle = $Plots["Angle"][0];
foreach ($Plots["Angle"] as $Key => $Angle) {
if ($Angle == VOID) {
$EndAngle = $Plots["Angle"][$Key - 1];
}
}
if ($StartAngle <= 270 && $StartAngle >= 90) {
$this->pChartObject
->drawLine($Plots["OutX1"], $Plots["OutY1"], $Plots["OutX1"], $Plots["OutY1"] - $SliceHeight, $Settings);
}
if ($EndAngle <= 270 && $EndAngle >= 90) {
$this->pChartObject
->drawLine($Plots["OutX2"], $Plots["OutY2"], $Plots["OutX2"], $Plots["OutY2"] - $SliceHeight, $Settings);
}
}
/* Draw the outer vertical slices */
foreach ($Slices as $SliceID => $Plots) {
$Settings = $SliceColors[$SliceID];
$Settings["NoBorder"] = TRUE;
$Settings["R"] = $Settings["R"] + $Cf;
$Settings["G"] = $Settings["G"] + $Cf;
$Settings["B"] = $Settings["B"] + $Cf;
$Outer = TRUE;
$Inner = FALSE;
$OuterPlotsA = "";
$OuterPlotsB = "";
$InnerPlotsA = "";
$InnerPlotsB = "";
foreach ($Plots["Angle"] as $ID => $Angle) {
if ($Angle == VOID) {
$Outer = FALSE;
$Inner = TRUE;
}
elseif ($Outer) {
if ($Angle > 90 && $Angle < 270 && isset($Plots["BottomPoly"][$ID * 2])) {
$Xo = $Plots["BottomPoly"][$ID * 2];
$Yo = $Plots["BottomPoly"][$ID * 2 + 1];
$OuterPlotsA[] = $Xo;
$OuterPlotsA[] = $Yo;
$OuterPlotsB[] = $Xo;
$OuterPlotsB[] = $Yo - $SliceHeight;
}
}
}
if ($OuterPlotsA != "") {
$OuterPlots = array_merge($OuterPlotsA, $this
->arrayReverse($OuterPlotsB));
$this->pChartObject
->drawPolygon($OuterPlots, $Settings);
}
}
$Slices = array_reverse($Slices);
$SliceColors = array_reverse($SliceColors);
/* Draw the top pie splice */
foreach ($Slices as $SliceID => $Plots) {
$Settings = $SliceColors[$SliceID];
$Settings["NoBorder"] = TRUE;
$Settings["R"] = $Settings["R"] + $Cf * 2;
$Settings["G"] = $Settings["G"] + $Cf * 2;
$Settings["B"] = $Settings["B"] + $Cf * 2;
$this->pChartObject
->drawPolygon($Plots["TopPoly"], $Settings);
if ($RecordImageMap) {
$this->pChartObject
->addToImageMap("POLY", $this
->arraySerialize($Plots["TopPoly"]), $this->pChartObject
->toHTMLColor($Settings["R"], $Settings["G"], $Settings["B"]), $Data["Series"][$Data["Abscissa"]]["Data"][$SliceID], $Data["Series"][$DataSerie]["Data"][count($Slices) - $SliceID - 1]);
}
foreach ($Plots["AA"] as $Key => $Pos) {
$this->pChartObject
->drawAntialiasPixel($Pos[0], $Pos[1] - $SliceHeight, $Settings);
}
$this->pChartObject
->drawLine($Plots["InX1"], $Plots["InY1"] - $SliceHeight, $Plots["OutX2"], $Plots["OutY2"] - $SliceHeight, $Settings);
$this->pChartObject
->drawLine($Plots["InX2"], $Plots["InY2"] - $SliceHeight, $Plots["OutX1"], $Plots["OutY1"] - $SliceHeight, $Settings);
}
if ($DrawLabels) {
$Offset = 360;
foreach ($Values as $Key => $Value) {
$StartAngle = $Offset;
$EndAngle = $Offset - $Value * $ScaleFactor;
if ($EndAngle < 0) {
$EndAngle = 0;
}
if ($LabelColor == PIE_LABEL_COLOR_AUTO) {
$Settings = array(
"FillR" => $Palette[$ID]["R"],
"FillG" => $Palette[$ID]["G"],
"FillB" => $Palette[$ID]["B"],
"Alpha" => $Palette[$ID]["Alpha"],
);
}
else {
$Settings = array(
"FillR" => $LabelR,
"FillG" => $LabelG,
"FillB" => $LabelB,
"Alpha" => $LabelAlpha,
);
}
$Angle = ($EndAngle - $Offset) / 2 + $Offset;
$Xc = cos(($Angle - 90) * PI / 180) * ($OuterRadius + $DataGapRadius) + $X;
$Yc = sin(($Angle - 90) * PI / 180) * ($OuterRadius + $DataGapRadius) * $SkewFactor + $Y;
if ($WriteValues == PIE_VALUE_PERCENTAGE) {
$Label = $Display = round(100 / $SerieSum * $Value, $Precision) . "%";
}
elseif ($WriteValues == PIE_VALUE_NATURAL) {
$Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];
}
else {
$Label = "";
}
if ($LabelStacked) {
$this
->writePieLabel($Xc, $Yc - $SliceHeight, $Label, $Angle, $Settings, TRUE, $X, $Y, $OuterRadius);
}
else {
$this
->writePieLabel($Xc, $Yc - $SliceHeight, $Label, $Angle, $Settings, FALSE);
}
$Offset = $EndAngle - $DataGapAngle;
$ID--;
$Slice++;
}
}
if ($DrawLabels && $LabelStacked) {
$this
->writeShiftedLabels();
}
$this->pChartObject->Shadow = $RestoreShadow;
return PIE_RENDERED;
}