Subversion Repositories Sites.obs-saisons.fr

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 aurelien 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 820 2006-12-14 01:04:01Z ljp $
7
//
8
// Copyright (c) Aditus Consulting. All rights reserved.
9
//========================================================================
10
*/
11
 
12
 
13
DEFINE('LOGLABELS_PLAIN',0);
14
DEFINE('LOGLABELS_MAGNITUDE',1);
15
 
16
//===================================================
17
// CLASS LogScale
18
// Description: Logarithmic scale between world and screen
19
//===================================================
20
class LogScale extends LinearScale {
21
//---------------
22
// CONSTRUCTOR
23
 
24
    // Log scale is specified using the log of min and max
25
    function LogScale($min,$max,$type="y") {
26
	$this->LinearScale($min,$max,$type);
27
	$this->ticks = new LogTicks();
28
	$this->name = 'log';
29
    }
30
 
31
//----------------
32
// PUBLIC METHODS
33
 
34
    // Translate between world and screen
35
    function Translate($a) {
36
	if( !is_numeric($a) ) {
37
	    if( $a != '' && $a != '-' && $a != 'x' )
38
		JpGraphError::RaiseL(11001);
39
//('Your data contains non-numeric values.');
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
	    return 1;
60
	}
61
	if( $a==0 ) $a=1;
62
	$a=log10($a);
63
	return round(($a*1.0 - $this->scale[0]) * $this->scale_factor);
64
    }
65
 
66
    // Use bcpow() for increased precision
67
    function GetMinVal() {
68
	if( function_exists("bcpow") )
69
	    return round(bcpow(10,$this->scale[0],15),14);
70
	else
71
	    return round(pow(10,$this->scale[0]),14);
72
    }
73
 
74
    function GetMaxVal() {
75
	if( function_exists("bcpow") )
76
	    return round(bcpow(10,$this->scale[1],15),14);
77
	else
78
	    return round(pow(10,$this->scale[1]),14);
79
    }
80
 
81
    // Logarithmic autoscaling is much simplier since we just
82
    // set the min and max to logs of the min and max values.
83
    // Note that for log autoscale the "maxstep" the fourth argument
84
    // isn't used. This is just included to give the method the same
85
    // signature as the linear counterpart.
86
    function AutoScale(&$img,$min,$max,$dummy) {
87
	if( $min==0 ) $min=1;
88
 
89
	if( $max <= 0 ) {
90
	    JpGraphError::RaiseL(11004);
91
//('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.');
92
	}
93
	if( is_numeric($this->autoscale_min) ) {
94
	    $smin = round($this->autoscale_min);
95
	    $smax = ceil(log10($max));
96
	    if( $min >= $max ) {
97
		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.');
98
	    }
99
	}
100
	else {
101
	    $smin = floor(log10($min));
102
	    if( is_numeric($this->autoscale_max) ) {
103
		$smax = round($this->autoscale_max);
104
		if( $smin >= $smax ) {
105
		    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.');
106
		}
107
	    }
108
	    else
109
		$smax = ceil(log10($max));
110
	}
111
	$this->Update($img,$smin,$smax);
112
    }
113
//---------------
114
// PRIVATE METHODS
115
} // Class
116
 
117
//===================================================
118
// CLASS LogTicks
119
// Description:
120
//===================================================
121
class LogTicks extends Ticks{
122
    var $label_logtype=LOGLABELS_MAGNITUDE;
123
//---------------
124
// CONSTRUCTOR
125
    function LogTicks() {
126
    }
127
//---------------
128
// PUBLIC METHODS
129
    function IsSpecified() {
130
	return true;
131
    }
132
 
133
    function SetLabelLogType($aType) {
134
	$this->label_logtype = $aType;
135
    }
136
 
137
    // For log scale it's meaningless to speak about a major step
138
    // We just return -1 to make the framework happy (specifically
139
    // StrokeLabels() )
140
    function GetMajor() {
141
	return -1;
142
    }
143
 
144
    function SetTextLabelStart($aStart) {
145
	JpGraphError::RaiseL(11005);
146
//('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.');
147
    }
148
 
149
    function SetXLabelOffset($dummy) {
150
	// For log scales we dont care about XLabel offset
151
    }
152
 
153
    // Draw ticks on image "img" using scale "scale". The axis absolute
154
    // position in the image is specified in pos, i.e. for an x-axis
155
    // it specifies the absolute y-coord and for Y-ticks it specified the
156
    // absolute x-position.
157
    function Stroke(&$img,&$scale,$pos) {
158
	$start = $scale->GetMinVal();
159
	$limit = $scale->GetMaxVal();
160
	$nextMajor = 10*$start;
161
	$step = $nextMajor / 10.0;
162
 
163
 
164
	$img->SetLineWeight($this->weight);
165
 
166
	if( $scale->type == "y" ) {
167
	    // member direction specified if the ticks should be on
168
	    // left or right side.
169
	    $a=$pos + $this->direction*$this->GetMinTickAbsSize();
170
	    $a2=$pos + $this->direction*$this->GetMajTickAbsSize();
171
 
172
	    $count=1;
173
	    $this->maj_ticks_pos[0]=$scale->Translate($start);
174
	    $this->maj_ticklabels_pos[0]=$scale->Translate($start);
175
	    if( $this->supress_first )
176
		$this->maj_ticks_label[0]="";
177
	    else {
178
		if( $this->label_formfunc != '' ) {
179
		    $f = $this->label_formfunc;
180
		    $this->maj_ticks_label[0]=call_user_func($f,$start);
181
		}
182
		elseif( $this->label_logtype == LOGLABELS_PLAIN )
183
		    $this->maj_ticks_label[0]=$start;
184
		else
185
		    $this->maj_ticks_label[0]='10^'.round(log10($start));
186
	    }
187
	    $i=1;
188
	    for($y=$start; $y<=$limit; $y+=$step,++$count  ) {
189
		$ys=$scale->Translate($y);
190
		$this->ticks_pos[]=$ys;
191
		$this->ticklabels_pos[]=$ys;
192
		if( $count % 10 == 0 ) {
193
		    if( !$this->supress_tickmarks ) {
194
			if( $this->majcolor!="" ) {
195
			    $img->PushColor($this->majcolor);
196
			    $img->Line($pos,$ys,$a2,$ys);
197
			    $img->PopColor();
198
			}
199
			else
200
			    $img->Line($pos,$ys,$a2,$ys);
201
		    }
202
 
203
		    $this->maj_ticks_pos[$i]=$ys;
204
		    $this->maj_ticklabels_pos[$i]=$ys;
205
 
206
		    if( $this->label_formfunc != '' ) {
207
			$f = $this->label_formfunc;
208
			$this->maj_ticks_label[$i]=call_user_func($f,$nextMajor);
209
		    }
210
		    elseif( $this->label_logtype == 0 )
211
			$this->maj_ticks_label[$i]=$nextMajor;
212
		    else
213
			$this->maj_ticks_label[$i]='10^'.round(log10($nextMajor));
214
		    ++$i;
215
		    $nextMajor *= 10;
216
		    $step *= 10;
217
		    $count=1;
218
		}
219
		else {
220
		    if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
221
			if( $this->mincolor!="" ) $img->PushColor($this->mincolor);
222
			$img->Line($pos,$ys,$a,$ys);
223
			if( $this->mincolor!="" ) $img->PopColor();
224
		    }
225
		}
226
	    }
227
	}
228
	else {
229
	    $a=$pos - $this->direction*$this->GetMinTickAbsSize();
230
	    $a2=$pos - $this->direction*$this->GetMajTickAbsSize();
231
	    $count=1;
232
	    $this->maj_ticks_pos[0]=$scale->Translate($start);
233
	    $this->maj_ticklabels_pos[0]=$scale->Translate($start);
234
	    if( $this->supress_first )
235
		$this->maj_ticks_label[0]="";
236
	    else {
237
		if( $this->label_formfunc != '' ) {
238
		    $f = $this->label_formfunc;
239
		    $this->maj_ticks_label[0]=call_user_func($f,$start);
240
		}
241
		elseif( $this->label_logtype == 0 )
242
		    $this->maj_ticks_label[0]=$start;
243
		else
244
		    $this->maj_ticks_label[0]='10^'.round(log10($start));
245
	    }
246
	    $i=1;
247
	    for($x=$start; $x<=$limit; $x+=$step,++$count  ) {
248
		$xs=$scale->Translate($x);
249
		$this->ticks_pos[]=$xs;
250
		$this->ticklabels_pos[]=$xs;
251
		if( $count % 10 == 0 ) {
252
		    if( !$this->supress_tickmarks ) {
253
			$img->Line($xs,$pos,$xs,$a2);
254
		    }
255
		    $this->maj_ticks_pos[$i]=$xs;
256
		    $this->maj_ticklabels_pos[$i]=$xs;
257
 
258
		    if( $this->label_formfunc != '' ) {
259
			$f = $this->label_formfunc;
260
			$this->maj_ticks_label[$i]=call_user_func($f,$nextMajor);
261
		    }
262
		    elseif( $this->label_logtype == 0 )
263
			$this->maj_ticks_label[$i]=$nextMajor;
264
		    else
265
			$this->maj_ticks_label[$i]='10^'.round(log10($nextMajor));
266
		    ++$i;
267
		    $nextMajor *= 10;
268
		    $step *= 10;
269
		    $count=1;
270
		}
271
		else {
272
		    if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) {
273
			$img->Line($xs,$pos,$xs,$a);
274
		    }
275
		}
276
	    }
277
	}
278
	return true;
279
    }
280
} // Class
281
/* EOF */
282
?>