<?php
/*
pScatter - class to draw scatter charts

Version     : 2.1.4
Made by     : Jean-Damien POGOLOTTI
Last Update : 19/01/2014

This file can be distributed under the license you can find at :

http://www.pchart.net/license

You can find the whole class documentation on the pChart web site.
*/
define("SCATTER_MISSING_X_SERIE", 190001);
define("SCATTER_MISSING_Y_SERIE", 190002);

/* pScatter class definition */
class pScatter
{
	var $pChartObject;
	var $pDataObject;
	/* Class creator */
	function __construct($pChartObject, $pDataObject)
	{
		$this->pChartObject = $pChartObject;
		$this->pDataObject = $pDataObject;
	}

	/* Prepare the scale */
	function drawScatterScale(array $Format = [])
	{
		
		/* Check if we have at least both one X and Y axis */
		$GotXAxis = FALSE;
		$GotYAxis = FALSE;
		foreach($this->pDataObject->Data["Axis"] as $AxisID => $AxisSettings) {
			($AxisSettings["Identity"] == AXIS_X) AND $GotXAxis = TRUE;
			($AxisSettings["Identity"] == AXIS_Y) AND $GotYAxis = TRUE;
		}

		if (!$GotXAxis) {
			return SCATTER_MISSING_X_SERIE;
		}

		if (!$GotYAxis) {
			return SCATTER_MISSING_Y_SERIE;
		}
		
		$Mode = SCALE_MODE_FLOATING;
		$Floating = FALSE;
		$XLabelsRotation = 90;
		$MinDivHeight = 20;
		$Factors = [1,2,5];
		$ManualScale = array("0" => ["Min" => - 100,"Max" => 100]);
		$XMargin = 0;
		$YMargin = 0;
		$ScaleSpacing = 15;
		$InnerTickWidth = 2;
		$OuterTickWidth = 2;
		$DrawXLines = ALL;
		$DrawYLines = ALL;
		$GridTicks = 4;
		$GridR = 255;
		$GridG = 255;
		$GridB = 255;
		$GridAlpha = 40;
		$AxisRo = isset($Format["AxisR"]) ? $Format["AxisR"] : 0;
		$AxisGo = isset($Format["AxisG"]) ? $Format["AxisG"] : 0;
		$AxisBo = isset($Format["AxisB"]) ? $Format["AxisB"] : 0;
		$AxisAlpha = 100;
		$TickRo = isset($Format["TickR"]) ? $Format["TickR"] : 0;
		$TickGo = isset($Format["TickG"]) ? $Format["TickG"] : 0;
		$TickBo = isset($Format["TickB"]) ? $Format["TickB"] : 0;
		$TickAlpha = 100;
		$DrawSubTicks = FALSE;
		$InnerSubTickWidth = 0;
		$OuterSubTickWidth = 2;
		$SubTickR = 255;
		$SubTickG = 0;
		$SubTickB = 0;
		$SubTickAlpha = 100;
		$XReleasePercent = 1;
		$DrawArrows = FALSE;
		$ArrowSize = 8;
		$CycleBackground = FALSE;
		$BackgroundR1 = 255;
		$BackgroundG1 = 255;
		$BackgroundB1 = 255;
		$BackgroundAlpha1 = 10;
		$BackgroundR2 = 230;
		$BackgroundG2 = 230;
		$BackgroundB2 = 230;
		$BackgroundAlpha2 = 10;
		
		/* Override defaults */
		extract($Format);
		
		$BG1 = ["R" => $BackgroundR1,"G" => $BackgroundG1,"B" => $BackgroundB1,"Alpha" => $BackgroundAlpha1];
		$BG2 = ["R" => $BackgroundR2,"G" => $BackgroundG2,"B" => $BackgroundB2,"Alpha" => $BackgroundAlpha2];

		/* Skip a NOTICE event in case of an empty array */
		($DrawYLines == NONE) AND $DrawYLines = ["zarma" => "31"];
		
		$Data = $this->pDataObject->getData();
		foreach($Data["Axis"] as $AxisID => $AxisSettings) {
			if ($AxisSettings["Identity"] == AXIS_X) {
				$Width = $this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2;
			} else {
				$Width = $this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $YMargin * 2;
			}

			$AxisMin = ABSOLUTE_MAX;
			$AxisMax = OUT_OF_SIGHT;
			if ($Mode == SCALE_MODE_FLOATING) {
				foreach($Data["Series"] as $SerieID => $SerieParameter) {
					if ($SerieParameter["Axis"] == $AxisID && $Data["Series"][$SerieID]["isDrawable"]) {
						$AxisMax = max($AxisMax, $Data["Series"][$SerieID]["Max"]);
						$AxisMin = min($AxisMin, $Data["Series"][$SerieID]["Min"]);
					}
				}

				$AutoMargin = (($AxisMax - $AxisMin) / 100) * $XReleasePercent;
				$Data["Axis"][$AxisID]["Min"] = $AxisMin - $AutoMargin;
				$Data["Axis"][$AxisID]["Max"] = $AxisMax + $AutoMargin;
			} elseif ($Mode == SCALE_MODE_MANUAL) {
				if (isset($ManualScale[$AxisID]["Min"]) && isset($ManualScale[$AxisID]["Max"])) {
					$Data["Axis"][$AxisID]["Min"] = $ManualScale[$AxisID]["Min"];
					$Data["Axis"][$AxisID]["Max"] = $ManualScale[$AxisID]["Max"];
				} else {
					echo "Manual scale boundaries not set.";
					exit();
				}
			}

			/* Full manual scale */
			if (isset($ManualScale[$AxisID]["Rows"]) && isset($ManualScale[$AxisID]["RowHeight"])) {
				$Scale = ["Rows" => $ManualScale[$AxisID]["Rows"],"RowHeight" => $ManualScale[$AxisID]["RowHeight"],"XMin" => $ManualScale[$AxisID]["Min"],"XMax" => $ManualScale[$AxisID]["Max"]];
			} else {
				$MaxDivs = floor($Width / $MinDivHeight);
				$Scale = $this->pChartObject->computeScale($Data["Axis"][$AxisID]["Min"], $Data["Axis"][$AxisID]["Max"], $MaxDivs, $Factors, $AxisID);
			}

			$Data["Axis"][$AxisID]["Margin"] = $AxisSettings["Identity"] == AXIS_X ? $XMargin : $YMargin;
			$Data["Axis"][$AxisID]["ScaleMin"] = $Scale["XMin"];
			$Data["Axis"][$AxisID]["ScaleMax"] = $Scale["XMax"];
			$Data["Axis"][$AxisID]["Rows"] = $Scale["Rows"];
			$Data["Axis"][$AxisID]["RowHeight"] = $Scale["RowHeight"];
			(isset($Scale["Format"])) AND $Data["Axis"][$AxisID]["Format"] = $Scale["Format"];
			(!isset($Data["Axis"][$AxisID]["Display"])) AND $Data["Axis"][$AxisID]["Display"] = NULL;
			(!isset($Data["Axis"][$AxisID]["Format"])) AND $Data["Axis"][$AxisID]["Format"] = NULL;
			(!isset($Data["Axis"][$AxisID]["Unit"])) AND $Data["Axis"][$AxisID]["Unit"] = NULL;
		}

		/* Set the original boundaries */
		$AxisPos = [
			"L" => $this->pChartObject->GraphAreaX1,
			"R" => $this->pChartObject->GraphAreaX2,
			"T" => $this->pChartObject->GraphAreaY1,
			"B" => $this->pChartObject->GraphAreaY2
		];
		
		foreach($Data["Axis"] as $AxisID => $AxisSettings) {
			if (isset($AxisSettings["Color"])) {
				$AxisR = $AxisSettings["Color"]["R"];
				$AxisG = $AxisSettings["Color"]["G"];
				$AxisB = $AxisSettings["Color"]["B"];
				$TickR = $AxisSettings["Color"]["R"];
				$TickG = $AxisSettings["Color"]["G"];
				$TickB = $AxisSettings["Color"]["B"];
				$this->pChartObject->setFontProperties(["R" => $AxisR,"G" => $AxisG,"B" => $AxisB]);
			} else {
				$AxisR = $AxisRo;
				$AxisG = $AxisGo;
				$AxisB = $AxisBo;
				$TickR = $TickRo;
				$TickG = $TickGo;
				$TickB = $TickBo;
				/* Get the default font color */
				$this->pChartObject->setFontProperties(["R" => $this->pChartObject->FontColorR,"G" => $this->pChartObject->FontColorG,"B" => $this->pChartObject->FontColorB]);
			}

			$LastValue = "w00t";
			$ID = 1;
			if ($AxisSettings["Identity"] == AXIS_X) {
				if ($AxisSettings["Position"] == AXIS_POSITION_BOTTOM) {
					if ($XLabelsRotation == 0) {
						$LabelAlign = TEXT_ALIGN_TOPMIDDLE;
						$LabelOffset = 2;
					}

					if ($XLabelsRotation > 0 && $XLabelsRotation < 190) {
						$LabelAlign = TEXT_ALIGN_MIDDLERIGHT;
						$LabelOffset = 5;
					}

					if ($XLabelsRotation == 180) {
						$LabelAlign = TEXT_ALIGN_BOTTOMMIDDLE;
						$LabelOffset = 5;
					}

					if ($XLabelsRotation > 180 && $XLabelsRotation < 360) {
						$LabelAlign = TEXT_ALIGN_MIDDLELEFT;
						$LabelOffset = 2;
					}

					if ($Floating) {
						$FloatingOffset = $YMargin;
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"], $AxisPos["B"], $this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["B"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					} else {
						$FloatingOffset = 0;
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1, $AxisPos["B"], $this->pChartObject->GraphAreaX2, $AxisPos["B"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					}

					if ($DrawArrows) {
						$this->pChartObject->drawArrow($this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["B"], $this->pChartObject->GraphAreaX2 + ($ArrowSize * 2) , $AxisPos["B"], ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
					}

					$Width = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $AxisSettings["Margin"] * 2;
					$Step = $Width / $AxisSettings["Rows"];
					$SubTicksSize = $Step / 2;
					$MaxBottom = $AxisPos["B"];
					$LastX = NULL;
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
						$XPos = $this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"] + $Step * $i;
						$YPos = $AxisPos["B"];
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;

						if ($LastX != NULL && $CycleBackground && ($DrawXLines == ALL || in_array($AxisID, $DrawXLines))) {
							$this->pChartObject->drawFilledRectangle($LastX, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, $BGColor);
						}

						if ($DrawXLines == ALL || in_array($AxisID, $DrawXLines)) {
							$this->pChartObject->drawLine($XPos, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
						}

						if ($DrawSubTicks && $i != $AxisSettings["Rows"]){
							$this->pChartObject->drawLine($XPos + $SubTicksSize, $YPos - $InnerSubTickWidth, $XPos + $SubTicksSize, $YPos + $OuterSubTickWidth, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
						}
						
						$this->pChartObject->drawLine($XPos, $YPos - $InnerTickWidth, $XPos, $YPos + $OuterTickWidth, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
						$Bounds = $this->pChartObject->drawText($XPos, $YPos + $OuterTickWidth + $LabelOffset, $Value, ["Angle" => $XLabelsRotation,"Align" => $LabelAlign]);
						$TxtBottom = $YPos + 2 + $OuterTickWidth + 2 + ($Bounds[0]["Y"] - $Bounds[2]["Y"]);
						$MaxBottom = max($MaxBottom, $TxtBottom);
						$LastX = $XPos;
					}

					if (isset($AxisSettings["Name"])) {
						$YPos = $MaxBottom + 2;
						$XPos = $this->pChartObject->GraphAreaX1 + ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / 2;
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"], ["Align" => TEXT_ALIGN_TOPMIDDLE]);
						$MaxBottom = $Bounds[0]["Y"];
						$this->pDataObject->Data["GraphArea"]["Y2"] = $MaxBottom + $this->pChartObject->FontSize;
					}

					$AxisPos["B"] = $MaxBottom + $ScaleSpacing;
					
				} elseif ($AxisSettings["Position"] == AXIS_POSITION_TOP) {
					
					if ($XLabelsRotation == 0) {
						$LabelAlign = TEXT_ALIGN_BOTTOMMIDDLE;
						$LabelOffset = 2;
					}

					if ($XLabelsRotation > 0 && $XLabelsRotation < 190) {
						$LabelAlign = TEXT_ALIGN_MIDDLELEFT;
						$LabelOffset = 2;
					}

					if ($XLabelsRotation == 180) {
						$LabelAlign = TEXT_ALIGN_TOPMIDDLE;
						$LabelOffset = 5;
					}

					if ($XLabelsRotation > 180 && $XLabelsRotation < 360) {
						$LabelAlign = TEXT_ALIGN_MIDDLERIGHT;
						$LabelOffset = 5;
					}

					if ($Floating) {
						$FloatingOffset = $YMargin;
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"], $AxisPos["T"], $this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["T"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					} else {
						$FloatingOffset = 0;
						$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1, $AxisPos["T"], $this->pChartObject->GraphAreaX2, $AxisPos["T"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					}

					if ($DrawArrows) {
						$this->pChartObject->drawArrow($this->pChartObject->GraphAreaX2 - $AxisSettings["Margin"], $AxisPos["T"], $this->pChartObject->GraphAreaX2 + ($ArrowSize * 2) , $AxisPos["T"], ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
					}

					$Width = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $AxisSettings["Margin"] * 2;
					$Step = $Width / $AxisSettings["Rows"];
					$SubTicksSize = $Step / 2;
					$MinTop = $AxisPos["T"];
					$LastX = NULL;
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
						$XPos = $this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"] + $Step * $i;
						$YPos = $AxisPos["T"];
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;

						if ($LastX != NULL && $CycleBackground && ($DrawXLines == ALL || in_array($AxisID, $DrawXLines))) {
							$this->pChartObject->drawFilledRectangle($LastX, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, $BGColor);
						}

						if ($DrawXLines == ALL || in_array($AxisID, $DrawXLines)) {
							$this->pChartObject->drawLine($XPos, $this->pChartObject->GraphAreaY1 + $FloatingOffset, $XPos, $this->pChartObject->GraphAreaY2 - $FloatingOffset, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
						}

						if ($DrawSubTicks && $i != $AxisSettings["Rows"]) {
							$this->pChartObject->drawLine($XPos + $SubTicksSize, $YPos - $OuterSubTickWidth, $XPos + $SubTicksSize, $YPos + $InnerSubTickWidth, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
						}

						$this->pChartObject->drawLine($XPos, $YPos - $OuterTickWidth, $XPos, $YPos + $InnerTickWidth, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
						$Bounds = $this->pChartObject->drawText($XPos, $YPos - $OuterTickWidth - $LabelOffset, $Value, ["Angle" => $XLabelsRotation,"Align" => $LabelAlign]);
						$TxtBox = $YPos - $OuterTickWidth - 4 - ($Bounds[0]["Y"] - $Bounds[2]["Y"]);
						$MinTop = min($MinTop, $TxtBox);
						$LastX = $XPos;
					}

					if (isset($AxisSettings["Name"])) {
						$YPos = $MinTop - 2;
						$XPos = $this->pChartObject->GraphAreaX1 + ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / 2;
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"], ["Align" => TEXT_ALIGN_BOTTOMMIDDLE]);
						$MinTop = $Bounds[2]["Y"];
						$this->pDataObject->Data["GraphArea"]["Y1"] = $MinTop;
					}

					$AxisPos["T"] = $MinTop - $ScaleSpacing;
				}
				
			} elseif ($AxisSettings["Identity"] == AXIS_Y) {
				if ($AxisSettings["Position"] == AXIS_POSITION_LEFT) {
					if ($Floating) {
						$FloatingOffset = $XMargin;
						$this->pChartObject->drawLine($AxisPos["L"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["L"], $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					} else {
						$FloatingOffset = 0;
						$this->pChartObject->drawLine($AxisPos["L"], $this->pChartObject->GraphAreaY1, $AxisPos["L"], $this->pChartObject->GraphAreaY2, ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					}

					if ($DrawArrows) {
						$this->pChartObject->drawArrow($AxisPos["L"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["L"], $this->pChartObject->GraphAreaY1 - ($ArrowSize * 2) , ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
					}

					$Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $AxisSettings["Margin"] * 2;
					$Step = $Height / $AxisSettings["Rows"];
					$SubTicksSize = $Step / 2;
					$MinLeft = $AxisPos["L"];
					$LastY = NULL;
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
						$YPos = $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"] - $Step * $i;
						$XPos = $AxisPos["L"];
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;

						if ($LastY != NULL && $CycleBackground && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
							$this->pChartObject->drawFilledRectangle($this->pChartObject->GraphAreaX1 + $FloatingOffset, $LastY, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, $BGColor);
						}

						if (($YPos != $this->pChartObject->GraphAreaY1 && $YPos != $this->pChartObject->GraphAreaY2) && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
							$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $FloatingOffset, $YPos, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
						}

						if ($DrawSubTicks && $i != $AxisSettings["Rows"]) {
							 $this->pChartObject->drawLine($XPos - $OuterSubTickWidth, $YPos - $SubTicksSize, $XPos + $InnerSubTickWidth, $YPos - $SubTicksSize, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
						}
						
						$this->pChartObject->drawLine($XPos - $OuterTickWidth, $YPos, $XPos + $InnerTickWidth, $YPos, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
						$Bounds = $this->pChartObject->drawText($XPos - $OuterTickWidth - 2, $YPos, $Value, ["Align" => TEXT_ALIGN_MIDDLERIGHT]);
						$TxtLeft = $XPos - $OuterTickWidth - 2 - ($Bounds[1]["X"] - $Bounds[0]["X"]);
						$MinLeft = min($MinLeft, $TxtLeft);
						$LastY = $YPos;
					}

					if (isset($AxisSettings["Name"])) {
						$XPos = $MinLeft - 2;
						$YPos = $this->pChartObject->GraphAreaY1 + ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / 2;
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"],["Align" => TEXT_ALIGN_BOTTOMMIDDLE,"Angle" => 90]);
						$MinLeft = $Bounds[2]["X"];
						$this->pDataObject->Data["GraphArea"]["X1"] = $MinLeft;
					}

					$AxisPos["L"] = $MinLeft - $ScaleSpacing;
				} elseif ($AxisSettings["Position"] == AXIS_POSITION_RIGHT) {
					if ($Floating) {
						$FloatingOffset = $XMargin;
						$this->pChartObject->drawLine($AxisPos["R"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["R"], $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"], ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					} else {
						$FloatingOffset = 0;
						$this->pChartObject->drawLine($AxisPos["R"], $this->pChartObject->GraphAreaY1, $AxisPos["R"], $this->pChartObject->GraphAreaY2, ["R" => $AxisR,"G" => $AxisG,"B" => $AxisB,"Alpha" => $AxisAlpha]);
					}

					if ($DrawArrows) {
						$this->pChartObject->drawArrow($AxisPos["R"], $this->pChartObject->GraphAreaY1 + $AxisSettings["Margin"], $AxisPos["R"], $this->pChartObject->GraphAreaY1 - ($ArrowSize * 2), ["FillR" => $AxisR,"FillG" => $AxisG,"FillB" => $AxisB,"Size" => $ArrowSize]);
					}

					$Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $AxisSettings["Margin"] * 2;
					$Step = $Height / $AxisSettings["Rows"];
					$SubTicksSize = $Step / 2;
					$MaxLeft = $AxisPos["R"];
					$LastY = NULL;
					for ($i = 0; $i <= $AxisSettings["Rows"]; $i++) {
						$YPos = $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"] - $Step * $i;
						$XPos = $AxisPos["R"];
						$Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"] * $i, $AxisSettings["Display"], $AxisSettings["Format"], $AxisSettings["Unit"]);
						$BGColor = ($i % 2 == 1) ? $BG1 : $BG2;

						if ($LastY != NULL && $CycleBackground && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
							$this->pChartObject->drawFilledRectangle($this->pChartObject->GraphAreaX1 + $FloatingOffset, $LastY, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, $BGColor);
						}

						if (($YPos != $this->pChartObject->GraphAreaY1 && $YPos != $this->pChartObject->GraphAreaY2) && ($DrawYLines == ALL || in_array($AxisID, $DrawYLines))) {
							$this->pChartObject->drawLine($this->pChartObject->GraphAreaX1 + $FloatingOffset, $YPos, $this->pChartObject->GraphAreaX2 - $FloatingOffset, $YPos, ["R" => $GridR,"G" => $GridG,"B" => $GridB,"Alpha" => $GridAlpha,"Ticks" => $GridTicks]);
						}

						if ($DrawSubTicks && $i != $AxisSettings["Rows"]) {
							$this->pChartObject->drawLine($XPos - $InnerSubTickWidth, $YPos - $SubTicksSize, $XPos + $OuterSubTickWidth, $YPos - $SubTicksSize, ["R" => $SubTickR,"G" => $SubTickG,"B" => $SubTickB,"Alpha" => $SubTickAlpha]);
						}
						
						$this->pChartObject->drawLine($XPos - $InnerTickWidth, $YPos, $XPos + $OuterTickWidth, $YPos, ["R" => $TickR,"G" => $TickG,"B" => $TickB,"Alpha" => $TickAlpha]);
						$Bounds = $this->pChartObject->drawText($XPos + $OuterTickWidth + 2, $YPos, $Value, ["Align" => TEXT_ALIGN_MIDDLELEFT]);
						$TxtLeft = $XPos + $OuterTickWidth + 2 + ($Bounds[1]["X"] - $Bounds[0]["X"]);
						$MaxLeft = max($MaxLeft, $TxtLeft);
						$LastY = $YPos;
					}

					if (isset($AxisSettings["Name"])) {
						$XPos = $MaxLeft + 6;
						$YPos = $this->pChartObject->GraphAreaY1 + ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / 2;
						$Bounds = $this->pChartObject->drawText($XPos, $YPos, $AxisSettings["Name"], ["Align" => TEXT_ALIGN_BOTTOMMIDDLE,"Angle" => 270]);
						$MaxLeft = $Bounds[2]["X"];
						$this->pDataObject->Data["GraphArea"]["X2"] = $MaxLeft + $this->pChartObject->FontSize;
					}

					$AxisPos["R"] = $MaxLeft + $ScaleSpacing;
				}
			}
		}

		$this->pDataObject->saveAxisConfig($Data["Axis"]);
	}

	/* Draw a scatter plot chart */
	function drawScatterPlotChart(array $Format = [])
	{
		$PlotSize = 3;
		$PlotBorder = FALSE;
		$BorderR = 250;
		$BorderG = 250;
		$BorderB = 250;
		$BorderAlpha = 30;
		$BorderSize = 1;
		$Surrounding = NULL;
		$RecordImageMap = FALSE;
		$ImageMapTitle = NULL;
		$ImageMapPrecision = 2;
		
		/* Override defaults */
		extract($Format);
		
		$Data = $this->pDataObject->getData();
		$Palette = $this->pDataObject->getPalette();
		$BorderColor =["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha];
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE) {
				$SerieX = $Series["X"];
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
				$SerieY = $Series["Y"];
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
				$Description = ($ImageMapTitle == NULL) ? $Data["Series"][$Series["X"]]["Description"] . " / " . $Data["Series"][$Series["Y"]]["Description"] : $ImageMapTitle;

				if (isset($Series["Picture"]) && $Series["Picture"] != "") {
					$Picture = $Series["Picture"];
					list($PicWidth, $PicHeight, $PicType) = $this->pChartObject->getPicInfo($Picture);
				} else {
					$Picture = NULL;
				}

				$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
				(!is_array($PosArrayX)) AND $PosArrayX = [0 => $PosArrayX];

				$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
				(!is_array($PosArrayY)) AND $PosArrayY = [0 => $PosArrayY];
	
				$Color = array("R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]);
				
				foreach($PosArrayX as $Key => $Value) {
					$X = $Value;
					$Y = $PosArrayY[$Key];
					if ($X != VOID && $Y != VOID) {
						$RealValue = round($Data["Series"][$Series["X"]]["Data"][$Key], 2) . " / " . round($Data["Series"][$Series["Y"]]["Data"][$Key], 2);
						if ($RecordImageMap) {
							$this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . floor($PlotSize + $BorderSize) , $this->pChartObject->toHTMLColor($Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"]) , $Description, $RealValue);
						}

						if (isset($Series["Shape"])) {
							$this->pChartObject->drawShape($X, $Y, $Series["Shape"], $PlotSize, $PlotBorder, $BorderSize, $Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"], $Series["Color"]["Alpha"], $BorderR, $BorderG, $BorderB, $BorderAlpha);
						} elseif ($Picture == NULL) {
							if ($PlotBorder) {
								$this->pChartObject->drawFilledCircle($X, $Y, $PlotSize + $BorderSize, $BorderColor);
							}

							$this->pChartObject->drawFilledCircle($X, $Y, $PlotSize, $Color);
						} else {
							$this->pChartObject->drawFromPicture($PicType, $Picture, $X - $PicWidth / 2, $Y - $PicHeight / 2);
						}
					}
				}
			}
		}
	}

	/* Draw a scatter line chart */
	function drawScatterLineChart(array $Format = [])
	{
		$Data = $this->pDataObject->getData();
		$Palette = $this->pDataObject->getPalette();
		$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
		$ImageMapTitle = isset($Format["ImageMapTitle"]) ? $Format["ImageMapTitle"] : NULL;
		$ImageMapPlotSize = isset($Format["ImageMapPlotSize"]) ? $Format["ImageMapPlotSize"] : 10;
		$ImageMapPrecision = isset($Format["ImageMapPrecision"]) ? $Format["ImageMapPrecision"] : 2;
		/* Parse all the series to draw */
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE) {
				$SerieX = $Series["X"];
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
				$SerieY = $Series["Y"];
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
				$Ticks = $Series["Ticks"];
				$Weight = $Series["Weight"];
				$Description = ($ImageMapTitle == NULL) ? $Data["Series"][$Series["X"]]["Description"] . " / " . $Data["Series"][$Series["Y"]]["Description"] : $ImageMapTitle;

				$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
				(!is_array($PosArrayX)) AND $PosArrayX = [0 => $PosArrayX];
	
				$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
				(!is_array($PosArrayY)) AND $PosArrayY = [0 => $PosArrayY];

				$Color = ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]];
				($Ticks != 0) AND $Color["Ticks"] = $Ticks;
				($Weight != 0) AND $Color["Weight"] = $Weight;

				$LastX = VOID;
				$LastY = VOID;
				foreach($PosArrayX as $Key => $Value) {
					$X = $Value;
					$Y = $PosArrayY[$Key];
					if ($X != VOID && $Y != VOID) {
						$RealValue = round($Data["Series"][$Series["X"]]["Data"][$Key], 2) . " / " . round($Data["Series"][$Series["Y"]]["Data"][$Key], 2);
						if ($RecordImageMap) {
							$this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . $ImageMapPlotSize, $this->pChartObject->toHTMLColor($Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"]) , $Description, $RealValue);
						}
						
						if ($LastX != VOID && $LastY != VOID){
							$this->pChartObject->drawLine($LastX, $LastY, $X, $Y, $Color);
						}
					}

					$LastX = $X;
					$LastY = $Y;
				}
			}
		}
	}

	/* Draw a scatter spline chart */
	function drawScatterSplineChart(array $Format = [])
	{
		$Data = $this->pDataObject->getData();
		$Palette = $this->pDataObject->getPalette();
		$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
		$ImageMapTitle = isset($Format["ImageMapTitle"]) ? $Format["ImageMapTitle"] : NULL;
		$ImageMapPlotSize = isset($Format["ImageMapPlotSize"]) ? $Format["ImageMapPlotSize"] : 10;
		$ImageMapPrecision = isset($Format["ImageMapPrecision"]) ? $Format["ImageMapPrecision"] : 2;
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE) {
				$SerieX = $Series["X"];
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
				$SerieY = $Series["Y"];
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
				$Ticks = $Series["Ticks"];
				$Weight = $Series["Weight"];
				$Description = ($ImageMapTitle == NULL) ? $Data["Series"][$Series["X"]]["Description"] . " / " . $Data["Series"][$Series["Y"]]["Description"] : $ImageMapTitle;

				$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
				if (!is_array($PosArrayX)) {
					$Value = $PosArrayX;
					$PosArrayX = [];
					$PosArrayX[0] = $Value;
				}

				$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
				if (!is_array($PosArrayY)) {
					$Value = $PosArrayY;
					$PosArrayY = [0 => $Value];
				}

				$SplineSettings = ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]];
				($Ticks != 0) AND $SplineSettings["Ticks"] = $Ticks;
				($Weight != 0) AND $SplineSettings["Weight"] = $Weight;
				
				$LastX = VOID;
				$LastY = VOID;
				$WayPoints = [];
				$Forces = [];
				foreach($PosArrayX as $Key => $Value) {
					$X = $Value;
					$Y = $PosArrayY[$Key];
					$Force = $this->pChartObject->getLength($LastX, $LastY, $X, $Y) / 5;
					if ($X != VOID && $Y != VOID) {
						$RealValue = round($Data["Series"][$Series["X"]]["Data"][$Key], 2) . " / " . round($Data["Series"][$Series["Y"]]["Data"][$Key], 2);
						if ($RecordImageMap) {
							$this->pChartObject->addToImageMap("CIRCLE", floor($X) . "," . floor($Y) . "," . $ImageMapPlotSize, $this->pChartObject->toHTMLColor($Series["Color"]["R"], $Series["Color"]["G"], $Series["Color"]["B"]) , $Description, $RealValue);
						}
					}

					if ($X != VOID && $Y != VOID) {
						$WayPoints[] = [$X,$Y];
						$Forces[] = $Force;
					}

					if ($Y == VOID || $X == VOID) {
						$SplineSettings["Forces"] = $Forces;
						$this->pChartObject->drawSpline($WayPoints, $SplineSettings);
						$WayPoints = [];
						$Forces = [];
					}

					$LastX = $X;
					$LastY = $Y;
				}

				$SplineSettings["Forces"] = $Forces;
				$this->pChartObject->drawSpline($WayPoints, $SplineSettings);
			}
		}
	}

	/* Return the scaled plot position */
	function getPosArray($Values, $AxisID)
	{
		$Data = $this->pDataObject->getData();
		$ScaleHeight = $Data["Axis"][$AxisID]["ScaleMax"] - $Data["Axis"][$AxisID]["ScaleMin"];
		
		(!is_array($Values)) AND $Values = [$Values];
		$Result = [];

		if ($Data["Axis"][$AxisID]["Identity"] == AXIS_X) {
			$Height = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $Data["Axis"][$AxisID]["Margin"] * 2;
			$Step = $Height / $ScaleHeight;

			foreach($Values as $Key => $Value) {
				$Result[] = ($Value == VOID) ? VOID : $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"] + ($Step * ($Value - $Data["Axis"][$AxisID]["ScaleMin"]));
			}
			
		} else {
			$Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $Data["Axis"][$AxisID]["Margin"] * 2;
			$Step = $Height / $ScaleHeight;

			foreach($Values as $Key => $Value) {
				$Result[] = ($Value == VOID) ? VOID : $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"] - ($Step * ($Value - $Data["Axis"][$AxisID]["ScaleMin"]));
			}
		}
		
		return (count($Result) == 1) ? $Result[0] : $Result;
			
	}

	/* Draw the legend of the active series */
	function drawScatterLegend($X, $Y, array $Format = [])
	{
		$Family = LEGEND_FAMILY_BOX;
		$FontName = $this->pChartObject->FontName;
		$FontSize = $this->pChartObject->FontSize;
		$FontR = $this->pChartObject->FontColorR;
		$FontG = $this->pChartObject->FontColorG;
		$FontB = $this->pChartObject->FontColorB;
		$BoxWidth = isset($Format["BoxWidth"]) ? $Format["BoxWidth"] : 5;
		$BoxHeight = isset($Format["BoxHeight"]) ? $Format["BoxHeight"] : 5;
		$IconAreaWidth = $BoxWidth;
		$IconAreaHeight = $BoxHeight;
		$XSpacing = 5;
		$Margin = 5;
		$R = 200;
		$G = 200;
		$B = 200;
		$Alpha = 100;
		$BorderR = 255;
		$BorderG = 255;
		$BorderB = 255;
		$Surrounding = NULL;
		$Style = LEGEND_ROUND;
		$Mode = LEGEND_VERTICAL;
		
		/* Override defaults */
		extract($Format);
		
		if ($Surrounding != NULL) {
			$BorderR = $R + $Surrounding;
			$BorderG = $G + $Surrounding;
			$BorderB = $B + $Surrounding;
		}

		$Data = $this->pDataObject->getData();
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE && isset($Series["Picture"])) {
				list($PicWidth, $PicHeight) = $this->pChartObject->getPicInfo($Series["Picture"]);
				($IconAreaWidth < $PicWidth) AND $IconAreaWidth = $PicWidth;
				($IconAreaHeight < $PicHeight) AND $IconAreaHeight = $PicHeight;
			}
		}

		$YStep = max($this->pChartObject->FontSize, $IconAreaHeight) + 5;
		$XStep = $IconAreaWidth + 5;
		$XStep = $XSpacing;
		$Boundaries = ["L" => $X, "T" => $Y, "R" => 0, "B" => 0];
		$vY = $Y;
		$vX = $X;
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE) {
				if ($Mode == LEGEND_VERTICAL) {
					$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 4, $vY + $IconAreaHeight / 2, $FontName, $FontSize, 0, $Series["Description"]);
					($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
					($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
					($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
					$Lines = preg_split("/\n/", $Series["Description"]);
					$vY = $vY + max($this->pChartObject->FontSize * count($Lines) , $IconAreaHeight) + 5;
					
				} elseif ($Mode == LEGEND_HORIZONTAL) {
					$Lines = preg_split("/\n/", $Series["Description"]);
					$Width = [];
					foreach($Lines as $Key => $Value) {
						$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 6, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key) , $FontName, $FontSize, 0, $Value);
						($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
						($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
						($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
						
						$Width[] = $BoxArray[1]["X"];
					}

					$vX = max($Width) + $XStep;
				}
			}
		}

		$vY = $vY - $YStep;
		$vX = $vX - $XStep;
		$TopOffset = $Y - $Boundaries["T"];
		if ($Boundaries["B"] - ($vY + $IconAreaHeight) < $TopOffset) {
			$Boundaries["B"] = $vY + $IconAreaHeight + $TopOffset;
		}

		if ($Style == LEGEND_ROUND) {
			$this->pChartObject->drawRoundedFilledRectangle($Boundaries["L"] - $Margin, $Boundaries["T"] - $Margin, $Boundaries["R"] + $Margin, $Boundaries["B"] + $Margin, $Margin, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"BorderR" => $BorderR,"BorderG" => $BorderG,"BorderB" => $BorderB]);
		} elseif ($Style == LEGEND_BOX) {
			$this->pChartObject->drawFilledRectangle($Boundaries["L"] - $Margin, $Boundaries["T"] - $Margin, $Boundaries["R"] + $Margin, $Boundaries["B"] + $Margin, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"BorderR" => $BorderR,"BorderG" => $BorderG,"BorderB" => $BorderB]);
		}

		$RestoreShadow = $this->pChartObject->Shadow;
		$this->Shadow = FALSE;
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE) {
				$R = $Series["Color"]["R"];
				$G = $Series["Color"]["G"];
				$B = $Series["Color"]["B"];
				$Ticks = $Series["Ticks"];
				$Weight = $Series["Weight"];
				if (isset($Series["Picture"])) {
					$Picture = $Series["Picture"];
					list($PicWidth, $PicHeight) = $this->pChartObject->getPicInfo($Picture);
					$PicX = $X + $IconAreaWidth / 2;
					$PicY = $Y + $IconAreaHeight / 2;
					$this->pChartObject->drawFromPNG($PicX - $PicWidth / 2, $PicY - $PicHeight / 2, $Picture);
					
				} else {
					if ($Family == LEGEND_FAMILY_BOX) {
						$XOffset = ($BoxWidth != $IconAreaWidth) ? floor(($IconAreaWidth - $BoxWidth) / 2) : 0;
						$YOffset = ($BoxHeight != $IconAreaHeight) ? floor(($IconAreaHeight - $BoxHeight) / 2) : 0;

						$this->pChartObject->drawFilledRectangle($X + 1 + $XOffset, $Y + 1 + $YOffset, $X + $BoxWidth + $XOffset + 1, $Y + $BoxHeight + 1 + $YOffset, ["R" => 0,"G" => 0,"B" => 0,"Alpha" => 20]);
						$this->pChartObject->drawFilledRectangle($X + $XOffset, $Y + $YOffset, $X + $BoxWidth + $XOffset, $Y + $BoxHeight + $YOffset, ["R" => $R,"G" => $G,"B" => $B,"Surrounding" => 20]);
					} elseif ($Family == LEGEND_FAMILY_CIRCLE) {
						$this->pChartObject->drawFilledCircle($X + 1 + $IconAreaWidth / 2, $Y + 1 + $IconAreaHeight / 2, min($IconAreaHeight / 2, $IconAreaWidth / 2), ["R" => 0,"G" => 0,"B" => 0,"Alpha" => 20]);
						$this->pChartObject->drawFilledCircle($X + $IconAreaWidth / 2, $Y + $IconAreaHeight / 2, min($IconAreaHeight / 2, $IconAreaWidth / 2), ["R" => $R,"G" => $G,"B" => $B,"Surrounding" => 20]);
					} elseif ($Family == LEGEND_FAMILY_LINE) {
						$this->pChartObject->drawLine($X + 1, $Y + 1 + $IconAreaHeight / 2, $X + 1 + $IconAreaWidth, $Y + 1 + $IconAreaHeight / 2, ["R" => 0,"G" => 0,"B" => 0,"Alpha" => 20,"Ticks" => $Ticks,	"Weight" => $Weight]);
						$this->pChartObject->drawLine($X, $Y + $IconAreaHeight / 2, $X + $IconAreaWidth, $Y + $IconAreaHeight / 2, ["R" => $R,"G" => $G,"B" => $B,"Ticks" => $Ticks,"Weight" => $Weight]);
					}
				}

				if ($Mode == LEGEND_VERTICAL) {
					$Lines = preg_split("/\n/", $Series["Description"]);
					foreach($Lines as $Key => $Value) $this->pChartObject->drawText($X + $IconAreaWidth + 4, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key), $Value, ["R" => $FontR,"G" => $FontG,"B" => $FontB,"Align" => TEXT_ALIGN_MIDDLELEFT]);
					$Y = $Y + max($this->pChartObject->FontSize * count($Lines) , $IconAreaHeight) + 5;
				} elseif ($Mode == LEGEND_HORIZONTAL) {
					$Lines = preg_split("/\n/", $Series["Description"]);
					$Width = [];
					foreach($Lines as $Key => $Value) {
						$BoxArray = $this->pChartObject->drawText($X + $IconAreaWidth + 4, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key) , $Value, ["R" => $FontR,"G" => $FontG,"B" => $FontB,"Align" => TEXT_ALIGN_MIDDLELEFT]);
						$Width[] = $BoxArray[1]["X"];
					}
					$X = max($Width) + 2 + $XStep;
				}
			}
		}

		$this->Shadow = $RestoreShadow;
	} 

	/* Get the legend box size */
	function getScatterLegendSize(array $Format = [])
	{
		$FontName = isset($Format["FontName"]) ? $Format["FontName"] : $this->pChartObject->FontName;
		$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->pChartObject->FontSize;
		$BoxSize = isset($Format["BoxSize"]) ? $Format["BoxSize"] : 5;
		$Margin = isset($Format["Margin"]) ? $Format["Margin"] : 5;
		$Style = isset($Format["Style"]) ? $Format["Style"] : LEGEND_ROUND;
		$Mode = isset($Format["Mode"]) ? $Format["Mode"] : LEGEND_VERTICAL;
		$YStep = max($this->pChartObject->FontSize, $BoxSize) + 5;
		$XStep = $BoxSize + 5;
		$X = 100;
		$Y = 100;
		$Data = $this->pDataObject->getData();
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE && isset($Series["Picture"])) {
				list($PicWidth, $PicHeight) = $this->pChartObject->getPicInfo($Series["Picture"]);
				($IconAreaWidth < $PicWidth) AND $IconAreaWidth = $PicWidth;
				($IconAreaHeight < $PicHeight) AND $IconAreaHeight = $PicHeight;
			}
		}

		$YStep = max($this->pChartObject->FontSize, $IconAreaHeight) + 5;
		$XStep = $IconAreaWidth + 5;
		$XStep = $XSpacing;
		$Boundaries = ["L" => $X, "T" => $Y, "R" => 0, "B" => 0];
		$vY = $Y;
		$vX = $X;
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE) {
				if ($Mode == LEGEND_VERTICAL) {
					$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 4, $vY + $IconAreaHeight / 2, $FontName, $FontSize, 0, $Series["Description"]);
					($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
					($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
					($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
					
					$Lines = preg_split("/\n/", $Series["Description"]);
					$vY = $vY + max($this->pChartObject->FontSize * count($Lines) , $IconAreaHeight) + 5;
					
				} elseif ($Mode == LEGEND_HORIZONTAL) {
					$Lines = preg_split("/\n/", $Series["Description"]);
					$Width = [];
					foreach($Lines as $Key => $Value) {
						$BoxArray = $this->pChartObject->getTextBox($vX + $IconAreaWidth + 6, $Y + $IconAreaHeight / 2 + (($this->pChartObject->FontSize + 3) * $Key) , $FontName, $FontSize, 0, $Value);
						($Boundaries["T"] > $BoxArray[2]["Y"] + $IconAreaHeight / 2) AND $Boundaries["T"] = $BoxArray[2]["Y"] + $IconAreaHeight / 2;
						($Boundaries["R"] < $BoxArray[1]["X"] + 2) AND $Boundaries["R"] = $BoxArray[1]["X"] + 2;
						($Boundaries["B"] < $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2) AND $Boundaries["B"] = $BoxArray[1]["Y"] + 2 + $IconAreaHeight / 2;
						
						$Width[] = $BoxArray[1]["X"];
					}

					$vX = max($Width) + $XStep;
				}
			}
		}

		$vY = $vY - $YStep;
		$vX = $vX - $XStep;
		$TopOffset = $Y - $Boundaries["T"];
		($Boundaries["B"] - ($vY + $BoxSize) < $TopOffset) AND $Boundaries["B"] = $vY + $BoxSize + $TopOffset;
		$Width = ($Boundaries["R"] + $Margin) - ($Boundaries["L"] - $Margin);
		$Height = ($Boundaries["B"] + $Margin) - ($Boundaries["T"] - $Margin);
		
		return ["Width" => $Width,"Height" => $Height];
	}

	/* Draw the line of best fit */
	function drawScatterBestFit(array $Format = [])
	{
		$Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : 0;
		$Data = $this->pDataObject->getData();
		foreach($Data["ScatterSeries"] as $Key => $Series) {
			if ($Series["isDrawable"] == TRUE) {
				$SerieX = $Series["X"];
				$SerieValuesX = $Data["Series"][$SerieX]["Data"];
				$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
				$SerieY = $Series["Y"];
				$SerieValuesY = $Data["Series"][$SerieY]["Data"];
				$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
				$Color = ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]];
				$Color["Ticks"] = $Ticks;
				$PosArrayX = $Data["Series"][$Series["X"]]["Data"];
				$PosArrayY = $Data["Series"][$Series["Y"]]["Data"];
				$Sxy = 0;
				$Sx = 0;
				$Sy = 0;
				$Sxx = 0;
				foreach($PosArrayX as $Key => $Value) {
					$X = $Value;
					$Y = $PosArrayY[$Key];
					$Sxy = $Sxy + $X * $Y;
					$Sx = $Sx + $X;
					$Sy = $Sy + $Y;
					$Sxx = $Sxx + $X * $X;
				}

				$n = count($PosArrayX);
				if ((($n * $Sxx) == ($Sx * $Sx))) {
					$X1 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMin"], $SerieXAxis);
					$X2 = $X1;
					$Y1 = $this->pChartObject->GraphAreaY1;
					$Y2 = $this->pChartObject->GraphAreaY2;
				} else {
					$M = (($n * $Sxy) - ($Sx * $Sy)) / (($n * $Sxx) - ($Sx * $Sx));
					$B = (($Sy) - ($M * $Sx)) / ($n);
					$X1 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMin"], $SerieXAxis);
					$Y1 = $this->getPosArray($M * $Data["Axis"][$SerieXAxis]["ScaleMin"] + $B, $SerieYAxis);
					$X2 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMax"], $SerieXAxis);
					$Y2 = $this->getPosArray($M * $Data["Axis"][$SerieXAxis]["ScaleMax"] + $B, $SerieYAxis);
					$RealM = - ($Y2 - $Y1) / ($X2 - $X1);
					if ($Y1 < $this->pChartObject->GraphAreaY1) {
						$X1 = $X1 + ($this->pChartObject->GraphAreaY1 - $Y1 / $RealM);
						$Y1 = $this->pChartObject->GraphAreaY1;
					}

					if ($Y1 > $this->pChartObject->GraphAreaY2) {
						$X1 = $X1 + ($Y1 - $this->pChartObject->GraphAreaY2) / $RealM;
						$Y1 = $this->pChartObject->GraphAreaY2;
					}

					if ($Y2 < $this->pChartObject->GraphAreaY1) {
						$X2 = $X2 - ($this->pChartObject->GraphAreaY1 - $Y2) / $RealM;
						$Y2 = $this->pChartObject->GraphAreaY1;
					}

					if ($Y2 > $this->pChartObject->GraphAreaY2) {
						$X2 = $X2 - ($Y2 - $this->pChartObject->GraphAreaY2) / $RealM;
						$Y2 = $this->pChartObject->GraphAreaY2;
					}
				}

				$this->pChartObject->drawLine($X1, $Y1, $X2, $Y2, $Color);
			}
		}
	}

	function writeScatterLabel($ScatterSerieID, $Points, array $Format = [])
	{
		$Data = $this->pDataObject->getData();
		$Palette = $this->pDataObject->getPalette();
				
		if (!isset($Data["ScatterSeries"][$ScatterSerieID])) {
			return 0;
		}
		
		(!is_array($Points)) AND $Points = [$Points]; 
		$OverrideTitle = isset($Format["OverrideTitle"]) ? $Format["OverrideTitle"] : NULL;
		$DrawPoint = isset($Format["DrawPoint"]) ? $Format["DrawPoint"] : LABEL_POINT_BOX;
		$Decimals = isset($Format["Decimals"]) ? $Format["Decimals"] : NULL;

		$Series = $Data["ScatterSeries"][$ScatterSerieID];
		$SerieX = $Series["X"];
		$SerieValuesX = $Data["Series"][$SerieX]["Data"];
		$SerieXAxis = $Data["Series"][$SerieX]["Axis"];
		$SerieY = $Series["Y"];
		$SerieValuesY = $Data["Series"][$SerieY]["Data"];
		$SerieYAxis = $Data["Series"][$SerieY]["Axis"];
		
		$PosArrayX = $this->getPosArray($SerieValuesX, $SerieXAxis);
		(!is_array($PosArrayX)) AND $PosArrayX = [0 => $PosArrayX];

		$PosArrayY = $this->getPosArray($SerieValuesY, $SerieYAxis);
		(!is_array($PosArrayY)) AND $PosArrayY = [0 => $PosArrayY];

		foreach($Points as $Key => $Point) {
			if (isset($PosArrayX[$Point]) && isset($PosArrayY[$Point])) {
				$X = floor($PosArrayX[$Point]);
				$Y = floor($PosArrayY[$Point]);
				if ($DrawPoint == LABEL_POINT_CIRCLE) {
					$this->pChartObject->drawFilledCircle($X, $Y, 3, ["R" => 255,"G" => 255,"B" => 255,"BorderR" => 0,"BorderG" => 0,"BorderB" => 0]);
				} elseif ($DrawPoint == LABEL_POINT_BOX) {
					$this->pChartObject->drawFilledRectangle($X - 2, $Y - 2, $X + 2, $Y + 2, ["R" => 255,"G" => 255,"B" => 255,"BorderR" => 0,"BorderG" => 0,"BorderB" => 0]);
				}

				$XValue = ($Decimals == NULL) ? $SerieValuesX[$Point] : round($SerieValuesX[$Point], $Decimals);
				$XValue = $this->pChartObject->scaleFormat($XValue, $Data["Axis"][$SerieXAxis]["Display"], $Data["Axis"][$SerieXAxis]["Format"], $Data["Axis"][$SerieXAxis]["Unit"]);
				
				$YValue = ($Decimals == NULL) ? $SerieValuesY[$Point] : round($SerieValuesY[$Point], $Decimals);
				$YValue = $this->pChartObject->scaleFormat($YValue, $Data["Axis"][$SerieYAxis]["Display"], $Data["Axis"][$SerieYAxis]["Format"], $Data["Axis"][$SerieYAxis]["Unit"]);
				
				$Description = (isset($Series["Description"])) ? $Series["Description"] : "No description";
				$Series = ["Format" => ["R" => $Series["Color"]["R"],"G" => $Series["Color"]["G"],"B" => $Series["Color"]["B"],"Alpha" => $Series["Color"]["Alpha"]],"Caption" => $XValue . " / " . $YValue];
				$this->pChartObject->drawLabelBox($X, $Y - 3, $Description, $Series, $Format);
			}
		}
	}

	/* Draw a Scatter threshold */
	function drawScatterThreshold($Value, array $Format = [])
	{
				
		$AxisID = 0;
		$R = 255;
		$G = 0;
		$B = 0;
		$Alpha = 50;
		$Weight = NULL;
		$Ticks = 3;
		$Wide = FALSE;
		$WideFactor = 5;
		$WriteCaption = FALSE;
		$Caption = NULL;
		$CaptionAlign = CAPTION_LEFT_TOP;
		$CaptionOffset = 10;
		$CaptionR = 255;
		$CaptionG = 255;
		$CaptionB = 255;
		$CaptionAlpha = 100;
		$DrawBox = TRUE;
		$DrawBoxBorder = FALSE;
		$BorderOffset = 5;
		$BoxRounded = TRUE;
		$RoundedRadius = 3;
		$BoxR = 0;
		$BoxG = 0;
		$BoxB = 0;
		$BoxAlpha = 20;
		$BoxSurrounding = "";
		$BoxBorderR = 255;
		$BoxBorderG = 255;
		$BoxBorderB = 255;
		$BoxBorderAlpha = 100;
		
		/* Override defaults */
		extract($Format);
		
		$Data = $this->pDataObject->getData();
		if (!isset($Data["Axis"][$AxisID])) {
			return -1;
		}
		
		($Caption == NULL) AND $Caption = $Value;
		$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 ($Data["Axis"][$AxisID]["Identity"] == AXIS_Y) {
			$X1 = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"];
			$X2 = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"];
			$Y = $this->getPosArray($Value, $AxisID);
			$this->pChartObject->drawLine($X1, $Y, $X2, $Y, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks,"Weight" => $Weight]);
			if ($Wide) {
				$this->pChartObject->drawLine($X1, $Y - 1, $X2, $Y - 1, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
				$this->pChartObject->drawLine($X1, $Y + 1, $X2, $Y + 1, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
			}

			if ($WriteCaption) {
				if ($CaptionAlign == CAPTION_LEFT_TOP) {
					$X = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"] + $CaptionOffset;
					$CaptionSettings["Align"] = TEXT_ALIGN_MIDDLELEFT;
				} else {
					$X = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"] - $CaptionOffset;
					$CaptionSettings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
				}

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

			return ["Y" => $Y];
			
		} elseif ($Data["Axis"][$AxisID]["Identity"] == AXIS_X) {
			$X = $this->getPosArray($Value, $AxisID);
			$Y1 = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"];
			$Y2 = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"];
			$this->pChartObject->drawLine($X, $Y1, $X, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha,"Ticks" => $Ticks,"Weight" => $Weight]);
			if ($Wide) {
				$this->pChartObject->drawLine($X - 1, $Y1, $X - 1, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
				$this->pChartObject->drawLine($X + 1, $Y1, $X + 1, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha / $WideFactor,"Ticks" => $Ticks]);
			}

			if ($WriteCaption) {
				if ($CaptionAlign == CAPTION_LEFT_TOP) {
					$Y = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"] + $CaptionOffset;
					#$CaptionSettings["Align"] = TEXT_ALIGN_TOPMIDDLE; # POINTLESS
				} else {
					$Y = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"] - $CaptionOffset;
					#$CaptionSettings["Align"] = TEXT_ALIGN_BOTTOMMIDDLE; # POINTLESS
				}

				$CaptionSettings["Align"] = TEXT_ALIGN_TOPMIDDLE;
				$this->pChartObject->drawText($X, $Y, $Caption, $CaptionSettings);
			}

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

	/* Draw a Scatter threshold area */
	function drawScatterThresholdArea($Value1, $Value2, array $Format = [])
	{		
		$AxisID = 0;
		$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"] : 20;
		$Border = TRUE;
		$BorderR = $R;
		$BorderG = $G;
		$BorderB = $B;
		$BorderAlpha = $Alpha + 20;
		$BorderTicks = 2;
		$AreaName = "La ouate de phoque"; //NULL;
		$NameAngle = ZONE_NAME_ANGLE_AUTO;
		$NameR = 255;
		$NameG = 255;
		$NameB = 255;
		$NameAlpha = 100;
		$DisableShadowOnArea = TRUE;
		
		/* Override defaults */
		extract($Format);
		
		$Data = $this->pDataObject->getData();
		if (!isset($Data["Axis"][$AxisID])) {
			return -1;
		}
		
		($BorderAlpha > 100) AND $BorderAlpha = 100;
				
		if ($Value1 > $Value2) {
			list($Value1, $Value2) = [$Value2,$Value1];
		}

		$RestoreShadow = $this->pChartObject->Shadow;
		if ($DisableShadowOnArea && $this->pChartObject->Shadow) {
			$this->pChartObject->Shadow = FALSE;
		}
	
		if ($Data["Axis"][$AxisID]["Identity"] == AXIS_X) {
			$Y1 = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"];
			$Y2 = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"];
			$X1 = $this->getPosArray($Value1, $AxisID);
			$X2 = $this->getPosArray($Value2, $AxisID);
			if ($X1 <= $this->pChartObject->GraphAreaX1) {
				$X1 = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"];
			}

			if ($X2 >= $this->pChartObject->GraphAreaX2) {
				$X2 = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"];
			}

			$this->pChartObject->drawFilledRectangle($X1, $Y1, $X2, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha]);
			
			if ($Border) {
				$this->pChartObject->drawLine($X1, $Y1, $X1, $Y2, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
				$this->pChartObject->drawLine($X2, $Y1, $X2, $Y2, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
			}

			if ($AreaName != NULL) {
				$XPos = ($X2 - $X1) / 2 + $X1;
				$YPos = ($Y2 - $Y1) / 2 + $Y1;
				if ($NameAngle == ZONE_NAME_ANGLE_AUTO) {
					$TxtPos = $this->pChartObject->getTextBox($XPos, $YPos, $this->pChartObject->FontName, $this->pChartObject->FontSize, 0, $AreaName);
					$TxtWidth = $TxtPos[1]["X"] - $TxtPos[0]["X"];
					$NameAngle = (abs($X2 - $X1) > $TxtWidth) ? 0 : 90;
				}

				$this->pChartObject->Shadow = $RestoreShadow;
				$this->pChartObject->drawText($XPos, $YPos, $AreaName, ["R" => $NameR,"G" => $NameG,"B" => $NameB,"Alpha" => $NameAlpha,"Angle" => $NameAngle,"Align" => TEXT_ALIGN_MIDDLEMIDDLE]);
				($DisableShadowOnArea) AND $this->pChartObject->Shadow = FALSE;
			}

			$this->pChartObject->Shadow = $RestoreShadow;
			
			return ["X1" => $X1,"X2" => $X2];
			
		} elseif ($Data["Axis"][$AxisID]["Identity"] == AXIS_Y) {
			
			$X1 = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"];
			$X2 = $this->pChartObject->GraphAreaX2 - $Data["Axis"][$AxisID]["Margin"];
			$Y1 = $this->getPosArray($Value1, $AxisID);
			$Y2 = $this->getPosArray($Value2, $AxisID);
			if ($Y1 >= $this->pChartObject->GraphAreaY2) {
				$Y1 = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"];
			}

			if ($Y2 <= $this->pChartObject->GraphAreaY1) {
				$Y2 = $this->pChartObject->GraphAreaY1 + $Data["Axis"][$AxisID]["Margin"];
			}

			$this->pChartObject->drawFilledRectangle($X1, $Y1, $X2, $Y2, ["R" => $R,"G" => $G,"B" => $B,"Alpha" => $Alpha]);
			if ($Border) {
				$this->pChartObject->drawLine($X1, $Y1, $X2, $Y1, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
				$this->pChartObject->drawLine($X1, $Y2, $X2, $Y2, ["R" => $BorderR,"G" => $BorderG,"B" => $BorderB,"Alpha" => $BorderAlpha,"Ticks" => $BorderTicks]);
			}

			if ($AreaName != NULL) {
				$XPos = ($X2 - $X1) / 2 + $X1;
				$YPos = ($Y2 - $Y1) / 2 + $Y1;
				$this->pChartObject->Shadow = $RestoreShadow;
				$this->pChartObject->drawText($YPos, $XPos, $AreaName, ["R" => $NameR,"G" => $NameG,"B" => $NameB,"Alpha" => $NameAlpha,"Angle" => 0,"Align" => TEXT_ALIGN_MIDDLEMIDDLE]);
				($DisableShadowOnArea) AND $this->Shadow = FALSE;
			}

			$this->pChartObject->Shadow = $RestoreShadow;
			
			return ["Y1" => $Y1,"Y2" => $Y2];
		}
	}
}

?>