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-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

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