summaryrefslogtreecommitdiff
path: root/bin/piechart
blob: c1a57ee4ba2cd5f9c4ec779bf3a43a639ad6b4b1 (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
#!/usr/bin/awk -f
## piechart
#
# BUGS:
# Adjacient colours could have higher contrast.
# Negative angles.
#

function hex(i) {
	if (i < 16) {
		if (i < 1) {
			return ""
		} else if (i < 10) {
			return "" int(i)
		} else switch (int(i)) {
			case 10: return "a"
			case 11: return "b"
			case 12: return "c"
			case 13: return "d"
			case 14: return "e"
			case 15: return "f"
	}	}
	return hex(i/16) hex(i%16)
}
function phex(i) {
	if (i==0) { return "00" }
	if (i<16) { return "0" hex(i) }
	return hex(i)
}

BEGIN {
	print "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
	print "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1/EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
	print "<svg"
	print "	xmlns=\"http://www.w3.org/2000/svg\""
	print "	version=\"1.1\""
	print "	width=\"500\""
	print "	height=\"500\""
	print "	viewBox=\"0 0 500 500\""
	print ">"
	sum = 0
	values[0]=0
	labels[0]=""
}
END {
	tau = 2*atan2(0,-1)
	r = 100

	progress = 0
	overlap = 0
	for (i = 1;i < length(values);i++) {
		label = labels[i]
		number = values[i]
		angle = tau*number/sum
		fangle = angle < 0 ? -angle : (angle-overlap)

		x1 = r*cos(progress);
		y1 = r*sin(progress);
		x2 = r*cos(progress+fangle);
		y2 = r*sin(progress+fangle);
		divider = progress+fangle/2;
		xo = 250+(3*r/2*cos(divider));
		yo = 250+(3*r/2*sin(divider));

	#	rr = phex(int(0xff*((divider)/(tau))));
	#	gg = phex(int(0xff*((divider-tau/3)/(tau))));
	#	bb = phex(int(0xff*((divider-2*tau/3)/(tau))));

		rr = int(0xff*((divider)/(tau)))%0x100;
		gg = int(0xff*((divider+2*tau/3)/(tau)))%0x100;
		bb = int(0xff*((divider+tau/3)/(tau)))%0x100;

		# Mx,y : move to x,y
		# Lx,y : draw line to x,y
		# Arx,ry rot 0,0 x,y : arc with radii rx,ry rotated by rot large-arch or not,clockwise or not to point x,y
		# z : closes the path
		printf "<path stroke=\"#000000\" fill=\"#%02x%02x%02x\" d=\"M250,250 L%f,%f A%f,%f 0 %d,%d %f,%f z\"/>\n", rr,gg,bb,250+x1,250+y1,r,r,(fangle>tau/2),1,250+x2,250+y2
		if (label != "") {
			print "<line stroke=\"#000000\" x1=\"" 250+(2*r/3*cos(divider)) "\" y1=\"" 250+(2*r/3*sin(divider)) "\" x2=\"" xo "\" y2=\"" yo "\" />"
			print "<text x=\"" xo "\" y=\"" yo "\">" label "</text>"
		}

		progress += fangle;
		overlap -= angle; # multiple overlaps accumulate
		if (overlap<0) { overlap=0 }
	}
	print "</svg>"
}
# At the very least, we need a true value.
# Everything following it can be label or whatever.
/^[0-9]/ {
	values[length(values)] = $1
	sum += $1
	labels[length(labels)] = substr($0, length($1)+2)
}
# If the value is negative, it is meant to overlap with the previous record. Or records.
# The value would have to be ignored for computing the sum total.
/^-[0-9]/ {
	values[length(values)] = $1
	labels[length(labels)] = substr($0, length($1)+2)
}
# If there is no number, the line is obviously a comment and should be ignored.
!/^-?[0-9]/{
	print "<!-- " $0 "-->"
}