pIndicator   C
last analyzed

Complexity

Total Complexity 62

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%
Metric Value
dl 0
loc 215
ccs 0
cts 180
cp 0
rs 5.9493
wmc 62
lcom 1
cbo 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A pIndicator() 0 4 1
F draw() 0 203 61

How to fix   Complexity   

Complex Class

Complex classes like pIndicator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use pIndicator, and based on these observations, apply Extract Interface, too.

1
<?php
2
 /*
3
     pIndicator - class to draw indicators
4
5
     Version     : 2.1.4
6
     Made by     : Jean-Damien POGOLOTTI
7
     Last Update : 19/01/2014
8
9
     This file can be distributed under the license you can find at :
10
11
                       http://www.pchart.net/license
12
13
     You can find the whole class documentation on the pChart web site.
14
 */
15
16
 define("INDICATOR_CAPTION_DEFAULT"	, 700001);
17
 define("INDICATOR_CAPTION_EXTENDED"	, 700002);
18
19
 define("INDICATOR_CAPTION_INSIDE"	, 700011);
20
 define("INDICATOR_CAPTION_BOTTOM"	, 700012);
21
22
 define("INDICATOR_VALUE_BUBBLE"	, 700021);
23
 define("INDICATOR_VALUE_LABEL"		, 700022);
24
25
 /* pIndicator class definition */
26
 class pIndicator
27
  {
28
   var $pChartObject;
29
30
   /* Class creator */
31
   function pIndicator($pChartObject)
32
    {
33
     $this->pChartObject = $pChartObject;
34
    }
35
36
   /* Draw an indicator */
37
   function draw($X,$Y,$Width,$Height,$Format="")
38
    {
39
     $Values			= isset($Format["Values"]) ? $Format["Values"] : VOID;
40
     $IndicatorSections		= isset($Format["IndicatorSections"]) ? $Format["IndicatorSections"] : NULL;
41
     $ValueDisplay		= isset($Format["ValueDisplay"]) ? $Format["ValueDisplay"] : INDICATOR_VALUE_BUBBLE;
42
     $SectionsMargin		= isset($Format["SectionsMargin"]) ? $Format["SectionsMargin"] : 4;
43
     $DrawLeftHead		= isset($Format["DrawLeftHead"]) ? $Format["DrawLeftHead"] : TRUE;
44
     $DrawRightHead		= isset($Format["DrawRightHead"]) ? $Format["DrawRightHead"] : TRUE;
45
     $HeadSize			= isset($Format["HeadSize"]) ? $Format["HeadSize"] : floor($Height/4);
46
     $TextPadding		= isset($Format["TextPadding"]) ? $Format["TextPadding"] : 4;
47
     $CaptionLayout		= isset($Format["CaptionLayout"]) ? $Format["CaptionLayout"] : INDICATOR_CAPTION_EXTENDED;
48
     $CaptionPosition		= isset($Format["CaptionPosition"]) ? $Format["CaptionPosition"] : INDICATOR_CAPTION_INSIDE;
49
     $CaptionColorFactor	= isset($Format["CaptionColorFactor"]) ? $Format["CaptionColorFactor"] : NULL;
50
     $CaptionR			= isset($Format["CaptionR"]) ? $Format["CaptionR"] : 255;
51
     $CaptionG			= isset($Format["CaptionG"]) ? $Format["CaptionG"] : 255;
52
     $CaptionB			= isset($Format["CaptionB"]) ? $Format["CaptionB"] : 255;
53
     $CaptionAlpha		= isset($Format["CaptionAlpha"]) ? $Format["CaptionAlpha"] : 100;
54
     $SubCaptionColorFactor	= isset($Format["SubCaptionColorFactor"]) ? $Format["SubCaptionColorFactor"] : NULL;
55
     $SubCaptionR		= isset($Format["SubCaptionR"]) ? $Format["SubCaptionR"] : 50;
56
     $SubCaptionG		= isset($Format["SubCaptionG"]) ? $Format["SubCaptionG"] : 50;
57
     $SubCaptionB		= isset($Format["SubCaptionB"]) ? $Format["SubCaptionB"] : 50;
58
     $SubCaptionAlpha		= isset($Format["SubCaptionAlpha"]) ? $Format["SubCaptionAlpha"] : 100;
59
     $ValueFontName		= isset($Format["ValueFontName"]) ? $Format["ValueFontName"] : $this->pChartObject->FontName;
60
     $ValueFontSize		= isset($Format["ValueFontSize"]) ? $Format["ValueFontSize"] : $this->pChartObject->FontSize;
61
     $CaptionFontName		= isset($Format["CaptionFontName"]) ? $Format["CaptionFontName"] : $this->pChartObject->FontName;
62
     $CaptionFontSize		= isset($Format["CaptionFontSize"]) ? $Format["CaptionFontSize"] : $this->pChartObject->FontSize;
63
     $Unit			= isset($Format["Unit"]) ? $Format["Unit"] : "";
64
65
     /* Convert the Values to display to an array if needed */
66
     if ( !is_array($Values) ) { $Value = $Values; $Values = ""; $Values[] = $Value; }
67
68
     /* No section, let's die */
69
     if ( $IndicatorSections == NULL ) { return(0); }
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $IndicatorSections of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
70
71
     /* Determine indicator visual configuration */
72
     $OverallMin = $IndicatorSections[0]["End"]; $OverallMax = $IndicatorSections[0]["Start"];
73
     foreach ($IndicatorSections as $Key => $Settings)
0 ignored issues
show
Bug introduced by
The expression $IndicatorSections of type string is not traversable.
Loading history...
74
      {
75
       if ( $Settings["End"] > $OverallMax )   { $OverallMax = $Settings["End"]; }
76
       if ( $Settings["Start"] < $OverallMin ) { $OverallMin = $Settings["Start"]; }
77
      }
78
     $RealWidth = $Width - (count($IndicatorSections)-1)*$SectionsMargin;
79
     $XScale    = $RealWidth / ($OverallMax-$OverallMin);
80
81
     $X1 = $X; $ValuesPos = "";
82
     foreach ($IndicatorSections as $Key => $Settings)
0 ignored issues
show
Bug introduced by
The expression $IndicatorSections of type string is not traversable.
Loading history...
83
      {
84
       $Color      = array("R"=>$Settings["R"],"G"=>$Settings["G"],"B"=>$Settings["B"]);
85
       $Caption    = $Settings["Caption"];
86
       $SubCaption = $Settings["Start"]." - ".$Settings["End"];
87
88
       $X2 = $X1 + ($Settings["End"] - $Settings["Start"]) * $XScale;
89
90
       if ( $Key == 0 && $DrawLeftHead )
91
        {
92
         $Poly = ""; $Poly[] = $X1-1; $Poly[] = $Y; $Poly[] = $X1-1; $Poly[] = $Y+$Height; $Poly[] = $X1-1-$HeadSize; $Poly[] = $Y+($Height/2);
93
         $this->pChartObject->drawPolygon($Poly,$Color);
94
         $this->pChartObject->drawLine($X1-2,$Y,$X1-2-$HeadSize,$Y+($Height/2),$Color);
95
         $this->pChartObject->drawLine($X1-2,$Y+$Height,$X1-2-$HeadSize,$Y+($Height/2),$Color);
96
        }
97
98
       /* Determine the position of the breaks */
99
       $Break = "";
100
       foreach($Values as $iKey => $Value)
0 ignored issues
show
Bug introduced by
The expression $Values of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
101
        {
102
         if ( $Value >= $Settings["Start"] && $Value <= $Settings["End"] )
103
          {
104
           $XBreak  = $X1 + ($Value - $Settings["Start"]) * $XScale;
105
           $ValuesPos[$Value] = $XBreak;
106
           $Break[] = floor($XBreak);
107
          }
108
        }
109
110
       if ( $ValueDisplay == INDICATOR_VALUE_LABEL )
111
        {
112
         if ( $Break == "" )
113
          $this->pChartObject->drawFilledRectangle($X1,$Y,$X2,$Y+$Height,$Color);
114
         else
115
          {
116
           sort($Break);
117
           $Poly = ""; $Poly[] = $X1; $Poly[] = $Y; $LastPointWritten = FALSE;
118
           foreach($Break as $iKey => $Value)
119
            {
120
             if ( $Value-5 >= $X1 )
121
              { $Poly[] = $Value-5; $Poly[] = $Y; }
122
             elseif ($X1 - ($Value-5) > 0 )
123
              {
124
               $Offset = $X1 - ($Value-5);
125
               $Poly = ""; $Poly[] = $X1; $Poly[] = $Y + $Offset;
126
              }
127
128
             $Poly[] = $Value;   $Poly[] = $Y+5;
129
130
             if ( $Value+5 <= $X2 )
131
              { $Poly[] = $Value+5; $Poly[] = $Y; }
132
             elseif (($Value+5) > $X2 )
133
              {
134
               $Offset = ($Value+5) - $X2;
135
               $Poly[] = $X2; $Poly[] = $Y + $Offset;
136
               $LastPointWritten = TRUE;
137
              }
138
139
            }
140
           if ( !$LastPointWritten ) { $Poly[] = $X2; $Poly[] = $Y; }
141
           $Poly[] = $X2; $Poly[] = $Y+$Height;
142
           $Poly[] = $X1; $Poly[] = $Y+$Height;
143
144
           $this->pChartObject->drawPolygon($Poly,$Color);
145
          }
146
        }
147
       else
148
        $this->pChartObject->drawFilledRectangle($X1,$Y,$X2,$Y+$Height,$Color);
149
150
       if ( $Key == count($IndicatorSections)-1 && $DrawRightHead )
151
        {
152
         $Poly = ""; $Poly[] = $X2+1; $Poly[] = $Y; $Poly[] = $X2+1; $Poly[] = $Y+$Height; $Poly[] = $X2+1+$HeadSize; $Poly[] = $Y+($Height/2);
153
         $this->pChartObject->drawPolygon($Poly,$Color);
154
         $this->pChartObject->drawLine($X2+1,$Y,$X2+1+$HeadSize,$Y+($Height/2),$Color);
155
         $this->pChartObject->drawLine($X2+1,$Y+$Height,$X2+1+$HeadSize,$Y+($Height/2),$Color);
156
        }
157
158
       if ( $CaptionPosition == INDICATOR_CAPTION_INSIDE )
159
        {
160
         $TxtPos  = $this->pChartObject->getTextBox($X1,$Y+$Height+$TextPadding,$CaptionFontName,$CaptionFontSize,0,$Caption);
161
         $YOffset = ($TxtPos[0]["Y"] - $TxtPos[2]["Y"]) + $TextPadding;
162
163
         if ( $CaptionLayout == INDICATOR_CAPTION_EXTENDED )
164
          {
165
           $TxtPos  = $this->pChartObject->getTextBox($X1,$Y+$Height+$TextPadding,$CaptionFontName,$CaptionFontSize,0,$SubCaption);
166
           $YOffset = $YOffset + ($TxtPos[0]["Y"] - $TxtPos[2]["Y"]) + $TextPadding*2;
167
          }
168
169
         $XOffset = $TextPadding;
170
        }
171
       else
172
        { $YOffset = 0; $XOffset = 0; }
173
174
       if ( $CaptionColorFactor == NULL )
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $CaptionColorFactor of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
175
        { $CaptionColor    = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$CaptionR,"G"=>$CaptionG,"B"=>$CaptionB,"Alpha"=>$CaptionAlpha); }
176
       else
177
        { $CaptionColor    = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$Settings["R"]+$CaptionColorFactor,"G"=>$Settings["G"]+$CaptionColorFactor,"B"=>$Settings["B"]+$CaptionColorFactor); }
178
179
       if ( $SubCaptionColorFactor == NULL )
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $SubCaptionColorFactor of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
180
        $SubCaptionColor = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$SubCaptionR,"G"=>$SubCaptionG,"B"=>$SubCaptionB,"Alpha"=>$SubCaptionAlpha);
181
       else
182
        $SubCaptionColor = array("Align"=>TEXT_ALIGN_TOPLEFT,"FontName"=>$CaptionFontName,"FontSize"=>$CaptionFontSize,"R"=>$Settings["R"]+$SubCaptionColorFactor,"G"=>$Settings["G"]+$SubCaptionColorFactor,"B"=>$Settings["B"]+$SubCaptionColorFactor);
183
184
       $RestoreShadow = $this->pChartObject->Shadow;
185
       $this->pChartObject->Shadow = FALSE;
186
187
       if ( $CaptionLayout == INDICATOR_CAPTION_DEFAULT )
188
        $this->pChartObject->drawText($X1,$Y+$Height+$TextPadding,$Caption,$CaptionColor);
189
       elseif ( $CaptionLayout == INDICATOR_CAPTION_EXTENDED )
190
        {
191
         $TxtPos        = $this->pChartObject->getTextBox($X1,$Y+$Height+$TextPadding,$CaptionFontName,$CaptionFontSize,0,$Caption);
192
         $CaptionHeight = $TxtPos[0]["Y"] - $TxtPos[2]["Y"];
193
194
         $this->pChartObject->drawText($X1+$XOffset,$Y+$Height-$YOffset+$TextPadding,$Caption,$CaptionColor);
195
         $this->pChartObject->drawText($X1+$XOffset,$Y+$Height-$YOffset+$CaptionHeight+$TextPadding*2,$SubCaption,$SubCaptionColor);
196
        }
197
198
       $this->pChartObject->Shadow = $RestoreShadow;
199
200
       $X1 = $X2 + $SectionsMargin;
201
      }
202
203
     $RestoreShadow = $this->pChartObject->Shadow;
204
     $this->pChartObject->Shadow = FALSE;
205
206
     foreach($Values as $Key => $Value)
0 ignored issues
show
Bug introduced by
The expression $Values of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
207
      {
208
       if ( $Value >= $OverallMin && $Value <= $OverallMax )
209
        {
210
         foreach ($IndicatorSections as $Key => $Settings)
0 ignored issues
show
Bug introduced by
The expression $IndicatorSections of type string is not traversable.
Loading history...
211
          {
212
           if ( $Value >= $Settings["Start"] && $Value <= $Settings["End"] )
213
            {
214
             $X1 = $ValuesPos[$Value]; //$X + $Key*$SectionsMargin + ($Value - $OverallMin) * $XScale;
215
216
             if ( $ValueDisplay == INDICATOR_VALUE_BUBBLE )
217
              {
218
               $TxtPos = $this->pChartObject->getTextBox($X1,$Y,$ValueFontName,$ValueFontSize,0,$Value.$Unit);
219
               $Radius = floor(($TxtPos[1]["X"] - $TxtPos[0]["X"] + $TextPadding*4)/2);
220
221
               $this->pChartObject->drawFilledCircle($X1,$Y,$Radius+4,array("R"=>$Settings["R"]+20,"G"=>$Settings["G"]+20,"B"=>$Settings["B"]+20));
222
               $this->pChartObject->drawFilledCircle($X1,$Y,$Radius,array("R"=>255,"G"=>255,"B"=>255));
223
224
               $TextSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"FontName"=>$ValueFontName,"FontSize"=>$ValueFontSize);
225
               $this->pChartObject->drawText($X1-1,$Y-1,$Value.$Unit,$TextSettings);
226
              }
227
             elseif( $ValueDisplay == INDICATOR_VALUE_LABEL )
228
              {
229
               $Caption = "";
230
               $Caption[] = array("Format"=>array("R"=>$Settings["R"],"G"=>$Settings["G"],"B"=>$Settings["B"],"Alpha"=>100),"Caption"=>$Value.$Unit);
231
               $this->pChartObject->drawLabelBox(floor($X1),floor($Y)+2,"Value - ".$Settings["Caption"],$Caption);
232
              }
233
            }
234
           $X1 = $X2 + $SectionsMargin;
235
          }
236
        }
237
      }
238
     $this->pChartObject->Shadow = $RestoreShadow;
239
    }
240
  }
241
?>