BookmarkSubscribeRSS Feed
Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10



To mark the close of the old year and beginning of the new, here's a short program for a Pac-Man inspired New Year's Eve countdown timer. Who says you shouldn't use Pie Charts? Smiley Happy Happy New Year, all!


Btw, for a compilation of past Fun-With-SAS-ODS-Graphics posts, check out Oh, There’s No Place Like SAS ODS Graphics for the Holidays! Silly, yes, but also illustrates some techniques you may find useful for creating reproducible and scalable graphics in your Day Job!


* Fun With SAS ODS Graphics: Pac-Man inspired New Years Eve 2019 Pie Chart countdown timer;

data slices;                                 * Create SAS data for pie charts;
do r=1 to 10;                                * 10-9-8-7-6-5-4-3-2-1 countdown (seconds);
do p=0 to 20 by 2.5, 20 to 0 by -2.5;        * 18 charts for each second (mouth closed=0% to wide-open=20%, and back again!);    
  n+1;                                       * Assign unique # to each chart (2 slices/chart);
  slice=1; pct=p;     output;                * 1st slice for "mouth";
  slice=2; pct=100-p; output;                * 2nd slice for remainder;

proc template;                               * Template for New Years Eve countdown timer chart (pie chart + text);                         
define statgraph pacman;                
mvar Yr remainSec unicodeSec xLoc Msg;       * Parameters: year, remaining seconds, Unicode secs, x-location (%), Happy New Year message;
begingraph / subpixel=on border=false datacolors=(black CXFFFF00) backgroundcolor=black pad=0in; * Like game, make "Pac-Man" yellow, with black "mouth";
layout region / border=false backgroundcolor=black outerpad=1in; * Provide some padding for text;
piechart category=slice response=pct / datalabelcontent=none centerfirstslice=true display=(fill); 
drawtext textattrs=(size=36pt color=CX00ff00 weight=bold) Yr / y=100 anchor=top widthunit=percent width=100 yspace=graphpercent xspace=graphpercent; * Green year;
drawtext textattrs=(size=16pt color=CX00ff00 weight=bold) remainSec / y=5 anchor=bottom widthunit=percent width=100 yspace=graphpercent xspace=graphpercent; * Green seconds remaining;
drawtext textattrs=(size=24pt color=CXFFFF00 weight=bold family="Arial Unicode MS") {unicode unicodeSec} / y=50.5 anchor=right x=xLoc widthunit=percent width=100 yspace=graphpercent xspace=graphpercent; * Yellow "dots" with seconds remaining;
drawtext textattrs=(size=24pt color=CX1919A6 weight=bold) Msg / justify=center y=50 anchor=center x=50 widthunit=percent width=50 yspace=graphpercent xspace=graphpercent; * Blue-ish Happy New Year message;

ods _all_ close;                             * Animated GIF setup (pause for 1.5 secs on 1st frame);                       
options papersize=('3 in', '3 in') printerpath=gif animation=start nodate nonumber animduration=1.5 animloop=NO NOANIMOVERLAY;
ods printer file='/folders/myfolders/PacMan.gif'; * Animated GIF image filename;
ods graphics / height=3in width=3in imagefmt=gif antialias; 

%macro genframes;                            /* Generate 180-frame coundown (10 seconds * 18 frames/second) */ 
%do s=10 %to 1 %by -1;                       /* Generate set of 18 frames for each second in 10-second countdown */
  %let UnicodeSec="%scan(2460 2461 2462 2463 2464 2465 2466 2467 2468 2469, &s, ' ')"x; /* Unicode values for animated dots filled with remaining secs (10, 9, ..., 1) */
  %let RemainSec="Time Remaining: 00:%sysfunc(putN(&s,z2.))"; /* Display remaining secs at bottom of image */
  %do c=1 %to 18;                            /* Generate frames for one second interval */                           
    %let n=%eval((&s-1)*18+&c);              /* Determine pie chart # (used to select data generated earlier) */
    %let xLoc=%scan(100 98 96 94 92 90 88 86 84 82 80 78 76 74 72 70 68 66, &c, ' '); /* X-coordinates (%'s) for animated dot that show seconds remaining */
    proc sgrender data=slices(where=(n=&n)) template=pacman; /* Create pie charts! */
    options animduration=.056;               /* Try to make total duration of 10 seconds-ish (180 images x .056 sec/image) */

%let Yr="2018";                              * Display old year (2018);
%let Msg="";                                 * No Happy New Year message until end;
%genframes;                                  * Issue macro call to generate 180 frames!;

options animduration=1.5;                    * Display "GAME OVER" frame at bottome of screen for 1.5 seconds;
%let RemainSec="GAME OVER";
proc sgrender data=slices(where=(n=180)) template=pacman; * Create pie chart|;

options animduration=3;                      * For 3 seconds, show final frame...;
%let Yr="2019";                              * Display new year (2019) at top of screen;
%let Msg="HAPPY NEW YEAR!";                  * Display "HAPPY NEW YEAR" over pie chart in middle of screen; 
%let RemainSec="PRESS START";                * Display "PRESS START" at bottom of screen;
proc sgrender data=slices(where=(n=180)) template=pacman; * Create pie chart!;

options printerpath=gif animation=stop;      * Animated GIF wrap-up;
ods printer close;


Meteorite | Level 14

Nice work, TC.  Good to see a natural use case for CenterFirstSlice option.

Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10



Lest the above give people the idea it takes lots of code to render a pie chart with SAS, here's all it takes to recreate the famous "Percentage of Chart Which Resembles Pac-Man" joke using the SGPIE procedure (pre-production) that's included with SAS 9.4M6. And, if you want more options, check out the GTL PIECHART statement examples!


* Fun w/SAS ODS Graphics - Recreate "Percentage of Chart Which Resembles Pac-Man" pie chart joke w/PROC SGPIE
  Original circa-2006 joke at;

data slices;                         * Generate pie chart data;
input pct 1-3 slice $25.;
80 Resembles Pac-Man
20 Does not resemble Pac-Man
proc sgpie data=slices;              * Create chart;
title "Percentage of Chart Which Resembles Pac-Man";
styleattrs datacolors=(yellow deeppink);
pie slice / response=pct startangle=180 datalabeldisplay=none sliceorder=data; 
label slice='';



Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Get the $99 certification deal.jpg



Back in the Classroom!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 2 in conversation