bash - ImageMagick - Pie Chart Script

This is a very simple script that will create a pie chart and legend using bash, bc, and ImageMagick. Many thanks to the link above which provided the algorithms to complete the SVG paths.

It accepts a list of parameters which must add up to 100. The script has two arrays, LABELS and COLORS which are applied to each parameter in order.


#!/bin/bash

function usage {
        echo "Usage: `basename $0` piece1 piece2 piece3 ..."
        echo -e "\tWhere each piece is a percentage of the pie"
        echo -e "\tThe pieces must add up to 100"
        exit $E_BADARGS
}

LABELS=("None"  "Accept" "Defer" "Discard")
COLORS=("#1c28a1"  "#107a3f" "#ff6d00" "#bf0000");

TARGET_DIR='images'

if [ $# -lt 3 ];
then
        usage
fi;

arc=()
sum=0
for piece in "$@"
do
        sum=$(( $piece + $sum ))
done

if [ $sum -ne 100 ];
then
        usage
fi

WIDTHxHEIGHT='330x330'
RADIUS=135
CENTERX=160
CENTERY=160

count=0
startAngle=0
endAngle=0
arc=0
total=0
x1=0
x2=0
y1=0
y2=0
pi=$(echo "scale=10; 4*a(1)" | bc -l)
cmd='convert -size '$WIDTHxHEIGHT' xc:white -stroke white -strokewidth 5 '
first=0
for piece in "$@"
do
        startAngle=$endAngle
        endAngle=$(echo "scale=10;$startAngle+(360*$piece/100)" | bc -l)
        x1=$(echo "scale=10;$CENTERX+$RADIUS*c($pi*$startAngle/180)" | bc -l)
        y1=$(echo "scale=10;$CENTERY+$RADIUS*s($pi*$startAngle/180)" | bc -l)
        x2=$(echo "scale=10;$CENTERX+$RADIUS*c($pi*$endAngle/180)" | bc -l)
        y2=$(echo "scale=10;$CENTERY+$RADIUS*s($pi*$endAngle/180)" | bc -l)
        if [ $piece -ge 50 ]
        then
                FIFTY=1
        else
                FIFTY=0
          fi
        cmd=$cmd"-fill '${COLORS[count]}' -draw \"path 'M $CENTERX,$CENTERY L $x1,$y1 A $RADIUS,$RADIUS 0 $FIFTY,1 $x2,$y2 Z'\" "

        count=$(( $count + 1 ))
done
cmd=$cmd" $TARGET_DIR/idea_chart.jpg"

eval $cmd

KEY_SIZE=20
MARGIN=5
TEXT_X=$(( $KEY_SIZE+$MARGIN ))

legends=$(( $#*($KEY_SIZE+$MARGIN) ))

cmd='convert -size 125x'$legends' xc:white -fill white '
label=" -font 'Nimbus-Sans-Bold' -stroke none -pointsize 12 "
count=0;
y1=5
for piece in "$@"
do
        y2=$(( $y1+$KEY_SIZE ))
        y3=$(( $y2-$MARGIN ))
        label=$label"-fill '${COLORS[count]}' -draw 'rectangle 0,$y1 $KEY_SIZE,$y2 ' -draw \"text $TEXT_X,$y3 '$piece% ${LABELS[count]}'\" "
        count=$(( $count + 1 ))
        y1=$(( $y1+$KEY_SIZE+$MARGIN ))
done
cmd=$cmd$label" $TARGET_DIR/idea_legend.jpg"

eval $cmd

exit; 

The FIFTY is used when an arc will span 50% or more of the pie, it sets the large-arc-flag.

This post courtesy of Worktrainer.