Conditions | 67 |
Paths | > 20000 |
Total Lines | 390 |
Code Lines | 208 |
Lines | 0 |
Ratio | 0 % |
Tests | 142 |
CRAP Score | 188.81 |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.
There are several approaches to avoid long parameter lists:
1 | <?php |
||
425 | 2 | public function Pie3D( |
|
426 | $aaoption, |
||
427 | $img, |
||
428 | $data, |
||
429 | $colors, |
||
430 | $xc, |
||
431 | $yc, |
||
432 | $d, |
||
433 | $angle, |
||
434 | $z, |
||
435 | $shadow = 0.65, |
||
436 | $startangle = 0, |
||
437 | $edgecolor = '', |
||
438 | $edgeweight = 1 |
||
439 | ) { |
||
440 | /** |
||
441 | * As usual the algorithm get more complicated than I originally |
||
442 | * // envisioned. I believe that this is as simple as it is possible |
||
443 | * // to do it with the features I want. It's a good exercise to start |
||
444 | * // thinking on how to do this to convince your self that all this |
||
445 | * // is really needed for the general case. |
||
446 | * // |
||
447 | * // The algorithm two draw 3D pies without "real 3D" is done in |
||
448 | * // two steps. |
||
449 | * // First imagine the pie cut in half through a thought line between |
||
450 | * // 12'a clock and 6'a clock. It now easy to imagine that we can plot |
||
451 | * // the individual slices for each half by starting with the topmost |
||
452 | * // pie slice and continue down to 6'a clock. |
||
453 | * // |
||
454 | * // In the algortithm this is done in three principal steps |
||
455 | * // Step 1. Do the knife cut to ensure by splitting slices that extends |
||
456 | * // over the cut line. This is done by splitting the original slices into |
||
457 | * // upto 3 subslices. |
||
458 | * // Step 2. Find the top slice for each half |
||
459 | * // Step 3. Draw the slices from top to bottom |
||
460 | * // |
||
461 | * // The thing that slightly complicates this scheme with all the |
||
462 | * // angle comparisons below is that we can have an arbitrary start |
||
463 | * // angle so we must take into account the different equivalence classes. |
||
464 | * // For the same reason we must walk through the angle array in a |
||
465 | * // modulo fashion. |
||
466 | * // |
||
467 | * // Limitations of algorithm: |
||
468 | * // * A small exploded slice which crosses the 270 degree point |
||
469 | * // will get slightly nagged close to the center due to the fact that |
||
470 | * // we print the slices in Z-order and that the slice left part |
||
471 | * // get printed first and might get slightly nagged by a larger |
||
472 | * // slice on the right side just before the right part of the small |
||
473 | * // slice. Not a major problem though. |
||
474 | */ |
||
475 | // Determine the height of the ellippse which gives an |
||
476 | // indication of the inclination angle |
||
477 | 2 | $h = ($angle / 90.0) * $d; |
|
478 | 2 | $sum = 0; |
|
479 | 2 | for ($i = 0; $i < safe_count($data); ++$i) { |
|
480 | 2 | $sum += $data[$i]; |
|
481 | } |
||
482 | |||
483 | // Special optimization |
||
484 | 2 | if ($sum == 0) { |
|
485 | return; |
||
486 | } |
||
487 | |||
488 | 2 | if ($this->labeltype == 2) { |
|
489 | $this->adjusted_data = $this->AdjPercentage($data); |
||
490 | } |
||
491 | |||
492 | // Setup the start |
||
493 | 2 | $accsum = 0; |
|
494 | 2 | $a = $startangle; |
|
495 | 2 | $a = $this->NormAngle($a); |
|
496 | |||
497 | // |
||
498 | // Step 1 . Split all slices that crosses 90 or 270 |
||
499 | // |
||
500 | 2 | $idx = 0; |
|
501 | 2 | $adjexplode = []; |
|
502 | 2 | $numcolors = safe_count($colors); |
|
503 | 2 | for ($i = 0; $i < safe_count($data); ++$i, ++$idx) { |
|
504 | 2 | $da = $data[$i] / $sum * 360; |
|
505 | |||
506 | 2 | if (empty($this->explode_radius[$i])) { |
|
507 | 2 | $this->explode_radius[$i] = 0; |
|
508 | } |
||
509 | |||
510 | 2 | $expscale = 1; |
|
511 | 2 | if ($aaoption == 1) { |
|
512 | 2 | $expscale = 2; |
|
513 | } |
||
514 | |||
515 | 2 | $la = $a + $da / 2; |
|
516 | 2 | $explode = [$xc + $this->explode_radius[$i] * cos($la * M_PI / 180) * $expscale, |
|
517 | 2 | $yc - $this->explode_radius[$i] * sin($la * M_PI / 180) * ($h / $d) * $expscale, ]; |
|
518 | 2 | $adjexplode[$idx] = $explode; |
|
519 | 2 | $labeldata[$i] = [$la, $explode[0], $explode[1]]; |
|
520 | 2 | $originalangles[$i] = [$a, $a + $da]; |
|
521 | |||
522 | 2 | $ne = $this->NormAngle($a + $da); |
|
523 | 2 | if ($da <= 180) { |
|
524 | // If the slice size is <= 90 it can at maximum cut across |
||
525 | // one boundary (either 90 or 270) where it needs to be split |
||
526 | 2 | $split = -1; // no split |
|
527 | 2 | if (($da <= 90 && ($a <= 90 && $ne > 90)) || |
|
528 | 2 | (($da <= 180 && $da > 90) && (($a < 90 || $a >= 270) && $ne > 90))) { |
|
529 | 2 | $split = 90; |
|
530 | 2 | } elseif (($da <= 90 && ($a <= 270 && $ne > 270)) || |
|
531 | 2 | (($da <= 180 && $da > 90) && ($a >= 90 && $a < 270 && ($a + $da) > 270))) { |
|
532 | 2 | $split = 270; |
|
533 | } |
||
534 | 2 | if ($split > 0) { |
|
535 | // split in two |
||
536 | 2 | $angles[$idx] = [$a, $split]; |
|
537 | 2 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
|
538 | 2 | $adjexplode[$idx] = $explode; |
|
539 | 2 | $angles[++$idx] = [$split, $ne]; |
|
540 | 2 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
|
541 | 2 | $adjexplode[$idx] = $explode; |
|
542 | } else { |
||
543 | // no split |
||
544 | 2 | $angles[$idx] = [$a, $ne]; |
|
545 | 2 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
|
546 | 2 | $adjexplode[$idx] = $explode; |
|
547 | } |
||
548 | } else { |
||
549 | // da>180 |
||
550 | // Slice may, depending on position, cross one or two |
||
551 | // bonudaries |
||
552 | |||
553 | if ($a < 90) { |
||
554 | $split = 90; |
||
555 | } elseif ($a <= 270) { |
||
556 | $split = 270; |
||
557 | } else { |
||
558 | $split = 90; |
||
559 | } |
||
560 | |||
561 | $angles[$idx] = [$a, $split]; |
||
562 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||
563 | $adjexplode[$idx] = $explode; |
||
564 | //if( $a+$da > 360-$split ) { |
||
565 | // For slices larger than 270 degrees we might cross |
||
566 | // another boundary as well. This means that we must |
||
567 | // split the slice further. The comparison gets a little |
||
568 | // bit complicated since we must take into accound that |
||
569 | // a pie might have a startangle >0 and hence a slice might |
||
570 | // wrap around the 0 angle. |
||
571 | // Three cases: |
||
572 | // a) Slice starts before 90 and hence gets a split=90, but |
||
573 | // we must also check if we need to split at 270 |
||
574 | // b) Slice starts after 90 but before 270 and slices |
||
575 | // crosses 90 (after a wrap around of 0) |
||
576 | // c) If start is > 270 (hence the firstr split is at 90) |
||
577 | // and the slice is so large that it goes all the way |
||
578 | // around 270. |
||
579 | if (($a < 90 && ($a + $da > 270)) || ($a > 90 && $a <= 270 && ($a + $da > 360 + 90)) || ($a > 270 && $this->NormAngle($a + $da) > 270)) { |
||
580 | $angles[++$idx] = [$split, 360 - $split]; |
||
581 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||
582 | $adjexplode[$idx] = $explode; |
||
583 | $angles[++$idx] = [360 - $split, $ne]; |
||
584 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||
585 | $adjexplode[$idx] = $explode; |
||
586 | } else { |
||
587 | // Just a simple split to the previous decided |
||
588 | // angle. |
||
589 | $angles[++$idx] = [$split, $ne]; |
||
590 | $adjcolors[$idx] = $colors[$i % $numcolors]; |
||
591 | $adjexplode[$idx] = $explode; |
||
592 | } |
||
593 | } |
||
594 | 2 | $a += $da; |
|
595 | 2 | $a = $this->NormAngle($a); |
|
596 | } |
||
597 | |||
598 | // Total number of slices |
||
599 | 2 | $n = safe_count($angles); |
|
600 | |||
601 | 2 | for ($i = 0; $i < $n; ++$i) { |
|
602 | 2 | list($dbgs, $dbge) = $angles[$i]; |
|
603 | } |
||
604 | |||
605 | // |
||
606 | // Step 2. Find start index (first pie that starts in upper left quadrant) |
||
607 | // |
||
608 | 2 | $minval = $angles[0][0]; |
|
609 | 2 | $min = 0; |
|
610 | 2 | for ($i = 0; $i < $n; ++$i) { |
|
611 | 2 | if ($angles[$i][0] < $minval) { |
|
612 | $minval = $angles[$i][0]; |
||
613 | $min = $i; |
||
614 | } |
||
615 | } |
||
616 | 2 | $j = $min; |
|
617 | 2 | $cnt = 0; |
|
618 | 2 | while ($angles[$j][1] <= 90) { |
|
619 | 2 | ++$j; |
|
620 | 2 | if ($j >= $n) { |
|
621 | $j = 0; |
||
622 | } |
||
623 | 2 | if ($cnt > $n) { |
|
624 | Util\JpGraphError::RaiseL(14005); |
||
625 | //("Pie3D Internal error (#1). Trying to wrap twice when looking for start index"); |
||
626 | } |
||
627 | 2 | ++$cnt; |
|
628 | } |
||
629 | 2 | $start = $j; |
|
630 | |||
631 | // |
||
632 | // Step 3. Print slices in z-order |
||
633 | // |
||
634 | 2 | $cnt = 0; |
|
635 | |||
636 | // First stroke all the slices between 90 and 270 (left half circle) |
||
637 | // counterclockwise |
||
638 | |||
639 | 2 | while ($angles[$j][0] < 270 && $aaoption !== 2) { |
|
640 | 2 | list($x, $y) = $adjexplode[$j]; |
|
641 | |||
642 | 2 | $this->Pie3DSlice( |
|
643 | 2 | $img, |
|
644 | 2 | $x, |
|
645 | 2 | $y, |
|
646 | 2 | $d, |
|
647 | 2 | $h, |
|
648 | 2 | $angles[$j][0], |
|
649 | 2 | $angles[$j][1], |
|
650 | 2 | $z, |
|
651 | 2 | $adjcolors[$j], |
|
652 | 2 | $shadow |
|
653 | ); |
||
654 | |||
655 | 2 | $last = [$x, $y, $j]; |
|
656 | |||
657 | 2 | ++$j; |
|
658 | 2 | if ($j >= $n) { |
|
659 | $j = 0; |
||
660 | } |
||
661 | |||
662 | 2 | if ($cnt > $n) { |
|
663 | Util\JpGraphError::RaiseL(14006); |
||
664 | //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); |
||
665 | } |
||
666 | 2 | ++$cnt; |
|
667 | } |
||
668 | |||
669 | 2 | $slice_left = $n - $cnt; |
|
670 | 2 | $j = $start - 1; |
|
671 | 2 | if ($j < 0) { |
|
672 | $j = $n - 1; |
||
673 | } |
||
674 | |||
675 | 2 | $cnt = 0; |
|
676 | |||
677 | // The stroke all slices from 90 to -90 (right half circle) |
||
678 | // clockwise |
||
679 | 2 | while ($cnt < $slice_left && $aaoption !== 2) { |
|
680 | 2 | list($x, $y) = $adjexplode[$j]; |
|
681 | |||
682 | 2 | $this->Pie3DSlice( |
|
683 | 2 | $img, |
|
684 | 2 | $x, |
|
685 | 2 | $y, |
|
686 | 2 | $d, |
|
687 | 2 | $h, |
|
688 | 2 | $angles[$j][0], |
|
689 | 2 | $angles[$j][1], |
|
690 | 2 | $z, |
|
691 | 2 | $adjcolors[$j], |
|
692 | 2 | $shadow |
|
693 | ); |
||
694 | 2 | --$j; |
|
695 | 2 | if ($cnt > $n) { |
|
696 | Util\JpGraphError::RaiseL(14006); |
||
697 | //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); |
||
698 | } |
||
699 | 2 | if ($j < 0) { |
|
700 | 2 | $j = $n - 1; |
|
701 | } |
||
702 | |||
703 | 2 | ++$cnt; |
|
704 | } |
||
705 | |||
706 | // Now do a special thing. Stroke the last slice on the left |
||
707 | // halfcircle one more time. This is needed in the case where |
||
708 | // the slice close to 270 have been exploded. In that case the |
||
709 | // part of the slice close to the center of the pie might be |
||
710 | // slightly nagged. |
||
711 | 2 | if ($aaoption !== 2) { |
|
712 | 2 | $this->Pie3DSlice( |
|
713 | 2 | $img, |
|
714 | 2 | $last[0], |
|
715 | 2 | $last[1], |
|
716 | 2 | $d, |
|
717 | 2 | $h, |
|
718 | 2 | $angles[$last[2]][0], |
|
719 | 2 | $angles[$last[2]][1], |
|
720 | 2 | $z, |
|
721 | 2 | $adjcolors[$last[2]], |
|
722 | 2 | $shadow |
|
723 | ); |
||
724 | } |
||
725 | |||
726 | 2 | if ($aaoption !== 1) { |
|
727 | // Now print possible labels and add csim |
||
728 | 2 | $this->value->ApplyFont($img); |
|
729 | 2 | $margin = $img->GetFontHeight() / 2 + $this->value->margin; |
|
730 | 2 | for ($i = 0; $i < safe_count($data); ++$i) { |
|
731 | 2 | $la = $labeldata[$i][0]; |
|
732 | 2 | $x = $labeldata[$i][1] + cos($la * M_PI / 180) * ($d + $margin) * $this->ilabelposadj; |
|
733 | 2 | $y = $labeldata[$i][2] - sin($la * M_PI / 180) * ($h + $margin) * $this->ilabelposadj; |
|
734 | 2 | if ($this->ilabelposadj >= 1.0) { |
|
735 | 2 | if ($la > 180 && $la < 360) { |
|
736 | 2 | $y += $z; |
|
737 | } |
||
738 | } |
||
739 | 2 | if ($this->labeltype == 0) { |
|
740 | 2 | if ($sum > 0) { |
|
741 | 2 | $l = 100 * $data[$i] / $sum; |
|
742 | } else { |
||
743 | 2 | $l = 0; |
|
744 | } |
||
745 | } elseif ($this->labeltype == 1) { |
||
746 | $l = $data[$i]; |
||
747 | } else { |
||
748 | $l = $this->adjusted_data[$i]; |
||
749 | } |
||
750 | 2 | if (isset($this->labels[$i]) && is_string($this->labels[$i])) { |
|
751 | $l = sprintf($this->labels[$i], $l); |
||
752 | } |
||
753 | |||
754 | 2 | $this->StrokeLabels($l, $img, $labeldata[$i][0] * M_PI / 180, $x, $y, $z); |
|
755 | |||
756 | 2 | $this->Add3DSliceToCSIM( |
|
757 | 2 | $i, |
|
758 | 2 | $labeldata[$i][1], |
|
759 | 2 | $labeldata[$i][2], |
|
760 | 2 | $h * 2, |
|
761 | 2 | $d * 2, |
|
762 | 2 | $z, |
|
763 | 2 | $originalangles[$i][0], |
|
764 | 2 | $originalangles[$i][1] |
|
765 | ); |
||
766 | } |
||
767 | } |
||
768 | |||
769 | // |
||
770 | // Finally add potential lines in pie |
||
771 | // |
||
772 | |||
773 | 2 | if ($edgecolor == '' || $aaoption !== 0) { |
|
774 | 2 | return; |
|
775 | } |
||
776 | |||
777 | $accsum = 0; |
||
778 | $a = $startangle; |
||
779 | $a = $this->NormAngle($a); |
||
780 | |||
781 | $a *= M_PI / 180.0; |
||
782 | |||
783 | $idx = 0; |
||
784 | $img->PushColor($edgecolor); |
||
785 | $img->SetLineWeight($edgeweight); |
||
786 | |||
787 | $fulledge = true; |
||
788 | for ($i = 0; $i < safe_count($data) && $fulledge; ++$i) { |
||
789 | if (empty($this->explode_radius[$i])) { |
||
790 | $this->explode_radius[$i] = 0; |
||
791 | } |
||
792 | if ($this->explode_radius[$i] > 0) { |
||
793 | $fulledge = false; |
||
794 | } |
||
795 | } |
||
796 | |||
797 | for ($i = 0; $i < safe_count($data); ++$i, ++$idx) { |
||
798 | $da = $data[$i] / $sum * 2 * M_PI; |
||
799 | $this->StrokeFullSliceFrame( |
||
800 | $img, |
||
801 | $xc, |
||
802 | $yc, |
||
803 | $a, |
||
804 | $a + $da, |
||
805 | $d, |
||
806 | $h, |
||
807 | $z, |
||
808 | $edgecolor, |
||
809 | $this->explode_radius[$i], |
||
810 | $fulledge |
||
811 | ); |
||
812 | $a += $da; |
||
813 | } |
||
814 | $img->PopColor(); |
||
815 | } |
||
1079 |