Issues (459)

src/graph/WindrosePlotScale.php (1 issue)

1
<?php
2
3
/**
4
 * JPGraph v4.0.3
5
 */
6
7
namespace Amenadiel\JpGraph\Graph;
8
9
use Amenadiel\JpGraph\Text;
10
use Amenadiel\JpGraph\Util;
11
12
/**
13
 * @class WindrosePlotScale
14
 */
15
class WindrosePlotScale
16
{
17
    private $iMax;
18
    private $iDelta          = 5;
19
    private $iNumCirc        = 3;
20
    public $iMaxNum          = 0;
21
    private $iLblFmt         = '%.0f%%';
22
    public $iFontFamily      = FF_VERDANA;
23
    public $iFontStyle       = FS_NORMAL;
24
    public $iFontSize        = 10;
25
    public $iZFontFamily     = FF_ARIAL;
26
    public $iZFontStyle      = FS_NORMAL;
27
    public $iZFontSize       = 10;
28
    public $iFontColor       = 'black';
29
    public $iZFontColor      = 'black';
30
    private $iFontFrameColor = false;
31
    private $iFontBkgColor   = false;
32
    private $iLblZeroTxt;
33
    private $iLblAlign    = LBLALIGN_CENTER;
34
    public $iAngle        = 'auto';
35
    private $iManualScale = false;
36
    private $iHideLabels  = false;
37
38
    public function __construct($aData)
39
    {
40
        $max            = 0;
41
        $totlegsum      = 0;
42
        $maxnum         = 0;
43
        $this->iZeroSum = 0;
44
        foreach ($aData as $idx => $legdata) {
45
            $legsum = array_sum($legdata);
46
            $maxnum = max($maxnum, safe_count($legdata) - 1);
47
            $max    = max($legsum - $legdata[0], $max);
48
            $totlegsum += $legsum;
49
            $this->iZeroSum += $legdata[0];
50
        }
51
        if (round($totlegsum) > 100) {
52
            Util\JpGraphError::RaiseL(22001, $legsum);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $legsum seems to be defined by a foreach iteration on line 44. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
53
            //("Total percentage for all windrose legs in a windrose plot can not exceed  100% !\n(Current max is: ".$legsum.')');
54
        }
55
        $this->iMax     = $max;
56
        $this->iMaxNum  = $maxnum;
57
        $this->iNumCirc = $this->GetNumCirc();
58
        $this->iMaxVal  = $this->iNumCirc * $this->iDelta;
59
    }
60
61
    // Return number of grid circles
62
    public function GetNumCirc()
63
    {
64
        // Never return less than 1 circles
65
        $num = ceil($this->iMax / $this->iDelta);
66
67
        return max(1, $num);
68
    }
69
70
    public function SetMaxValue($aMax)
71
    {
72
        $this->iMax     = $aMax;
73
        $this->iNumCirc = $this->GetNumCirc();
74
        $this->iMaxVal  = $this->iNumCirc * $this->iDelta;
75
    }
76
77
    // Set step size for circular grid
78
    public function Set($aMax, $aDelta = null)
79
    {
80
        if ($aDelta == null) {
81
            $this->SetMaxValue($aMax);
82
83
            return;
84
        }
85
        $this->iDelta   = $aDelta;
86
        $this->iNumCirc = ceil($aMax / $aDelta); //$this->GetNumCirc();
87
        $this->iMaxVal  = $this->iNumCirc * $this->iDelta;
88
        $this->iMax     = $aMax;
89
        // Remember that user has specified interval so don't
90
        // do autoscaling
91
        $this->iManualScale = true;
92
    }
93
94
    public function AutoScale($aRadius, $aMinDist = 30)
95
    {
96
        if ($this->iManualScale) {
97
            return;
98
        }
99
100
        // Make sure distance (in pixels) between two circles
101
        // is never less than $aMinDist pixels
102
        $tst = ceil($aRadius / $this->iNumCirc);
103
104
        while ($tst <= $aMinDist && $this->iDelta < 100) {
105
            $this->iDelta += 5;
106
            $tst = ceil($aRadius / $this->GetNumCirc());
107
        }
108
109
        if ($this->iDelta >= 100) {
110
            Util\JpGraphError::RaiseL(22002); //('Graph is too small to have a scale. Please make the graph larger.');
111
        }
112
113
        // If the distance is to large try with multiples of 2 instead
114
        if ($tst > $aMinDist * 3) {
115
            $this->iDelta = 2;
116
            $tst          = ceil($aRadius / $this->iNumCirc);
117
118
            while ($tst <= $aMinDist && $this->iDelta < 100) {
119
                $this->iDelta += 2;
120
                $tst = ceil($aRadius / $this->GetNumCirc());
121
            }
122
123
            if ($this->iDelta >= 100) {
124
                Util\JpGraphError::RaiseL(22002); //('Graph is too small to have a scale. Please make the graph larger.');
125
            }
126
        }
127
128
        $this->iNumCirc = $this->GetNumCirc();
129
        $this->iMaxVal  = $this->iNumCirc * $this->iDelta;
130
    }
131
132
    // Return max of all leg values
133
    public function GetMax()
134
    {
135
        return $this->iMax;
136
    }
137
138
    public function Hide($aFlg = true)
139
    {
140
        $this->iHideLabels = $aFlg;
141
    }
142
143
    public function SetAngle($aAngle)
144
    {
145
        $this->iAngle = $aAngle;
146
    }
147
148
    // Translate a Leg value to radius distance
149
    public function RelTranslate($aVal, $r, $ri)
150
    {
151
        $tv = round($aVal / $this->iMaxVal * ($r - $ri));
152
153
        return $tv;
154
    }
155
156
    public function SetLabelAlign($aAlign)
157
    {
158
        $this->iLblAlign = $aAlign;
159
    }
160
161
    public function SetLabelFormat($aFmt)
162
    {
163
        $this->iLblFmt = $aFmt;
164
    }
165
166
    public function SetLabelFillColor($aBkgColor, $aBorderColor = false)
167
    {
168
        $this->iFontBkgColor = $aBkgColor;
169
        if ($aBorderColor === false) {
170
            $this->iFontFrameColor = $aBkgColor;
171
        } else {
172
            $this->iFontFrameColor = $aBorderColor;
173
        }
174
    }
175
176
    public function SetFontColor($aColor)
177
    {
178
        $this->iFontColor  = $aColor;
179
        $this->iZFontColor = $aColor;
180
    }
181
182
    public function SetFont($aFontFamily, $aFontStyle = FS_NORMAL, $aFontSize = 10)
183
    {
184
        $this->iFontFamily = $aFontFamily;
185
        $this->iFontStyle  = $aFontStyle;
186
        $this->iFontSize   = $aFontSize;
187
        $this->SetZFont($aFontFamily, $aFontStyle, $aFontSize);
188
    }
189
190
    public function SetZFont($aFontFamily, $aFontStyle = FS_NORMAL, $aFontSize = 10)
191
    {
192
        $this->iZFontFamily = $aFontFamily;
193
        $this->iZFontStyle  = $aFontStyle;
194
        $this->iZFontSize   = $aFontSize;
195
    }
196
197
    public function SetZeroLabel($aTxt)
198
    {
199
        $this->iLblZeroTxt = $aTxt;
200
    }
201
202
    public function SetZFontColor($aColor)
203
    {
204
        $this->iZFontColor = $aColor;
205
    }
206
207
    public function StrokeLabels($aImg, $xc, $yc, $ri, $rr)
208
    {
209
        if ($this->iHideLabels) {
210
            return;
211
        }
212
213
        // Setup some convinient vairables
214
        $a = $this->iAngle * M_PI / 180.0;
215
        $n = $this->iNumCirc;
216
        $d = $this->iDelta;
217
218
        // Setup the font and font color
219
        $val = new Text\Text();
220
        $val->SetFont($this->iFontFamily, $this->iFontStyle, $this->iFontSize);
221
        $val->SetColor($this->iFontColor);
222
223
        if ($this->iFontBkgColor !== false) {
224
            $val->SetBox($this->iFontBkgColor, $this->iFontFrameColor);
225
        }
226
227
        // Position the labels relative to the radiant circles
228
        if ($this->iLblAlign == LBLALIGN_TOP) {
229
            if ($a > 0 && $a <= M_PI / 2) {
230
                $val->SetAlign('left', 'bottom');
231
            } elseif ($a > M_PI / 2 && $a <= M_PI) {
232
                $val->SetAlign('right', 'bottom');
233
            }
234
        } elseif ($this->iLblAlign == LBLALIGN_CENTER) {
235
            $val->SetAlign('center', 'center');
236
        }
237
238
        // Stroke the labels close to each circle
239
        $v  = $d;
240
        $si = sin($a);
241
        $co = cos($a);
242
        for ($i = 0; $i < $n; ++$i, $v += $d) {
243
            $r = $ri + ($i + 1) * $rr;
244
            $x = $xc + $co * $r;
245
            $y = $yc - $si * $r;
246
            $val->Set(sprintf($this->iLblFmt, $v));
247
            $val->Stroke($aImg, $x, $y);
248
        }
249
250
        // Print the text in the zero circle
251
        if ($this->iLblZeroTxt === null) {
252
            $this->iLblZeroTxt = sprintf($this->iLblFmt, $this->iZeroSum);
253
        } else {
254
            $this->iLblZeroTxt = sprintf($this->iLblZeroTxt, $this->iZeroSum);
255
        }
256
257
        $val->Set($this->iLblZeroTxt);
258
        $val->SetAlign('center', 'center');
259
        $val->SetParagraphAlign('center');
260
        $val->SetColor($this->iZFontColor);
261
        $val->SetFont($this->iZFontFamily, $this->iZFontStyle, $this->iZFontSize);
262
        $val->Stroke($aImg, $xc, $yc);
263
    }
264
}
265