Subversion Repositories Applications.annuaire

Rev

Rev 94 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
66 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 1106 2009-02-22 20:16:35Z ljp $
7
 //
8
 // Copyright (c) Aditus Consulting. All rights reserved.
9
 //========================================================================
10
 */
11
 
12
DEFINE('LOGLABELS_PLAIN',0);
13
DEFINE('LOGLABELS_MAGNITUDE',1);
14
 
15
//===================================================
16
// CLASS LogScale
17
// Description: Logarithmic scale between world and screen
18
//===================================================
19
class 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
//===================================================
129
class LogTicks extends Ticks{
130
    private $label_logtype=LOGLABELS_MAGNITUDE;
131
    private $ticklabels_pos = array();
132
    //---------------
133
    // CONSTRUCTOR
134
    function LogTicks() {
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
?>