Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,532 @@
<?php
namespace CpChart\Chart;
use CpChart\Data;
use CpChart\Image;
/**
* Bubble - class to draw bubble 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.
*/
class Bubble
{
/**
* @var Image
*/
public $pChartObject;
/**
* @var Data
*/
public $pDataObject;
/**
* @param Image $pChartObject
* @param Data $pDataObject
*/
public function __construct(Image $pChartObject, Data $pDataObject)
{
$this->pChartObject = $pChartObject;
$this->pDataObject = $pDataObject;
}
/**
* Prepare the scale
*
* @param mixed $DataSeries
* @param mixed $WeightSeries
*/
public function bubbleScale($DataSeries, $WeightSeries)
{
if (!is_array($DataSeries)) {
$DataSeries = [$DataSeries];
}
if (!is_array($WeightSeries)) {
$WeightSeries = [$WeightSeries];
}
/* Parse each data series to find the new min & max boundaries to scale */
$NewPositiveSerie = [];
$NewNegativeSerie = [];
$MaxValues = 0;
$LastPositive = 0;
$LastNegative = 0;
foreach ($DataSeries as $Key => $SerieName) {
$SerieWeightName = $WeightSeries[$Key];
$this->pDataObject->setSerieDrawable($SerieWeightName, false);
$serieData = $this->pDataObject->Data["Series"][$SerieName]["Data"];
if (count($serieData) > $MaxValues) {
$MaxValues = count($serieData);
}
foreach ($serieData as $Key => $Value) {
if ($Value >= 0) {
$BubbleBounds = $Value + $this->pDataObject->Data["Series"][$SerieWeightName]["Data"][$Key];
if (!isset($NewPositiveSerie[$Key])) {
$NewPositiveSerie[$Key] = $BubbleBounds;
} elseif ($NewPositiveSerie[$Key] < $BubbleBounds) {
$NewPositiveSerie[$Key] = $BubbleBounds;
}
$LastPositive = $BubbleBounds;
} else {
$BubbleBounds = $Value - $this->pDataObject->Data["Series"][$SerieWeightName]["Data"][$Key];
if (!isset($NewNegativeSerie[$Key])) {
$NewNegativeSerie[$Key] = $BubbleBounds;
} elseif ($NewNegativeSerie[$Key] > $BubbleBounds) {
$NewNegativeSerie[$Key] = $BubbleBounds;
}
$LastNegative = $BubbleBounds;
}
}
}
/* Check for missing values and all the fake positive serie */
if (count($NewPositiveSerie)) {
for ($i = 0; $i < $MaxValues; $i++) {
if (!isset($NewPositiveSerie[$i])) {
$NewPositiveSerie[$i] = $LastPositive;
}
}
$this->pDataObject->addPoints($NewPositiveSerie, "BubbleFakePositiveSerie");
}
/* Check for missing values and all the fake negative serie */
if (count($NewNegativeSerie)) {
for ($i = 0; $i < $MaxValues; $i++) {
if (!isset($NewNegativeSerie[$i])) {
$NewNegativeSerie[$i] = $LastNegative;
}
}
$this->pDataObject->addPoints($NewNegativeSerie, "BubbleFakeNegativeSerie");
}
}
public function resetSeriesColors()
{
$Data = $this->pDataObject->getData();
$Palette = $this->pDataObject->getPalette();
$ID = 0;
foreach ($Data["Series"] as $SerieName => $SeriesParameters) {
if ($SeriesParameters["isDrawable"]) {
$this->pDataObject->Data["Series"][$SerieName]["Color"]["R"] = $Palette[$ID]["R"];
$this->pDataObject->Data["Series"][$SerieName]["Color"]["G"] = $Palette[$ID]["G"];
$this->pDataObject->Data["Series"][$SerieName]["Color"]["B"] = $Palette[$ID]["B"];
$this->pDataObject->Data["Series"][$SerieName]["Color"]["Alpha"] = $Palette[$ID]["Alpha"];
$ID++;
}
}
}
/* Prepare the scale */
public function drawBubbleChart($DataSeries, $WeightSeries, $Format = "")
{
$ForceAlpha = isset($Format["ForceAlpha"]) ? $Format["ForceAlpha"] : VOID;
$DrawBorder = isset($Format["DrawBorder"]) ? $Format["DrawBorder"] : true;
$BorderWidth = isset($Format["BorderWidth"]) ? $Format["BorderWidth"] : 1;
$Shape = isset($Format["Shape"]) ? $Format["Shape"] : BUBBLE_SHAPE_ROUND;
$Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : null;
$BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : 0;
$BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : 0;
$BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : 0;
$BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : 30;
$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : false;
if (!is_array($DataSeries)) {
$DataSeries = [$DataSeries];
}
if (!is_array($WeightSeries)) {
$WeightSeries = [$WeightSeries];
}
$Data = $this->pDataObject->getData();
$Palette = $this->pDataObject->getPalette();
if (isset($Data["Series"]["BubbleFakePositiveSerie"])) {
$this->pDataObject->setSerieDrawable("BubbleFakePositiveSerie", false);
}
if (isset($Data["Series"]["BubbleFakeNegativeSerie"])) {
$this->pDataObject->setSerieDrawable("BubbleFakeNegativeSerie", false);
}
$this->resetSeriesColors();
list($XMargin, $XDivs) = $this->pChartObject->scaleGetXSettings();
foreach ($DataSeries as $Key => $SerieName) {
$AxisID = $Data["Series"][$SerieName]["Axis"];
$Mode = $Data["Axis"][$AxisID]["Display"];
$Format = $Data["Axis"][$AxisID]["Format"];
$Unit = $Data["Axis"][$AxisID]["Unit"];
if (isset($Data["Series"][$SerieName]["Description"])) {
$SerieDescription = $Data["Series"][$SerieName]["Description"];
} else {
$SerieDescription = $SerieName;
}
$XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs;
$X = $this->pChartObject->GraphAreaX1 + $XMargin;
$Y = $this->pChartObject->GraphAreaY1 + $XMargin;
$Color = [
"R" => $Palette[$Key]["R"],
"G" => $Palette[$Key]["G"],
"B" => $Palette[$Key]["B"],
"Alpha" => $Palette[$Key]["Alpha"]
];
if ($ForceAlpha != VOID) {
$Color["Alpha"] = $ForceAlpha;
}
if ($DrawBorder) {
if ($BorderWidth != 1) {
if ($Surrounding != null) {
$BorderR = $Palette[$Key]["R"] + $Surrounding;
$BorderG = $Palette[$Key]["G"] + $Surrounding;
$BorderB = $Palette[$Key]["B"] + $Surrounding;
}
if ($ForceAlpha != VOID) {
$BorderAlpha = $ForceAlpha / 2;
}
$BorderColor = [
"R" => $BorderR,
"G" => $BorderG,
"B" => $BorderB,
"Alpha" => $BorderAlpha
];
} else {
$Color["BorderAlpha"] = $BorderAlpha;
if ($Surrounding != null) {
$Color["BorderR"] = $Palette[$Key]["R"] + $Surrounding;
$Color["BorderG"] = $Palette[$Key]["G"] + $Surrounding;
$Color["BorderB"] = $Palette[$Key]["B"] + $Surrounding;
} else {
$Color["BorderR"] = $BorderR;
$Color["BorderG"] = $BorderG;
$Color["BorderB"] = $BorderB;
}
if ($ForceAlpha != VOID) {
$Color["BorderAlpha"] = $ForceAlpha / 2;
}
}
}
foreach ($Data["Series"][$SerieName]["Data"] as $iKey => $Point) {
$Weight = $Point + $Data["Series"][$WeightSeries[$Key]]["Data"][$iKey];
$PosArray = $this->pChartObject->scaleComputeY(
$Point,
["AxisID" => $AxisID]
);
$WeightArray = $this->pChartObject->scaleComputeY(
$Weight,
["AxisID" => $AxisID]
);
if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
if ($XDivs == 0) {
$XStep = 0;
} else {
$XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2)
/ $XDivs
;
}
$Y = floor($PosArray);
$CircleRadius = floor(abs($PosArray - $WeightArray) / 2);
if ($Shape == BUBBLE_SHAPE_SQUARE) {
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"RECT",
(
floor($X - $CircleRadius)
. "," . floor($Y - $CircleRadius)
. "," . floor($X + $CircleRadius)
. "," . floor($Y + $CircleRadius)
),
$this->pChartObject->toHTMLColor(
$Palette[$Key]["R"],
$Palette[$Key]["G"],
$Palette[$Key]["B"]
),
$SerieDescription,
$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]
);
}
if ($BorderWidth != 1) {
$this->pChartObject->drawFilledRectangle(
$X - $CircleRadius - $BorderWidth,
$Y - $CircleRadius - $BorderWidth,
$X + $CircleRadius + $BorderWidth,
$Y + $CircleRadius + $BorderWidth,
$BorderColor
);
$this->pChartObject->drawFilledRectangle(
$X - $CircleRadius,
$Y - $CircleRadius,
$X + $CircleRadius,
$Y + $CircleRadius,
$Color
);
} else {
$this->pChartObject->drawFilledRectangle(
$X - $CircleRadius,
$Y - $CircleRadius,
$X + $CircleRadius,
$Y + $CircleRadius,
$Color
);
}
} elseif ($Shape == BUBBLE_SHAPE_ROUND) {
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"CIRCLE",
floor($X) . "," . floor($Y) . "," . floor($CircleRadius),
$this->pChartObject->toHTMLColor(
$Palette[$Key]["R"],
$Palette[$Key]["G"],
$Palette[$Key]["B"]
),
$SerieDescription,
$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]
);
}
if ($BorderWidth != 1) {
$this->pChartObject->drawFilledCircle(
$X,
$Y,
$CircleRadius + $BorderWidth,
$BorderColor
);
$this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
} else {
$this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
}
}
$X = $X + $XStep;
} elseif ($Data["Orientation"] == SCALE_POS_TOPBOTTOM) {
if ($XDivs == 0) {
$XStep = 0;
} else {
$XStep = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $XMargin * 2)
/ $XDivs
;
}
$X = floor($PosArray);
$CircleRadius = floor(abs($PosArray - $WeightArray) / 2);
if ($Shape == BUBBLE_SHAPE_SQUARE) {
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"RECT",
(
floor($X - $CircleRadius) . ","
. floor($Y - $CircleRadius) . ","
. floor($X + $CircleRadius) . ","
. floor($Y + $CircleRadius)
),
$this->pChartObject->toHTMLColor(
$Palette[$Key]["R"],
$Palette[$Key]["G"],
$Palette[$Key]["B"]
),
$SerieDescription,
$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]
);
}
if ($BorderWidth != 1) {
$this->pChartObject->drawFilledRectangle(
$X - $CircleRadius - $BorderWidth,
$Y - $CircleRadius - $BorderWidth,
$X + $CircleRadius + $BorderWidth,
$Y + $CircleRadius + $BorderWidth,
$BorderColor
);
$this->pChartObject->drawFilledRectangle(
$X - $CircleRadius,
$Y - $CircleRadius,
$X + $CircleRadius,
$Y + $CircleRadius,
$Color
);
} else {
$this->pChartObject->drawFilledRectangle(
$X - $CircleRadius,
$Y - $CircleRadius,
$X + $CircleRadius,
$Y + $CircleRadius,
$Color
);
}
} elseif ($Shape == BUBBLE_SHAPE_ROUND) {
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"CIRCLE",
floor($X) . "," . floor($Y) . "," . floor($CircleRadius),
$this->pChartObject->toHTMLColor(
$Palette[$Key]["R"],
$Palette[$Key]["G"],
$Palette[$Key]["B"]
),
$SerieDescription,
$Data["Series"][$WeightSeries[$Key]]["Data"][$iKey]
);
}
if ($BorderWidth != 1) {
$this->pChartObject->drawFilledCircle(
$X,
$Y,
$CircleRadius + $BorderWidth,
$BorderColor
);
$this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
} else {
$this->pChartObject->drawFilledCircle($X, $Y, $CircleRadius, $Color);
}
}
$Y = $Y + $XStep;
}
}
}
}
public function writeBubbleLabel($SerieName, $SerieWeightName, $Points, $Format = "")
{
$DrawPoint = isset($Format["DrawPoint"]) ? $Format["DrawPoint"] : LABEL_POINT_BOX;
if (!is_array($Points)) {
$Point = $Points;
$Points = [];
$Points[] = $Point;
}
$Data = $this->pDataObject->getData();
if (!isset($Data["Series"][$SerieName])
|| !isset($Data["Series"][$SerieWeightName])
) {
return(0);
}
list($XMargin, $XDivs) = $this->pChartObject->scaleGetXSettings();
$AxisID = $Data["Series"][$SerieName]["Axis"];
$AxisMode = $Data["Axis"][$AxisID]["Display"];
$AxisFormat = $Data["Axis"][$AxisID]["Format"];
$AxisUnit = $Data["Axis"][$AxisID]["Unit"];
$XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs;
$X = $InitialX = $this->pChartObject->GraphAreaX1 + $XMargin;
$Y = $InitialY = $this->pChartObject->GraphAreaY1 + $XMargin;
$Color = [
"R" => $Data["Series"][$SerieName]["Color"]["R"],
"G" => $Data["Series"][$SerieName]["Color"]["G"],
"B" => $Data["Series"][$SerieName]["Color"]["B"],
"Alpha" => $Data["Series"][$SerieName]["Color"]["Alpha"]
];
foreach ($Points as $Key => $Point) {
$Value = $Data["Series"][$SerieName]["Data"][$Point];
$PosArray = $this->pChartObject->scaleComputeY($Value, ["AxisID" => $AxisID]);
if (isset($Data["Abscissa"]) && isset($Data["Series"][$Data["Abscissa"]]["Data"][$Point])) {
$Abscissa = $Data["Series"][$Data["Abscissa"]]["Data"][$Point] . " : ";
} else {
$Abscissa = "";
}
$Value = $this->pChartObject->scaleFormat($Value, $AxisMode, $AxisFormat, $AxisUnit);
$Weight = $Data["Series"][$SerieWeightName]["Data"][$Point];
$Caption = $Abscissa . $Value . " / " . $Weight;
if (isset($Data["Series"][$SerieName]["Description"])) {
$Description = $Data["Series"][$SerieName]["Description"];
} else {
$Description = "No description";
}
$Series = [["Format" => $Color, "Caption" => $Caption]];
if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
if ($XDivs == 0) {
$XStep = 0;
} else {
$XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2)
/ $XDivs
;
}
$X = floor($InitialX + $Point * $XStep);
$Y = floor($PosArray);
} else {
if ($XDivs == 0) {
$YStep = 0;
} else {
$YStep = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $XMargin * 2)
/ $XDivs
;
}
$X = floor($PosArray);
$Y = floor($InitialY + $Point * $YStep);
}
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
]
);
}
$this->pChartObject->drawLabelBox($X, $Y - 3, $Description, $Series, $Format);
}
}
}

View File

@@ -0,0 +1,377 @@
<?php
namespace CpChart\Chart;
use CpChart\Image;
/**
* Indicator - class to draw indicators
*
* 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.
*/
class Indicator
{
/**
* @var Image
*/
public $pChartObject;
/**
* @param Image $pChartObject
*/
public function __construct(Image $pChartObject)
{
$this->pChartObject = $pChartObject;
}
/**
* Draw an indicator
*
* @param int $X
* @param int $Y
* @param int $Width
* @param int $Height
* @param array $Format
* @return null|int
*/
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;
}
}

2320
vendor/szymach/c-pchart/src/Chart/Pie.php vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
<?php
namespace CpChart\Chart;
use CpChart\Data;
use CpChart\Image;
/**
* Split - class to draw spline splitted 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.
*/
class Split
{
/**
* @var Image
*/
public $pChartObject;
/**
* Create the encoded string
* @param Image $Object
* @param Data $Values
* @param array $Format
*/
public function drawSplitPath(Image $Object, Data $Values, array $Format = [])
{
$this->pChartObject = $Object;
$Spacing = isset($Format["Spacing"]) ? $Format["Spacing"] : 20;
$TextPadding = isset($Format["TextPadding"]) ? $Format["TextPadding"] : 2;
$TextPos = isset($Format["TextPos"]) ? $Format["TextPos"] : TEXT_POS_TOP;
$Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : null;
$Force = isset($Format["Force"]) ? $Format["Force"] : 70;
$Segments = isset($Format["Segments"]) ? $Format["Segments"] : 15;
$X1 = $Object->GraphAreaX1;
$Y1 = $Object->GraphAreaY1;
$X2 = $Object->GraphAreaX2;
$Y2 = $Object->GraphAreaY2;
/* Data Processing */
$Data = $Values->getData();
$Palette = $Values->getPalette();
$LabelSerie = $Data["Abscissa"];
$DataSerie = [];
foreach ($Data["Series"] as $SerieName => $Value) {
if ($SerieName != $LabelSerie && empty($DataSerie)) {
$DataSerie = $SerieName;
}
}
$DataSerieSum = array_sum($Data["Series"][$DataSerie]["Data"]);
$DataSerieCount = count($Data["Series"][$DataSerie]["Data"]);
/* Scale Processing */
if ($TextPos == TEXT_POS_RIGHT) {
$YScale = (($Y2 - $Y1) - (($DataSerieCount + 1) * $Spacing)) / $DataSerieSum;
} else {
$YScale = (($Y2 - $Y1) - ($DataSerieCount * $Spacing)) / $DataSerieSum;
}
$LeftHeight = $DataSerieSum * $YScale;
/* Re-compute graph width depending of the text mode choosen */
if ($TextPos == TEXT_POS_RIGHT) {
$MaxWidth = 0;
foreach ($Data["Series"][$LabelSerie]["Data"] as $Key => $Label) {
$Boundardies = $Object->getTextBox(0, 0, $Object->FontName, $Object->FontSize, 0, $Label);
if ($Boundardies[1]["X"] > $MaxWidth) {
$MaxWidth = $Boundardies[1]["X"] + $TextPadding * 2;
}
}
$X2 = $X2 - $MaxWidth;
}
/* Drawing */
$LeftY = ((($Y2 - $Y1) / 2) + $Y1) - ($LeftHeight / 2);
$RightY = $Y1;
foreach ($Data["Series"][$DataSerie]["Data"] as $Key => $Value) {
if (isset($Data["Series"][$LabelSerie]["Data"][$Key])) {
$Label = $Data["Series"][$LabelSerie]["Data"][$Key];
} else {
$Label = "-";
}
$LeftY1 = $LeftY;
$LeftY2 = $LeftY + $Value * $YScale;
$RightY1 = $RightY + $Spacing;
$RightY2 = $RightY + $Spacing + $Value * $YScale;
$Settings = [
"R" => $Palette[$Key]["R"],
"G" => $Palette[$Key]["G"],
"B" => $Palette[$Key]["B"],
"Alpha" => $Palette[$Key]["Alpha"],
"NoDraw" => true,
"Segments" => $Segments,
"Surrounding" => $Surrounding
];
$Angle = $Object->getAngle($X2, $RightY1, $X1, $LeftY1);
$VectorX1 = cos(deg2rad($Angle + 90)) * $Force + ($X2 - $X1) / 2 + $X1;
$VectorY1 = sin(deg2rad($Angle + 90)) * $Force + ($RightY1 - $LeftY1) / 2 + $LeftY1;
$VectorX2 = cos(deg2rad($Angle - 90)) * $Force + ($X2 - $X1) / 2 + $X1;
$VectorY2 = sin(deg2rad($Angle - 90)) * $Force + ($RightY1 - $LeftY1) / 2 + $LeftY1;
$Points = $Object->drawBezier(
$X1,
$LeftY1,
$X2,
$RightY1,
$VectorX1,
$VectorY1,
$VectorX2,
$VectorY2,
$Settings
);
$PolyGon = [];
foreach ($Points as $Key => $Pos) {
$PolyGon[] = $Pos["X"];
$PolyGon[] = $Pos["Y"];
}
$Angle = $Object->getAngle($X2, $RightY2, $X1, $LeftY2);
$VectorX1 = cos(deg2rad($Angle + 90)) * $Force + ($X2 - $X1) / 2 + $X1;
$VectorY1 = sin(deg2rad($Angle + 90)) * $Force + ($RightY2 - $LeftY2) / 2 + $LeftY2;
$VectorX2 = cos(deg2rad($Angle - 90)) * $Force + ($X2 - $X1) / 2 + $X1;
$VectorY2 = sin(deg2rad($Angle - 90)) * $Force + ($RightY2 - $LeftY2) / 2 + $LeftY2;
$Points = $Object->drawBezier(
$X1,
$LeftY2,
$X2,
$RightY2,
$VectorX1,
$VectorY1,
$VectorX2,
$VectorY2,
$Settings
);
$Points = array_reverse($Points);
foreach ($Points as $Key => $Pos) {
$PolyGon[] = $Pos["X"];
$PolyGon[] = $Pos["Y"];
}
$Object->drawPolygon($PolyGon, $Settings);
if ($TextPos == TEXT_POS_RIGHT) {
$Object->drawText(
$X2 + $TextPadding,
($RightY2 - $RightY1) / 2 + $RightY1,
$Label,
["Align" => TEXT_ALIGN_MIDDLELEFT]
);
} else {
$Object->drawText(
$X2,
$RightY1 - $TextPadding,
$Label,
["Align" => TEXT_ALIGN_BOTTOMRIGHT]
);
}
$LeftY = $LeftY2;
$RightY = $RightY2;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,453 @@
<?php
namespace CpChart\Chart;
use CpChart\Data;
use CpChart\Image;
/**
* Stock - class to draw stock 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.
*/
class Stock
{
/**
* @var Image
*/
public $pChartObject;
/**
* @var Data
*/
public $pDataObject;
/**
* @param Image $pChartObject
* @param Data $pDataObject
*/
public function __construct(Image $pChartObject, Data $pDataObject)
{
$this->pChartObject = $pChartObject;
$this->pDataObject = $pDataObject;
}
/**
* Draw a stock chart
* @param array $Format
* @return integer|null
*/
public function drawStockChart(array $Format = [])
{
$SerieOpen = isset($Format["SerieOpen"]) ? $Format["SerieOpen"] : "Open";
$SerieClose = isset($Format["SerieClose"]) ? $Format["SerieClose"] : "Close";
$SerieMin = isset($Format["SerieMin"]) ? $Format["SerieMin"] : "Min";
$SerieMax = isset($Format["SerieMax"]) ? $Format["SerieMax"] : "Max";
$SerieMedian = isset($Format["SerieMedian"]) ? $Format["SerieMedian"] : null;
$LineWidth = isset($Format["LineWidth"]) ? $Format["LineWidth"] : 1;
$LineR = isset($Format["LineR"]) ? $Format["LineR"] : 0;
$LineG = isset($Format["LineG"]) ? $Format["LineG"] : 0;
$LineB = isset($Format["LineB"]) ? $Format["LineB"] : 0;
$LineAlpha = isset($Format["LineAlpha"]) ? $Format["LineAlpha"] : 100;
$ExtremityWidth = isset($Format["ExtremityWidth"]) ? $Format["ExtremityWidth"] : 1;
$ExtremityLength = isset($Format["ExtremityLength"]) ? $Format["ExtremityLength"] : 3;
$ExtremityR = isset($Format["ExtremityR"]) ? $Format["ExtremityR"] : 0;
$ExtremityG = isset($Format["ExtremityG"]) ? $Format["ExtremityG"] : 0;
$ExtremityB = isset($Format["ExtremityB"]) ? $Format["ExtremityB"] : 0;
$ExtremityAlpha = isset($Format["ExtremityAlpha"]) ? $Format["ExtremityAlpha"] : 100;
$BoxWidth = isset($Format["BoxWidth"]) ? $Format["BoxWidth"] : 8;
$BoxUpR = isset($Format["BoxUpR"]) ? $Format["BoxUpR"] : 188;
$BoxUpG = isset($Format["BoxUpG"]) ? $Format["BoxUpG"] : 224;
$BoxUpB = isset($Format["BoxUpB"]) ? $Format["BoxUpB"] : 46;
$BoxUpAlpha = isset($Format["BoxUpAlpha"]) ? $Format["BoxUpAlpha"] : 100;
$BoxUpSurrounding = isset($Format["BoxUpSurrounding"]) ? $Format["BoxUpSurrounding"] : null;
$BoxUpBorderR = isset($Format["BoxUpBorderR"]) ? $Format["BoxUpBorderR"] : $BoxUpR - 20;
$BoxUpBorderG = isset($Format["BoxUpBorderG"]) ? $Format["BoxUpBorderG"] : $BoxUpG - 20;
$BoxUpBorderB = isset($Format["BoxUpBorderB"]) ? $Format["BoxUpBorderB"] : $BoxUpB - 20;
$BoxUpBorderAlpha = isset($Format["BoxUpBorderAlpha"]) ? $Format["BoxUpBorderAlpha"] : 100;
$BoxDownR = isset($Format["BoxDownR"]) ? $Format["BoxDownR"] : 224;
$BoxDownG = isset($Format["BoxDownG"]) ? $Format["BoxDownG"] : 100;
$BoxDownB = isset($Format["BoxDownB"]) ? $Format["BoxDownB"] : 46;
$BoxDownAlpha = isset($Format["BoxDownAlpha"]) ? $Format["BoxDownAlpha"] : 100;
$BoxDownSurrounding = isset($Format["BoxDownSurrounding"]) ? $Format["BoxDownSurrounding"] : null;
$BoxDownBorderR = isset($Format["BoxDownBorderR"]) ? $Format["BoxDownBorderR"] : $BoxDownR - 20;
$BoxDownBorderG = isset($Format["BoxDownBorderG"]) ? $Format["BoxDownBorderG"] : $BoxDownG - 20;
$BoxDownBorderB = isset($Format["BoxDownBorderB"]) ? $Format["BoxDownBorderB"] : $BoxDownB - 20;
$BoxDownBorderAlpha = isset($Format["BoxDownBorderAlpha"]) ? $Format["BoxDownBorderAlpha"] : 100;
$ShadowOnBoxesOnly = isset($Format["ShadowOnBoxesOnly"]) ? $Format["ShadowOnBoxesOnly"] : true;
$MedianR = isset($Format["MedianR"]) ? $Format["MedianR"] : 255;
$MedianG = isset($Format["MedianG"]) ? $Format["MedianG"] : 0;
$MedianB = isset($Format["MedianB"]) ? $Format["MedianB"] : 0;
$MedianAlpha = isset($Format["MedianAlpha"]) ? $Format["MedianAlpha"] : 100;
$RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : false;
$ImageMapTitle = isset($Format["ImageMapTitle"]) ? $Format["ImageMapTitle"] : "Stock Chart";
/* Data Processing */
if ($BoxUpSurrounding != null) {
$BoxUpBorderR = $BoxUpR + $BoxUpSurrounding;
$BoxUpBorderG = $BoxUpG + $BoxUpSurrounding;
$BoxUpBorderB = $BoxUpB + $BoxUpSurrounding;
}
if ($BoxDownSurrounding != null) {
$BoxDownBorderR = $BoxDownR + $BoxDownSurrounding;
$BoxDownBorderG = $BoxDownG + $BoxDownSurrounding;
$BoxDownBorderB = $BoxDownB + $BoxDownSurrounding;
}
if ($LineWidth != 1) {
$LineOffset = $LineWidth / 2;
}
$BoxOffset = $BoxWidth / 2;
$Data = $this->pChartObject->DataSet->getData();
list($XMargin, $XDivs) = $this->pChartObject->scaleGetXSettings();
if (!isset($Data["Series"][$SerieOpen])
|| !isset($Data["Series"][$SerieClose])
|| !isset($Data["Series"][$SerieMin])
|| !isset($Data["Series"][$SerieMax])
) {
return STOCK_MISSING_SERIE;
}
$Plots = [];
foreach ($Data["Series"][$SerieOpen]["Data"] as $Key => $Value) {
$Point = [];
if (isset($Data["Series"][$SerieClose]["Data"][$Key])
|| isset($Data["Series"][$SerieMin]["Data"][$Key])
|| isset($Data["Series"][$SerieMax]["Data"][$Key])
) {
$Point = [
$Value,
$Data["Series"][$SerieClose]["Data"][$Key],
$Data["Series"][$SerieMin]["Data"][$Key],
$Data["Series"][$SerieMax]["Data"][$Key]
];
}
if ($SerieMedian != null && isset($Data["Series"][$SerieMedian]["Data"][$Key])) {
$Point[] = $Data["Series"][$SerieMedian]["Data"][$Key];
}
$Plots[] = $Point;
}
$AxisID = $Data["Series"][$SerieOpen]["Axis"];
$Format = $Data["Axis"][$AxisID]["Format"];
$YZero = $this->pChartObject->scaleComputeY(0, ["AxisID" => $AxisID]);
$XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs;
$X = $this->pChartObject->GraphAreaX1 + $XMargin;
$Y = $this->pChartObject->GraphAreaY1 + $XMargin;
$LineSettings = ["R" => $LineR, "G" => $LineG, "B" => $LineB, "Alpha" => $LineAlpha];
$ExtremitySettings = [
"R" => $ExtremityR,
"G" => $ExtremityG,
"B" => $ExtremityB,
"Alpha" => $ExtremityAlpha
];
$BoxUpSettings = [
"R" => $BoxUpR,
"G" => $BoxUpG,
"B" => $BoxUpB,
"Alpha" => $BoxUpAlpha,
"BorderR" => $BoxUpBorderR,
"BorderG" => $BoxUpBorderG,
"BorderB" => $BoxUpBorderB,
"BorderAlpha" => $BoxUpBorderAlpha
];
$BoxDownSettings = [
"R" => $BoxDownR,
"G" => $BoxDownG,
"B" => $BoxDownB,
"Alpha" => $BoxDownAlpha,
"BorderR" => $BoxDownBorderR,
"BorderG" => $BoxDownBorderG,
"BorderB" => $BoxDownBorderB,
"BorderAlpha" => $BoxDownBorderAlpha
];
$MedianSettings = ["R" => $MedianR, "G" => $MedianG, "B" => $MedianB, "Alpha" => $MedianAlpha];
foreach ($Plots as $Key => $Points) {
$PosArray = $this->pChartObject->scaleComputeY($Points, ["AxisID" => $AxisID]);
$Values = "Open :" . $Data["Series"][$SerieOpen]["Data"][$Key]
. "<BR>Close : " . $Data["Series"][$SerieClose]["Data"][$Key]
. "<BR>Min : " . $Data["Series"][$SerieMin]["Data"][$Key]
. "<BR>Max : " . $Data["Series"][$SerieMax]["Data"][$Key] . "<BR>";
if ($SerieMedian != null) {
$Values = $Values . "Median : " . $Data["Series"][$SerieMedian]["Data"][$Key] . "<BR>";
}
if ($PosArray[0] > $PosArray[1]) {
$ImageMapColor = $this->pChartObject->toHTMLColor($BoxUpR, $BoxUpG, $BoxUpB);
} else {
$ImageMapColor = $this->pChartObject->toHTMLColor($BoxDownR, $BoxDownG, $BoxDownB);
}
if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) {
if ($YZero > $this->pChartObject->GraphAreaY2 - 1) {
$YZero = $this->pChartObject->GraphAreaY2 - 1;
}
if ($YZero < $this->pChartObject->GraphAreaY1 + 1) {
$YZero = $this->pChartObject->GraphAreaY1 + 1;
}
if ($XDivs == 0) {
$XStep = 0;
} else {
$XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2)
/ $XDivs
;
}
if ($ShadowOnBoxesOnly) {
$RestoreShadow = $this->pChartObject->Shadow;
$this->pChartObject->Shadow = false;
}
if ($LineWidth == 1) {
$this->pChartObject->drawLine($X, $PosArray[2], $X, $PosArray[3], $LineSettings);
} else {
$this->pChartObject->drawFilledRectangle(
$X - $LineOffset,
$PosArray[2],
$X + $LineOffset,
$PosArray[3],
$LineSettings
);
}
if ($ExtremityWidth == 1) {
$this->pChartObject->drawLine(
$X - $ExtremityLength,
$PosArray[2],
$X + $ExtremityLength,
$PosArray[2],
$ExtremitySettings
);
$this->pChartObject->drawLine(
$X - $ExtremityLength,
$PosArray[3],
$X + $ExtremityLength,
$PosArray[3],
$ExtremitySettings
);
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"RECT",
sprintf(
"%s,%s,%s,%s",
floor($X - $ExtremityLength),
floor($PosArray[2]),
floor($X + $ExtremityLength),
floor($PosArray[3])
),
$ImageMapColor,
$ImageMapTitle,
$Values
);
}
} else {
$this->pChartObject->drawFilledRectangle(
$X - $ExtremityLength,
$PosArray[2],
$X + $ExtremityLength,
$PosArray[2] - $ExtremityWidth,
$ExtremitySettings
);
$this->pChartObject->drawFilledRectangle(
$X - $ExtremityLength,
$PosArray[3],
$X + $ExtremityLength,
$PosArray[3] + $ExtremityWidth,
$ExtremitySettings
);
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"RECT",
sprintf(
"%s,%s,%s,%s",
floor($X - $ExtremityLength),
floor($PosArray[2] - $ExtremityWidth),
floor($X + $ExtremityLength),
floor($PosArray[3] + $ExtremityWidth)
),
$ImageMapColor,
$ImageMapTitle,
$Values
);
}
}
if ($ShadowOnBoxesOnly) {
$this->pChartObject->Shadow = $RestoreShadow;
}
if ($PosArray[0] > $PosArray[1]) {
$this->pChartObject->drawFilledRectangle(
$X - $BoxOffset,
$PosArray[0],
$X + $BoxOffset,
$PosArray[1],
$BoxUpSettings
);
} else {
$this->pChartObject->drawFilledRectangle(
$X - $BoxOffset,
$PosArray[0],
$X + $BoxOffset,
$PosArray[1],
$BoxDownSettings
);
}
if (isset($PosArray[4])) {
$this->pChartObject->drawLine(
$X - $ExtremityLength,
$PosArray[4],
$X + $ExtremityLength,
$PosArray[4],
$MedianSettings
);
}
$X = $X + $XStep;
} elseif ($Data["Orientation"] == SCALE_POS_TOPBOTTOM) {
if ($YZero > $this->pChartObject->GraphAreaX2 - 1) {
$YZero = $this->pChartObject->GraphAreaX2 - 1;
}
if ($YZero < $this->pChartObject->GraphAreaX1 + 1) {
$YZero = $this->pChartObject->GraphAreaX1 + 1;
}
if ($XDivs == 0) {
$XStep = 0;
} else {
$XStep = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $XMargin * 2)
/ $XDivs
;
}
if ($LineWidth == 1) {
$this->pChartObject->drawLine($PosArray[2], $Y, $PosArray[3], $Y, $LineSettings);
} else {
$this->pChartObject->drawFilledRectangle(
$PosArray[2],
$Y - $LineOffset,
$PosArray[3],
$Y + $LineOffset,
$LineSettings
);
}
if ($ShadowOnBoxesOnly) {
$RestoreShadow = $this->pChartObject->Shadow;
$this->pChartObject->Shadow = false;
}
if ($ExtremityWidth == 1) {
$this->pChartObject->drawLine(
$PosArray[2],
$Y - $ExtremityLength,
$PosArray[2],
$Y + $ExtremityLength,
$ExtremitySettings
);
$this->pChartObject->drawLine(
$PosArray[3],
$Y - $ExtremityLength,
$PosArray[3],
$Y + $ExtremityLength,
$ExtremitySettings
);
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"RECT",
sprintf(
"%s,%s,%s,%s",
floor($PosArray[2]),
floor($Y - $ExtremityLength),
floor($PosArray[3]),
floor($Y + $ExtremityLength)
),
$ImageMapColor,
$ImageMapTitle,
$Values
);
}
} else {
$this->pChartObject->drawFilledRectangle(
$PosArray[2],
$Y - $ExtremityLength,
$PosArray[2] - $ExtremityWidth,
$Y + $ExtremityLength,
$ExtremitySettings
);
$this->pChartObject->drawFilledRectangle(
$PosArray[3],
$Y - $ExtremityLength,
$PosArray[3] + $ExtremityWidth,
$Y + $ExtremityLength,
$ExtremitySettings
);
if ($RecordImageMap) {
$this->pChartObject->addToImageMap(
"RECT",
sprintf(
"%s,%s,%s,%s",
floor($PosArray[2] - $ExtremityWidth),
floor($Y - $ExtremityLength),
floor($PosArray[3] + $ExtremityWidth),
floor($Y + $ExtremityLength)
),
$ImageMapColor,
$ImageMapTitle,
$Values
);
}
}
if ($ShadowOnBoxesOnly) {
$this->pChartObject->Shadow = $RestoreShadow;
}
if ($PosArray[0] < $PosArray[1]) {
$this->pChartObject->drawFilledRectangle(
$PosArray[0],
$Y - $BoxOffset,
$PosArray[1],
$Y + $BoxOffset,
$BoxUpSettings
);
} else {
$this->pChartObject->drawFilledRectangle(
$PosArray[0],
$Y - $BoxOffset,
$PosArray[1],
$Y + $BoxOffset,
$BoxDownSettings
);
}
if (isset($PosArray[4])) {
$this->pChartObject->drawLine(
$PosArray[4],
$Y - $ExtremityLength,
$PosArray[4],
$Y + $ExtremityLength,
$MedianSettings
);
}
$Y = $Y + $XStep;
}
}
}
}

View File

@@ -0,0 +1,414 @@
<?php
namespace CpChart\Chart;
use CpChart\Image;
/**
* Surface - class to draw surface 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.
*/
class Surface
{
/**
* @var Image
*/
public $pChartObject;
/**
* @var int
*/
public $GridSizeX;
/**
* @var int
*/
public $GridSizeY;
/**
* @var array
*/
public $Points = [];
/**
* @param Image $pChartObject
*/
public function __construct(Image $pChartObject)
{
$this->pChartObject = $pChartObject;
}
/**
* Define the grid size and initialise the 2D matrix
* @param int $XSize
* @param int $YSize
*/
public function setGrid($XSize = 10, $YSize = 10)
{
for ($X = 0; $X <= $XSize; $X++) {
for ($Y = 0; $Y <= $YSize; $Y++) {
$this->Points[$X][$Y] = UNKNOWN;
}
}
$this->GridSizeX = $XSize;
$this->GridSizeY = $YSize;
}
/**
* Add a point on the grid
* @param int $X
* @param int $Y
* @param int|float $Value
* @param boolean $Force
* @return null
*/
public function addPoint($X, $Y, $Value, $Force = true)
{
if ($X < 0 || $X > $this->GridSizeX) {
return 0;
}
if ($Y < 0 || $Y > $this->GridSizeY) {
return 0;
}
if ($this->Points[$X][$Y] == UNKNOWN || $Force) {
$this->Points[$X][$Y] = $Value;
} elseif ($this->Points[$X][$Y] == UNKNOWN) {
$this->Points[$X][$Y] = $Value;
} else {
$this->Points[$X][$Y] = ($this->Points[$X][$Y] + $Value) / 2;
}
}
/**
* Write the X labels
* @param array $Format
* @return null|int
*/
public function writeXLabels(array $Format = [])
{
$R = isset($Format["R"]) ? $Format["R"] : $this->pChartObject->FontColorR;
$G = isset($Format["G"]) ? $Format["G"] : $this->pChartObject->FontColorG;
$B = isset($Format["B"]) ? $Format["B"] : $this->pChartObject->FontColorB;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->pChartObject->FontColorA;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$Padding = isset($Format["Padding"]) ? $Format["Padding"] : 5;
$Position = isset($Format["Position"]) ? $Format["Position"] : LABEL_POSITION_TOP;
$Labels = isset($Format["Labels"]) ? $Format["Labels"] : null;
$CountOffset = isset($Format["CountOffset"]) ? $Format["CountOffset"] : 0;
if ($Labels != null && !is_array($Labels)) {
$Label = $Labels;
$Labels = [$Label];
}
$X0 = $this->pChartObject->GraphAreaX1;
$XSize = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) / ($this->GridSizeX + 1);
$Settings = ["Angle" => $Angle, "R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
if ($Position == LABEL_POSITION_TOP) {
$YPos = $this->pChartObject->GraphAreaY1 - $Padding;
if ($Angle == 0) {
$Settings["Align"] = TEXT_ALIGN_BOTTOMMIDDLE;
}
if ($Angle != 0) {
$Settings["Align"] = TEXT_ALIGN_MIDDLELEFT;
}
} elseif ($Position == LABEL_POSITION_BOTTOM) {
$YPos = $this->pChartObject->GraphAreaY2 + $Padding;
if ($Angle == 0) {
$Settings["Align"] = TEXT_ALIGN_TOPMIDDLE;
}
if ($Angle != 0) {
$Settings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
}
} else {
return -1;
}
for ($X = 0; $X <= $this->GridSizeX; $X++) {
$XPos = floor($X0 + $X * $XSize + $XSize / 2);
if ($Labels == null || !isset($Labels[$X])) {
$Value = $X + $CountOffset;
} else {
$Value = $Labels[$X];
}
$this->pChartObject->drawText($XPos, $YPos, $Value, $Settings);
}
}
/**
* Write the Y labels
* @param array $Format
* @return type
*/
public function writeYLabels(array $Format = [])
{
$R = isset($Format["R"]) ? $Format["R"] : $this->pChartObject->FontColorR;
$G = isset($Format["G"]) ? $Format["G"] : $this->pChartObject->FontColorG;
$B = isset($Format["B"]) ? $Format["B"] : $this->pChartObject->FontColorB;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->pChartObject->FontColorA;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$Padding = isset($Format["Padding"]) ? $Format["Padding"] : 5;
$Position = isset($Format["Position"]) ? $Format["Position"] : LABEL_POSITION_LEFT;
$Labels = isset($Format["Labels"]) ? $Format["Labels"] : null;
$CountOffset = isset($Format["CountOffset"]) ? $Format["CountOffset"] : 0;
if ($Labels != null && !is_array($Labels)) {
$Label = $Labels;
$Labels = [$Label];
}
$Y0 = $this->pChartObject->GraphAreaY1;
$YSize = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) / ($this->GridSizeY + 1);
$Settings = ["Angle" => $Angle, "R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
if ($Position == LABEL_POSITION_LEFT) {
$XPos = $this->pChartObject->GraphAreaX1 - $Padding;
$Settings["Align"] = TEXT_ALIGN_MIDDLERIGHT;
} elseif ($Position == LABEL_POSITION_RIGHT) {
$XPos = $this->pChartObject->GraphAreaX2 + $Padding;
$Settings["Align"] = TEXT_ALIGN_MIDDLELEFT;
} else {
return -1;
}
for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
$YPos = floor($Y0 + $Y * $YSize + $YSize / 2);
if ($Labels == null || !isset($Labels[$Y])) {
$Value = $Y + $CountOffset;
} else {
$Value = $Labels[$Y];
}
$this->pChartObject->drawText($XPos, $YPos, $Value, $Settings);
}
}
/**
* Draw the area arround the specified Threshold
* @param int|float $Threshold
* @param array $Format
*/
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);
}
}
}
}
}
/**
* Draw the surface chart
* @param array $Format
*/
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);
}
}
}
}
/**
* Compute the missing points
*/
public function computeMissing()
{
$Missing = [];
for ($X = 0; $X <= $this->GridSizeX; $X++) {
for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
if ($this->Points[$X][$Y] == UNKNOWN) {
$Missing[] = $X . "," . $Y;
}
}
}
shuffle($Missing);
foreach ($Missing as $Pos) {
$Pos = preg_split("/,/", $Pos);
$X = $Pos[0];
$Y = $Pos[1];
if ($this->Points[$X][$Y] == UNKNOWN) {
$NearestNeighbor = $this->getNearestNeighbor($X, $Y);
$Value = 0;
$Points = 0;
for ($Xi = $X - $NearestNeighbor; $Xi <= $X + $NearestNeighbor; $Xi++) {
for ($Yi = $Y - $NearestNeighbor; $Yi <= $Y + $NearestNeighbor; $Yi++) {
if ($Xi >= 0
&& $Yi >= 0
&& $Xi <= $this->GridSizeX
&& $Yi <= $this->GridSizeY
&& $this->Points[$Xi][$Yi] != UNKNOWN
&& $this->Points[$Xi][$Yi] != IGNORED
) {
$Value = $Value + $this->Points[$Xi][$Yi];
$Points++;
}
}
}
if ($Points != 0) {
$this->Points[$X][$Y] = $Value / $Points;
}
}
}
}
/**
* Return the nearest Neighbor distance of a point
* @param int $Xp
* @param int $Yp
* @return int
*/
public function getNearestNeighbor($Xp, $Yp)
{
$Nearest = UNKNOWN;
for ($X = 0; $X <= $this->GridSizeX; $X++) {
for ($Y = 0; $Y <= $this->GridSizeY; $Y++) {
if ($this->Points[$X][$Y] != UNKNOWN && $this->Points[$X][$Y] != IGNORED) {
$DistanceX = max($Xp, $X) - min($Xp, $X);
$DistanceY = max($Yp, $Y) - min($Yp, $Y);
$Distance = max($DistanceX, $DistanceY);
if ($Distance < $Nearest || $Nearest == UNKNOWN) {
$Nearest = $Distance;
}
}
}
}
return $Nearest;
}
}