data gsales93;
   length city $13;
   input city & $ sales;
   cards;
Chicago  59852330
Dallas  48198208
Los Angeles  45668204
Atlanta  37915024
San Francisco  31774845
Denver  28285189
New York  27441937
;

proc means data=gsales93 max noprint;
   var sales;
   output out=max max=max;
run;

data _null_;
   set max;
   call symput('max',max);
run;

proc sort data=gsales93;
   by city;

proc sort data=maps.uscity out=uscity;
   by city;

data cityloc;
   merge uscity(in=incities) gsales93(in=indata);
   by city;
   if incities and indata;
   x=long*arcos(-1)/180;
   y=lat*arcos(-1)/180;
   state=x+100;
run;

data states;
   set maps.states;
   if state=2 or state=15 or state=72 then delete;
   if density lt 4;
run;

data allmap;
   set states cityloc;
run;

proc gproject data=allmap
              out=allproj
              project=gnomon
              polelong=160
              polelat=45;
   id state;
run;

data anno usmap;
   set allproj;
   if state gt 100 then output anno;
   else output usmap;
run;

proc sort data=anno;
   by descending y;
run;

data anno;
   set anno end=eof;
   length function style color $ 8 text $30;

      /* XSYS and YSYS coordinate systems are defined so that x   */
      /* and y values are interpreted as data values. HSYS is     */
      /* set to use screen percentage values. The variable WHEN   */
      /* dictates that the annotation will be drawn after the     */
      /* graph is drawn.                                          */
   xsys='2'; ysys='2'; hsys='3';
   when='a';

   /* Place the star character from the MARKER font at each city  */
   /* location,  centered at the x/y coordinate.                  */
function='label';
color='black';
position='+';
size=4;
style='marker';
text='V';
output;

   /* Change x and y coordinate systems to reflect screen         */
   /* percentages and draw a line to an x position of 70 percent  */
   /* of graphics output area. The corresponding y position for   */
   /* each line decreases based on the observation number in      */
   /* increments of 10 percent starting at a y position of 90     */
   /* percent.                                                    */
function='move';
output;
function='draw';
size=.25;
xsys='3';
ysys='3';
x=70;
ystart=90;
y=ystart-(_n_*10);

   /* Create variables to store the current x/y position for use  */
   /* later in the DATA step.                                     */
xhold=x;
yhold=y;
output;

   /* Draw a bar to reflect the gross sales figure for each       */
   /* regional office. The length of each bar is scaled based on  */
   /* the maximum data value which has a length of 25 percent.    */
   /* The width of each bar is 5 percent of the graphics output   */
   /* area.                                                       */
function='move';
y=y-2.5;
output;
function='bar';
x=70+(25*(sales/&max));
y=y+5;
style='solid';
color='black';
output;

   /* Label each bar with the city name and associated sales      */
   /* value beginning at the previously stored location on the    */
   /* on the left side of the bar.                                */
function='label';
x=xhold+1; y=yhold;
style='swissl';
color='white';
position='>';
size=1.75;
text=left(put(sales,dollar15.));
output;

y=y+2.5;
position='3';
color='black';
text=trim(left(city));
output;
run;

      /* set graphics options                                     */
   goptions reset=all target=psll ftext=swissl;

      title1 h=2 f=swiss 'Gross Sales for Regional Offices';
      footnote1 a=90 h=35 pct '  ';
      footnote2 j=l 'SAS/GRAPH' move=(+0,+.5) '02'x 
                move=(+0,-.5) ' Software';
      pattern1 v=empty c=black r=50;

proc gmap data=usmap map=usmap all;
   id state;
   choro state / nolegend anno=anno;
run;
quit;