1<?php 2 /* 3 pRadar - class to draw radar charts 4 5 Version : 2.1.3 6 Made by : Jean-Damien POGOLOTTI 7 Last Update : 09/09/11 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("SEGMENT_HEIGHT_AUTO" , 690001); 17 18 define("RADAR_LAYOUT_STAR" , 690011); 19 define("RADAR_LAYOUT_CIRCLE" , 690012); 20 21 define("RADAR_LABELS_ROTATED" , 690021); 22 define("RADAR_LABELS_HORIZONTAL" , 690022); 23 24 /* pRadar class definition */ 25 class pRadar 26 { 27 var $pChartObject; 28 29 /* Class creator */ 30 function pRadar() 31 { } 32 33 /* Draw a radar chart */ 34 function drawRadar($Object,$Values,$Format="") 35 { 36 $this->pChartObject = $Object; 37 38 $FixedMax = isset($Format["FixedMax"]) ? $Format["FixedMax"] : VOID; 39 $AxisR = isset($Format["AxisR"]) ? $Format["AxisR"] : 60; 40 $AxisG = isset($Format["AxisG"]) ? $Format["AxisG"] : 60; 41 $AxisB = isset($Format["AxisB"]) ? $Format["AxisB"] : 60; 42 $AxisAlpha = isset($Format["AxisAlpha"]) ? $Format["AxisAlpha"] : 50; 43 $AxisRotation = isset($Format["AxisRotation"]) ? $Format["AxisRotation"] : 0; 44 $DrawTicks = isset($Format["DrawTicks"]) ? $Format["DrawTicks"] : TRUE; 45 $TicksLength = isset($Format["TicksLength"]) ? $Format["TicksLength"] : 2; 46 $DrawAxisValues = isset($Format["DrawAxisValues"]) ? $Format["DrawAxisValues"] : TRUE; 47 $AxisBoxRounded = isset($Format["AxisBoxRounded"]) ? $Format["AxisBoxRounded"] : TRUE; 48 $AxisFontName = isset($Format["AxisFontName"]) ? $Format["AxisFontName"] : $this->pChartObject->FontName; 49 $AxisFontSize = isset($Format["AxisFontSize"]) ? $Format["AxisFontSize"] : $this->pChartObject->FontSize; 50 $WriteValues = isset($Format["WriteValues"]) ? $Format["WriteValues"] : FALSE; 51 $WriteValuesInBubble = isset($Format["WriteValuesInBubble"]) ? $Format["WriteValuesInBubble"] : TRUE; 52 $ValueFontName = isset($Format["ValueFontName"]) ? $Format["ValueFontName"] : $this->pChartObject->FontName; 53 $ValueFontSize = isset($Format["ValueFontSize"]) ? $Format["ValueFontSize"] : $this->pChartObject->FontSize; 54 $ValuePadding = isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 4; 55 $OuterBubbleRadius = isset($Format["OuterBubbleRadius"]) ? $Format["OuterBubbleRadius"] : 2; 56 $OuterBubbleR = isset($Format["OuterBubbleR"]) ? $Format["OuterBubbleR"] : VOID; 57 $OuterBubbleG = isset($Format["OuterBubbleG"]) ? $Format["OuterBubbleG"] : VOID; 58 $OuterBubbleB = isset($Format["OuterBubbleB"]) ? $Format["OuterBubbleB"] : VOID; 59 $OuterBubbleAlpha = isset($Format["OuterBubbleAlpha"]) ? $Format["OuterBubbleAlpha"] : 100; 60 $InnerBubbleR = isset($Format["InnerBubbleR"]) ? $Format["InnerBubbleR"] : 255; 61 $InnerBubbleG = isset($Format["InnerBubbleG"]) ? $Format["InnerBubbleG"] : 255; 62 $InnerBubbleB = isset($Format["InnerBubbleB"]) ? $Format["InnerBubbleB"] : 255; 63 $InnerBubbleAlpha = isset($Format["InnerBubbleAlpha"]) ? $Format["InnerBubbleAlpha"] : 100; 64 $DrawBackground = isset($Format["DrawBackground"]) ? $Format["DrawBackground"] : TRUE; 65 $BackgroundR = isset($Format["BackgroundR"]) ? $Format["BackgroundR"] : 255; 66 $BackgroundG = isset($Format["BackgroundG"]) ? $Format["BackgroundG"] : 255; 67 $BackgroundB = isset($Format["BackgroundB"]) ? $Format["BackgroundB"] : 255; 68 $BackgroundAlpha = isset($Format["BackgroundAlpha"]) ? $Format["BackgroundAlpha"] : 50; 69 $BackgroundGradient= isset($Format["BackgroundGradient"]) ? $Format["BackgroundGradient"] : NULL; 70 $Layout = isset($Format["Layout"]) ? $Format["Layout"] : RADAR_LAYOUT_STAR; 71 $SegmentHeight = isset($Format["SegmentHeight"]) ? $Format["SegmentHeight"] : SEGMENT_HEIGHT_AUTO; 72 $Segments = isset($Format["Segments"]) ? $Format["Segments"] : 4; 73 $WriteLabels = isset($Format["WriteLabels"]) ? $Format["WriteLabels"] : TRUE; 74 $SkipLabels = isset($Format["SkipLabels"]) ? $Format["SkipLabels"] : 1; 75 $LabelMiddle = isset($Format["LabelMiddle"]) ? $Format["LabelMiddle"] : FALSE; 76 $LabelsBackground = isset($Format["LabelsBackground"]) ? $Format["LabelsBackground"] : TRUE; 77 $LabelsBGR = isset($Format["LabelsBGR"]) ? $Format["LabelsBGR"] : 255; 78 $LabelsBGG = isset($Format["LabelsBGR"]) ? $Format["LabelsBGG"] : 255; 79 $LabelsBGB = isset($Format["LabelsBGR"]) ? $Format["LabelsBGB"] : 255; 80 $LabelsBGAlpha = isset($Format["LabelsBGAlpha"]) ? $Format["LabelsBGAlpha"] : 50; 81 $LabelPos = isset($Format["LabelPos"]) ? $Format["LabelPos"] : RADAR_LABELS_ROTATED; 82 $LabelPadding = isset($Format["LabelPadding"]) ? $Format["LabelPadding"] : 4; 83 $DrawPoints = isset($Format["DrawPoints"]) ? $Format["DrawPoints"] : TRUE; 84 $PointRadius = isset($Format["PointRadius"]) ? $Format["PointRadius"] : 4; 85 $PointSurrounding = isset($Format["PointRadius"]) ? $Format["PointRadius"] : -30; 86 $DrawLines = isset($Format["DrawLines"]) ? $Format["DrawLines"] : TRUE; 87 $LineLoopStart = isset($Format["LineLoopStart"]) ? $Format["LineLoopStart"] : TRUE; 88 $DrawPoly = isset($Format["DrawPoly"]) ? $Format["DrawPoly"] : FALSE; 89 $PolyAlpha = isset($Format["PolyAlpha"]) ? $Format["PolyAlpha"] : 40; 90 $FontSize = $Object->FontSize; 91 $X1 = $Object->GraphAreaX1; 92 $Y1 = $Object->GraphAreaY1; 93 $X2 = $Object->GraphAreaX2; 94 $Y2 = $Object->GraphAreaY2; 95 $RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE; 96 97 /* Cancel default tick length if ticks not enabled */ 98 if ( $DrawTicks == FALSE ) { $TicksLength = 0; } 99 100 /* Data Processing */ 101 $Data = $Values->getData(); 102 $Palette = $Values->getPalette(); 103 104 /* Catch the number of required axis */ 105 $LabelSerie = $Data["Abscissa"]; 106 if ( $LabelSerie != "" ) 107 { $Points = count($Data["Series"][$LabelSerie]["Data"]); } 108 else 109 { 110 $Points = 0; 111 foreach($Data["Series"] as $SerieName => $DataArray) 112 { if ( count($DataArray["Data"]) > $Points ) { $Points = count($DataArray["Data"]); } } 113 } 114 115 /* Draw the axis */ 116 $CenterX = ($X2-$X1)/2 + $X1; 117 $CenterY = ($Y2-$Y1)/2 + $Y1; 118 119 $EdgeHeight = min(($X2-$X1)/2,($Y2-$Y1)/2); 120 if ( $WriteLabels ) 121 $EdgeHeight = $EdgeHeight - $FontSize - $LabelPadding - $TicksLength; 122 123 /* Determine the scale if set to automatic */ 124 if ( $SegmentHeight == SEGMENT_HEIGHT_AUTO) 125 { 126 if ( $FixedMax != VOID ) 127 $Max = $FixedMax; 128 else 129 { 130 $Max = 0; 131 foreach($Data["Series"] as $SerieName => $DataArray) 132 { 133 if ( $SerieName != $LabelSerie ) 134 { 135 if ( max($DataArray["Data"]) > $Max ) { $Max = max($DataArray["Data"]); } 136 } 137 } 138 } 139 $MaxSegments = $EdgeHeight/20; 140 $Scale = $Object->computeScale(0,$Max,$MaxSegments,array(1,2,5)); 141 142 $Segments = $Scale["Rows"]; 143 $SegmentHeight = $Scale["RowHeight"]; 144 } 145 146 if ( $LabelMiddle && $SkipLabels == 1 ) 147 { $Axisoffset = (360/$Points)/2; } 148 elseif ( $LabelMiddle && $SkipLabels != 1 ) 149 { $Axisoffset = (360/($Points/$SkipLabels))/2; } 150 elseif ( !$LabelMiddle ) 151 { $Axisoffset = 0; } 152 153 /* Background processing */ 154 if ( $DrawBackground ) 155 { 156 $RestoreShadow = $Object->Shadow; 157 $Object->Shadow = FALSE; 158 159 if ($BackgroundGradient == NULL) 160 { 161 if ( $Layout == RADAR_LAYOUT_STAR ) 162 { 163 $Color = array("R"=>$BackgroundR,"G"=>$BackgroundG,"B"=>$BackgroundB,"Alpha"=>$BackgroundAlpha); 164 $PointArray = ""; 165 for($i=0;$i<=360;$i=$i+(360/$Points)) 166 { 167 $PointArray[] = cos(deg2rad($i+$AxisRotation)) * $EdgeHeight + $CenterX; 168 $PointArray[] = sin(deg2rad($i+$AxisRotation)) * $EdgeHeight + $CenterY; 169 } 170 $Object->drawPolygon($PointArray,$Color); 171 } 172 elseif ( $Layout == RADAR_LAYOUT_CIRCLE ) 173 { 174 $Color = array("R"=>$BackgroundR,"G"=>$BackgroundG,"B"=>$BackgroundB,"Alpha"=>$BackgroundAlpha); 175 $Object->drawFilledCircle($CenterX,$CenterY,$EdgeHeight,$Color); 176 } 177 } 178 else 179 { 180 $GradientROffset = ($BackgroundGradient["EndR"] - $BackgroundGradient["StartR"]) / $Segments; 181 $GradientGOffset = ($BackgroundGradient["EndG"] - $BackgroundGradient["StartG"]) / $Segments; 182 $GradientBOffset = ($BackgroundGradient["EndB"] - $BackgroundGradient["StartB"]) / $Segments; 183 $GradientAlphaOffset = ($BackgroundGradient["EndAlpha"] - $BackgroundGradient["StartAlpha"]) / $Segments; 184 185 if ( $Layout == RADAR_LAYOUT_STAR ) 186 { 187 for($j=$Segments;$j>=1;$j--) 188 { 189 $Color = array("R"=>$BackgroundGradient["StartR"]+$GradientROffset*$j,"G"=>$BackgroundGradient["StartG"]+$GradientGOffset*$j,"B"=>$BackgroundGradient["StartB"]+$GradientBOffset*$j,"Alpha"=>$BackgroundGradient["StartAlpha"]+$GradientAlphaOffset*$j); 190 $PointArray = ""; 191 192 for($i=0;$i<=360;$i=$i+(360/$Points)) 193 { 194 $PointArray[] = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX; 195 $PointArray[] = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY; 196 } 197 $Object->drawPolygon($PointArray,$Color); 198 } 199 } 200 elseif ( $Layout == RADAR_LAYOUT_CIRCLE ) 201 { 202 for($j=$Segments;$j>=1;$j--) 203 { 204 $Color = array("R"=>$BackgroundGradient["StartR"]+$GradientROffset*$j,"G"=>$BackgroundGradient["StartG"]+$GradientGOffset*$j,"B"=>$BackgroundGradient["StartB"]+$GradientBOffset*$j,"Alpha"=>$BackgroundGradient["StartAlpha"]+$GradientAlphaOffset*$j); 205 $Object->drawFilledCircle($CenterX,$CenterY,($EdgeHeight/$Segments)*$j,$Color); 206 } 207 } 208 } 209 $Object->Shadow = $RestoreShadow; 210 } 211 212 /* Axis to axis lines */ 213 $Color = array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha); 214 $ColorDotted = array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha*.8, "Ticks"=>2); 215 if ( $Layout == RADAR_LAYOUT_STAR ) 216 { 217 for($j=1;$j<=$Segments;$j++) 218 { 219 for($i=0;$i<360;$i=$i+(360/$Points)) 220 { 221 $EdgeX1 = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX; 222 $EdgeY1 = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY; 223 $EdgeX2 = cos(deg2rad($i+$AxisRotation+(360/$Points))) * ($EdgeHeight/$Segments)*$j + $CenterX; 224 $EdgeY2 = sin(deg2rad($i+$AxisRotation+(360/$Points))) * ($EdgeHeight/$Segments)*$j + $CenterY; 225 226 $Object->drawLine($EdgeX1,$EdgeY1,$EdgeX2,$EdgeY2,$Color); 227 } 228 } 229 } 230 elseif ( $Layout == RADAR_LAYOUT_CIRCLE ) 231 { 232 for($j=1;$j<=$Segments;$j++) 233 { 234 $Radius = ($EdgeHeight/$Segments)*$j; 235 $Object->drawCircle($CenterX,$CenterY,$Radius,$Radius,$Color); 236 } 237 } 238 239 if ( $DrawAxisValues ) 240 { 241 if ( $LabelsBackground ) 242 $Options = array("DrawBox"=>TRUE, "Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"BoxR"=>$LabelsBGR,"BoxG"=>$LabelsBGG,"BoxB"=>$LabelsBGB,"BoxAlpha"=>$LabelsBGAlpha); 243 else 244 $Options = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE); 245 246 if ( $AxisBoxRounded ) { $Options["BoxRounded"] = TRUE; } 247 248 $Options["FontName"] = $AxisFontName; 249 $Options["FontSize"] = $AxisFontSize; 250 251 $Angle = 360 / ($Points*2); 252 for($j=1;$j<=$Segments;$j++) 253 { 254 $Label = $j * $SegmentHeight; 255 256 if ( $Layout == RADAR_LAYOUT_CIRCLE ) 257 { 258 $EdgeX1 = cos(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX; 259 $EdgeY1 = sin(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY; 260 } 261 elseif ( $Layout == RADAR_LAYOUT_STAR ) 262 { 263 $EdgeX1 = cos(deg2rad($AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX; 264 $EdgeY1 = sin(deg2rad($AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY; 265 $EdgeX2 = cos(deg2rad((360 / $Points) + $AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX; 266 $EdgeY2 = sin(deg2rad((360 / $Points) + $AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY; 267 268 $EdgeX1 = ($EdgeX2 - $EdgeX1)/2 + $EdgeX1; 269 $EdgeY1 = ($EdgeY2 - $EdgeY1)/2 + $EdgeY1; 270 } 271 272 $Object->drawText($EdgeX1,$EdgeY1,$Label,$Options); 273 } 274 } 275 276 /* Axis lines */ 277 $ID = 0; 278 for($i=0;$i<360;$i=$i+(360/$Points)) 279 { 280 $EdgeX = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterX; 281 $EdgeY = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterY; 282 283 if ($ID % $SkipLabels == 0) 284 { $Object->drawLine($CenterX,$CenterY,$EdgeX,$EdgeY,$Color); } 285 else 286 { $Object->drawLine($CenterX,$CenterY,$EdgeX,$EdgeY,$ColorDotted); } 287 288 if ( $WriteLabels ) 289 { 290 $LabelX = cos(deg2rad($i+$AxisRotation+$Axisoffset)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterX; 291 $LabelY = sin(deg2rad($i+$AxisRotation+$Axisoffset)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterY; 292 293 if ( $LabelSerie != "" ) 294 { $Label = isset($Data["Series"][$LabelSerie]["Data"][$ID]) ? $Data["Series"][$LabelSerie]["Data"][$ID] : ""; } 295 else 296 $Label = $ID; 297 298 if ($ID % $SkipLabels == 0) 299 { 300 if ( $LabelPos == RADAR_LABELS_ROTATED ) 301 $Object->drawText($LabelX,$LabelY,$Label,array("Angle"=>(360-($i+$AxisRotation+$Axisoffset))-90,"Align"=>TEXT_ALIGN_BOTTOMMIDDLE)); 302 else 303 { 304 if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE)); } 305 if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMLEFT)); } 306 if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLELEFT)); } 307 if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPLEFT)); } 308 if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMRIGHT)); } 309 if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLERIGHT)); } 310 if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPRIGHT)); } 311 if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPMIDDLE)); } 312 } 313 } 314 } 315 $ID++; 316 } 317 318 /* Compute the plots position */ 319 $ID = 0; $Plot = ""; 320 foreach($Data["Series"] as $SerieName => $DataS) 321 { 322 if ( $SerieName != $LabelSerie ) 323 { 324 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding); 325 foreach($DataS["Data"] as $Key => $Value) 326 { 327 $Angle = (360/$Points) * $Key; 328 $Length = ($EdgeHeight/($Segments*$SegmentHeight))*$Value; 329 330 $X = cos(deg2rad($Angle+$AxisRotation)) * $Length + $CenterX; 331 $Y = sin(deg2rad($Angle+$AxisRotation)) * $Length + $CenterY; 332 333 $Plot[$ID][] = array($X,$Y,$Value); 334 335 if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("CIRCLE",floor($X).",".floor($Y).",".floor($PointRadius),$this->pChartObject->toHTMLColor($Palette[$ID]["R"],$Palette[$ID]["G"],$Palette[$ID]["B"]),$DataS["Description"],$Data["Series"][$LabelSerie]["Data"][$Key]." = ".$Value); } 336 } 337 $ID++; 338 } 339 } 340 341 /* Draw all that stuff! */ 342 foreach($Plot as $ID => $Points) 343 { 344 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding); 345 346 /* Draw the polygons */ 347 if ( $DrawPoly ) 348 { 349 if ($PolyAlpha != NULL) 350 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$PolyAlpha,"Surrounding"=>$PointSurrounding); 351 352 $PointsArray = ""; 353 for($i=0; $i<count($Points);$i++) 354 { $PointsArray[] = $Points[$i][0]; $PointsArray[] = $Points[$i][1]; } 355 $Object->drawPolygon($PointsArray,$Color); 356 } 357 358 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding); 359 360 /* Bubble and labels settings */ 361 $TextSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"FontName"=>$ValueFontName,"FontSize"=>$ValueFontSize,"R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"]); 362 $InnerColor = array("R"=>$InnerBubbleR,"G"=>$InnerBubbleG,"B"=>$InnerBubbleB,"Alpha"=>$InnerBubbleAlpha); 363 if ( $OuterBubbleR != VOID ) 364 $OuterColor = array("R"=>$OuterBubbleR,"G"=>$OuterBubbleG,"B"=>$OuterBubbleB,"Alpha"=>$OuterBubbleAlpha); 365 else 366 $OuterColor = array("R"=>$Palette[$ID]["R"]+20,"G"=>$Palette[$ID]["G"]+20,"B"=>$Palette[$ID]["B"]+20,"Alpha"=>$Palette[$ID]["Alpha"]); 367 368 /* Loop to the starting points if asked */ 369 if ( $LineLoopStart && $DrawLines ) 370 $Object->drawLine($Points[count($Points)-1][0],$Points[count($Points)-1][1],$Points[0][0],$Points[0][1],$Color); 371 372 /* Draw the lines & points */ 373 for($i=0; $i<count($Points);$i++) 374 { 375 if ( $DrawLines && $i < count($Points)-1) 376 $Object->drawLine($Points[$i][0],$Points[$i][1],$Points[$i+1][0],$Points[$i+1][1],$Color); 377 378 if ( $DrawPoints ) 379 $Object->drawFilledCircle($Points[$i][0],$Points[$i][1],$PointRadius,$Color); 380 381 if ( $WriteValuesInBubble && $WriteValues ) 382 { 383 $TxtPos = $this->pChartObject->getTextBox($Points[$i][0],$Points[$i][1],$ValueFontName,$ValueFontSize,0,$Points[$i][2]); 384 $Radius = floor(($TxtPos[1]["X"] - $TxtPos[0]["X"] + $ValuePadding*2)/2); 385 386 $this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius+$OuterBubbleRadius,$OuterColor); 387 $this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius,$InnerColor); 388 } 389 390 if ( $WriteValues ) 391 $this->pChartObject->drawText($Points[$i][0]-1,$Points[$i][1]-1,$Points[$i][2],$TextSettings); 392 } 393 } 394 } 395 396 397 398 /* Draw a radar chart */ 399 function drawPolar($Object,$Values,$Format="") 400 { 401 $this->pChartObject = $Object; 402 403 $FixedMax = isset($Format["FixedMax"]) ? $Format["FixedMax"] : VOID; 404 $AxisR = isset($Format["AxisR"]) ? $Format["AxisR"] : 60; 405 $AxisG = isset($Format["AxisG"]) ? $Format["AxisG"] : 60; 406 $AxisB = isset($Format["AxisB"]) ? $Format["AxisB"] : 60; 407 $AxisAlpha = isset($Format["AxisAlpha"]) ? $Format["AxisAlpha"] : 50; 408 $AxisRotation = isset($Format["AxisRotation"]) ? $Format["AxisRotation"] : -90; 409 $DrawTicks = isset($Format["DrawTicks"]) ? $Format["DrawTicks"] : TRUE; 410 $TicksLength = isset($Format["TicksLength"]) ? $Format["TicksLength"] : 2; 411 $DrawAxisValues = isset($Format["DrawAxisValues"]) ? $Format["DrawAxisValues"] : TRUE; 412 $AxisBoxRounded = isset($Format["AxisBoxRounded"]) ? $Format["AxisBoxRounded"] : TRUE; 413 $AxisFontName = isset($Format["FontName"]) ? $Format["FontName"] : $this->pChartObject->FontName; 414 $AxisFontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->pChartObject->FontSize; 415 $WriteValues = isset($Format["WriteValues"]) ? $Format["WriteValues"] : FALSE; 416 $WriteValuesInBubble = isset($Format["WriteValuesInBubble"]) ? $Format["WriteValuesInBubble"] : TRUE; 417 $ValueFontName = isset($Format["ValueFontName"]) ? $Format["ValueFontName"] : $this->pChartObject->FontName; 418 $ValueFontSize = isset($Format["ValueFontSize"]) ? $Format["ValueFontSize"] : $this->pChartObject->FontSize; 419 $ValuePadding = isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 4; 420 $OuterBubbleRadius = isset($Format["OuterBubbleRadius"]) ? $Format["OuterBubbleRadius"] : 2; 421 $OuterBubbleR = isset($Format["OuterBubbleR"]) ? $Format["OuterBubbleR"] : VOID; 422 $OuterBubbleG = isset($Format["OuterBubbleG"]) ? $Format["OuterBubbleG"] : VOID; 423 $OuterBubbleB = isset($Format["OuterBubbleB"]) ? $Format["OuterBubbleB"] : VOID; 424 $OuterBubbleAlpha = isset($Format["OuterBubbleAlpha"]) ? $Format["OuterBubbleAlpha"] : 100; 425 $InnerBubbleR = isset($Format["InnerBubbleR"]) ? $Format["InnerBubbleR"] : 255; 426 $InnerBubbleG = isset($Format["InnerBubbleG"]) ? $Format["InnerBubbleG"] : 255; 427 $InnerBubbleB = isset($Format["InnerBubbleB"]) ? $Format["InnerBubbleB"] : 255; 428 $InnerBubbleAlpha = isset($Format["InnerBubbleAlpha"]) ? $Format["InnerBubbleAlpha"] : 100; 429 $DrawBackground = isset($Format["DrawBackground"]) ? $Format["DrawBackground"] : TRUE; 430 $BackgroundR = isset($Format["BackgroundR"]) ? $Format["BackgroundR"] : 255; 431 $BackgroundG = isset($Format["BackgroundG"]) ? $Format["BackgroundG"] : 255; 432 $BackgroundB = isset($Format["BackgroundB"]) ? $Format["BackgroundB"] : 255; 433 $BackgroundAlpha = isset($Format["BackgroundAlpha"]) ? $Format["BackgroundAlpha"] : 50; 434 $BackgroundGradient= isset($Format["BackgroundGradient"]) ? $Format["BackgroundGradient"] : NULL; 435 $AxisSteps = isset($Format["AxisSteps"]) ? $Format["AxisSteps"] : 20; 436 $SegmentHeight = isset($Format["SegmentHeight"]) ? $Format["SegmentHeight"] : SEGMENT_HEIGHT_AUTO; 437 $Segments = isset($Format["Segments"]) ? $Format["Segments"] : 4; 438 $WriteLabels = isset($Format["WriteLabels"]) ? $Format["WriteLabels"] : TRUE; 439 $LabelsBackground = isset($Format["LabelsBackground"]) ? $Format["LabelsBackground"] : TRUE; 440 $LabelsBGR = isset($Format["LabelsBGR"]) ? $Format["LabelsBGR"] : 255; 441 $LabelsBGG = isset($Format["LabelsBGR"]) ? $Format["LabelsBGG"] : 255; 442 $LabelsBGB = isset($Format["LabelsBGR"]) ? $Format["LabelsBGB"] : 255; 443 $LabelsBGAlpha = isset($Format["LabelsBGAlpha"]) ? $Format["LabelsBGAlpha"] : 50; 444 $LabelPos = isset($Format["LabelPos"]) ? $Format["LabelPos"] : RADAR_LABELS_ROTATED; 445 $LabelPadding = isset($Format["LabelPadding"]) ? $Format["LabelPadding"] : 4; 446 $DrawPoints = isset($Format["DrawPoints"]) ? $Format["DrawPoints"] : TRUE; 447 $PointRadius = isset($Format["PointRadius"]) ? $Format["PointRadius"] : 4; 448 $PointSurrounding = isset($Format["PointRadius"]) ? $Format["PointRadius"] : -30; 449 $DrawLines = isset($Format["DrawLines"]) ? $Format["DrawLines"] : TRUE; 450 $LineLoopStart = isset($Format["LineLoopStart"]) ? $Format["LineLoopStart"] : FALSE; 451 $DrawPoly = isset($Format["DrawPoly"]) ? $Format["DrawPoly"] : FALSE; 452 $PolyAlpha = isset($Format["PolyAlpha"]) ? $Format["PolyAlpha"] : NULL; 453 $FontSize = $Object->FontSize; 454 $X1 = $Object->GraphAreaX1; 455 $Y1 = $Object->GraphAreaY1; 456 $X2 = $Object->GraphAreaX2; 457 $Y2 = $Object->GraphAreaY2; 458 $RecordImageMap = isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE; 459 460 if ( $AxisBoxRounded ) { $DrawAxisValues = TRUE; } 461 462 /* Cancel default tick length if ticks not enabled */ 463 if ( $DrawTicks == FALSE ) { $TicksLength = 0; } 464 465 /* Data Processing */ 466 $Data = $Values->getData(); 467 $Palette = $Values->getPalette(); 468 469 /* Catch the number of required axis */ 470 $LabelSerie = $Data["Abscissa"]; 471 if ( $LabelSerie != "" ) 472 { $Points = count($Data["Series"][$LabelSerie]["Data"]); } 473 else 474 { 475 $Points = 0; 476 foreach($Data["Series"] as $SerieName => $DataArray) 477 { if ( count($DataArray["Data"]) > $Points ) { $Points = count($DataArray["Data"]); } } 478 } 479 480 /* Draw the axis */ 481 $CenterX = ($X2-$X1)/2 + $X1; 482 $CenterY = ($Y2-$Y1)/2 + $Y1; 483 484 $EdgeHeight = min(($X2-$X1)/2,($Y2-$Y1)/2); 485 if ( $WriteLabels ) 486 $EdgeHeight = $EdgeHeight - $FontSize - $LabelPadding - $TicksLength; 487 488 /* Determine the scale if set to automatic */ 489 if ( $SegmentHeight == SEGMENT_HEIGHT_AUTO) 490 { 491 if ( $FixedMax != VOID ) 492 $Max = $FixedMax; 493 else 494 { 495 $Max = 0; 496 foreach($Data["Series"] as $SerieName => $DataArray) 497 { 498 if ( $SerieName != $LabelSerie ) 499 { 500 if ( max($DataArray["Data"]) > $Max ) { $Max = max($DataArray["Data"]); } 501 } 502 } 503 } 504 $MaxSegments = $EdgeHeight/20; 505 $Scale = $Object->computeScale(0,$Max,$MaxSegments,array(1,2,5)); 506 507 $Segments = $Scale["Rows"]; 508 $SegmentHeight = $Scale["RowHeight"]; 509 } 510 511 512 /* Background processing */ 513 if ( $DrawBackground ) 514 { 515 $RestoreShadow = $Object->Shadow; 516 $Object->Shadow = FALSE; 517 518 if ($BackgroundGradient == NULL) 519 { 520 $Color = array("R"=>$BackgroundR,"G"=>$BackgroundG,"B"=>$BackgroundB,"Alpha"=>$BackgroundAlpha); 521 $Object->drawFilledCircle($CenterX,$CenterY,$EdgeHeight,$Color); 522 } 523 else 524 { 525 $GradientROffset = ($BackgroundGradient["EndR"] - $BackgroundGradient["StartR"]) / $Segments; 526 $GradientGOffset = ($BackgroundGradient["EndG"] - $BackgroundGradient["StartG"]) / $Segments; 527 $GradientBOffset = ($BackgroundGradient["EndB"] - $BackgroundGradient["StartB"]) / $Segments; 528 $GradientAlphaOffset = ($BackgroundGradient["EndAlpha"] - $BackgroundGradient["StartAlpha"]) / $Segments; 529 530 for($j=$Segments;$j>=1;$j--) 531 { 532 $Color = array("R"=>$BackgroundGradient["StartR"]+$GradientROffset*$j,"G"=>$BackgroundGradient["StartG"]+$GradientGOffset*$j,"B"=>$BackgroundGradient["StartB"]+$GradientBOffset*$j,"Alpha"=>$BackgroundGradient["StartAlpha"]+$GradientAlphaOffset*$j); 533 $Object->drawFilledCircle($CenterX,$CenterY,($EdgeHeight/$Segments)*$j,$Color); 534 } 535 } 536 $Object->Shadow = $RestoreShadow; 537 } 538 539 /* Axis to axis lines */ 540 $Color = array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha); 541 for($j=1;$j<=$Segments;$j++) 542 { 543 $Radius = ($EdgeHeight/$Segments)*$j; 544 $Object->drawCircle($CenterX,$CenterY,$Radius,$Radius,$Color); 545 } 546 547 if ( $DrawAxisValues ) 548 { 549 if ( $LabelsBackground ) 550 $Options = array("DrawBox"=>TRUE, "Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"BoxR"=>$LabelsBGR,"BoxG"=>$LabelsBGG,"BoxB"=>$LabelsBGB,"BoxAlpha"=>$LabelsBGAlpha); 551 else 552 $Options = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE); 553 554 if ( $AxisBoxRounded ) { $Options["BoxRounded"] = TRUE; } 555 556 $Options["FontName"] = $AxisFontName; 557 $Options["FontSize"] = $AxisFontSize; 558 559 $Angle = 360 / ($Points*2); 560 for($j=1;$j<=$Segments;$j++) 561 { 562 $EdgeX1 = cos(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterX; 563 $EdgeY1 = sin(deg2rad($Angle+$AxisRotation)) * ($EdgeHeight/$Segments)*$j + $CenterY; 564 $Label = $j*$SegmentHeight; 565 566 $Object->drawText($EdgeX1,$EdgeY1,$Label,$Options); 567 } 568 } 569 570 /* Axis lines */ 571 $ID = 0; 572 for($i=0;$i<=359;$i=$i+$AxisSteps) 573 { 574 $EdgeX = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterX; 575 $EdgeY = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$TicksLength) + $CenterY; 576 577 $Object->drawLine($CenterX,$CenterY,$EdgeX,$EdgeY,$Color); 578 579 if ( $WriteLabels ) 580 { 581 $LabelX = cos(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterX; 582 $LabelY = sin(deg2rad($i+$AxisRotation)) * ($EdgeHeight+$LabelPadding+$TicksLength) + $CenterY; 583 $Label = $i."�"; 584 585 if ( $LabelPos == RADAR_LABELS_ROTATED ) 586 $Object->drawText($LabelX,$LabelY,$Label,array("Angle"=>(360-$i),"Align"=>TEXT_ALIGN_BOTTOMMIDDLE)); 587 else 588 { 589 if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE)); } 590 if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMLEFT)); } 591 if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLELEFT)); } 592 if ( (floor($LabelX) > floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPLEFT)); } 593 if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) < floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_BOTTOMRIGHT)); } 594 if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) == floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_MIDDLERIGHT)); } 595 if ( (floor($LabelX) < floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPRIGHT)); } 596 if ( (floor($LabelX) == floor($CenterX)) && (floor($LabelY) > floor($CenterY)) ) { $Object->drawText($LabelX,$LabelY,$Label,array("Align"=>TEXT_ALIGN_TOPMIDDLE)); } 597 } 598 } 599 $ID++; 600 } 601 602 /* Compute the plots position */ 603 $ID = 0; $Plot = ""; 604 foreach($Data["Series"] as $SerieName => $DataSet) 605 { 606 if ( $SerieName != $LabelSerie ) 607 { 608 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding); 609 foreach($DataSet["Data"] as $Key => $Value) 610 { 611 $Angle = $Data["Series"][$LabelSerie]["Data"][$Key]; 612 $Length = ($EdgeHeight/($Segments*$SegmentHeight))*$Value; 613 614 $X = cos(deg2rad($Angle+$AxisRotation)) * $Length + $CenterX; 615 $Y = sin(deg2rad($Angle+$AxisRotation)) * $Length + $CenterY; 616 617 if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("CIRCLE",floor($X).",".floor($Y).",".floor($PointRadius),$this->pChartObject->toHTMLColor($Palette[$ID]["R"],$Palette[$ID]["G"],$Palette[$ID]["B"]),$DataSet["Description"],$Data["Series"][$LabelSerie]["Data"][$Key]."° = ".$Value); } 618 619 $Plot[$ID][] = array($X,$Y,$Value); 620 } 621 $ID++; 622 } 623 } 624 625 /* Draw all that stuff! */ 626 foreach($Plot as $ID => $Points) 627 { 628 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding); 629 630 /* Draw the polygons */ 631 if ( $DrawPoly ) 632 { 633 if ($PolyAlpha != NULL) 634 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$PolyAlpha,"Surrounding"=>$PointSurrounding); 635 636 $PointsArray = ""; 637 for($i=0; $i<count($Points);$i++) 638 { $PointsArray[] = $Points[$i][0]; $PointsArray[] = $Points[$i][1]; } 639 640 $Object->drawPolygon($PointsArray,$Color); 641 } 642 643 $Color = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"],"Surrounding"=>$PointSurrounding); 644 645 /* Bubble and labels settings */ 646 $TextSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"FontName"=>$ValueFontName,"FontSize"=>$ValueFontSize,"R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"]); 647 $InnerColor = array("R"=>$InnerBubbleR,"G"=>$InnerBubbleG,"B"=>$InnerBubbleB,"Alpha"=>$InnerBubbleAlpha); 648 if ( $OuterBubbleR != VOID ) 649 $OuterColor = array("R"=>$OuterBubbleR,"G"=>$OuterBubbleG,"B"=>$OuterBubbleB,"Alpha"=>$OuterBubbleAlpha); 650 else 651 $OuterColor = array("R"=>$Palette[$ID]["R"]+20,"G"=>$Palette[$ID]["G"]+20,"B"=>$Palette[$ID]["B"]+20,"Alpha"=>$Palette[$ID]["Alpha"]); 652 653 /* Loop to the starting points if asked */ 654 if ( $LineLoopStart && $DrawLines ) 655 $Object->drawLine($Points[count($Points)-1][0],$Points[count($Points)-1][1],$Points[0][0],$Points[0][1],$Color); 656 657 /* Draw the lines & points */ 658 for($i=0; $i<count($Points);$i++) 659 { 660 if ( $DrawLines && $i < count($Points)-1) 661 $Object->drawLine($Points[$i][0],$Points[$i][1],$Points[$i+1][0],$Points[$i+1][1],$Color); 662 663 if ( $DrawPoints ) 664 $Object->drawFilledCircle($Points[$i][0],$Points[$i][1],$PointRadius,$Color); 665 666 if ( $WriteValuesInBubble && $WriteValues ) 667 { 668 $TxtPos = $this->pChartObject->getTextBox($Points[$i][0],$Points[$i][1],$ValueFontName,$ValueFontSize,0,$Points[$i][2]); 669 $Radius = floor(($TxtPos[1]["X"] - $TxtPos[0]["X"] + $ValuePadding*2)/2); 670 671 $this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius+$OuterBubbleRadius,$OuterColor); 672 $this->pChartObject->drawFilledCircle($Points[$i][0],$Points[$i][1],$Radius,$InnerColor); 673 } 674 675 if ( $WriteValues ) 676 $this->pChartObject->drawText($Points[$i][0]-1,$Points[$i][1]-1,$Points[$i][2],$TextSettings); 677 } 678 } 679 } 680 } 681?>