ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
phplot_data.php
Go to the documentation of this file.
1 <?php
2 /* $Id$
3  *
4  * Copyright (C) 2000 Afan Ottenheimer. Released under
5  * the GPL and PHP licenses as stated in the the README file which
6  * should have been included with this document.
7 
8  * This is an subclass for phplot.php and should only be
9  * called after phplot.ini has been called. This extends
10  * phplot by adding additional routines that can be used
11  * to modify the data arrays.
12  *
13  * Data must be a *numerical* array, this is enforced in SetDataValues()
14  */
15 
16 require_once("phplot.php");
17 
18 class PHPlot_Data extends PHPlot
19 {
23  function PHPlot_Data($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
24  {
25  if (! isset($this->img)) {
26  $this->PHPlot($which_width, $which_height, $which_output_file, $which_input_file);
27  }
28  }
29 
36  function DoScaleData($even, $show_in_legend)
37  {
38  $offset = 0; // We use this not to read labels in text-data
39 
40  if ($this->data_type == 'text-data') {
41  $offset = 1;
42  } elseif ($this->data_type != 'data-data') {
43  $this->DrawError('wrong data type!!');
44  return FALSE;
45  }
46 
47  // Determine maxima for each data row in array $max
48  // Put maximum of the maxima in $maxmax
49  $maxmax = 0;
50  for($i=0; $i < $this->num_data_rows; $i++) {
51  $rowsize = count($this->data[$i]);
52  for ($j=$offset; $j < $rowsize; $j++) {
53  if ($this->data[$i][$j] > @ $max[$j])
54  $max[$j] = $this->data[$i][$j];
55  if (@ $max[$j] > $maxmax)
56  $maxmax = $max[$j];
57  }
58  }
59 
60  // determine amplification factor $amplify
61  $end = count($max) + $offset;
62  for ($i=$offset; $i < $end; $i++) {
63  if ($max[$i] == 0 || $max[$i] == $maxmax) {
64  $amplify[$i] = 1; // no divide by zero
65  } else {
66  if ($even) {
67  $amp = pow(10,round(log10($maxmax / $max[$i]))-1);
68  if ($amp * $max[$i] * 5 < $maxmax) {
69  $amp *= 5;
70  } elseif ($amp * $max[$i] * 2 < $maxmax) {
71  $amp *= 2;
72  }
73  } else {
74  $amp = $maxmax / $max[$i];
75  $digits = floor(log10($amp));
76  $amp = round($amp/pow(10,$digits-1))*pow(10,$digits-1);
77  }
78  $amplify[$i] = $amp;
79  }
80  if ($amplify[$i] != 1 && $show_in_legend)
81  @ $this->legend[$i] .= "*$amplify[$i]";
82  }
83 
84  // Amplify data
85  // On my machine, running 1000 iterations over 1000 rows of 12 elements each,
86  // the for loops were 43.2% faster (MBD)
87  for ($i = 0; $i < $this->num_data_rows; $i++) {
88  $rowsize = count($this->data[$i]);
89  for ($j=$offset; $j < $rowsize; $j++) {
90  $this->data[$i][$j] *= $amplify[$j];
91  }
92  }
93 
94  //Re-Scale Vertical Ticks if not already set
95  if ( ! $this->y_tick_increment) {
96  $this->SetYTickIncrement() ;
97  }
98 
99  return TRUE;
100  } //function DoScaleData
101 
102 
117  function DoMovingAverage($datarow, $interval, $show=TRUE, $color=NULL, $width=NULL)
118  {
119  $off = 1; // Skip record #0 (data label)
120 
121  $this->PadArrays();
122 
123  if ($interval == 0) {
124  $this->DrawError('DoMovingAverage(): interval can\'t be 0');
125  return FALSE;
126  }
127 
128  if ($datarow >= $this->records_per_group) {
129  $this->DrawError("DoMovingAverage(): Data row out of bounds ($datarow >= $this->records_per_group)");
130  return FALSE;
131  }
132 
133  if ($this->data_type == 'text-data') {
134  // Ok. No need to set the offset to skip more records.
135  } elseif ($this->data_type == 'data-data') {
136  $off++; // first Y value at $data[][2]
137  } else {
138  $this->DrawError('DoMovingAverage(): wrong data type!!');
139  return FALSE;
140  }
141 
142  // Set color:
143  if ($color) {
144  array_push($this->ndx_data_colors, $this->SetIndexDarkColor($color));
145  } else {
146  array_push($this->ndx_data_colors, $this->SetIndexDarkColor($this->data_colors[$datarow]));
147  }
148  // Set line width:
149  if ($width) {
150  array_push($this->line_widths, $width);
151  } else {
152  array_push($this->line_widths, $this->line_widths[$datarow] * 2);
153  }
154  // Show in legend?
155  if ($show) {
156  $this->legend[$this->records_per_group-1] = "(MA[$datarow]:$interval)";
157  }
158 
159  $datarow += $off;
160  for ($i = 0; $i < $this->num_data_rows; $i++) {
161  $storage[$i % $interval] = @ $this->data[$i][$datarow];
162  $ma = array_sum($storage);
163  $ma /= count($storage);
164  array_push($this->data[$i], $ma); // Push the data onto the array
165  $this->num_recs[$i]++; // Tell the drawing functions it is there
166  }
167  $this->records_per_group++;
168 // $this->FindDataLimits();
169  return TRUE;
170  } //function DoMovingAverage()
171 
172 
178  function DoExponentialMovingAverage($datarow, $perc, $show_in_legend)
179  {
180  if ($this->data_type == 'text-data') {
181  $datarow++;
182  } elseif ($this->data_type != 'data-data') {
183  $this->DrawError('DoWeightedMovingAverage(): wrong data type!!');
184  return FALSE;
185  }
186 
187  if ($show_in_legend) {
188  $this->legend[$datarow] .= " (MA: $interval)";
189  }
190 
191  $storage[0] = $this->data[0][$datarow];
192  for ($i=1;$i < $this->num_data_rows; $i++) {
193  $storage[$i] = @ $storage[$i-1] + $perc * ($this->data[$i][$datarow] - $storage[$i-1]);
194  $ma = array_sum($storage);
195  $ma /= count($storage);
196  $this->data[$i][$datarow] = $ma;
197  }
198  return TRUE;
199  } // function DoExponentialMovingAverage()
200 
201 
205  function DoRemoveDataSet($index)
206  {
207  $offset = 1;
208  if ($this->data_type == 'data-data') {
209  $offset++;
210  } elseif ($this->data_type != 'text-data') {
211  $this->DrawError('wrong data type!!');
212  return FALSE;
213  }
214 
215  $index += $offset;
216  foreach ($this->data as $key=>$val) {
217  foreach ($val as $key2=>$val2) {
218  if ($key2 >= $index) {
219  if (isset($this->data[$key][$key2+1])) {
220  $this->data[$key][$key2] = $this->data[$key][$key2+1];
221  } else {
222  unset($this->data[$key][$key2]);
223  }
224  }
225  }
226  }
227  } // function DoRemoveDataSet
228 
229 
234  function DoDivision($x,$y)
235  {
236  $offset = 1;
237  if ($this->data_type == 'data-data') {
238  $offset++;
239  } elseif ($this->data_type != 'text-data') {
240  $this->DrawError('wrong data type!!');
241  return FALSE;
242  }
243 
244  $x += $offset; $y += $offset;
245  reset($this->data);
246  while (list($key, $val) = each($this->data)) {
247  if ($this->data[$key][$y] == 0) {
248  $this->data[$key][$x] = 0;
249  } else {
250  $this->data[$key][$x] /= $this->data[$key][$y];
251  }
252  }
253 
254  $this->DoRemoveDataSet($y-$offset);
255  } // function DoDivision
256 
257 } // class PHPlot_Data extends PHPlot
258 ?>