%let name=w_nile;

/*
Ideally, I would be able to just use "by date", but I also want to change
the viewing angle for each frame (not just the date), so I have to set up 
a macro, and then loop through, calling it for each date, and passing in
a different viewing angle...
*/

%let radius=8;   /* radius of viewing position (distance away from map) */
%let zview=5;    /* height above map (position from which you're looking down) */
%let delay=35;   /* delay between frames (75 = .75 seconds) */
%let state=SD;   /* South Dakota */

data mydata;
input date date9. county cases;
state=stfips("&state");
datalines;
01jul2000   23   3
01jul2000    9   1
01jul2000  135   5
05jul2000   23   2
05jul2000    9   5
05jul2000  135   1
05jul2000   53   1
05jul2000  123   1
05jul2000   27   2
05jul2000   85   1
06jul2000    9   1
07jul2000    3   1
07jul2000    5   2
07jul2000   73   2
07jul2000  111   3
09jul2000   23   4
09jul2000    9   5
09jul2000   15   1
09jul2000   17   1
09jul2000   75   6
09jul2000   71   3
09jul2000  119   3
09jul2000   75   5
09jul2000   93   1
10jul2000   23   4
10jul2000   55   4
10jul2000    9   6
10jul2000  135   3
11jul2000    9   1
12jul2000  115   4
12jul2000   11   1
12jul2000  137   1
12jul2000   93   1
13jul2000   31   1
14jul2000   23   1
15jul2000   17   8
15jul2000   73   2
15jul2000  119   5
16jul2000   23   1
17jul2000   23   1
25jul2000    9   3
25jul2000  135   6
27jul2000   23   6
27jul2000    9   6
27jul2000  135   6
28jul2000  109   3
29jul2000   23   1
01aug2000   15   2
01aug2000   17   6
03aug2000   15   2
03aug2000   17   3
03aug2000  123   2
03aug2000   27   3
03aug2000   85   2
05aug2000   23   4
05aug2000    9   3
05aug2000   85   5
05aug2000  135   4
05aug2000   53   5
05aug2000  123   4
06aug2000   49   4
09aug2000   15   4
09aug2000   43   4
09aug2000   67   4
09aug2000   15   2
09aug2000  129   2
09aug2000   31   3
10aug2000  113   2
12aug2000   43   2
12aug2000   67   2
12aug2000   67   2
12aug2000   61   1
12aug2000   35   1
18aug2000    3   2
18aug2000   61   2
18aug2000   35   1
18aug2000   51   1
18aug2000   85   3
19aug2000   63   2
19aug2000   49   4
19aug2000  105   1
19aug2000   91   1
19aug2000  109   8
20aug2000   95   1
20aug2000   53   4
20aug2000    7   1
23aug2000   95   4
23aug2000  121   2
23aug2000   91   3
;
run;

proc sort data=mydata out=mydata; 
by date;
run;

proc sql noprint;
select min(date) format=date9. into :min_date from mydata;
select max(date) format=date9. into :max_date from mydata;
create table mydates as select unique date from mydata;
select count(*) into :num_days from mydates;
quit; run;

data mydates; set mydates;
daynum+1;
run;
%let startangle=180;
data mydates; set mydates;
degrees=(daynum-1)*(360/(&num_days-1))+&startangle;
radians=degrees*(atan(1)/45);
xview=&radius * sin(radians);
yview=&radius * cos(radians);
run;


proc sql;

create table mymap as
select * from maps.uscounty
where state = stfips("&state");

create table blank as
select unique state, county 
from mymap;

quit; run;


options mprint source source2;

%macro do_map(datestr);
%local datestr day_num;

proc sql noprint;

create table tempdata as
select unique state, county, sum(cases) as cases
from mydata
where date le "&datestr"d
group by state, county;

create table tempdata as
select unique blank.state, blank.county, tempdata.cases
from blank left join tempdata
on blank.state=tempdata.state and blank.county=tempdata.county;

select xview into :xview from mydates where date eq "&datestr"d;
select yview into :yview from mydates where date eq "&datestr"d;

quit; 
run;

data tempdata; set tempdata;
if (cases eq .) then cases=0;
if cases=0 then range=1;
if cases>=1 and cases<=2 then range=2;
if cases>=3 and cases<=5 then range=3;
if cases>=6 and cases<=10 then range=4;
if cases>=11 then range=5;
run;

proc format;
   value range_fmt
   1='0'
   2='1-2'
   3='3-5'
   4='6-10'
   5='11+'
   ;
run;

pattern1 v=solid color=gray44;
pattern2 v=solid color=cxffffb2;
pattern3 v=solid color=cxfecc5c;
pattern4 v=solid color=cxfd8d3c;
pattern5 v=solid color=cxe31a1c;


title1 ls=1.5 "Total Accumulation of West Nile Cases";
title2 j=center "South Dakota" j=right move=(-3,+0) "&datestr";

goptions gunit=pct htitle=5.0 htext=3.5 ftitle="albany amt/bold" ftext="albany amt" ;

legend1 label=(font="albany amt/bold" 'Cases:') value=(justify=left) shape=bar(2,2.5);

proc gmap map=mymap data=tempdata all;
format range range_fmt.;
id state county; 
prism range / midpoints = 1 2 3 4 5
 xview=&xview
 yview=&yview
 zview=&zview
 coutline=gray88
 legend=legend1;
run;

%mend do_map;



/**************************************************************************/

%macro bigloop;

data _null_;
   file "&name._anim.htm";
   put "<HTML>";
   put "<BODY>";
   put "<BLOCKQUOTE>";
   put "<P><img src='&name._anim.gif' title='&state DoH - West Nile Animation' ";
   put "</BLOCKQUOTE>";
   put "</BODY>";
   put "</HTML>";

filename animmap "&name._anim.gif";
goption reset gsfname=animmap gsfmode=replace dev=gifanim 
 iteration=1 delay=&delay disposal=background userinput;


/* Treat the first frame special */
%do_map(&min_date);


/* Do all frameb between first & last */
goption gsfmode=append;
data foo; set mydates end=eof;
 if (_n_ = 1) then put 'FFFFFFFFFFFFFFFFFFirst';
 else if eof then put 'LLLLLLLLLLLLLLLLLLast';
 else do;
  call execute('%do_map('||trim(left(put(date,date9.)))||'); ');
  end;
run;

/* And, treat the last frame special */
goptions gepilog='3B'x;
%do_map(&max_date);

%mend bigloop;

%bigloop;
