source: trunk/client/modules/Elezioni/grafici/jpgraph_log.php@ 417

Last change on this file since 417 was 284, checked in by roby, 6 years ago
File size: 10.8 KB
Line 
1<?php
2/*=======================================================================
3 // File: JPGRAPH_LOG.PHP
4 // Description: Log scale plot extension for JpGraph
5 // Created: 2001-01-08
6 // Ver: $Id: jpgraph_log.php 1106 2009-02-22 20:16:35Z ljp $
7 //
8 // Copyright (c) Asial Corporation. All rights reserved.
9 //========================================================================
10 */
11
12DEFINE('LOGLABELS_PLAIN',0);
13DEFINE('LOGLABELS_MAGNITUDE',1);
14
15//===================================================
16// CLASS LogScale
17// Description: Logarithmic scale between world and screen
18//===================================================
19class LogScale extends LinearScale {
20 //---------------
21 // CONSTRUCTOR
22
23 // Log scale is specified using the log of min and max
24 function __construct($min,$max,$type="y") {
25 parent::__construct($min,$max,$type);
26 $this->ticks = new LogTicks();
27 $this->name = 'log';
28 }
29
30 //----------------
31 // PUBLIC METHODS
32
33 // Translate between world and screen
34 function Translate($a) {
35 if( !is_numeric($a) ) {
36 if( $a != '' && $a != '-' && $a != 'x' ) {
37 JpGraphError::RaiseL(11001);
38 // ('Your data contains non-numeric values.');
39 }
40 return 1;
41 }
42 if( $a < 0 ) {
43 JpGraphError::RaiseL(11002);
44 //("Negative data values can not be used in a log scale.");
45 exit(1);
46 }
47 if( $a==0 ) $a=1;
48 $a=log10($a);
49 return ceil($this->off + ($a*1.0 - $this->scale[0]) * $this->scale_factor);
50 }
51
52 // Relative translate (don't include offset) usefull when we just want
53 // to know the relative position (in pixels) on the axis
54 function RelTranslate($a) {
55 if( !is_numeric($a) ) {
56 if( $a != '' && $a != '-' && $a != 'x' ) {
57 JpGraphError::RaiseL(11001);
58 //('Your data contains non-numeric values.');
59 }
60 return 1;
61 }
62 if( $a==0 ) {
63 $a=1;
64 }
65 $a=log10($a);
66 return round(($a*1.0 - $this->scale[0]) * $this->scale_factor);
67 }
68
69 // Use bcpow() for increased precision
70 function GetMinVal() {
71 if( function_exists("bcpow") ) {
72 return round(bcpow(10,$this->scale[0],15),14);
73 }
74 else {
75 return round(pow(10,$this->scale[0]),14);
76 }
77 }
78
79 function GetMaxVal() {
80 if( function_exists("bcpow") ) {
81 return round(bcpow(10,$this->scale[1],15),14);
82 }
83 else {
84 return round(pow(10,$this->scale[1]),14);
85 }
86 }
87
88 // Logarithmic autoscaling is much simplier since we just
89 // set the min and max to logs of the min and max values.
90 // Note that for log autoscale the "maxstep" the fourth argument
91 // isn't used. This is just included to give the method the same
92 // signature as the linear counterpart.
93 function AutoScale($img,$min,$max,$maxsteps,$majend=true) {
94 if( $min==0 ) $min=1;
95
96 if( $max <= 0 ) {
97 JpGraphError::RaiseL(11004);
98 //('Scale error for logarithmic scale. You have a problem with your data values. The max value must be greater than 0. It is mathematically impossible to have 0 in a logarithmic scale.');
99 }
100 if( is_numeric($this->autoscale_min) ) {
101 $smin = round($this->autoscale_min);
102 $smax = ceil(log10($max));
103 if( $min >= $max ) {
104 JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.');
105 }
106 }
107 else {
108 $smin = floor(log10($min));
109 if( is_numeric($this->autoscale_max) ) {
110 $smax = round($this->autoscale_max);
111 if( $smin >= $smax ) {
112 JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.');
113 }
114 }
115 else
116 $smax = ceil(log10($max));
117 }
118
119 $this->Update($img,$smin,$smax);
120 }
121 //---------------
122 // PRIVATE METHODS
123} // Class
124
125//===================================================
126// CLASS LogTicks
127// Description:
128//===================================================
129class LogTicks extends Ticks{
130 private $label_logtype=LOGLABELS_MAGNITUDE;
131 private $ticklabels_pos = array();
132 //---------------
133 // CONSTRUCTOR
134 function __construct() {
135 }
136 //---------------
137 // PUBLIC METHODS
138 function IsSpecified() {
139 return true;
140 }
141
142 function SetLabelLogType($aType) {
143 $this->label_logtype = $aType;
144 }
145
146 // For log scale it's meaningless to speak about a major step
147 // We just return -1 to make the framework happy (specifically
148 // StrokeLabels() )
149 function GetMajor() {
150 return -1;
151 }
152
153 function SetTextLabelStart($aStart) {
154 JpGraphError::RaiseL(11005);
155 //('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.');
156 }
157
158 function SetXLabelOffset($dummy) {
159 // For log scales we dont care about XLabel offset
160 }
161
162 // Draw ticks on image "img" using scale "scale". The axis absolute
163 // position in the image is specified in pos, i.e. for an x-axis
164 // it specifies the absolute y-coord and for Y-ticks it specified the
165 // absolute x-position.
166 function Stroke($img,$scale,$pos) {
167 $start = $scale->GetMinVal();
168 $limit = $scale->GetMaxVal();
169 $nextMajor = 10*$start;
170 $step = $nextMajor / 10.0;
171
172
173 $img->SetLineWeight($this->weight);
174
175 if( $scale->type == "y" ) {
176 // member direction specified if the ticks should be on
177 // left or right side.
178 $a=$pos + $this->direction*$this->GetMinTickAbsSize();
179 $a2=$pos + $this->direction*$this->GetMajTickAbsSize();
180
181 $count=1;
182 $this->maj_ticks_pos[0]=$scale->Translate($start);
183 $this->maj_ticklabels_pos[0]=$scale->Translate($start);
184 if( $this->supress_first )
185 $this->maj_ticks_label[0]="";
186 else {
187 if( $this->label_formfunc != '' ) {
188 $f = $this->label_formfunc;
189 $this->maj_ticks_label[0]=call_user_func($f,$start);
190 }
191 elseif( $this->label_logtype == LOGLABELS_PLAIN ) {
192 $this->maj_ticks_label[0]=$start;
193 }
194 else {
195 $this->maj_ticks_label[0]='10^'.round(log10($start));
196 }
197 }
198 $i=1;
199 for($y=$start; $y<=$limit; $y+=$step,++$count ) {
200 $ys=$scale->Translate($y);
201 $this->ticks_pos[]=$ys;
202 $this->ticklabels_pos[]=$ys;
203 if( $count % 10 == 0 ) {
204 if( !$this->supress_tickmarks ) {
205 if( $this->majcolor!="" ) {
206 $img->PushColor($this->majcolor);
207 $img->Line($pos,$ys,$a2,$ys);
208 $img->PopColor();
209 }
210 else {
211 $img->Line($pos,$ys,$a2,$ys);
212 }
213 }
214
215 $this->maj_ticks_pos[$i]=$ys;
216 $this->maj_ticklabels_pos[$i]=$ys;
217
218 if( $this->label_formfunc != '' ) {
219 $f = $this->label_formfunc;
220 $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor);
221 }
222 elseif( $this->label_logtype == 0 ) {
223 $this->maj_ticks_label[$i]=$nextMajor;
224 }
225 else {
226 $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor));
227 }
228 ++$i;
229 $nextMajor *= 10;
230 $step *= 10;
231 $count=1;
232 }
233 else {
234 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
235 if( $this->mincolor!="" ) {
236 $img->PushColor($this->mincolor);
237 }
238 $img->Line($pos,$ys,$a,$ys);
239 if( $this->mincolor!="" ) {
240 $img->PopColor();
241 }
242 }
243 }
244 }
245 }
246 else {
247 $a=$pos - $this->direction*$this->GetMinTickAbsSize();
248 $a2=$pos - $this->direction*$this->GetMajTickAbsSize();
249 $count=1;
250 $this->maj_ticks_pos[0]=$scale->Translate($start);
251 $this->maj_ticklabels_pos[0]=$scale->Translate($start);
252 if( $this->supress_first ) {
253 $this->maj_ticks_label[0]="";
254 }
255 else {
256 if( $this->label_formfunc != '' ) {
257 $f = $this->label_formfunc;
258 $this->maj_ticks_label[0]=call_user_func($f,$start);
259 }
260 elseif( $this->label_logtype == 0 ) {
261 $this->maj_ticks_label[0]=$start;
262 }
263 else {
264 $this->maj_ticks_label[0]='10^'.round(log10($start));
265 }
266 }
267 $i=1;
268 for($x=$start; $x<=$limit; $x+=$step,++$count ) {
269 $xs=$scale->Translate($x);
270 $this->ticks_pos[]=$xs;
271 $this->ticklabels_pos[]=$xs;
272 if( $count % 10 == 0 ) {
273 if( !$this->supress_tickmarks ) {
274 $img->Line($xs,$pos,$xs,$a2);
275 }
276 $this->maj_ticks_pos[$i]=$xs;
277 $this->maj_ticklabels_pos[$i]=$xs;
278
279 if( $this->label_formfunc != '' ) {
280 $f = $this->label_formfunc;
281 $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor);
282 }
283 elseif( $this->label_logtype == 0 ) {
284 $this->maj_ticks_label[$i]=$nextMajor;
285 }
286 else {
287 $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor));
288 }
289 ++$i;
290 $nextMajor *= 10;
291 $step *= 10;
292 $count=1;
293 }
294 else {
295 if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
296 $img->Line($xs,$pos,$xs,$a);
297 }
298 }
299 }
300 }
301 return true;
302 }
303} // Class
304/* EOF */
305?>
Note: See TracBrowser for help on using the repository browser.