%let name=periodic_table_ods_graphs;
filename odsout '.';

/*
My version of Ted Conway's graphic, from SASGF 2018:
https://communities.sas.com/t5/SAS-GRAPH-and-ODS-Graphics/A-Periodic-Table-of-Introductory-SAS-ODS-Graphics-Examples-SASGF/m-p/453462#M15548

This example creates a periodic table using SAS/Graph gmap & annotate.
The numbering for the rows & columns of the table starts at the bottom/left 
corner (since that's the origin of gmap's coordinate system).
*/

%let cellwidth=1.1;
%let cellheight=1.2;
%let gap=.05;

%let blue=cx0070c0;
%let red=cxff0000;;
%let green=cx00b050;;
%let orange=cxf08000;;
%let gray=cx7f7f7f;;
%let black=cx000000;;
%let purple=cx7030a0;;
%let pink=cxff69b4;;

data table_data;
infile datalines pad truncover;
input column row number $ 10-12 abbreviation $ 14-16 graph_type $ 18-33 description $ 35-100;
datalines;
 1  8      1   S SCATTER          Sgplot Basic Scatter Plot               
14  8      2   S SCATTER          Sgplot Scatter with Gradient Colors
 1  7      3   S SCATTER          Sgplot Scatter Plot with Discrete Colors
 2  7      4   S SCATTER          Sgplot Scatter with Unicode Character Markers
13  7      1  Li LINE             Sgplot Sgplot Line Plot            
14  7      2  Li LINE             Sgplot Line Plot and Forecast     
 1  6      3  Li LINE             Sgplot Line Plot with Markers  
 2  6      4  Li LINE             Sgplot Line Plots Overlaid        
13  6      1  St STEP             Sgplot Basic Step Plot            
14  6      2  St STEP             Sgplot Labeled Step Plot          
 1  5      1  Ba BAR              Sgplot Basic Bar Chart  
 2  5      2  Ba BAR              Sgplot Horizontal Bar Chart
 3  5      3  Ba BAR              Sgplot Stacked Bar Chart   
 4  5      4  Ba BAR              Sgplot Paired Bar Chart    
 5  5      5  Ba BAR              Sgplot Labeled Bar Chart   
 6  5      1   C COMBO            Sgplot Bar and Line Chart  
 7  5      2   C COMBO            Sgplot Scatter with Regression Line
 8  5      .   T TABLE            Sgplot Table Chart         
 9  5      .   D DOT              Sgplot Dot Chart                  
10  5      1  Bu BUBBLE           Sgplot Basic Bubble Chart  
11  5      2  Bu BUBBLE           Sgplot Colored Bubble Chart
12  5      3  Bu BUBBLE           Sgplot Grid of Bubbles     
13  5      1  Bx BOX              Sgplot Basic Box Chart     
14  5      2  Bx BOX              Sgplot Colored Box Chart   
 1  4      3  Bx BOX              Sgplot Labeled Box Chart
 2  4      1  Hl HIGH-LOW         Sgplot Basic High-Low Chart     
 3  4      2  Hl HIGH-LOW         Sgplot High-Low Open/Close Chart
 4  4      3  Hl HIGH-LOW         Sgplot Labeled High-Low Chart
 5  4      1   W WATERFALL        Sgplot Basic Waterfall Chart
 6  4      2   W WATERFALL        Sgplot Labeled Waterfall Chart    
 7  4      1  Se SERIES           Sgplot Basic Series Plot   
 8  4      2  Se SERIES           Sgplot Series Plot with Line Thickness
 9  4      3  Se SERIES           Sgplot Series Plots Overlaid
10  4      1  Hi HISTOGRAM        Sgplot Basic Histogram     
11  4      2  Hi HISTOGRAM        Sgplot 3d-Shiny Histogram  
12  4      1   V VECTOR           Sgplot Basic Vector Plot   
13  4      2   V VECTOR           Sgplot Labeled Vector Plot 
14  4      1  Tx TEXT             Sgplot Basic Text Plot
 1  3      2  Tx TEXT             Sgplot Text Plot with Targeted Text
 2  3      1   N NEEDLE           Sgplot Basic Needle Plot        
 3  3      2   N NEEDLE           Sgplot 'Lollipop' Plot     
 4  3      1   H HEATMAP          Sgplot Basic Heatmap       
 5  3      2   H HEATMAP          Sgplot Heatmap Grid        
 6  3      1   B BAND             Sgplot Basic Band Plot     
 7  3      2   B BAND             Sgplot Area-Under-Curve Band Plot
 8  3      .  Bl BLOCK            Sgplot Basic Block Plot    
 9  3      .   M MAP              Sgmap Basic Geographic Map
10  3      .   E ELLIPSE          Sgplot Basic Ellipse        
11  3      1  Am ATTR MAP         Sgplot Discrete Attribute Map (Color List)
12  3      2  Am ATTR MAP         Sgplot Range Attribute Map (Color List)
13  3      3  Am ATTR MAP         Sgplot Range Attribute Map (Color Model)
14  3      .   A ANNOTATE         Sgplot with Watermark       
 4  2      1  Pn BAR              Sgpanel Bar                
 5  2      2  Pn DOT              Sgpanel Dot           
 6  2      3  Pn LATTICE          Sgpanel Lattice            
 7  2      4  Pn SERIES           Sgpanel Series             
 8  2      1  Sc MATRIX           Sgscatter Matrix           
 9  2      2  Sc HISTOGRAM        Sgscatter with Histogram   
10  2      3  Sc PLOT             Sgscatter of Plots         
11  2      4  Sc PLOT/ROWS        Sgscatter Rows of Plots      
 4  1      5  Sc PLOT/COLS        Sgscatter Columns of Plots 
 5  1      6  Sc COMPARE          Sgscatter Comparison Plot
 6  1      .   P POLYGON          Sgrender Polygons via Template
 7  1      1  Gt GTL              Sgrender GTL Lattice
 8  1      2  Gt GTL              Sgrender GTL Lattice with Reflines
 9  1      .  Pi PIE              Sgrender GTL Pie
10  1      .  Mo MOSAIC           Sgrender GTL Mosaic
11  1      .  3D HISTOGRAM        Sgrender 3D GTL Histogram 
;
run;

data table_data; set table_data;

length cell_id $20;
cell_id=trim(left(row))||'_'||trim(left(column));

length gaph_filename $20;
if number^=. then graph_filename=trim(left(lowcase(abbreviation)))||trim(left(number));
else graph_filename=trim(left(lowcase(abbreviation)));

length my_html $300;
my_html=
 'title='||quote(
  trim(left(graph_type))||' '||trim(left(number))||'0d'x||
  trim(left(description)))||
 ' href='||quote('./samples/'||trim(left(graph_filename))||'_info.htm');
run;


proc format;
 value colorfmt
 1 = 'SGPLOT (Basic)'
 2 = 'SGPLOT (Categorization)'
 3 = 'SGPLOT (Distribution)'
 4 = 'SGPLOT (Statements, Other)'
 5 = 'SGMAP (Geographic Mapping)'
 6 = 'SGPANEL (Miscellaneous)'
 7 = 'SGSCATTER (Miscellaneous)'
 8 = 'SGRENDER, GTL (Miscellaneous)'
 ;
run;

/* add a variable to control the color */
data table_data; set table_data;
length color $12;
format colorvar colorfmt.;
if abbreviation in ("S" "St" "V" "Bu" "E" "Bl" "Se" "B" "Tx" "N" "Hl" "H") then colorvar=1;   
else if abbreviation in ("D" "Li" "Ba" "W") then colorvar=2;  
else if abbreviation in ("Hi" "Bx") then colorvar=3;    
else if abbreviation in ("T" "C" "A" "Am") then colorvar=4;   
else if abbreviation in ("M") then colorvar=5;   
else if abbreviation in ("Pn") then colorvar=6;     
else if abbreviation in ("Sc") then colorvar=7;    
else if abbreviation in ("Mo" "Pi" "Gt" "P" "3D") then colorvar=8;     
else colorvar=.;   
run;

/* 
Create the geometry (4 corners for each cell in the table)
for the SAS/Graph gmap.
*/
data table_map; set table_data;
x=column*&cellwidth; y=row*&cellheight; output;
x=x+&cellwidth-&gap; output;
y=y+&cellheight-&gap; output;
x=x-&cellwidth+&gap; output;
run;

/* 
Annotate the text values for each cell, at the center of each x/y gmap area.
*/
proc sql noprint;
create table anno_text as 
select unique cell_id, avg(x) as x_center, avg(y) as y_center, number, abbreviation, description, graph_type
from table_map
group by cell_id;
quit; run;

data anno_text; 
length function color $8 style $20 text $300;
 set anno_text;
xsys='2'; ysys='2'; when='a'; 
function='label'; color='white';
style="albany amt/bold"; 
fullsize=2.0;

/* main/big abbreviation (a little above center) */
y=y_center+(&gap*3);
x=x_center;
position='5'; 
size=fullsize; 
text=trim(left(abbreviation));
output;

/* subscript number */
y=y_center+(&gap*2);
x=.;
position='f';
size=fullsize*.5;
text='a0'x||trim(left(number));
output;

/* text name, smaller and a little below center */
y=y_center-(&gap*2);
x=x_center;
position='8'; 
size=fullsize*.40;
text=trim(left(graph_type)); 
output;

run;

data anno_starburst;
length function $8 color $12 style $35 text $300;
xsys='3'; ysys='3'; hsys='3'; when='a';
function='label'; position='5'; 

/* starburst */
style='Webdings'; text='2a'x; 
x=13;     y=20.5; size=25.0; color='gray44'; output;
x=13;     y=20.5; size=size-1; color='cx4f81bd'; output;
x=100-13; y=20.5; size=25.0; color='gray44'; output;
x=100-13; y=20.5; size=size-1; color='cx4f81bd'; output;

/* text */
style=''; color='white'; size=2.7;
x=13; y=18.5; text='Hover to see'; output;
x=13; y=y-4;; text='descriptions!'; output;
x=100-13; y=18.5; text='Click to see'; output;
x=100-13; y=y-4;; text='examples!'; output;
run;

/* 
Annotate the title text, rather than using the standard title,
so you can share the space with the map (rather than reserving 
space above the map).
*/
data anno_titles;
length function $8 style $35 text $300 html $300;
xsys='3'; ysys='3'; hsys='4'; when='a';
function='label'; position='5'; size=2.2; style='albany amt/bold';
x=50; 
y=96; text='A "Periodic Table" of Introductory'; output;
/* have to get a little tricky, to get the superscripted 'registered trademark' symbol */
position='6';
x=30;
y=90; 
text='SAS'; output;
x=.;
size=1.2; text='ae'x; output;
size=2.2; text=' ODS Graphics Examples'; output;
run;

data anno_all; 
set anno_text anno_starburst anno_titles;
run;


goptions device=png xpixels=1050 ypixels=675;
goptions border cback=cxa0c3ff;
 
ODS LISTING CLOSE;
ODS HTML path=odsout body="&name..htm" 
 (title="Periodic Table of SAS ODS Graphs") 
 style=htmlblue;

goptions gunit=pct htitle=4.5 htext=2.0 ftitle="albany amt/bold" ftext="albany amt";
goptions ctext=gray33;

pattern1 v=s c="&blue";
pattern2 v=s c="&red";
pattern3 v=s c="&green";
pattern4 v=s c="&gray";
pattern5 v=s c="&pink";
pattern6 v=s c="&orange";
pattern7 v=s c="&black";
pattern8 v=s c="&purple";

legend1 label=none position=(top center) mode=share across=2 
 value=(justify=left) shape=bar(.18in,.18in) offset=(0,-18) colmajor;

/* Add a little white-space on the top, left, and right sides */
title1 h=.01 ' ';
title2 a=90 h=1 ' ';
title3 a=-90 h=1 ' ';

footnote h=1.9 ls=0.7 color=gray55
 link='http://www.sasgfsessioncatalog.com/#/speaker/name@Conway%20Ted%3E0Conway%20Ted@3214'
 "Variation of Ted Conway's SGF 2018 e-Poster, which was inspired by"
 link='http://www.visual-literacy.org/periodic_table/periodic_table.pdf'
 " 'Towards a Periodic Table of Visualization Methods for Management' (2007)";

proc gmap map=table_map data=table_data anno=anno_all;
id cell_id; 
choro colorvar / discrete midpoints=(1 2 3 4 5 6 7 8) legend=legend1
 coutline=gray33 
 html=my_html
 des='' name="&name";
run;

quit;
ODS HTML CLOSE;
ODS LISTING;
