HuasoFoundries /
jpgraph
| 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 PolarAxis |
||
| 14 | */ |
||
| 15 | class PolarAxis extends Axis |
||
| 16 | { |
||
| 17 | private $angle_step = 15; |
||
| 18 | private $angle_color = 'lightgray'; |
||
| 19 | private $angle_label_color = 'black'; |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 20 | private $angle_fontfam = FF_FONT1; |
||
| 21 | private $angle_fontstyle = FS_NORMAL; |
||
| 22 | private $angle_fontsize = 10; |
||
| 23 | private $angle_fontcolor = 'navy'; |
||
| 24 | private $gridminor_color = 'lightgray'; |
||
| 25 | private $gridmajor_color = 'lightgray'; |
||
| 26 | private $show_minor_grid = false; |
||
| 27 | private $show_major_grid = true; |
||
| 28 | private $show_angle_mark = true; |
||
| 29 | private $show_angle_grid = true; |
||
| 30 | private $show_angle_label = true; |
||
| 31 | private $angle_tick_len = 3; |
||
| 32 | private $angle_tick_len2 = 3; |
||
| 33 | private $angle_tick_color = 'black'; |
||
| 34 | private $show_angle_tick = true; |
||
| 35 | private $radius_tick_color = 'black'; |
||
| 36 | |||
| 37 | public function __construct($img, $aScale) |
||
| 38 | { |
||
| 39 | parent::__construct($img, $aScale); |
||
| 40 | } |
||
| 41 | |||
| 42 | public function ShowAngleDegreeMark($aFlg = true) |
||
| 43 | { |
||
| 44 | $this->show_angle_mark = $aFlg; |
||
| 45 | } |
||
| 46 | |||
| 47 | public function SetAngleStep($aStep) |
||
| 48 | { |
||
| 49 | $this->angle_step = $aStep; |
||
| 50 | } |
||
| 51 | |||
| 52 | public function HideTicks($aFlg = true, $aAngleFlg = true) |
||
| 53 | { |
||
| 54 | parent::HideTicks($aFlg, $aFlg); |
||
| 55 | $this->show_angle_tick = !$aAngleFlg; |
||
| 56 | } |
||
| 57 | |||
| 58 | public function ShowAngleLabel($aFlg = true) |
||
| 59 | { |
||
| 60 | $this->show_angle_label = $aFlg; |
||
| 61 | } |
||
| 62 | |||
| 63 | public function ShowGrid($aMajor = true, $aMinor = false, $aAngle = true) |
||
| 64 | { |
||
| 65 | $this->show_minor_grid = $aMinor; |
||
| 66 | $this->show_major_grid = $aMajor; |
||
| 67 | $this->show_angle_grid = $aAngle; |
||
| 68 | } |
||
| 69 | |||
| 70 | public function SetAngleFont($aFontFam, $aFontStyle = FS_NORMAL, $aFontSize = 10) |
||
| 71 | { |
||
| 72 | $this->angle_fontfam = $aFontFam; |
||
| 73 | $this->angle_fontstyle = $aFontStyle; |
||
| 74 | $this->angle_fontsize = $aFontSize; |
||
| 75 | } |
||
| 76 | |||
| 77 | public function SetColor($aColor, $aRadColor = '', $aAngleColor = '') |
||
| 78 | { |
||
| 79 | if ($aAngleColor == '') { |
||
| 80 | $aAngleColor = $aColor; |
||
| 81 | } |
||
| 82 | |||
| 83 | parent::SetColor($aColor, $aRadColor); |
||
| 84 | $this->angle_fontcolor = $aAngleColor; |
||
| 85 | } |
||
| 86 | |||
| 87 | public function SetGridColor($aMajorColor, $aMinorColor = '', $aAngleColor = '') |
||
| 88 | { |
||
| 89 | if ($aMinorColor == '') { |
||
| 90 | $aMinorColor = $aMajorColor; |
||
| 91 | } |
||
| 92 | |||
| 93 | if ($aAngleColor == '') { |
||
| 94 | $aAngleColor = $aMajorColor; |
||
| 95 | } |
||
| 96 | |||
| 97 | $this->gridminor_color = $aMinorColor; |
||
| 98 | $this->gridmajor_color = $aMajorColor; |
||
| 99 | $this->angle_color = $aAngleColor; |
||
| 100 | } |
||
| 101 | |||
| 102 | public function SetTickColors($aRadColor, $aAngleColor = '') |
||
| 103 | { |
||
| 104 | $this->radius_tick_color = $aRadColor; |
||
| 105 | $this->angle_tick_color = $aAngleColor; |
||
| 106 | } |
||
| 107 | |||
| 108 | // Private methods |
||
| 109 | public function StrokeGrid($pos) |
||
| 110 | { |
||
| 111 | $x = round($this->img->left_margin + $this->img->plotwidth / 2); |
||
| 112 | $this->scale->ticks->Stroke($this->img, $this->scale, $pos); |
||
| 113 | |||
| 114 | // Stroke the minor arcs |
||
| 115 | $pmin = []; |
||
| 116 | $p = $this->scale->ticks->ticks_pos; |
||
| 117 | $n = safe_count($p); |
||
| 118 | $i = 0; |
||
| 119 | $this->img->SetColor($this->gridminor_color); |
||
| 120 | while ($i < $n) { |
||
| 121 | $r = $p[$i] - $x + 1; |
||
| 122 | $pmin[] = $r; |
||
| 123 | if ($this->show_minor_grid) { |
||
| 124 | $this->img->Circle($x, $pos, $r); |
||
| 125 | } |
||
| 126 | ++$i; |
||
| 127 | } |
||
| 128 | |||
| 129 | $limit = max($this->img->plotwidth, $this->img->plotheight) * 1.4; |
||
| 130 | while ($r < $limit) { |
||
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
| 131 | $off = $r; |
||
| 132 | $i = 1; |
||
| 133 | $r = $off + round($p[$i] - $x + 1); |
||
| 134 | while ($r < $limit && $i < $n) { |
||
| 135 | $r = $off + $p[$i] - $x; |
||
| 136 | $pmin[] = $r; |
||
| 137 | if ($this->show_minor_grid) { |
||
| 138 | $this->img->Circle($x, $pos, $r); |
||
| 139 | } |
||
| 140 | ++$i; |
||
| 141 | } |
||
| 142 | } |
||
| 143 | |||
| 144 | // Stroke the major arcs |
||
| 145 | if ($this->show_major_grid) { |
||
| 146 | // First determine how many minor step on |
||
| 147 | // every major step. We have recorded the minor radius |
||
| 148 | // in pmin and use these values. This is done in order |
||
| 149 | // to avoid rounding errors if we were to recalculate the |
||
| 150 | // different major radius. |
||
| 151 | $pmaj = $this->scale->ticks->maj_ticks_pos; |
||
| 152 | $p = $this->scale->ticks->ticks_pos; |
||
| 153 | if ($this->scale->name == 'lin') { |
||
| 154 | $step = round(($pmaj[1] - $pmaj[0]) / ($p[1] - $p[0])); |
||
| 155 | } else { |
||
| 156 | $step = 9; |
||
| 157 | } |
||
| 158 | $n = round(safe_count($pmin) / $step); |
||
| 159 | $i = 0; |
||
|
0 ignored issues
–
show
|
|||
| 160 | $this->img->SetColor($this->gridmajor_color); |
||
| 161 | $limit = max($this->img->plotwidth, $this->img->plotheight) * 1.4; |
||
| 162 | $off = $r; |
||
|
0 ignored issues
–
show
|
|||
| 163 | $i = 0; |
||
| 164 | $r = $pmin[$i * $step]; |
||
| 165 | while ($r < $limit && $i < $n) { |
||
| 166 | $r = $pmin[$i * $step]; |
||
| 167 | $this->img->Circle($x, $pos, $r); |
||
| 168 | ++$i; |
||
| 169 | } |
||
| 170 | } |
||
| 171 | |||
| 172 | // Draw angles |
||
| 173 | if ($this->show_angle_grid) { |
||
| 174 | $this->img->SetColor($this->angle_color); |
||
| 175 | $d = max($this->img->plotheight, $this->img->plotwidth) * 1.4; |
||
| 176 | $a = 0; |
||
| 177 | $p = $this->scale->ticks->ticks_pos; |
||
| 178 | $start_radius = $p[1] - $x; |
||
| 179 | while ($a < 360) { |
||
| 180 | if ($a == 90 || $a == 270) { |
||
| 181 | // Make sure there are no rounding problem with |
||
| 182 | // exactly vertical lines |
||
| 183 | $this->img->Line( |
||
| 184 | $x + $start_radius * cos($a / 180 * M_PI) + 1, |
||
| 185 | $pos - $start_radius * sin($a / 180 * M_PI), |
||
| 186 | $x + $start_radius * cos($a / 180 * M_PI) + 1, |
||
| 187 | $pos - $d * sin($a / 180 * M_PI) |
||
| 188 | ); |
||
| 189 | } else { |
||
| 190 | $this->img->Line( |
||
| 191 | $x + $start_radius * cos($a / 180 * M_PI) + 1, |
||
| 192 | $pos - $start_radius * sin($a / 180 * M_PI), |
||
| 193 | $x + $d * cos($a / 180 * M_PI), |
||
| 194 | $pos - $d * sin($a / 180 * M_PI) |
||
| 195 | ); |
||
| 196 | } |
||
| 197 | $a += $this->angle_step; |
||
| 198 | } |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | public function StrokeAngleLabels($pos, $type) |
||
| 203 | { |
||
| 204 | if (!$this->show_angle_label) { |
||
| 205 | return; |
||
| 206 | } |
||
| 207 | |||
| 208 | $x0 = round($this->img->left_margin + $this->img->plotwidth / 2) + 1; |
||
| 209 | |||
| 210 | $d = max($this->img->plotwidth, $this->img->plotheight) * 1.42; |
||
| 211 | $a = $this->angle_step; |
||
| 212 | $t = new Text\Text(); |
||
| 213 | $t->SetColor($this->angle_fontcolor); |
||
| 214 | $t->SetFont($this->angle_fontfam, $this->angle_fontstyle, $this->angle_fontsize); |
||
| 215 | $xright = $this->img->width - $this->img->right_margin; |
||
| 216 | $ytop = $this->img->top_margin; |
||
| 217 | $xleft = $this->img->left_margin; |
||
| 218 | $ybottom = $this->img->height - $this->img->bottom_margin; |
||
| 219 | $ha = 'left'; |
||
| 220 | $va = 'center'; |
||
| 221 | $w = $this->img->plotwidth / 2; |
||
| 222 | $h = $this->img->plotheight / 2; |
||
| 223 | $xt = $x0; |
||
| 224 | $yt = $pos; |
||
| 225 | $margin = 5; |
||
| 226 | |||
| 227 | $tl = $this->angle_tick_len; // Outer len |
||
| 228 | $tl2 = $this->angle_tick_len2; // Interior len |
||
| 229 | |||
| 230 | $this->img->SetColor($this->angle_tick_color); |
||
| 231 | $rot90 = $this->img->a == 90; |
||
| 232 | |||
| 233 | if ($type == POLAR_360) { |
||
| 234 | // Corner angles of the four corners |
||
| 235 | $ca1 = atan($h / $w) / M_PI * 180; |
||
| 236 | $ca2 = 180 - $ca1; |
||
| 237 | $ca3 = $ca1 + 180; |
||
| 238 | $ca4 = 360 - $ca1; |
||
| 239 | $end = 360; |
||
| 240 | |||
| 241 | while ($a < $end) { |
||
| 242 | $ca = cos($a / 180 * M_PI); |
||
| 243 | $sa = sin($a / 180 * M_PI); |
||
| 244 | $x = $d * $ca; |
||
| 245 | $y = $d * $sa; |
||
| 246 | $xt = 1000; |
||
| 247 | $yt = 1000; |
||
| 248 | if ($a <= $ca1 || $a >= $ca4) { |
||
| 249 | $yt = $pos - $w * $y / $x; |
||
| 250 | $xt = $xright + $margin; |
||
| 251 | if ($rot90) { |
||
| 252 | $ha = 'center'; |
||
| 253 | $va = 'top'; |
||
| 254 | } else { |
||
| 255 | $ha = 'left'; |
||
| 256 | $va = 'center'; |
||
| 257 | } |
||
| 258 | $x1 = $xright - $tl2; |
||
| 259 | $x2 = $xright + $tl; |
||
| 260 | $y1 = $y2 = $yt; |
||
| 261 | } elseif ($a > $ca1 && $a < $ca2) { |
||
| 262 | $xt = $x0 + $h * $x / $y; |
||
| 263 | $yt = $ytop - $margin; |
||
| 264 | if ($rot90) { |
||
| 265 | $ha = 'left'; |
||
| 266 | $va = 'center'; |
||
| 267 | } else { |
||
| 268 | $ha = 'center'; |
||
| 269 | $va = 'bottom'; |
||
| 270 | } |
||
| 271 | $y1 = $ytop + $tl2; |
||
| 272 | $y2 = $ytop - $tl; |
||
| 273 | $x1 = $x2 = $xt; |
||
| 274 | } elseif ($a >= $ca2 && $a <= $ca3) { |
||
| 275 | $yt = $pos + $w * $y / $x; |
||
| 276 | $xt = $xleft - $margin; |
||
| 277 | if ($rot90) { |
||
| 278 | $ha = 'center'; |
||
| 279 | $va = 'bottom'; |
||
| 280 | } else { |
||
| 281 | $ha = 'right'; |
||
| 282 | $va = 'center'; |
||
| 283 | } |
||
| 284 | $x1 = $xleft + $tl2; |
||
| 285 | $x2 = $xleft - $tl; |
||
| 286 | $y1 = $y2 = $yt; |
||
| 287 | } else { |
||
| 288 | $xt = $x0 - $h * $x / $y; |
||
| 289 | $yt = $ybottom + $margin; |
||
| 290 | if ($rot90) { |
||
| 291 | $ha = 'right'; |
||
| 292 | $va = 'center'; |
||
| 293 | } else { |
||
| 294 | $ha = 'center'; |
||
| 295 | $va = 'top'; |
||
| 296 | } |
||
| 297 | $y1 = $ybottom - $tl2; |
||
| 298 | $y2 = $ybottom + $tl; |
||
| 299 | $x1 = $x2 = $xt; |
||
| 300 | } |
||
| 301 | if ($a != 0 && $a != 180) { |
||
| 302 | $t->Align($ha, $va); |
||
| 303 | if ($this->scale->clockwise) { |
||
| 304 | $t->Set(360 - $a); |
||
| 305 | } else { |
||
| 306 | $t->Set($a); |
||
| 307 | } |
||
| 308 | if ($this->show_angle_mark && $t->font_family > 4) { |
||
| 309 | $a .= SymChar::Get('degree'); |
||
| 310 | } |
||
| 311 | $t->Stroke($this->img, $xt, $yt); |
||
| 312 | if ($this->show_angle_tick) { |
||
| 313 | $this->img->Line($x1, $y1, $x2, $y2); |
||
| 314 | } |
||
| 315 | } |
||
| 316 | $a += $this->angle_step; |
||
| 317 | } |
||
| 318 | } else { |
||
| 319 | // POLAR_HALF |
||
| 320 | $ca1 = atan($h / $w * 2) / M_PI * 180; |
||
| 321 | $ca2 = 180 - $ca1; |
||
| 322 | $end = 180; |
||
| 323 | while ($a < $end) { |
||
| 324 | $ca = cos($a / 180 * M_PI); |
||
| 325 | $sa = sin($a / 180 * M_PI); |
||
| 326 | $x = $d * $ca; |
||
| 327 | $y = $d * $sa; |
||
| 328 | if ($a <= $ca1) { |
||
| 329 | $yt = $pos - $w * $y / $x; |
||
| 330 | $xt = $xright + $margin; |
||
| 331 | if ($rot90) { |
||
| 332 | $ha = 'center'; |
||
| 333 | $va = 'top'; |
||
| 334 | } else { |
||
| 335 | $ha = 'left'; |
||
| 336 | $va = 'center'; |
||
| 337 | } |
||
| 338 | $x1 = $xright - $tl2; |
||
| 339 | $x2 = $xright + $tl; |
||
| 340 | $y1 = $y2 = $yt; |
||
| 341 | } elseif ($a > $ca1 && $a < $ca2) { |
||
| 342 | $xt = $x0 + 2 * $h * $x / $y; |
||
| 343 | $yt = $ytop - $margin; |
||
| 344 | if ($rot90) { |
||
| 345 | $ha = 'left'; |
||
| 346 | $va = 'center'; |
||
| 347 | } else { |
||
| 348 | $ha = 'center'; |
||
| 349 | $va = 'bottom'; |
||
| 350 | } |
||
| 351 | $y1 = $ytop + $tl2; |
||
| 352 | $y2 = $ytop - $tl; |
||
| 353 | $x1 = $x2 = $xt; |
||
| 354 | } elseif ($a >= $ca2) { |
||
| 355 | $yt = $pos + $w * $y / $x; |
||
| 356 | $xt = $xleft - $margin; |
||
| 357 | if ($rot90) { |
||
| 358 | $ha = 'center'; |
||
| 359 | $va = 'bottom'; |
||
| 360 | } else { |
||
| 361 | $ha = 'right'; |
||
| 362 | $va = 'center'; |
||
| 363 | } |
||
| 364 | $x1 = $xleft + $tl2; |
||
| 365 | $x2 = $xleft - $tl; |
||
| 366 | $y1 = $y2 = $yt; |
||
| 367 | } |
||
| 368 | $t->Align($ha, $va); |
||
| 369 | if ($this->show_angle_mark && $t->font_family > 4) { |
||
| 370 | $a .= SymChar::Get('degree'); |
||
| 371 | } |
||
| 372 | $t->Set($a); |
||
| 373 | $t->Stroke($this->img, $xt, $yt); |
||
| 374 | if ($this->show_angle_tick) { |
||
| 375 | $this->img->Line($x1, $y1, $x2, $y2); |
||
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
| 376 | } |
||
| 377 | $a += $this->angle_step; |
||
| 378 | } |
||
| 379 | } |
||
| 380 | } |
||
| 381 | |||
| 382 | public function Stroke($pos, $dummy = true) |
||
| 383 | { |
||
| 384 | $this->img->SetLineWeight($this->weight); |
||
| 385 | $this->img->SetColor($this->color); |
||
| 386 | $this->img->SetFont($this->font_family, $this->font_style, $this->font_size); |
||
| 387 | if (!$this->hide_line) { |
||
| 388 | $this->img->FilledRectangle( |
||
| 389 | $this->img->left_margin, |
||
| 390 | $pos, |
||
| 391 | $this->img->width - $this->img->right_margin, |
||
| 392 | $pos + $this->weight - 1 |
||
| 393 | ); |
||
| 394 | } |
||
| 395 | $y = $pos + $this->img->GetFontHeight() + $this->title_margin + $this->title->margin; |
||
| 396 | if ($this->title_adjust == 'high') { |
||
| 397 | $this->title->SetPos($this->img->width - $this->img->right_margin, $y, 'right', 'top'); |
||
| 398 | } elseif ($this->title_adjust == 'middle' || $this->title_adjust == 'center') { |
||
| 399 | $this->title->SetPos( |
||
| 400 | ($this->img->width - $this->img->left_margin - $this->img->right_margin) / 2 + $this->img->left_margin, |
||
| 401 | $y, |
||
| 402 | 'center', |
||
| 403 | 'top' |
||
| 404 | ); |
||
| 405 | } elseif ($this->title_adjust == 'low') { |
||
| 406 | $this->title->SetPos($this->img->left_margin, $y, 'left', 'top'); |
||
| 407 | } else { |
||
| 408 | Util\JpGraphError::RaiseL(17002, $this->title_adjust); |
||
| 409 | //('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')'); |
||
| 410 | } |
||
| 411 | |||
| 412 | if (!$this->hide_labels) { |
||
| 413 | $this->StrokeLabels($pos, false); |
||
| 414 | } |
||
| 415 | $this->img->SetColor($this->radius_tick_color); |
||
| 416 | $this->scale->ticks->Stroke($this->img, $this->scale, $pos); |
||
| 417 | |||
| 418 | // |
||
| 419 | // Mirror the positions for the left side of the scale |
||
| 420 | // |
||
| 421 | $mid = 2 * ($this->img->left_margin + $this->img->plotwidth / 2); |
||
| 422 | $n = safe_count($this->scale->ticks->ticks_pos); |
||
| 423 | $i = 0; |
||
| 424 | while ($i < $n) { |
||
| 425 | $this->scale->ticks->ticks_pos[$i] = |
||
| 426 | $mid - $this->scale->ticks->ticks_pos[$i]; |
||
| 427 | ++$i; |
||
| 428 | } |
||
| 429 | |||
| 430 | $n = safe_count($this->scale->ticks->maj_ticks_pos); |
||
| 431 | $i = 0; |
||
| 432 | while ($i < $n) { |
||
| 433 | $this->scale->ticks->maj_ticks_pos[$i] = |
||
| 434 | $mid - $this->scale->ticks->maj_ticks_pos[$i]; |
||
| 435 | ++$i; |
||
| 436 | } |
||
| 437 | |||
| 438 | $n = safe_count($this->scale->ticks->maj_ticklabels_pos); |
||
| 439 | $i = 1; |
||
| 440 | while ($i < $n) { |
||
| 441 | $this->scale->ticks->maj_ticklabels_pos[$i] = |
||
| 442 | $mid - $this->scale->ticks->maj_ticklabels_pos[$i]; |
||
| 443 | ++$i; |
||
| 444 | } |
||
| 445 | |||
| 446 | // Draw the left side of the scale |
||
| 447 | $n = safe_count($this->scale->ticks->ticks_pos); |
||
| 448 | $yu = $pos - $this->scale->ticks->direction * $this->scale->ticks->GetMinTickAbsSize(); |
||
| 449 | |||
| 450 | // Minor ticks |
||
| 451 | if (!$this->scale->ticks->supress_minor_tickmarks) { |
||
| 452 | $i = 1; |
||
| 453 | while ($i < $n / 2) { |
||
| 454 | $x = round($this->scale->ticks->ticks_pos[$i]); |
||
| 455 | $this->img->Line($x, $pos, $x, $yu); |
||
| 456 | ++$i; |
||
| 457 | } |
||
| 458 | } |
||
| 459 | |||
| 460 | $n = safe_count($this->scale->ticks->maj_ticks_pos); |
||
| 461 | $yu = $pos - $this->scale->ticks->direction * $this->scale->ticks->GetMajTickAbsSize(); |
||
| 462 | |||
| 463 | // Major ticks |
||
| 464 | if (!$this->scale->ticks->supress_tickmarks) { |
||
| 465 | $i = 1; |
||
| 466 | while ($i < $n / 2) { |
||
| 467 | $x = round($this->scale->ticks->maj_ticks_pos[$i]); |
||
| 468 | $this->img->Line($x, $pos, $x, $yu); |
||
| 469 | ++$i; |
||
| 470 | } |
||
| 471 | } |
||
| 472 | if (!$this->hide_labels) { |
||
| 473 | $this->StrokeLabels($pos, false); |
||
| 474 | } |
||
| 475 | $this->title->Stroke($this->img); |
||
| 476 | } |
||
| 477 | } |
||
| 478 |