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,274 @@
<?php
namespace CpChart\Barcode;
use CpChart\Image;
use Exception;
/**
* pBarcode128 - class to create barcodes (128B)
*
* 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 Barcode128
{
/**
* @var array
*/
public $Codes;
/**
* @var array
*/
public $Reverse;
/**
* @var string
*/
public $Result;
/**
* @var Image
*/
public $pChartObject;
/**
* @var integer
*/
public $CRC;
/**
* @param string $filePath
* @throws Exception
*/
public function __construct($filePath = '')
{
$this->Codes = [];
$this->Reverse = [];
if (!file_exists($filePath)) {
$filePath = sprintf('%s/../../resources/barcode/128B.db', __DIR__);
}
$FileHandle = @fopen($filePath, "r");
if (!$FileHandle) {
throw new Exception(
sprintf("Cannot find barcode database (%s).", $filePath)
);
}
while (!feof($FileHandle)) {
$Buffer = fgets($FileHandle, 4096);
$Buffer = str_replace(chr(10), "", $Buffer);
$Buffer = str_replace(chr(13), "", $Buffer);
$Values = preg_split("/;/", $Buffer);
$this->Codes[$Values[1]]["ID"] = $Values[0];
$this->Codes[$Values[1]]["Code"] = $Values[2];
$this->Reverse[$Values[0]]["Code"] = $Values[2];
$this->Reverse[$Values[0]]["Asc"] = $Values[1];
}
fclose($FileHandle);
}
/**
* Return the projected size of a barcode
*
* @param string $TextString
* @param string $Format
* @return array
*/
public function getSize($TextString, $Format = "")
{
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : false;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : false;
$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : 12;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$TextString = $this->encode128($TextString);
$BarcodeLength = strlen($this->Result);
$WOffset = $DrawArea ? 20 : 0;
$HOffset = $ShowLegend ? $FontSize + $LegendOffset + $WOffset : 0;
$X1 = cos($Angle * PI / 180) * ($WOffset + $BarcodeLength);
$Y1 = sin($Angle * PI / 180) * ($WOffset + $BarcodeLength);
$X2 = $X1 + cos(($Angle + 90) * PI / 180) * ($HOffset + $Height);
$Y2 = $Y1 + sin(($Angle + 90) * PI / 180) * ($HOffset + $Height);
$AreaWidth = max(abs($X1), abs($X2));
$AreaHeight = max(abs($Y1), abs($Y2));
return ["Width" => $AreaWidth, "Height" => $AreaHeight];
}
/**
*
* @param string $Value
* @param string $Format
* @return string
*/
public function encode128($Value, $Format = "")
{
$this->Result = "11010010000";
$this->CRC = 104;
$TextString = "";
for ($i = 1; $i <= strlen($Value); $i++) {
$CharCode = ord($this->mid($Value, $i, 1));
if (isset($this->Codes[$CharCode])) {
$this->Result = $this->Result . $this->Codes[$CharCode]["Code"];
$this->CRC = $this->CRC + $i * $this->Codes[$CharCode]["ID"];
$TextString = $TextString . chr($CharCode);
}
}
$this->CRC = $this->CRC - floor($this->CRC / 103) * 103;
$this->Result = $this->Result . $this->Reverse[$this->CRC]["Code"];
$this->Result = $this->Result . "1100011101011";
return $TextString;
}
/**
* Create the encoded string
* @param Image $Object
* @param string $Value
* @param int $X
* @param int $Y
* @param array $Format
*/
public function draw(Image $Object, $Value, $X, $Y, $Format = [])
{
$this->pChartObject = $Object;
$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;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : false;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : false;
$AreaR = isset($Format["AreaR"]) ? $Format["AreaR"] : 255;
$AreaG = isset($Format["AreaG"]) ? $Format["AreaG"] : 255;
$AreaB = isset($Format["AreaB"]) ? $Format["AreaB"] : 255;
$AreaBorderR = isset($Format["AreaBorderR"]) ? $Format["AreaBorderR"] : $AreaR;
$AreaBorderG = isset($Format["AreaBorderG"]) ? $Format["AreaBorderG"] : $AreaG;
$AreaBorderB = isset($Format["AreaBorderB"]) ? $Format["AreaBorderB"] : $AreaB;
$TextString = $this->encode128($Value);
if ($DrawArea) {
$X1 = $X + cos(($Angle - 135) * PI / 180) * 10;
$Y1 = $Y + sin(($Angle - 135) * PI / 180) * 10;
$X2 = $X1 + cos($Angle * PI / 180) * (strlen($this->Result) + 20);
$Y2 = $Y1 + sin($Angle * PI / 180) * (strlen($this->Result) + 20);
if ($ShowLegend) {
$X3 = $X2
+ cos(($Angle + 90) * PI / 180)
* ($Height + $LegendOffset + $this->pChartObject->FontSize + 10)
;
$Y3 = $Y2
+ sin(($Angle + 90) * PI / 180)
* ($Height + $LegendOffset + $this->pChartObject->FontSize + 10)
;
} else {
$X3 = $X2 + cos(($Angle + 90) * PI / 180) * ($Height + 20);
$Y3 = $Y2 + sin(($Angle + 90) * PI / 180) * ($Height + 20);
}
$X4 = $X3 + cos(($Angle + 180) * PI / 180) * (strlen($this->Result) + 20);
$Y4 = $Y3 + sin(($Angle + 180) * PI / 180) * (strlen($this->Result) + 20);
$Polygon = [$X1, $Y1, $X2, $Y2, $X3, $Y3, $X4, $Y4];
$Settings = [
"R" => $AreaR,
"G" => $AreaG,
"B" => $AreaB,
"BorderR" => $AreaBorderR,
"BorderG" => $AreaBorderG,
"BorderB" => $AreaBorderB
];
$this->pChartObject->drawPolygon($Polygon, $Settings);
}
for ($i = 1; $i <= strlen($this->Result); $i++) {
if ($this->mid($this->Result, $i, 1) == 1) {
$X1 = $X + cos($Angle * PI / 180) * $i;
$Y1 = $Y + sin($Angle * PI / 180) * $i;
$X2 = $X1 + cos(($Angle + 90) * PI / 180) * $Height;
$Y2 = $Y1 + sin(($Angle + 90) * PI / 180) * $Height;
$Settings = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
$this->pChartObject->drawLine($X1, $Y1, $X2, $Y2, $Settings);
}
}
if ($ShowLegend) {
$X1 = $X + cos($Angle * PI / 180) * (strlen($this->Result) / 2);
$Y1 = $Y + sin($Angle * PI / 180) * (strlen($this->Result) / 2);
$LegendX = $X1 + cos(($Angle + 90) * PI / 180) * ($Height + $LegendOffset);
$LegendY = $Y1 + sin(($Angle + 90) * PI / 180) * ($Height + $LegendOffset);
$Settings = [
"R" => $R,
"G" => $G,
"B" => $B,
"Alpha" => $Alpha,
"Angle" => -$Angle,
"Align" => TEXT_ALIGN_TOPMIDDLE
];
$this->pChartObject->drawText($LegendX, $LegendY, $TextString, $Settings);
}
}
/**
*
* @param string $value
* @param int $NbChar
* @return string
*/
public function left($value, $NbChar)
{
return substr($value, 0, $NbChar);
}
/**
*
* @param string $value
* @param int $NbChar
* @return string
*/
public function right($value, $NbChar)
{
return substr($value, strlen($value) - $NbChar, $NbChar);
}
/**
*
* @param string $value
* @param int $Depart
* @param int $NbChar
* @return string
*/
public function mid($value, $Depart, $NbChar)
{
return substr($value, $Depart - 1, $NbChar);
}
}

View File

@@ -0,0 +1,296 @@
<?php
namespace CpChart\Barcode;
use CpChart\Image;
use Exception;
/**
* pBarcode39 - class to create barcodes (39B)
*
* 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 Barcode39
{
/**
* @var array
*/
public $Codes;
/**
* @var array
*/
public $Reverse;
/**
* @var string
*/
public $Result;
/**
* @var Image
*/
public $pChartObject;
/**
* @var integer
*/
public $CRC;
/**
* @var boolean
*/
public $MOD43;
/**
* @param string $filePath
* @param boolean $EnableMOD43
* @throws Exception
*/
public function __construct($filePath = "", $EnableMOD43 = false)
{
$this->MOD43 = (boolean) $EnableMOD43;
$this->Codes = [];
$this->Reverse = [];
if (!file_exists($filePath)) {
$filePath = sprintf('%s/../../resources/barcode/39.db', __DIR__);
}
$FileHandle = @fopen($filePath, "r");
if (!$FileHandle) {
throw new Exception(
"Cannot find barcode database (" . $filePath . ")."
);
}
while (!feof($FileHandle)) {
$Buffer = fgets($FileHandle, 4096);
$Buffer = str_replace(chr(10), "", $Buffer);
$Buffer = str_replace(chr(13), "", $Buffer);
$Values = preg_split("/;/", $Buffer);
$this->Codes[$Values[0]] = $Values[1];
}
fclose($FileHandle);
}
/**
* Return the projected size of a barcode
*
* @param string $TextString
* @param string $Format
* @return array
*/
public function getSize($TextString, $Format = "")
{
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : false;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : false;
$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : 12;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$TextString = $this->encode39($TextString);
$BarcodeLength = strlen($this->Result);
$WOffset = $DrawArea ? 20 : 0;
$HOffset = $ShowLegend ? $FontSize + $LegendOffset + $WOffset : 0;
$X1 = cos($Angle * PI / 180) * ($WOffset + $BarcodeLength);
$Y1 = sin($Angle * PI / 180) * ($WOffset + $BarcodeLength);
$X2 = $X1 + cos(($Angle + 90) * PI / 180) * ($HOffset + $Height);
$Y2 = $Y1 + sin(($Angle + 90) * PI / 180) * ($HOffset + $Height);
$AreaWidth = max(abs($X1), abs($X2));
$AreaHeight = max(abs($Y1), abs($Y2));
return ["Width" => $AreaWidth, "Height" => $AreaHeight];
}
/**
* Create the encoded string
*
* @param string $Value
* @return string
*/
public function encode39($Value)
{
$this->Result = "100101101101" . "0";
$TextString = "";
for ($i = 1; $i <= strlen($Value); $i++) {
$CharCode = ord($this->mid($Value, $i, 1));
if ($CharCode >= 97 && $CharCode <= 122) {
$CharCode = $CharCode - 32;
}
if (isset($this->Codes[chr($CharCode)])) {
$this->Result = $this->Result . $this->Codes[chr($CharCode)] . "0";
$TextString = $TextString . chr($CharCode);
}
}
if ($this->MOD43) {
$Checksum = $this->checksum($TextString);
$this->Result = $this->Result . $this->Codes[$Checksum] . "0";
}
$this->Result = $this->Result . "100101101101";
$TextString = "*" . $TextString . "*";
return $TextString;
}
/**
* Create the encoded string
* @param Image $Object
* @param type $Value
* @param type $X
* @param type $Y
* @param array $Format
*/
public function draw(Image $Object, $Value, $X, $Y, $Format = [])
{
$this->pChartObject = $Object;
$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;
$Height = isset($Format["Height"]) ? $Format["Height"] : 30;
$Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
$ShowLegend = isset($Format["ShowLegend"]) ? $Format["ShowLegend"] : false;
$LegendOffset = isset($Format["LegendOffset"]) ? $Format["LegendOffset"] : 5;
$DrawArea = isset($Format["DrawArea"]) ? $Format["DrawArea"] : false;
$AreaR = isset($Format["AreaR"]) ? $Format["AreaR"] : 255;
$AreaG = isset($Format["AreaG"]) ? $Format["AreaG"] : 255;
$AreaB = isset($Format["AreaB"]) ? $Format["AreaB"] : 255;
$AreaBorderR = isset($Format["AreaBorderR"]) ? $Format["AreaBorderR"] : $AreaR;
$AreaBorderG = isset($Format["AreaBorderG"]) ? $Format["AreaBorderG"] : $AreaG;
$AreaBorderB = isset($Format["AreaBorderB"]) ? $Format["AreaBorderB"] : $AreaB;
$TextString = $this->encode39($Value);
if ($DrawArea) {
$X1 = $X + cos(($Angle - 135) * PI / 180) * 10;
$Y1 = $Y + sin(($Angle - 135) * PI / 180) * 10;
$X2 = $X1 + cos($Angle * PI / 180) * (strlen($this->Result) + 20);
$Y2 = $Y1 + sin($Angle * PI / 180) * (strlen($this->Result) + 20);
if ($ShowLegend) {
$X3 = $X2
+ cos(($Angle + 90) * PI / 180)
* ($Height + $LegendOffset + $this->pChartObject->FontSize + 10)
;
$Y3 = $Y2
+ sin(($Angle + 90) * PI / 180)
* ($Height + $LegendOffset + $this->pChartObject->FontSize + 10)
;
} else {
$X3 = $X2 + cos(($Angle + 90) * PI / 180) * ($Height + 20);
$Y3 = $Y2 + sin(($Angle + 90) * PI / 180) * ($Height + 20);
}
$X4 = $X3 + cos(($Angle + 180) * PI / 180) * (strlen($this->Result) + 20);
$Y4 = $Y3 + sin(($Angle + 180) * PI / 180) * (strlen($this->Result) + 20);
$Polygon = [$X1, $Y1, $X2, $Y2, $X3, $Y3, $X4, $Y4];
$Settings = [
"R" => $AreaR,
"G" => $AreaG,
"B" => $AreaB,
"BorderR" => $AreaBorderR,
"BorderG" => $AreaBorderG,
"BorderB" => $AreaBorderB
];
$this->pChartObject->drawPolygon($Polygon, $Settings);
}
for ($i = 1; $i <= strlen($this->Result); $i++) {
if ($this->mid($this->Result, $i, 1) == 1) {
$X1 = $X + cos($Angle * PI / 180) * $i;
$Y1 = $Y + sin($Angle * PI / 180) * $i;
$X2 = $X1 + cos(($Angle + 90) * PI / 180) * $Height;
$Y2 = $Y1 + sin(($Angle + 90) * PI / 180) * $Height;
$Settings = ["R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha];
$this->pChartObject->drawLine($X1, $Y1, $X2, $Y2, $Settings);
}
}
if ($ShowLegend) {
$X1 = $X + cos($Angle * PI / 180) * (strlen($this->Result) / 2);
$Y1 = $Y + sin($Angle * PI / 180) * (strlen($this->Result) / 2);
$LegendX = $X1 + cos(($Angle + 90) * PI / 180) * ($Height + $LegendOffset);
$LegendY = $Y1 + sin(($Angle + 90) * PI / 180) * ($Height + $LegendOffset);
$Settings = [
"R" => $R,
"G" => $G,
"B" => $B,
"Alpha" => $Alpha,
"Angle" => -$Angle,
"Align" => TEXT_ALIGN_TOPMIDDLE
];
$this->pChartObject->drawText($LegendX, $LegendY, $TextString, $Settings);
}
}
/**
* @param string $string
* @return string
*/
public function checksum($string)
{
$checksum = 0;
$length = strlen($string);
$charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%';
for ($i = 0; $i < $length; ++$i) {
$checksum += strpos($charset, $string[$i]);
}
return substr($charset, ($checksum % 43), 1);
}
/**
* @param string $value
* @param int $NbChar
* @return string
*/
public function left($value, $NbChar)
{
return substr($value, 0, $NbChar);
}
/**
* @param string $value
* @param int $NbChar
* @return string|false
*/
public function right($value, $NbChar)
{
return substr($value, strlen($value) - $NbChar, $NbChar);
}
/**
* @param string $value
* @param int $Depart
* @param int $NbChar
* @return string
*/
public function mid($value, $Depart, $NbChar)
{
return substr($value, $Depart - 1, $NbChar);
}
}

1728
vendor/szymach/c-pchart/src/BaseDraw.php vendored Normal file

File diff suppressed because it is too large Load Diff

392
vendor/szymach/c-pchart/src/Cache.php vendored Normal file
View File

@@ -0,0 +1,392 @@
<?php
namespace CpChart;
/**
* Cache - speed up the rendering by caching up the pictures
*
* 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 Cache
{
/**
* @var string
*/
public $CacheFolder;
/**
* @var string
*/
public $CacheIndex;
/**
* @var string
*/
public $CacheDB;
/**
* @param array $Settings
*/
public function __construct(array $Settings = [])
{
$CacheFolder = isset($Settings["CacheFolder"]) ? $Settings["CacheFolder"] : __DIR__ . "/../cache";
$CacheIndex = isset($Settings["CacheIndex"]) ? $Settings["CacheIndex"] : "index.db";
$CacheDB = isset($Settings["CacheDB"]) ? $Settings["CacheDB"] : "cache.db";
$this->CacheFolder = $CacheFolder;
$this->CacheIndex = $CacheIndex;
$this->CacheDB = $CacheDB;
if (!file_exists($this->CacheFolder . "/" . $this->CacheIndex)) {
touch($this->CacheFolder . "/" . $this->CacheIndex);
}
if (!file_exists($this->CacheFolder . "/" . $this->CacheDB)) {
touch($this->CacheFolder . "/" . $this->CacheDB);
}
}
/**
* Flush the cache contents
*/
public function flush()
{
if (file_exists($this->CacheFolder . "/" . $this->CacheIndex)) {
unlink($this->CacheFolder . "/" . $this->CacheIndex);
touch($this->CacheFolder . "/" . $this->CacheIndex);
}
if (file_exists($this->CacheFolder . "/" . $this->CacheDB)) {
unlink($this->CacheFolder . "/" . $this->CacheDB);
touch($this->CacheFolder . "/" . $this->CacheDB);
}
}
/**
* Return the MD5 of the data array to clearly identify the chart
*
* @param Data $Data
* @param string $Marker
* @return string
*/
public function getHash(Data $Data, $Marker = "")
{
return md5($Marker . serialize($Data->Data));
}
/**
* Write the generated picture to the cache
*
* @param string $ID
* @param Image $pChartObject
*/
public function writeToCache($ID, Image $pChartObject)
{
/* Compute the paths */
$TemporaryFile = tempnam($this->CacheFolder, "tmp_");
$Database = $this->CacheFolder . "/" . $this->CacheDB;
$Index = $this->CacheFolder . "/" . $this->CacheIndex;
/* Flush the picture to a temporary file */
imagepng($pChartObject->Picture, $TemporaryFile);
/* Retrieve the files size */
$PictureSize = filesize($TemporaryFile);
$DBSize = filesize($Database);
/* Save the index */
$Handle = fopen($Index, "a");
fwrite($Handle, $ID . "," . $DBSize . "," . $PictureSize . "," . time() . ",0\r\n");
fclose($Handle);
/* Get the picture raw contents */
$Handle = fopen($TemporaryFile, "r");
$Raw = fread($Handle, $PictureSize);
fclose($Handle);
/* Save the picture in the solid database file */
$Handle = fopen($Database, "a");
fwrite($Handle, $Raw);
fclose($Handle);
/* Remove temporary file */
unlink($TemporaryFile);
}
/**
* Remove object older than the specified TS
* @param int $Expiry
*/
public function removeOlderThan($Expiry)
{
$this->dbRemoval(["Expiry" => $Expiry]);
}
/**
* Remove an object from the cache
* @param string $ID
*/
public function remove($ID)
{
$this->dbRemoval(["Name" => $ID]);
}
/**
* Remove with specified criterias.
*
* @param array $Settings
* @return int
*/
public function dbRemoval(array $Settings)
{
$ID = isset($Settings["Name"]) ? $Settings["Name"] : null;
$Expiry = isset($Settings["Expiry"]) ? $Settings["Expiry"] : -(24 * 60 * 60);
$TS = time() - $Expiry;
/* Compute the paths */
$Database = $this->CacheFolder . "/" . $this->CacheDB;
$Index = $this->CacheFolder . "/" . $this->CacheIndex;
$DatabaseTemp = $this->CacheFolder . "/" . $this->CacheDB . ".tmp";
$IndexTemp = $this->CacheFolder . "/" . $this->CacheIndex . ".tmp";
/* Single file removal */
if ($ID != null) {
/* Retrieve object informations */
$Object = $this->isInCache($ID, true);
/* If it's not in the cache DB, go away */
if (!$Object) {
return(0);
}
}
/* Create the temporary files */
if (!file_exists($DatabaseTemp)) {
touch($DatabaseTemp);
}
if (!file_exists($IndexTemp)) {
touch($IndexTemp);
}
/* Open the file handles */
$IndexHandle = @fopen($Index, "r");
$IndexTempHandle = @fopen($IndexTemp, "w");
$DBHandle = @fopen($Database, "r");
$DBTempHandle = @fopen($DatabaseTemp, "w");
/* Remove the selected ID from the database */
while (!feof($IndexHandle)) {
$Entry = fgets($IndexHandle, 4096);
$Entry = str_replace("\r", "", $Entry);
$Entry = str_replace("\n", "", $Entry);
$Settings = preg_split("/,/", $Entry);
if ($Entry != "") {
$PicID = $Settings[0];
$DBPos = $Settings[1];
$PicSize = $Settings[2];
$GeneratedTS = $Settings[3];
$Hits = $Settings[4];
if ($Settings[0] != $ID && $GeneratedTS > $TS) {
$CurrentPos = ftell($DBTempHandle);
fwrite(
$IndexTempHandle,
sprintf(
"%s,%s,%s,%s,%s\r\n",
$PicID,
$CurrentPos,
$PicSize,
$GeneratedTS,
$Hits
)
);
fseek($DBHandle, $DBPos);
$Picture = fread($DBHandle, $PicSize);
fwrite($DBTempHandle, $Picture);
}
}
}
/* Close the handles */
fclose($IndexHandle);
fclose($IndexTempHandle);
fclose($DBHandle);
fclose($DBTempHandle);
/* Remove the prod files */
unlink($Database);
unlink($Index);
/* Swap the temp & prod DB */
rename($DatabaseTemp, $Database);
rename($IndexTemp, $Index);
}
/**
* Is the file in cache?
*
* @param string $ID
* @param boolean $Verbose
* @param boolean $UpdateHitsCount
* @return boolean
*/
public function isInCache($ID, $Verbose = false, $UpdateHitsCount = false)
{
/* Compute the paths */
$Index = $this->CacheFolder . "/" . $this->CacheIndex;
/* Search the picture in the index file */
$Handle = @fopen($Index, "r");
while (!feof($Handle)) {
$IndexPos = ftell($Handle);
$Entry = fgets($Handle, 4096);
if ($Entry != "") {
$Settings = preg_split("/,/", $Entry);
$PicID = $Settings[0];
if ($PicID == $ID) {
fclose($Handle);
$DBPos = $Settings[1];
$PicSize = $Settings[2];
$GeneratedTS = $Settings[3];
$Hits = intval($Settings[4]);
if ($UpdateHitsCount) {
$Hits++;
if (strlen($Hits) < 7) {
$Hits = $Hits . str_repeat(" ", 7 - strlen($Hits));
}
$Handle = @fopen($Index, "r+");
fseek($Handle, $IndexPos);
fwrite(
$Handle,
sprintf(
"%s,%s,%s,%s,%s\r\n",
$PicID,
$DBPos,
$PicSize,
$GeneratedTS,
$Hits
)
);
fclose($Handle);
}
if ($Verbose) {
return [
"DBPos" => $DBPos,
"PicSize" => $PicSize,
"GeneratedTS" => $GeneratedTS,
"Hits" => $Hits
];
} else {
return true;
}
}
}
}
fclose($Handle);
/* Picture isn't in the cache */
return false;
}
/**
* Automatic output method based on the calling interface
* @param string $ID
* @param string $Destination
*/
public function autoOutput($ID, $Destination = "output.png")
{
if (php_sapi_name() == "cli") {
$this->saveFromCache($ID, $Destination);
} else {
$this->strokeFromCache($ID);
}
}
/**
* Show image from cache
* @param string $ID
* @return boolean
*/
public function strokeFromCache($ID)
{
/* Get the raw picture from the cache */
$Picture = $this->getFromCache($ID);
/* Do we have a hit? */
if ($Picture == null) {
return false;
}
header('Content-type: image/png');
echo $Picture;
return true;
}
/**
* Save file from cache.
* @param string $ID
* @param string $Destination
* @return boolean
*/
public function saveFromCache($ID, $Destination)
{
/* Get the raw picture from the cache */
$Picture = $this->getFromCache($ID);
/* Do we have a hit? */
if ($Picture == null) {
return false;
}
/* Flush the picture to a file */
$Handle = fopen($Destination, "w");
fwrite($Handle, $Picture);
fclose($Handle);
/* All went fine */
return true;
}
/**
* Get file from cache
* @param string $ID
* @return string|null
*/
public function getFromCache($ID)
{
/* Compute the path */
$Database = $this->CacheFolder . "/" . $this->CacheDB;
/* Lookup for the picture in the cache */
$CacheInfo = $this->isInCache($ID, true, true);
/* Not in the cache */
if (!$CacheInfo) {
return null;
}
/* Get the database extended information */
$DBPos = $CacheInfo["DBPos"];
$PicSize = $CacheInfo["PicSize"];
/* Extract the picture from the solid cache file */
$Handle = @fopen($Database, "r");
fseek($Handle, $DBPos);
$Picture = fread($Handle, $PicSize);
fclose($Handle);
/* Return back the raw picture data */
return $Picture;
}
}

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;
}
}

1318
vendor/szymach/c-pchart/src/Data.php vendored Normal file

File diff suppressed because it is too large Load Diff

10363
vendor/szymach/c-pchart/src/Draw.php vendored Normal file

File diff suppressed because it is too large Load Diff

748
vendor/szymach/c-pchart/src/Image.php vendored Normal file
View File

@@ -0,0 +1,748 @@
<?php
namespace CpChart;
/**
* Image - The actual class to do most of the drawing. Extends the Draw class
* with the bulk of drawing methods.
*
* 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 Image extends Draw
{
/**
* @param int $XSize
* @param int $YSize
* @param Data $DataSet
* @param boolean $TransparentBackground
*/
public function __construct(
$XSize,
$YSize,
Data $DataSet = null,
$TransparentBackground = false
) {
parent::__construct();
$this->TransparentBackground = $TransparentBackground;
$this->DataSet = null !== $DataSet ? $DataSet : new Data();
$this->XSize = $XSize;
$this->YSize = $YSize;
$this->Picture = imagecreatetruecolor($XSize, $YSize);
if ($this->TransparentBackground) {
imagealphablending($this->Picture, false);
imagefilledrectangle(
$this->Picture,
0,
0,
$XSize,
$YSize,
imagecolorallocatealpha($this->Picture, 255, 255, 255, 127)
);
imagealphablending($this->Picture, true);
imagesavealpha($this->Picture, true);
} else {
$C_White = $this->AllocateColor($this->Picture, 255, 255, 255);
imagefilledrectangle($this->Picture, 0, 0, $XSize, $YSize, $C_White);
}
}
/**
* Enable / Disable and set shadow properties
* @param boolean $Enabled
* @param array $Format
*/
public function setShadow($Enabled = true, array $Format = [])
{
$X = isset($Format["X"]) ? $Format["X"] : 2;
$Y = isset($Format["Y"]) ? $Format["Y"] : 2;
$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"] : 10;
$this->Shadow = $Enabled;
$this->ShadowX = $X;
$this->ShadowY = $Y;
$this->ShadowR = $R;
$this->ShadowG = $G;
$this->ShadowB = $B;
$this->Shadowa = $Alpha;
}
/**
* Set the graph area position
* @param int $X1
* @param int $Y1
* @param int $X2
* @param int $Y2
* @return int|null
*/
public function setGraphArea($X1, $Y1, $X2, $Y2)
{
if ($X2 < $X1 || $X1 == $X2 || $Y2 < $Y1 || $Y1 == $Y2) {
return -1;
}
$this->GraphAreaX1 = $X1;
$this->DataSet->Data["GraphArea"]["X1"] = $X1;
$this->GraphAreaY1 = $Y1;
$this->DataSet->Data["GraphArea"]["Y1"] = $Y1;
$this->GraphAreaX2 = $X2;
$this->DataSet->Data["GraphArea"]["X2"] = $X2;
$this->GraphAreaY2 = $Y2;
$this->DataSet->Data["GraphArea"]["Y2"] = $Y2;
}
/**
* Return the width of the picture
* @return int
*/
public function getWidth()
{
return $this->XSize;
}
/**
* Return the heigth of the picture
* @return int
*/
public function getHeight()
{
return $this->YSize;
}
/**
* Render the picture to a file
* @param string $FileName
*/
public function render($FileName)
{
if ($this->TransparentBackground) {
imagealphablending($this->Picture, false);
imagesavealpha($this->Picture, true);
}
imagepng($this->Picture, $FileName);
}
public function __toString()
{
if ($this->TransparentBackground) {
imagealphablending($this->Picture, false);
imagesavealpha($this->Picture, true);
}
ob_start();
imagepng($this->Picture);
return ob_get_clean();
}
public function toDataURI()
{
return 'data:image/png;base64,' . base64_encode($this->__toString());
}
/**
* Render the picture to a web browser stream
* @param boolean $BrowserExpire
*/
public function stroke($BrowserExpire = false)
{
if ($this->TransparentBackground) {
imagealphablending($this->Picture, false);
imagesavealpha($this->Picture, true);
}
if ($BrowserExpire) {
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache");
header("Pragma: no-cache");
}
header('Content-type: image/png');
imagepng($this->Picture);
}
/**
* Automatic output method based on the calling interface
* @param string $FileName
*/
public function autoOutput($FileName = "output.png")
{
if (php_sapi_name() == "cli") {
$this->Render($FileName);
} else {
$this->Stroke();
}
}
/**
* Return the length between two points
* @param int $X1
* @param int $Y1
* @param int $X2
* @param int $Y2
* @return float
*/
public function getLength($X1, $Y1, $X2, $Y2)
{
return sqrt(
pow(max($X1, $X2) - min($X1, $X2), 2) + pow(max($Y1, $Y2) - min($Y1, $Y2), 2)
);
}
/**
* Return the orientation of a line
* @param int $X1
* @param int $Y1
* @param int $X2
* @param int $Y2
* @return int
*/
public function getAngle($X1, $Y1, $X2, $Y2)
{
$Opposite = $Y2 - $Y1;
$Adjacent = $X2 - $X1;
$Angle = rad2deg(atan2($Opposite, $Adjacent));
if ($Angle > 0) {
return $Angle;
} else {
return 360 - abs($Angle);
}
}
/**
* Return the surrounding box of text area
* @param int $X
* @param int $Y
* @param string $FontName
* @param int $FontSize
* @param int $Angle
* @param int $Text
* @return array
*/
public function getTextBox($X, $Y, $FontName, $FontSize, $Angle, $Text)
{
$coords = imagettfbbox($FontSize, 0, $this->loadFont($FontName, 'fonts'), $Text);
$a = deg2rad($Angle);
$ca = cos($a);
$sa = sin($a);
$RealPos = [];
for ($i = 0; $i < 7; $i += 2) {
$RealPos[$i / 2]["X"] = $X + round($coords[$i] * $ca + $coords[$i + 1] * $sa);
$RealPos[$i / 2]["Y"] = $Y + round($coords[$i + 1] * $ca - $coords[$i] * $sa);
}
$RealPos[TEXT_ALIGN_BOTTOMLEFT]["X"] = $RealPos[0]["X"];
$RealPos[TEXT_ALIGN_BOTTOMLEFT]["Y"] = $RealPos[0]["Y"];
$RealPos[TEXT_ALIGN_BOTTOMRIGHT]["X"] = $RealPos[1]["X"];
$RealPos[TEXT_ALIGN_BOTTOMRIGHT]["Y"] = $RealPos[1]["Y"];
$RealPos[TEXT_ALIGN_TOPLEFT]["X"] = $RealPos[3]["X"];
$RealPos[TEXT_ALIGN_TOPLEFT]["Y"] = $RealPos[3]["Y"];
$RealPos[TEXT_ALIGN_TOPRIGHT]["X"] = $RealPos[2]["X"];
$RealPos[TEXT_ALIGN_TOPRIGHT]["Y"] = $RealPos[2]["Y"];
$RealPos[TEXT_ALIGN_BOTTOMMIDDLE]["X"] = ($RealPos[1]["X"] - $RealPos[0]["X"]) / 2 + $RealPos[0]["X"];
$RealPos[TEXT_ALIGN_BOTTOMMIDDLE]["Y"] = ($RealPos[0]["Y"] - $RealPos[1]["Y"]) / 2 + $RealPos[1]["Y"];
$RealPos[TEXT_ALIGN_TOPMIDDLE]["X"] = ($RealPos[2]["X"] - $RealPos[3]["X"]) / 2 + $RealPos[3]["X"];
$RealPos[TEXT_ALIGN_TOPMIDDLE]["Y"] = ($RealPos[3]["Y"] - $RealPos[2]["Y"]) / 2 + $RealPos[2]["Y"];
$RealPos[TEXT_ALIGN_MIDDLELEFT]["X"] = ($RealPos[0]["X"] - $RealPos[3]["X"]) / 2 + $RealPos[3]["X"];
$RealPos[TEXT_ALIGN_MIDDLELEFT]["Y"] = ($RealPos[0]["Y"] - $RealPos[3]["Y"]) / 2 + $RealPos[3]["Y"];
$RealPos[TEXT_ALIGN_MIDDLERIGHT]["X"] = ($RealPos[1]["X"] - $RealPos[2]["X"]) / 2 + $RealPos[2]["X"];
$RealPos[TEXT_ALIGN_MIDDLERIGHT]["Y"] = ($RealPos[1]["Y"] - $RealPos[2]["Y"]) / 2 + $RealPos[2]["Y"];
$RealPos[TEXT_ALIGN_MIDDLEMIDDLE]["X"] = ($RealPos[1]["X"] - $RealPos[3]["X"]) / 2 + $RealPos[3]["X"];
$RealPos[TEXT_ALIGN_MIDDLEMIDDLE]["Y"] = ($RealPos[0]["Y"] - $RealPos[2]["Y"]) / 2 + $RealPos[2]["Y"];
return $RealPos;
}
/**
* Set current font properties
* @param array $Format
*/
public function setFontProperties($Format = [])
{
$R = isset($Format["R"]) ? $Format["R"] : -1;
$G = isset($Format["G"]) ? $Format["G"] : -1;
$B = isset($Format["B"]) ? $Format["B"] : -1;
$Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
$FontName = isset($Format["FontName"]) ? $Format["FontName"] : null;
$FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : null;
if ($R != -1) {
$this->FontColorR = $R;
}
if ($G != -1) {
$this->FontColorG = $G;
}
if ($B != -1) {
$this->FontColorB = $B;
}
if ($Alpha != null) {
$this->FontColorA = $Alpha;
}
if ($FontName != null) {
$this->FontName = $this->loadFont($FontName, 'fonts');
}
if ($FontSize != null) {
$this->FontSize = $FontSize;
}
}
/**
* Returns the 1st decimal values (used to correct AA bugs)
* @param mixed $Value
* @return mixed
*/
public function getFirstDecimal($Value)
{
$Values = preg_split("/\./", $Value);
if (isset($Values[1])) {
return substr($Values[1], 0, 1);
} else {
return 0;
}
}
/**
* Attach a dataset to your pChart Object
* @param Data $DataSet
*/
public function setDataSet(Data $DataSet)
{
$this->DataSet = $DataSet;
}
/**
* Print attached dataset contents to STDOUT
*/
public function printDataSet()
{
print_r($this->DataSet);
}
/**
* Initialise the image map methods
* @param string $Name
* @param int $StorageMode
* @param string $UniqueID
* @param string $StorageFolder
*/
public function initialiseImageMap(
$Name = "pChart",
$StorageMode = IMAGE_MAP_STORAGE_SESSION,
$UniqueID = "imageMap",
$StorageFolder = "tmp"
) {
$this->ImageMapIndex = $Name;
$this->ImageMapStorageMode = $StorageMode;
if ($StorageMode == IMAGE_MAP_STORAGE_SESSION) {
if (!isset($_SESSION)) {
session_start();
}
$_SESSION[$this->ImageMapIndex] = null;
} elseif ($StorageMode == IMAGE_MAP_STORAGE_FILE) {
$this->ImageMapFileName = $UniqueID;
$this->ImageMapStorageFolder = $StorageFolder;
$path = sprintf("%s/%s.map", $StorageFolder, $UniqueID);
if (file_exists($path)) {
unlink($path);
}
}
}
/**
* Add a zone to the image map
*
* @param string $Type
* @param string $Plots
* @param string|null $Color
* @param string $Title
* @param string $Message
* @param boolean $HTMLEncode
*/
public function addToImageMap(
$Type,
$Plots,
$Color = null,
$Title = null,
$Message = null,
$HTMLEncode = false
) {
if ($this->ImageMapStorageMode == null) {
$this->initialiseImageMap();
}
/* Encode the characters in the imagemap in HTML standards */
$Title = htmlentities(
str_replace("&#8364;", "\u20AC", $Title),
ENT_QUOTES,
"ISO-8859-15"
);
if ($HTMLEncode) {
$Message = str_replace(
"&gt;",
">",
str_replace(
"&lt;",
"<",
htmlentities($Message, ENT_QUOTES, "ISO-8859-15")
)
);
}
if ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION) {
if (!isset($_SESSION)) {
$this->initialiseImageMap();
}
$_SESSION[$this->ImageMapIndex][] = [$Type, $Plots, $Color, $Title, $Message];
} elseif ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE) {
$Handle = fopen(
sprintf("%s/%s.map", $this->ImageMapStorageFolder, $this->ImageMapFileName),
'a'
);
fwrite(
$Handle,
sprintf(
"%s%s%s%s%s%s%s%s%s\r\n",
$Type,
IMAGE_MAP_DELIMITER,
$Plots,
IMAGE_MAP_DELIMITER,
$Color,
IMAGE_MAP_DELIMITER,
$Title,
IMAGE_MAP_DELIMITER,
$Message
)
);
fclose($Handle);
}
}
/**
* Remove VOID values from an imagemap custom values array
* @param string $SerieName
* @param array $Values
* @return array
*/
public function removeVOIDFromArray($SerieName, array $Values)
{
if (!isset($this->DataSet->Data["Series"][$SerieName])) {
return -1;
}
$Result = [];
foreach ($this->DataSet->Data["Series"][$SerieName]["Data"] as $Key => $Value) {
if ($Value != VOID && isset($Values[$Key])) {
$Result[] = $Values[$Key];
}
}
return $Result;
}
/**
* Replace the title of one image map serie
* @param string $OldTitle
* @param string|array $NewTitle
* @return null|int
*/
public function replaceImageMapTitle($OldTitle, $NewTitle)
{
if ($this->ImageMapStorageMode == null) {
return -1;
}
if (is_array($NewTitle)) {
$NewTitle = $this->removeVOIDFromArray($OldTitle, $NewTitle);
}
if ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION) {
if (!isset($_SESSION)) {
return -1;
}
if (is_array($NewTitle)) {
$ID = 0;
foreach ($_SESSION[$this->ImageMapIndex] as $Key => $Settings) {
if ($Settings[3] == $OldTitle && isset($NewTitle[$ID])) {
$_SESSION[$this->ImageMapIndex][$Key][3] = $NewTitle[$ID];
$ID++;
}
}
} else {
foreach ($_SESSION[$this->ImageMapIndex] as $Key => $Settings) {
if ($Settings[3] == $OldTitle) {
$_SESSION[$this->ImageMapIndex][$Key][3] = $NewTitle;
}
}
}
} elseif ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE) {
$TempArray = [];
$Handle = $this->openFileHandle();
if ($Handle) {
while (($Buffer = fgets($Handle, 4096)) !== false) {
$Fields = preg_split(
sprintf("/%s/", IMAGE_MAP_DELIMITER),
str_replace([chr(10), chr(13)], "", $Buffer)
);
$TempArray[] = [$Fields[0], $Fields[1], $Fields[2], $Fields[3], $Fields[4]];
}
fclose($Handle);
if (is_array($NewTitle)) {
$ID = 0;
foreach ($TempArray as $Key => $Settings) {
if ($Settings[3] == $OldTitle && isset($NewTitle[$ID])) {
$TempArray[$Key][3] = $NewTitle[$ID];
$ID++;
}
}
} else {
foreach ($TempArray as $Key => $Settings) {
if ($Settings[3] == $OldTitle) {
$TempArray[$Key][3] = $NewTitle;
}
}
}
$Handle = $this->openFileHandle("w");
foreach ($TempArray as $Key => $Settings) {
fwrite(
$Handle,
sprintf(
"%s%s%s%s%s%s%s%s%s\r\n",
$Settings[0],
IMAGE_MAP_DELIMITER,
$Settings[1],
IMAGE_MAP_DELIMITER,
$Settings[2],
IMAGE_MAP_DELIMITER,
$Settings[3],
IMAGE_MAP_DELIMITER,
$Settings[4]
)
);
}
fclose($Handle);
}
}
}
/**
* Replace the values of the image map contents
* @param string $Title
* @param array $Values
* @return null|int
*/
public function replaceImageMapValues($Title, array $Values)
{
if ($this->ImageMapStorageMode == null) {
return -1;
}
$Values = $this->removeVOIDFromArray($Title, $Values);
$ID = 0;
if ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION) {
if (!isset($_SESSION)) {
return -1;
}
foreach ($_SESSION[$this->ImageMapIndex] as $Key => $Settings) {
if ($Settings[3] == $Title) {
if (isset($Values[$ID])) {
$_SESSION[$this->ImageMapIndex][$Key][4] = $Values[$ID];
}
$ID++;
}
}
} elseif ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE) {
$TempArray = [];
$Handle = $this->openFileHandle();
if ($Handle) {
while (($Buffer = fgets($Handle, 4096)) !== false) {
$Fields = preg_split(
"/" . IMAGE_MAP_DELIMITER . "/",
str_replace([chr(10), chr(13)], "", $Buffer)
);
$TempArray[] = [$Fields[0], $Fields[1], $Fields[2], $Fields[3], $Fields[4]];
}
fclose($Handle);
foreach ($TempArray as $Key => $Settings) {
if ($Settings[3] == $Title) {
if (isset($Values[$ID])) {
$TempArray[$Key][4] = $Values[$ID];
}
$ID++;
}
}
$Handle = $this->openFileHandle("w");
foreach ($TempArray as $Key => $Settings) {
fwrite(
$Handle,
sprintf(
"%s%s%s%s%s%s%s%s%s\r\n",
$Settings[0],
IMAGE_MAP_DELIMITER,
$Settings[1],
IMAGE_MAP_DELIMITER,
$Settings[2],
IMAGE_MAP_DELIMITER,
$Settings[3],
IMAGE_MAP_DELIMITER,
$Settings[4]
)
);
}
fclose($Handle);
}
}
}
/**
* Dump the image map
* @param string $Name
* @param int $StorageMode
* @param string $UniqueID
* @param string $StorageFolder
*/
public function dumpImageMap(
$Name = "pChart",
$StorageMode = IMAGE_MAP_STORAGE_SESSION,
$UniqueID = "imageMap",
$StorageFolder = "tmp"
) {
$this->ImageMapIndex = $Name;
$this->ImageMapStorageMode = $StorageMode;
if ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_SESSION) {
if (!isset($_SESSION)) {
session_start();
}
if ($_SESSION[$Name] != null) {
foreach ($_SESSION[$Name] as $Key => $Params) {
echo $Params[0] . IMAGE_MAP_DELIMITER . $Params[1]
. IMAGE_MAP_DELIMITER . $Params[2] . IMAGE_MAP_DELIMITER
. $Params[3] . IMAGE_MAP_DELIMITER . $Params[4] . "\r\n";
}
}
} elseif ($this->ImageMapStorageMode == IMAGE_MAP_STORAGE_FILE) {
if (file_exists($StorageFolder . "/" . $UniqueID . ".map")) {
$Handle = @fopen($StorageFolder . "/" . $UniqueID . ".map", "r");
if ($Handle) {
while (($Buffer = fgets($Handle, 4096)) !== false) {
echo $Buffer;
}
}
fclose($Handle);
if ($this->ImageMapAutoDelete) {
unlink($StorageFolder . "/" . $UniqueID . ".map");
}
}
}
/* When the image map is returned to the client, the script ends */
exit();
}
/**
* Return the HTML converted color from the RGB composite values
* @param int $R
* @param int $G
* @param int $B
* @return string
*/
public function toHTMLColor($R, $G, $B)
{
$R = intval($R);
$G = intval($G);
$B = intval($B);
$R = dechex($R < 0 ? 0 : ($R > 255 ? 255 : $R));
$G = dechex($G < 0 ? 0 : ($G > 255 ? 255 : $G));
$B = dechex($B < 0 ? 0 : ($B > 255 ? 255 : $B));
$Color = "#" . (strlen($R) < 2 ? '0' : '') . $R;
$Color .= (strlen($G) < 2 ? '0' : '') . $G;
$Color .= (strlen($B) < 2 ? '0' : '') . $B;
return $Color;
}
/**
* Reverse an array of points
* @param array $Plots
* @return array
*/
public function reversePlots(array $Plots)
{
$Result = [];
for ($i = count($Plots) - 2; $i >= 0; $i = $i - 2) {
$Result[] = $Plots[$i];
$Result[] = $Plots[$i + 1];
}
return $Result;
}
/**
* Mirror Effect
* @param int $X
* @param int $Y
* @param int $Width
* @param int $Height
* @param array $Format
*/
public function drawAreaMirror($X, $Y, $Width, $Height, array $Format = [])
{
$StartAlpha = isset($Format["StartAlpha"]) ? $Format["StartAlpha"] : 80;
$EndAlpha = isset($Format["EndAlpha"]) ? $Format["EndAlpha"] : 0;
$AlphaStep = ($StartAlpha - $EndAlpha) / $Height;
$Picture = imagecreatetruecolor($this->XSize, $this->YSize);
imagecopy($Picture, $this->Picture, 0, 0, 0, 0, $this->XSize, $this->YSize);
for ($i = 1; $i <= $Height; $i++) {
if ($Y + ($i - 1) < $this->YSize && $Y - $i > 0) {
imagecopymerge(
$Picture,
$this->Picture,
$X,
$Y + ($i - 1),
$X,
$Y - $i,
$Width,
1,
$StartAlpha - $AlphaStep * $i
);
}
}
imagecopy($this->Picture, $Picture, 0, 0, 0, 0, $this->XSize, $this->YSize);
}
/**
* Open a handle to image storage file.
* @param string $mode
* @return resource
*/
private function openFileHandle($mode = "r")
{
return @fopen(
sprintf("%s/%s.map", $this->ImageMapStorageFolder, $this->ImageMapFileName),
$mode
);
}
}