Thursday, May 23, 2013

Drawing a pie chart with Adjustable Wedge using AppleScript

OmniGraffle has a set of built-in tools and shapes that you can reference by name in AppleScript. Some of these have special AppleScript access. These blessed shapes are Adjustable Wedge, Adjustable Arc, Adjustable Star, Adjustable Arrow, and Adjustable Double Arrow. (See Shapes in OmniGraffle's AppleScript Dictionary.)

Here I'll be focusing on the Adjustable Wedge, which is not in the Tools toolbar, but you can find it in the Common stencil under "Shapes."

Adjustable Wedge turns out to be very easy to manipulate, as it has the properties startAngle and endAngle for adjusting the outer arc, each of which goes from 0 to 360. If Adjustable Wedge were a clock, 0 would be 12 o'clock, 90 would be 3 o'clock, 270 would be 9 o'clock, and so on. (Adjustable Arc has the same properties.)

This makes creating a pie chart a piece of cake, as you just take the percentage of the chart that a piece of data would occupy, multiply it by 360, and that is the span of the arc. No trigonometry needed for calculating x,y postions on the arc. Adjustable Wedge handles that for you.

The code below creates this pie chart:



Previous AppleScript posts on this blog explain much of what is going on in the following script. I'll call out various lines of interest below it. Here are all posts about AppleScript on this blog.

-----

-- Copyright © 2013, Joseph Brick
-- All rights reserved. 
-- Redistribution, with or without modification, is permitted provided that the copyright notice is retained.

tell application id "OGfl"

    -- stuff the script user might want ot adjust
    set pieLoc to {50, 50}
    set pieDiameter to 400
    set wedgeValues to {24, 55, 77, 130, 37} -- values or percentages; doesn't matter
    set wedgeColors to {{1, 0, 0}, {0, 1, 1}, {1, 0, 1}, {0, 0, 1}, {0, 1, 0}} -- same length as wedgeValues
    set wedgeStartAngle to 0 -- angle at which first wedge starts drawing (0 is 12 o'clock, 180 is 6 o'clock)
   
    -- get the sum of all wedge values
    set sumOfWedgeValues to 0
    repeat with wedgeValue in wedgeValues
        set sumOfWedgeValues to sumOfWedgeValues + wedgeValue
    end repeat

    set wedges to {}  -- initialize list of wedge shapes to an empty list

   --draw one wedge per loop
    repeat with i from 1 to count of wedgeValues
        set wedgeDegrees to ((item i of wedgeValues) / sumOfWedgeValues) * 360  
        set wedgeEndAngle to wedgeStartAngle + wedgeDegrees

        tell canvas of  front window
            set wedge to make new shape at end of graphics with properties {name:"AdjustableWedge", size:{pieDiameter, pieDiameter}, origin:pieLoc, startAngle:wedgeStartAngle, endAngle:wedgeEndAngle, draws shadow:false, draws stroke:false, fill color:item i of wedgeColors}
        end tell

        set end of wedges to wedge  -- add wedge to list of wedges
        set wedgeStartAngle to wedgeEndAngle    -- start next wedge where this wedge ended
    end repeat
    assemble wedges -- group wedges
end tell

-----

repeat with i from 1 to count of wedgeValues

This is yet another form of the repeat loop. The value of variable i increases by 1 on each run through the loop, starting at 1, and ending at the number of items in the variable wedgeValues.

make new shape

This command draws each wedge. The easy way to find out how to make a given shape in AppleScript is to select that shape in OmniGraffle, and choose Edit > Copy As > AppleScript. This puts AppleScript on the clipboard that will draw this object or objects. Then it's just a matter of using variables for various properties instead of hard-coded values.

set end of wedges to wedge

It may seem counterintuitive, but setting the beginning or end of a list to something appends that something to that list. Here we are adding the latest Adjustable Wedge object we created (held by the variable wedge), and appending it to the list wedges, which we initialized as an empty list before the loop.

assemble wedges

The command assemble groups a list of objects. The variable wedges contains all of the wedges we drew. 

2 comments:

  1. Ooh, thank you! I've been creating pie charts in Excel, exporting as picture, placing picture into 'graffle and then tracing over them with line tool. So much easier!

    ReplyDelete
  2. Very useful, thanks very much.

    ReplyDelete