]> git.sur5r.net Git - bacula/bacula/blob - gui/bacula-web/bgraph.inc.php
bacula-web: Improved SetLegend loop in BGraph classe
[bacula/bacula] / gui / bacula-web / bgraph.inc.php
1 <?php
2 require_once ("external_packages/phplot/phplot.php");
3
4 class BGraph{
5         private $title;
6         
7         private $data;
8         private $data_type;
9         private $type;
10         
11         private $colors;
12         private $shading;
13         
14         private $width;
15         private $height;
16         private $output_file;
17         private $plot;
18         
19         function __construct( $filename = "graph.png" )
20         {
21                 if( !empty($filename) )
22                         $this->output_file = "graph.png";
23                 else
24                         $this->output_file = $filename;
25         }
26         
27         public function SetData( $data_in, $type, $data_type, $shading = 5 )
28         {
29                 $this->data             = $data_in;
30                 $this->type             = $type;
31                 $this->data_type        = $data_type;
32                 $this->shadding         = $shading;
33         }
34         
35         public function SetGraphSize( $width, $height )
36         {
37                 $this->width  = $width;
38                 $this->height = $height;
39         }
40         
41         public function SetTitle( $title )
42         {
43                 if( !empty($title) )
44                         $this->title = $title;
45                 else
46                         die( "Please provide a non empty title for the graph" );
47         }
48         
49         public function SetColors( $colors )
50         {
51                 if( is_array( $colors ) )
52                         $this->colors = $colors;
53                 else
54                         die( "Please provide a array in BGraph->SetColors()" );
55         }
56         
57         public function Get_Image_file()
58         {
59                 return $this->output_file;
60         }
61         
62         public function Render()
63         {
64                 // Setting the size
65                 $this->plot = new PHPlot( $this->width, $this->height );
66                 
67                 // Render to file instead of screen
68                 $this->plot->SetIsInline( true );
69                 $this->plot->SetOutputFile( $this->output_file );
70                 
71                 $this->plot->SetImageBorderType('plain');
72
73                 // Data, type and data type
74                 $this->plot->SetPlotType( $this->type );
75                 $this->plot->SetDataType( $this->data_type );
76                 $this->plot->SetDataValues( $this->data );
77                 
78                 // Plot colors
79                 $this->plot->SetDataColors( $this->colors );
80                 
81                 // Plot shading
82                 $this->plot->SetShading( $this->shading );
83                 
84                 // Image border
85                 $this->plot->SetImageBorderType( 'none' );
86
87
88                 // Labels position
89                 if( $this->type == 'pie' )
90                         $this->plot->SetLabelScalePosition( 0.2 );
91                 
92                 // Graph title
93                 $this->plot->SetTitle( $this->title );
94
95                 //$this->plot->SetLegend(array('Engineering', 'Manufacturing', 'Administration'));
96                 // Setting up legends
97                 $legends = array();
98                 foreach( $this->data as $key => $legend ) {
99                         $this->plot->SetLegend( implode(': ',$legend) );
100                 }
101
102                 # Turn off X tick labels and ticks because they don't apply here:
103                 $this->plot->SetXTickLabelPos('none');
104                 $this->plot->SetXTickPos('none');
105
106                 $this->plot->DrawGraph();
107         } // end function Render()
108 }
109 /*
110 class BGraph {
111
112         var $type;
113         var $sizex;
114         var $sizey;
115         var $MarginBottom;
116         var $MarginLeft;
117         var $Leg;
118
119
120         
121         function BShowGraph($datos,$title,$xlabel,$ylabel,$leyenda,$tipo="lines") {
122         
123                 global $type;
124         
125                 require_once ("external_packages/phplot/phplot.php");
126
127                 if ( empty($this->sizex) || empty($this->sizey) ) {    //Default size
128                         $this->sizex = "600";
129                         $this->sizey = "400";
130                 }
131                 if ( empty($this->MarginBottom) ) {
132                         $this->MarginBottom = 120;
133                 }
134                 
135                 $legend = $leyenda;
136 //              $bgcolor = array(222,206,215);      // Background color of graph
137                 $bgcolor = array(207,231,231);
138                 $fgcolor = array(110,41,57);
139                 
140
141                 
142                 $graph = new PHPlot($this->sizex,$this->sizey,"","");
143
144                 if ( !empty($type) )
145                         $graph->setDataType($type);
146
147                 $graph->SetDataValues($datos);
148                 $graph->SetPlotType($tipo);
149 //              $graph->SetUseTTF(1);
150                 $graph->SetBackgroundColor($bgcolor);
151
152                 $graph->SetLegendPixels(1,20);
153                 $graph->SetDataColors(array('SkyBlue','purple','PeachPuff','aquamarine1','#2CB04B','beige','#9F865F','#135568','orchid','navy','red', 'black', 'blue', 'green', 'brown', 'yellow','cyan','orange','#B9F5A7','#AFAFAF'));
154                 $graph->SetTitle($title);
155                 $graph->SetXLabel($xlabel);
156                 $graph->SetYLabel($ylabel);
157                 $graph->SetPlotAreaWorld("","","","");
158                 
159                 if ( count($datos) > 5 )
160                         $graph->SetXDataLabelAngle(90);
161                 else
162                         $graph->SetXDataLabelAngle(0);
163                 $graph->SetNumXTicks(1);
164 //              $graph->SetXDataLabelPos('none');
165 //              $graph->SetXTickLabelPos('plotdown');
166                 
167 //              $graph->SetXGridLabelType("time");
168 //              $graph->SetXTimeFormat("%b ") ;
169
170                 if ( $this->Leg == 1 ) {
171                         $this->MarginLeftWithLegend($legend);
172                         $graph->SetMarginsPixels($this->MarginLeft,10,35,$this->MarginBottom);
173                         $graph->SetLegend($legend);
174                                 }
175                 else
176                         $graph->SetMarginsPixels(90,35,35,$this->MarginBottom);
177 //              $graph->SetDataColors(array($fgcolor),array( "black"));
178                 $graph->SetFileFormat( "png");
179 //              $graph->DoScaleData(1,1);
180 //              $graph->DoMovingAverage(1,1,1);
181
182 //              FIX ME -- to round y axis.
183                 $vtick = strlen (round ($graph->max_y));
184                 $res = 1;
185                 for ($i=1;$i < $vtick; $i++)
186                         $res = $res*10;
187                 if (strlen($graph->max_y-$res) != $vtick )
188                         $res = $res/10;
189                 $graph->SetVertTickIncrement($res);
190                 $graph->DrawGraph();
191
192         }//end Crear
193
194
195 //Estupidez que tengo que cambiar. !!!!!!!!!!!
196         function SetDataType($typ) {
197                 
198                 global $type;
199                 $type = $typ;
200         }
201
202         function MarginLeftWithLegend($clients) {
203                 
204                 $maxlen = 0;
205                 
206                 while (next($clients)) {
207                         $tmp = strlen(current($clients));
208                         if ( $tmp > $maxlen )
209                                 $maxlen = $tmp;
210                 }
211                 $this->MarginLeft = $maxlen * 9;
212         }       
213
214 }//end class
215
216
217
218
219
220 class BCreateGraph extends BGraph {
221
222         var $BD_bacula;
223         var $izquierda;
224         var $derecha;
225         var $StartDate;
226         var $EndDate;
227         var $elapsed;                        // Default elapsed time to show complex graphs
228         
229         
230         
231         function BCreateGraph() {
232         
233                 $this->StartDate = "1900-01-01";
234                 $this->EndDate = "4000-01-01";
235                 $this->elapsed = "86400";                   // 24 hours in seconds.
236                 
237          }              
238          
239          
240          
241         function BCreate($server,$tipo_dato,$title,$tipo="bars",$xlabel="",$ylabel="") {
242         
243                 global $DB_bacula;
244                 global $izquierda;
245                 global $derecha;
246                 global $clientes;
247         
248                 $this->clientes=array();
249                 $DB_bacula = new Bweb();
250                 $datos = $this->SQLPrepareData($server,$tipo_dato);
251         
252                 if ( empty($datos) ) {                       //No data = No stats = Empty graph
253                         header("Content-type: image/png");
254                         $img= @ImageCreate(200,100) or die ("Cannot intialize GD stream");
255                         $bgc= ImageColorAllocate($img, 0, 255,255);
256                         $txc= ImageColorAllocate($img, 0,0,0);
257                         ImageString($img, 5, 4, 4, "No data to process", $txc);
258                         ImagePng($img);
259                         ImageDestroy($img);
260                         return; 
261                 }
262         
263                 if ( empty ($xlabel) ) {                       // If no label, table names like leyends
264                         $xlabel=$derecha; $ylabel=$izquierda; 
265                 } 
266                         
267                 $this->SetDataType("text-data");
268                 $this->BShowGraph($datos,$title,$xlabel,$ylabel,$this->clientes,$tipo);
269                 
270         }
271
272
273  
274         function SQLPrepareData($servidor,$tipo_dato=0) {         // Prepare bytes data from database.
275
276                 global $DB_bacula;
277                 global $izquierda;
278                 global $derecha;
279         
280                 if ( $tipo_dato<30 ) {               // Simple graph. Only 2 data 
281         
282                 switch ($tipo_dato)
283                                 {
284                                 case BACULA_TYPE_BYTES_FILES:
285                                         $izquierda="jobbytes";
286                                         $derecha="jobfiles";
287                                         break;
288                                 case BACULA_TYPE_FILES_JOBID:
289                                         $izquierda="jobfiles";
290                                         $derecha="jobid";
291                                         break;
292                                 default:
293                                         $izquierda="jobbytes";
294                                         $derecha="endtime";
295                                         break;
296                                 }
297                         $result = $DB_bacula->db_link->query("select $derecha,$izquierda from Job where Name='$servidor' and EndTime < '$this->EndDate' and EndTime > '$this->StartDate' order by SchedTime asc")
298                                 or die ("classes.inc: Error at query: 5");
299                 while ( $row = $result->fetchRow(DB_FETCHMODE_ASSOC) ) {
300                         $whole_result[] = $this->array_merge_php4($row["$derecha"],$row[$izquierda]);
301                 }
302                 $result->free();
303         } else {                                                // Complex graph. 3 or more data.
304                 
305                         switch ( $tipo_dato )
306                                 {
307                                 case '30':                      // Unused, at this time.
308                                         $result = $DB_bacula->db_link->query("select JobBytes,JobFiles,Jobid from Job where Name='$servidor' order by EndTime asc")
309                                                 or die ("classes.inc: Error at query: 6");
310                                         while ( $row = $result->fetchRow(DB_FETCHMODE_ASSOC) )
311                                                 $whole_result[] = array_merge($row["Jobid"],$row["JobFiles"],$row["JobBytes"]);
312                                         $result->free();
313                                         break;
314                                 case BACULA_TYPE_BYTES_ENDTIME_ALLJOBS:  // Special: Generic graph from all clientes.
315                                         $i = -1;                         // Counter of number of jobs of one client. SP: Contador del nmero de jobs totales de un cliente.
316                                         $i2 = 0;                         // Counter of number of keys of array. SP: Contador del nmero de valores del array.
317                                         
318                                         if ($DB_bacula->driver == "mysql") {
319                                         $res = $DB_bacula->db_link->query("select Name from Job where UNIX_TIMESTAMP(EndTime) > UNIX_TIMESTAMP(NOW())-$this->elapsed  group by Name order by Name desc")
320                                                 or die ("classes.inc: Error at query: 7");
321                                                 $resdata = $DB_bacula->db_link->query("select date_format(EndTime,\"%Y-%m-%d\") from Job where UNIX_TIMESTAMP(EndTime) > UNIX_TIMESTAMP(NOW())-$this->elapsed  group by date_format(EndTime, \"%Y-%m-%d\") order by EndTime")
322                                                         or die ("classes.inc: Error at query: 8");
323                                         }
324                                         else if ($DB_bacula->driver == "pgsql") {
325                                                 $res = $DB_bacula->db_link->query("select Name from Job where EndTime > now() - 1*interval'$this->elapsed s'  group by Name order by Name desc")
326                                                         or die ("classes.inc: Error at query: 8");
327                                                 $resdata = $DB_bacula->db_link->query("select to_char(EndTime,'YY-MM-DD') from Job where EndTime > NOW() - 1*interval'$this->elapsed s'  group by EndTime order by EndTime")
328                                                         or die ("classes.inc: Error at query: 9");
329                                         }
330                                         
331                                         if (PEAR::isError($resdata))
332                                                 die("classes.inc: Error at query: 9.1<br>".$resdata->getMessage());
333                                         while ( $tmpdata = $res->fetchRow() )
334                                                 array_push($this->clientes,$tmpdata[0]);
335                                                 
336 //                                      echo "<pre>";
337 //                                      print_r ($this->clientes);
338 //                                      echo "</pre>";
339                                         
340                                         
341                                         $spr                    = array();                        // Temporal array
342                                         $spr2                   = array();                       // Temporal array
343                                         $whole_result   = array();
344                                         $count                  = 0;
345                                                                                 
346                                         while ( $tmpdata = $resdata->fetchRow() ) {
347                                                 $count++;
348                                                 array_push($spr,$tmpdata[0]);
349                                                 if ($DB_bacula->driver == "mysql")
350                                                         $result = $DB_bacula->db_link->query("select date_format(EndTime,\"%Y-%m-%d\"),SUM(JobBytes) as sum,Name as name,count(Name) as Nname from Job WHERE EndTime like '$tmpdata[0]%' group by Name order by Name desc")
351                                                                 or die ("classes.inc: Error at query: 10");
352                                                 else if ($DB_bacula->driver == "pgsql") {
353                                                         $query = "select to_char(EndTime,'YY-MM-DD'),SUM(JobBytes) as sum,Name,count(Name) as Nname from Job WHERE EndTime like '%$tmpdata[0]%' group by EndTime,Name order by Name desc";
354                                                         $result = $DB_bacula->db_link->query($query)
355                                                                 or die ("classes.inc: Error at query: 11");
356                                                 }
357                                                 while ( $row = $result->fetchRow(DB_FETCHMODE_ASSOC) ) {
358                                                         $spr2 = array_merge($spr2,array($row["name"]=>$row["sum"]));
359                                                         $i = $result->numRows();
360                                                 }
361
362                                         
363 //                                              echo "<pre>";
364 //                                              print_r ($spr2);
365 //                                              echo "</pre>";
366                                                 
367                                                 reset ($this->clientes);        
368                                                 do {
369                                                         if ( $spr2[current($this->clientes)] != NULL)
370                                                                 array_push($spr,$spr2[current($this->clientes)]);
371                                                         else
372                                                                 array_push($spr,0);
373                                                 } while ( next($this->clientes) );
374                                                 
375                                                 if ( $i2 < $i )
376                                                         $i2 = $i;
377                                                 
378                                                 if ( $tmpdata[0] != $row["EndTime"] )   
379                                                         array_push($whole_result,$spr);
380                                                 
381                                                 $spr = array();
382                                                 $spr2 = array();
383                                         }
384
385                                         for ( $i = 0; $i < count($whole_result); $i++ ) {  // To equal the arrays so that the graph is not unsquared. SP:Igualamos las matrices para que la gr?ica no se descuadre
386                                                 $tmp = count($whole_result[$i]);
387                                                 if ( $i2 < $tmp )                // Estupidez?. Check this code later...
388                                                         continue;
389                                                 $tmp = $i2 - $tmp;
390                                                 for ( $a = 0; $a <= $tmp; $a++ )
391                                                         array_push($whole_result[$i],"0");                                      // Fill the array
392                                         }
393                                         $resdata->free();       
394 //                                      echo "DEBUG:<br>";
395 //                                      echo "<pre>";
396 //                                      print_r ($whole_result);
397 //                                      echo "</pre>";  
398                                         break;
399                                 
400                                 default:
401                                         break;
402                         }
403                 }
404 //      $result->free();
405           return $whole_result;
406         }//end function
407
408
409
410         //Convert date from mysql to smarty.           THE SAME FUNCTION AT 2 CLASSES. THIS WAY IS BUGGY. TO SOLVE LATER.
411         function PrepareDate($StartDateMonth,$StartDateDay,$StartDateYear,$EndDateMonth,$EndDateDay,$EndDateYear){
412         
413                 $this->StartDate = $StartDateYear."-".$StartDateMonth."-".$StartDateDay." 00:00:00";
414                 $this->EndDate = $EndDateYear."-".$EndDateMonth."-".$EndDateDay." 23:59:00";
415                 
416         }//end function
417
418
419         function array_merge_php4($array1,$array2) {
420             $return=array();
421
422             foreach(func_get_args() as $arg) {
423                 if(!is_array($arg)){
424                 $arg=array($arg);
425                 }
426                     foreach($arg as $key=>$val){
427                             if(!is_int($key)){
428                                 $return[$key]=$val;
429                             }else{
430                                 $return[]=$val;
431                             }
432                     }
433             }
434         return $return;
435         }
436
437 }//end class
438 */
439 ?>