summaryrefslogtreecommitdiff
path: root/piechart.php
blob: ddb34c0c844756ac337fbc6e2e81686f8e1240c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php

/* 
A small PHP program and function that draws a pie chart in SVG format. 

Written by Branko Collin in 2008.

This code is hereby released into the public domain. In case this is not legally
possible: I, Branko Collin, hereby grant anyone the right to use this work for
any purpose, without any conditions, unless such conditions are required by law.
*/ 

/* Working with relative values confused me, so I worked with absolute ones 
instead. Generally this should not be a problem, as the only relative values you 
need are the chart's centre coordinates and its radius, and these are a linear
function of the bounding box size or canvas size. See the sample values for how 
this could work out. */

/* Sample values */
$values[] = 14625;
$values[] = 644;

$width = 400; // canvas size
$height = 400; 
$centerx = $width / 2; // centre of the pie chart
$centery = $height / 2;
$radius = min($centerx,$centery) - 10; // radius of the pie chart
if ($radius < 5) {
	die("Your chart is too small to draw.");
} 

/* Draw and output the SVG file. */

header('Content-type: image/svg+xml');

echo <<<END
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
	version="1.0" width="$width" height="$height" id="svg2">

  <title>Pie chart</title>
  <desc>Picture of a pie chart</desc>
END;

print piechart($values,200,200,190);

print "\n</svg>\n";


/* 
	The piechart function
	
	Arguments are an aray of values, the centre coordinates x and y, and 
	the radius of the piechart.
*/

function piechart($data, $cx, $cy, $radius) {
	$chartelem = "";

	$max = count($data);
	
//	$colours = array('#4e9a06','#a40000','#204a87','#5c3566','#ce5c00');
	$colours = array('#73d216','#cc0000','#3465a4','#75507b','#f57900');
//	$colours = array('#8ae234','#ef2929','#729fcf','#ad7fa8','#fcaf3e');
	
	$sum = 0;
	foreach ($data as $key=>$val) {
		$sum += $val;
	}
	$deg = $sum/360; // one degree
	$jung = $sum/2; // necessary to test for arc type
	
	/* Data for grid, circle, and slices */ 
	
	$dx = $radius; // Starting point: 
	$dy = 0; // first slice starts in the East
	$oldangle = 0;
	
	/* Loop through the slices */
	for ($i = 0; $i<$max; $i++) {
		$angle = $oldangle + $data[$i]/$deg; // cumulative angle
		$x = cos(deg2rad($angle)) * $radius; // x of arc's end point
		$y = sin(deg2rad($angle)) * $radius; // y of arc's end point
	
		$colour = $colours[$i];
	
		if ($data[$i] > $jung) {
			// arc spans more than 180 degrees
			$laf = 1;
		}
		else {
			$laf = 0;
		}
	
		$ax = $cx + $x; // absolute $x
		$ay = $cy + $y; // absolute $y
		$adx = $cx + $dx; // absolute $dx
		$ady = $cy + $dy; // absolute $dy
		$chartelem .= "\n";
		$chartelem .= "<path d=\"M$cx,$cy "; // move cursor to center
		$chartelem .= " L$adx,$ady "; // draw line away away from cursor
		$chartelem .= " A$radius,$radius 0 $laf,1 $ax,$ay "; // draw arc
		$chartelem .= " z\" "; // z = close path
		$chartelem .= " fill=\"$colour\" stroke=\"#FFFFFF\" stroke-width=\"3\" ";
		$chartelem .= " fill-opacity=\"1.0\" stroke-linejoin=\"round\" />";
		$dx = $x; // old end points become new starting point
		$dy = $y; // id.
		$oldangle = $angle;
	}
	
	return $chartelem; 
}

?>