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

ParadeChart.png

 

After reading @Jay54's Pie Charts Redux, spotting Flag Print Dinner Paper Plates at Target, and seeing American Flag Doughnuts, what was I supposed to do - not try to create a (two-outcome) Stars-and-Stripes-Forever Donut Chart macro? Have a nice 4th of July!

 

* Fun w/SAS ODS Graphics, Stars-and-Stripes-Forever Donut Charts;

%macro RedWhiteAndBlueDonut(YES=, DONUTHOLE=);        /* Specify % for Yes wedge and text to apppear in center */
ods graphics on / height=5in width=5in;  
data stars(keep=x y);                                 /* Generate x/y points for white stars on blue background */
do y=-15 to 15;                                       /* 31 rows of 31 stars */                                       
  do x=-15 to 15;
    output;                                           
  end;
end;    

data stripes(keep=spolygon sx sy red);                /* Generate x/y points for polygons for stripes */
pi=constant('pi');
pctyes=&YES/100;                                      /* Convert to decimal */

if pctyes<.4999 then do;                              /* Stripes for top half of circle if needed (YES<50%) */
  red=1;                                              /* Alternate red and white stripes */
  do stripe=.25 to 16.25 by 1;                        /* Top semicirlce, center YES wedge at top middle */
    StartRadians=90/360*2*pi-.50*pctyes*2*pi;         /* Need to create diagonal edges for polygon stripes along wedges */
    spolygon+1;                                       /* Stripe plygons for left side of NO wedge */
    sy=stripe;          sx=-15;   output;             /* Upper left x/y point */
    sy=stripe;          sx=-(abs(sy)/sin(startradians))*cos(startradians);  output; /* Upper right x/y point */
    sy=max(stripe-1,0); sx=-(abs(sy)/sin(startradians))*cos(startradians);  output; /* Lower right x/y point */
    sy=max(stripe-1,0); sx=-15; output;               /* Lower left x/y point */
    spolygon+1;                                       /* Stripe polygons for right side of NO wedge */
    sy=stripe;          sx=(abs(sy)/sin(startradians))*cos(startradians);   output; /* Upper left x/y point */
    sy=stripe;          sx=15;  output;               /* Upper right x/y point */
    sy=max(stripe-1,0); sx=15;  output;               /* Lower right x/y point */
    sy=max(stripe-1,0); sx=(abs(sy)/sin(startradians))*cos(startradians); output; /* Lower left x/y point */  
    red=^red;                                         /* Alternate red and white stripes */
  end;
end;

lowerwedge=min(1-pctyes,.49999);                      /* Stripes for lower half of circle if needed (YES<100%) */                   
if lowerwedge>0 then do;
  red=0;                                              /* Alternate red and white stripes */
  do stripe=-14.75 to .25 by 1;                       /* Bottom semicirlce, center NO wedge at bottom middle */
    StartRadians=90/360*2*pi-.50*lowerwedge*2*pi;     /* Need to create diagonal edges for polygon stripes along wedges */ 
    spolygon+1;                                       /* Stripe polygons for NO wedge */
    sy=min(stripe,0); sx=-(abs(sy)/sin(startradians))*cos(startradians); output; /* Upper left x/y point */
    sy=min(stripe,0); sx=-sx;  output;                /* Upper right x/y point */
    sy=(stripe-1);    sx=(abs(sy)/sin(startradians))*cos(startradians);  output; /* Lower right x/y point */
    sy=(stripe-1);    sx=-sx; output;                 /* Lower left x/y point */
    red=^red;
  end;
  end;

data text;                                            /* Text for donut hole */
tx=0; ty=0; text="&DonutHole"; output;

data StarsAndStripes;                                 /* Combine stars, stripes, text */
set stars stripes text;

data mapStripes;                                      /* Attribute map to assign colors to stripes */
ID="Red"; value=1; linecolor="CXB22234"; fillcolor="CXB22234"; output;
ID="Red"; value=0; linecolor="WHITE"; fillcolor="WHITE"; output;

                                                     /* Draw stars-and-stripes-forever donut chart! */
proc sgplot data=StarsAndStripes noautolegend noborder pad=0 nowall dattrmap=mapStripes;
styleattrs backcolor=CX3C3B6E;                       /* "Old Glory Blue" background color */
symbolchar name=uniStar char='2605'x;                /* Unicode value for 5-pointed star */
xaxis display=none offsetmin=0 offsetmax=0 values=(-15 15); * Supress axes display;
yaxis display=none offsetmin=0 offsetmax=0 values=(-15 15);
scatter x=x y=y / markerattrs=(symbol=unistar color=CXFFFFFF size=18pt); * Stars (White);   
polygon x=sx y=sy id=spolygon / group=red fill nooutline attrid=Red;  * Stripes (Red & White);
ellipseparm semimajor=9 semiminor=9 / slope=0        /* Inner circle of donut (white) */
       xorigin=0 yorigin=0 fill fillattrs=(color=white);
ellipseparm semimajor=9 semiminor=9 / slope=0        /* Inner circle line */
       xorigin=0 yorigin=0 lineattrs=(color=black thickness=1pt);       
text x=tx y=ty text=text / splitchar='*' strip splitpolicy=splitalways textattrs=(size=16pt weight=bold); * Donut hole text;
ellipseparm semimajor=20 semiminor=20 / slope=0      /* Outer circle with really thick line to "crop" stars/stripes image into circle */
       xorigin=0 yorigin=0 lineattrs=(color=white thickness=128pt);       
run;
%mend;

* Fun Facts about the 4th of July: themuse.com/advice/34-fun-facts-about-the-4th-of-july;

%RedWhiteAndBlueDonut(YES=32, DONUTHOLE=WATCH*4TH OF JULY PARADE?*YES: 32%  NO: 68%);
%RedWhiteAndBlueDonut(YES=63, DONUTHOLE=ATTEND*FIREWORKS DISPLAY?*YES: 63%  NO: 37%);

FireworksChart.png 

3 REPLIES 3
MichelleHomes
Meteorite | Level 14

I love how you shared your inspiration for the Stars-and-Stripes donut charts and the very cool code!

 

Always impressed with your SAS ODS Graphics fun. Robot Happy

 

Thanks for sharing - especially on your holiday!

 

Cheers,

Michelle

//Contact me to learn how Metacoda software can help keep your SAS platform secure - https://www.metacoda.com
PGStats
Opal | Level 21

I wish everyone, including myself, commented their code this well!

PG

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

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

View all other training opportunities.

Discussion stats
  • 3 replies
  • 1792 views
  • 12 likes
  • 4 in conversation