## Fun With SAS ODS Graphics: New Year's Eve Analog Clock Countdown

Frequent Contributor
Posts: 89

# Fun With SAS ODS Graphics: New Year's Eve Analog Clock Countdown

ODS Graphics take on a brewpub's NYE party invite. Happy New Year, all!

``````* Fun w/SAS ODS Graphics: New Year's Eve Analog Watch Countdown;

data clock1;                                           * Generate points for clock seconds (text plot - filled circles);
pi=constant('pi');
do remaining=0 to 10;                                  * Generate one "frame" for each countdown second;
do seconds=0 to 59;
tick=.;
xTxt=cos(seconds/60*2*pi);                           * Second markers aranged around circle of radius=1;
yTxt=sin(seconds/60*2*pi);
if mod(seconds,5) then output;                       * Every 5th second is plotted as a bar (see next step);
end;
end;

data clock2;                                           * Generate points for clock seconds (vector plot line segments);
pi=constant('pi');
do remaining=0 to 10;                                  * Generate one "frame" for each countdown second;
do seconds=0 to 55 by 5;                               * Every 5th second is plotted as a bar instead of circle;
vX1=.925*cos(seconds/60*2*pi);                       * Line segments extend beyond seconds markers;
vX2=1.075*cos(seconds/60*2*pi);
vY1=.925*sin(seconds/60*2*pi);
vY2=1.075*sin(seconds/60*2*pi);
output;
end;
end;

data clock3;                                           * Generate points for clock seconds hand (vector plot line);
pi=constant('pi');
do seconds=50 to 60;                                   * Generate one "frame" for each countdown second;
remaining=60-seconds;
vXsec=1.075*sin(seconds/60*2*pi);                    * Seconds hand extends to length of bars;
vYsec=1.075*cos(seconds/60*2*pi);
output;
end;

data clock4;                                           * Generate points for clock minute hand (vector plot line);
pi=constant('pi');
do seconds=50 to 60;                                   * Generate one "frame" for each countdown second;
remaining=60-seconds;
vXmin=1.075*sin((59*60+seconds)/(60*60)*2*pi);       * Minutes hand extends to length of bars;
vYmin=1.075*cos((59*60+seconds)/(60*60)*2*pi);
output;
end;
run;

data clock5;                                           * Generate points for clock hour hand (vector plot line);
pi=constant('pi');
do seconds=50 to 60;                                   * Generate one "frame" for each countdown second;
remaining=60-seconds;                                * Hours hand is shorter than seconds/minutes hands;
vXhr=.7*sin((11*60*60+59*60+seconds)/(12*60*60)*2*pi);
vYhr=.7*cos((11*60*60+59*60+seconds)/(12*60*60)*2*pi);
output;
end;
run;

data clock6;                                           * Generate countdown text, points (text plot);
do remaining=10 to 1 by -1;                            * Generate one "frame" for each countdown second;
text=compress(put(remaining,2.));
txtX=0; txtY=0;
output;
end;

data clock7;                                           * Generate "Happy New Year" text, point (text plot);
remaining=0;                                           * Last frame;
text2="Happy*New Year!*2018";
txt2X=0; txt2Y=0;

data clock;                                            * Merge chart datasets;
set clock1 clock2 clock3 clock4 clock5 clock6 clock7;

proc sort data=clock;                                  * Sort by countdown (desc seconds remaining);
by descending remaining;

proc format;                                           * Unicode filled circle character for circles on clock;
value tickfmt other="(*ESC*){unicode '25CF'x}";

proc template;                                         * Create animated GIF "clock" with countdown;
define statgraph newyearplot;
begingraph / opaque=true border=false drawspace=layoutpercent backgroundcolor=black;
layout overlayequated / equatetype=square border=false
WALLDISPLAY=NONE commonaxisopts=(viewmin=-1.15 viewmax=1.15 tickvaluelist=(-1.15 1.15))
xaxisopts=(display=none OFFSETMAX=0 OFFSETMIN=0) yaxisopts=(display=none OFFSETMAX=0 OFFSETMIN=0);
/* Countdown text (10.9.8.7.6.5.4.3.2.1) */
textplot x=txtX y=txtY text=text / position=center vcenter=bbox splitchar='*' contributeoffsets=none
textattrs=(size=216pt weight=bold color=silver) strip=true;
/* Watch dial seconds markers (cirlces) */
textplot x=xTxt y=yTxt text=tick / position=center vcenter=bbox strip=true contributeoffsets=none
textattrs=(size=18pt weight=bold color=silver);
/* Watch dial seconds markers (every 5th marker is a bar) */
vectorplot xorigin=vX1 x=vX2 yorigin=vY1 y=vY2 / lineattrs=(thickness=7pt color=silver)arrowheads=false;
/* Seconds hand */
vectorplot xorigin=0 x=vXsec yorigin=0 y=vYsec / lineattrs=(thickness=3pt color=white) arrowheads=false;
/* Minutes hand */
vectorplot xorigin=0 x=vXmin yorigin=0 y=vYmin / lineattrs=(thickness=4pt color=white) arrowheads=false;
/* Hours hand */
vectorplot xorigin=0 x=vXhr yorigin=0 y=vYhr / lineattrs=(thickness=9pt color=white) arrowheads=false;
/* Center of watch dial (white circle) */
ellipseparm xorigin=0 yorigin=0 semimajor=.07 semiminor=.07 slope=0 / display=(fill outline) fillattrs=(color=white) outlineattrs=(color=black);
/* Center of watch dial (black dot) */
ellipseparm xorigin=0 yorigin=0 semimajor=.03 semiminor=.03 slope=0 / display=(fill outline) fillattrs=(color=black) outlineattrs=(color=black);
/* Happy New Year! 2018 greeting */
textplot x=txt2X y=txt2Y text=text2 / position=center vcenter=bbox splitchar='*' splitpolicy=splitalways backlight=1
textattrs=(size=50pt weight=bold color=silver) contributeoffsets=none strip=true;
endlayout;
endgraph;
end;

options nobyline;                                      * Animated GIF initialization;
ods _all_ close;
options papersize=('5 in', '5 in') printerpath=gif animation=start
nodate nonumber animloop=YES animduration=1 NOANIMOVERLAY ;
ods printer file='/folders/myfolders/HappyAnalogNewYear/HappyAnalogNewYear.gif';
ods graphics / width=5in height=5in imagefmt=GIF border=off;
* Generate 10-9-8-7-6-5-4-3-2-1 countdown frames;
proc sgrender data=clock(where=(remaining>0)) template=newyearplot;
by descending remaining;
format tick tickfmt.;
run;                                                   * Generate Happy New Year! 2018 frame;
options animduration=5;                                * Freeze last frame for 5 seconds;
proc sgrender data=clock(where=(remaining=0)) template=newyearplot;
format tick tickfmt.;

options printerpath=gif animation=stop;                * Wrap-up animated GIF creation;
run;
ods printer close;``````
Highlighted
Community Manager
Posts: 3,357

## Re: Fun With SAS ODS Graphics: New Year's Eve Analog Clock Countdown

I love it!  Just enough geometry at work to provide a math nerd fix.

Sorry I didn't see this before New Year's Eve - I would have projected it during our gathering as midnight approached.

New Contributor
Posts: 2

## Re: Fun With SAS ODS Graphics: New Year's Eve Analog Clock Countdown

Its wonderfull

With SAS , can you do anything???

Thanks to open my eyes
Discussion stats
• 2 replies
• 735 views
• 6 likes
• 3 in conversation