/**********************************************************************/ data st_data1; input state $ sites product; cards; AL 90 1 FA 22 1 GA 46 1 NY 55 1 VT 38 1 AL 45 2 FA 29 2 GA 41 2 NY 36 2 VT 24 2 ; run; /**********************************************************************/ proc means data=st_data1 noprint; by product state; var sites; output out=st_data2 sum=sum1; run; /**********************************************************************/ proc means data=st_data2 noprint; by product; var sum1; output out=st_data3 sum=sum2; run; /**********************************************************************/ data merged; merge st_data2 st_data3; by product; run; /**********************************************************************/ data st_data; keep sum product sum1; set merged; by product; sum = round(sum1 / sum2 * 360); run; /**********************************************************************/ proc print; title 'Output 1'; run; /**********************************************************************/ goptions reset=all gunit=pct cback=white ctext=black border target=dj1200ps; /**********************************************************************/ %MACRO PIE3D( ds, /* Input data set */ slc_cnt, /* Number of midpoint values, ie., number of pie slices */ slice1, /* List the midpoint values in order */ slice2, slice3, slice4, slice5, color1, /* List the colors of the pie slices in order */ color2, color3, color4, color5, shade, /* Color of the pie's edge */ outline, /* Color of the pie's outline */ val_col, /* Color of the pie's slice */ xcenter, /* Horizontal center of the pie (pct) */ ycenter, /* Vertical center of the pie (pct) */ majaxis, /* Horizontal length of the pie (pct) */ minaxis, /* Vertical length of the pie (pct) */ thicknes, /* Thickness of the pie (pct) */ legnlabl, /* Legend label */ legendx, /* Horizontal center of the legend (pct) */ legendy, /* Vertical center of the legend (pct) */ titlex, /* Horizontal position of the title (pct) */ titley, /* Vertical position of the title (pct) */ titletxt, /* Text of the title */ by_var /* The BY variable used to create multiple pies */ ); /**********************************************************************/ goptions colors=(&color1 &color2 &color3 &color4 &color5 &shade &outline &val_col); /**********************************************************************/ data b; drop sum sum1 i; retain i 1; array slice{&slc_cnt} s1 - s&slc_cnt; array sliceb{&slc_cnt} sb1 - sb&slc_cnt; do i = 1 to &slc_cnt; set &ds; by &by_var; slice{i} = sum; sliceb{i} = sum1; end; run; proc print; title 'Output 2'; run; /**********************************************************************/ goptions reset=title; /**********************************************************************/ data piechart; array slice{&slc_cnt} s1 - s&slc_cnt; array sliceb{&slc_cnt} sb1 - sb&slc_cnt; set b; by &by_var; x=&xcenter; y=&ycenter; maj=&majaxis; min=&minaxis; rc=ginit(); rc=graph('clear', 'piechart'); rc=gset('window',1,0,0,100,100); rc=gset('transno',1); /**********************************************************************/ /* Draw the bottom of the pie. */ rc=gset('filcolor', &slc_cnt+1); rc=gset('filtype', 'solid'); rc=gdraw('ellipse', x, y-&thicknes, maj, min, 0, 360, 0); /* Draw the outline of the bottom of the pie. */ rc=gset('filcolor', &slc_cnt+2); rc=gset('filtype', 'hollow'); rc=gdraw('ellipse', x, y-&thicknes, maj, min, 0, 360, 0); /* Draw the i'th pie slice. */ total_s = 0; %do i = 1 %to &slc_cnt; rc=gset('filcolor', &i); rc=gset('filtype', 'solid'); rc=gdraw('ellipse', x, y, maj, min, total_s, s&i+total_s, 0); /* Draw the outline for the i'th pie slice. */ rc=gset('filcolor', &slc_cnt+2); rc=gset('filtype', 'hollow'); rc=gdraw('ellipse', x, y, maj, min, total_s, s&i+total_s, 0); /* Calculate the x and y position along the outer edge for the */ /* center of the i'th pie slice. */ pi=arcos(-1); tilt_ang=0; if (&i = 1) then end_ang = (s&i/2)*pi/180; if (&i > 1) then end_ang=((total_s + s&i - (s&i/2))*pi)/180; xtop=&xcenter + (cos(tilt_ang) * cos(end_ang) * &majaxis*.6) - (&minaxis*.6 * sin(end_ang) * sin(tilt_ang)); ytop=&ycenter + (sin(tilt_ang) * cos(end_ang) * &majaxis*.6) + (&minaxis*.6 * sin(end_ang) * cos(tilt_ang)); /* Position the i'th pie slice value away from the pie so */ /* that the text does not overlay the pie. */ rc=gset('texfont', 'swiss'); rc=gset('texcolor', &slc_cnt+3); rc=gset('texheight',2.5); if (s&i/2 + total_s le 90) then do; xtop=xtop-&thicknes; rc=gdraw('text',xtop,ytop,left(trim(put(sb&i,4.0)))); end; if (s&i/2 + total_s > 90) and (s&i/2 + total_s le 180) then do; xtop=xtop-&thicknes*3; rc=gdraw('text',xtop,ytop,right(trim(put(sb&i,4.0)))); end; if (s&i/2 + total_s > 180) and (s&i/2 + total_s le 270) then do; xtop=xtop-&thicknes*3; ytop=ytop-&thicknes*2; rc=gdraw('text',xtop,ytop,right(trim(put(sb&i,4.0)))); end; if (s&i/2 + total_s > 270) then do; xtop=xtop-&thicknes; ytop=ytop-&thicknes*2; rc=gdraw('text',xtop,ytop,left(trim(put(sb&i,4.0)))); end; /* Draw a vertical line on the edge of the pie to separate the */ /* slices that are positioned in the bottom half of the pie. */ total_s = total_s + s&i; if (total_s > 180) and (total_s < 360) then do; pi=arcos(-1); tilt_ang=0; end_ang=(total_s*pi)/180; xtop=&xcenter + (cos(tilt_ang) * cos(end_ang) * &majaxis*.5) - (&minaxis*.5 * sin(end_ang) * sin(tilt_ang)); ytop=&ycenter + (sin(tilt_ang) * cos(end_ang) * &majaxis*.5) + (&minaxis*.5 * sin(end_ang) * cos(tilt_ang)); xbottom=&xcenter + (cos(tilt_ang) * cos(end_ang) * &majaxis*.5) - (&minaxis*.5 * sin(end_ang) * sin(tilt_ang)); ybottom=&ycenter-&thicknes + (sin(tilt_ang) * cos(end_ang) * &majaxis*.5) + (&minaxis*.5 * sin(end_ang) * cos(tilt_ang)); rc=gset('lincolor', &slc_cnt+2); rc=gset('linwidth', 1); rc=gdraw('line', 2, xtop, xbottom, ytop, ybottom); end; %end; /* Display the first title. */ rc=gset('texfont', 'swissb'); rc=gset('texcolor', 1); rc=gset('texheight',4); rc=gdraw('text',&titlex, &titley, "&titletxt"); /* Display the second title. This section of code is optional. */ rc=gset('texfont', 'swiss'); rc=gset('texcolor', 1); rc=gset('texheight',3); rc=gdraw('text',37, &titley-4, upcase("&by_var ")||put(product,2.)); /* Display the legend label. */ rc=gset('texfont','swissb'); rc=gset('texcolor', 1); rc=gset('texheight',3); rc=gdraw('text',&legendx-5, &legendy, "&legnlabl"); /* Draw the i'th legend bar. */ y_pos = &legendy-3; %do i = 1 %to &slc_cnt; rc=gset('filcolor', &i); rc=gset('filtype', 'solid'); rc=gdraw('bar',&legendx-6, y_pos-3, &legendx-3, y_pos); /* Draw the i'th legend value. */ rc=gset('texfont', 'swiss'); rc=gset('texcolor', 1); rc=gset('texheight', 3); rc=gdraw('text', &legendx, y_pos-3, "&&slice&i"); y_pos=y_pos-4; %end; /* Display the graph and end DSGI. */ rc=graph('update'); rc=gterm(); run; /* End the macro definition. */ %MEND PIE3D; /* Finally, make the macro call to PIE3D. */ %PIE3D( ds=st_data, /* Input data set */ slc_cnt=5, /* Number of midpoint values, ie., number of pie slices */ slice1=Alabama, /* List the midpoint values in order */ slice2=Florida, slice3=Georgia, slice4=New York, slice5=Vermont, color1=blue, /* List the colors of the pie slices in order */ color2=green, color3=gold, color4=magenta, color5=olive, shade=graybb, /* Color of the pie's edge */ outline=black, /* Color of the pie's outline */ val_col=black, /* Color of the pie's slices */ xcenter=50, /* Horizontal center of the pie (pct) */ ycenter=61, /* Vertical center of the pie (pct) */ majaxis=50, /* Horizontal length of the pie (pct) */ minaxis=30, /* Vertical length of the pie (pct) */ thicknes=2, /* Thickness of the pie (pct) */ legnlabl=STATES, /* Legend label */ legendx=48, /* Horizontal center of the legend (pct) */ legendy=30, /* Vertical center of the legend (pct) */ titlex=12, /* Horizontal position of the title (pct) */ titley=91, /* Vertical position of the title (pct) */ titletxt=Number of Sites per State, /* Text of the title */ by_var=product /* The BY variable used to create multiple pies */ );