Draw an indicator

@param int $X
@param int $Y
@param int $Width
@param int $Height
@param array $Format
@return null|int
499778
public function draw($X, $Y, $Width, $Height, array $Format = [])
    {
        $Values = isset($Format["Values"]) ? $Format["Values"] : VOID;
        $IndicatorSections = isset($Format["IndicatorSections"]) ? $Format["IndicatorSections"] : null;
        $ValueDisplay = isset($Format["ValueDisplay"]) ? $Format["ValueDisplay"] : INDICATOR_VALUE_BUBBLE;
        $SectionsMargin = isset($Format["SectionsMargin"]) ? $Format["SectionsMargin"] : 4;
        $DrawLeftHead = isset($Format["DrawLeftHead"]) ? $Format["DrawLeftHead"] : true;
        $DrawRightHead = isset($Format["DrawRightHead"]) ? $Format["DrawRightHead"] : true;
        $HeadSize = isset($Format["HeadSize"]) ? $Format["HeadSize"] : floor($Height / 4);
        $TextPadding = isset($Format["TextPadding"]) ? $Format["TextPadding"] : 4;
        $CaptionLayout = isset($Format["CaptionLayout"]) ? $Format["CaptionLayout"] : INDICATOR_CAPTION_EXTENDED;
        $CaptionPosition = isset($Format["CaptionPosition"]) ? $Format["CaptionPosition"] : INDICATOR_CAPTION_INSIDE;
        $CaptionColorFactor = isset($Format["CaptionColorFactor"]) ? $Format["CaptionColorFactor"] : null;
        $CaptionR = isset($Format["CaptionR"]) ? $Format["CaptionR"] : 255;
        $CaptionG = isset($Format["CaptionG"]) ? $Format["CaptionG"] : 255;
        $CaptionB = isset($Format["CaptionB"]) ? $Format["CaptionB"] : 255;
        $CaptionAlpha = isset($Format["CaptionAlpha"]) ? $Format["CaptionAlpha"] : 100;
        $SubCaptionColorFactor = isset($Format["SubCaptionColorFactor"]) ? $Format["SubCaptionColorFactor"] : null;
        $SubCaptionR = isset($Format["SubCaptionR"]) ? $Format["SubCaptionR"] : 50;
        $SubCaptionG = isset($Format["SubCaptionG"]) ? $Format["SubCaptionG"] : 50;
        $SubCaptionB = isset($Format["SubCaptionB"]) ? $Format["SubCaptionB"] : 50;
        $SubCaptionAlpha = isset($Format["SubCaptionAlpha"]) ? $Format["SubCaptionAlpha"] : 100;
        $ValueFontName = isset($Format["ValueFontName"]) ? $Format["ValueFontName"] : $this->pChartObject->FontName;
        $ValueFontSize = isset($Format["ValueFontSize"]) ? $Format["ValueFontSize"] : $this->pChartObject->FontSize;
        $CaptionFontName = isset($Format["CaptionFontName"])
            ? $Format["CaptionFontName"] : $this->pChartObject->FontName
        ;
        $CaptionFontSize = isset($Format["CaptionFontSize"])
            ? $Format["CaptionFontSize"] : $this->pChartObject->FontSize
        ;
        $Unit = isset($Format["Unit"]) ? $Format["Unit"] : "";

        /* Convert the Values to display to an array if needed */
        if (!is_array($Values)) {
            $Values = [$Values];
        }

        /* No section, let's die */
        if ($IndicatorSections == null) {
            return 0;
        }

        /* Determine indicator visual configuration */
        $OverallMin = $IndicatorSections[0]["End"];
        $OverallMax = $IndicatorSections[0]["Start"];
        foreach ($IndicatorSections as $Key => $Settings) {
            if ($Settings["End"] > $OverallMax) {
                $OverallMax = $Settings["End"];
            }
            if ($Settings["Start"] < $OverallMin) {
                $OverallMin = $Settings["Start"];
            }
        }
        $RealWidth = $Width - (count($IndicatorSections) - 1) * $SectionsMargin;
        $XScale = $RealWidth / ($OverallMax - $OverallMin);

        $X1 = $X;
        $ValuesPos = [];
        foreach ($IndicatorSections as $Key => $Settings) {
            $Color = ["R" => $Settings["R"], "G" => $Settings["G"], "B" => $Settings["B"]];
            $Caption = $Settings["Caption"];
            $SubCaption = $Settings["Start"] . " - " . $Settings["End"];

            $X2 = $X1 + ($Settings["End"] - $Settings["Start"]) * $XScale;

            if ($Key == 0 && $DrawLeftHead) {
                $Poly = [];
                $Poly[] = $X1 - 1;
                $Poly[] = $Y;
                $Poly[] = $X1 - 1;
                $Poly[] = $Y + $Height;
                $Poly[] = $X1 - 1 - $HeadSize;
                $Poly[] = $Y + ($Height / 2);
                $this->pChartObject->drawPolygon($Poly, $Color);
                $this->pChartObject->drawLine($X1 - 2, $Y, $X1 - 2 - $HeadSize, $Y + ($Height / 2), $Color);
                $this->pChartObject->drawLine(
                    $X1 - 2,
                    $Y + $Height,
                    $X1 - 2 - $HeadSize,
                    $Y + ($Height / 2),
                    $Color
                );
            }

            /* Determine the position of the breaks */
            $Break = [];
            foreach ($Values as $iKey => $Value) {
                if ($Value >= $Settings["Start"] && $Value <= $Settings["End"]) {
                    $XBreak = $X1 + ($Value - $Settings["Start"]) * $XScale;
                    $ValuesPos[$Value] = $XBreak;
                    $Break[] = floor($XBreak);
                }
            }

            if ($ValueDisplay == INDICATOR_VALUE_LABEL) {
                if (!count($Break)) {
                    $this->pChartObject->drawFilledRectangle($X1, $Y, $X2, $Y + $Height, $Color);
                } else {
                    sort($Break);
                    $Poly = [];
                    $Poly[] = $X1;
                    $Poly[] = $Y;
                    $LastPointWritten = false;
                    foreach ($Break as $iKey => $Value) {
                        if ($Value - 5 >= $X1) {
                            $Poly[] = $Value - 5;
                            $Poly[] = $Y;
                        } elseif ($X1 - ($Value - 5) > 0) {
                            $Offset = $X1 - ($Value - 5);
                            $Poly = [$X1, $Y + $Offset];
                        }

                        $Poly[] = $Value;
                        $Poly[] = $Y + 5;

                        if ($Value + 5 <= $X2) {
                            $Poly[] = $Value + 5;
                            $Poly[] = $Y;
                        } elseif (($Value + 5) > $X2) {
                            $Offset = ($Value + 5) - $X2;
                            $Poly[] = $X2;
                            $Poly[] = $Y + $Offset;
                            $LastPointWritten = true;
                        }
                    }
                    if (!$LastPointWritten) {
                        $Poly[] = $X2;
                        $Poly[] = $Y;
                    }
                    $Poly[] = $X2;
                    $Poly[] = $Y + $Height;
                    $Poly[] = $X1;
                    $Poly[] = $Y + $Height;

                    $this->pChartObject->drawPolygon($Poly, $Color);
                }
            } else {
                $this->pChartObject->drawFilledRectangle($X1, $Y, $X2, $Y + $Height, $Color);
            }

            if ($Key == count($IndicatorSections) - 1 && $DrawRightHead) {
                $Poly = [];
                $Poly[] = $X2 + 1;
                $Poly[] = $Y;
                $Poly[] = $X2 + 1;
                $Poly[] = $Y + $Height;
                $Poly[] = $X2 + 1 + $HeadSize;
                $Poly[] = $Y + ($Height / 2);
                $this->pChartObject->drawPolygon($Poly, $Color);
                $this->pChartObject->drawLine($X2 + 1, $Y, $X2 + 1 + $HeadSize, $Y + ($Height / 2), $Color);
                $this->pChartObject->drawLine(
                    $X2 + 1,
                    $Y + $Height,
                    $X2 + 1 + $HeadSize,
                    $Y + ($Height / 2),
                    $Color
                );
            }

            $YOffset = 0;
            $XOffset = 0;
            if ($CaptionPosition == INDICATOR_CAPTION_INSIDE) {
                $TxtPos = $this->pChartObject->getTextBox(
                    $X1,
                    $Y + $Height + $TextPadding,
                    $CaptionFontName,
                    $CaptionFontSize,
                    0,
                    $Caption
                );
                $YOffset = ($TxtPos[0]["Y"] - $TxtPos[2]["Y"]) + $TextPadding;

                if ($CaptionLayout == INDICATOR_CAPTION_EXTENDED) {
                    $TxtPos = $this->pChartObject->getTextBox(
                        $X1,
                        $Y + $Height + $TextPadding,
                        $CaptionFontName,
                        $CaptionFontSize,
                        0,
                        $SubCaption
                    );
                    $YOffset = $YOffset + ($TxtPos[0]["Y"] - $TxtPos[2]["Y"]) + $TextPadding * 2;
                }
                $XOffset = $TextPadding;
            }

            if ($CaptionColorFactor == null) {
                $CaptionColor = [
                    "Align" => TEXT_ALIGN_TOPLEFT,
                    "FontName" => $CaptionFontName,
                    "FontSize" => $CaptionFontSize,
                    "R" => $CaptionR,
                    "G" => $CaptionG,
                    "B" => $CaptionB,
                    "Alpha" => $CaptionAlpha
                ];
            } else {
                $CaptionColor = [
                    "Align" => TEXT_ALIGN_TOPLEFT,
                    "FontName" => $CaptionFontName,
                    "FontSize" => $CaptionFontSize,
                    "R" => $Settings["R"] + $CaptionColorFactor,
                    "G" => $Settings["G"] + $CaptionColorFactor,
                    "B" => $Settings["B"] + $CaptionColorFactor
                ];
            }

            if ($SubCaptionColorFactor == null) {
                $SubCaptionColor = [
                    "Align" => TEXT_ALIGN_TOPLEFT,
                    "FontName" => $CaptionFontName,
                    "FontSize" => $CaptionFontSize,
                    "R" => $SubCaptionR,
                    "G" => $SubCaptionG,
                    "B" => $SubCaptionB,
                    "Alpha" => $SubCaptionAlpha
                ];
            } else {
                $SubCaptionColor = [
                    "Align" => TEXT_ALIGN_TOPLEFT,
                    "FontName" => $CaptionFontName,
                    "FontSize" => $CaptionFontSize,
                    "R" => $Settings["R"] + $SubCaptionColorFactor,
                    "G" => $Settings["G"] + $SubCaptionColorFactor,
                    "B" => $Settings["B"] + $SubCaptionColorFactor
                ];
            }

            $RestoreShadow = $this->pChartObject->Shadow;
            $this->pChartObject->Shadow = false;

            if ($CaptionLayout == INDICATOR_CAPTION_DEFAULT) {
                $this->pChartObject->drawText($X1, $Y + $Height + $TextPadding, $Caption, $CaptionColor);
            } elseif ($CaptionLayout == INDICATOR_CAPTION_EXTENDED) {
                $TxtPos = $this->pChartObject->getTextBox(
                    $X1,
                    $Y + $Height + $TextPadding,
                    $CaptionFontName,
                    $CaptionFontSize,
                    0,
                    $Caption
                );
                $CaptionHeight = $TxtPos[0]["Y"] - $TxtPos[2]["Y"];

                $this->pChartObject->drawText(
                    $X1 + $XOffset,
                    $Y + $Height - $YOffset + $TextPadding,
                    $Caption,
                    $CaptionColor
                );
                $this->pChartObject->drawText(
                    $X1 + $XOffset,
                    $Y + $Height - $YOffset + $CaptionHeight + $TextPadding * 2,
                    $SubCaption,
                    $SubCaptionColor
                );
            }

            $this->pChartObject->Shadow = $RestoreShadow;

            $X1 = $X2 + $SectionsMargin;
        }

        $RestoreShadow = $this->pChartObject->Shadow;
        $this->pChartObject->Shadow = false;

        foreach ($Values as $Key => $Value) {
            if ($Value >= $OverallMin && $Value <= $OverallMax) {
                foreach ($IndicatorSections as $Key => $Settings) {
                    if ($Value >= $Settings["Start"] && $Value <= $Settings["End"]) {
                        $X1 = $ValuesPos[$Value]; //$X + $Key*$SectionsMargin + ($Value - $OverallMin) * $XScale;

                        if ($ValueDisplay == INDICATOR_VALUE_BUBBLE) {
                            $TxtPos = $this->pChartObject->getTextBox(
                                $X1,
                                $Y,
                                $ValueFontName,
                                $ValueFontSize,
                                0,
                                $Value . $Unit
                            );
                            $Radius = floor(($TxtPos[1]["X"] - $TxtPos[0]["X"] + $TextPadding * 4) / 2);

                            $this->pChartObject->drawFilledCircle(
                                $X1,
                                $Y,
                                $Radius + 4,
                                [
                                    "R" => $Settings["R"] + 20,
                                    "G" => $Settings["G"] + 20,
                                    "B" => $Settings["B"] + 20
                                ]
                            );
                            $this->pChartObject->drawFilledCircle(
                                $X1,
                                $Y,
                                $Radius,
                                ["R" => 255, "G" => 255, "B" => 255]
                            );

                            $TextSettings = [
                                "Align" => TEXT_ALIGN_MIDDLEMIDDLE,
                                "FontName" => $ValueFontName,
                                "FontSize" => $ValueFontSize
                            ];
                            $this->pChartObject->drawText($X1 - 1, $Y - 1, $Value . $Unit, $TextSettings);
                        } elseif ($ValueDisplay == INDICATOR_VALUE_LABEL) {
                            $Caption = [
                                [
                                    "Format" => [
                                        "R" => $Settings["R"],
                                        "G" => $Settings["G"],
                                        "B" => $Settings["B"],
                                        "Alpha" => 100
                                    ],
                                    "Caption" => $Value . $Unit
                                ]
                            ];
                            $this->pChartObject->drawLabelBox(
                                floor($X1),
                                floor($Y) + 2,
                                "Value - " . $Settings["Caption"],
                                $Caption
                            );
                        }
                    }
                    $X1 = $X2 + $SectionsMargin;
                }
            }
        }
        $this->pChartObject->Shadow = $RestoreShadow;
    }
1095511
public static function canvas($width, $height, $background = null)
    {
        return self::getManager()->canvas($width, $height, $background);
    }
375390
public function draw2DPie($X, $Y, array $Format = [])
    {
        $Radius = isset($Format["Radius"]) ? $Format["Radius"] : 60;
        $Precision = isset($Format["Precision"]) ? $Format["Precision"] : 0;
        $DataGapAngle = isset($Format["DataGapAngle"]) ? $Format["DataGapAngle"] : 0;
        $DataGapRadius = isset($Format["DataGapRadius"]) ? $Format["DataGapRadius"] : 0;
        $SecondPass = isset($Format["SecondPass"]) ? $Format["SecondPass"] : true;
        $Border = isset($Format["Border"]) ? $Format["Border"] : false;
        $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 255;
        $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 255;
        $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 255;
        $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;
        $WriteValues = isset($Format["WriteValues"]) ? $Format["WriteValues"] : null;
        $ValuePosition = isset($Format["ValuePosition"]) ? $Format["ValuePosition"] : PIE_VALUE_OUTSIDE;
        $ValuePadding = isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 15;
        $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;

        $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 = null;
        foreach (array_keys($Data["Series"]) as $SerieName) {
            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;

            $ShadowFormat = $Format;
            $ShadowFormat["Shadow"] = true;
            $this->draw2DPie(
                $X + $this->pChartObject->ShadowX,
                $Y + $this->pChartObject->ShadowY,
                $ShadowFormat
            );
        }

        /* Draw the polygon pie elements */
        $Step = 360 / (2 * PI * $Radius);
        $Offset = 0;
        $ID = 0;
        foreach ($Values as $Key => $Value) {
            if ($Shadow) {
                $Settings = [
                    "R" => $this->pChartObject->ShadowR,
                    "G" => $this->pChartObject->ShadowG,
                    "B" => $this->pChartObject->ShadowB,
                    "Alpha" => $this->pChartObject->Shadowa
                ];
            } else {
                if (!isset($Palette[$ID]["R"])) {
                    $Color = $this->pChartObject->getRandomColor();
                    $Palette[$ID] = $Color;
                    $this->pDataObject->savePalette($ID, $Color);
                }
                $Settings = [
                    "R" => $Palette[$ID]["R"],
                    "G" => $Palette[$ID]["G"],
                    "B" => $Palette[$ID]["B"],
                    "Alpha" => $Palette[$ID]["Alpha"]
                ];
            }

            if (!$SecondPass && !$Shadow) {
                if (!$Border) {
                    $Settings["Surrounding"] = 10;
                } else {
                    $Settings["BorderR"] = $BorderR;
                    $Settings["BorderG"] = $BorderG;
                    $Settings["BorderB"] = $BorderB;
                }
            }

            $EndAngle = $Offset + ($Value * $ScaleFactor);
            if ($EndAngle > 360) {
                $EndAngle = 360;
            }

            $Angle = ($EndAngle - $Offset) / 2 + $Offset;
            if ($DataGapAngle == 0) {
                $X0 = $X;
                $Y0 = $Y;
            } else {
                $X0 = cos(($Angle - 90) * PI / 180) * $DataGapRadius + $X;
                $Y0 = sin(($Angle - 90) * PI / 180) * $DataGapRadius + $Y;
            }

            $Plots = [$X0, $Y0];

            for ($i = $Offset; $i <= $EndAngle; $i = $i + $Step) {
                $Xc = cos(($i - 90) * PI / 180) * $Radius + $X;
                $Yc = sin(($i - 90) * PI / 180) * $Radius + $Y;

                if ($SecondPass && ($i < 90)) {
                    $Yc++;
                }
                if ($SecondPass && ($i > 180 && $i < 270)) {
                    $Xc++;
                }
                if ($SecondPass && ($i >= 270)) {
                    $Xc++;
                    $Yc++;
                }

                $Plots[] = $Xc;
                $Plots[] = $Yc;
            }

            $this->pChartObject->drawPolygon($Plots, $Settings);
            if ($RecordImageMap && !$Shadow) {
                $this->pChartObject->addToImageMap(
                    "POLY",
                    $this->arraySerialize($Plots),
                    $this->pChartObject->toHTMLColor(
                        $Palette[$ID]["R"],
                        $Palette[$ID]["G"],
                        $Palette[$ID]["B"]
                    ),
                    $Data["Series"][$Data["Abscissa"]]["Data"][$Key],
                    $Value
                );
            }

            if ($DrawLabels && !$Shadow && !$SecondPass) {
                if ($LabelColor == PIE_LABEL_COLOR_AUTO) {
                    $Settings = [
                        "FillR" => $Palette[$ID]["R"],
                        "FillG" => $Palette[$ID]["G"],
                        "FillB" => $Palette[$ID]["B"],
                        "Alpha" => $Palette[$ID]["Alpha"]
                    ];
                } else {
                    $Settings = [
                        "FillR" => $LabelR,
                        "FillG" => $LabelG,
                        "FillB" => $LabelB,
                        "Alpha" => $LabelAlpha
                    ];
                }

                $Angle = ($EndAngle - $Offset) / 2 + $Offset;
                $Xc = cos(($Angle - 90) * PI / 180) * $Radius + $X;
                $Yc = sin(($Angle - 90) * PI / 180) * $Radius + $Y;

                $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];

                if ($LabelStacked) {
                    $this->writePieLabel($Xc, $Yc, $Label, $Angle, $Settings, true, $X, $Y, $Radius);
                } else {
                    $this->writePieLabel($Xc, $Yc, $Label, $Angle, $Settings, false);
                }
            }

            $Offset = $i + $DataGapAngle;
            $ID++;
        }

        /* Second pass to smooth the angles */
        if ($SecondPass) {
            $Step = 360 / (2 * PI * $Radius);
            $Offset = 0;
            $ID = 0;
            foreach ($Values as $Key => $Value) {
                $FirstPoint = true;
                if ($Shadow) {
                    $Settings = [
                        "R" => $this->pChartObject->ShadowR,
                        "G" => $this->pChartObject->ShadowG,
                        "B" => $this->pChartObject->ShadowB,
                        "Alpha" => $this->pChartObject->Shadowa
                    ];
                } else {
                    if ($Border) {
                        $Settings = ["R" => $BorderR, "G" => $BorderG, "B" => $BorderB];
                    } else {
                        $Settings = [
                            "R" => $Palette[$ID]["R"],
                            "G" => $Palette[$ID]["G"],
                            "B" => $Palette[$ID]["B"],
                            "Alpha" => $Palette[$ID]["Alpha"]
                        ];
                    }
                }

                $EndAngle = $Offset + ($Value * $ScaleFactor);
                if ($EndAngle > 360) {
                    $EndAngle = 360;
                }

                if ($DataGapAngle == 0) {
                    $X0 = $X;
                    $Y0 = $Y;
                } else {
                    $Angle = ($EndAngle - $Offset) / 2 + $Offset;
                    $X0 = cos(($Angle - 90) * PI / 180) * $DataGapRadius + $X;
                    $Y0 = sin(($Angle - 90) * PI / 180) * $DataGapRadius + $Y;
                }
                $Plots[] = $X0;
                $Plots[] = $Y0;

                for ($i = $Offset; $i <= $EndAngle; $i = $i + $Step) {
                    $Xc = cos(($i - 90) * PI / 180) * $Radius + $X;
                    $Yc = sin(($i - 90) * PI / 180) * $Radius + $Y;

                    if ($FirstPoint) {
                        $this->pChartObject->drawLine($Xc, $Yc, $X0, $Y0, $Settings);
                        $FirstPoint = false;
                    }

                    $this->pChartObject->drawAntialiasPixel($Xc, $Yc, $Settings);
                }
                $this->pChartObject->drawLine($Xc, $Yc, $X0, $Y0, $Settings);

                if ($DrawLabels && !$Shadow) {
                    if ($LabelColor == PIE_LABEL_COLOR_AUTO) {
                        $Settings = [
                            "FillR" => $Palette[$ID]["R"],
                            "FillG" => $Palette[$ID]["G"],
                            "FillB" => $Palette[$ID]["B"],
                            "Alpha" => $Palette[$ID]["Alpha"]
                        ];
                    } else {
                        $Settings = [
                            "FillR" => $LabelR,
                            "FillG" => $LabelG,
                            "FillB" => $LabelB,
                            "Alpha" => $LabelAlpha
                        ];
                    }

                    $Angle = ($EndAngle - $Offset) / 2 + $Offset;
                    $Xc = cos(($Angle - 90) * PI / 180) * $Radius + $X;
                    $Yc = sin(($Angle - 90) * PI / 180) * $Radius + $Y;

                    $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];

                    if ($LabelStacked) {
                        $this->writePieLabel($Xc, $Yc, $Label, $Angle, $Settings, true, $X, $Y, $Radius);
                    } else {
                        $this->writePieLabel($Xc, $Yc, $Label, $Angle, $Settings, false);
                    }
                }

                $Offset = $i + $DataGapAngle;
                $ID++;
            }
        }

        if ($WriteValues != null && !$Shadow) {
            $Step = 360 / (2 * PI * $Radius);
            $Offset = 0;
            $ID = count($Values) - 1;
            $Settings = [
                "Align" => TEXT_ALIGN_MIDDLEMIDDLE,
                "R" => $ValueR,
                "G" => $ValueG,
                "B" => $ValueB,
                "Alpha" => $ValueAlpha
            ];
            foreach ($Values as $Key => $Value) {
                $EndAngle = ($Value * $ScaleFactor) + $Offset;
                if ((int) $EndAngle > 360) {
                    $EndAngle = 0;
                }
                $Angle = ($EndAngle - $Offset) / 2 + $Offset;

                if ($ValuePosition == PIE_VALUE_OUTSIDE) {
                    $Xc = cos(($Angle - 90) * PI / 180) * ($Radius + $ValuePadding) + $X;
                    $Yc = sin(($Angle - 90) * PI / 180) * ($Radius + $ValuePadding) + $Y;
                } else {
                    $Xc = cos(($Angle - 90) * PI / 180) * ($Radius) / 2 + $X;
                    $Yc = sin(($Angle - 90) * PI / 180) * ($Radius) / 2 + $Y;
                }

                if ($WriteValues == PIE_VALUE_PERCENTAGE) {
                    $Display = round((100 / $SerieSum) * $Value, $Precision) . "%";
                } elseif ($WriteValues == PIE_VALUE_NATURAL) {
                    $Display = $Value . $ValueSuffix;
                }
                $this->pChartObject->drawText($Xc, $Yc, $Display, $Settings);

                $Offset = $EndAngle + $DataGapAngle;
                $ID--;
            }
        }

        if ($DrawLabels && $LabelStacked) {
            $this->writeShiftedLabels();
        }

        $this->pChartObject->Shadow = $RestoreShadow;

        return PIE_RENDERED;
    }
1248547
def draw_oval(x, y, width, height)
      @context.drawOval(x, y, width, height)
    end
1106579
public function drawBestFit(array $Format = [])
    {
        $OverrideTicks = isset($Format["Ticks"]) ? $Format["Ticks"] : null;
        $OverrideR = isset($Format["R"]) ? $Format["R"] : VOID;
        $OverrideG = isset($Format["G"]) ? $Format["G"] : VOID;
        $OverrideB = isset($Format["B"]) ? $Format["B"] : VOID;
        $OverrideAlpha = isset($Format["Alpha"]) ? $Format["Alpha"] : VOID;

        $Data = $this->DataSet->getData();
        list($XMargin, $XDivs) = $this->scaleGetXSettings();

        foreach ($Data["Series"] as $SerieName => $Serie) {
            if ($Serie["isDrawable"] == true && $SerieName != $Data["Abscissa"]) {
                if ($OverrideR != VOID && $OverrideG != VOID && $OverrideB != VOID) {
                    $R = $OverrideR;
                    $G = $OverrideG;
                    $B = $OverrideB;
                } else {
                    $R = $Serie["Color"]["R"];
                    $G = $Serie["Color"]["G"];
                    $B = $Serie["Color"]["B"];
                }
                if ($OverrideTicks == null) {
                    $Ticks = $Serie["Ticks"];
                } else {
                    $Ticks = $OverrideTicks;
                }
                if ($OverrideAlpha == VOID) {
                    $Alpha = $Serie["Color"]["Alpha"];
                } else {
                    $Alpha = $OverrideAlpha;
                }

                $Color = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha, "Ticks" => $Ticks];

                $PosArray = $this->scaleComputeY(
                    $Serie["Data"],
                    ["AxisID" => $Serie["Axis"]]
                );

                if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
                    if ($XDivs == 0) {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1) / 4;
                    } else {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1 - $XMargin * 2) / $XDivs;
                    }
                    $X = $this->GraphAreaX1 + $XMargin;

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    $Sxy = 0;
                    $Sx = 0;
                    $Sy = 0;
                    $Sxx = 0;
                    foreach ($PosArray as $Key => $Y) {
                        if ($Y != VOID) {
                            $Sxy = $Sxy + $X * $Y;
                            $Sx = $Sx + $X;
                            $Sy = $Sy + $Y;
                            $Sxx = $Sxx + $X * $X;
                        }

                        $X = $X + $XStep;
                    }
                    $n = count($this->DataSet->stripVOID($PosArray)); //$n = count($PosArray);
                    $M = (($n * $Sxy) - ($Sx * $Sy)) / (($n * $Sxx) - ($Sx * $Sx));
                    $B = (($Sy) - ($M * $Sx)) / ($n);

                    $X1 = $this->GraphAreaX1 + $XMargin;
                    $Y1 = $M * $X1 + $B;
                    $X2 = $this->GraphAreaX2 - $XMargin;
                    $Y2 = $M * $X2 + $B;

                    if ($Y1 < $this->GraphAreaY1) {
                        $X1 = $X1 + ($this->GraphAreaY1 - $Y1);
                        $Y1 = $this->GraphAreaY1;
                    }
                    if ($Y1 > $this->GraphAreaY2) {
                        $X1 = $X1 + ($Y1 - $this->GraphAreaY2);
                        $Y1 = $this->GraphAreaY2;
                    }
                    if ($Y2 < $this->GraphAreaY1) {
                        $X2 = $X2 - ($this->GraphAreaY1 - $Y2);
                        $Y2 = $this->GraphAreaY1;
                    }
                    if ($Y2 > $this->GraphAreaY2) {
                        $X2 = $X2 - ($Y2 - $this->GraphAreaY2);
                        $Y2 = $this->GraphAreaY2;
                    }

                    $this->drawLine($X1, $Y1, $X2, $Y2, $Color);
                } else {
                    if ($XDivs == 0) {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1) / 4;
                    } else {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1 - $XMargin * 2) / $XDivs;
                    }
                    $Y = $this->GraphAreaY1 + $XMargin;

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    $Sxy = 0;
                    $Sx = 0;
                    $Sy = 0;
                    $Sxx = 0;
                    foreach ($PosArray as $Key => $X) {
                        if ($X != VOID) {
                            $Sxy = $Sxy + $X * $Y;
                            $Sx = $Sx + $Y;
                            $Sy = $Sy + $X;
                            $Sxx = $Sxx + $Y * $Y;
                        }

                        $Y = $Y + $YStep;
                    }
                    $n = count($this->DataSet->stripVOID($PosArray)); //$n = count($PosArray);
                    $M = (($n * $Sxy) - ($Sx * $Sy)) / (($n * $Sxx) - ($Sx * $Sx));
                    $B = (($Sy) - ($M * $Sx)) / ($n);

                    $Y1 = $this->GraphAreaY1 + $XMargin;
                    $X1 = $M * $Y1 + $B;
                    $Y2 = $this->GraphAreaY2 - $XMargin;
                    $X2 = $M * $Y2 + $B;

                    if ($X1 < $this->GraphAreaX1) {
                        $Y1 = $Y1 + ($this->GraphAreaX1 - $X1);
                        $X1 = $this->GraphAreaX1;
                    }
                    if ($X1 > $this->GraphAreaX2) {
                        $Y1 = $Y1 + ($X1 - $this->GraphAreaX2);
                        $X1 = $this->GraphAreaX2;
                    }
                    if ($X2 < $this->GraphAreaX1) {
                        $Y2 = $Y2 - ($this->GraphAreaY1 - $X2);
                        $X2 = $this->GraphAreaX1;
                    }
                    if ($X2 > $this->GraphAreaX2) {
                        $Y2 = $Y2 - ($X2 - $this->GraphAreaX2);
                        $X2 = $this->GraphAreaX2;
                    }

                    $this->drawLine($X1, $Y1, $X2, $Y2, $Color);
                }
            }
        }
    }
277890
public function drawStepChart(array $Format = [])
    {
        $BreakVoid = isset($Format["BreakVoid"]) ? $Format["BreakVoid"] : false;
        $ReCenter = isset($Format["ReCenter"]) ? $Format["ReCenter"] : true;
        $VoidTicks = isset($Format["VoidTicks"]) ? $Format["VoidTicks"] : 4;
        $BreakR = isset($Format["BreakR"]) ? $Format["BreakR"] : null;
        $BreakG = isset($Format["BreakG"]) ? $Format["BreakG"] : null;
        $BreakB = isset($Format["BreakB"]) ? $Format["BreakB"] : null;
        $DisplayValues = isset($Format["DisplayValues"]) ? $Format["DisplayValues"] : false;
        $DisplayOffset = isset($Format["DisplayOffset"]) ? $Format["DisplayOffset"] : 2;
        $DisplayColor = isset($Format["DisplayColor"]) ? $Format["DisplayColor"] : DISPLAY_MANUAL;
        $DisplayR = isset($Format["DisplayR"]) ? $Format["DisplayR"] : 0;
        $DisplayG = isset($Format["DisplayG"]) ? $Format["DisplayG"] : 0;
        $DisplayB = isset($Format["DisplayB"]) ? $Format["DisplayB"] : 0;
        $RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : false;
        $ImageMapPlotSize = isset($Format["ImageMapPlotSize"]) ? $Format["ImageMapPlotSize"] : 5;

        $this->LastChartLayout = CHART_LAST_LAYOUT_REGULAR;

        $Data = $this->DataSet->getData();
        list($XMargin, $XDivs) = $this->scaleGetXSettings();
        foreach ($Data["Series"] as $SerieName => $Serie) {
            if ($Serie["isDrawable"] == true && $SerieName != $Data["Abscissa"]) {
                $R = $Serie["Color"]["R"];
                $G = $Serie["Color"]["G"];
                $B = $Serie["Color"]["B"];
                $Alpha = $Serie["Color"]["Alpha"];
                $Ticks = $Serie["Ticks"];
                $Weight = $Serie["Weight"];

                if (isset($Serie["Description"])) {
                    $SerieDescription = $Serie["Description"];
                } else {
                    $SerieDescription = $SerieName;
                }

                if ($BreakR == null) {
                    $BreakSettings = [
                        "R" => $R,
                        "G" => $G,
                        "B" => $B,
                        "Alpha" => $Alpha,
                        "Ticks" => $VoidTicks,
                        "Weight" => $Weight
                    ];
                } else {
                    $BreakSettings = [
                        "R" => $BreakR,
                        "G" => $BreakG,
                        "B" => $BreakB,
                        "Alpha" => $Alpha,
                        "Ticks" => $VoidTicks,
                        "Weight" => $Weight
                    ];
                }
                if ($DisplayColor == DISPLAY_AUTO) {
                    $DisplayR = $R;
                    $DisplayG = $G;
                    $DisplayB = $B;
                }

                $AxisID = $Serie["Axis"];
                $Mode = $Data["Axis"][$AxisID]["Display"];
                $Format = $Data["Axis"][$AxisID]["Format"];
                $Unit = $Data["Axis"][$AxisID]["Unit"];
                $Color = [
                    "R" => $R,
                    "G" => $G,
                    "B" => $B,
                    "Alpha" => $Alpha,
                    "Ticks" => $Ticks,
                    "Weight" => $Weight
                ];

                $PosArray = $this->scaleComputeY(
                    $Serie["Data"],
                    ["AxisID" => $Serie["Axis"]]
                );

                $this->DataSet->Data["Series"][$SerieName]["XOffset"] = 0;

                if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
                    if ($XDivs == 0) {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1) / 4;
                    } else {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1 - $XMargin * 2) / $XDivs;
                    }
                    $X = $this->GraphAreaX1 + $XMargin;
                    $LastX = null;
                    $LastY = null;

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    $LastGoodY = null;
                    $LastGoodX = null;
                    $Init = false;
                    foreach ($PosArray as $Key => $Y) {
                        if ($DisplayValues && $Serie["Data"][$Key] != VOID) {
                            if ($Y <= $LastY) {
                                $Align = TEXT_ALIGN_BOTTOMMIDDLE;
                                $Offset = $DisplayOffset;
                            } else {
                                $Align = TEXT_ALIGN_TOPMIDDLE;
                                $Offset = -$DisplayOffset;
                            }
                            $this->drawText(
                                $X,
                                $Y - $Offset - $Weight,
                                $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit),
                                ["R" => $DisplayR, "G" => $DisplayG, "B" => $DisplayB, "Align" => $Align]
                            );
                        }

                        if ($Y != VOID && $LastX != null && $LastY != null) {
                            $this->drawLine($LastX, $LastY, $X, $LastY, $Color);
                            $this->drawLine($X, $LastY, $X, $Y, $Color);
                            if ($ReCenter && $X + $XStep < $this->GraphAreaX2 - $XMargin) {
                                $this->drawLine($X, $Y, $X + $XStep, $Y, $Color);
                                if ($RecordImageMap) {
                                    $this->addToImageMap(
                                        "RECT",
                                        sprintf(
                                            '%s,%s,%s,%s',
                                            floor($X - $ImageMapPlotSize),
                                            floor($Y - $ImageMapPlotSize),
                                            floor($X + $XStep + $ImageMapPlotSize),
                                            floor($Y + $ImageMapPlotSize)
                                        ),
                                        $this->toHTMLColor($R, $G, $B),
                                        $SerieDescription,
                                        $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                    );
                                }
                            } else {
                                if ($RecordImageMap) {
                                    $this->addToImageMap(
                                        "RECT",
                                        sprintf(
                                            '%s,%s,%s,%s',
                                            floor($LastX - $ImageMapPlotSize),
                                            floor($LastY - $ImageMapPlotSize),
                                            floor($X + $ImageMapPlotSize),
                                            floor($LastY + $ImageMapPlotSize)
                                        ),
                                        $this->toHTMLColor($R, $G, $B),
                                        $SerieDescription,
                                        $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                    );
                                }
                            }
                        }

                        if ($Y != VOID && $LastY == null && $LastGoodY != null && !$BreakVoid) {
                            if ($ReCenter) {
                                $this->drawLine($LastGoodX + $XStep, $LastGoodY, $X, $LastGoodY, $BreakSettings);
                                if ($RecordImageMap) {
                                    $this->addToImageMap(
                                        "RECT",
                                        sprintf(
                                            '%s,%s,%s,%s',
                                            floor($LastGoodX + $XStep - $ImageMapPlotSize),
                                            floor($LastGoodY - $ImageMapPlotSize),
                                            floor($X + $ImageMapPlotSize),
                                            floor($LastGoodY + $ImageMapPlotSize)
                                        ),
                                        $this->toHTMLColor($R, $G, $B),
                                        $SerieDescription,
                                        $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                    );
                                }
                            } else {
                                $this->drawLine($LastGoodX, $LastGoodY, $X, $LastGoodY, $BreakSettings);
                                if ($RecordImageMap) {
                                    $this->addToImageMap(
                                        "RECT",
                                        sprintf(
                                            '%s,%s,%s,%s',
                                            floor($LastGoodX - $ImageMapPlotSize),
                                            floor($LastGoodY - $ImageMapPlotSize),
                                            floor($X + $ImageMapPlotSize),
                                            floor($LastGoodY + $ImageMapPlotSize)
                                        ),
                                        $SerieDescription,
                                        $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                    );
                                }
                            }

                            $this->drawLine($X, $LastGoodY, $X, $Y, $BreakSettings);
                            $LastGoodY = null;
                        } elseif (!$BreakVoid && $LastGoodY == null && $Y != VOID) {
                            $this->drawLine($this->GraphAreaX1 + $XMargin, $Y, $X, $Y, $BreakSettings);
                            if ($RecordImageMap) {
                                $this->addToImageMap(
                                    "RECT",
                                    sprintf(
                                        '%s,%s,%s,%s',
                                        floor($this->GraphAreaX1 + $XMargin - $ImageMapPlotSize),
                                        floor($Y - $ImageMapPlotSize),
                                        floor($X + $ImageMapPlotSize),
                                        floor($Y + $ImageMapPlotSize)
                                    ),
                                    $this->toHTMLColor($R, $G, $B),
                                    $SerieDescription,
                                    $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                );
                            }
                        }

                        if ($Y != VOID) {
                            $LastGoodY = $Y;
                            $LastGoodX = $X;
                        }
                        if ($Y == VOID) {
                            $Y = null;
                        }

                        if (!$Init && $ReCenter) {
                            $X = $X - $XStep / 2;
                            $Init = true;
                        }
                        $LastX = $X;
                        $LastY = $Y;
                        if ($LastX < $this->GraphAreaX1 + $XMargin) {
                            $LastX = $this->GraphAreaX1 + $XMargin;
                        }
                        $X = $X + $XStep;
                    }
                    if ($ReCenter) {
                        $this->drawLine($LastX, $LastY, $this->GraphAreaX2 - $XMargin, $LastY, $Color);
                        if ($RecordImageMap) {
                            $this->addToImageMap(
                                "RECT",
                                sprintf(
                                    '%s,%s,%s,%s',
                                    floor($LastX - $ImageMapPlotSize),
                                    floor($LastY - $ImageMapPlotSize),
                                    floor($this->GraphAreaX2 - $XMargin + $ImageMapPlotSize),
                                    floor($LastY + $ImageMapPlotSize)
                                ),
                                $this->toHTMLColor($R, $G, $B),
                                $SerieDescription,
                                $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                            );
                        }
                    }
                } else {
                    if ($XDivs == 0) {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1) / 4;
                    } else {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1 - $XMargin * 2) / $XDivs;
                    }
                    $Y = $this->GraphAreaY1 + $XMargin;
                    $LastX = null;
                    $LastY = null;

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    $LastGoodY = null;
                    $LastGoodX = null;
                    $Init = false;
                    foreach ($PosArray as $Key => $X) {
                        if ($DisplayValues && $Serie["Data"][$Key] != VOID) {
                            if ($X >= $LastX) {
                                $Align = TEXT_ALIGN_MIDDLELEFT;
                                $Offset = $DisplayOffset;
                            } else {
                                $Align = TEXT_ALIGN_MIDDLERIGHT;
                                $Offset = -$DisplayOffset;
                            }
                            $this->drawText(
                                $X + $Offset + $Weight,
                                $Y,
                                $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit),
                                [
                                    "R" => $DisplayR,
                                    "G" => $DisplayG,
                                    "B" => $DisplayB,
                                    "Align" => $Align
                                ]
                            );
                        }

                        if ($X != VOID && $LastX != null && $LastY != null) {
                            $this->drawLine($LastX, $LastY, $LastX, $Y, $Color);
                            $this->drawLine($LastX, $Y, $X, $Y, $Color);

                            if ($RecordImageMap) {
                                $this->addToImageMap(
                                    "RECT",
                                    sprintf(
                                        '%s,%s,%s,%s',
                                        floor($LastX - $ImageMapPlotSize),
                                        floor($LastY - $ImageMapPlotSize),
                                        floor($LastX + $XStep + $ImageMapPlotSize),
                                        floor($Y + $ImageMapPlotSize)
                                    ),
                                    $this->toHTMLColor($R, $G, $B),
                                    $SerieDescription,
                                    $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                );
                            }
                        }

                        if ($X != VOID && $LastX == null && $LastGoodY != null && !$BreakVoid) {
                            $this->drawLine(
                                $LastGoodX,
                                $LastGoodY,
                                $LastGoodX,
                                $LastGoodY + $YStep,
                                $Color
                            );
                            if ($RecordImageMap) {
                                $this->addToImageMap(
                                    "RECT",
                                    sprintf(
                                        '%s,%s,%s,%s',
                                        floor($LastGoodX - $ImageMapPlotSize),
                                        floor($LastGoodY - $ImageMapPlotSize),
                                        floor($LastGoodX + $ImageMapPlotSize),
                                        floor($LastGoodY + $YStep + $ImageMapPlotSize)
                                    ),
                                    $this->toHTMLColor($R, $G, $B),
                                    $SerieDescription,
                                    $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                );
                            }

                            $this->drawLine(
                                $LastGoodX,
                                $LastGoodY + $YStep,
                                $LastGoodX,
                                $Y,
                                $BreakSettings
                            );
                            if ($RecordImageMap) {
                                $this->addToImageMap(
                                    "RECT",
                                    sprintf(
                                        '%s,%s,%s,%s',
                                        floor($LastGoodX - $ImageMapPlotSize),
                                        floor($LastGoodY + $YStep - $ImageMapPlotSize),
                                        floor($LastGoodX + $ImageMapPlotSize),
                                        floor($YStep + $ImageMapPlotSize)
                                    ),
                                    $this->toHTMLColor($R, $G, $B),
                                    $SerieDescription,
                                    $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                );
                            }

                            $this->drawLine($LastGoodX, $Y, $X, $Y, $BreakSettings);
                            $LastGoodY = null;
                        } elseif ($X != VOID && $LastGoodY == null && !$BreakVoid) {
                            $this->drawLine($X, $this->GraphAreaY1 + $XMargin, $X, $Y, $BreakSettings);
                            if ($RecordImageMap) {
                                $this->addToImageMap(
                                    "RECT",
                                    sprintf(
                                        '%s,%s,%s,%s',
                                        floor($X - $ImageMapPlotSize),
                                        floor($this->GraphAreaY1 + $XMargin - $ImageMapPlotSize),
                                        floor($X + $ImageMapPlotSize),
                                        floor($Y + $ImageMapPlotSize)
                                    ),
                                    $this->toHTMLColor($R, $G, $B),
                                    $SerieDescription,
                                    $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                                );
                            }
                        }

                        if ($X != VOID) {
                            $LastGoodY = $Y;
                            $LastGoodX = $X;
                        }
                        if ($X == VOID) {
                            $X = null;
                        }

                        if (!$Init && $ReCenter) {
                            $Y = $Y - $YStep / 2;
                            $Init = true;
                        }
                        $LastX = $X;
                        $LastY = $Y;
                        if ($LastY < $this->GraphAreaY1 + $XMargin) {
                            $LastY = $this->GraphAreaY1 + $XMargin;
                        }
                        $Y = $Y + $YStep;
                    }
                    if ($ReCenter) {
                        $this->drawLine($LastX, $LastY, $LastX, $this->GraphAreaY2 - $XMargin, $Color);
                        if ($RecordImageMap) {
                            $this->addToImageMap(
                                "RECT",
                                sprintf(
                                    '%s,%s,%s,%s',
                                    floor($LastX - $ImageMapPlotSize),
                                    floor($LastY - $ImageMapPlotSize),
                                    floor($LastX + $ImageMapPlotSize),
                                    floor($this->GraphAreaY2 - $XMargin + $ImageMapPlotSize)
                                ),
                                $this->toHTMLColor($R, $G, $B),
                                $SerieDescription,
                                $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit)
                            );
                        }
                    }
                }
            }
        }
    }
853524
public static function create($x, $y, $width, $height) : Box
    {
        return new self($x, $y, $width, $height);
    }
150767
public function drawSurface(array $Format = [])
    {
        $Palette = isset($Format["Palette"]) ? $Format["Palette"] : null;
        $ShadeR1 = isset($Format["ShadeR1"]) ? $Format["ShadeR1"] : 77;
        $ShadeG1 = isset($Format["ShadeG1"]) ? $Format["ShadeG1"] : 205;
        $ShadeB1 = isset($Format["ShadeB1"]) ? $Format["ShadeB1"] : 21;
        $ShadeA1 = isset($Format["ShadeA1"]) ? $Format["ShadeA1"] : 40;
        $ShadeR2 = isset($Format["ShadeR2"]) ? $Format["ShadeR2"] : 227;
        $ShadeG2 = isset($Format["ShadeG2"]) ? $Format["ShadeG2"] : 135;
        $ShadeB2 = isset($Format["ShadeB2"]) ? $Format["ShadeB2"] : 61;
        $ShadeA2 = isset($Format["ShadeA2"]) ? $Format["ShadeA2"] : 100;
        $Border = isset($Format["Border"]) ? $Format["Border"] : false;
        $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 0;
        $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 0;
        $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 0;
        $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : -1;
        $Padding = isset($Format["Padding"]) ? $Format["Padding"] : 1;

        $X0 = $this->pChartObject->GraphAreaX1;
        $Y0 = $this->pChartObject->GraphAreaY1;
        $XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
        $YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);

        for ($X = 0; $X <= $this->GridSizeX; $X++) {
            for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
                $Value = $this->Points[$X][$Y];

                if ($Value != UNKNOWN && $Value != IGNORED) {
                    $X1 = floor($X0 + $X * $XSize) + $Padding;
                    $Y1 = floor($Y0 + $Y * $YSize) + $Padding;
                    $X2 = floor($X0 + $X * $XSize + $XSize);
                    $Y2 = floor($Y0 + $Y * $YSize + $YSize);

                    if ($Palette != null) {
                        if (isset($Palette[$Value]) && isset($Palette[$Value]["R"])) {
                            $R = $Palette[$Value]["R"];
                        } else {
                            $R = 0;
                        }

                        if (isset($Palette[$Value]) && isset($Palette[$Value]["G"])) {
                            $G = $Palette[$Value]["G"];
                        } else {
                            $G = 0;
                        }

                        if (isset($Palette[$Value]) && isset($Palette[$Value]["B"])) {
                            $B = $Palette[$Value]["B"];
                        } else {
                            $B = 0;
                        }
                        if (isset($Palette[$Value]) && isset($Palette[$Value]["Alpha"])) {
                            $Alpha = $Palette[$Value]["Alpha"];
                        } else {
                            $Alpha = 1000;
                        }
                    } else {
                        $R = (($ShadeR2 - $ShadeR1) / 100) * $Value + $ShadeR1;
                        $G = (($ShadeG2 - $ShadeG1) / 100) * $Value + $ShadeG1;
                        $B = (($ShadeB2 - $ShadeB1) / 100) * $Value + $ShadeB1;
                        $Alpha = (($ShadeA2 - $ShadeA1) / 100) * $Value + $ShadeA1;
                    }

                    $Settings = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
                    if ($Border) {
                        $Settings["BorderR"] = $BorderR;
                        $Settings["BorderG"] = $BorderG;
                        $Settings["BorderB"] = $BorderB;
                    }
                    if ($Surrounding != -1) {
                        $Settings["BorderR"] = $R + $Surrounding;
                        $Settings["BorderG"] = $G + $Surrounding;
                        $Settings["BorderB"] = $B + $Surrounding;
                    }

                    $this->pChartObject->drawFilledRectangle($X1, $Y1, $X2 - 1, $Y2 - 1, $Settings);
                }
            }
        }
    }
808123
public function draw2DRing($X, $Y, array $Format = [])
    {
        $OuterRadius = isset($Format["Radius"]) ? $Format["Radius"] : 60; // For compatibility
        $OuterRadius = isset($Format["OuterRadius"]) ? $Format["OuterRadius"] : $OuterRadius;
        $Precision = isset($Format["Precision"]) ? $Format["Precision"] : 0;
        $InnerRadius = isset($Format["InnerRadius"]) ? $Format["InnerRadius"] : 30;
        $Border = isset($Format["Border"]) ? $Format["Border"] : false;
        $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 255;
        $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 255;
        $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 255;
        $BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : 100;
        $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;
        $WriteValues = isset($Format["WriteValues"]) ? $Format["WriteValues"] : null; //PIE_VALUE_PERCENTAGE
        $ValuePadding = isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 5;
        $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;

        /* 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 = null;
        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 = 0;
        } // count($Values)

        /* Compute the scale */
        $ScaleFactor = (360 - $WastedAngular) / $SerieSum;

        $RestoreShadow = $this->pChartObject->Shadow;
        if ($this->pChartObject->Shadow) {
            $this->pChartObject->Shadow = false;

            $ShadowFormat = $Format;
            $ShadowFormat["Shadow"] = true;
            $this->draw2DRing(
                $X + $this->pChartObject->ShadowX,
                $Y + $this->pChartObject->ShadowY,
                $ShadowFormat
            );
        }

        /* Draw the polygon pie elements */
        $Step = 360 / (2 * PI * $OuterRadius);
        $Offset = 0;
        $ID = 0;
        foreach ($Values as $Key => $Value) {
            if ($Shadow) {
                $Settings = [
                    "R" => $this->pChartObject->ShadowR,
                    "G" => $this->pChartObject->ShadowG,
                    "B" => $this->pChartObject->ShadowB,
                    "Alpha" => $this->pChartObject->Shadowa
                ];
                $BorderColor = $Settings;
            } else {
                if (!isset($Palette[$ID]["R"])) {
                    $Color = $this->pChartObject->getRandomColor();
                    $Palette[$ID] = $Color;
                    $this->pDataObject->savePalette($ID, $Color);
                }
                $Settings = [
                    "R" => $Palette[$ID]["R"],
                    "G" => $Palette[$ID]["G"],
                    "B" => $Palette[$ID]["B"],
                    "Alpha" => $Palette[$ID]["Alpha"]
                ];

                if ($Border) {
                    $BorderColor = [
                        "R" => $BorderR,
                        "G" => $BorderG,
                        "B" => $BorderB,
                        "Alpha" => $BorderAlpha
                    ];
                } else {
                    $BorderColor = $Settings;
                }
            }

            $Plots = [];
            $Boundaries = [];
            $AAPixels = [];
            $EndAngle = $Offset + ($Value * $ScaleFactor);
            if ($EndAngle > 360) {
                $EndAngle = 360;
            }
            for ($i = $Offset; $i <= $EndAngle; $i = $i + $Step) {
                $Xc = cos(($i - 90) * PI / 180) * $OuterRadius + $X;
                $Yc = sin(($i - 90) * PI / 180) * $OuterRadius + $Y;

                if (!isset($Boundaries[0]["X1"])) {
                    $Boundaries[0]["X1"] = $Xc;
                    $Boundaries[0]["Y1"] = $Yc;
                }
                $AAPixels[] = [$Xc, $Yc];

                if ($i < 90) {
                    $Yc++;
                }
                if ($i > 180 && $i < 270) {
                    $Xc++;
                }
                if ($i >= 270) {
                    $Xc++;
                    $Yc++;
                }

                $Plots[] = $Xc;
                $Plots[] = $Yc;
            }
            $Boundaries[1]["X1"] = $Xc;
            $Boundaries[1]["Y1"] = $Yc;
            $Lasti = $EndAngle;

            for ($i = $EndAngle; $i >= $Offset; $i = $i - $Step) {
                $Xc = cos(($i - 90) * PI / 180) * ($InnerRadius - 1) + $X;
                $Yc = sin(($i - 90) * PI / 180) * ($InnerRadius - 1) + $Y;

                if (!isset($Boundaries[1]["X2"])) {
                    $Boundaries[1]["X2"] = $Xc;
                    $Boundaries[1]["Y2"] = $Yc;
                }
                $AAPixels[] = [$Xc, $Yc];

                $Xc = cos(($i - 90) * PI / 180) * $InnerRadius + $X;
                $Yc = sin(($i - 90) * PI / 180) * $InnerRadius + $Y;

                if ($i < 90) {
                    $Yc++;
                }
                if ($i > 180 && $i < 270) {
                    $Xc++;
                }
                if ($i >= 270) {
                    $Xc++;
                    $Yc++;
                }

                $Plots[] = $Xc;
                $Plots[] = $Yc;
            }
            $Boundaries[0]["X2"] = $Xc;
            $Boundaries[0]["Y2"] = $Yc;

            /* Draw the polygon */
            $this->pChartObject->drawPolygon($Plots, $Settings);
            if ($RecordImageMap && !$Shadow) {
                $this->pChartObject->addToImageMap(
                    "POLY",
                    $this->arraySerialize($Plots),
                    $this->pChartObject->toHTMLColor(
                        $Palette[$ID]["R"],
                        $Palette[$ID]["G"],
                        $Palette[$ID]["B"]
                    ),
                    $Data["Series"][$Data["Abscissa"]]["Data"][$Key],
                    $Value
                );
            }

            /* Smooth the edges using AA */
            foreach ($AAPixels as $Pos) {
                $this->pChartObject->drawAntialiasPixel($Pos[0], $Pos[1], $BorderColor);
            }
            $this->pChartObject->drawLine(
                $Boundaries[0]["X1"],
                $Boundaries[0]["Y1"],
                $Boundaries[0]["X2"],
                $Boundaries[0]["Y2"],
                $BorderColor
            );
            $this->pChartObject->drawLine(
                $Boundaries[1]["X1"],
                $Boundaries[1]["Y1"],
                $Boundaries[1]["X2"],
                $Boundaries[1]["Y2"],
                $BorderColor
            );

            if ($DrawLabels && !$Shadow) {
                if ($LabelColor == PIE_LABEL_COLOR_AUTO) {
                    $Settings = [
                        "FillR" => $Palette[$ID]["R"],
                        "FillG" => $Palette[$ID]["G"],
                        "FillB" => $Palette[$ID]["B"],
                        "Alpha" => $Palette[$ID]["Alpha"]
                    ];
                } else {
                    $Settings = [
                        "FillR" => $LabelR,
                        "FillG" => $LabelG,
                        "FillB" => $LabelB,
                        "Alpha" => $LabelAlpha
                    ];
                }

                $Angle = ($EndAngle - $Offset) / 2 + $Offset;
                $Xc = cos(($Angle - 90) * PI / 180) * $OuterRadius + $X;
                $Yc = sin(($Angle - 90) * PI / 180) * $OuterRadius + $Y;

                $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];

                if ($LabelStacked) {
                    $this->writePieLabel($Xc, $Yc, $Label, $Angle, $Settings, true, $X, $Y, $OuterRadius);
                } else {
                    $this->writePieLabel($Xc, $Yc, $Label, $Angle, $Settings, false);
                }
            }

            $Offset = $Lasti;
            $ID++;
        }

        if ($DrawLabels && $LabelStacked) {
            $this->writeShiftedLabels();
        }

        if ($WriteValues && !$Shadow) {
            $Step = 360 / (2 * PI * $OuterRadius);
            $Offset = 0;
            foreach ($Values as $Key => $Value) {
                $EndAngle = $Offset + ($Value * $ScaleFactor);
                if ($EndAngle > 360) {
                    $EndAngle = 360;
                }

                $Angle = $Offset + ($Value * $ScaleFactor) / 2;
                if ($ValuePosition == PIE_VALUE_OUTSIDE) {
                    $Xc = cos(($Angle - 90) * PI / 180) * ($OuterRadius + $ValuePadding) + $X;
                    $Yc = sin(($Angle - 90) * PI / 180) * ($OuterRadius + $ValuePadding) + $Y;
                    if ($Angle >= 0 && $Angle <= 90) {
                        $Align = TEXT_ALIGN_BOTTOMLEFT;
                    }
                    if ($Angle > 90 && $Angle <= 180) {
                        $Align = TEXT_ALIGN_TOPLEFT;
                    }
                    if ($Angle > 180 && $Angle <= 270) {
                        $Align = TEXT_ALIGN_TOPRIGHT;
                    }
                    if ($Angle > 270) {
                        $Align = TEXT_ALIGN_BOTTOMRIGHT;
                    }
                } else {
                    $Xc = cos(($Angle - 90) * PI / 180)
                        * (($OuterRadius - $InnerRadius) / 2 + $InnerRadius)
                        + $X
                    ;
                    $Yc = sin(($Angle - 90) * PI / 180)
                        * (($OuterRadius - $InnerRadius) / 2 + $InnerRadius)
                        + $Y
                    ;
                    $Align = TEXT_ALIGN_MIDDLEMIDDLE;
                }

                if ($WriteValues == PIE_VALUE_PERCENTAGE) {
                    $Display = round((100 / $SerieSum) * $Value, $Precision) . "%";
                } elseif ($WriteValues == PIE_VALUE_NATURAL) {
                    $Display = $Value . $ValueSuffix;
                } else {
                    $Display = "";
                }
                $this->pChartObject->drawText(
                    $Xc,
                    $Yc,
                    $Display,
                    ["Align" => $Align, "R" => $ValueR, "G" => $ValueG, "B" => $ValueB]
                );
                $Offset = $EndAngle;
            }
        }

        $this->pChartObject->Shadow = $RestoreShadow;

        return PIE_RENDERED;
    }
605847
public function draw($target, $format)
    {
        /** @var ClassMetadata[] $mds */
        $mds = $this->em->getMetadataFactory()->getAllMetadata();

        // Create graph
        $g = new Graph();

        // Create all boxes
        foreach ($mds as $m) {
            $g->addBox($m->getReflectionClass()->getName());
        }

        // Add all data
        foreach ($mds as $m) {
            $ref = $m->getReflectionClass();

            // Define this entity
            $box = $g->getBox($ref->getName());

            // Class extension
            if (false !== $parent = $ref->getParentClass()) {
                $box->addExtends($parent->getName());
            }

            // Fields
            foreach ($m->getFieldNames() as $field) {
                $property = $this->findProperty($ref, $field);
                $visibility = $property->isPrivate() ? Box::VISIBILITY_PRIVATE : ($property->isProtected() ? Box::VISIBILITY_PROTECTED : Box::VISIBILITY_PUBLIC);
                $isNullable = $m->isNullable($field);
                $box->addParameter($field, $m->getTypeOfField($field), $visibility, !$isNullable);
            }

            // Associations
            foreach ($m->getAssociationNames() as $field) {
                $mapping = $m->getAssociationMapping($field);
                switch ($mapping['type']) {
                    case ClassMetadataInfo::MANY_TO_MANY:
                        if ($mapping['isOwningSide']) {
                            $box->addManyToMany(
                                $mapping['targetEntity'],
                                $mapping['fieldName']
                            );
                        }
                        break;
                    case ClassMetadataInfo::MANY_TO_ONE:
                        if ($mapping['isOwningSide']) {
                            $box->addManyToOne(
                                $mapping['targetEntity'],
                                $mapping['fieldName']
                            );
                        }
                        break;
                    case ClassMetadataInfo::ONE_TO_MANY:
                        if ($mapping['isOwningSide']) {
                            $box->addOneToMany(
                                $mapping['targetEntity'],
                                $mapping['fieldName']
                            );
                        }
                        break;
                    case ClassMetadataInfo::ONE_TO_ONE:
                        if ($mapping['isOwningSide']) {
                            $box->addOneToOne(
                                $mapping['targetEntity'],
                                $mapping['fieldName']
                            );
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        return $this->plantUML->dump($g, $target, $format);
    }
881555
function calculatePosition( $parameters, $width, $height )
    {
        $xAxis = eZImageObject::initializeAxis( $parameters, 'x' );
        $yAxis = eZImageObject::initializeAxis( $parameters, 'y' );
        $x = eZImageObject::calculateAxisPlacement( $xAxis['value'], $xAxis['placement'], $xAxis['alignment'],
                                                    0, $this->width(), $width );
        $y = eZImageObject::calculateAxisPlacement( $yAxis['value'], $yAxis['placement'], $yAxis['alignment'],
                                                    0, $this->height(), $height );
        return array( 'x' => $x,
                      'y' => $y );
    }
759448
public function crop($x, $y, $width, $height)
    {
        $oCanvas = imagecreatetruecolor($width, $height);
        imagecopyresampled($oCanvas, $this->oImg, 0, 0, $x, $y, $width, $height, $width, $height);
        $this->oImg = $oCanvas;
        return $this;
    }
69460
public function drawFilledStepChart(array $Format = [])
    {
        $ReCenter = isset($Format["ReCenter"]) ? $Format["ReCenter"] : true;
        $DisplayValues = isset($Format["DisplayValues"]) ? $Format["DisplayValues"] : false;
        $DisplayOffset = isset($Format["DisplayOffset"]) ? $Format["DisplayOffset"] : 2;
        $DisplayColor = isset($Format["DisplayColor"]) ? $Format["DisplayColor"] : DISPLAY_MANUAL;
        $ForceTransparency = isset($Format["ForceTransparency"]) ? $Format["ForceTransparency"] : null;
        $DisplayR = isset($Format["DisplayR"]) ? $Format["DisplayR"] : 0;
        $DisplayG = isset($Format["DisplayG"]) ? $Format["DisplayG"] : 0;
        $DisplayB = isset($Format["DisplayB"]) ? $Format["DisplayB"] : 0;
        $AroundZero = isset($Format["AroundZero"]) ? $Format["AroundZero"] : true;

        $this->LastChartLayout = CHART_LAST_LAYOUT_REGULAR;

        $Data = $this->DataSet->getData();
        list($XMargin, $XDivs) = $this->scaleGetXSettings();
        foreach ($Data["Series"] as $SerieName => $Serie) {
            if ($Serie["isDrawable"] == true && $SerieName != $Data["Abscissa"]) {
                $R = $Serie["Color"]["R"];
                $G = $Serie["Color"]["G"];
                $B = $Serie["Color"]["B"];
                $Alpha = $Serie["Color"]["Alpha"];

                if ($DisplayColor == DISPLAY_AUTO) {
                    $DisplayR = $R;
                    $DisplayG = $G;
                    $DisplayB = $B;
                }

                $AxisID = $Serie["Axis"];
                $Format = $Data["Axis"][$AxisID]["Format"];

                $Color = ["R" => $R, "G" => $G, "B" => $B];
                if ($ForceTransparency != null) {
                    $Color["Alpha"] = $ForceTransparency;
                } else {
                    $Color["Alpha"] = $Alpha;
                }

                $PosArray = $this->scaleComputeY($Serie["Data"], ["AxisID" => $Serie["Axis"]]);
                $YZero = $this->scaleComputeY(0, ["AxisID" => $Serie["Axis"]]);

                $this->DataSet->Data["Series"][$SerieName]["XOffset"] = 0;

                if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
                    if ($YZero > $this->GraphAreaY2 - 1) {
                        $YZero = $this->GraphAreaY2 - 1;
                    }
                    if ($YZero < $this->GraphAreaY1 + 1) {
                        $YZero = $this->GraphAreaY1 + 1;
                    }

                    if ($XDivs == 0) {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1) / 4;
                    } else {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1 - $XMargin * 2) / $XDivs;
                    }
                    $X = $this->GraphAreaX1 + $XMargin;
                    $LastX = null;
                    $LastY = null;

                    if (!$AroundZero) {
                        $YZero = $this->GraphAreaY2 - 1;
                    }

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    $LastGoodY = null;
                    $LastGoodX = null;
                    $Points = [];
                    $Init = false;
                    foreach ($PosArray as $Key => $Y) {
                        if ($Y == VOID && $LastX != null && $LastY != null && count($Points)) {
                            $Points[] = $LastX;
                            $Points[] = $LastY;
                            $Points[] = $X;
                            $Points[] = $LastY;
                            $Points[] = $X;
                            $Points[] = $YZero;
                            $this->drawPolygon($Points, $Color);
                            $Points = [];
                        }

                        if ($Y != VOID && $LastX != null && $LastY != null) {
                            if (count($Points)) {
                                $Points[] = $LastX;
                                $Points[] = $YZero;
                            }
                            $Points[] = $LastX;
                            $Points[] = $LastY;
                            $Points[] = $X;
                            $Points[] = $LastY;
                            $Points[] = $X;
                            $Points[] = $Y;
                        }

                        if ($Y != VOID) {
                            $LastGoodY = $Y;
                            $LastGoodX = $X;
                        }
                        if ($Y == VOID) {
                            $Y = null;
                        }

                        if (!$Init && $ReCenter) {
                            $X = $X - $XStep / 2;
                            $Init = true;
                        }
                        $LastX = $X;
                        $LastY = $Y;
                        if ($LastX < $this->GraphAreaX1 + $XMargin) {
                            $LastX = $this->GraphAreaX1 + $XMargin;
                        }
                        $X = $X + $XStep;
                    }

                    if ($ReCenter) {
                        $Points[] = $LastX + $XStep / 2;
                        $Points[] = $LastY;
                        $Points[] = $LastX + $XStep / 2;
                        $Points[] = $YZero;
                    } else {
                        $Points[] = $LastX;
                        $Points[] = $YZero;
                    }

                    $this->drawPolygon($Points, $Color);
                } else {
                    if ($YZero < $this->GraphAreaX1 + 1) {
                        $YZero = $this->GraphAreaX1 + 1;
                    }
                    if ($YZero > $this->GraphAreaX2 - 1) {
                        $YZero = $this->GraphAreaX2 - 1;
                    }

                    if ($XDivs == 0) {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1) / 4;
                    } else {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1 - $XMargin * 2) / $XDivs;
                    }
                    $Y = $this->GraphAreaY1 + $XMargin;
                    $LastX = null;
                    $LastY = null;

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    $LastGoodY = null;
                    $LastGoodX = null;
                    $Points = [];
                    foreach ($PosArray as $Key => $X) {
                        if ($X == VOID && $LastX != null && $LastY != null && count($Points)) {
                            $Points[] = $LastX;
                            $Points[] = $LastY;
                            $Points[] = $LastX;
                            $Points[] = $Y;
                            $Points[] = $YZero;
                            $Points[] = $Y;
                            $this->drawPolygon($Points, $Color);
                            $Points = [];
                        }

                        if ($X != VOID && $LastX != null && $LastY != null) {
                            if (count($Points)) {
                                $Points[] = $YZero;
                                $Points[] = $LastY;
                            }
                            $Points[] = $LastX;
                            $Points[] = $LastY;
                            $Points[] = $LastX;
                            $Points[] = $Y;
                            $Points[] = $X;
                            $Points[] = $Y;
                        }

                        if ($X != VOID) {
                            $LastGoodY = $Y;
                            $LastGoodX = $X;
                        }
                        if ($X == VOID) {
                            $X = null;
                        }

                        if ($LastX == null && $ReCenter) {
                            $Y = $Y - $YStep / 2;
                        }
                        $LastX = $X;
                        $LastY = $Y;
                        if ($LastY < $this->GraphAreaY1 + $XMargin) {
                            $LastY = $this->GraphAreaY1 + $XMargin;
                        }
                        $Y = $Y + $YStep;
                    }

                    if ($ReCenter) {
                        $Points[] = $LastX;
                        $Points[] = $LastY + $YStep / 2;
                        $Points[] = $YZero;
                        $Points[] = $LastY + $YStep / 2;
                    } else {
                        $Points[] = $YZero;
                        $Points[] = $LastY;
                    }

                    $this->drawPolygon($Points, $Color);
                }
            }
        }
    }
828446
public function drawAreaChart(array $Format = [])
    {
        $DisplayValues = isset($Format["DisplayValues"]) ? $Format["DisplayValues"] : false;
        $DisplayOffset = isset($Format["DisplayOffset"]) ? $Format["DisplayOffset"] : 2;
        $DisplayColor = isset($Format["DisplayColor"]) ? $Format["DisplayColor"] : DISPLAY_MANUAL;
        $DisplayR = isset($Format["DisplayR"]) ? $Format["DisplayR"] : 0;
        $DisplayG = isset($Format["DisplayG"]) ? $Format["DisplayG"] : 0;
        $DisplayB = isset($Format["DisplayB"]) ? $Format["DisplayB"] : 0;
        $ForceTransparency = isset($Format["ForceTransparency"]) ? $Format["ForceTransparency"] : 25;
        $AroundZero = isset($Format["AroundZero"]) ? $Format["AroundZero"] : true;
        $Threshold = isset($Format["Threshold"]) ? $Format["Threshold"] : null;

        $this->LastChartLayout = CHART_LAST_LAYOUT_REGULAR;

        $Data = $this->DataSet->getData();
        list($XMargin, $XDivs) = $this->scaleGetXSettings();

        foreach ($Data["Series"] as $SerieName => $Serie) {
            if ($Serie["isDrawable"] == true && $SerieName != $Data["Abscissa"]) {
                $R = $Serie["Color"]["R"];
                $G = $Serie["Color"]["G"];
                $B = $Serie["Color"]["B"];
                $Alpha = $Serie["Color"]["Alpha"];
                $Ticks = $Serie["Ticks"];
                if ($DisplayColor == DISPLAY_AUTO) {
                    $DisplayR = $R;
                    $DisplayG = $G;
                    $DisplayB = $B;
                }

                $AxisID = $Serie["Axis"];
                $Mode = $Data["Axis"][$AxisID]["Display"];
                $Format = $Data["Axis"][$AxisID]["Format"];
                $Unit = $Data["Axis"][$AxisID]["Unit"];

                $PosArray = $this->scaleComputeY($Serie["Data"], ["AxisID" => $Serie["Axis"]]);
                $YZero = $this->scaleComputeY(0, ["AxisID" => $Serie["Axis"]]);

                if ($Threshold != null) {
                    foreach ($Threshold as $Key => $Params) {
                        $Threshold[$Key]["MinX"] = $this->scaleComputeY(
                            $Params["Min"],
                            ["AxisID" => $Serie["Axis"]]
                        );
                        $Threshold[$Key]["MaxX"] = $this->scaleComputeY(
                            $Params["Max"],
                            ["AxisID" => $Serie["Axis"]]
                        );
                    }
                }

                $this->DataSet->Data["Series"][$SerieName]["XOffset"] = 0;

                if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
                    if ($YZero > $this->GraphAreaY2 - 1) {
                        $YZero = $this->GraphAreaY2 - 1;
                    }

                    $Areas = [];
                    $AreaID = 0;
                    $Areas[$AreaID][] = $this->GraphAreaX1 + $XMargin;
                    if ($AroundZero) {
                        $Areas[$AreaID][] = $YZero;
                    } else {
                        $Areas[$AreaID][] = $this->GraphAreaY2 - 1;
                    }

                    if ($XDivs == 0) {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1) / 4;
                    } else {
                        $XStep = ($this->GraphAreaX2 - $this->GraphAreaX1 - $XMargin * 2) / $XDivs;
                    }
                    $X = $this->GraphAreaX1 + $XMargin;
                    $LastX = null;
                    $LastY = null;

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    foreach ($PosArray as $Key => $Y) {
                        if ($DisplayValues && $Serie["Data"][$Key] != VOID) {
                            if ($Serie["Data"][$Key] > 0) {
                                $Align = TEXT_ALIGN_BOTTOMMIDDLE;
                                $Offset = $DisplayOffset;
                            } else {
                                $Align = TEXT_ALIGN_TOPMIDDLE;
                                $Offset = -$DisplayOffset;
                            }
                            $this->drawText(
                                $X,
                                $Y - $Offset,
                                $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit),
                                ["R" => $DisplayR, "G" => $DisplayG, "B" => $DisplayB, "Align" => $Align]
                            );
                        }

                        if ($Y == VOID && isset($Areas[$AreaID])) {
                            if ($LastX == null) {
                                $Areas[$AreaID][] = $X;
                            } else {
                                $Areas[$AreaID][] = $LastX;
                            }

                            if ($AroundZero) {
                                $Areas[$AreaID][] = $YZero;
                            } else {
                                $Areas[$AreaID][] = $this->GraphAreaY2 - 1;
                            }
                            $AreaID++;
                        } elseif ($Y != VOID) {
                            if (!isset($Areas[$AreaID])) {
                                $Areas[$AreaID][] = $X;
                                if ($AroundZero) {
                                    $Areas[$AreaID][] = $YZero;
                                } else {
                                    $Areas[$AreaID][] = $this->GraphAreaY2 - 1;
                                }
                            }

                            $Areas[$AreaID][] = $X;
                            $Areas[$AreaID][] = $Y;
                        }

                        $LastX = $X;
                        $X = $X + $XStep;
                    }
                    $Areas[$AreaID][] = $LastX;
                    if ($AroundZero) {
                        $Areas[$AreaID][] = $YZero;
                    } else {
                        $Areas[$AreaID][] = $this->GraphAreaY2 - 1;
                    }

                    /* Handle shadows in the areas */
                    if ($this->Shadow) {
                        $ShadowArea = [];
                        foreach ($Areas as $Key => $Points) {
                            $ShadowArea[$Key] = [];
                            foreach ($Points as $Key2 => $Value) {
                                if ($Key2 % 2 == 0) {
                                    $ShadowArea[$Key][] = $Value + $this->ShadowX;
                                } else {
                                    $ShadowArea[$Key][] = $Value + $this->ShadowY;
                                }
                            }
                        }

                        foreach ($ShadowArea as $Key => $Points) {
                            $this->drawPolygonChart(
                                $Points,
                                [
                                    "R" => $this->ShadowR,
                                    "G" => $this->ShadowG,
                                    "B" => $this->ShadowB,
                                    "Alpha" => $this->Shadowa
                                ]
                            );
                        }
                    }

                    $Alpha = $ForceTransparency != null ? $ForceTransparency : $Alpha;
                    $Color = [
                        "R" => $R,
                        "G" => $G,
                        "B" => $B,
                        "Alpha" => $Alpha,
                        "Threshold" => $Threshold
                    ];

                    foreach ($Areas as $Key => $Points) {
                        $this->drawPolygonChart($Points, $Color);
                    }
                } else {
                    if ($YZero < $this->GraphAreaX1 + 1) {
                        $YZero = $this->GraphAreaX1 + 1;
                    }
                    if ($YZero > $this->GraphAreaX2 - 1) {
                        $YZero = $this->GraphAreaX2 - 1;
                    }

                    $Areas = [];
                    $AreaID = 0;
                    if ($AroundZero) {
                        $Areas[$AreaID][] = $YZero;
                    } else {
                        $Areas[$AreaID][] = $this->GraphAreaX1 + 1;
                    }
                    $Areas[$AreaID][] = $this->GraphAreaY1 + $XMargin;

                    if ($XDivs == 0) {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1) / 4;
                    } else {
                        $YStep = ($this->GraphAreaY2 - $this->GraphAreaY1 - $XMargin * 2) / $XDivs;
                    }
                    $Y = $this->GraphAreaY1 + $XMargin;
                    $LastX = null;
                    $LastY = null;

                    if (!is_array($PosArray)) {
                        $Value = $PosArray;
                        $PosArray = [];
                        $PosArray[0] = $Value;
                    }
                    foreach ($PosArray as $Key => $X) {
                        if ($DisplayValues && $Serie["Data"][$Key] != VOID) {
                            if ($Serie["Data"][$Key] > 0) {
                                $Align = TEXT_ALIGN_BOTTOMMIDDLE;
                                $Offset = $DisplayOffset;
                            } else {
                                $Align = TEXT_ALIGN_TOPMIDDLE;
                                $Offset = -$DisplayOffset;
                            }
                            $this->drawText(
                                $X + $Offset,
                                $Y,
                                $this->scaleFormat($Serie["Data"][$Key], $Mode, $Format, $Unit),
                                [
                                    "Angle" => 270,
                                    "R" => $DisplayR,
                                    "G" => $DisplayG,
                                    "B" => $DisplayB,
                                    "Align" => $Align
                                ]
                            );
                        }

                        if ($X == VOID && isset($Areas[$AreaID])) {
                            if ($AroundZero) {
                                $Areas[$AreaID][] = $YZero;
                            } else {
                                $Areas[$AreaID][] = $this->GraphAreaX1 + 1;
                            }

                            if ($LastY == null) {
                                $Areas[$AreaID][] = $Y;
                            } else {
                                $Areas[$AreaID][] = $LastY;
                            }

                            $AreaID++;
                        } elseif ($X != VOID) {
                            if (!isset($Areas[$AreaID])) {
                                if ($AroundZero) {
                                    $Areas[$AreaID][] = $YZero;
                                } else {
                                    $Areas[$AreaID][] = $this->GraphAreaX1 + 1;
                                }
                                $Areas[$AreaID][] = $Y;
                            }

                            $Areas[$AreaID][] = $X;
                            $Areas[$AreaID][] = $Y;
                        }

                        $LastX = $X;
                        $LastY = $Y;
                        $Y = $Y + $YStep;
                    }
                    if ($AroundZero) {
                        $Areas[$AreaID][] = $YZero;
                    } else {
                        $Areas[$AreaID][] = $this->GraphAreaX1 + 1;
                    }
                    $Areas[$AreaID][] = $LastY;

                    /* Handle shadows in the areas */
                    if ($this->Shadow) {
                        $ShadowArea = [];
                        foreach ($Areas as $Key => $Points) {
                            $ShadowArea[$Key] = [];
                            foreach ($Points as $Key2 => $Value) {
                                if ($Key2 % 2 == 0) {
                                    $ShadowArea[$Key][] = $Value + $this->ShadowX;
                                } else {
                                    $ShadowArea[$Key][] = $Value + $this->ShadowY;
                                }
                            }
                        }

                        foreach ($ShadowArea as $Key => $Points) {
                            $this->drawPolygonChart(
                                $Points,
                                [
                                    "R" => $this->ShadowR,
                                    "G" => $this->ShadowG,
                                    "B" => $this->ShadowB,
                                    "Alpha" => $this->Shadowa
                                ]
                            );
                        }
                    }

                    $Alpha = $ForceTransparency != null ? $ForceTransparency : $Alpha;
                    $Color = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha, "Threshold" => $Threshold];

                    foreach ($Areas as $Key => $Points) {
                        $this->drawPolygonChart($Points, $Color);
                    }
                }
            }
        }
    }
461710
public function drawContour($Threshold, array $Format = [])
    {
        $R = isset($Format["R"]) ? $Format["R"] : 0;
        $G = isset($Format["G"]) ? $Format["G"] : 0;
        $B = isset($Format["B"]) ? $Format["B"] : 0;
        $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
        $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : 3;
        $Padding = isset($Format["Padding"]) ? $Format["Padding"] : 0;

        $X0 = $this->pChartObject->GraphAreaX1;
        $Y0 = $this->pChartObject->GraphAreaY1;
        $XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
        $YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);

        $Color = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha, "Ticks" => $Ticks];

        for ($X = 0; $X <= $this->GridSizeX; $X++) {
            for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
                $Value = $this->Points[$X][$Y];

                if ($Value != UNKNOWN && $Value != IGNORED && $Value >= $Threshold) {
                    $X1 = floor($X0 + $X * $XSize) + $Padding;
                    $Y1 = floor($Y0 + $Y * $YSize) + $Padding;
                    $X2 = floor($X0 + $X * $XSize + $XSize);
                    $Y2 = floor($Y0 + $Y * $YSize + $YSize);

                    if ($X > 0 && $this->Points[$X - 1][$Y] != UNKNOWN
                        && $this->Points[$X - 1][$Y] != IGNORED
                        && $this->Points[$X - 1][$Y] < $Threshold
                    ) {
                        $this->pChartObject->drawLine($X1, $Y1, $X1, $Y2, $Color);
                    }
                    if ($Y > 0 && $this->Points[$X][$Y - 1] != UNKNOWN
                        && $this->Points[$X][$Y - 1] != IGNORED
                        && $this->Points[$X][$Y - 1] < $Threshold
                    ) {
                        $this->pChartObject->drawLine($X1, $Y1, $X2, $Y1, $Color);
                    }
                    if ($X < $this->GridSizeX
                        && $this->Points[$X + 1][$Y] != UNKNOWN
                        && $this->Points[$X + 1][$Y] != IGNORED
                        && $this->Points[$X + 1][$Y] < $Threshold
                    ) {
                        $this->pChartObject->drawLine($X2, $Y1, $X2, $Y2, $Color);
                    }
                    if ($Y < $this->GridSizeY
                        && $this->Points[$X][$Y + 1] != UNKNOWN
                        && $this->Points[$X][$Y + 1] != IGNORED
                        && $this->Points[$X][$Y + 1] < $Threshold
                    ) {
                        $this->pChartObject->drawLine($X1, $Y2, $X2, $Y2, $Color);
                    }
                }
            }
        }
    }
317207
@Override
	public void draw(float x, float y) {
		init();
		draw(x,y,width,height);
	}
1028638
public function drawXThreshold($Value, array $Format = [])
    {
        $R = isset($Format["R"]) ? $Format["R"] : 255;
        $G = isset($Format["G"]) ? $Format["G"] : 0;
        $B = isset($Format["B"]) ? $Format["B"] : 0;
        $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 50;
        $Weight = isset($Format["Weight"]) ? $Format["Weight"] : null;
        $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : 6;
        $Wide = isset($Format["Wide"]) ? $Format["Wide"] : false;
        $WideFactor = isset($Format["WideFactor"]) ? $Format["WideFactor"] : 5;
        $WriteCaption = isset($Format["WriteCaption"]) ? $Format["WriteCaption"] : false;
        $Caption = isset($Format["Caption"]) ? $Format["Caption"] : null;
        $CaptionAlign = isset($Format["CaptionAlign"]) ? $Format["CaptionAlign"] : CAPTION_LEFT_TOP;
        $CaptionOffset = isset($Format["CaptionOffset"]) ? $Format["CaptionOffset"] : 5;
        $CaptionR = isset($Format["CaptionR"]) ? $Format["CaptionR"] : 255;
        $CaptionG = isset($Format["CaptionG"]) ? $Format["CaptionG"] : 255;
        $CaptionB = isset($Format["CaptionB"]) ? $Format["CaptionB"] : 255;
        $CaptionAlpha = isset($Format["CaptionAlpha"]) ? $Format["CaptionAlpha"] : 100;
        $DrawBox = isset($Format["DrawBox"]) ? $Format["DrawBox"] : true;
        $DrawBoxBorder = isset($Format["DrawBoxBorder"]) ? $Format["DrawBoxBorder"] : false;
        $BorderOffset = isset($Format["BorderOffset"]) ? $Format["BorderOffset"] : 3;
        $BoxRounded = isset($Format["BoxRounded"]) ? $Format["BoxRounded"] : true;
        $RoundedRadius = isset($Format["RoundedRadius"]) ? $Format["RoundedRadius"] : 3;
        $BoxR = isset($Format["BoxR"]) ? $Format["BoxR"] : 0;
        $BoxG = isset($Format["BoxG"]) ? $Format["BoxG"] : 0;
        $BoxB = isset($Format["BoxB"]) ? $Format["BoxB"] : 0;
        $BoxAlpha = isset($Format["BoxAlpha"]) ? $Format["BoxAlpha"] : 30;
        $BoxSurrounding = isset($Format["BoxSurrounding"]) ? $Format["BoxSurrounding"] : "";
        $BoxBorderR = isset($Format["BoxBorderR"]) ? $Format["BoxBorderR"] : 255;
        $BoxBorderG = isset($Format["BoxBorderG"]) ? $Format["BoxBorderG"] : 255;
        $BoxBorderB = isset($Format["BoxBorderB"]) ? $Format["BoxBorderB"] : 255;
        $BoxBorderAlpha = isset($Format["BoxBorderAlpha"]) ? $Format["BoxBorderAlpha"] : 100;
        $ValueIsLabel = isset($Format["ValueIsLabel"]) ? $Format["ValueIsLabel"] : false;

        $Data = $this->DataSet->getData();
        $AbscissaMargin = $this->getAbscissaMargin($Data);
        $XScale = $this->scaleGetXSettings();

        if (is_array($Value)) {
            foreach ($Value as $Key => $ID) {
                $this->drawXThreshold($ID, $Format);
            }
            return 0;
        }

        if ($ValueIsLabel) {
            $Format["ValueIsLabel"] = false;
            foreach ($Data["Series"][$Data["Abscissa"]]["Data"] as $Key => $SerieValue) {
                if ($SerieValue == $Value) {
                    $this->drawXThreshold($Key, $Format);
                }
            }
            return 0;
        }

        $CaptionSettings = [
            "DrawBox" => $DrawBox,
            "DrawBoxBorder" => $DrawBoxBorder,
            "BorderOffset" => $BorderOffset,
            "BoxRounded" => $BoxRounded,
            "RoundedRadius" => $RoundedRadius,
            "BoxR" => $BoxR,
            "BoxG" => $BoxG,
            "BoxB" => $BoxB,
            "BoxAlpha" => $BoxAlpha,
            "BoxSurrounding" => $BoxSurrounding,
            "BoxBorderR" => $BoxBorderR,
            "BoxBorderG" => $BoxBorderG,
            "BoxBorderB" => $BoxBorderB,
            "BoxBorderAlpha" => $BoxBorderAlpha,
            "R" => $CaptionR,
            "G" => $CaptionG,
            "B" => $CaptionB,
            "Alpha" => $CaptionAlpha
        ];

        if ($Caption == null) {
            $Caption = $Value;
            if (isset($Data["Abscissa"])
                && isset($Data["Series"][$Data["Abscissa"]]["Data"][$Value])
            ) {
                $Caption = $Data["Series"][$Data["Abscissa"]]["Data"][$Value];
            }
        }

        if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
            $XStep = (($this->GraphAreaX2 - $this->GraphAreaX1) - $XScale[0] * 2) / $XScale[1];
            $XPos = $this->GraphAreaX1 + $XScale[0] + $XStep * $Value;
            $YPos1 = $this->GraphAreaY1 + $Data["YMargin"];
            $YPos2 = $this->GraphAreaY2 - $Data["YMargin"];

            if ($XPos >= $this->GraphAreaX1 + $AbscissaMargin
                && $XPos <= $this->GraphAreaX2 - $AbscissaMargin
            ) {
                $this->drawLine(
                    $XPos,
                    $YPos1,
                    $XPos,
                    $YPos2,
                    [
                        "R" => $R,
                        "G" => $G,
                        "B" => $B,
                        "Alpha" => $Alpha,
                        "Ticks" => $Ticks,
                        "Weight" => $Weight
                    ]
                );

                if ($Wide) {
                    $this->drawLine(
                        $XPos - 1,
                        $YPos1,
                        $XPos - 1,
                        $YPos2,
                        [
                            "R" => $R,
                            "G" => $G,
                            "B" => $B,
                            "Alpha" => $Alpha / $WideFactor,
                            "Ticks" => $Ticks
                        ]
                    );
                    $this->drawLine(
                        $XPos + 1,
                        $YPos1,
                        $XPos + 1,
                        $YPos2,
                        [
                            "R" => $R,
                            "G" => $G,
                            "B" => $B,
                            "Alpha" => $Alpha / $WideFactor,
                            "Ticks" => $Ticks
                        ]
                    );
                }

                if ($WriteCaption) {
                    if ($CaptionAlign == CAPTION_LEFT_TOP) {
                        $Y = $YPos1 + $CaptionOffset;
                        $CaptionSettings["Align"] = TEXT_ALIGN_TOPMIDDLE;
                    } else {
                        $Y = $YPos2 - $CaptionOffset;
                        $CaptionSettings["Align"] = TEXT_ALIGN_BOTTOMMIDDLE;
                    }
                    $this->drawText($XPos, $Y, $Caption, $CaptionSettings);
                }

                return ["X" => $XPos];
            }
        } elseif ($Data["Orientation"] == SCALE_POS_TOPBOTTOM) {
            $XStep = (($this->GraphAreaY2 - $this->GraphAreaY1) - $XScale[0] * 2) / $XScale[1];
            $XPos = $this->GraphAreaY1 + $XScale[0] + $XStep * $Value;
            $YPos1 = $this->GraphAreaX1 + $Data["YMargin"];
            $YPos2 = $this->GraphAreaX2 - $Data["YMargin"];

            if ($XPos >= $this->GraphAreaY1 + $AbscissaMargin
                && $XPos <= $this->GraphAreaY2 - $AbscissaMargin
            ) {
                $this->drawLine(
                    $YPos1,
                    $XPos,
                    $YPos2,
                    $XPos,
                    [
                        "R" => $R,
                        "G" => $G,
                        "B" => $B,
                        "Alpha" => $Alpha,
                        "Ticks" => $Ticks,
                        "Weight" => $Weight
                    ]
                );

                if ($Wide) {
                    $this->drawLine(
                        $YPos1,
                        $XPos - 1,
                        $YPos2,
                        $XPos - 1,
                        [
                            "R" => $R,
                            "G" => $G,
                            "B" => $B,
                            "Alpha" => $Alpha / $WideFactor,
                            "Ticks" => $Ticks
                        ]
                    );
                    $this->drawLine(
                        $YPos1,
                        $XPos + 1,
                        $YPos2,
                        $XPos + 1,
                        [
                            "R" => $R,
                            "G" => $G,
                            "B" => $B,
                            "Alpha" => $Alpha / $WideFactor,
                            "Ticks" => $Ticks
                        ]
                    );
                }

                if ($WriteCaption) {
                    if ($CaptionAlign == CAPTION_LEFT_TOP) {
                        $Y = $YPos1 + $CaptionOffset;
                        $CaptionSettings["Align"] = TEXT_ALIGN_MIDDLELEFT;
                    } else {
                        $Y = $YPos2 - $CaptionOffset;
                        $CaptionSettings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
                    }

                    $this->drawText($Y, $XPos, $Caption, $CaptionSettings);
                }

                return ["X" => $XPos];
            }
        }
    }