Data visualization with SAS programming

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

Reply
Frequent Contributor
Frequent Contributor
Posts: 81

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

HappyAnalogNewYear.gif

 

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;
Community Manager
Posts: 3,118

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
Ask a Question
Discussion stats
  • 2 replies
  • 496 views
  • 6 likes
  • 3 in conversation