diff options
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/piechart | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/bin/piechart b/bin/piechart new file mode 100755 index 0000000..c1a57ee --- /dev/null +++ b/bin/piechart @@ -0,0 +1,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 "-->" +} |
