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 "-->"
}
|