Test Failed
Push — develop ( 48349f...3c7590 )
by Felipe
15:17
created

LinearScale::IsSpecified()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
/**
4
 * JPGraph v4.1.0-beta.01
5
 */
6
7
namespace Amenadiel\JpGraph\Graph\Scale;
8
9
use Amenadiel\JpGraph\Graph\Tick;
10
use Amenadiel\JpGraph\Util;
11
use function assert;
12
use function is_numeric;
13
use function round;
14
15
/**
16
 * @class LinearScale
17
 * // Description: Handle linear scaling between screen and world
18
 */
19
class LinearScale extends Scale
20
{
21
    public $textscale = false; // Just a flag to let the Plot class find out if
22
    // we are a textscale or not. This is a cludge since
23
    // this information is available in Graph::axtype but
24
    // we don't have access to the graph object in the Plots
25
    // stroke method. So we let graph store the status here
26
    // when the linear scale is created. A real cludge...
27
    public $type; // is this x or y scale ?
28
    public $ticks; // Store ticks
29
    public $text_scale_off = 0;
30
    public $scale_abs      = [0, 0];
31
    public $scale_factor; // Scale factor between world and screen
32
    public $off; // Offset between image edge and plot area
33
    public $scale      = [0, 0];
34
    public $name       = 'lin';
35
    public $auto_ticks = false; // When using manual scale should the ticks be automatically set?
36
    public $world_abs_size; // Plot area size in pixels (Needed public in jpgraph_radar.php)
37
    public $intscale         = false; // Restrict autoscale to integers
38
    protected $autoscale_min = false; // Forced minimum value, auto determine max
39
    protected $autoscale_max = false; // Forced maximum value, auto determine min
40
    private $gracetop        = 0;
41
    private $gracebottom     = 0;
42
43
    private $_world_size; // Plot area size in world coordinates
0 ignored issues
show
introduced by
The private property $_world_size is not used, and could be removed.
Loading history...
44
45
    public function __construct($aMin = 0, $aMax = 0, $aType = 'y', $subType = null)
46
    {
47
        assert($aType == 'x' || $aType == 'y');
48
        assert($aMin <= $aMax);
49
50
        $this->type       = $aType;
51
        $this->scale      = [$aMin, $aMax];
52
        $this->world_size = $aMax - $aMin;
53
        if ($subType === 'radar') {
54
            $this->ticks = new Tick\RadarLinearTicks();
55
            $this->ticks->SupressMinorTickMarks();
56
        } else {
57
            $this->ticks = new Tick\LinearTicks();
58
        }
59
    }
60
61
    // Check if scale is set or if we should autoscale
62
    // We should do this is either scale or ticks has not been set
63
    public function IsSpecified()
64
    {
65
        if ($this->GetMinVal() == $this->GetMaxVal()) {
66
            // Scale not set
67
            return false;
68
        }
69
70
        return true;
71
    }
72
73
    // Set the minimum data value when the autoscaling is used.
74
    // Usefull if you want a fix minimum (like 0) but have an
75
    // automatic maximum
76
    public function SetAutoMin($aMin)
77
    {
78
        $this->autoscale_min = $aMin;
79
    }
80
81
    // Set the minimum data value when the autoscaling is used.
82
    // Usefull if you want a fix minimum (like 0) but have an
83
    // automatic maximum
84
    public function SetAutoMax($aMax)
85
    {
86
        $this->autoscale_max = $aMax;
87
    }
88
89
    // If the user manually specifies a scale should the ticks
90
    // still be set automatically?
91
    public function SetAutoTicks($aFlag = true)
92
    {
93
        $this->auto_ticks = $aFlag;
94
    }
95
96
    // Specify scale "grace" value (top and bottom)
97
    public function SetGrace($aGraceTop, $aGraceBottom = 0)
98
    {
99
        if ($aGraceTop < 0 || $aGraceBottom < 0) {
100
            Util\JpGraphError::RaiseL(25069); //(" Grace must be larger then 0");
101
        }
102
        $this->gracetop    = $aGraceTop;
103
        $this->gracebottom = $aGraceBottom;
104
    }
105
106
107
108
    // Calculate autoscale. Used if user hasn't given a scale and ticks
109
    // $maxsteps is the maximum number of major tickmarks allowed.
110
    public function AutoScale($img, $min, $max, $maxsteps, $majend = true)
111
    {
112
        if (!is_numeric($min) || !is_numeric($max)) {
113
            Util\JpGraphError::Raise(25044);
114
        }
115
116
        if ($this->intscale) {
117
            $this->IntAutoScale($img, $min, $max, $maxsteps, $majend);
118
119
            return;
120
        }
121
        if (abs($min - $max) < 0.00001) {
122
            // We need some difference to be able to autoscale
123
            // make it 5% above and 5% below value
124
            if ($min == 0 && $max == 0) {
125
                // Special case
126
                $min = -1;
127
                $max = 1;
128
            } else {
129
                $delta = (abs($max) + abs($min)) * 0.005;
130
                $min -= $delta;
131
                $max += $delta;
132
            }
133
        }
134
135
        $gracetop    = ($this->gracetop / 100.0) * abs($max - $min);
136
        $gracebottom = ($this->gracebottom / 100.0) * abs($max - $min);
137
        if (is_numeric($this->autoscale_min)) {
0 ignored issues
show
introduced by
The condition is_numeric($this->autoscale_min) is always false.
Loading history...
138
            $min = $this->autoscale_min;
139
            if ($min >= $max) {
140
                Util\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.');
141
            }
142
            if (abs($min - $max) < 0.001) {
143
                $max *= 1.2;
144
            }
145
        }
146
147
        if (is_numeric($this->autoscale_max)) {
0 ignored issues
show
introduced by
The condition is_numeric($this->autoscale_max) is always false.
Loading history...
148
            $max = $this->autoscale_max;
149
            if ($min >= $max) {
150
                Util\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.');
151
            }
152
            if (abs($min - $max) < 0.001) {
153
                $min *= 0.8;
154
            }
155
        }
156
157
        $min -= $gracebottom;
158
        $max += $gracetop;
159
160
        // First get tickmarks as multiples of 0.1, 1, 10, ...
161
        if ($majend) {
162
            list($num1steps, $adj1min, $adj1max, $min1step, $maj1step) = $this->CalcTicks($maxsteps, $min, $max, 1, 2);
163
        } else {
164
            $adj1min                               = $min;
165
            $adj1max                               = $max;
166
            list($num1steps, $min1step, $maj1step) = $this->CalcTicksFreeze($maxsteps, $min, $max, 1, 2, false);
0 ignored issues
show
Unused Code introduced by
The call to Amenadiel\JpGraph\Graph\...cale::CalcTicksFreeze() has too many arguments starting with false. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

166
            /** @scrutinizer ignore-call */ 
167
            list($num1steps, $min1step, $maj1step) = $this->CalcTicksFreeze($maxsteps, $min, $max, 1, 2, false);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
167
        }
168
169
        // Then get tick marks as 2:s 0.2, 2, 20, ...
170
        if ($majend) {
171
            list($num2steps, $adj2min, $adj2max, $min2step, $maj2step) = $this->CalcTicks($maxsteps, $min, $max, 5, 2);
172
        } else {
173
            $adj2min                               = $min;
174
            $adj2max                               = $max;
175
            list($num2steps, $min2step, $maj2step) = $this->CalcTicksFreeze($maxsteps, $min, $max, 5, 2, false);
176
        }
177
178
        // Then get tickmarks as 5:s 0.05, 0.5, 5, 50, ...
179
        if ($majend) {
180
            list($num5steps, $adj5min, $adj5max, $min5step, $maj5step) = $this->CalcTicks($maxsteps, $min, $max, 2, 5);
181
        } else {
182
            $adj5min                               = $min;
183
            $adj5max                               = $max;
184
            list($num5steps, $min5step, $maj5step) = $this->CalcTicksFreeze($maxsteps, $min, $max, 2, 5, false);
185
        }
186
187
        // Check to see whichof 1:s, 2:s or 5:s fit better with
188
        // the requested number of major ticks
189
        $match1 = abs($num1steps - $maxsteps);
190
        $match2 = abs($num2steps - $maxsteps);
191
        $match5 = abs($num5steps - $maxsteps);
192
193
        // Compare these three values and see which is the closest match
194
        // We use a 0.8 weight to gravitate towards multiple of 5:s
195
        $r = $this->MatchMin3($match1, $match2, $match5, 0.8);
196
        switch ($r) {
197
            case 1:
198
                $this->Update($img, $adj1min, $adj1max);
199
                $this->ticks->Set($maj1step, $min1step);
200
201
                break;
202
            case 2:
203
                $this->Update($img, $adj2min, $adj2max);
204
                $this->ticks->Set($maj2step, $min2step);
205
206
                break;
207
            case 3:
208
                $this->Update($img, $adj5min, $adj5max);
209
                $this->ticks->Set($maj5step, $min5step);
210
211
                break;
212
        }
213
    }
214
215
216
217
    // Translate between world and screen
218
    public function Translate($aCoord)
219
    {
220
        if (!is_numeric($aCoord)) {
221
            if ($aCoord != '' && $aCoord != '-' && $aCoord != 'x') {
222
                Util\JpGraphError::RaiseL(25070); //('Your data contains non-numeric values.');
223
            }
224
225
            return 0;
226
        }
227
228
        return round($this->off + ($aCoord - $this->scale[0]) * $this->scale_factor);
229
    }
230
231
    // Relative translate (don't include offset) usefull when we just want
232
    // to know the relative position (in pixels) on the axis
233
    public function RelTranslate($aCoord)
234
    {
235
        if (!is_numeric($aCoord)) {
236
            if ($aCoord != '' && $aCoord != '-' && $aCoord != 'x') {
237
                Util\JpGraphError::RaiseL(25070); //('Your data contains non-numeric values.');
238
            }
239
240
            return 0;
241
        }
242
243
        return ($aCoord - $this->scale[0]) * $this->scale_factor;
244
    }
245
246
    // Restrict autoscaling to only use integers
247
    public function SetIntScale($aIntScale = true)
248
    {
249
        $this->intscale = $aIntScale;
250
    }
251
252
    // Determine the minimum of three values witha  weight for last value
253
    public function MatchMin3($a, $b, $c, $weight)
254
    {
255
        if ($a < $b) {
256
            if ($a < ($c * $weight)) {
257
                return 1; // $a smallest
258
            }
259
260
            return 3; // $c smallest
261
        }
262
        if ($b < ($c * $weight)) {
263
            return 2; // $b smallest
264
        }
265
266
        return 3; // $c smallest
267
    }
268
} // @class
269