Home > Miscellaneous > Making graphs with PHP

Making graphs with PHP

February 26th, 2010

Like I promised yesterday, here's the tutorial for creating little fancy graphs.

Actual result:


First things first. Figure out what offsets you will need to display the graph in. Easiest way is to do this by drawing up a little box on a piece of paper or in paint. If you're too lazy for this, there's one after the jump:

And you need to know that the X and Y-coordinates you need always start at the top left.

Let us jump right into the beginning and create an actual image.

$img = imagecreate(160,110);
imagecolorallocatealpha($img, 247,247,247,127);

They speak for theirselves. We're making an image 160 pixels wide by 110 pixels high (110 pixels is easy to make this work with; 5 pixels margin and you have 100 pixels height left. Thats 1 pixel for each percent.). Then we assign the background colour for this image. Namely rgb(247,247,247), but beware because the last argument we passed is the transparency, where 0 means completely opaque and 127 completely see-through.

So now we have a 160x110 pixel transparent image. What I like to do now is add a black line that defines the lower bound, or the line that represents zero in this case. But before we can do this, we need to assign some colours.

$black = imagecolorallocate($img,0,0,0);
$graph = imagecolorallocate($img,47,116,168);
$shadow = imagecolorallocate($img,195,195,195);

Now it's time to draw the actual line, for this we use the function imageline(handle, Xstart, Ystart, Xend, Yend, colour). The X is the offset to the right. Since it's a horizontal line we'll draw the line from 5 - 155 and leave a 5 px border. The height at which we need to draw is 110 - margin, so 105 pixels deep.

imageline($img, 5, 105, 155, 105, $black);

We now have the base line, and we know how much higher it can go (100 px). But since the coordinates start at the top left instead of bottom left like in a graph, we will need the complement of the height. So for example:

$y = (105 - $value);

Let's assume you have all values in an array. We'll read them in to our own array with X and Y coordinates so we can use it with imagefilledpolygon(). Thing is, if we want a filled graph (we do), we'll also need to specify the baseline so it knows from where to fill. And instead of starting on top of the base, we'll start 1 px higher.

$points = array(
	5, 104,
	155, 104,
$pos = 0;
foreach ($array as $key => $value) {
	$points[] = ($pos+= 5);
	$points[] = 104-$value;

I'll assume you have an array with size 30 so we can draw a point every 5px. If you don't, put this before the points key to fill in some random numbers.

$array = array();
for ($i = 0; $i <= 30; $i++)
	$array[] = rand(30,70);

And don't forget to show it with imagefilledpolygon(handle, pointArray, pointCount, colour):

imagefilledpolygon($img, $points, count($points)/2, $graph);

Now we'll have created this:

Bit bleak isn't it?
I'm no graphical designer by far, but I do like the looks of adding a little shadow behind the actual graph.
Try inserting this part before the foreach() loop:

$highlight = array(3, 104, 153, 104);

And editing the loop that it says this instead:

$pos = 0;
foreach ($array as $key => $value) {
	$highlight[] = ($pos + 3); // Two pixels to the left
	$highlight[] = 104 - $value + 3;  // And three pixels up
	$points[] = ($pos+= 5);
	$points[] = 104-$value;

And don't forget to show this polygon BEFORE you output the actual graph.

imagefilledpolygon($img, $highlight, count($highlight)/2, $shadow);

And last, but definitely not least, output the graph:

header('Content-Type: image/png');


Ta da!

Popularity: 22% [?]


  1. July 31st, 2014 at 18:56 | #1

    Great post. I was checking continuously this blog and I am impressed!

    Very useful information specially the closing section :)
    I maintain such info much. I was looking for this particular info for
    a very lengthy time. Thank yoou and good luck.

  2. August 4th, 2014 at 23:52 | #2

    Thanks , I have just been looking for info about this subject for a while and
    yours is the best I have found out till now. However, what in regards to the
    conclusion? Are you certain in regards to the source?

  3. August 9th, 2014 at 02:38 | #3

    whoah this weblog is fantastic i love reading your articles.

    Keep up the great work! You recognize, a lot of people are looking round for
    this info, you could aid them greatly.

  4. August 16th, 2014 at 16:14 | #4

    Hi everyone, it’s my first pay a visit at this web page, and paragraph is in fact fruitful designed for me, keep up posting these content.

  5. January 3rd, 2015 at 15:05 | #5

    Hello there, You’ve done an excellent job. I will definitely digg it and personally recommend to my friends.
    I am sure they’ll be benefited from this website.

  6. February 11th, 2015 at 08:44 | #6

    Appreciating the time and effort you put into your
    site and in depth information you provide. It’s great to come
    across a blog every once in a while that isn’t the same unwanted rehashed material.
    Fantastic read! I’ve bookmarked your site and I’m adding your RSS feeds to my Google account.

    creditos rapidos sin nomina

Comment pages
  1. No trackbacks yet.