Bubble.php
1 year ago
Indicator.php
1 year ago
Pie.php
1 year ago
Radar.php
1 year ago
Scatter.php
1 year ago
Split.php
1 year ago
Spring.php
1 year ago
Stock.php
1 year ago
Surface.php
1 year ago
Stock.php
237 lines
| 1 | <?php |
| 2 | |
| 3 | namespace CpChart\Chart; |
| 4 | |
| 5 | use CpChart\Data; |
| 6 | use CpChart\Image; |
| 7 | /** |
| 8 | * Stock - class to draw stock charts |
| 9 | * |
| 10 | * Version : 2.1.4 |
| 11 | * Made by : Jean-Damien POGOLOTTI |
| 12 | * Last Update : 19/01/2014 |
| 13 | * |
| 14 | * This file can be distributed under the license you can find at : |
| 15 | * |
| 16 | * http://www.pchart.net/license |
| 17 | * |
| 18 | * You can find the whole class documentation on the pChart web site. |
| 19 | */ |
| 20 | class Stock |
| 21 | { |
| 22 | /** |
| 23 | * @var Image |
| 24 | */ |
| 25 | public $pChartObject; |
| 26 | /** |
| 27 | * @var Data |
| 28 | */ |
| 29 | public $pDataObject; |
| 30 | /** |
| 31 | * @param Image $pChartObject |
| 32 | * @param Data $pDataObject |
| 33 | */ |
| 34 | public function __construct(Image $pChartObject, Data $pDataObject) |
| 35 | { |
| 36 | $this->pChartObject = $pChartObject; |
| 37 | $this->pDataObject = $pDataObject; |
| 38 | } |
| 39 | /** |
| 40 | * Draw a stock chart |
| 41 | * @param array $Format |
| 42 | * @return integer|null |
| 43 | */ |
| 44 | public function drawStockChart(array $Format = []) |
| 45 | { |
| 46 | $SerieOpen = isset($Format["SerieOpen"]) ? $Format["SerieOpen"] : "Open"; |
| 47 | $SerieClose = isset($Format["SerieClose"]) ? $Format["SerieClose"] : "Close"; |
| 48 | $SerieMin = isset($Format["SerieMin"]) ? $Format["SerieMin"] : "Min"; |
| 49 | $SerieMax = isset($Format["SerieMax"]) ? $Format["SerieMax"] : "Max"; |
| 50 | $SerieMedian = isset($Format["SerieMedian"]) ? $Format["SerieMedian"] : null; |
| 51 | $LineWidth = isset($Format["LineWidth"]) ? $Format["LineWidth"] : 1; |
| 52 | $LineR = isset($Format["LineR"]) ? $Format["LineR"] : 0; |
| 53 | $LineG = isset($Format["LineG"]) ? $Format["LineG"] : 0; |
| 54 | $LineB = isset($Format["LineB"]) ? $Format["LineB"] : 0; |
| 55 | $LineAlpha = isset($Format["LineAlpha"]) ? $Format["LineAlpha"] : 100; |
| 56 | $ExtremityWidth = isset($Format["ExtremityWidth"]) ? $Format["ExtremityWidth"] : 1; |
| 57 | $ExtremityLength = isset($Format["ExtremityLength"]) ? $Format["ExtremityLength"] : 3; |
| 58 | $ExtremityR = isset($Format["ExtremityR"]) ? $Format["ExtremityR"] : 0; |
| 59 | $ExtremityG = isset($Format["ExtremityG"]) ? $Format["ExtremityG"] : 0; |
| 60 | $ExtremityB = isset($Format["ExtremityB"]) ? $Format["ExtremityB"] : 0; |
| 61 | $ExtremityAlpha = isset($Format["ExtremityAlpha"]) ? $Format["ExtremityAlpha"] : 100; |
| 62 | $BoxWidth = isset($Format["BoxWidth"]) ? $Format["BoxWidth"] : 8; |
| 63 | $BoxUpR = isset($Format["BoxUpR"]) ? $Format["BoxUpR"] : 188; |
| 64 | $BoxUpG = isset($Format["BoxUpG"]) ? $Format["BoxUpG"] : 224; |
| 65 | $BoxUpB = isset($Format["BoxUpB"]) ? $Format["BoxUpB"] : 46; |
| 66 | $BoxUpAlpha = isset($Format["BoxUpAlpha"]) ? $Format["BoxUpAlpha"] : 100; |
| 67 | $BoxUpSurrounding = isset($Format["BoxUpSurrounding"]) ? $Format["BoxUpSurrounding"] : null; |
| 68 | $BoxUpBorderR = isset($Format["BoxUpBorderR"]) ? $Format["BoxUpBorderR"] : $BoxUpR - 20; |
| 69 | $BoxUpBorderG = isset($Format["BoxUpBorderG"]) ? $Format["BoxUpBorderG"] : $BoxUpG - 20; |
| 70 | $BoxUpBorderB = isset($Format["BoxUpBorderB"]) ? $Format["BoxUpBorderB"] : $BoxUpB - 20; |
| 71 | $BoxUpBorderAlpha = isset($Format["BoxUpBorderAlpha"]) ? $Format["BoxUpBorderAlpha"] : 100; |
| 72 | $BoxDownR = isset($Format["BoxDownR"]) ? $Format["BoxDownR"] : 224; |
| 73 | $BoxDownG = isset($Format["BoxDownG"]) ? $Format["BoxDownG"] : 100; |
| 74 | $BoxDownB = isset($Format["BoxDownB"]) ? $Format["BoxDownB"] : 46; |
| 75 | $BoxDownAlpha = isset($Format["BoxDownAlpha"]) ? $Format["BoxDownAlpha"] : 100; |
| 76 | $BoxDownSurrounding = isset($Format["BoxDownSurrounding"]) ? $Format["BoxDownSurrounding"] : null; |
| 77 | $BoxDownBorderR = isset($Format["BoxDownBorderR"]) ? $Format["BoxDownBorderR"] : $BoxDownR - 20; |
| 78 | $BoxDownBorderG = isset($Format["BoxDownBorderG"]) ? $Format["BoxDownBorderG"] : $BoxDownG - 20; |
| 79 | $BoxDownBorderB = isset($Format["BoxDownBorderB"]) ? $Format["BoxDownBorderB"] : $BoxDownB - 20; |
| 80 | $BoxDownBorderAlpha = isset($Format["BoxDownBorderAlpha"]) ? $Format["BoxDownBorderAlpha"] : 100; |
| 81 | $ShadowOnBoxesOnly = isset($Format["ShadowOnBoxesOnly"]) ? $Format["ShadowOnBoxesOnly"] : \true; |
| 82 | $MedianR = isset($Format["MedianR"]) ? $Format["MedianR"] : 255; |
| 83 | $MedianG = isset($Format["MedianG"]) ? $Format["MedianG"] : 0; |
| 84 | $MedianB = isset($Format["MedianB"]) ? $Format["MedianB"] : 0; |
| 85 | $MedianAlpha = isset($Format["MedianAlpha"]) ? $Format["MedianAlpha"] : 100; |
| 86 | $RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : \false; |
| 87 | $ImageMapTitle = isset($Format["ImageMapTitle"]) ? $Format["ImageMapTitle"] : "Stock Chart"; |
| 88 | /* Data Processing */ |
| 89 | if ($BoxUpSurrounding != null) { |
| 90 | $BoxUpBorderR = $BoxUpR + $BoxUpSurrounding; |
| 91 | $BoxUpBorderG = $BoxUpG + $BoxUpSurrounding; |
| 92 | $BoxUpBorderB = $BoxUpB + $BoxUpSurrounding; |
| 93 | } |
| 94 | if ($BoxDownSurrounding != null) { |
| 95 | $BoxDownBorderR = $BoxDownR + $BoxDownSurrounding; |
| 96 | $BoxDownBorderG = $BoxDownG + $BoxDownSurrounding; |
| 97 | $BoxDownBorderB = $BoxDownB + $BoxDownSurrounding; |
| 98 | } |
| 99 | if ($LineWidth != 1) { |
| 100 | $LineOffset = $LineWidth / 2; |
| 101 | } |
| 102 | $BoxOffset = $BoxWidth / 2; |
| 103 | $Data = $this->pChartObject->DataSet->getData(); |
| 104 | list($XMargin, $XDivs) = $this->pChartObject->scaleGetXSettings(); |
| 105 | if (!isset($Data["Series"][$SerieOpen]) || !isset($Data["Series"][$SerieClose]) || !isset($Data["Series"][$SerieMin]) || !isset($Data["Series"][$SerieMax])) { |
| 106 | return STOCK_MISSING_SERIE; |
| 107 | } |
| 108 | $Plots = []; |
| 109 | foreach ($Data["Series"][$SerieOpen]["Data"] as $Key => $Value) { |
| 110 | $Point = []; |
| 111 | if (isset($Data["Series"][$SerieClose]["Data"][$Key]) || isset($Data["Series"][$SerieMin]["Data"][$Key]) || isset($Data["Series"][$SerieMax]["Data"][$Key])) { |
| 112 | $Point = [$Value, $Data["Series"][$SerieClose]["Data"][$Key], $Data["Series"][$SerieMin]["Data"][$Key], $Data["Series"][$SerieMax]["Data"][$Key]]; |
| 113 | } |
| 114 | if ($SerieMedian != null && isset($Data["Series"][$SerieMedian]["Data"][$Key])) { |
| 115 | $Point[] = $Data["Series"][$SerieMedian]["Data"][$Key]; |
| 116 | } |
| 117 | $Plots[] = $Point; |
| 118 | } |
| 119 | $AxisID = $Data["Series"][$SerieOpen]["Axis"]; |
| 120 | $Format = $Data["Axis"][$AxisID]["Format"]; |
| 121 | $YZero = $this->pChartObject->scaleComputeY(0, ["AxisID" => $AxisID]); |
| 122 | $XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs; |
| 123 | $X = $this->pChartObject->GraphAreaX1 + $XMargin; |
| 124 | $Y = $this->pChartObject->GraphAreaY1 + $XMargin; |
| 125 | $LineSettings = ["R" => $LineR, "G" => $LineG, "B" => $LineB, "Alpha" => $LineAlpha]; |
| 126 | $ExtremitySettings = ["R" => $ExtremityR, "G" => $ExtremityG, "B" => $ExtremityB, "Alpha" => $ExtremityAlpha]; |
| 127 | $BoxUpSettings = ["R" => $BoxUpR, "G" => $BoxUpG, "B" => $BoxUpB, "Alpha" => $BoxUpAlpha, "BorderR" => $BoxUpBorderR, "BorderG" => $BoxUpBorderG, "BorderB" => $BoxUpBorderB, "BorderAlpha" => $BoxUpBorderAlpha]; |
| 128 | $BoxDownSettings = ["R" => $BoxDownR, "G" => $BoxDownG, "B" => $BoxDownB, "Alpha" => $BoxDownAlpha, "BorderR" => $BoxDownBorderR, "BorderG" => $BoxDownBorderG, "BorderB" => $BoxDownBorderB, "BorderAlpha" => $BoxDownBorderAlpha]; |
| 129 | $MedianSettings = ["R" => $MedianR, "G" => $MedianG, "B" => $MedianB, "Alpha" => $MedianAlpha]; |
| 130 | foreach ($Plots as $Key => $Points) { |
| 131 | $PosArray = $this->pChartObject->scaleComputeY($Points, ["AxisID" => $AxisID]); |
| 132 | $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>"; |
| 133 | if ($SerieMedian != null) { |
| 134 | $Values = $Values . "Median : " . $Data["Series"][$SerieMedian]["Data"][$Key] . "<BR>"; |
| 135 | } |
| 136 | if ($PosArray[0] > $PosArray[1]) { |
| 137 | $ImageMapColor = $this->pChartObject->toHTMLColor($BoxUpR, $BoxUpG, $BoxUpB); |
| 138 | } else { |
| 139 | $ImageMapColor = $this->pChartObject->toHTMLColor($BoxDownR, $BoxDownG, $BoxDownB); |
| 140 | } |
| 141 | if ($Data["Orientation"] == SCALE_POS_LEFTRIGHT) { |
| 142 | if ($YZero > $this->pChartObject->GraphAreaY2 - 1) { |
| 143 | $YZero = $this->pChartObject->GraphAreaY2 - 1; |
| 144 | } |
| 145 | if ($YZero < $this->pChartObject->GraphAreaY1 + 1) { |
| 146 | $YZero = $this->pChartObject->GraphAreaY1 + 1; |
| 147 | } |
| 148 | if ($XDivs == 0) { |
| 149 | $XStep = 0; |
| 150 | } else { |
| 151 | $XStep = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin * 2) / $XDivs; |
| 152 | } |
| 153 | if ($ShadowOnBoxesOnly) { |
| 154 | $RestoreShadow = $this->pChartObject->Shadow; |
| 155 | $this->pChartObject->Shadow = \false; |
| 156 | } |
| 157 | if ($LineWidth == 1) { |
| 158 | $this->pChartObject->drawLine($X, $PosArray[2], $X, $PosArray[3], $LineSettings); |
| 159 | } else { |
| 160 | $this->pChartObject->drawFilledRectangle($X - $LineOffset, $PosArray[2], $X + $LineOffset, $PosArray[3], $LineSettings); |
| 161 | } |
| 162 | if ($ExtremityWidth == 1) { |
| 163 | $this->pChartObject->drawLine($X - $ExtremityLength, $PosArray[2], $X + $ExtremityLength, $PosArray[2], $ExtremitySettings); |
| 164 | $this->pChartObject->drawLine($X - $ExtremityLength, $PosArray[3], $X + $ExtremityLength, $PosArray[3], $ExtremitySettings); |
| 165 | if ($RecordImageMap) { |
| 166 | $this->pChartObject->addToImageMap("RECT", sprintf("%s,%s,%s,%s", floor($X - $ExtremityLength), floor($PosArray[2]), floor($X + $ExtremityLength), floor($PosArray[3])), $ImageMapColor, $ImageMapTitle, $Values); |
| 167 | } |
| 168 | } else { |
| 169 | $this->pChartObject->drawFilledRectangle($X - $ExtremityLength, $PosArray[2], $X + $ExtremityLength, $PosArray[2] - $ExtremityWidth, $ExtremitySettings); |
| 170 | $this->pChartObject->drawFilledRectangle($X - $ExtremityLength, $PosArray[3], $X + $ExtremityLength, $PosArray[3] + $ExtremityWidth, $ExtremitySettings); |
| 171 | if ($RecordImageMap) { |
| 172 | $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); |
| 173 | } |
| 174 | } |
| 175 | if ($ShadowOnBoxesOnly) { |
| 176 | $this->pChartObject->Shadow = $RestoreShadow; |
| 177 | } |
| 178 | if ($PosArray[0] > $PosArray[1]) { |
| 179 | $this->pChartObject->drawFilledRectangle($X - $BoxOffset, $PosArray[0], $X + $BoxOffset, $PosArray[1], $BoxUpSettings); |
| 180 | } else { |
| 181 | $this->pChartObject->drawFilledRectangle($X - $BoxOffset, $PosArray[0], $X + $BoxOffset, $PosArray[1], $BoxDownSettings); |
| 182 | } |
| 183 | if (isset($PosArray[4])) { |
| 184 | $this->pChartObject->drawLine($X - $ExtremityLength, $PosArray[4], $X + $ExtremityLength, $PosArray[4], $MedianSettings); |
| 185 | } |
| 186 | $X = $X + $XStep; |
| 187 | } elseif ($Data["Orientation"] == SCALE_POS_TOPBOTTOM) { |
| 188 | if ($YZero > $this->pChartObject->GraphAreaX2 - 1) { |
| 189 | $YZero = $this->pChartObject->GraphAreaX2 - 1; |
| 190 | } |
| 191 | if ($YZero < $this->pChartObject->GraphAreaX1 + 1) { |
| 192 | $YZero = $this->pChartObject->GraphAreaX1 + 1; |
| 193 | } |
| 194 | if ($XDivs == 0) { |
| 195 | $XStep = 0; |
| 196 | } else { |
| 197 | $XStep = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $XMargin * 2) / $XDivs; |
| 198 | } |
| 199 | if ($LineWidth == 1) { |
| 200 | $this->pChartObject->drawLine($PosArray[2], $Y, $PosArray[3], $Y, $LineSettings); |
| 201 | } else { |
| 202 | $this->pChartObject->drawFilledRectangle($PosArray[2], $Y - $LineOffset, $PosArray[3], $Y + $LineOffset, $LineSettings); |
| 203 | } |
| 204 | if ($ShadowOnBoxesOnly) { |
| 205 | $RestoreShadow = $this->pChartObject->Shadow; |
| 206 | $this->pChartObject->Shadow = \false; |
| 207 | } |
| 208 | if ($ExtremityWidth == 1) { |
| 209 | $this->pChartObject->drawLine($PosArray[2], $Y - $ExtremityLength, $PosArray[2], $Y + $ExtremityLength, $ExtremitySettings); |
| 210 | $this->pChartObject->drawLine($PosArray[3], $Y - $ExtremityLength, $PosArray[3], $Y + $ExtremityLength, $ExtremitySettings); |
| 211 | if ($RecordImageMap) { |
| 212 | $this->pChartObject->addToImageMap("RECT", sprintf("%s,%s,%s,%s", floor($PosArray[2]), floor($Y - $ExtremityLength), floor($PosArray[3]), floor($Y + $ExtremityLength)), $ImageMapColor, $ImageMapTitle, $Values); |
| 213 | } |
| 214 | } else { |
| 215 | $this->pChartObject->drawFilledRectangle($PosArray[2], $Y - $ExtremityLength, $PosArray[2] - $ExtremityWidth, $Y + $ExtremityLength, $ExtremitySettings); |
| 216 | $this->pChartObject->drawFilledRectangle($PosArray[3], $Y - $ExtremityLength, $PosArray[3] + $ExtremityWidth, $Y + $ExtremityLength, $ExtremitySettings); |
| 217 | if ($RecordImageMap) { |
| 218 | $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); |
| 219 | } |
| 220 | } |
| 221 | if ($ShadowOnBoxesOnly) { |
| 222 | $this->pChartObject->Shadow = $RestoreShadow; |
| 223 | } |
| 224 | if ($PosArray[0] < $PosArray[1]) { |
| 225 | $this->pChartObject->drawFilledRectangle($PosArray[0], $Y - $BoxOffset, $PosArray[1], $Y + $BoxOffset, $BoxUpSettings); |
| 226 | } else { |
| 227 | $this->pChartObject->drawFilledRectangle($PosArray[0], $Y - $BoxOffset, $PosArray[1], $Y + $BoxOffset, $BoxDownSettings); |
| 228 | } |
| 229 | if (isset($PosArray[4])) { |
| 230 | $this->pChartObject->drawLine($PosArray[4], $Y - $ExtremityLength, $PosArray[4], $Y + $ExtremityLength, $MedianSettings); |
| 231 | } |
| 232 | $Y = $Y + $XStep; |
| 233 | } |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 |