%let name=wafer2; filename odsout '.'; goptions reset=global; /* These others should be calculated/derived from the &granule value, but I can't think of the right %eval syntax at the moment */ %let granule=200; %let radius=100; %let num1=100.5; %let num2=99.5; /* %let granule=100; %let radius=50; %let num1=50.5; %let num2=49.5; */ /* %let granule=50; %let radius=25; %let num1=25.5; %let num2=24.5; */ /* Create the 'map' dataset. */ data work.wafermap; length id $ 20; do grid_y=1 to &granule; do grid_x=1 to &granule; /* Calculate distance of this box from center of wafer */ distance = sqrt( ((grid_x-&num1)*(grid_x-&num1)) + ((grid_y-&num1)*(grid_y-&num1)) ); /* If this falls within the circle, use it */ if distance <= &num2 then do; id=trim(left(grid_x))||'_'||trim(left(grid_y)); middle_x=grid_x-.5; middle_y=grid_y-.5; /* Value is 0-1, and treat that as the size of the box */ x=middle_x-.5; y=middle_y-.5; output; x=middle_x+.5; y=middle_y-.5; output; x=middle_x+.5; y=middle_y+.5; output; x=middle_x-.5; y=middle_y+.5; output; end; end; end; run; /* Annotate a gray circular polygon behind the grid */ data work.graycircle; length function color $ 8 text $ 30; xsys='2'; ysys='2'; hsys='3'; when='b'; /* draw gray circle 'before'/behind the gmap */ size=1; /* line thickness */ style='msolid'; color='gray77'; radius=(&granule)/2; x_circle_origin=(&granule/2); y_circle_origin=(&granule/2); do degrees=0 to 360 by 5; if degrees eq 0 then function='poly'; else function='polycont'; radians=degrees/57.3; x=(radius * cos(radians)) + x_circle_origin; y=(radius * sin(radians)) + y_circle_origin; output; end; run; proc sql; create table work.rawdata as select unique id, grid_x, grid_y, distance from work.wafermap; quit; run; data work.griddata; set work.rawdata; length html $ 254; format value comma5.3; /* Generate a random data value, from 0-.06 */ value=ranuni(765422)*.06; /* For this fake data, make the values lower towards the outer edge */ if distance > (.65 * &radius) then value=value*.8; if distance > (.80 * &radius) then value=value*.8; /* And, make the values lower/bluer on the right side of the wafer */ if grid_x > (&radius) then value=value*.85; if grid_x > (1.5 * &radius) then value=value*.8; if grid_x > (1.8 * &radius) then value=value*.8; if grid_x > (1.9 * &radius) then value=value*.8; /* Could add a chart tip & drilldown for each cell in the grid */ /* ** With a grid this dense, I'm leaving this out */ /* myhtml= 'title='|| quote( 'id: '||trim(left(id))||'0D'x|| 'x: '||grid_x||'0D'x|| 'y: '||grid_y||'0D'x|| 'value: '||value||' ' ) ||' '|| 'href="wafer3.htm"'; if value^=. then output; run; */ /* Create some 'fake' data, to force the legend and color assignment to go from 0-.06, rather than auto-rescaling with each drilldown */ data work.fakedata; x=0; y=0; id='foo1'; value=0; output; x=0; y=0; id='foo2'; value=.06; output; run; data work.griddata; set work.griddata work.fakedata; run; GOPTIONS DEVICE=gif; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" (title="SAS/GRAPH Example") style=d3d gtitle gfootnote ; goptions gunit=pct htitle=5 htext=3.75 ftitle="arial/bo" ftext="arial"; title "Silicon Wafer Map Analysis"; title2 h=3 " "; /* This just puts more space between title1 and the plot/map */ footnote1 h=1 " "; footnote2 h=3 link="http://www.hologenix.com/example4.gif" "Similar to this HoloGenix WaferMap (click here to see)"; legend1 across=1 position=(middle right) shape=bar(2,2) label=(position=top 'PPM / Sr') /* origin=(5,5) */ value=(h=2) /* mode=share */; /* Lowest value maps to pattern1 */ pattern1 v=s c=mob; /* deep blue */ pattern2 v=s c=cx0000ff; pattern3 v=s c=vligb; /* vivid greenish blue */ pattern4 v=s c=green; pattern5 v=s c=cx00ff00; pattern6 v=s c=yellowgreen; pattern7 v=s c=yellow; pattern8 v=s c=orange; pattern9 v=s c=red; /* Highest value maps to highest pattern# */ goptions cback=white; goptions hsize=7in vsize=7in; goptions border; proc gmap data=work.griddata map=work.wafermap anno=work.graycircle /* all */; id id; choro value / legend=legend1 /* html=myhtml */ levels=9 coutline=same des="" name="&name"; run; quit; ODS HTML CLOSE; ODS LISTING;