1 | <?php
|
---|
2 |
|
---|
3 | include_once(dirname(__FILE__).'/../../Base/View.php');
|
---|
4 | include_once(dirname(__FILE__).'/../Model/Measure.php');
|
---|
5 |
|
---|
6 | class GraphView extends View
|
---|
7 | {
|
---|
8 | var $FontSize;
|
---|
9 | var $FontFileName;
|
---|
10 | var $ValueToImageHeigthCoefficient;
|
---|
11 | var $DefaultWidth;
|
---|
12 | var $DefaultHeight;
|
---|
13 |
|
---|
14 | function __construct($System)
|
---|
15 | {
|
---|
16 | parent::__construct($System);
|
---|
17 | $this->DefaultWidth = 800;
|
---|
18 | $this->DefaultHeight = 200;
|
---|
19 | $this->FontSize = 10;
|
---|
20 | $this->FontFileName = 'Arial.ttf';
|
---|
21 | $this->ValueToImageHeigthCoefficient = 0.9;
|
---|
22 | }
|
---|
23 |
|
---|
24 | function Render()
|
---|
25 | {
|
---|
26 | if(array_key_exists('Debug', $_GET)) $Debug = $_GET['Debug'];
|
---|
27 | else $Debug = 0;
|
---|
28 |
|
---|
29 | if(!array_key_exists('From', $_GET)) die('Musíte zadat čas počátku');
|
---|
30 | $StartTime = addslashes($_GET['From']);
|
---|
31 | if(!array_key_exists('To', $_GET)) die('Musíte zadat čas konce');
|
---|
32 | $EndTime = addslashes($_GET['To']);
|
---|
33 | if($EndTime < $StartTime) $EndTime = $StartTime + 60;
|
---|
34 | $TimeDifference = $EndTime - $StartTime;
|
---|
35 | if(!array_key_exists('Measure', $_GET)) die('Musíte zadat měřenou veličinu');
|
---|
36 | $MeasureId = addslashes($_GET['Measure']);
|
---|
37 | if(!array_key_exists('Width', $_GET)) $Width = $this->DefaultWidth;
|
---|
38 | else $Width = addslashes($_GET['Width']);
|
---|
39 | if(!array_key_exists('Height', $_GET)) $Height = $this->DefaultHeight;
|
---|
40 | else $Height = addslashes($_GET['Height']);
|
---|
41 | if(!array_key_exists('Differential', $_GET)) $Differential = $this->Config['Application']['DefaultVariables']['Differential'];
|
---|
42 | else $Differential = addslashes($_GET['Differential']);
|
---|
43 | $VerticalLinesCount = round($Height / ($this->FontSize + 4));
|
---|
44 |
|
---|
45 | $PrefixMultiplier = new PrefixMultiplier();
|
---|
46 | $StopWatchStart = $this->System->GetMicrotime();
|
---|
47 |
|
---|
48 | $Measure = new Measure($this->System);
|
---|
49 | $Measure->Load($MeasureId);
|
---|
50 | $Measure->LevelReducing = $this->Config['Application']['LevelReducing'];
|
---|
51 | $Measure->ReferenceTime = $this->Config['Application']['ReferenceTime'];
|
---|
52 | $Measure->MaxLevel = $this->Config['Application']['MaxLevel'];
|
---|
53 | $Measure->DivisionCount = $this->Config['Application']['DivisionCount'];
|
---|
54 | $Measure->Differential = $this->Config['Application']['DefaultVariables']['Differential'];
|
---|
55 | $Measure->Debug = $Debug;
|
---|
56 | $DbResult2 = $this->Database->select('MeasureMethod', '*', 'Id='.$Measure->Data['Method']);
|
---|
57 | $MeasureMethod = $DbResult2->fetch_assoc();
|
---|
58 |
|
---|
59 | $FontSize = $this->FontSize;
|
---|
60 | $FontFile = dirname(__FILE__).'/../Style/'.$this->Config['System']['Style'].'/'.$this->FontFileName;
|
---|
61 |
|
---|
62 | $Level = floor(log(($EndTime - $StartTime) / $Measure->DivisionCount / 60) / log($Measure->LevelReducing)) - 1;
|
---|
63 | if($Level < 0) $Level = 0;
|
---|
64 | if($Level > $Measure->MaxLevel) $Level = $Measure->MaxLevel;
|
---|
65 | //$Level = 0;
|
---|
66 |
|
---|
67 | $Points = $Measure->GetValues($StartTime, $EndTime, $Level);
|
---|
68 |
|
---|
69 | if($Debug) echo('Points count: '.count($Points).'<br/>');
|
---|
70 | //if($Debug) foreach($Points as $Index => $Item)
|
---|
71 | // echo($Index.': '.$Item['min'].'<br/>');
|
---|
72 |
|
---|
73 | // Calculate total max, avg, min value
|
---|
74 | $MaxValue = -1000000000000000000;
|
---|
75 | $AvgValue = 0;
|
---|
76 | $MinValue = 1000000000000000000;
|
---|
77 | foreach($Points as $Index => $Item)
|
---|
78 | {
|
---|
79 | //$Points[$Index]['min'] = $Points[$Index]['min'] / $Measure['Divider'];
|
---|
80 | //$Points[$Index]['avg'] = $Points[$Index]['avg'] / $Measure['Divider'];
|
---|
81 | //$Points[$Index]['max'] = $Points[$Index]['max'] / $Measure['Divider'];
|
---|
82 | if($Points[$Index]['Avg'] > $MaxValue) $MaxValue = $Points[$Index]['Avg'];
|
---|
83 | if($Points[$Index]['Avg'] < $MinValue) $MinValue = $Points[$Index]['Avg'];
|
---|
84 | if($Points[$Index]['Max'] > $MaxValue) $MaxValue = $Points[$Index]['Max'];
|
---|
85 | if($Points[$Index]['Min'] < $MinValue) $MinValue = $Points[$Index]['Min'];
|
---|
86 | $AvgValue = $AvgValue + $Points[$Index]['Avg'];
|
---|
87 | }
|
---|
88 | //$MinValue = round($MinValue * $Measure['Divider']) / $Measure['Divider'];
|
---|
89 | //$MaxValue = round($MaxValue * $Measure['Divider']) / $Measure['Divider'];
|
---|
90 | $AvgValue = $AvgValue / count($Points); //round( * $Measure['Divider']) / $Measure['Divider'];
|
---|
91 |
|
---|
92 | // Generate polygon and recalculate y values to fit graph height
|
---|
93 | $PointsMin = array(0, $Height - 1);
|
---|
94 | $PointsAvg = array(0, $Height - 1);
|
---|
95 | $PointsMax = array(0, $Height - 1);
|
---|
96 | if(($MaxValue - $MinValue) == 0) $MaxValue = $MinValue + 1;
|
---|
97 | {
|
---|
98 | foreach($Points as $Index => $Item)
|
---|
99 | {
|
---|
100 | $PointsMin[] = $Index * $Width / $Measure->DivisionCount;
|
---|
101 | $PointsMin[] = $Height - 1 - ($Points[$Index]['Min'] - $MinValue) /
|
---|
102 | ($MaxValue - $MinValue) * $Height * $this->ValueToImageHeigthCoefficient;
|
---|
103 | $PointsAvg[] = $Index * $Width / $Measure->DivisionCount;
|
---|
104 | $PointsAvg[] = $Height - 1 - ($Points[$Index]['Avg'] - $MinValue) /
|
---|
105 | ($MaxValue - $MinValue) * $Height * $this->ValueToImageHeigthCoefficient;
|
---|
106 | $PointsMax[] = $Index * $Width / $Measure->DivisionCount;
|
---|
107 | $PointsMax[] = $Height - 1 - ($Points[$Index]['Max'] - $MinValue) /
|
---|
108 | ($MaxValue - $MinValue) * $Height * $this->ValueToImageHeigthCoefficient;
|
---|
109 | //echo($Index.' - '.$Item.' '.$Points[$Index].'<br/>');
|
---|
110 | }
|
---|
111 | }
|
---|
112 | $PointsMin[] = $Width - 1;
|
---|
113 | $PointsMin[] = $Height - 1;
|
---|
114 | $PointsAvg[] = $Width - 1;
|
---|
115 | $PointsAvg[] = $Height - 1;
|
---|
116 | $PointsMax[] = $Width - 1;
|
---|
117 | $PointsMax[] = $Height - 1;
|
---|
118 | $PointsMin[] = $Width - 1;
|
---|
119 | $PointsMin[] = $Height - 1;
|
---|
120 | $PointsAvg[] = $Width - 1;
|
---|
121 | $PointsAvg[] = $Height - 1;
|
---|
122 | $PointsMax[] = $Width - 1;
|
---|
123 | $PointsMax[] = $Height - 1;
|
---|
124 |
|
---|
125 | //array_unshift($Points, $Height - 1);
|
---|
126 | //array_unshift($Points, 0);
|
---|
127 | //$Points[] = $Width - 1;
|
---|
128 | //$Points[] = $Height - 1; echo('sds');
|
---|
129 | //print_r($PointsMax);
|
---|
130 |
|
---|
131 | // Generate image
|
---|
132 | if(!$Debug)
|
---|
133 | {
|
---|
134 | Header('Content-type: image/png');
|
---|
135 | Header('Cache-Control: no-cache'); // Dynamic graph - no cache
|
---|
136 | $Image = @imagecreate($Width, $Height);
|
---|
137 | $BackgroundColor = imagecolorallocate($Image, 255, 255, 255);
|
---|
138 | $Black = imagecolorallocate($Image, 0, 0, 0);
|
---|
139 | $White = imagecolorallocate($Image, 255, 255, 255);
|
---|
140 | $Gray = imagecolorallocate($Image, 200, 200, 200);
|
---|
141 | $DarkGray = imagecolorallocate($Image, 100, 100, 100);
|
---|
142 | $LightBlue = imagecolorallocate($Image, 150, 150, 255);
|
---|
143 | $Blue = imagecolorallocate($Image, 0, 0, 255);
|
---|
144 | $LightRed = imagecolorallocate($Image, 255, 150, 150);
|
---|
145 | $Red = imagecolorallocate($Image, 255, 0, 0);
|
---|
146 | $Green = imagecolorallocate($Image, 0, 200, 0);
|
---|
147 | $LightGreen = imagecolorallocate($Image, 150, 255, 150);
|
---|
148 |
|
---|
149 | imagefilledpolygon($Image, $PointsMax, count($PointsMax) / 2, $LightRed);
|
---|
150 | imagefilledpolygon($Image, $PointsAvg, count($PointsAvg) / 2, $LightGreen);
|
---|
151 | imagefilledpolygon($Image, $PointsMin, count($PointsMin) / 2, $LightBlue);
|
---|
152 |
|
---|
153 | $TimeMarks = array(1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30, 60*60*24*365, 60*60*24*365*10);
|
---|
154 |
|
---|
155 | $TimeRange = $EndTime - $StartTime;
|
---|
156 | $TimeMarksIndex = 0;
|
---|
157 | while(($TimeRange / $TimeMarks[$TimeMarksIndex]) > 1) $TimeMarksIndex += 1;
|
---|
158 | if($TimeMarksIndex < 2) $TimeMarksIndex = 2;
|
---|
159 | $MajorTimeMarks = $TimeMarks[$TimeMarksIndex - 1];
|
---|
160 | $MinorTimeMarks = $TimeMarks[$TimeMarksIndex - 2];
|
---|
161 |
|
---|
162 | $TimeShift = $Measure->AlignTime($StartTime, $MajorTimeMarks) - $StartTime;
|
---|
163 | //imagestring($Image, 10, 40, 50, $TimeShift, $Black);
|
---|
164 |
|
---|
165 | // Zobraz měřítko Y
|
---|
166 | $VerticalLinesDistance = $Height / $VerticalLinesCount;
|
---|
167 | for($I = 1; $I <= $VerticalLinesCount; $I++)
|
---|
168 | {
|
---|
169 | $Y = $Height - 1 - ($VerticalLinesDistance * $I);
|
---|
170 | for($X = 1; $X < $Width; $X = $X + 3) imagesetpixel($Image, $X, $Y, $Gray);
|
---|
171 | //imageline($Image, 30, $Y, $Width-1, $Y, IMG_COLOR_STYLED);
|
---|
172 | }
|
---|
173 |
|
---|
174 | $TimeShift = $Measure->AlignTime($StartTime, $MinorTimeMarks) - $StartTime;
|
---|
175 |
|
---|
176 | // Zobraz měřítko X
|
---|
177 | $LastTextEnd = 0;
|
---|
178 | for($Time = $StartTime; $Time < $EndTime; $Time += $MajorTimeMarks)
|
---|
179 | {
|
---|
180 | $X = round(($Time - $StartTime + $TimeShift) / $TimeRange * $Width) % $Width;
|
---|
181 | //imageline($Image, 30, $Y, $Width-1, $Y, IMG_COLOR_STYLED);
|
---|
182 | if(($MajorTimeMarks > 60 * 60 * 24)) $Text = date('j.n.Y', $Time + $TimeShift);
|
---|
183 | else $Text = date('j.n.Y G:i', $Time + $TimeShift);
|
---|
184 | $BoundBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
|
---|
185 | if($LastTextEnd < ($X - ($BoundBox[2] - $BoundBox[0] + 20) / 2))
|
---|
186 | {
|
---|
187 | for($Y = 0; $Y < $Height; $Y = $Y + 1) imagesetpixel($Image, $X, $Y, $Gray);
|
---|
188 | imagettftext($Image, $FontSize, 0, $X - ($BoundBox[2] - $BoundBox[0]) / 2,
|
---|
189 | $Height - 2, $Black, $FontFile, $Text);
|
---|
190 | $LastTextEnd = $X + ($BoundBox[2] - $BoundBox[0]) / 2;
|
---|
191 | }
|
---|
192 | else for($Y = 0; $Y < $Height; $Y = $Y + 3) imagesetpixel($Image, $X, $Y, $Gray);
|
---|
193 | }
|
---|
194 |
|
---|
195 | // Popisky osy Y
|
---|
196 | for($I = 1; $I <= $VerticalLinesCount; $I++)
|
---|
197 | {
|
---|
198 | $Y = $Height - 1 - ($VerticalLinesDistance * $I);
|
---|
199 | //$Y = $Height - 1 - ($VerticalLinesDistance * $I / ($MaxValue - $MinValue) * $this->Config['Application']['ValueToImageHeigthCoefficient'] * $Height);
|
---|
200 | $Text = $PrefixMultiplier->Add(round(($I * $VerticalLinesDistance /
|
---|
201 | $Height / $this->ValueToImageHeigthCoefficient * ($MaxValue - $MinValue) + $MinValue)), $MeasureMethod['Unit'], 3);
|
---|
202 | $BoundBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
|
---|
203 | if(($Y - ($BoundBox[5] - $BoundBox[1]) / 2) > 10)
|
---|
204 | imagettftext($Image, $FontSize, 0, 2, $Y - ($BoundBox[5] - $BoundBox[1]) / 2, $Black, $FontFile, $Text);
|
---|
205 | }
|
---|
206 | $GenerationTime = floor(($this->System->GetMicrotime() - $StopWatchStart) * 1000 ) / 1000;
|
---|
207 |
|
---|
208 | $Left = $Width - 10;
|
---|
209 | $Text = ' Max. '.$PrefixMultiplier->Add($MaxValue, $MeasureMethod['Unit']);
|
---|
210 | $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
|
---|
211 | $Left -= ($BoundingBox[2] - $BoundingBox[0]);
|
---|
212 | imagettftext($Image, $FontSize, 0, $Left, 14, $Red, $FontFile, $Text);
|
---|
213 |
|
---|
214 | $Text = ' Avg. '.$PrefixMultiplier->Add($AvgValue, $MeasureMethod['Unit']);
|
---|
215 | $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
|
---|
216 | $Left -= ($BoundingBox[2] - $BoundingBox[0]);
|
---|
217 | imagettftext($Image, $FontSize, 0, $Left, 14, $Green, $FontFile, $Text);
|
---|
218 |
|
---|
219 | $Text = ' Min. '.$PrefixMultiplier->Add($MinValue, $MeasureMethod['Unit']);
|
---|
220 | $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
|
---|
221 | $Left -= ($BoundingBox[2] - $BoundingBox[0]);
|
---|
222 | imagettftext($Image, $FontSize, 0, $Left, 14, $Blue, $FontFile, $Text);
|
---|
223 | //imagestring($Image, 2, 70, 20, 'Vygenerováno za '.$GenerationTime.' sekund', $Black);
|
---|
224 | //imagestring($Image, 2, 50, 30, 'Level: '.$Level, $Black);
|
---|
225 |
|
---|
226 | imagettftext($Image, $FontSize, 0, 70, 14, $Black, $FontFile, $Measure->Data['Description']);
|
---|
227 | imagerectangle($Image, 0, 0, $Width - 1, $Height - 1, $Black); // Frame border
|
---|
228 | imagepng($Image);
|
---|
229 | imagedestroy($Image);
|
---|
230 | }
|
---|
231 | }
|
---|
232 | }
|
---|