Lapis Lazuli | Level 10

## Fun With SAS ODS Graphics: New Year's Eve 7-Segment 'Shot Clock' Countdown Timer

Happy New Year!

It's time to roll out 2021 and ring in 2022, so here's an animated New Year's Eve 7-segment countdown timer that's inspired by basketball shot clocks. The x/y coordinates for the segments came from SVG polygon definitions found in Manuel Schulz's clever CodePen project ("Digital SVG clock to be set via css and attributes"), the 11:59 analog clock image is from Wikimedia user Micthev, and the champagne bottle is a low-res version of Adrien Coquet's "Champagne Party" icon at The Noun Project. Happy New Year, all!

* Fun W/SAS ODS Graphics: New Year's Eve 7-Segment "Shot Clock" Countdown Timer
Digital clock SVG x/y coordinates courtesy of Manuel Schulz (codepen.io/tornography/pen/qaBOLJ)
Clock image courtesy of Micthev (commons.wikimedia.org/wiki/File:Clock_11-59.svg)
Champagne icon courtesy of Adrien Coquet (thenounproject.com/icon/champagne-party-970849/);

data polygons(keep=digit polygon p x y color);                 * Create table of polygons for digits 0-9;
length x y 3;
input digits \$10. points \$60.;                                 * Read SVG x/y coordinates for segments for digits 0-9;
do digit=0 to 9;
i=1;
polygon+1;
color=ifn(index(digits,put(digit,1.))>0,1,0);                * Is segment lit for this digit?;
do while(scan(points,i,' ')^='');                            * Loop thru x/y point pairs;
p+1; x=scan(points,i,', '); y=scan(points,i+1,', '); i+2; output;
end;
end;
if _n_=1; digit=8; polygon+1; p+1; color=0; x=0; y=0; output;  * Need a non-displayable "off" polygon for 8;
datalines;
12347890  48 38 44 42 40 38 40 10 44 6 48 10 48 382
23567890  38 0 42 4 38 8 10 8 6 4 10 0 38 0
456890    8 38 4 42 0 38 0 10 4 6 8 10 8 38
2345689   38 40 42 44 38 48 10 48 6 44 10 40 38 40
2356890   38 80 42 84 38 88 10 88 6 84 10 80 38 80
2680      8 78 4 82 0 78 0 50 4 46 8 50 8 78
134567890 48 78 44 82 40 78 40 50 44 46 48 50 48 78
;
data countdown;                                                * Generate digits of countdown numbers 10->0;
length digit 3.;
do count=10 to 0 by -1;
place=1; digit=substr(put(count,z2.),1,1); output;           * Digit for tens place;
place=2; digit=substr(put(count,z2.),2,1); output;           * Digit for ones place;
end;

proc sql;                                                      * Merge countdown digits with polygons;
create table countdownpolygons as
select c.count, c.place, p.*
from countdown c join polygons p on p.digit=c.digit
order by count desc, place, polygon, p;
* Generate NYE countdown "shot clock" GIF (2-across panel of polygon plots);
options papersize=('6 in', '5.17 in') printerpath=gif animation=start
nodate nonumber animloop=YES animduration=2 NOANIMOVERLAY nobyline;
ods printer file='~/HappyNewYear2021.gif';                     * Build GIF from multiple images;
ods graphics / reset antialias border=no height=5.17in width=6in imagefmt=gif border=off;

data opening; x=0; y=0;                                        * Generate 2021 opening title frame;
proc sgplot data=opening noborder nowall noautolegend pad=0; styleattrs backcolor=black;
symbolimage name=midnight image='/home/ted.conway/1159.png';   * Clock image 11:59;
scatter x=x y=y / markerattrs=(symbol=midnight size=324pt);
xaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0; yaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0;
run;

options animduration=1;                                        * Generate countdown frames (10->0);
proc sgpanel data=countdownpolygons noautolegend subpixel pad=0;
by descending count;
panelby place / sort=data noborder noheader novarname nowall columns=2 onepanel; * One cell per digit;
styleattrs backcolor=black;
polygon x=x y=y id=polygon / fill  colorresponse=color colormodel=(cx171717 white); * Draw On (White) & Off ("Matte Black") segments;
colaxis  display=none values=(-5 to 53 by 58) offsetmin=0 offsetmax=0;
rowaxis display=none reverse values=(-5 to 93 by 98) offsetmin=0 offsetmax=0;
run;

%macro closing(text=2022,inset=HAPPY NEW YEAR!, icon=Y);       * Macro used to enerate closing title frames;
data closing; x=0; y=0; text="&text"; yImg=-.75;
proc sgplot data=title noborder nowall noautolegend pad=0; styleattrs backcolor=black;
inset "&inset" / noborder position=top textattrs=(weight=bold size=36pt color=white);
text x=x y=y text=text / position=center contributeoffsets=none strip textattrs=(color=white size=144pt weight=bold);;
symbolimage name=champagne image='/home/ted.conway/champagne.png'; * Show champagne icon?;
%if &icon=Y %then scatter x=x y=yImg / markerattrs=(symbol=champagne size=72pt);;
xaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0;
yaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0;
run;
%mend;

options animduration=1; %title; options animduration=.5;       * Generate 2022 closing title frames;
%title(inset=); %title; %title(inset=); %title; %title(inset=);* Make inset (Happy New Year!) blink several times for a half-second;
options animduration=1; %title; %title(text=,inset=,icon=N);   * Display blank frame before recycling GIF;
options printerpath=gif animation=stop;                        * Wrap-up animated GIF creation;
run;
ods printer close;

SAS ODS Graphics 'Shot Clock'