Drawing dynamic arcs with PHP
A few years ago I was managing a web project where part of the requirement was to render a coloured rainbow representing achievement against a number of dimensions. The (existing) solution used Flash to achieve this, but this caused our users a lot of issues because they (variously) had flash disabled, the wrong version etc etc
Our developers at the time had dismissed alternate versions as not possible. However, I had a little spare time one weekend and built a solution using PHP.
The code
This page is just a simple html form allowing the values to be entered as percentages. In the production system these would be calculated from a range of metrics, which I’m emulating here using the form. Then, these values are used to dynamically create the image using this PHP. The approach I’ve taken is to draw a series of concentric segments, decreasing in size, so the subsequent segments are drawn on top of the previous segments, resulting in the concentric arcs.
<?php // create a 600 by 300px image $Image = imagecreatetruecolor(600, 300); //set some colours $Grey = imagecolorallocate($Image,220,220,220); $White = imagecolorallocate($Image, 255, 255, 255); $Black = imagecolorallocate($Image, 0, 0, 0); $Green[0]= imagecolorallocate($Image, 166, 206, 57); $Green[1] = imagecolorallocate($Image, 23, 206, 57); $Green[2] = imagecolorallocate($Image, 0, 174, 57); $Green[3] = imagecolorallocate($Image, 0, 141, 51); $Green[4] = imagecolorallocate($Image, 0, 126, 57); //set the centre position for all the arcs $CenterX = 300; $CenterY= 250; $arc = array(470,430,390,340,300);//an array holding the starting point for each arc //calculate the ending value of each arc in degrees based on form values //set 181 as the minimum value otherwise the arc doesn't display properly $end[0]=max(($_GET['arc1']*1.8)+180,181); $end[1]=max(($_GET['arc2']*1.8)+180,181); $end[2]=max(($_GET['arc3']*1.8)+180,181); $end[3]=max(($_GET['arc4']*1.8)+180,181); $end[4]=max(($_GET['arc5']*1.8)+180,181); $Start=180;//starting point for all the arcs imagefill($Image,0,0,$White);//white background imagesetthickness($Image,1);//set the thickness of lines to 1px //loop through all the arcs for ($i=0; $i<=4; $i++) { // draw the arcs imagefilledarc($Image, $CenterX, $CenterY, $arc[$i], $arc[$i], 180, 0, $Grey, IMG_ARC_EDGED);//draw the whole arc in grey - to cover anything from the previous green arc imagefilledarc($Image, $CenterX, $CenterY, $arc[$i], $arc[$i], $Start, $end[$i], $Green[$i], IMG_ARC_EDGED);//draw a green filled arc in green to the right size imagearc($Image, $CenterX, $CenterY, $arc[$i], $arc[$i], $Start, 0, $Black);//draw a black line outside the green arc } imagefilledarc($Image, $CenterX, $CenterY, 260, 260, $Start, 0, $White, IMG_ARC_EDGED);//draw a white filled arc inside the last green arc imagearc($Image, $CenterX, $CenterY, 260, 260, $Start, 0, $Black);//draw the last black line inside the last arc // output image in the browser header("Content-type: image/png"); imagepng($Image); // free memory imagedestroy($Image); ?>
The demo
Here’s the result:
Thanks, bon site